如何缓存嵌入结果
预备知识
本指南假设您熟悉以下概念:
可以存储或临时缓存嵌入结果以避免重复计算它们。
可以使用 CacheBackedEmbeddings 实例来实现嵌入缓存。
缓存支持的嵌入器是一个封装了嵌入器的包装器,它将嵌入结果缓存在键值存储中。
文本会被哈希处理,并且该哈希值将作为缓存中的键使用。
初始化 CacheBackedEmbeddings 的主要支持方式是使用 fromBytesStore 静态方法。它接受以下参数:
underlyingEmbeddings: 要使用的嵌入模型。documentEmbeddingCache: 用于存储文档嵌入的缓存。namespace: (可选,默认为 "") 文档缓存使用的命名空间。该命名空间用于避免与其他缓存发生冲突。例如,您可以将其设置为所使用的嵌入模型的名称。
注意: 请务必设置命名空间参数,以避免使用不同嵌入模型对相同文本进行嵌入时发生冲突。
内存缓存
:::提示 请参阅安装集成包的一般说明部分。 :::
- npm
- Yarn
- pnpm
npm install @langchain/openai @langchain/community @langchain/core
yarn add @langchain/openai @langchain/community @langchain/core
pnpm add @langchain/openai @langchain/community @langchain/core
以下是一个使用内存缓存的基本测试示例。这种类型的缓存主要用于单元测试或原型设计。 如果您需要长期存储嵌入结果,请不要使用此缓存:
import { OpenAIEmbeddings } from "@langchain/openai";
import { CacheBackedEmbeddings } from "langchain/embeddings/cache_backed";
import { InMemoryStore } from "@langchain/core/stores";
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { FaissStore } from "@langchain/community/vectorstores/faiss";
import { TextLoader } from "langchain/document_loaders/fs/text";
const underlyingEmbeddings = new OpenAIEmbeddings();
const inMemoryStore = new InMemoryStore();
const cacheBackedEmbeddings = CacheBackedEmbeddings.fromBytesStore(
underlyingEmbeddings,
inMemoryStore,
{
namespace: underlyingEmbeddings.model,
}
);
const loader = new TextLoader("./state_of_the_union.txt");
const rawDocuments = await loader.load();
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 0,
});
const documents = await splitter.splitDocuments(rawDocuments);
// No keys logged yet since the cache is empty
for await (const key of inMemoryStore.yieldKeys()) {
console.log(key);
}
let time = Date.now();
const vectorstore = await FaissStore.fromDocuments(
documents,
cacheBackedEmbeddings
);
console.log(`Initial creation time: ${Date.now() - time}ms`);
/*
Initial creation time: 1905ms
*/
// The second time is much faster since the embeddings for the input docs have already been added to the cache
time = Date.now();
const vectorstore2 = await FaissStore.fromDocuments(
documents,
cacheBackedEmbeddings
);
console.log(`Cached creation time: ${Date.now() - time}ms`);
/*
Cached creation time: 8ms
*/
// Many keys logged with hashed values
const keys = [];
for await (const key of inMemoryStore.yieldKeys()) {
keys.push(key);
}
console.log(keys.slice(0, 5));
/*
[
'text-embedding-ada-002ea9b59e760e64bec6ee9097b5a06b0d91cb3ab64',
'text-embedding-ada-0023b424f5ed1271a6f5601add17c1b58b7c992772e',
'text-embedding-ada-002fec5d021611e1527297c5e8f485876ea82dcb111',
'text-embedding-ada-00262f72e0c2d711c6b861714ee624b28af639fdb13',
'text-embedding-ada-00262d58882330038a4e6e25ea69a938f4391541874'
]
*/
API Reference:
- OpenAIEmbeddings from
@langchain/openai - CacheBackedEmbeddings from
langchain/embeddings/cache_backed - InMemoryStore from
@langchain/core/stores - RecursiveCharacterTextSplitter from
@langchain/textsplitters - FaissStore from
@langchain/community/vectorstores/faiss - TextLoader from
langchain/document_loaders/fs/text
Redis
以下是一个使用 Redis 缓存的示例。
您首先需要安装 ioredis 作为对等依赖项,并传入一个已初始化的客户端:
- npm
- Yarn
- pnpm
npm install ioredis
yarn add ioredis
pnpm add ioredis
import { Redis } from "ioredis";
import { OpenAIEmbeddings } from "@langchain/openai";
import { CacheBackedEmbeddings } from "langchain/embeddings/cache_backed";
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { FaissStore } from "@langchain/community/vectorstores/faiss";
import { RedisByteStore } from "@langchain/community/storage/ioredis";
import { TextLoader } from "langchain/document_loaders/fs/text";
const underlyingEmbeddings = new OpenAIEmbeddings();
// Requires a Redis instance running at http://localhost:6379.
// See https://github.com/redis/ioredis for full config options.
const redisClient = new Redis();
const redisStore = new RedisByteStore({
client: redisClient,
});
const cacheBackedEmbeddings = CacheBackedEmbeddings.fromBytesStore(
underlyingEmbeddings,
redisStore,
{
namespace: underlyingEmbeddings.model,
}
);
const loader = new TextLoader("./state_of_the_union.txt");
const rawDocuments = await loader.load();
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 0,
});
const documents = await splitter.splitDocuments(rawDocuments);
let time = Date.now();
const vectorstore = await FaissStore.fromDocuments(
documents,
cacheBackedEmbeddings
);
console.log(`Initial creation time: ${Date.now() - time}ms`);
/*
Initial creation time: 1808ms
*/
// The second time is much faster since the embeddings for the input docs have already been added to the cache
time = Date.now();
const vectorstore2 = await FaissStore.fromDocuments(
documents,
cacheBackedEmbeddings
);
console.log(`Cached creation time: ${Date.now() - time}ms`);
/*
Cached creation time: 33ms
*/
// Many keys logged with hashed values
const keys = [];
for await (const key of redisStore.yieldKeys()) {
keys.push(key);
}
console.log(keys.slice(0, 5));
/*
[
'text-embedding-ada-002fa9ac80e1bf226b7b4dfc03ea743289a65a727b2',
'text-embedding-ada-0027dbf9c4b36e12fe1768300f145f4640342daaf22',
'text-embedding-ada-002ea9b59e760e64bec6ee9097b5a06b0d91cb3ab64',
'text-embedding-ada-002fec5d021611e1527297c5e8f485876ea82dcb111',
'text-embedding-ada-002c00f818c345da13fed9f2697b4b689338143c8c7'
]
*/
API Reference:
- OpenAIEmbeddings from
@langchain/openai - CacheBackedEmbeddings from
langchain/embeddings/cache_backed - RecursiveCharacterTextSplitter from
@langchain/textsplitters - FaissStore from
@langchain/community/vectorstores/faiss - RedisByteStore from
@langchain/community/storage/ioredis - TextLoader from
langchain/document_loaders/fs/text
下一步
现在您已经学会了如何使用缓存来避免重复计算嵌入结果。
接下来,请查看完整的 检索增强生成教程。