基于亚马逊云科技服务,构建大语言模型问答知识库

news2025/2/25 9:36:06

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

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

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

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

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

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

  • Glue Job中会进行文档解析和拆分,并调用SageMaker的Embedding模型进行向量化

  • 通过Bulk方式注入到Amazon OpenSearch中去

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

 知识向量化

 文档拆分

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

 a. 拆分片段的方法

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

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

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

  • FAQ文件,必须按照一问一答粒度拆分,后续向量化的输入可以仅仅使用问题,也可以使用问题+答案

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

 PDF文件,会包含更丰富的格式信息。Langchain里面提供了非常多的Loader,但Langchain中的PDFMinerPDFasHTMLLoader的切分效果上会更好,它把PDF转换成HTML,通过HTML的

块进行切分,这种方式能保留每个块的字号信息,从而可以推导出每块内容的隶属关系,把一个段落的标题和上一级父标题关联上,使得信息更加完整。

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

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

 模型名称

 Max_seq_length

 paraphrase-multilingual-mpnet-base-v2(sbert.net)

 128

 text2vec-base-chinese(text2vec)

 128

 text2vec-large-chinese(text2vec)

 512

 text-embedding-ada-002(openai)

 8192

 这里的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这种大数据框架来并行处理过重,并不合适。使用多核实例进行多进程并发处理则过于原始,任务的观测追踪上不太方便。所以可以选用AWS Glue的Python shell引擎进行处理。主要有如下好处:

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

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

 向量化推理并行

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

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

  • 多节点Endpoint对于临时的大并发向量生成,通过部署多节点Endpoint进行处理,处理完毕后可以关闭

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

 OpenSearch批量注入

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

 向量数据库优化

 向量数据库选择哪种近似搜索算法,选择合适的集群规模以及集群设置调优对于知识库的读写性能也十分关键,主要需要考虑以下几个方面:

 算法选择

 在OpenSearch里,提供了两种k-NN的算法:HNSW (Hierarchical Navigable Small World)和IVF(Inverted File)。

 在选择k-NN搜索算法时,需要考虑多个因素。如果内存不是限制因素,建议优先考虑使用HNSW算法,因为HNSW算法可以同时保证latency和recall。如果内存使用量需要控制,可以考虑使用IVF算法,它可以在保持类似HNSW的查询速度和质量的同时,减少内存使用量。但是,如果内存是较大的限制因素,可以考虑为HNSW或IVF算法添加PQ编码,以进一步减少内存使用量。需要注意的是,添加PQ编码可能会降低准确率。因此,在选择算法和优化方法时,需要综合考虑多个因素,以满足具体的应用需求。

 集群规模预估

 选定了算法后,可以根据公式,计算所需的内存进而推导出k-NN集群大小

 批量注入优化

 在向知识向量库中注入大量数据时,需要关注一些关键的性能优化,以下是一些主要的优化策略:

  • Disable refresh interval

  • 增加indexing线程

  • 增加knn内存占比

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

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

相关文章

嵌入式学习-c语言字符串处理函数

字符串处理函数头文件 在c语言程序中要想使用字符串处理函数&#xff0c;就需要加头文件 #include<string.h> 常见的字符串处理函数 ① 求字符串长度的函数strlen ② 字符串拷贝函数strcpy ③ 字符串连接函数strcat ④ 字符串比较函数strcmp ⑤ 字符串分解函数strtok …

保姆级WireShark的入门教程,速度收藏!

晚上好&#xff0c;我是老杨。 wireshark是个啥就不多说了&#xff0c;非常流行的网络封包分析软件。 可以截取各种网络封包&#xff0c;显示网络封包的详细信息。 软件功能十分强大&#xff0c;操作也不复杂。 很多小友都在后台问能不能出一期完整的抓包分析贴&#xff0c…

Nginx入门——Nginx的docker版本和windows版本安装和使用 代理的概念 负载分配策略

目录 引出nginx是啥正向代理和反向代理正向代理反向代理 nginx的安装使用Docker版本的nginx安装下载创建挂载文件获取配置文件创建docker容器拷贝容器中的配置文件删除容器 创建运行容器开放端口进行代理和测试 Windows版本的使用反向代理多个端口运行日志查看启动关闭重启 负载…

AD的软件安装,使用(仅学习用途),中英文切换,背景颜色设置,AD工程组成即创建

1.百度网盘地址如下&#xff1a; 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;j2hf git地址如下&#xff1a;(软件过大&#xff0c;暂时没有完全上传至git仓库内&#xff0c;稍后更新) 2.安装&#xff1a; 一.使用百度网盘或者git下载后&#xff0c;双击点开…

数据中台容易失败的20多种原因全部在这里了

数据中台失败的原因总结 在当今数字化转型的浪潮中&#xff0c;数据中台作为关键的战略举措被越来越多的企业所关注和实施。然而&#xff0c;数据中台项目的实施过程中并不乏失败案例&#xff0c;这引业界对于数据中台失败原因的深入思考和分析。通过一些公开的信息和数据&…

开源社区的力量:合作与创新

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

68、使用aws官方的demo和配置aws服务,进行视频流上传播放

基本思想&#xff1a;参考官方视频&#xff0c;进行了配置aws&#xff0c;测试了视频推流&#xff0c;rtsp和mp4格式的视频貌似有问题&#xff0c;待调研和解决 第一步&#xff1a;1) 进入aws的网站&#xff0c;然后进入ioT Core 2)先配置 Thing types & Thing&#xff0c…

