亚马逊云科技向量数据库助力生成式AI成功落地实践探秘(一) ​

随着大语言模型效果明显提升,其相关的应用不断涌现呈现出越来越火爆的趋势。其中一种比较被广泛关注的技术路线是大语言模型(LLM)+知识召回(Knowledge Retrieval)的方式,在私域知识问答方面可以很好的弥补通用大语言模型的一些短板,解决通用大语言模型在专业领域回答缺乏依据、存在幻觉等问题。其基本思路是把私域知识文档进行切片,然后向量化后续通过向量数据库检索进行召回,再作为上下文输入到大语言模型进行归纳总结。

在这个技术方向的具体实践中,知识库可以采取基于倒排和基于向量的向量数据库两种索引方式进行构建,它对于知识问答流程中的知识召回这步起关键作用,和普通的文档索引或日志索引不同,知识的向量化需要借助深度模型的语义化能力、存在文档切分、向量数据模型部署&推理等额外步骤。知识向量化建库即向量数据库过程中,不仅仅需要考虑原始的文档量级,还需要考虑切分粒度,向量维度等因素,最终被向量数据库索引的知识条数可能达到一个非常大的量级,可能由以下两方面的原因引起:

1.各个行业的既有文档量很高,如金融、医药、法律领域等,新增量也很大。

2.为了召回效果的追求,对文档的切分常常会采用按句或者按段进行多粒度的冗余存贮。

这些细节对知识向量数据库的写入和查询性能带来一定的挑战,为了优化向量化知识库的构建和管理,本文基于亚马逊云科技的服务,构建了如下图的知识库构建流程:

1.通过 S3 Bucket 的 Handler 实时触发 Amazon Lambda 启动对应知识文件入库的 Amazon Glue job;

2.Glue Job 中会进行文档解析和拆分,并调用 Amazon Sagemaker 的 Embedding 模型进行向量化;

3.通过 Bulk 方式注入到 Amazon OpenSearch 中去。

并对整个流程中涉及的多个方面,包括如何进行知识向量化、向量数据库调优总结了一些最佳实践和心得。

知识向量化(即向量数据库的原始步骤)的前置步骤是进行知识的拆分,语义完整性的保持是最重要的考量。分两个方面展开讨论。该如何选用以下两个关注点分别总结了一些经验:

a. 拆分片段的方法

关于这部分的工作,Langchain 作为一种流行的大语言模型集成框架,提供了非常多的 Document Loader 和 Text Spiltters,其中的一些实现具有借鉴意义,但也有不少实现效果是重复的。

目前使用较多的基础方式是采用 Langchain 中的 RecursiveCharacterTextSplitter,属于是 Langchain 的默认拆分器。它采用这个多级分隔字符列表 – [“\n\n”, “\n”, ” “, “”] 来进行拆分,默认先按照段落做拆分,如果拆分结果的 chunk_size 超出,再继续利用下一级分隔字符继续拆分,直到满足 chunk_size 的要求。

但这种做法相对来说还是比较粗糙,还是可能会造成一些关键内容会被拆开。对于一些其他的文档格式可以有一些更细致的做法。

FAQ 文件,必须按照一问一答粒度拆分,后续向量化的输入可以仅仅使用问题,也可以使用问题+答案(本系列 blog 的后续文章会进一步讨论)

Markdown 文件,”#”是用于标识标题的特殊字符,可以采用 MarkdownHeaderTextSplitter 作为分割器,它能更好的保证内容和标题对应的被提取出来。

PDF 文件,会包含更丰富的格式信息。Langchain 里面提供了非常多的 Loader,但 Langchain 中的 PDFMinerPDFasHTMLLoader 的切分效果上会更好,它把 PDF 转换成 HTML,通过 HTML 的 <div> 块进行切分,这种方式能保留每个块的字号信息,从而可以推导出每块内容的隶属关系,把一个段落的标题和上一级父标题关联上,使得信息更加完整。类似下面这种效果。

b. 模型对片段长度的支持

