高效缓存文本嵌入: 使用CacheBackedEmbeddings 降低计算成本

91 阅读3分钟

引言

在处理自然语言处理任务时,文本嵌入(Embeddings)是一个常见且重要的步骤。然而,计算文本嵌入通常需要消耗大量的计算资源。为了提高效率,我们可以将嵌入结果缓存起来。这篇文章将介绍如何使用 CacheBackedEmbeddings 缓存文本嵌入,以避免重复计算嵌入,从而节省计算资源。

主要内容

1. 什么是 CacheBackedEmbeddings

CacheBackedEmbeddings 是一个包裹在嵌入器周围的工具,它将嵌入结果缓存在一个键值存储中。通过对待嵌入文本进行哈希处理,然后将哈希值作为缓存的键,可以有效地缓存和检索嵌入结果。

2. 初始化 CacheBackedEmbeddings

主要的初始化方法是 from_bytes_store,它接受以下参数:

  • underlying_embedder: 使用的嵌入器。
  • document_embedding_cache: 用于缓存文档嵌入的 ByteStore
  • batch_size (可选,默认为 None):每次存储更新之间嵌入的文档数量。
  • namespace (可选,默认为 ""):用于文档缓存的命名空间,以避免与其他缓存冲突。例如,可以将其设置为使用的嵌入模型名称。
  • query_embedding_cache (可选,默认为 None 或不缓存):用于缓存查询嵌入的 ByteStore,或 True 使用与 document_embedding_cache 相同的存储。

3. 注意事项

  • 确保设置 namespace 参数,以避免使用不同嵌入模型嵌入相同文本时发生冲突。
  • 默认情况下,CacheBackedEmbeddings 不缓存查询嵌入。要启用查询缓存,需要指定 query_embedding_cache

4. 使用 CacheBackedEmbeddings 和向量存储

下面是一个使用本地文件系统存储嵌入,并使用 FAISS 向量存储进行检索的示例。

代码示例

以下代码展示了如何使用 CacheBackedEmbeddings 缓存嵌入结果并创建向量存储。

# 安装必要的包
%pip install --upgrade --quiet langchain-openai faiss-cpu

# 导入相关模块
from langchain.storage import LocalFileStore
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter
from langchain.embeddings import CacheBackedEmbeddings

# 创建嵌入器
underlying_embeddings = OpenAIEmbeddings()

# 创建缓存存储
store = LocalFileStore("./cache/")  # 使用本地文件系统作为存储

# 使用缓存嵌入器
cached_embedder = CacheBackedEmbeddings.from_bytes_store(
    underlying_embeddings, store, namespace=underlying_embeddings.model
)

# 加载文档并分割成块
raw_documents = TextLoader("state_of_the_union.txt").load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
documents = text_splitter.split_documents(raw_documents)

# 创建向量存储
%%time
db = FAISS.from_documents(documents, cached_embedder)

# 再次创建向量存储时将更快速,因为无需重新计算嵌入
%%time
db2 = FAISS.from_documents(documents, cached_embedder)

# 查看一些创建的嵌入
list(store.yield_keys())[:5]

常见问题和解决方案

  1. 缓存冲突: 确保在创建 CacheBackedEmbeddings 时使用唯一的 namespace 以避免缓存冲突。
  2. 性能问题: 确保 ByteStore 的实现适用于你的存储需要。例如,对于持久存储,使用 LocalFileStore;对于临时存储,使用 InMemoryByteStore

总结和进一步学习资源

通过使用 CacheBackedEmbeddings,我们可以显著减少重复计算嵌入所需的时间和资源。建议进一步学习以下相关资源:

参考资料

  1. Langchain 官方文档: Langchain Documentation
  2. FAISS 官方文档: FAISS Documentation

结束语: '如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!'

---END---