随着时间的推移,越来越多的企业和用户开始关注大语言模型在业务中的应用。然而,由于大语言模型中存在的过时、不准确、幻觉、一本正经的胡说八道、基于互联网数据训练这些缺点,因此,直接使用大语言模型生成的内容在商业场景中,特别是涉及到一些专业领域以及私有数据的场景,是无法提供准确或有价值的信息的。因此,大模型的应用通常需要与搜索技术相结合。由此,语义搜索也从之前的鲜有人问津,突然变成了一个热门话题。但是,将语义搜索与大型模型结合并不是一个简单的工具组合,也不是“将所有数据用机器学习模型转化 -> 再进行语义搜索 -> 最后搜索结果输入大型模型”就能实现的。因此,本文将介绍在这方面的一些思考,希望能对大家有所帮助。
首席,我们需要思考,为什么我们使用大模型时要使用语义搜索,知道初心是什么,然后才能坚守初心,而不至于被次要的东西所影响,最后导致项目变形。
我们的初心是用大模型的理解能力、推理能力、生成能力来帮助我们提升生产率,用户体验,但是大模型中过时的、或者不准确的、基于互联网数据而训练出来推理答案有缺陷,因此,我们需要一种技术来给大模型提供准确的上下文信息(加上提问)作为生成的原始素材。
因为语义搜索能够更好的理解长文本的对话式提问,并能从数据库中找到更相关的内容,所以,这是对大模型的一个很好补充。
语义搜索的核心能力能够为大模型提供准确的上下文(context window)
但另外一点,我们需要明确知道的是,无论是ChatGPT还是Bard,亦或是文心一言,通义千问等,LLM的输入其实都是文本。我们提交给大模型进行总结,扩展,翻译,重写,创作的内容,都不是向量。
因此,准确且高效地给大语言模型提供上下文信息是主要目的。而语义搜索只是一个可以选择的技术手段,而且是多路召回中的一个分支,倒排检索、数据类目和实体过滤、召回融合,重排等都是为了此目的需要考虑的技术方案。
语义搜索分为稀疏表征的倒排检索和稠密表征的相似性搜索两种。我们通常说的向量搜索是指的基于embedding的稠密表征的相似性搜索(KNN和ANN搜索)。但实际上,我们还有有基于稀疏表征的倒排语义检索。这两种搜索技术,都得益于大规模语言模型(注意,LLM是指参数很多的语言模型,并非特指类似chatGPT这种超高参数的模型,实际上,特征参数在数千万级别的模型都能称作大语言模型)的发展,而在召回率和相关性方面有了长足的进步,特别是在transformer的基础上演进出来的模型,比如BERT等。
但我们在选择语义搜索方案时,基于embedding的稠密表征的相似性搜索(KNN和ANN搜索)不见得就是最优解。比如说下图的SPLADE的,就是一种不逊色于大多数稠密embedding模型的稀疏表征的模型,而这种模型的优势在于,经过模型处理后的数据不是数组类型的向量,而是人类可读的、搜索可解释的词+权重,应用的仍然是倒排检索技术。因此,在模型大小,生成的索引,与检索性能上会有优势,而且因为term匹配能力强,也能更好的适应用户输入过短,没有上足够上下文时,向量搜索所表现出来的信息表达能力弱的缺点。
而在这方面,Elasticsearch中的ELSER表现优异:
当然,向量搜索仍然是具备更强大的语义理解能力的。我们需要向量搜索。但同时,也需要知道,高效、优雅、准确的构建向量搜索能力并不容易。其受限于:
一句话解释,就是向量搜索的效果,并不是你选择使用向量库之后就能直接呈现,直接能够获得的。选择模型,合理调优,模型的维度、量化,模型的更新等都会影响效果。
特别是大部分向量库仅仅提供了向量存储,向量索引,向量相似性比较这三方面的能力,但这只解决了工程上问题,也就是说,向量库只解决了向量搜索搜得快不快,QPS高不高,吞吐大不大的问题,但没法解决搜索的准不准的问题,即在效果上的问题,需要依赖embedding模型的选择、调优和持续的训练。这并不是狭义上的“向量搜索”的问题,而是一个广义上的NLP(自然语言处理)的问题。
向量搜索的相关性严重依赖于所选择的模型。从下面的测试中我们可以看到,甚至有很多embedding模型的效果还不如BM25+CE。同时也不如稀疏表征的倒排检索。因此,千万别一上来就使用基于KNN或者ANN的向量搜索,因为效果可能远没有你想象的好。而且即便你用正确的方式打开了向量搜索,获得的提升也大多在10%左右(从8x%的召回率到9x%的召回率),对最终的用户体验有多少的帮助,是需要评估的。这种评估应该来自于搜索结果的点击量方面去评估。
要使用向量搜索,我们就必须首先解决文档和query的向量化问题。也就是说,我们需要知道如何选择和使用一个embedding模型。
不同的embedding模型在不同的领域是效果不一样,其原因在于:
针对特定领域,为了获得更好的效果,应考虑以下方法:
因此,如果没有适合自己数据的模型,还不如先用BM25建立自己的基准,再去一一比较效果。
token长度限制
Transformer 本身是自回归的,BERT 的创建者指出,当使用超过 512 个tokens的文档时,性能会显着下降。
而基于Transormer的模型大抵都有这个限制。以下是几种基于Transformer的常见嵌入(embedding)模型:
除了上述模型,还有其他基于 Transformer 的嵌入模型,例如 Transformer-XL、Electra、BERT-base 等。这些模型都基于 Transformer 的架构,因此,我们不仅需要根据具体任务和需求选择合适的基于 Transformer 的嵌入模型,并进行相应的预训练或微调,以获取适用于特定任务的文本嵌入表示,并且在生成嵌入的时候,还需要考虑token的限制。
而对于OpenAI而言,目前,其主要的embedding模型是,token长度限制为:8191。。
而对于其他可以从Huggingface上下载到的模型来说,大部分在model card里面都没有指明其限制,但从来看,一般都是限制在512以下:
(sentence-transformers/facebook-dpr-ctx_encoder-multiset-base)
所以,如果要想用好embedding模型,需要观察自己的输入文档的大小。长文本的输入(比如论文,新闻稿等),需要采用分块(chunking)的策略来处理文件,比如,可以按行、按句子、按段落或按指定的字符数来进行分割。总体原则,就是在不超出限制的情况下,尽量保证切割出来的内容包含完整的语义。常见的处理方法有Clipping(截断法),Pooling(),划窗法,压缩法。可参考:或者
因此,embedding模型是否能够达到期望的相关性,是有非常多的限制的,比如BEIR中的dataset,都是:
另一方面,其实不是所有的数据都应该用于embedding,参考上面的BEIR数据集,能够回答问题的部分才值得做embedding,而一篇文章中,有些部分是适合用用于精确匹配和过滤的,以论文为例:
应该首先使用合适的NLP模型,提取出论文中的类目,作者,引用等信息,这种类型的信息更适合存储于keyword字段中进行全文检索和精确匹配。而对于简介,总结,结果,内容,效果等内容,则进行chunk后,用embedding模型提取特征信息。
embedding模型的资源消耗与利用
另一方面,为了有更好的效果,embedding模型都会倾向于增加模型中的参数以提高上下文的理解能力。一些效果好的embedding模型,甚至能够支持多种语言的语义理解,但也因为参数更多,往往消耗的资源也更大。OpenAI的embedding模型,其模型大小超过300GB。
如果自己使用机器学习平台进行部署,则需要注意资源消耗的问题,在Elasticsearch中,模型是在线程之间共享的。也就是说,模型会被加载到内存当中,并在多个allocation之间共享(allocation越多,并发吞吐越高),而每个allocation又能够通过配置多线程来提高处理能力(线程越多,推理速度越快)
为了能给大模型提供更准确的上下文信息,需要结合不同场景下的最佳方式,才能做到高效且准确。
在实际应用中,我们往往需要结合向量搜索和其他搜索技术,甚至是结合机器学习与NLP推理技术来构建一个高效且灵活的搜索系统。这样可以充分利用各种技术的优势,同时避免各种技术的局限性。以下是一些常见的方法和建议:
而在Elasticsearch的搜索平台中,不仅提供了提升搜索相关性的各种工具,也提供了验证召回和相关性效果的基线测试工具。更得益于社区的支持,可以使用不同的插件在不同的情况下实现优化。
搜索能力的提升不可能一蹴而就,需求的变化和技术的迭代也意味着需要持续的改进。选择一个健壮、完善、被广泛验证过的平台,将是我们有效使用语义搜索,有效的与大模型相集合的良好开端,帮助我们赢在起跑线。