由于拆分的片段后续需要通过向量化模型进行推理,所以必须考虑向量化模型的 Max_seq_length 的限制,超出这个限制可能会导致出现截断,导致语义不完整。从支持的 Max_seq_length 来划分,目前主要有两类 Embedding 模型,如下表所示(这四个是有过实践经验的模型)。

这里的 Max_seq_length 是指 Token 数,和字符数并不等价。依据之前的测试经验,前三个模型一个 token 约为 1.5 个汉字字符左右。而对于大语言模型,如 chatglm,一个 token 一般为 2 个字符左右。如果在切分时不方便计算 token 数,也可以简单按照这个比例来简单换算,保证不出现截断的情况。

前三个模型属于基于 Bert 的 Embedding 模型,OpenAI 的 text-embedding-ada-002 模型是基于 GPT3 的模型。前者适合句或者短段落的向量化,后者 OpenAI 的 SAAS 化接口,适合长文本的向量化,但不能私有化部署。

可以根据召回效果进行验证选择。从目前的实践经验上看 text-embedding-ada-002 对于中文的相似性打分排序性可以,但区分度不够(集中 0.7 左右),不太利于直接通过阈值判断是否有相似知识召回。

另外,对于长度限制的问题也有另外一种改善方法,可以对拆分的片段进行编号,相邻的片段编号也临近,当召回其中一个片段时,可以通过向量数据库的 range search 把附近的片段也召回回来,也能保证召回内容的语意完整性。

我们上面提到四个向量数据库模型只是提到了模型对于文本长度的支持差异,效果方面目前并没有非常权威的结论。可以通过 leaderboard 来了解各个模型的性能,榜上的大多数的模型的评测还是基于公开数据集的 benchmark,对于真实生产中的场景 benchmark 结论是否成立还需要 case by case 地来看。但原则上有以下几方面的经验可以分享:

经过垂直领域 Finetune 的模型比原始向量模型有明显优势;

目前的向量化模型分为两类,对称和非对称。未进行微调的情况下,对于 FAQ 建议走对称召回,也就是 Query 到 Question 的召回。对于文档片段知识,建议使用非对称召回模型,也就是 Query 到 Answer(文档片段)的召回;

没有效果上的明显的差异的情况下,尽量选择向量维度短的模型,高维向量(如 openai 的 text-embedding-ada-002)会给向量数据库造成检索性能和成本两方面的压力。

更多的内容会在本系列的召回优化部分进行深入讨论。

真实的业务场景中,文档的规模在百到百万这个数量级之间。按照冗余的多级召回方式,对应的知识条目最高可能达到亿的规模。由于整个离线计算的规模很大,所以必须并发进行,否则无法满足知识新增和向量检索效果迭代的要求。步骤上主要分为以下三个计算阶段。

文档切分并行

计算的并发粒度是文件级别的,处理的文件格式也是多样的,如 TXT 纯文本、Markdown、PDF 等,其对应的切分逻辑也有差异。而使用 Spark 这种大数据框架来并行处理过重,并不合适。使用多核实例进行多进程并发处理则过于原始,任务的观测追踪上不太方便。所以可以选用 Amazon Glue 的 Python shell 引擎进行处理。主要有如下好处:

1.方便的按照文件粒度进行并发,并发度简单可控。具有重试、超时等机制,方便任务的追踪和观察,日志直接对接到 Amazon CloudWatch;

2.方便的构建运行依赖包,通过参数–additional-python-modules 指定即可,同时 Glue Python 的运行环境中已经自带了 opensearch_py 等依赖。

可参考如下代码:

注意:Amazon Glue 每个账户默认的最大并发运行的 Job 数为 200 个,如果需要更大的并发数,需要申请提高对应的 Service Quota,可以通过后台或联系客户经理。

向量化推理并行

由于切分的段落和句子相对于文档数量也膨胀了很多倍,向量数据库模型的推理吞吐能力决定了整个流程的吞吐能力。这里采用 SageMaker Endpoint 来部署向量化模型,一般来说为了提供模型的吞吐能力,可以采用 GPU 实例推理,以及多节点 Endpoint/Endpoint 弹性伸缩能力,Server-Side/Client-Side Batch 推理能力这些都是一些有效措施。具体到离线向量知识库构建这个场景,可以采用如下几种策略:

