AIxiv专栏是本站发布学术、技术内容的栏目。过去数年,本站AIxiv专栏接收报道了2000多篇内容,覆盖全球各大高校与企业的顶级实验室,有效促进了学术交流与传播。如果您有优秀的工作想要分享,欢迎投稿或者联系报道。投稿邮箱:liyazhou@jiqizhixin.com;zhaoyunfeng@jiqizhixin.com
本文作者是来自 OpenSearch 中国研发团队的机器学习负责人杨扬博士以及机器学习工程师耿志超和管聪。OpenSearch 是一个由亚马逊云科技发起的纯开源搜索和实时分析引擎项目。目前软件超过 5 亿下载量,社区在全球拥有 70 个以上的企业合作伙伴。
自从大模型爆火以来,语义检索也逐渐成为一项热门技术。尤其是在 RAG(retrieval augmented generation)应用中,检索结果的相关性直接决定了 AI 生成的最终效果。Relevance Demo
稀疏编码与稠密编码对比
由于稀疏编码所产生的 token - 权值组合,与传统文本匹配方法采用的 term-vector 非常类似,所以在 OpenSearch 中可以采用原生的 Lucene 索引去存储文档稀疏编码。相较于 k-NN 搜索引擎,原生的 Luence 引擎会更加轻便,占用的资源也较少。*整个系统在只运行 OpenSearch 时的内存,包括 JVM 的堆内和堆外内存
在陌生数据集上的自适应性部分数据集上几个方法的相关性表现比较
我们在实验中发现稀疏编码在陌生数据集上的表现要优于稠密编码。虽然目前还没有更加详细的量化数据来印证,但根据在部分样本上的分析,其优势主要在两点:1)稀疏编码在近义词的联想方面更加突出,2)在遇到完全陌生的文本表述,例如一些专业术语,稀疏编码会更倾向于增强这些术语 token 的权值而弱化联想出的 token 的权值,使得检索过程向关键词匹配退化,追求的一个稳定的相关性表现。两阶段式搜索速度对比
用 5 步在 OpenSearch 中搭建 Neural Sparse 语义检索应用PUT /_cluster/settings{"transient" : {"plugins.ml_commons.allow_registering_model_via_url" : true,"plugins.ml_commons.only_run_on_ml_node" : false,"plugins.ml_commons.native_memory_threshold" : 99}}
2. 部署编码器
Opensearch 目前开源了 3 个模型。相关注册信息都可以在官方文档中获取。我们以 amazon/neural-sparse/opensearch-neural-sparse-encoding-v1 为例,首先使用 register API 来注册:
POST /_plugins/_ml/models/_register?deploy=true{ "name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-v1", "version": "1.0.1", "model_format": "TORCH_SCRIPT"}在集群的返回中,可以看到 task_id
{"task_id": " ","status": "CREATED"}
用 task_id 来得到详细的注册信息:
GET /_plugins/_ml/tasks/
在 API 返回中,我们可以拿到具体的 model_id:
{"model_id": " ","task_type": "REGISTER_MODEL","function_name": "SPARSE_TOKENIZE","state": "COMPLETED","worker_node": ["wubXZX7xTIC7RW2z8nzhzw"], "create_time":1701390988405,"last_update_time": 1701390993724,"is_async": true}
在索引之前,每个文档需要被编码的文本字段需要被转变成稀疏向量。在 OpenSearch 中,这一过程是通过预处理器来自动实现的。你可以使用以下 API 来创建离线索引时的处理器管线:
PUT /_ingest/pipeline/neural-sparse-pipeline{ "description": "An example neural sparse encoding pipeline", "processors" : [ { "sparse_encoding": { "model_id": " ", "field_map": { "passage_text": "passage_embedding" } } } ]}
如果需要开启两阶段加速功能 (非必需功能),则需要建立一个两阶段搜索管线,并在索引建立之后设置为默认的搜索管线。
建立一个默认参数的两阶段加速搜索管线方式如下,更详细的参数设置和意义请参考 2.15 及以后版本的 OpenSearch 官方文档。
PUT /_search/pipeline/two_phase_search_pipeline{ "request_processors": [ { "neural_sparse_two_phase_processor": { "tag": "neural-sparse", "description": "This processor is making two-phase processor." } } ]}
4. 设置索引
神经稀疏搜索利用 rank_features 字段类型来存储编码得到的词元和相对应的权重。索引将使用上述预处理器来编码文本。我们可以按以下方式创建索一个包含两阶段搜索加速管线的索引(如果不想开启此功能,可把 `two_phase_search_pipeline` 替换为 `_none` 或删除 `settings.search` 这一配置单元)。
PUT /my-neural-sparse-index{ "settings": { "ingest":{ "default_pipeline":"neural-sparse-pipeline" }, "search":{ "default_pipeline":"two_phase_search_pipeline" } }, "mappings": { "properties": { "passage_embedding": { "type": "rank_features" }, "passage_text": { "type": "text" } } }}
PUT /my-neural-sparse-index/_doc/{ "passage_text": "Hello world"}
在索引中进行稀疏语义搜索的接口如下,将 替换为第二步中注册的 model_id:
GET my-neural-sparse-index/_search{ "query":{ "neural_sparse":{ "passage_embedding":{ "query_text": "Hi world", "model_id": } } }}