缓存
Embeddings 可以被存储或临时缓存,以避免重复计算。
可以通过 CacheBackedEmbeddings 来缓存 embeddings。缓存式 embedder 是一个 embedder 的包装器,它将 embeddings 缓存到键值存储中。文本会被哈希,然后该哈希作为缓存的键。
初始化 CacheBackedEmbeddings 的主要支持方式是 from_bytes_store。它接受以下参数:
- underlying_embedder: 用于嵌入的 embedder。
- document_embedding_cache: 用于缓存文档 embeddings 的任何
ByteStore。 - batch_size: (可选,默认为
None) 存储更新之间用于嵌入的文档数量。 - namespace: (可选,默认为
"") 用于文档缓存的命名空间。此命名空间用于避免与其他缓存发生冲突。例如,可以将其设置为使用的嵌入模型的名称。 - query_embedding_cache: (可选,默认为
None或不缓存) 用于缓存查询 embeddings 的ByteStore,或者设置为True以使用与document_embedding_cache相同的存储。
请注意:
- 务必设置
namespace参数,以避免使用不同嵌入模型嵌入相同文本时发生冲突。 - 默认情况下,
CacheBackedEmbeddings不缓存查询 embeddings。要启用查询缓存,需要指定query_embedding_cache。
from langchain.embeddings import CacheBackedEmbeddings
API Reference:CacheBackedEmbeddings
与 Vector Store 结合使用
首先,让我们看一个使用本地文件系统存储 embedding 并结合 FAISS vector store 进行检索的示例。
%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
underlying_embeddings = OpenAIEmbeddings()
store = LocalFileStore("./cache/")
cached_embedder = CacheBackedEmbeddings.from_bytes_store(
underlying_embeddings, store, namespace=underlying_embeddings.model
)
缓存将在嵌入前是空的:
list(store.yield_keys())
[]
加载文档,将其分割成块,嵌入每个块并加载到向量存储中。
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)
CPU times: user 218 ms, sys: 29.7 ms, total: 248 ms
Wall time: 1.02 s
如果我们再次尝试创建 vector store,速度会快得多,因为它不需要重新计算任何 embeddings。
%%time
db2 = FAISS.from_documents(documents, cached_embedder)
CPU times: user 15.7 ms, sys: 2.22 ms, total: 18 ms
Wall time: 17.2 ms
以下是一些已创建的嵌入:
list(store.yield_keys())[:5]
['text-embedding-ada-00217a6727d-8916-54eb-b196-ec9c9d6ca472',
'text-embedding-ada-0025fc0d904-bd80-52da-95c9-441015bfb438',
'text-embedding-ada-002e4ad20ef-dfaa-5916-9459-f90c6d8e8159',
'text-embedding-ada-002ed199159-c1cd-5597-9757-f80498e8f17b',
'text-embedding-ada-0021297d37a-2bc1-5e19-bf13-6c950f075062']
切换 ByteStore
如果要使用不同的 ByteStore,只需在创建 CacheBackedEmbeddings 时使用它即可。下面,我们创建了一个等效的缓存嵌入对象,但改用了非持久化的 InMemoryByteStore:
from langchain.embeddings import CacheBackedEmbeddings
from langchain.storage import InMemoryByteStore
store = InMemoryByteStore()
cached_embedder = CacheBackedEmbeddings.from_bytes_store(
underlying_embeddings, store, namespace=underlying_embeddings.model
)
API Reference:CacheBackedEmbeddings | InMemoryByteStore