Skip to main content

缓存

LangChain为LLMs提供了一个可选的缓存层。这有两个用途:

如果您经常多次请求相同的完成结果,它可以通过减少对LLM提供者的API调用次数来节省费用。它可以通过减少对LLM提供者的API调用次数来加快应用程序的速度。

import langchain
from langchain.llms import OpenAI

# 为了使缓存更明显,让我们使用一个较慢的模型。
llm = OpenAI(model_name="text-davinci-002", n=2, best_of=2)

内存缓存

from langchain.cache import InMemoryCache
langchain.llm_cache = InMemoryCache()

# 第一次调用时,它还没有在缓存中,所以需要更长时间。
llm.predict("Tell me a joke")

# CPU times: user 35.9 ms, sys: 28.6 ms, total: 64.6 ms
# Wall time: 4.83 s

# "\n\n为什么自行车不能自己站起来?因为它...太累了!"

第二次调用时,它已经在缓存中,所以速度更快。

llm.predict("Tell me a joke")

# CPU times: user 238 µs, sys: 143 µs, total: 381 µs
# Wall time: 1.76 ms

# "\n\n为什么鸡会过马路?\n\n为了到达另一边。"

SQLite缓存

rm .langchain.db

# 我们可以使用SQLite缓存做同样的事情
from langchain.cache import SQLiteCache
langchain.llm_cache = SQLiteCache(database_path=".langchain.db")

# 第一次调用时,它还没有在缓存中,所以需要更长时间。
llm.predict("Tell me a joke")

# CPU times: user 17 ms, sys: 9.76 ms, total: 26.7 ms
# Wall time: 825 ms

# "\n\n为什么鸡会过马路?\n\n为了到达另一边。"

第二次调用时,它已经在缓存中,所以速度更快。

llm.predict("Tell me a joke")

# CPU times: user 2.46 ms, sys: 1.23 ms, total: 3.7 ms
# Wall time: 2.67 ms

# "\n\n为什么鸡会过马路?\n\n为了到达另一边。"

链中的可选缓存

您还可以关闭链中特定节点的缓存。请注意,由于某些接口的限制,先构建链,然后再编辑LLM通常更容易。

作为示例,我们将加载一个summarizer的map-reduce链。我们将对map步骤进行缓存,但对combine步骤不进行冻结。

llm = OpenAI(model_name="text-davinci-002")
no_cache_llm = OpenAI(model_name="text-davinci-002", cache=False)

from langchain.text_splitter import CharacterTextSplitter
from langchain.chains.mapreduce import MapReduceChain

text_splitter = CharacterTextSplitter()

with open('../../../state_of_the_union.txt') as f:
state_of_the_union = f.read()
texts = text_splitter.split_text(state_of_the_union)

from langchain.docstore.document import Document
docs = [Document(page_content=t) for t in texts[:3]]
from langchain.chains.summarize import load_summarize_chain

chain = load_summarize_chain(llm, chain_type="map_reduce", reduce_llm=no_cache_llm)

chain.run(docs)

# CPU times: user 452 ms, sys: 60.3 ms, total: 512 ms
# Wall time: 5.09 s

# "\n\n拜登总统正在讨论美国救援计划和两党基础设施法案,这将创造就业机会并帮助美国人民。"

当我们再次运行它时,我们可以看到它运行得更快,但最终的答案不同。这是由于在map步骤进行了缓存,但在reduce步骤没有进行缓存。

chain.run(docs)

# CPU times: user 11.5 ms, sys: 4.33 ms, total: 15.8 ms
# Wall time: 1.04 s

# "\n\n拜登总统正在讨论美国救援计划和两党基础设施法案,这将创造就业机会并帮助美国人民。"
rm .langchain.db sqlite.db