生成式人工智能是人工智能中发展迅速的一个分支,最近因其可能给各行各业带来变革而备受关注。GCP 坚定不移地致力于实现生成式人工智能的民主化,强调在严格的安全协议、有效的数据管理和可扩展性的支持下采用技术。GCP 的与众不同之处在于其综合产品,将可访问的基础模型、可扩展的基础设施以及一整套调整、部署和维护工具结合在一起。
生成式人工智能和 LLM 讨论中经常出现的一个关键术语是 "语义缓存",尤其是在谈到优化话题时。尽管已经有了 GPT Cache、LangChain 等开放式框架,但这一概念仍需引起注意。对于使用语言模型的开发人员来说,延迟和成本是巨大的挑战。高延迟会损害用户体验,而成本上升则会阻碍可扩展性。
请考虑以下场景: 你开发的 GenAI 应用程序获得了巨大的发展,每天都要处理大量的 API 调用。你注意到,用户经常会提出类似的查询,而这些查询之前都已处理过。然而,与 LLM 的每次交互都会产生多余令牌的成本,从而导致用户体验不佳。
这就是语义缓存的作用所在。它允许对重复的语义类似查询进行缓存响应,从而无需求助于人工智能提供商。这就节省了成本,减少了延迟。
语义缓存为 LLM 带来了几个关键优势。
这一系列优势使得语义缓存成为扩展和提高 LLM 应用程序或管道效率的重要优化策略。
缓存的演变--从标准向语义过渡
缓存是提高 LLM 或任何应用的速度和计算效率的关键技术。传统的缓存方法可存储并快速检索预生成的响应,用于 LLM 生成式人工智能的重复查询,从而大大减少计算负荷和响应时间。然而,在不断变化的人类语言领域,精确的查询匹配是很少见的。这就是语义缓存发挥作用的地方。
语义缓存通过解释和利用查询的基本语义来工作。它能识别并获取在语义上与输入查询相关的缓存响应,从而增加缓存命中的机会,改善响应时间和资源利用率。这种方法尤其适用于用户对类似查询使用不同措辞的情况,例如财务报告搜索。语义缓存可以避免多余的计算,快速准确地响应此类查询,从而提高 LM 应用程序的性能。
它标志着从传统的基于关键字的缓存向考虑查询语义意图或上下文的方法过渡。例如,如果给出两个措辞不同但意图相同的提示--"给我看年度财务报告 "和 "我需要年度财务报表"--语义缓存会识别出相同的意图并提供相似的响应,这是传统缓存无法做到的。
语义缓存:高层视角
在本文中,我们将利用一系列 GCP 服务演示一个功能完备的语义缓存系统。生成式应用的效率取决于强大的高性能数据层。该层能以最小的延迟促进快速交易,确保无缝的用户交互。在我们的文章中,该数据层应缓存预先计算的响应或嵌入,保留先前交互的记录,并执行语义搜索以检索相关上下文或知识。
近年来,矢量数据库在各行各业的 LM 应用程序中发挥了重要作用,因此已成为数据层的有效解决方案。在架构设计中,我们将使用 Vertex AI 向量搜索。这将作为我们的矢量数据库,用于以下两方面:a) 创建金融文档集合的语义索引;b) 创建用户查询的语义索引。
我们将使用 Redis 支持的 Memorystore 作为标准缓存。我们将使用云存储(Cloud Storage)作为托管原始数据和处理过的数据以创建索引的首选登陆区。编码后的文档和查询存储在这里。我们将使用两种模型: 1/ 文本生成模型 Gemini 1.0 Pro,以及 2/ Vertex AI 的文本嵌入模型。
我们将首先定义数据集,然后使用 DocumentAI(其他 GCP 人工智能服务)对这些原始文档进行预处理。接下来,我们将了解使用矢量搜索创建语义索引的过程,并学习如何使用 Memorystore 上的 Redis 设置标准缓存。最后,我们将了解如何为整个系统布线,以建立一个可靠的机制。
只要需要调用文本生成的基础模型,语义缓存就可以用于多种生成任务。这些任务的范围可以从问题解答和总结到分类,也可以是自然语言理解/处理任务的任何变体,这些任务都需要可以进行语义推断的文本输入。
在本文中,我们将重点讨论文档问题解答用例。在这种情况下,我们针对经过处理的文档语料库提出一个复杂的问题,从而得出答案。这一过程由两个关键组件推动--一个检索组件和一个由 LLM 支持的生成组件。这就是文档问题解答的标准检索-增强生成(RAG)管道。
数据集
我们将用于实验的数据集包括三家科技公司的季度报告: Alphabet、亚马逊和微软。从 2021 年第一季度到 2023 年第四季度,这个数据集包含 36 份文件(每家公司 12 份),时间跨度为三年。
为便于实验,我们从这些文档中提取了 100 对问答。每对问答都直接链接到单个文档,建立了单跳问答场景。这些问题和答案经过精心设计,侧重于从表格和复杂段落中提取信息,对 RAG 系统提出了巨大挑战。PDF 金融季报数据集可在此处找到。显示问题-答案对数据集的基本事实可在数据文件夹中名为 ground_truth.csvin 的 CSV 文件中找到。
下面是 Alphabet 2020 年第一季度报告中的一个示例表格,总结了主要与营业收入和利润率相关的财务结果。
我们的基本真实 CSV 中的一个问题示例,以及从上表中得出的预期答案。
What was Google's operating income (in billions) at the end of March 2021, and
how did it compare to the same period of the previous year?
Google's operating income was $16.437 billion in Q1 2021. This was an increase
from $7.977 billion in Q1 2020.
文档处理
首先,让我们对财务报告数据集进行预处理。这将为我们的 RAG 管道摄取和索引做好准备。该工作流程的高级概览如下图所示。我们将每份 PDF 报告解析为页面文本,然后使用 DocumentAI 的专用处理器从各个页面中提取表格。然后,将 Markdown 格式的表格合并回这些 PDF 文档中每页提取的文本上下文中。
Google Cloud Document AI 是一个由机器学习驱动的平台,可简化从非结构化和半结构化文档中提取有价值的结构化数据的过程。它提供预建和可定制的模型以及 OCR 和 NLP 功能,可实现文档处理自动化、提高效率并增强决策能力。它可与其他谷歌云服务无缝集成,以便进一步分析和采取行动。
以下是 Alphabet 2021 年第一季度报告第 1 页的表格示例。
下面是使用 PyPDF 解析表格时的显示效果。
Quarter Ended March 31,
2020
2021
Revenues
$
41,159
$
55,314
Increase in revenues year over year
13 %
34 %
Increase in constant currency revenues year over year (1)
15 %
32 %
Operating income
Operating margin
Other income (expense), net
$
7,977
$
16,437
19 %
30 %
(220)
$
4,846
Net income
$
6,836 $
17,930
Diluted EPS
9.87 $
26.29
(1)
有了 DocumentAI,我们可以提取出同一文本的更简洁版本,同时保持空间信息和结构的完整性。然后,这个标记语言版本的表格会被合并回文档的提取文本中。
| | ('',) | ('Quarter Ended March 31, 2020 2021',) |
|---:|:----------------------------------------------------------|:-----------------------------------------|
| 0 | Revenues | 41,159 $ 55,314 |
| 1 | Increase in revenues year over year | 13 % 34 % |
| 2 | Increase in constant currency revenues year over year (¹) | 15 % 32 % |
| 3 | Operating income | SA 7,977 $ 16,437 |
| 4 | Operating margin | 19 % 30 % |
| 5 | Other income (expense), net | SA (220) 4,846 |
| 6 | Net income | $ 6,836 17,930 |
| 7 | Diluted EPS | $ 9.87 $ 26.29 |
你可以先运行 create.py,创建 DocumentAI OCR 处理器。然后运行 parse.py 和 parse_tables.py。最后,运行 merge.py,将提取的页面文本内容与提取和转换的表格(markdown 格式)合并为每个页面的单个文本文件。
接下来,我们将探索如何从财务报告中提取处理过的页面,并使用 Vertex AI 的文本嵌入模型将其编码为嵌入式内容。更重要的是,我们将使用 Vertex AI 的向量搜索对嵌入进行语义索引。
组装语义索引管道
在开始索引过程之前,让我们先了解一下什么是 Vertex AI、什么是 Agent Builder 以及向量搜索在其中的作用。
Vertex AI Agent Builder 是一个全面的人工智能平台,可以简化人工智能代理的开发和部署,适用于各种应用。无论你需要对话界面、智能搜索功能还是自动化工作流,Agent Builder 都能提供创建定制解决方案的工具。
该平台与 Vertex AI Search、Vertex AI Conversation 和 Vector Search 等核心组件无缝集成。Vertex AI Search可对结构化和非结构化数据编制索引,从而无需大量人工即可开发复杂的问题解答系统和知识库。Vertex AI Conversation 可帮助创建聊天机器人多转弯,并与搜索和其他路由功能紧密集成。
对于更高级的搜索用例,Vertex AI 提供矢量搜索。它使开发人员能够构建基于嵌入式的自定义 RAG 管道,释放语义搜索和增强信息检索的潜力。将 Vector Search 视为一个可管理的矢量数据库,你可以在其中对嵌入进行索引和搜索。它提供应用程序接口,用于创建、上插、删除和刷新索引,以及与索引进行匹配。
Agent Builder 既适合技术用户,也适合非技术用户。它提供了直观的无代码工具,可轻松创建代理,同时还提供了用于定制和微调的编程访问。回复可基于特定的数据源,或通过谷歌搜索从网上获取实时信息。Agent Builder 具有企业级安全性,并与其他谷歌云服务无缝集成,是一个多功能、安全的平台,可用于构建各种智能代理,同时确保数据隐私和合规性。
在本文章中,我们将使用矢量搜索(Vector Search)为数据集中的预处理页面和数据存储库中基本真实评估集中的用户查询创建语义索引。
要创建文档页面的语义索引,我们首先要从文档处理步骤中处理过的页面开始。然后使用文本嵌入应用程序接口(Text Embedding API)将这些页面编码为页面嵌入(下图中的步骤 1)。编码后的数据被推送到云存储(步骤 2)。然后,我们利用用于矢量搜索的 Vertex AI API 来摄取这些数据并为页面嵌入建立索引(步骤 3)。
create.pyc 使用用户定义的配置创建空语义索引。然后,我们使用 batch_encode.py,将预处理过的页面批量编码为嵌入式内容。最后,我们运行 deploy.py 创建一个私有端点,用于匹配针对该索引的查询。该脚本还将编码数据部署到之前创建的语义索引中,用于文档搜索。
接下来,让我们为文档问题解答系统中的一些用户查询创建一个语义索引。为此,我们将使用位于此处的基本真实评估集中的问题。
这个工作流程与上文提到的文档页面索引创建类似,只不过我们使用的是问题而不是页面。
注意:如果我们没有任何预期的查询(问题),我们可以从一个空索引开始。一般建议查看系统的历史使用模式或分析,并编制一份最频繁、最多样化和最独特的查询列表,以便在流程开始时先行一步。一旦我们建立了语义缓存的端到端工作流程,你就会发现我们也会将新查询上载到该索引中。
考虑到我们需要将查询动态地插入该索引,我们创建索引时将其设置为流类型。通过流式更新,你可以在几秒钟内更新和查询你的索引。
编码查询、创建查询索引和索引端点的所有代码示例都封装在此代码库中。
一旦建立了文档(在我们的例子中是页面)索引和查询索引,我们就可以在 Vector Search 控制台中使用这两种索引,如下图所示。
标准缓存设置
接下来,让我们看看如何设置标准缓存来捕捉问答对。我们可以将其用于端到端整体架构。为此,我们将使用 Memorystore。
Google Cloud Memorystore 是一种完全托管的内存数据存储服务,擅长缓存数据以提高实时应用程序的性能和响应速度。通过将频繁访问的数据存储在内存中,Memorystore 可提供亚毫秒级的延迟和高可用性。它支持 Redis 和 Memcached 协议,可无缝扩展以处理不断增长的工作负载,同时与其他 GCP 服务顺利集成。
通过 GCP 控制台设置该缓存相对简单。请确保已启用必要的 API 进行设置。在我们的练习中,我们基本上可以设置一个不带任何副本、内存最小为 4GB 的基本实例。
我们还要用问题-答案对来填充缓存。我们将使用之前用来创建语义索引的、来自地面实况测试集的同一组问题。但现在,我们将不再对问题进行编码,而是创建问题的唯一哈希值。这个哈希值将作为键,而实际的原始问题(文本)将作为值插入缓存。
接下来,对问题使用相同的哈希值 id,但在哈希值中添加 "ans: "前缀。以此为键插入相关答案。下图说明了这一过程。
你可以执行位于 src/redis 目录中的 load.pyl,预加载包含问答对的标准缓存。
在 Google 云平台上连接 Memorystore 时,通常需要使用端口转发功能,以便从本地机器安全地访问 Redis 云实例。这个过程包括设置一个小型虚拟机,作为本地环境和远程 Memorystore 服务之间的桥梁。下面是设置方法:
首先,运行以下命令在谷歌云项目中创建一个新的计算实例:
$ gcloud compute instances create 'redis-forwarder' --machine-type=f1-micro --zone=us-central1-a --project=your-project-idcreate 'redis-forwarder' --machine-type=f1-micro --zone=us-central1-a --project=your-project-id
将 your-project-id 替换为实际的 Google 云项目 ID。该实例将作为转发器。
接下来,与实例建立安全的 SSH 连接,并将本地端口转发到 Memorystore Redis 实例:
$ gcloud compute ssh redis-forwarder --zone=us-central1-a -- -N -L 6379:[Memorystore_IP]:6379--zone=us-central1-a -- -N -L 6379:[Memorystore_IP]:6379
将 [Memorystore_IP] 替换为 Memorystore Redis 实例的 IP 地址。这条命令会将本地端口 6379 映射到 Memorystore Redis 实例的端口 6379,使你可以像在本地运行一样与 Redis 数据库交互。
这种使用端口转发的方法对于保持安全连接和确保数据交易受到保护至关重要,尤其是在从本地开发环境访问云资源时。
连接各点--协调端到端工作流程
如果你已经走到了这一步,那么你应该已经成功地设置了所有必要元素,以构建一个全面的端到端工作流程,在文档答疑系统的范围内实施语义缓存。这一整体工作流程可细分为两个主要途径:一个侧重于精确匹配,另一个侧重于语义匹配。
精确匹配
考虑这样一种情况:系统可能会再次遇到来自同一用户或不同用户的相同搜索查询(问题)。当搜索查询较短且重复出现的几率较高时,通常会出现这种情况。在这种情况下,如果新收到的查询与缓存中已有的查询完全匹配,我们就可以直接从标准缓存中获取答案,而不是按照常规流程对搜索查询进行编码并与文档索引进行语义匹配。下图说明了这一过程。
如图所示,用户首先提出一个问题。然后,我们计算问题的哈希值,并检查标准缓存中是否存在哈希键。如果存在,我们会重新使用带有 "ans: "前缀的相同哈希值,生成一个新的哈希 ID,用于直接从缓存中提取答案。如果密钥不存在,我们就会返回到下一个机制,为输入的查询寻找语义匹配候选,这将在下文中讨论。
语义匹配
现在,让我们来探讨一下整体工作流程,看看语义匹配是如何与之前讨论过的精确匹配场景整合在一起的。如下图所示,我们将逐步分解所有工作流程。
qa.py包中的模块src/run说明了在一个工作编排中组合在一起的完整工作流程。
增强功能和附加功能
接下来,让我们研究一下可以对架构进行哪些改进。这些改进可能包括可以以不同方式实现的内容或对当前状况的改进。我们还建议进行额外的练习以更好地阐明这些内容。
进行测试:验证工作流程
现在我们了解了架构,并设置了问答 RAG 管道的所有先决条件,并使用语义缓存进行了优化,我们可以开始测试系统了。我们已经取得了重大进展!
让我们开始测试各种场景,以评估系统的精确匹配和语义匹配能力。此过程应包括预期结果以及系统如何处理极端情况的考虑。
测试 1
对于test 1,我们从基本事实问答对中的一个简单问题开始——“截至 2021 年 3 月底,谷歌的营业收入是多少(十亿美元),与去年同期相比如何? ” 这个问题已经填充到标准缓存中,也是我们之前设置的语义索引中的问题列表的一部分。根据我们的端到端架构,我们要做的第一件事是在标准缓存中寻找完全匹配。我们对问题进行哈希处理,并在内存存储中检查密钥。由于我们已经有了这个密钥,我们会立即检索答案并将其返回给用户。这个过程在上面的完全匹配部分中已经讨论过。在这种情况下,检索时间是最快的,大约为53 ms。
2024-06-07 12:05:48,703 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/utils.py]: MD5 hash generated for input: What was Google's operating income (in billions) at the end of March 2021, and how did it compare to the same period of the previous year? - Hash: 56fda240d018fdf8c73436229d47454e
2024-06-07 12:05:48,755 [INFO] [manager] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/redis/manager.py]: Answer retrieved for hash 56fda240d018fdf8c73436229d47454e: Google's operating income was $16.437 billion in Q1 2021. This was an increase from $7.977 billion in Q1 2020.
2024-06-07 12:05:48,755 [INFO] [exact] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/exact.py]: Redis retrieval time = 52.86216735839844 ms
{'question': "What was Google's operating income (in billions) at the end of March 2021, and how did it compare to the same period of the previous year?", 'closest_question': 'NA', 'match_type': 'EXACT', 'confidence': 'NA', 'answer': "Google's operating income was $16.437 billion in Q1 2021. This was an increase from $7.977 billion in Q1 2020.", 'execution_time': 52.92701721191406}
测试 2
接下来,我们利用 Gemini 创建用于 的相同问题的语义变体test 1。鉴于这个变体问题不是完全匹配,我们期望它在语义上与前一个问题相似。此问题导致缓存未命中,然后对其进行散列、编码,并与过去问题的语义索引进行匹配。我们期望最佳匹配与用于 的问题相同test 1。获得这个最佳匹配后,我们将使用问题的哈希 ID 从标准缓存中检索答案作为完全匹配。我们发现返回答案的总时间略高,大约1919 ms(~2 秒),因为我们正在进行一次语义匹配和两次完全匹配调用。请注意,只有当通过语义匹配的最佳匹配等于或超过我们设置的置信度阈值时,我们才会启动第二次完全匹配调用。
2024-06-07 12:05:49,908 [INFO] [qa] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/run/qa.py]: Query variant => What was Google's operating income (in billions) for the first quarter of 2021, and how did it compare to the first quarter of 2020?
2024-06-07 12:05:49,909 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/utils.py]: MD5 hash generated for input: What was Google's operating income (in billions) for the first quarter of 2021, and how did it compare to the first quarter of 2020? - Hash: a8445ce20d1d270dde869f309ffa9ae4
2024-06-07 12:05:49,959 [INFO] [manager] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/redis/manager.py]: No answer found for hash a8445ce20d1d270dde869f309ffa9ae4
2024-06-07 12:05:51,617 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/match/utils.py]: Neighbors found successfully.
2024-06-07 12:05:51,618 [INFO] [semantic] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/semantic.py]: Top match found: {'confidence': 0.956, 'query': "What was Google's operating income (in billions) at the end of March 2021, and how did it compare to the same period of the previous year?"}
2024-06-07 12:05:51,618 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/utils.py]: MD5 hash generated for input: What was Google's operating income (in billions) at the end of March 2021, and how did it compare to the same period of the previous year? - Hash: 56fda240d018fdf8c73436229d47454e
2024-06-07 12:05:51,670 [INFO] [manager] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/redis/manager.py]: Answer retrieved for hash 56fda240d018fdf8c73436229d47454e: Google's operating income was $16.437 billion in Q1 2021. This was an increase from $7.977 billion in Q1 2020.
2024-06-07 12:05:51,670 [INFO] [exact] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/exact.py]: Redis retrieval time = 51.931142807006836 ms
2024-06-07 12:05:51,670 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/utils.py]: MD5 hash generated for input: What was Google's operating income (in billions) for the first quarter of 2021, and how did it compare to the first quarter of 2020? - Hash: a8445ce20d1d270dde869f309ffa9ae4
2024-06-07 12:05:51,827 [INFO] [manager] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/redis/manager.py]: Question and answer stored successfully under hash: a8445ce20d1d270dde869f309ffa9ae4
{'question': "What was Google's operating income (in billions) for the first quarter of 2021, and how did it compare to the first quarter of 2020?", 'closest_question': "What was Google's operating income (in billions) at the end of March 2021, and how did it compare to the same period of the previous year?", 'match_type': 'SEMANTIC', 'confidence': 0.956, 'answer': "Google's operating income was $16.437 billion in Q1 2021. This was an increase from $7.977 billion in Q1 2020.", 'execution_time': 1918.9109802246094}
测试 3
在下一个测试中,我们重复使用相同的语义变体问题 — 根据下面的日志,我们可以看到我们从 Memorystore 获得了精确匹配,并且立即返回了答案。这是因为我们在上一步中将上一个测试中的变体问题与检索到的答案(我们使用了与变体最匹配的问题)一起插入到标准缓存中。
52 ms由于我们直接从 MemoryStore 获取答案,因此这次答案检索速度更快。
2024-06-07 12:05:51,828 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/utils.py]: MD5 hash generated for input: What was Google's operating income (in billions) for the first quarter of 2021, and how did it compare to the first quarter of 2020? - Hash: a8445ce20d1d270dde869f309ffa9ae4
2024-06-07 12:05:51,879 [INFO] [manager] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/redis/manager.py]: Answer retrieved for hash a8445ce20d1d270dde869f309ffa9ae4: Google's operating income was $16.437 billion in Q1 2021. This was an increase from $7.977 billion in Q1 2020.
2024-06-07 12:05:51,879 [INFO] [exact] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/exact.py]: Redis retrieval time = 51.53799057006836 ms
{'question': "What was Google's operating income (in billions) for the first quarter of 2021, and how did it compare to the first quarter of 2020?", 'closest_question': 'NA', 'match_type': 'EXACT', 'confidence': 'NA', 'answer': "Google's operating income was $16.437 billion in Q1 2021. This was an increase from $7.977 billion in Q1 2020.", 'execution_time': 51.631927490234375}
测试 4
在最后的测试中,我们选择一个完全不在真实测试集内的全新查询。此查询既不存在于标准缓存中,也不存在于语义缓存中。接下来,查询将经过前面的步骤,首先检查标准缓存中是否有完全匹配项。然后对其进行编码并与过去问题的语义索引进行匹配,以找到最匹配的类似问题。此查询是特意选择的,与测试集中的先前查询不同且独一无二。因此,它未能达到置信度阈值。因此,它将通过本机路径从页面的语义索引中找到前 3 个匹配页面。然后,它使用问题和上下文通过 Gemini 生成答案。
2024-06-07 12:05:51,879 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/utils.py]: MD5 hash generated for input: How did Alphabet's adjustment in the estimated useful lives of servers and network equipment affect its financial results for the fourth quarter of 2023? - Hash: bae6d9a678dc687767ab1148c7d36255
2024-06-07 12:05:51,932 [INFO] [manager] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/redis/manager.py]: No answer found for hash bae6d9a678dc687767ab1148c7d36255
2024-06-07 12:05:53,653 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/match/utils.py]: Neighbors found successfully.
2024-06-07 12:05:53,654 [INFO] [semantic] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/semantic.py]: Top match found: {'confidence': 0.8316, 'query': "How did Alphabet's non-marketable securities (assets) in Q4 2021 compare to Q4 2020?"}
2024-06-07 12:05:55,265 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/match/utils.py]: Neighbors found successfully.
2024-06-07 12:05:56,744 [INFO] [semantic] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/semantic.py]: Answer generated successfully.
2024-06-07 12:05:57,255 [INFO] [upsert] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/index/query/upsert.py]: Index instance created successfully.
2024-06-07 12:05:57,255 [INFO] [encode] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/index/query/encode.py]: Encoding question: How did Alphabet's adjustment in the estimated useful lives of servers and network equipment affect its financial results for the fourth quarter of 2023?
2024-06-07 12:05:57,256 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/utils.py]: MD5 hash generated for input: How did Alphabet's adjustment in the estimated useful lives of servers and network equipment affect its financial results for the fourth quarter of 2023? - Hash: bae6d9a678dc687767ab1148c7d36255
2024-06-07 12:05:57,698 [INFO] [upsert] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/index/query/upsert.py]: Query encoded into embeddings.
2024-06-07 12:05:57,700 [INFO] [base] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/.vai-semantic-cache/lib/python3.11/site-packages/google/cloud/aiplatform/base.py]: Upserting datapoints MatchingEngineIndex index: projects/390991481152/locations/us-central1/indexes/8030608628903837696
2024-06-07 12:05:58,225 [INFO] [base] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/.vai-semantic-cache/lib/python3.11/site-packages/google/cloud/aiplatform/base.py]: MatchingEngineIndex index Upserted datapoints. Resource name: projects/390991481152/locations/us-central1/indexes/8030608628903837696
2024-06-07 12:05:58,225 [INFO] [upsert] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/index/query/upsert.py]: Datapoint upserted successfully.
2024-06-07 12:05:58,225 [INFO] [utils] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/cache/utils.py]: MD5 hash generated for input: How did Alphabet's adjustment in the estimated useful lives of servers and network equipment affect its financial results for the fourth quarter of 2023? - Hash: bae6d9a678dc687767ab1148c7d36255
2024-06-07 12:05:58,382 [INFO] [manager] [/Users/arunpshankar/Desktop/Projects/VertexAI-Semantic-Caching/src/redis/manager.py]: Question and answer stored successfully under hash: bae6d9a678dc687767ab1148c7d36255
{'question': "How did Alphabet's adjustment in the estimated useful lives of servers and network equipment affect its financial results for the fourth quarter of 2023?", 'closest_question': 'NA', 'match_type': 'NATIVE', 'confidence': 'NA', 'answer': 'The change in accounting estimate resulted in a reduction in depreciation expense of $983 million and an increase in net income of $765 million, or $0.06 per basic and $0.06 per diluted share for the three months ended December 31, 2023.', 'execution_time': 6503.555059432983}
从日志中可以看到,该测试运行时间最长,答案检索耗时约 6504 毫秒(约 6 秒)。
值得注意的是,在我们的实现中,作为语义和本地匹配流程的一部分,我们在返回答案之前分别向语义缓存和标准缓存进行了上插和插入操作。理想情况下,这应该发生在返回答案之后,并且可以并发执行。还要注意的是,计时包括记录步骤的时间。在实际应用中,这应该会运行得更快。显示数字的目的是显示比较差异,而不是测量精确数字。
总结
总而言之,本篇文章主要讨论了在 RAG 管道中为问题解答任务实现功能完备的语义缓存机制。不过,通过重新思考其中的一些组件,所讨论的概念可以很容易地扩展到更多的 NLP/NLU 任务。我们讨论了建立这一架构所需的各个方面,包括设计和代码。