原文:
towardsdatascience.com/maximizing-ai-efficiency-in-production-with-caching-a-cost-efficient-performance-booster-9b8afd200efd
免费友链 – 请帮助点赞这篇领英帖子
简介
尽管 AI 应用具有变革潜力,但大约 70%的应用从未进入生产阶段。挑战是什么?成本、性能、安全性、灵活性以及可维护性。在这篇文章中,我们解决两个关键挑战:成本上升和需要高性能——并揭示 AI 中的缓存策略是如何成为解决方案的。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ec45e3dd3d691663582c3004b0970940.png
图片由Possessed Photography在Unsplash提供
成本挑战:当规模遇到费用
运行 AI 模型,尤其是在大规模上,可能会非常昂贵。以 GPT-4 模型为例,处理 100 万个输入标记需要 30 美元,处理 100 万个输出标记需要 60 美元。这些数字会迅速增加,使得广泛采用对许多项目来说是一个财务挑战。
为了更清楚地了解这一点,考虑一个客服聊天机器人,它每天平均处理50,000 个用户查询。每个查询和响应对可能平均包含 50 个标记。在一天之内,这就相当于 2,500,000 个标记,最多 75 百万个输入和 75 百万个输出,一个月下来。在 GPT-4 的价格下,这意味着聊天机器人的所有者每月可能面临大约 2250 美元的输入标记费用和 4500 美元的输出标记费用,总计 6750 美元仅用于处理用户查询。如果你的应用程序非常成功,每天有 50 万个或 500 万个用户查询会怎样呢?
性能范式:实时响应
今天的使用者期望立即得到满足——这是一个传统机器学习和深度学习方法难以满足的需求。生成式 AI 的到来承诺了近乎实时的响应,将用户交互转变为无缝体验。但有时生成式 AI 可能不够快。
考虑同一个用于客户支持的 AI 驱动的聊天机器人服务,旨在提供对客户查询的即时响应。如果没有缓存,每个查询都会实时处理,导致在高峰时段或需要更深入的 AI 分析时,会有几秒到几分钟的延迟。不耐心的用户可能已经关闭了应用程序并寻找其他替代方案。
缓存的魔法:
在 AI 应用的背景下,缓存涉及保存大型语言模型(LLMs)的提示和响应以供将来重用。这种策略不仅减少了响应时间,而且显著降低了与重复模型调用相关的成本。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/de598031c5a7f1881b91c092688a3018.png
为什么你应该在 AI 应用中使用缓存
现在,想象一下在同一个聊天机器人中实现缓存:关于产品推荐、营业时间、退货政策或运费等常见查询在它们的检索增强生成(RAG)过程之后被缓存。当新客户或重复客户询问之前已回答的问题时,聊天机器人会立即从缓存中检索答案,显著减少了通过 LLM 重新处理此查询的成本,并将响应时间从可能几秒缩短到几乎瞬间。
使用 LangChain 探索 AI 应用的先进缓存技术
在审视了挑战并介绍了缓存作为 AI 效率中一个出色的解决方案之后,让我们深入探讨不同的缓存方法,这些方法可以进一步优化性能和成本效益。
然而,缓存不是万能的解决方案。其有效性取决于应用的方法,尤其是在 AI 和自然语言处理的背景下。在这里,我们分析了两种主要的缓存技术:
标准缓存:基础知识
标准缓存涉及存储和检查用户查询与缓存存储中信息之间的精确匹配。这是一个直接的方法,但有时在处理自然语言的细微差别时可能会不足。
示例:如果一个用户询问,“制作披萨的原料是什么?”而另一个查询,“制作披萨的原料是什么?”尽管措辞略有不同,标准缓存可能将这些视为不同的请求,错失了提高效率的机会。
语义缓存:超越精确匹配
语义缓存通过识别和检索与用户查询语义相似的句子来提升缓存机制。这种方法特别适合自然语言环境,其中措辞的变化很常见。
示例:在上文中提到的披萨原料查询中,语义缓存识别了“制作披萨的原料是什么?”和“制作披萨的原料是什么?”之间的意图相似性,为两者提供相同的缓存响应,从而提高了效率。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d0e7e8e52e05482b82fd478a8d864162.png
标准缓存与语义缓存的比较
LangChain 框架中的缓存技术
LangChain 框架支持多种缓存技术,每种技术都适合不同的应用需求和规模。
内存缓存
使用计算机的 RAM 作为临时存储解决方案。它快速实现和访问,但受限于可用内存,并且由于易变性和可扩展性方面的担忧,不适合生产环境。
数据库作为缓存
数据库可以作为强大的缓存解决方案,提供持久性和可扩展性。以下是一些选项:
MongoDB 作为标准缓存和语义缓存:MongoDB 将结构化、非结构化和 AI 数据合并,便于进行高级 AI 应用程序开发。其架构简化了数据处理,加快了项目交付。具有大型数据类型(文本、数字、地理空间、时间序列等)、AI 分析集成以及广泛的 AI 工具兼容性和多云支持,MongoDB 确保了灵活性和快速创新。
SQLite 作为标准缓存:一个轻量级的基于磁盘的数据库,非常适合规模较小的应用程序,其中简单性和最小设置是关键。
Cassandra 作为标准缓存和语义缓存:以其可扩展性和性能著称,Cassandra 非常适合需要高可用性和大规模分布的应用程序。
Astra DB 作为标准缓存和语义缓存:作为云原生 Cassandra-as-a-Service,Astra DB 在管理 Cassandra 数据库方面提供可扩展性和简单性,包括缓存功能。
Azure Cosmos DB 作为语义缓存:仅在 Azure 上可用,但全球分布,多模型数据库服务,提供一键式全球分布,使其适合复杂的缓存需求,包括语义缓存。
外部缓存系统
对于需要高性能和可扩展性的应用程序,外部缓存系统提供专门的解决方案,但请注意,它们并非普通设置。除了您应用程序的全栈之外,还需要更多的努力:
Redis 作为标准缓存和语义缓存:一个内存数据结构存储,用作数据库、缓存和消息代理,Redis 以其速度著称,支持多种数据结构。
GPTCache 作为标准缓存和语义缓存:专门针对缓存生成式预训练变换器的响应而定制,优化了 AI 驱动应用程序的成本和响应时间。
Momento 作为标准缓存:一个完全管理的缓存服务,简化了缓存基础设施,提供可扩展性和易用性,无需广泛的缓存专业知识。
在 LangChain 框架中结合这些缓存技术和技术可以显著提高 AI 应用的效率、速度和成本效益。随着我们不断前进,重点将转向利用内存缓存和 MongoDB 进行缓存,展示选择适合您应用程序特定需求和规模的正确工具的重要性。
使用 LangChain 实现内存缓存
如上所述,内存缓存是最容易的缓存技术之一。以下代码片段展示了使用 LangChain 库和 OpenAI 的 GPT-3.5-turbo 模型实现内存缓存的实际应用。
设置环境
设置涉及从 LangChain 导入必要的模块,包括对 OpenAI 模型和内存缓存机制的支撑。通过初始化InMemoryCache,我们为存储和检索缓存中的响应做好准备,减少了重复调用 API 进行相同查询的需求。
importlangchainimporttimeimportosfromlangchain.llmsimportOpenAIfromlangchain.cacheimportInMemoryCachefromlangchain.callbacksimportget_openai_callbackfromlangchain.chainsimportLLMChain openai_api_key=os.environ["OPENAI_API_KEY"]langchain.llm_cache=InMemoryCache()查询处理和缓存
这种实现的核心在于处理启用缓存的LLM查询。过程很简单:
定义一个问题并将其传递给模型进行处理。
使用
get_openai_callback()上下文管理器来测量执行时间,展示了缓存的高效性。第一次调用通过 GPT-3.5-turbo 处理查询,获取响应并将其存储在缓存中。
随后的相同或相似查询的调用直接从缓存中检索响应,显著减少了响应时间和 API 成本。
llm=OpenAI(model="gpt-3.5-turbo-instruct")question="What are the ingredients to cook a pizza?"withget_openai_callback()ascb:start=time.time()result=llm(question)end=time.time()print(result)print("--- cb")print(str(cb)+f"({end-start:.2f}seconds)")withget_openai_callback()ascb2:start=time.time()result2=llm("What are the ingredients to cook pizzas?")end=time.time()print(result2)print("--- cb2")print(str(cb2)+f"({end-start:.2f}seconds)")withget_openai_callback()ascb3:start=time.time()result3=llm(question)end=time.time()print(result3)print("--- cb2")print(str(cb3)+f"({end-start:.2f}seconds)")观察和结果
结果证明了内存缓存的有效性:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/7fbe01709821d33755a4cfd5cd783ad5.png
第一次执行大约需要 1.24 秒,包括使用的令牌的详细分解和与处理查询相关的成本。这次初始调用由于 API 使用而产生了成本。
第二次执行处理了一个略微不同但非常相似的查询,但仍然通过 API 进行,耗时约 1.16 秒,表明基于精确匹配的缓存不会将此作为相同的查询进行缓存。
第三次执行重新审视了原始问题,由于缓存机制,它几乎瞬间(0.00 秒)检索到答案,处理时间可忽略不计,展示了缓存的高效性。
这种实现清楚地说明了内存缓存对性能和成本效率的显著影响。然而,需要注意的是,这里使用了标准缓存。因此,对于相似但不完全相同的问题,我们仍然通过 API 调用进行,假设类似的查询应该产生类似的响应。
在 AI 应用中集成 MongoDB 进行高级缓存
为什么 MongoDB 适用于 AI 应用?
MongoDB 作为 AI 应用的强大平台,提供了广泛的功能,以满足数据集成、管理和检索的复杂需求。
它能够简化向量和操作数据的集成,对于机器学习和 NLP 任务来说极为宝贵。
MongoDB Atlas,一个完全管理的开发者平台,通过自动化扩展、备份和监控减轻了数据库管理的负担,使开发者能够专注于提升 AI 功能。
MongoDB 的文档型模式提供了所需的灵活性,以适应 AI 数据的动态特性,简化了对数据需求变化的适应,无需进行复杂的模式更改。
MongoDB 的有效搜索能力和专门的向量搜索节点确保了快速的数据检索,这对于有效的缓存和可扩展的 AI 搜索功能至关重要。
支持在主要平台(如 AWS、Azure 和 GCP)上的多云,MongoDB 确保了可扩展性和弹性。
此外,MongoDB Atlas 因其全面的安全特性而备受赞誉,为 AI 应用提供强大的数据保护。
下文概述了将 MongoDB 缓存与 LangChain 框架结合以提升 AI 性能的实施步骤和内在优势。
MongoDB 标准缓存实现
提供的代码片段展示了 MongoDB 与 LangChain 框架无缝集成的示例,用于标准缓存目的。以下是设置 MongoDB 以缓存 AI 查询和响应所涉及的必要步骤的分解:
- 环境设置:
MongoDB Atlas 集群 URI 通过环境变量安全存储和访问,确保敏感信息得到保护。
importosfrompymongoimportMongoClientfromlangchain.llmsimportOpenAIfromlangchain_mongodb.cacheimportMongoDBCachefromlangchain_core.globalsimportset_llm_cachefromlangchain_openaiimportOpenAIEmbeddingsfromlangchain.callbacksimportget_openai_callbackimporttime openai_api_key=os.environ["OPENAI_API_KEY"]llm=OpenAI(model="gpt-3.5-turbo-instruct")2. MongoDB 客户端初始化:
使用 MongoDB Atlas 集群 URI 实例化 MongoDB 客户端,建立与数据库服务器的连接。缓存配置:MongoDBCache类配置了 MongoDB 连接细节,包括数据库名(langchain_db)和集合名(langchain_cache)。此设置指定了缓存在 MongoDB 数据库中的存储和检索位置。
MONGODB_ATLAS_CLUSTER_URI=os.getenv('MONGO_URI')# initialize MongoDB python clientclient=MongoClient(MONGODB_ATLAS_CLUSTER_URI)COLLECTION_NAME="langchain_cache"DATABASE_NAME="langchain_db"question="What are the ingredients to cook a pizza?"3. 缓存逻辑:
来自langchain_core.globals模块的set_llm_cache函数将MongoDBCache集成为 LangChain 框架的标准缓存机制。这种集成允许自动缓存由 AI 模型生成的查询和响应,在本例中为 OpenAI 的 GPT-3.5-turbo-instruct 模型。
set_llm_cache(MongoDBCache(connection_string=MONGODB_ATLAS_CLUSTER_URI,collection_name=COLLECTION_NAME,database_name=DATABASE_NAME,))4. 查询处理:
当查询通过llm函数(代表 AI 模型)处理时,系统首先检查 MongoDB 缓存中是否存在现有响应。如果找到缓存的响应,则立即返回,无需再次调用 AI 模型,从而节省处理时间和 API 调用成本。
5. 性能测量:
使用get_openai_callback包装器来测量和输出每个查询的执行时间,说明了缓存带来的效率提升。后续查询,尤其是相同或相似的查询,由于从缓存中检索响应,响应时间显著减少。
观察和结果
如以下图所示:
第一次运行产生了成本和令牌使用,突出了初始 API 调用的费用。
第二次尝试,尽管查询略有改变,但由于标准缓存的精确匹配,仍然触发了 API 调用,绕过了潜在的缓存优势。
然而,第三次运行重新发送初始问题并利用标准缓存,几乎瞬间(0.00 秒)提供答案,从而说明了缓存机制的效率。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/b533c3dab0fc0f960322fca56890a57f.png
MongoDB 标准缓存的结果
MongoDB 语义缓存实现
在 AI 驱动应用程序中实现 MongoDB Atlas 语义缓存代表了在优化响应准确性和速度方面的重要飞跃。这种方法利用了向量嵌入的力量和 MongoDB 强大的数据库管理功能,以创建一个语义缓存层。
提供的代码片段及其结果是对这种高级缓存机制的实际演示。
- OpenAI 和 MongoDB 客户端的初始化
该过程从初始化 OpenAI 模型和 MongoDB 客户端开始,连接到 MongoDB Atlas 集群 URI。这种设置构成了将 AI 模型响应与 MongoDB 缓存系统集成的基础。
2. 基于向量嵌入的语义缓存
通过使用OpenAIEmbeddings,实现生成了文本输入的向量嵌入,这对于语义分析至关重要。这些嵌入捕捉了查询的细微含义,允许进行比传统文本匹配更复杂的比较。
importosfrompymongoimportMongoClientfromlangchain.llmsimportOpenAIfromlangchain_community.llmsimportOpenAIfromlangchain_mongodb.cacheimportMongoDBCachefromlangchain_core.globalsimportset_llm_cachefromlangchain_openaiimportOpenAIEmbeddingsfromlangchain.callbacksimportget_openai_callbackimporttimefromlangchain_mongodb.cacheimportMongoDBAtlasSemanticCache openai_api_key=os.environ["OPENAI_API_KEY"]llm=OpenAI(model="gpt-3.5-turbo-instruct")embeddings=OpenAIEmbeddings(model="text-embedding-3-large",dimensions=1024)MONGODB_ATLAS_CLUSTER_URI=os.getenv('MONGO_URI')# initialize MongoDB python clientclient=MongoClient(MONGODB_ATLAS_CLUSTER_URI)COLLECTION_NAME="langchain_Semantic_cache"DATABASE_NAME="langchain_db"INDEX_NAME="vector_index"3. MongoDB Atlas 语义缓存配置
MongoDBAtlasSemanticCache类配置了必要参数,包括连接字符串、集合名称、数据库名称,以及如下所示的与向量嵌入索引对应的索引名称。
此配置对于启用语义缓存至关重要,其中查询嵌入之间的相似性决定了缓存命中。
set_llm_cache(MongoDBAtlasSemanticCache(embedding=embeddings,connection_string=MONGODB_ATLAS_CLUSTER_URI,collection_name=COLLECTION_NAME,database_name=DATABASE_NAME,index_name=INDEX_NAME,wait_until_ready=True# Optional, waits until the cache is ready to be used))4. MongoDB Atlas 语义匹配索引定义
索引配置,详细说明了numDimensions和path等字段,指定了向量嵌入如何在 MongoDB 中存储和搜索。将similarity设置为“余弦”确保搜索机制理解并利用向量之间的语义邻近性来找到最佳匹配。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/1634f8969663a9ae313a618494dd25c0.pnghttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/acfa6f2740e5b414295a18afa3267352.png
{"fields":[{"numDimensions":1024,"path":"embedding","similarity":"cosine","type":"vector"},{"path":"llm_string","type":"filter"}]}5. 查询处理和缓存
像这样的查询“如何制作披萨?”通过 AI 模型进行处理,并生成其嵌入。MongoDB Atlas 语义缓存根据这些嵌入检查是否存在类似的查询,例如**“制作披萨的配料有哪些?”**。如果找到匹配项,则检索缓存的响应,显著加快响应时间,同时从 AI 模型中不使用任何额外的标记。
question="How to make a pizza ?"similar_question="What are the ingredients to cook pizzas"withget_openai_callback()ascb:start=time.time()result=llm(question)end=time.time()print(result)print("--- cb")print(str(cb)+f"({end-start:.2f}seconds)")time.sleep(5)withget_openai_callback()ascb2:start=time.time()result2=llm(similar_question)end=time.time()print(result2)print("--- cb2")print(str(cb2)+f"({end-start:.2f}seconds)")time.sleep(5)withget_openai_callback()ascb3:start=time.time()result3=llm(question)end=time.time()print(result3)print("--- cb3")print(str(cb3)+f"({end-start:.2f}seconds)")6. 证明效率
如回调输出中所示,执行时间展示了使用语义缓存带来的效率提升。
最初生成和缓存嵌入和响应的查询需要稍微长一点的时间,
第二个相似但不同的查询几乎即时服务,展示了缓存的有效性。第二个查询没有使用任何标记,总成本为$0.0。
第三次查询由于我们能够找到这个查询的精确匹配,因此也以缓存的方式即时服务。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/7e08f4c689998ccfe8f1e77eea1b5d43.png
语义缓存的结果
商业案例比较:AI 应用的缓存策略
想象一家运营客户服务聊天机器人的企业,该聊天机器人处理各种客户查询,从产品信息、故障排除到订单处理。这个聊天机器人由像 OpenAI 的 GPT 4 这样的复杂 AI 模型驱动,每天平均处理 10 万次查询,每次查询及其响应的平均标记数约为 50。
不使用缓存
成本:高,每月 API 调用费用为 13,500 美元。
性能:较慢,响应时间有变化。
可扩展性:随着查询量的增加,在财务上具有挑战性。
使用标准缓存
成本降低:由于从缓存中服务了 30%的重复查询,成本明显降低,每月降至约 9,450 美元。
性能:重复查询的性能得到提升。
局限性:对于略有变化的查询无效。
使用语义缓存
成本效率:最大化,通过缓存 60%的查询(包括变体),可能将每月成本降低至 5,400 美元。
性能:对更广泛的查询范围提供近乎即时的响应。
可扩展性:增强,减少了直接调用 AI 模型。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e6bc92059b65d2910e4fc1d00ab141a1.png
模拟商业案例结果
结论
从不使用缓存过渡到使用语义缓存,显著提高了 AI 应用的操作效率和成本效益。语义缓存不仅通过更快的响应提供优越的用户体验,而且通过有效地处理查询变体,确保了可扩展性和财务可行性。
致谢
目前在 MongoDB 担任解决方案架构师,我想特别感谢我的同事,Prakul Agarwal,AI/ML 产品经理,他的宝贵产品见解,以及感谢Christophe Locoge分享关于企业及公司挑战的见解,这些见解来自与我们的客户的讨论。
在你离开之前!🦸🏻♀️
如果你觉得这篇文章有价值,并希望表达你的支持,**请‘点赞’这篇 LinkedIn 帖子。你还可以在 LinkedIn 帖子中找到免费友链。**你的参与将帮助扩大这篇文章的传播范围,你的支持对我来说是一个巨大的激励。✍🏻 🦾❤️
为我的文章鼓掌 50 次,这真的会对我有很大帮助,并推动这篇文章被更多人看到。👏
关注我在Medium ,LinkedIn上的动态,并订阅以获取我的最新文章🫶
如果你对这个话题感兴趣,你还可以阅读以下文章:
Gen AI 项目背后的全面 LLM 技术成本分析
无代码 GenAI 代理工作流程编排:AutoGen Studio 与本地 Mistral AI 模型
为什么高级 RAG 方法对 AI 的未来至关重要?
多模态 AI 是零售的未来吗?
MongoDB Atlas | 🦜️🔗 LangchainMo_ngoDB Atlas 是一个完全托管的云 Python.langchain.com