转眼到了2024年尾,和小伙伴一起创立TorchV也接近一年。虽然这一年做了很多事情,但从技术层面上来说,RAG肯定是不得不提的,所以今天分享一下作为大模型应用创业者所感知的这一年,RAG技术和市场环境的变化。
首先申明,本文更多来自于本人主观感受,且内容更多是回顾性的结论,不建议作为其他文章的引用材料。
主要内容包括:
- RAG技术变化
- 主要架构变化
- 技术细节变化
- 市场需求变化
- 上半年:AI无所不能,大而全;
- 下半年:回归理性,小而难;
- 明年预测:应用才是王道;
- 从业者变化。
其中技术部分放在上篇,市场需求变化放在下篇。
一、RAG技术变化
RAG(检索增强生成)其实是由两部分组成的,分别是检索和大模型生成。当然,既然有检索就必然会先有索引,包括chunking、embedding等动作都是为了建立更好的索引。因为我们之前从零开始创建并运营了一个千万级用户的智能问答类产品,所以在2021年左右其实就已经采用Java技术栈在使用RAG里面“RA”的大部分技术了。在2023年年中,RAG这个词突然火了起来,于是我们就立马就扑进去了,而且相信RAG在企业应用领域比纯粹使用大模型会更具实用性,至少在三年之内是这样的(随着最近传闻Scaling Law遇到瓶颈,好像这个时间还有可能被推后)。短短几个月,RAG开始的火爆程度甚至有超过LLM的趋势,在2024年1月我甚至还参加了“共识粉碎机”的EP15讨论会,主要话题就是“2024年是否会成为RAG元年?”。
1.主要架构变化
虽然RAG的火热,各种架构思想就被大师们总结出来,最出名的莫过于下面这张图了:
图1:RAG三种架构模式,来源于论文Retrieval-Augmented Generation for Large Language Models: A Survey。
站在现在(2024年11月)再看,其实Advanced RAG应该还是最主流的架构。因为它的效果明显比Naive RAG要好,但比Modular RAG更容易实现。在实际应用中,我们还需要为客户考虑经济成本和维护成本,很多时候基于客户需求,在Advanced RAG上做一些对症下药,远比全家桶更具适应性。
2.技术细节变化
相较于架构变化,技术细节的变化更加“风起云涌”,这一点从各自媒体的文章主题变化和从业者之间的交流内容中就能明显感知到。在RAG这个大框架之下,我们看到了每隔一段时间就会有一些技术细节被热炒,比如:
- 知识提取
- 索引组织
- 检索方法
01 知识提取
在2024年之前,我们看到的RAG面对的原始知识更多是非常标准的论文,一般是文字版PDF或者HTML,所以那时候内容提取还不是一个大问题。但是在2024年,随着各行各业都开始使用RAG之后,五花八门的文件类型解析变成了从业者们头痛的事情,于是,我们发现有好一波人开始专注于知识提取。
于是我们看到在2024年,出现了很多专门做知识提取的公司,比如已经在科创板上市合合信息(其实已经是老牌企业),在文件解析方面就非常出色,还有新创的SoMark等,当然大厂在这一块肯定也都涉足,特别是OCR解析,比如百度开源的PaddleOCR,其实还挺良心的。
我们也是如此,看到现成的python组件在面对多样的知识文件类型时渐感无力,于是就开始在知识提取方面花时间。从多类型文件的解析,包括一些老文件格式(.doc、.xls、.ppt等)的解析,再到比较难的PDF表格解析,需要去处理非常复杂的合并/拆分单元格,并且也有了具备原创知识产权的提取工具组件。
但是我一直在想,是否可以把整个工作流再前置,如果我们提供知识生产工具,用户可以在我们的知识管理和生产工具上进行知识生产和协作,那么知识提取是不是会更流畅?这个问题可以单独写一篇文章,就放在这个篇文章的上下篇结束之后吧。
02 索引组织
在RAG里面,索引组织可能是相对比较有技巧性的部分了。
了解RAG的人都听过chunking,不严谨地说,就是把文件切成若干片段,为的是可以在LLM的窗口大小之内进行作业。常见的chunking方式有按固定token数量的,有按Page的,也有通过NLTK等来进行切分的。但我始终觉得使用哪种chunking方法并不是重点,如果您使用的LLM的上下文窗口较大,对于一些4、5页的文件,还切它干嘛呢,直接扔进去就完事了。但在chunking过程中,其实有两个隐含的技巧是可以快速提升准确率的:指代消解和附加元数据。
指代消解
我们在实操中常见的是两种,一种是切割的时候,上一页有详细信息,而下一页中只有“这种方法”来指代。这时候最简单的方法就是做chunk叠加;还有一种就是类似合同,甲方乙方的具体名字只在最开头的地方出现,剩下全文都用“甲方”、“乙方”指代,这种情况因为被指代的名称是比较好获取的,可以直接加在chunk中,如下所示(伪代码),chunk_meta里面可以设置甲方乙方的全称:
1 | <chunk> |
附加元数据
其实元数据的索引存储结构和上面的指代消解示例中差不多,不同的是,我们需要关心的是:
- 元数据从哪里来?
- 在检索的过程中什么情况下激活元数据过滤?
元数据的来源只可能是人工标注或者应用侧(包括文件处理时)生成的,这里我们肯定先不去考虑人工标注了。从应用侧的设计来看,其实是可以拿到很多元数据的。比如我们上传文件、撰写知识的时候,自然可以拿到时间、文件名称(正常命名都会含有实体),也可以在交互设计中要求作者进行分类选择,简介编写等,无一不是增加元数据的手段。
但我们在索引中增加了元数据内容之后,也不是强行要激活元数据过滤的。我们在实操中是会设置自定义的系统槽位(system_slot),如果用户提问的文本中,包含也比较多的意图和实体信息,且与系统槽位存在匹配,才会激活。会先使用BM25进行元数据过滤,再进行dense检索。更具语义信息的dense索引有时候因为维度限制会丢失一些信息,或者说dense检索对于元数据过滤并不那么精准。这种设计一方面可以减少检索的时间,另一方面就是可以提高带有时间和实体(如城市、公司、部门等)意图的提问的准确率。说起来这好像是一种“退步”,因为当LLM(或GPT)所向披靡的时候,我们也是一度有点看不上之前的技术的,但是在企业应用实践中,客户问题的解决率才是一切的根本。所以,在TorchV AI中,我们让NLU和Slot(槽位填充)回归了。
是否使用Graph
对了,还有一个大家争论比较多的索引组织方式就是Graph或者叫图数据,将node(实体)和relation(关系)通过图论组织起来。我们团队从2015年开始一直有在使用neo4j开发一些有趣的应用,在寻找人类直观上不太容易识别的点与点关联的方面确实非常出色。但是这个技术非常大的问题就是索引建立,从关系数据库把结构化数据迁移到Graph数据库中还算容易,但是面对成千山万的非结构化数据的时候,说实话目前也就是只能让GPT4以上的LLM来帮忙了。和重度使用过图知识库的朋友聊的过程中,他们的一致感受是:花费太高昂,但是场景太薄弱,依然还存在手工校对的工作。换句话说,如果花了10万的费用,但在实际使用中却没这么多使用场景,得不偿失。
当然,如果您手头的工作非Graph不能解决,那就大胆去All-in吧。我们目前的系统并没有使用图数据库。
03 检索方法
有句话(我说的)不一定说的对,在某种意义上,知识提取决定了专有知识的完整性,索引组织决定了回答准确率,而检索方法则在减少幻觉上有重要意义。
如果我们可以准确检索召回,把非常明确的内容加上指令prompt,给到LLM处理,那么LLM给出的结果几乎不太会一本正经胡说八道。只有检索召回的内容和用户原问题不相关,或者召回内容存在多个不置可否的知识内容时,LLM才会按心情(概率和 temperature)选择错误知识或者使用预训练时学习的知识进行回答。所以,检索做得好,可以将整个RAG幻觉尽可能多的变为白盒。
Hybird
但是说到检索,我相信现在大部分的RAG系统都已经用上了Hybird检索了吧,一般来说也就是BM25+语义相似检索的混合检索。
BM25有自己的固有用武之地,就像前面说的元数据过滤,还有就是一些在类似产品型号和专业术语的检索上,其精确度和稳定性是远高于语义相似检索的。
语义相似检索有很多方法,因为我们主要用的还是Elasticsearch(也有Milvus),所以其实真正的语义相似检索就是ANN,说的更具体就是以HNSW为主的相似度算法。这个HNSW(最小可导航世界)的逻辑解释起来有点麻烦,但是我可以打一个比方:
比如你需要从一个城市的南部坐公交去北部,我们要选择最短的坐车路线(含换乘),那么有两种方式选择:
- knn:将所有可能的公交路线(含换乘)做一个整理,假设有28900条路线,然后按花费时间进行排序,选择Top1或者Top n。抛开语义理解错误的问题,这种方法是非常精确的,但是耗时巨大,也可以认为是一种暴力检索;
- ann:还有一种就是相似最近邻,我们这里说的更多的是hnsw。为了让非技术专业的朋友可以听懂,不严谨地说,看着地图,从28900条路线中,选择出发地和目的地两点连线附近的50或100条公交路线。这种方法的效率极高,可能耗时只需要knn的万分之一,但它的问题在于无法确定这50或100条里面哪几条才是最好的。于是,如果你采用ann却不用rerank的话,就会比较拉垮了。
RRF Fusion
RAG-Fusion主要是使用多个不同类型的检索方式进行检索,并按RRF(倒数排序融合)公式进行综合排名的一种检索方式。
多种检索方式包括:
- Sparse(稀疏)检索,比如BM25;
- Dense(稠密)检索,比如语义相似度检索;
- 还有就是使用不同配比的混合检索(在TorchV AI中,我们采用alpha值来做BM25和ANN的结果权重配比)。
然后使用RRF公式
RRF(d) = Σ(r ∈ R) 1 / (k + r(d))
具体公式就不解释了,有兴趣的朋友自己查资料吧。
来进行再排序,得出一个综合结果。其好处是使用不同的检索器,可以在各类不同问题场景下得到一个“思考”更周密的答案。我们在的系统里面有一个turbo开关,打开就会进行增强检索,其中也包括了该方法,且在召回率方面是有一定效果的。
Rerank
其实我应该不用再讲reank了,如果您看过上面hnsw算法的话,就能知道rerank的作用了。TorchV AI在使用rerank的时候也加入了自己的一些优化算法,比如归一化处理和密度函数(舍弃相关性较低的返回结果)。在使用rerank前后,准确率相差确实很大,但你要平心而论,元数据过滤对准确率的提升可能会更明显。因为rerank相对比较被动(根据前序召回的结果,有时候是矮子里拔将军),而元数据过滤则是直接在检索召回环节产生影响,相对更加主动(自己对召回哪些结果起到重要作用)。嗯,这是我自己的理解,不一定对。
3.技术部分小结
OK,RAG技术变化我想先做个小结。关于RAG的大流程已经有太多文章了,我自己也写了不少,所以本文我更希望是从几个点来讲衣鞋 技术实践上发现的变化。其实从RAG本身的各环节技术来说,没有出现新的现象级组件,2024这一年,感知和看到更多的,其实是大家根据实际需求不断探索最佳实践,并内化到系统能力中的一个过程。
*** 市场部分下周更新 ***