每日一题:leetcode 1267

这里有一幅服务器分布图&#xff0c;服务器的位置标识在 m * n 的整数矩阵网格 grid 中&#xff0c;1 表示单元格上有服务器&#xff0c;0 表示没有。 如果两台服务器位于同一行或者同一列&#xff0c;我们就认为它们之间可以进行通信。 请你统计并返回能够与至少一台其他服务…

[管理与领导-44]:IT基层管理者 - 个人管理 - 从掌握管理知识开始入门:管理的常识和基础

目录 前言&#xff1a;管理框架 一、什么是管理 1.1 以终为始 1.2、资源的优化配置&#xff08;人财物、权力、时间等资源&#xff09; 1.2.1 资源的优化配置的步骤 1.2.2 管理者拥有的资源 1.2.3 管理者的权力资源 1.3 分而治之 1.3.1 分目标&#xff1a;细化和分解目…

个人微信AI聊天机器人

个人微信AI聊天机器人 微信AI机器人介绍产品介绍联系本人微信&#xff1a;yao_you_meng_xiang代码地址&#xff1a;https://github.com/xshxsh/weChatAiRobot 前期准备个人微信号Windows电脑注册AI模型账号 搭建使用注册AI账号注册讯飞账号创建应用申请API使用 安装微信 安装代…

概率密度函数 累积分布函数

概率密度函数&#xff1a;是指想要求得面积的图形表达式&#xff0c;注意只是表达式&#xff0c;要乘上区间才是概率&#xff0c;所以概率密度并不是概率&#xff0c;而是概率的分布程度。 为什么要引入概率密度&#xff0c;可能是因为连续变量&#xff0c;无法求出某个变量的…

FreeSWITCH 1.10.10 简单图形化界面2 - 并发性能测试

FreeSWITCH 1.10.10 简单图形化界面2 - 并发性能测试 0. 界面预览1. 测试工具批量创建baresip配置文件批量注册baresipSIP终端 2. 测试方法fsapi呼叫脚本 3 服务器环境CPU 配置内存配置 4 语音并发测试结果&#xff08;1&#xff09;1000分机&#xff0c;创建账号后&#xff0c…

大型商城小程序源码_免费开源_OctShop

毫无疑问小程序&#xff0c;对电商行业的商机是很明显的。相比h5/wap、公众号等商城&#xff0c;具备更大的发展空间。其次就是交易成本低&#xff0c;交易标准化、流量来源与转化多样化等优势&#xff0c;能让商户和买家更加方便、快捷的访问小程序&#xff0c;为用户提供更加…

商业经济杂志商业经济杂志社商业经济编辑部2023年第9期目录

专家论坛 黑龙江省经济高质量发展与生态环境保护耦合协调发展研究 刘降斌;祃玉帅; 1-5142 我国省际数字经济高质量发展水平综合评价研究 耿娟;毕晨曦; 6-8 振兴龙江《商业经济》投稿&#xff1a;cnqikantg126.com 数字经济背景下黑龙江省冰雪产业价值链的发展研究 …

哈夫曼树:优雅的数据编码之道

前言 在计算机科学领域&#xff0c;哈夫曼树&#xff08;Huffman Tree&#xff09;是一种令人惊叹的数据结构&#xff0c;它不仅可以高效地实现数据压缩&#xff0c;还能在信息传输和存储方面发挥重要作用。本文将从另一个角度深入探讨哈夫曼树的构建原理、编码过程以及应用案…

远程I0(遥控IO)

内容参考自串口连接云平台实现异地远程控制io模块&#xff08;以综科智控的I/O为例&#xff09;_io_智控_异地 根据个人理解&#xff0c;记录一下&#xff1a; 1、在A地&#xff0c;通过串口助手 发送开/关指令&#xff0c;控制B地的指示灯亮/灭 2、实现效果

==和===的区别(经典面试题,你不知道的细节)

全等运算符 又叫全等运算符&#xff0c;结果会返回一个布尔值&#xff0c;在数据类型相同的情况下&#xff0c;会比较值&#xff0c;值相同才返回true "1" 1 // false NaN NaN // false undefined undefined // true相等运算符 相等运算符在比较两个变量是否相…

【C++】构造函数和初始化列表的性能差距

构造函数和初始化列表的性能差距对比测试 1.说明 在C类和对象中&#xff0c;你可能听到过更加推荐用初始化列表来初始化类内成员。如果类内成员是自定义类型&#xff0c;则只能在初始化列表中调用自定义类型的构造函数。 但初始化列表和在构造函数体内直接赋值有无性能差距呢…

亚马逊买家不能评论有哪些原因?怎么解决

如果你在亚马逊平台无法发表评论&#xff0c;那么以下几个是原因及解决方法&#xff1a; 1、账户问题&#xff1a;如果你的亚马逊账户存在异常或限制&#xff0c;可能就会被禁止或限制在产品页面上发表评论。因此你需要确保你的亚马逊账户信息是完整和准确的&#xff0c;包括联…

Web 开发 Django 管理工具

上次为大家介绍了 Django 的模型&#xff0c;通过模型就可以操作数据库&#xff0c;从而就可以改变页面的展示内容&#xff0c;那问题来了&#xff0c;我们只能通过手动编辑模型文件来配置模型吗&#xff1f;当然不是&#xff0c;Django 为我们提供了强大的工具&#xff0c;可以…