GPU 实例部署

向量化模型 CPU 实例是可以推理的。但离线场景下,推理并发度高,GPU 相对于 CPU 可以达到 20 倍左右的吞吐量提升。所以离线场景可以采用 GPU 推理,在线场景 CPU 推理的策略。

多节点 Endpoint

对于临时的大并发向量生成,通过部署多节点 Endpoint 进行处理,处理完毕后可以关闭*(注意:离线生成的请求量是突然增加的,Auto Scaling 冷启动时间 5-6 分钟,会导致前期的请求出现错误)*

利用 Client-Side Batch 推理

离线推理时,Client-side batch 构造十分容易。无需开启 Server-side Batch 推理,一般来说 Sever-side batch 都会有个等待时间,如 50ms 或 100ms,对于推理延迟比较高的大语言模型比较有效,对于向量化推理则不太适用。可以参考如下代码:

OpenSearch 批量注入

Amazon OpenSearch 的写入操作,在实现上可以通过 bulk 批量进行,比单条写入有很大优势。参考如下代码:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/166345.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

案例023:基于微信小程序的童装商城的设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

Java常量池理论篇:Class常量池、运行时常量池、String常量池、基本类型常量池,intern方法1.6、1.7的区别

文章目录 Class常量池运行时常量池String常量池基本类型常量池Integer 常量池Long 常量池 加餐部分 Class常量池 每个Class字节码文件中包含类常量池用来存放字面量以及符号引用等信息。 运行时常量池 java文件被编译成class文件之后&#xff0c;也就是会生成我上面所说的 …

webshell之基于框架免杀

thinkphp array_map_recursive函数 array_map_recursive函数分析 这里存在一个call_user_func命令执行函数 免杀效果 B函数 免杀效果 B函数分析 exec函数分析 在exec函数用存在有个类调用&#xff0c;且所有的参数都可控 smarty_php_tag函数 免杀效果 smarty_php_tag函数分析…

【开源】基于Vue.js的数据可视化的智慧河南大屏

项目编号&#xff1a; S 059 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S059&#xff0c;文末获取源码。} 项目编号&#xff1a;S059&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 数据模块 …

打印菱形-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第9讲。 打印菱形&#xff…

周转箱与工具柜的智能化应用

在当今制造业激烈竞争的市场中&#xff0c;6S管理方法作为提高企业竞争力的有力工具&#xff0c;与精益生产中的周转箱和工具柜相结合&#xff0c;将为企业带来更大的优势。通过实施6S管理方法&#xff0c;企业不仅能够提高生产效率、降低成本&#xff0c;还能够改善产品质量、…

GDPU 数据结构 天码行空11

文章目录 数据结构实验十一 图的创建与存储一、实验目的二、实验内容三、【实验源代码】&#x1f37b; CPP版&#x1f37b; c 语言版&#x1f37b; java版 四、【实验结果】五、【实验总结】 数据结构实验十一 图的创建与存储 一、实验目的 1、 理解图的存储结构与基本操作&a…

nf_conntrack内核模块常见问题

nf_conntrack内核模块常见问题 问题描述排查步骤前置条件&#xff1a;启用nf_conntrack内核模块检查nf_conntrack配置 解决办法1:半数减少nf_conntrack buckets的值解决办法2:加倍调大m.min_free_kbytes值解决办法3:Linux社区权威答复-忽略告警 问题描述 内核报错 falling bac…

什么是 npm —— 写给初学者的编程教程

原文链接&#xff1a; 什么是 npm —— 写给初学者的编程教程 自 2009 年以来&#xff0c;Node.js 一直席卷全球。成千上万个系统基于 Node.js 构建&#xff0c;促使开发者在社区宣称“JavaScript 正在吞噬软件”。 Node 成功的主要因素之一是它广受欢迎的软件包管理器——np…

前k个高频单词(C++实现)

前k个高频单词 题目思路代码代码讲解 题目 思路 通过统计字符串的出现次数&#xff0c;并根据出现次数和字典序对字符串进行排序&#xff0c;找出出现频率最高的前k个字符串。使用一个自定义的仿函数作为排序的比较函数&#xff0c;通过map容器进行统计&#xff0c;然后将结果…

