AI 大模型开发

embeddings 缓存处理

JACIN3 分钟阅读
AI 摘要

这篇笔记聚焦 LangChain embeddings 的本地文件缓存处理,核心场景是避免重复调用 embedding 模型,同时保证缓存命中结果不会因模型差异而混用。正文用 `LocalFileStore("./.cache/embeddings/", update_atime=True)` 和 `CacheBackedEmbeddings.from_bytes_store(...)` 展示了基本写法,并强调同一段文本在不同模型下会得到不同向量,因此缓存 key 需要通过 `namespace=openai_embeddings.model` 区分模型命名空间,避免串缓存。`LocalFileStore` 在读取缓存文件时可以主动刷新 atime,也就是最后访问时间,用来弥补某些文件系统默认不可靠更新 atime 或更新策略较弱的问题。缓存代理的工作流程是先由输入文本生成 key,再查本地 store,命中则直接返回 embedding,未命中才调用 `openai_embeddings` 并把结果写回缓存。文章还解释了 mtime、ctime、atime 的区别,并围绕 atime 引出缓存淘汰策略:LRU 会优先删除很久没访问的项目,适合 embedding 缓存、页面缓存、Redis 热数据和数据库 buffer pool 等大多数热点访问场景;MRU 则优先删除刚访问过的项目,更适合顺序扫描大文件、批处理或一次性遍历数据集这类短期不会回头访问的场景。读者可以据此理解 LangChain 缓存 embedding 的关键配置点,以及在清理本地缓存时如何根据访问模式选择 LRU 或 MRU。

缓存 store 处理

python
store = LocalFileStore("./.cache/embeddings/", update_atime=True)

# 同一段文本,用不同模型算出来的向量不一样。

# 所以缓存 key 里要区分模型命名空间,不然会串缓存。
cached_embedder = CacheBackedEmbeddings.from_bytes_store(
    openai_embeddings, store, namespace=openai_embeddings.model
)

当缓存文件被读取时,主动更新这个文件的“访问时间 atime”。

这里有三个常见时间概念:

  • mtime:modified time,文件内容最后修改时间
  • ctime:metadata change time,元数据变化时间
  • atime:access time,最后访问时间

这个参数的作用是:

有些文件系统默认不会可靠更新 atime,或者更新策略很弱,所以 LocalFileStore 在读取缓存时,手动帮你刷新“最近访问时间”。

store会帮你做这件事:

  • 先根据输入文本生成缓存 key
  • store 里查
  • 查到了就直接返回缓存的 embedding
  • 查不到才调用 openai_embeddings
  • 然后把结果写回 store

所以你可以把它理解成:

LangChain 帮你做了“带缓存的 embeddings 代理对象”。

LRU#

意思是:

优先淘汰“很久没被访问”的缓存项。

比如有 4 个缓存文件:

  • A:1小时前访问
  • B:10分钟前访问
  • C:昨天访问
  • D:刚访问

如果缓存满了,LRU 会优先删:

C

因为它最久没被用过。

LRU 的特点

它假设:

过去经常用、最近刚用过的东西,未来大概率还会再用。

所以 LRU 很适合大多数缓存场景。

比如:

  • embedding 缓存
  • 页面缓存
  • Redis 热数据
  • 数据库 buffer pool

MRU#

Most Recently Used

最近最多使用

意思是:

优先淘汰“刚刚才被访问过”的缓存项。

同样那 4 个文件:

  • A:1小时前访问
  • B:10分钟前访问
  • C:昨天访问
  • D:刚访问

如果用 MRU,可能优先删:

D

因为它是最近刚访问的。

比如一种场景:

数据是一遍扫过去的,刚用过的内容短期不会再回头访问。

例如:

  • 顺序扫描大文件
  • 某些批处理任务
  • 一次性遍历数据集

这时最近刚访问过的内容,反而最不可能马上再用,所以删它反而更合理。

评论

还没有评论,来发第一个吧