如何缓存嵌入结果
先决条件
本指南假设您熟悉以下概念
可以存储或临时缓存嵌入,以避免重新计算它们。
可以使用 CacheBackedEmbeddings
实例缓存嵌入。
缓存支持的嵌入器是嵌入器的包装器,它在键值存储中缓存嵌入。
文本被哈希化,哈希值用作缓存中的键。
初始化 CacheBackedEmbeddings
的主要支持方法是 fromBytesStore
静态方法。它接受以下参数
underlyingEmbeddings
:要使用的嵌入模型。documentEmbeddingCache
:要用于存储文档嵌入的缓存。namespace
: (可选,默认为 "") 要用于文档缓存的命名空间。此命名空间用于避免与其他缓存发生冲突。例如,您可以将其设置为所用嵌入模型的名称。
注意:请务必设置命名空间参数,以避免使用不同的嵌入模型对相同文本进行嵌入时发生冲突。
内存中
提示
- npm
- Yarn
- pnpm
npm install @langchain/openai @langchain/community
yarn add @langchain/openai @langchain/community
pnpm add @langchain/openai @langchain/community
以下是一个使用内存中缓存的基本测试示例。这种类型的缓存主要适用于单元测试或原型设计。如果您需要实际存储嵌入以供更长时间使用,请勿使用此缓存
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.modelName,
}
);
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 参考
- OpenAIEmbeddings 来自
@langchain/openai
- CacheBackedEmbeddings 来自
langchain/embeddings/cache_backed
- InMemoryStore 来自
@langchain/core/stores
- RecursiveCharacterTextSplitter 来自
@langchain/textsplitters
- FaissStore 来自
@langchain/community/vectorstores/faiss
- TextLoader 来自
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.modelName,
}
);
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 参考
- OpenAIEmbeddings 来自
@langchain/openai
- CacheBackedEmbeddings 来自
langchain/embeddings/cache_backed
- RecursiveCharacterTextSplitter 来自
@langchain/textsplitters
- FaissStore 来自
@langchain/community/vectorstores/faiss
- RedisByteStore 来自
@langchain/community/storage/ioredis
- TextLoader 来自
langchain/document_loaders/fs/text
下一步
您现在已经了解了如何使用缓存来避免重新计算嵌入。
接下来,查看有关检索增强生成的完整教程。