前端已死?看看我的秋招上岸历程

背景 求职方向&#xff1a;web前端 技术栈&#xff1a;vue2、springboot&#xff08;学校开过课&#xff0c;简单的学习过&#xff09; 实习经历&#xff1a;两段&#xff0c;但都是实训类的&#xff0c;说白了就是类似培训&#xff0c;每次面试官问起时我也会坦诚交代&…

关于鸿蒙网络请求的问题

https://developer.huawei.com/consumer/cn/forum/topic/0204136145853212268?fid0102683795438680754 鸿蒙OS 代码 import http from ohos.net.http;export const httpUtils (url: string, data: any) > {return new Promise((resolve, reject) > {let httpRequest …

创意设计与个性化定制:酒精壁炉的独特之处

在当今家居装饰的潮流中&#xff0c;人们越来越注重个性化和创意&#xff0c;而酒精壁炉正是在这一趋势中崭露头角。它不仅成为家居的温馨之选&#xff0c;更因其设计的灵活性而成为创意焦点&#xff0c;吸引了越来越多注重家居设计的人群。 酒精壁炉的设计灵活性为家居注入了新…

工作流引擎架构设计

一个应用MIS的系统的架构离不开工作流引擎&#xff0c;具有流程引擎思维的架构人员设计系统的时候就有流程的思维&#xff0c;他区别于过程思维&#xff0c;过程思维开发出来的系统&#xff0c;用户面对的是菜单、模块。而流程思维设计出来的系统就是发起、待办、在途、查询、近…

docker安装nacos,实现和mysql容器的通信

1.下载nacos镜像 docker pull nacos/nacos-server2. 启动nacos 启动命令如下&#xff1a; docker run -d -p 8848:8848 --name nacos \ -e JVM_XMS256m \ -e JVM_XMX256m \ -e MODEstandalone \ -e SPRING_DATASOURCE_PLATFORMmysql \ -e MYSQL_SERVICE_HOST192.168.131.223…

连接的原理(待修改)

搞数据库⼀个避不开的概念就是Join&#xff0c;翻译成中⽂就是连接。 相信很多⼩伙伴在初学连接的时候有些⼀脸懵逼&#xff0c;理解了连接的语义之后⼜可能不明⽩各个表中的记 录到底是怎么连起来的&#xff0c;以⾄于在使⽤的时候常常陷⼊下边两种误区&#xff1a; 误区⼀&…

linux磁盘清理

目录 排查过程1、查看磁盘占用情况2. 按照占用大小进行倒排-当前目录及其子目录3.当前目录磁盘占用情况 清理命令 排查过程 1、查看磁盘占用情况 df -hdf -h 命令用于显示磁盘空间的使用情况&#xff0c;以人类可读的方式呈现&#xff0c;其中&#xff1a;df 是 “disk free”…

“AI就绪”新计划,亚马逊云科技到2025年向200万人提供免费AI技能培训

AI就绪&#xff08;AI Ready&#xff09;计划 到2025年为全球200万人提供 免费人工智能&#xff08;AI&#xff09;技能培训和教育资源 亚马逊云科技宣布启动“AI就绪&#xff08;AI Ready&#xff09;”计划&#xff0c;旨在到2025年为全球200万人提供免费人工智能&#xff08…

易点易动固定资产管理系统:全生命周期管理的理想选择

在现代企业中&#xff0c;固定资产管理是一项至关重要的任务。为了确保企业的资产安全、提高资产利用率&#xff0c;全面管理固定资产的生命周期至关重要。易点易动固定资产管理系统为企业提供了一种全面的解决方案&#xff0c;实现了从固定资产申购、采购、入库、领用、退库、…

linux 内存回收mglru算法代码注释2

mglru与原lru算法的兼容 旧的lru算法有active与inactive两代lru&#xff0c;可参考linux 内存回收代码注释&#xff08;未实现多代lru版本&#xff09;-CSDN博客 新的算法在引入4代lru的同时&#xff0c;还引入了tier的概念。 新旧算法的切换的实现在lru_gen_change_state&a…