embeddings 缓存处理
这篇笔记聚焦 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 处理
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
因为它是最近刚访问的。
比如一种场景:
数据是一遍扫过去的,刚用过的内容短期不会再回头访问。
例如:
- 顺序扫描大文件
- 某些批处理任务
- 一次性遍历数据集
这时最近刚访问过的内容,反而最不可能马上再用,所以删它反而更合理。
评论
还没有评论,来发第一个吧