利用缓存可以让您的 Gemini 输入最多节省四倍费用。
上下文缓存机制旨在优化生成模型中大型上下文窗口的处理过程。它允许在多个请求中重复利用已计算的标记,从而有效地减少了每次新请求时重复计算重要输入上下文的需求。
这对于处理大量的文档、视频文件和较长的系统提示特别有帮助,比如采用上下文学习的方法时。
咱们先说说好处- 节省成本:通过将计算出的标记存储在内存里,你只需要为最初的计算付费,并只需支付少量费用来存储这些缓存标记,而不是为每个请求重新计算这些标记。
只有一个小好处。许多文章声称响应时间(速度)大幅减少,但这并不属实。Gemini 缓存只用来节省成本,并不会减少响应时间。过去几天我们广泛使用了缓存,我没有看到任何响应时间改进的例子。但这没关系。Google 并未声称它会减少响应时间。(如果他们真的这么说,请告诉我,我没找到任何这样的说法。)
直接跳转到笔记本界面及其代码本文中的所有代码已经准备好,可以直接在 Google Colab 笔记本中使用。如果有任何问题,欢迎通过 LinkedIn 与我联系。
Google Colab编辑说明(colab.research.google.com)[https://colab.research.google.com/drive/1rAg14spJLqAYss4nAu7fUaY6cpfExs0E?usp=sharing&source=post_page-----189117418b67--------------------------------)
这篇文章是周五直播系列的第 8 部分。你可以通过链接观看所有之前的录播。每个星期五上午 10-11:30 CET / 8-10:30 UTC ,欢迎准时加入我们的直播。
使用缓存上下文我喜欢谷歌实现的那个功能,觉得他们做得很好。我们首先直接缓存我们要处理的对象,这么做比较实际。
system_instruction = """
你是一位视频分析专家,根据你所分析的视频文件回答用户的问题。始终用Markdown格式回复。
"""
contents = [
Part.from_uri(
mime_type="video/mp4",
uri="gs://doit-ml-demo/gemini/caching/video/Getting started with Gemini on Vertex AI.mp4")
]
cached_content = caching.CachedContent.create(
#model_name="gemini-1.5-pro-001",
model_name="gemini-1.5-flash-001",
system_instruction=system_instruction,
contents=contents,
ttl=datetime.timedelta(minutes=60),
)
cache_name = cached_content.name
print(cache_name)
缓存支持所有Gemini支持的MIME类型
你也可以输出更多关于该缓存的详细信息,这在查看缓存的expireTime
时特别有用的功能。
cached_content = caching.CachedContent(cached_content_name=cache_name)
print(cached_content)
<vertexai.caching._caching.CachedContent 对象为 0x7b942ce42e00>: {
“name”: “projects/sascha-playground-doit/locations/us-central1/cachedContents/5733786013084418048”,
“model”: “projects/sascha-playground-doit/locations/us-central1/publishers/google/models/gemini-1.5-pro-001”,
“createTime”: “2024年07月01日18时47分59秒”,
“updateTime”: “2024年07月01日18时47分59秒”,
“expireTime”: “2024年07月01日19时47分59秒”
}
使用上下文缓存功能
为了对比Gemini在有缓存和无缓存时的使用情况,让我们进行一下比较。
# 无缓存的Gemini
model = GenerativeModel("gemini-1.5-pro-001")
response = model.generate_content("prompt")
# 有缓存的Gemini
model = GenerativeModel.from_cached_content(cached_content=cached_content)
你可以看到,我们使用了 from_cache_content
函数,这个函数包含了生成缓存时所用模型的引用。
如果需要,你可以延长缓存内容的过期时间。
- 在不带参数的情况下创建缓存时,默认缓存时间为60分钟。
- 您可以随意缓存,没有缓存时间上限。
cached_content.update_expiration(ttl=datetime.timedelta(minutes=3000)) # 更新缓存内容的过期时间,设置为50小时
有费用产生
缓存是根据缓存存在的时间(以小时计)来计费的。根据您使用哪种类型(图片、文本、视频或音频),价格会有所不同。
双子星闪存缓存存储的定价。请访问定价页面查看最新价格:https://cloud.google.com/vertex-ai/generative-ai/pricing#context-caching_。
此外,我们还需要为输入付费,和使用Gemini(一款软件或服务)时一样。然而,当我们使用缓存内容时,成本会降低。
假设我们有一个输入,包含 prompt_token_count
为 85208 个 token,并且我们使用 Gemini 1.5 Flash。
- 没有缓存时的成本
0.042604美元 ($) - 有缓存时的成本
0.010651美元 ($)
使用缓存可以让成本降低大约75%,换句话说,可以将你的Gemini的输入成本最多减少到原来的四分之一。
指标混乱需要对这些指标有更明确的说明。让我们仔细看看这个问题,以彻底避免任何混淆。我们可以用 usage_metadata
打印输入和输出的令牌数。
response = model.generate_content("解释一下这篇研究论文的细节")
print(response.usage_metadata)
这给我们带来了像这样的回答:
- candidates_token_count: 152
这是模型输出响应中的输出/响应令牌数量。启用缓存时,这个数字不会发生变化。 - prompt_token_count: 42638
这是发送给模型的提示。即使启用了缓存,这个数字仍然是提示的总令牌数。缓存不会减少提示中使用的令牌数量。启用缓存时,这里也不会有变化。 - total_token_count: 42790
两者加起来。
许多人不明白为什么使用缓存时提示的令牌计数没有减少。这是因为输入仍然是相同的。它已经被缓存,无需再次计算。因此,我们对缓存输入令牌的定价进行了调整。不用担心,一切都没问题。只需记住,你只需支付大约75%的费用,就可以获得相同数量的令牌了。
在选择RAG和缓存之间,哪个更好?如你所见,缓存并不会显著减少响应时间。至少目前,Google的Grounding或者其他RAG方法仍然提供更快的响应速度。然而,如果你有意使用大上下文,缓存是有意义的。某些用例更适合使用缓存,因为模型需要所有输入。通过使用Google的大上下文模型,我们能够访问许多传统检索方法难以实现的用例场景。
在具体情境中学习也称为小样本学习或小样本提示
缓存技术为需要大量上下文学习的应用场景提供了重大突破。我们可以在无需微调模型的情况下,有效使用大量示例,同时保持较低的成本。
谢谢阅读你的反馈和问题对我来说非常重要。你可以在LinkedIn上找到我,或者通过Twitter_@HeyerSascha_与我联系。更好的是,你可以订阅我的YouTube频道 ❤️