手记

Vertex AI上下文缓存与Gemini模型详解

利用缓存可以让您的 Gemini 输入最多节省四倍费用。

上下文缓存机制旨在优化生成模型中大型上下文窗口的处理过程。它允许在多个请求中重复利用已计算的标记,从而有效地减少了每次新请求时重复计算重要输入上下文的需求。

这对于处理大量的文档、视频文件和较长的系统提示特别有帮助,比如采用上下文学习的方法时。

咱们先说说好处
  1. 节省成本:通过将计算出的标记存储在内存里,你只需要为最初的计算付费,并只需支付少量费用来存储这些缓存标记,而不是为每个请求重新计算这些标记。

只有一个小好处。许多文章声称响应时间(速度)大幅减少,但这并不属实。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)
  • 在你可以使用缓存之前,你需要至少32k个令牌才能使用缓存。

  • 最棒的是,缓存允许函数调用以及系统指令

缓存支持所有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频道 ❤️

0人推荐
随时随地看视频
慕课网APP