本文使用文本嵌入模型(text_embedding)对用户查询进行深度语义解析,突破传统关键词匹配的局限,从海量数据中准确提取高度相关的内容。使用问答模型(question_answering)对关联文本进行精细解读,精准抽取答案,回答与文本相关的问题。文本嵌入模型和问答模型的组合可以用于智能搜索引擎、个性化推荐等场景,可以提升信息检索和问题解答的精准度。
准备工作
上传模型
本文选择huggingface仓库中的question_answering模型luhua/chinese_pretrain_mrc_macbert_large和text_embedding模型thenlper/gte-large-zh。将模型上传到阿里云ES中,请参见通过Eland上传第三方NLP模型。
由于中国内地网络访问huggingface较慢,本文采用离线上传模型的方式。
下载模型。
将模型上传到ECS中。
在ECS的根目录下新建一个文件夹,例如model,将模型上传到该文件夹中,请不要将模型上传到/root/目录下。
由于模型比较大,建议通过WinSCP的方式上传,请参见通过WinSCP上传或下载文件(本地主机为Windows)。
在ECS中执行如下命令,在模型文件目录下解压模型。
cd /model/ tar -xzvf luhua--chinese_pretrain_mrc_macbert_large.tar.gz tar -xzvf thenlper--gte-large-zh.tar.gz cd
在ECS中执行如下命令,将模型上传到ES中。
上传问答模型luhua--chinese_pretrain_mrc_macbert_large:
eland_import_hub_model --url 'http://es-cn-lbj3l7erv0009****.elasticsearch.aliyuncs.com:9200' --hub-model-id '/model/root/.cache/huggingface/hub/models--luhua--chinese_pretrain_mrc_macbert_large/snapshots/f2d95d06f16a3043002c9702f66c834f4e0aa944' --task-type question_answering --es-username elastic --es-password **** --es-model-id models--luhua--chinese_pretrain_mrc_macbert_large \
上传文本嵌入模型thenlper--gte-large-zh:
eland_import_hub_model --url 'http://es-cn-lbj3l7erv0009****.elasticsearch.aliyuncs.com:9200' --hub-model-id '/model/root/.cache/huggingface/hub/models--thenlper--gte-large-zh/snapshots/952432e6b99137bbfd8397d5ad92f920be5f22e9' --task-type text_embedding --es-username elastic --es-password **** --es-model-id models--thenlper--gte-large-zh \
部署模型
登录Kibana。具体操作,请参见登录Kibana控制台。
单击Kibana页面左上角的图标,选择Analytics > Machine Learning。
在左侧菜单栏,单击模型管理(Model Management) > 已训练模型(Trained Models)。
(可选)在页面上方,单击同步作业和已训练模型(Synchronize your jobs and trained models),在弹出的面板中单击同步(Synchronize)。
将鼠标移动到目标模型操作(Actions)列的前面,单击图标,启动模型。
在弹出的对话框中,配置模型后,单击启动(Start)。
页面右下角弹出已成功启动的提示对话框,表明模型部署成功。
说明模型无法启动可能是集群内存不足,升配集群后再试。无法启动的具体原因,请在提示对话框中单击请参阅完整的错误信息查看。
验证模型的可用性
单击Kibana页面左上角的图标,选择Management > 开发工具(Dev Tools)。
验证模型的可用性
执行以下命令,验证问答模型models--luhua--chinese_pretrain_mrc_macbert_large的可用性。
POST /_ml/trained_models/models--luhua--chinese_pretrain_mrc_macbert_large/_infer { "docs":[{"text_field": "没有必要。安装两个杀毒软件可以增强电脑的安全性,但是会导致以下弊端: 占用硬盘资源过多; 在同时启用两款软件的实时防护时,会导致系统硬件资源大量损耗,例如CPU处理过多,导致计算机工作能力下降; >在进行杀毒时,会导致系统占用资源过多,不但可能影响系统工作能力,还可能误报对方组件,导致.."}], "inference_config": {"question_answering": {"question": "电脑可以同时安装多个杀毒软件吗"}} }
返回结果如下所示,结果符合预期。
{ "inference_results": [ { "predicted_value": "没有必要", "start_offset": 0, "end_offset": 4, "prediction_probability": 0.8775923604355836 } ] }
执行以下命令,验证文本嵌入模型models--thenlper--gte-large-zh的可用性。
POST /_ml/trained_models/models--thenlper--gte-large-zh/_infer { "docs":[{"text_field": "没有必要。安装两个杀毒软件可以增强电脑的安全性,但是会导致以下弊端: 占用硬盘资源过多; 在同时启用两款软件的实时防护时,会导致系统硬件资源大量损耗,例如CPU处理过多,导致计算机工作能力下降; >在进行杀毒时,会导致系统占用资源过多,不但可能影响系统工作能力,还可能误报对方组件,导致.."}] }
部分返回结果如下所示,结果符合预期。
{ "inference_results": [ { "predicted_value": [ 1.389997959136963, -0.6398589611053467, -0.5746312737464905, -0.5629222393035889, -0.49914881587028503, 0.5277091264724731, -1.2194437980651855, 0.19847321510314941, .............. 0.6711148619651794, 1.6224931478500366, 2.0970489978790283, -0.4506820738315582, -0.298383504152298 ] } ] }
准备数据集
索引数据时需要示例数据集。
下载示例数据集。
文本以extracted_data.json数据集为例,请参见extracted_data.json。
将数据集上传到ECS中,例如文本将数据集上传到/model/目录下。
步骤一:索引数据
通过ingest pipeline在索引中配置模型,以便在数据写入过程中完成文本转换。
说明针对索引已存储数据需要应用模型完成向量转换,请参见reindex方式重建索引。
PUT _ingest/pipeline/text-embedding-pipeline { "processors": [ { "inference": { "model_id": "models--thenlper--gte-large-zh", "target_field": "text_embedding", "field_map": { "context": "text_field" } } } ] } #####创建索引mapping,指定ingest pipeline PUT question_answering { "settings": { "index": { "number_of_shards": 2, "number_of_replicas": 1, "default_pipeline": "text-embedding-pipeline" } }, "mappings": { "properties": { "text_embedding.predicted_value": { "type": "dense_vector", "dims": 1024, "index": true, "similarity": "l2_norm" }, "context": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } }
通过Python导入准备的数据集(python 3.10):
# -*- coding:utf-8 -*- import json from pprint import pprint import os import time from elasticsearch import helpers import time from elasticsearch import Elasticsearch elastic_user="elastic" elastic_password="****" elastic_endpoint="es-cn-lbj3l7erv0009****.elasticsearch.aliyuncs.com" url = f"http://{elastic_user}:{elastic_password}@{elastic_endpoint}:9200" es = Elasticsearch(url) print(es.info()) with open('/model/extracted_data.json') as f: data_json = json.load(f) # Prepare the documents to be indexed documents = [] for doc in data_json: documents.append({ "_index": "question_answering", "_source": doc, }) # Use helpers.bulk to index helpers.bulk(es, documents) print("Done indexing documents into `question_answering` index!") time.sleep(5)
步骤二、通过kibana检索
以“阿里云Elasticsearch应用场景有哪些”问题为例,在kibana上进行检索演示:
单击Kibana页面左上角的图标,选择Management > 开发工具(Dev Tools)。
调用阿里云ES机器学习推理接口,将文档转换为向量数据。
ES 8.7及以上版本
ES 8.7及以上版本可以通过query_vector_builder构建。
GET question_answering/_search { "_source": ["context","title"], "knn": { "field": "text_embedding.predicted_value", "k": 5, "num_candidates": 10, "query_vector_builder": { "text_embedding": { "model_id": "models--thenlper--gte-large-zh", "model_text": "阿里云elasticsearch应用场景有哪些" } } } }
返回结果如下所示,可以看出前5条文档和ES相关性比较大,第一条内容主要介绍阿里云ES服务。
{ "took": 30, "timed_out": false, "_shards": { "total": 2, "successful": 2, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 5, "relation": "eq" }, "max_score": 0.003581697, "hits": [ { "_index": "question_answering", "_id": "evdbaI0BU_1of7kX5_Hn", "_score": 0.003581697, "_source": { "context": "阿里云Elasticsearch是基于开源Elasticsearch构建的全托管Elasticsearch云服务,在100%兼容开源功能的同时,支持开箱即用、按需付费。不仅提供云上开箱即用的Elasticsearch、Logstash、Kibana、Beats在内的Elastic Stack生态组件,还与Elastic官方合作提供免费X-Pack(白金版高级特性)商业插件,集成了安全、SQL、机器学习、告警、监控等高级特性,被广泛应用于实时日志分析处理、信息检索、以及数据的多维查询和统计分析等场景。", "title": "什么是阿里云Elasticsearch" } }, { "_index": "question_answering", "_id": "2VBdaI0Bg5EzGjIAN-Tx", "_score": 0.003581697, "_source": { "context": "阿里云Elasticsearch是基于开源Elasticsearch构建的全托管Elasticsearch云服务,在100%兼容开源功能的同时,支持开箱即用、按需付费。不仅提供云上开箱即用的Elasticsearch、Logstash、Kibana、Beats在内的Elastic Stack生态组件,还与Elastic官方合作提供免费X-Pack(白金版高级特性)商业插件,集成了安全、SQL、机器学习、告警、监控等高级特性,被广泛应用于实时日志分析处理、信息检索、以及数据的多维查询和统计分析等场景。", "title": "什么是阿里云Elasticsearch" } }, { "_index": "question_answering", "_id": "t49gaI0BNqB2ciGcDbmF", "_score": 0.003581697, "_source": { "context": "阿里云Elasticsearch是基于开源Elasticsearch构建的全托管Elasticsearch云服务,在100%兼容开源功能的同时,支持开箱即用、按需付费。不仅提供云上开箱即用的Elasticsearch、Logstash、Kibana、Beats在内的Elastic Stack生态组件,还与Elastic官方合作提供免费X-Pack(白金版高级特性)商业插件,集成了安全、SQL、机器学习、告警、监控等高级特性,被广泛应用于实时日志分析处理、信息检索、以及数据的多维查询和统计分析等场景。", "title": "什么是阿里云Elasticsearch" } }, { "_index": "question_answering", "_id": "efdbaI0BU_1of7kX5_Hn", "_score": 0.0027631863, "_source": { "context": "登录Kibana控制台的具体操作,请参见登录Kibana控制台。Kibana控制台的用户名默认为elastic,密码为您创建阿里云Elasticsearch实例时设置的密码。如果忘记密码可以重置,重置密码的注意事项及具体操作,请参见重置实例访问密码。", "title": "如何登录Kibana控制台,用户名和密码是什么?" } }, { "_index": "question_answering", "_id": "2FBdaI0Bg5EzGjIAN-Tx", "_score": 0.0027631863, "_source": { "context": "登录Kibana控制台的具体操作,请参见登录Kibana控制台。Kibana控制台的用户名默认为elastic,密码为您创建阿里云Elasticsearch实例时设置的密码。如果忘记密码可以重置,重置密码的注意事项及具体操作,请参见重置实例访问密码。", "title": "如何登录Kibana控制台,用户名和密码是什么?" } } ] } }
ES 8.7以下版本
调用ES机器学习推理接口。
POST /_ml/trained_models/thenlper__gte-large-zh/_infer { "docs":[{"text_field": "阿里云elasticsearch应用场景有哪些"}] }
返回结果如下所示:
复制向量数据,使用knn搜索索引中相似的文档。
GET question_answering/_search { "_source": ["context","title"], "knn": { "field": "text_embedding.predicted_value", "k": 5, "num_candidates": 10, "query_vector": [ 0.2767493426799774, 0.05577810853719711, 0.2760164141654968, -0.9484721422195435, .............. 0.8358230590820312, 0.6053569316864014, -0.5380803942680359 ] } }
将第一个文档的context复制下来调用QA模型实现问答。
POST /_ml/trained_models/models--luhua--chinese_pretrain_mrc_macbert_large/_infer { "docs":[{"text_field": "阿里云Elasticsearch是基于开源Elasticsearch构建的全托管Elasticsearch云服务,在100%兼容开源功能的同时,支持开箱即用、按需付费。不仅提供云上开箱即用的Elasticsearch、Logstash、Kibana、Beats在内的Elastic Stack生态组件,还与Elastic官方合作提供免费X-Pack(白金版高级特性)商业插件,集成了安全、SQL、机器学习、告警、监控等高级特性,被广泛应用于实时日志分析处理、信息检索、以及数据的多维查询和统计分析等场景"}], "inference_config": {"question_answering": {"question": "阿里云elasticsearch应用场景有哪些"}} }
返回结果如下:
{ "inference_results": [ { "predicted_value": "实时日志分析处理", "start_offset": 220, "end_offset": 228, "prediction_probability": 0.014678373776954107 } ] }
步骤三:模拟问答场景
在ECS中执行Python3
加载Python环境后,执行以下命令模拟问答场景。
# -*- coding:utf-8 -*-
import json
from pprint import pprint
import os
import time
from elasticsearch import helpers
import time
from elasticsearch import Elasticsearch
elastic_user="elastic"
elastic_password="Es123456"
elastic_endpoint="es-cn-lbj3l7erv0009bz81.public.elasticsearch.aliyuncs.com"
url = f"http://{elastic_user}:{elastic_password}@{elastic_endpoint}:9200"
es = Elasticsearch(url)
question = input("请输入您的问题: ")
query_args = {
"field": "text_embedding.predicted_value",
"k": 5,
"num_candidates": 10,
"query_vector_builder": {
"text_embedding": {
"model_id": "models--thenlper--gte-large-zh",
"model_text": question
}
}
}
result=es.search(index="question_answering",source=["context","title"],knn=query_args)
# print(result["hits"]["hits"])
concatenated_content = ""
for hit in result["hits"]["hits"]:
context=hit["_source"]["context"]
concatenated_content += context+" "
#print(concatenated_content)
docs=[{"text_field": concatenated_content}]
inference_config= {"question_answering": {"question": question}}
response=es.ml.infer_trained_model(model_id="models--luhua--chinese_pretrain_mrc_macbert_large",docs=docs,inference_config=inference_config)
print("推理结果是: ")
print(response["inference_results"][0]["predicted_value"])
返回结果如下所示。
请输入您的问题:
张家港高铁站位置在哪
推理结果是:
塘桥镇新204国道东侧,人民路北路