2023 年,大模型惊艳了世界。2024 年,RAG 技术如日中天。
RAG 使得大模型能够在不更新模型参数的情况下,获得必要的上下文信息,从而减少大模型的幻觉。随着大型语言模型技术的不断成熟和行业应用的深入,人们对 RAG 系统的期望已经超越了对其“酷炫”效果的追求。企业和组织开始寻找更可靠、可扩展的 RAG 解决方案,以满足实际业务需求。
与此同时,支撑 RAG 的向量数据库市场竞争愈加激烈。然而从当前向量数据库的实现来看,无论是插件形式,还是专门的向量数据库,底层实现上很多都是采用诸如 HNSW 之类的公开算法,因此一些关键指标例如召回率并不会有太大的区别。那么一个企业级解决方案想要脱颖而出,需要在哪些方面下功夫呢?
1、向量数据库:RAG 的心脏
RAG 的出现是为了解决大模型幻觉问题,但它的出现也标志着搜索范式的变化。
过去我们通过搜索框输入关键词,然后在上面自己去查找内容。搜索可以使用特定关键字或者搜索技巧,很容易找到想要的信息。而问答则基于人类语言进行提问,不依赖关键字。这就导致了传统关键字检索的局限性,可能因为问法的不同而无法找到相关内容。在这种问答环境中,对语义的要求自然而然地凸显出来。所以这时候大家就基于向量数据库,进行语义检索,然后再将结果应用于 RAG。如同 MySQL 在传统 Web 应用的角色定位,向量数据库是 RAG 应用依赖的一项核心基础功能。
在此背景下,火山引擎云搜索团队提供的 RAG 解决方案可以视作一个两层的解决方案。上层提供 RAG 框架服务,包括大模型集成、LangChain 集成、模型管理、混合检索等。
下层则是向量检索能力。作为一项基础技术,单纯的向量检索能力可能并不会引起开发者的太多关注。但是在火山引擎云搜索服务的 tob 过程中,他们发现 RAG 场景不乏向量数据规模庞大的客户,从常见的千万级别,到 10 亿级别,甚至到 100 亿级都有。在这种规模条件下,向量检索解决方案选型就尤为重要,因为此时向量数据库的成本和稳定性都会面临非常大的挑战。
另外,RAG 技术的真正价值在于能够提供更准确的回答和更快速的搜索,其本质上又与搜索引擎类似。如果希望将搜索产品扩展为 RAG 产品,那么 ES 和 OpenSearch 是最佳选择之一。
在这方面,火山引擎云搜索服务提供了兼容 Elasticsearch/OpenSearch 的托管在线分布式搜索解决方案。早在 2022 年 4 月上线时,这项服务就内置了向量检索的能力。实际上,火山引擎云搜索团队在 2020 年就开始应用向量检索技术,当时在 ES 7.1 版本上集成了这一技术,以满足集团业务对多模态检索的需求。
在技术实现路线上,云搜索团队选择以开源开放的思路来建设向量检索能力,其团队成员还成为了 OpenSearch 开源项目向量检索功能模块的维护者,也是该模块中唯一来自非 AWS 的维护者。随着大模型技术的兴起,云搜索团队也从市场需求出发,从底层向量检索到上层应用服务,针对每一个环节提供了增强能力,形成一套完整易用的 RAG 应用解决方案。
从专有到集成的技术趋势
火山引擎云搜索团队涉足向量技术有着悠久的历史。然而,向量数据库真正走进大众视野却是近年来,这主要得益于 OpenAI 的兴起和商业数据库巨头们的加入。
2022 年,向量数据库领域融资热潮涌现,多家专有向量数据库厂商获得了巨额投资。然而,技术潮流瞬息万变。今年 6 月,OpenAI 收购实时分析数据库 Rockset,标志着向量数据库发展进入新阶段:向量数据库不再是独立的特性,而是集成在更大平台中的组件。
与 Chroma、Milvus、Pinecone 等专有向量数据库不同,Rockset 和 ES、Redis 等商业数据库选择通过插件形式加入向量检索能力。Rockset 甚至在今年 4 月才正式引入向量搜索功能。OpenAI 选择 Rockset 而非专有向量数据库,业界普遍认为这表明:客户更看重数据库的整体管理能力,以及与现有功能的无缝集成,以优化数据处理工作流程并提高整体效率。
这一趋势与火山引擎云搜索服务的发展路径不谋而合。云搜索团队选择在开源版 ES 和 OpenSearch 基础上增加向量功能,一方面能充分利用团队在文本检索和向量检索领域的多年积累,另一方面也是站在巨人的肩膀上进一步增强整体竞争力。
在他们看来,向量数据库更像是一种底层能力。客户在使用向量数据库时,不会单纯地使用它来存储或读取向量数据。他们更多的是将向量数据库与应用场景结合起来,例如 RAG、以图搜图等语义检索和解决方案。很多客户实际就是从原本的搜索应用升级到 RAG,这个迁移成本并不高。因此,如果一个数据库能够提供更多上层应用的支持能力,对客户来说会更有价值。
另一方面,在传统数据库实现向量,相当于在原有的场景插上一个新的翅膀,处理能力就会更强。云搜索团队在实践中已经认识到这一点,所以随着业务的发展,将向量检索与文本检索结合起来,实现了混合检索的能力。这种融合扩展了产品的使用场景,实现了更大范围内的功能和性能提升,提高了产品竞争力。
在一些实际应用中的复杂的场景里,单纯使用简单的 DSL 展开并不能满足需求,特别是在需要优化搜索准确率的情况下。但其实搜索原生生态系统已经提供了丰富的插件能力,这些插件可以有效优化和增强搜索性能。而且引入向量检索后,如在开源版 ES 或 OpenSearch 中,可以与原有的全文搜索引擎结合,实现复杂的结构化查询,从而显著提高准确率,达到一个非常好的效果。
以长文本为例,一篇包含 2 万个字的文章,前半部分可能介绍某个事物的发展史,而后半部分的结论可能推翻了前面的结论,如果只检索到前半部分内容,结果会导致回答与实际意图相反。这种情况下,就需要采用结构化混合检索,结合关键字和向量检索,能更好地匹配专有名词和复杂结构,获得更准确的结果。
像云搜索服务这样的产品,既支持向量检索,也支持在向量检索基础上的复杂结构化检索。同时还在在结构化检索的基础上通过插件扩展功能,提供干预、混排和重排等能力。从实际实践来看,在处理专业型文档时,借助这种增强的结构化查询检索的能力,其准确率远远优于纯向量检索。
开源才不怕绑定
在开源投入上,云搜索团队很早就参与了开源 ES 社区的建设。字节跳动内部很早就使用开源版 ES 用于支撑包括抖音、巨量引擎等核心业务,随着集团业务的发展,业务部门对多模态检索有使用需求,云搜索团队发现这些向量检索的需求与他们现有的 ES 使用场景可以结合。而当时,Elasticsearch 还未提供向量检索的能力。
亚马逊则较早在开源 ES 发型版本 OpenDistro 上以插件的形式实现了向量检索的能力,于 2019 年发布了并开源了该插件,也就是 OpenDistro k-NN 插件。鉴于当时的实际情况,云搜索团队在 2020 年将 k-NN 方案引入到内部的实践中,同时也积极参与社区的建设 。2021 年 4 月,亚马逊基于开源 ES 7.10.2 版本分叉创建了新的项目 OpenSearch,并继承了 OpenDistro 项目几乎所有的扩展功能,自然也包括了向量检索 k-NN 插件。
出于这些原因,在云搜索服务商用之后,团队决定继续通过 OpenSearch 来构建自身向量能力:“为了更好地满足开源需求,并遵循以开源为主导的思路,我们决定采用更加开源的方式来提供搜索服务。”
火山引擎云搜索团队选择 OpenSearch 来构建自身向量能力,不仅看中了其开源优势,也看重了其与 开源 ES 的技术传承。OpenSearch 的检索体系从 开源 ES 演变而来,是一个持续演进的技术体系,也是大家所熟悉的技术栈。云搜索团队选择基于 OpenSearch 去构建向量检索,也能更好的利用之前积累的内部经验。
随着 RAG 技术和大模型的发展,衍生出来对向量检索的要求不断提高。首先是向量维度的变化,其次是向量和文本结合功能性的需求,此外还有对搜索准确性的更高要求。核心数据库尤其是在向量场景下,需要不断迭代升级,来满足这种大模型场景下的搜索需求。
从 2020 年开始,云搜索团队进行向量检索的开发,并将向量检索与全文检索结合。在这个过程中提出了非常多的功能,这些功能一开始服务字节跳动集团的业务,到云搜索服务产品上线之后也面向外部客户。同时本着“开源开放”的基本策略,自从引入向量检索能力,团队开始将支持内部业务所需的一些新功能引入并贡献至 OpenSearch(当时的 OpenDistro)社区中去。
RAG 和向量检索在今年受到了极大的关注,火山引擎云搜索团队在过去几年也持续参与 OpenSeach 社区向量检索功能的建设,今年云搜索团队成员被邀请成为该项目维护者(maintainer),这也是一个重要的里程碑。
“将我们的技术贡献给 OpenSearch 社区,是一件成就感比较大的事情,”火山引擎云搜索团队鲁蕴铖分享道,“这不仅意味着我们的技术得到了认可,更重要的是,我们能够与社区一起共建一个更多人使用的服务、一个更加完善的搜索生态。”
鲁蕴铖认为,开源不仅是一种开发模式,更是一种理念。秉承开源理念,火山引擎云搜索团队能够与社区携手合作,共同推动搜索技术的进步。这不仅促进整个社区的繁荣发展,也对火山引擎自身的产品发展是有利的。
“开源产品需要持续的维护和迭代,”鲁蕴铖强调,“而社区的贡献正是推动产品发展的重要动力。我们积极参与 OpenSearch 社区的建设,不仅为产品带来了新的功能和特性,也提升了产品的稳定性和性能。”
而且,“遵守开源开放的标准,也让我们没有任何商业化和开源产品上的矛盾,也能帮助客户解决被某一家云厂商绑定的顾虑。”
2、一套 RAG 系统,多种向量算法引擎
随着业务的增长,为了满足大规模内部业务和外部客户的需求,团队对向量检索能力进行了持续迭代。特别是在 To B 场景下,用户的业务场景各不相同,数据规模也千差万别,他们的关注点也不一样。对于一个好的数据库产品,它应该能够尽可能多地支持不同规模的业务场景。例如不同业务向量数据的数量可能是 10 万级别、千万级别、10 亿,甚至 100 亿以上。除了数量级之外,用户采用的向量维度也呈逐步增加的趋势,例如尽管现在不少用户还在使用 128 或 512 维的向量,但是业界一些向量 embeddings 服务厂商例如微软 Azure 和 OpenAI 已经支持到 3072 维,云搜索产品也已经支持存取多至 16000 维的向量数据。数据条数越大,维度越高,对检索资源的需求也越高。
为了匹配不同规模的需求,火山引擎云搜索团队调研了多种引擎,希望在原有的 开源 ES 和 OpenSearch 基础上进行扩展,最终,他们率先引入了 Faiss 引擎。通过将 Faiss 与现有的全文检索能力结合,为内部集团业务提供向量检索服务。
另外,HNSW 加上 PQ 向量压缩是目前已有的向量数据库里用得最多的算法,虽然能够满足可能百分之八九十的云搜索用户需求,但是这两种其实已经发表很久了。而火山引擎云搜索的应用场景也比较多样化,处理的数据规模可能达到几百亿条,目前常见的基于内存的向量引擎在这种规模下,会消耗非常多的资源,检索时效上也不够快。在这种情况下,云搜索团队又引入了基于磁盘的 DiskANN 算法。
DiskANN 是一种基于图的索引和搜索系统,源自 2019 年发表在 NeurIPS 上的论文《DiskANN: Fast Accurate Billion-point Nearest Neighbor Search on a Single Node》,它结合两类算法:聚类压缩算法和图结构算法,只需有限的内存和 SSD 资源,就能支持数十亿的向量检索。与常见的 ANN 算法相比,DiskANN 大幅提升向量召回的读取效率,降低图算法的内存,提升召回率。
例如在当前主流的内存型 HNSW 算法下,业界常用的内存估算方式是:向量个数 *4* (向量维度 + 12)。那么在 DEEP 10M(96 维)的 1 千万数据就需要内存达到 4GB 以上,但是通过 DiskANN 优化后,仅需要 70MB 的内存就可以对海量数据高效的进行检索;在 MS-MARCO(1024 维)的 1.38 亿条记录里,需要内存更是高达 534GB,这样检索 1.38 亿的数据需要 12 个 64GB 的节点。
按照上述估算公式,达到 10 亿级别时需要大约 100 个节点,而达到 100 亿级别时则需要约 1000 个节点。这种规模的服务在资源成本和稳定性方面面临着极大的挑战。然而,引入了内存和磁盘更好平衡的 DiskANN 算法后,云搜索团队在 200 亿单一向量库中已成功验证了其效果:DiskANN 论文提到可以节约 95% 的资源,从多个实际用户案例来看,这一收益值非常接近。客户仅需几十台机器即可稳定高效地满足百亿级业务需求。
所以当前火山引擎云搜索提供了总共四种检索引擎,可以根据数据规模和成本预算来选择不同的引擎。如果数据规模非常小,又对这种性能检索性能有需求的话,可以使用基于内存的向量检索算法,比如 HNSW。对于大规模数据而言,如果仍使用一些高性能的基于内存的算法,资源成本会非常高。因此,这时可能需要使用一些基于磁盘的向量检索算法,比如 DiskANN,来达到资源和性能上的平衡。
目前云搜索服务通过 DiskANN 引擎提供的能力,完成了 200 亿级别的 512 维向量构建的客户案例。在这个案例中,通过分布式的能力,构建了一个超大规模的向量集群,实现了视频、图片、文本的混合检索。并且在业界,微软的 Azure ComosDB 目前也开始支持 DiskANN 算法。
“目前,我们支持了多种可商用的向量检索算法,除了常见的基于内存的 HNSW、IVF-Flat 之外,也包括基于硬盘的 DiskANN 算法。通过这种全方位、多层次的解决方案,用户可以根据自己实际关注点,例如数据规模、性能延迟、成本预算等,能够选择不同的算法。”李杰辉表示。
不可能三角:稳定、成本与性能
大模型火了之后,除了向量数据库,一些中间件如 LangChain 和 Llama Index 也备受关注。这些中间件负责将向量数据库与大语言模型(LLM)整合,形成 RAG 引擎。甚至有一些简单将向量数据库、中间件和 LLM 拼接起来的前端项目也吸引了大量关注。
然而,一套真正符合企业需求的 RAG 引擎并不仅仅是向量数据库加上 LangChain 或 Llama Index 等中间件的简单组合。从实践来看,使用 LangChain 或者 Llama Index 原始方案,可能准确率非常差,特别是在专业文献的这种领域。也就是说简单的拼装方案可能对一些基础的问答语料有效,但对于复杂的长文本或专业领域(如财务报表或判决书)的检索需求,仅靠简单拼合难以达到预期效果。
对于一个能使准确率得到很大的提升的 RAG 方案,需要从数据预处理到搜索增强整个流程不同阶段增加干预跟定制化能力。
一个完整的 RAG 处理流程要分为几个部分。首先一个是需要进行数据增强处理。无论是数据清理,还是对原始的半结构化数据进行抽取,例如实体抽取或事件抽取,都需要进行详细的处理。部分信息需要总结,并采用适当的方法进行分块,而不是简单地按照字数进行划分。比如,需要识别其中的表格和代码,并将这些块准确地拆分出来。第二个部分就是存储方案。最简单的方法是将数据分割后,添加元数据、原文和向量,或者拼接字段也需要进行 schema 的设计,使得系统具有更强的结构化检索能力。第三个部分,就是进行混合搜索。例如基于向量后进行标量过滤,或者关键词召回和向量召回,然后进行混排和精排。
火山引擎云搜索提供了非常强的混合检索能力,可以在向量召回的文档上结合更多的 operator 进行匹配和评分干预,从而确保更准确的检索效果。从检索方面看,结构化查询和查询后的 rerank 需要进行定制。通过这些步骤的干预,最终可以达到高准确率的检索效果。
简单来说,首先是对原始数据进行增强,然后进行合理的 schema 设计,而不仅仅是像 LangChain 那样通用的方式,这样检索效果可能更好。最后,进行结构化查询设计和 rerank。特别是对于专业文献,可能需要补充召回和 rerank 这些步骤,最终达到准确的检索效果。最后,对 prompt 进行调优和处理,形成一个完整的端到端方案。这只是基础单元,复杂场景下还需要进行 pipeline 设计,对意图进行分类,并分成不同的任务来处理。
为了应对复杂需求,火山引擎云搜索端到端的解决方案,提供的是一个完整的 RAG 生态,能够将火山引擎已有的搜索的经验运用起来,比如 RAG 搜索的召回率提升,ES 的插件化能力,干预能力,以及基于 LangChain 或其他模型所不具备的抽象搜索和检索重排功能。
“我的一个感受是 RAG 用户关注的跟搜索用户不一样,就是他对准确性的要求会高非常多。目前大部分用户多多少少会遇到召回的准确性不足,导致 RAG 回答效果不好的这种问题。这是 RAG 应用的一个挑战。”接触过不少客户的余炜强观察到。
理论上开源文本搜索引擎提供了很强基础能力,但是大部分用户可能没有足够的检索经验或能力去做优化,从而将它们发挥到最好。字节跳动历史上各类搜索经验,其中很大一部分可以并复用到了云搜索的 RAG 准确率优化上。另一方面云搜索团队在 RAG 生态系统上开发了许多组件,以帮助用户快速构建端到端的 RAG 应用,从而实现低接入成本和高效果的目标。
对比 LangChain 和 Llama Index 和向量数据库的简单拼合方案,云搜索团队的解决方案更为底层,虽然没有可拖拽的 pipeline 单元,但通过交互式编程方式,结合 AI 生态和大模型管理能力,可以注入增强逻辑,构建更复杂的应用。理论上,这些干预能力可以直接嵌入到 LangChain 和 Llama Index 中。例如,如果将 OpenSearch 用作 Llama Index 的作为 vector store ,可以传入一个 search pipeline。这个 pipeline 可以包含针对 RAG 的一些增强功能,包括干预增强,从而获得更好的调优体验。
对于向量数据库来说,“性能”是其中一个关键的产品竞争力评价指标。云搜索团队一开始也针对这些能力,尤其是性能和延迟方面,进行了全面的能力建设。其实在向量检索火起来之前,一直到现在,很多厂商在做性能报告的时候,都会把重点放在查询延迟上,这是一个比较通用的衡量标准。然而,随着向量检索技术的发展和应用场景的丰富,单纯的关注查询延迟已经无法满足所有需求。
在实际应用中,云搜索团队发现客户对底层检索数据库的需求通常可以归纳为三个维度:稳定性、成本(越低越好)和延迟性能(越低越好)。
“这三个维度形成了一个‘不可能三角’,其实在向量检索中,我们不可能找到一种方案能够同时满足这三个条件——既稳定,成本又低,且延迟时间非常短。”
通过与客户的深入交流,他们发现用户其实更多关注的是稳定性,这是所有的用户的一个共性,其次是成本。稳定性不仅意味着检索速度快或慢,而是指在数据量增加时,系统仍能可靠地返回结果。尽管很多人认为数据库性能应该保持在毫秒级别,但实际上在大规模检索场景中,许多客户可以接受秒级的延迟,当然这是在数据量非常大的前提下。例如,当数据规模达到 10 亿条时,如果客户要求毫秒级别的性能,则需要全内存方案支持。在这种情况下,支持 10 亿条向量可能需要四五百台机器,对于许多 To B 用户来说,这样的成本是非常难以接受的。对于他们来说,其实是能够接受成本低和较慢的查询速度,但是关键要稳定,不能数据稍微多一点就崩了。
“我们发现在这个不可能三角里,用户其实最看重的是稳定和成本,这也与常规的行业认知有一定偏差。”
所以后面火山引擎云搜索服务主要是沿着“既能有效控制成本,又能提供可靠的稳定性”的指导思维去迭代系统能力。
其中成本控制主要体现在使用成本和实际资源消耗成本上。在资源消耗成本上,火山引擎云搜索通过引入更优的算法 (DiskANN) 和采用无服务器 (Serverless) 方案。例如在当前主流的内存型 HNSW 算法下,业界常用的内存估算方式是:向量个数 *4* (向量维度 + 12)。那么 在 DEEP 10M(96 维)的 1 千万数据就需要内存达到 4GB 以上,但是通过 DiskANN 优化后,仅需要 70MB 的内存就可以对海量数据高效的进行检索。在使用成本方面,云搜索提供了完整的生态解决方案,加上 token 价格很低的方舟和豆包平台,这样用户的接入成本和使用成本也得到了显著降低。
向量检索算法引擎的选型上,对于小规模数据的用户推荐使用全内存方案,而对于大规模数据的用户,如果预算充足,则可以选择全内存方案,以确保性能和稳定性。对于同时关注稳定性和成本的用户,则推荐使用基于硬盘的检索方案,如 DiskANN。这种方案既能有效控制成本,又能提供可靠的稳定性。
构建生产级 RAG 仍然是一个复杂而微妙的问题,如何高效地接入企业搜索生态、如何将性价比做得更好,所有这些问题都不是单纯依靠开源的向量数据库、开源的 RAG 就能轻松解决的,每个环节的增强、每一个构建决策都能直接影响到产品的竞争力。
火山引擎云搜索团队的下一步计划是结合行业趋势,提供更多的 AI Native 能力。云搜索不仅已经支持图像搜索、文本搜索图像、文本搜索视频以及标签与向量语义联合查询等复杂查询,还希望在生成式 AI 领域进一步融合各种检索功能。一方面,通过降低使用门槛,用户可以更轻松地上手;另一方面,通过整合以往的技术积累,能够提供更优质的用户体验。