文本向量化检索最佳实践

购买OpenSearch召回引擎版实例

购买实例可参考购买OpenSearch召回引擎版实例

配置实例

新购买的实例,在其详情页中,实例状态为“待配置”,并且会自动部署一个与购买的查询节点和数据节点的个数及规格一致的空集群,之后需要为该集群配置数据源--->索引结构--->索引重建,之后才可正常搜索,点击操作栏下的“配置”按钮。

image.png

配置数据源

配置数据源(目前支持的数据源有“MaxCompute数据源”和“API推送数据源”和“OSS数据源”)这里以MaxCompute数据源为例:点击“添加数据源”,数据源类型选择“MaxCompute”,设置project、AccessKey ID、AccessKey Secret、Table、分组键partition,可按需选择是否开启“自动索引重建”:

image.png

校验成功之后,点击“确定”,完成数据源的添加,等待数据源创建成功:

image.png

配置索引结构

数据源配置成功后,需点击下一步配置索引结构:

image.png

点击添加索引表,配置索引表,填写索引表名称,选择1中的数据源,设置数据分片默认为1,如果设置了MaxCompute数据源,会自动映射数据源字段:

image.png

字段设置,文本向量化是通过系统将文本转换成向量,然后通过向量进行检索数据,因此此处需要配置3个必须字段,如上图(名称均可以自定义):

  1. 主键字段id:类型可以为STRING或者整数类型,需要勾选主键

    image.png

  2. vector_source_text:存储文本内容:

    image.png

  3. vector字段,如果选择“已有向量数据”,该字段的配置保持为空即可,平台转化向量需要高级配置如下:

    image.png

    {
      "vector_model": "ops-text-embedding-000",
      "vector_modal": "text",
      "vector_source_field": "vector_source_text"
    }
    1. vector_model:向量模型,目前支持中英文转化两种模型,

      1. ops-text-embedding-000,短文本转向量模型,维度固定为768。

      2. ops-text-embedding-en-000:英文短文本转向量模型,维度固定768。

    2. vector_modal:向量类型,文本向量

    3. vector_source_field:需要文本向量化的字段,本文中为vector_source_text

    重要

    属性和字段内容压缩

    • 属性字段可以选择是否压缩,默认为不压缩,选择file_compressor表示开启压缩

    • 字段内容可以选择是否压缩,默认为不压缩,默认多值和STRING类型选择uniq,单值数值类型是equal。

    • 使用向量检索,在定义字段时有位置要求,需要按照主键字段、标签字段(非必要)、向量字段的顺序创建。(如上图所示)。

    • 要求vector_source_text的数据,长度不得超过128字节,如果超过会截取前128字节做向量预测。

    • 如果是MaxCompute数据源,从数据源同步字段后,展示在预置字段下方。

    • 主键字段不支持压缩。

    • 字段压缩、属性压缩开启后将节省存储空间,但查询性能可能有所下降。

  4. 索引设置,必要设置的索引为主键索引和向量索引

    image.png

    1. 主键索引:名称自定义,索引类型选择PRIMARYKEY64,包含字段选择字段设置中设置为主键的字段,此处为id。

    2. 向量索引:名称自定义,索引类型选择CUSTOMIZED,包含字段可选择3个,如果没有标签可以不填,但是主键字段和向量字段必选:

      image.png

      向量索引的高级配置中需要将dimension改成768维,固定768维不可修改为其他维度,其他参数建议保持默认:

      image.png

  5. schema示例:

    {
      "file_compress": [
        {
          "name": "file_compressor",
          "type": "zstd"
        },
        {
          "name": "no_compressor",
          "type": ""
        }
      ],
      "table_name": "xiaoming001",
      "summarys": {
        "summary_fields": [
          "id",
          "vector_source_text",
          "cate_id",
          "vector"
        ],
        "parameter": {
          "file_compressor": "zstd"
        }
      },
      "indexs": [
        {
          "index_name": "id",
          "index_type": "PRIMARYKEY64",
          "index_fields": "id",
          "has_primary_key_attribute": true,
          "is_primary_key_sorted": false
        },
        {
          "index_name": "vector",
          "index_type": "CUSTOMIZED",
          "index_fields": [
            {
              "boost": 1,
              "field_name": "id"
            },
            {
              "boost": 1,
              "field_name": "vector"
            }
          ],
          "indexer": "aitheta2_indexer",
          "parameters": {
            "enable_rt_build": "true",
            "min_scan_doc_cnt": "20000",
            "vector_index_type": "Qc",
            "major_order": "col",
            "builder_name": "QcBuilder",
            "distance_type": "SquaredEuclidean",
            "embedding_delimiter": ",",
            "enable_recall_report": "true",
            "ignore_invalid_doc": "true",
            "is_embedding_saved": "false",
            "linear_build_threshold": "5000",
            "dimension": "768",
            "rt_index_params": "{\"proxima.oswg.streamer.segment_size\":2048}",
            "search_index_params": "{\"proxima.qc.searcher.scan_ratio\":0.01}",
            "searcher_name": "QcSearcher",
            "build_index_params": "{\"proxima.qc.builder.quantizer_class\":\"Int8QuantizerConverter\",\"proxima.qc.builder.quantize_by_centroid\":true,\"proxima.qc.builder.optimizer_class\":\"BruteForceBuilder\",\"proxima.qc.builder.thread_count\":10,\"proxima.qc.builder.optimizer_params\":{\"proxima.linear.builder.column_major_order\":true},\"proxima.qc.builder.store_original_features\":false,\"proxima.qc.builder.train_sample_count\":3000000,\"proxima.qc.builder.train_sample_ratio\":0.5}"
          }
        }
      ],
      "attributes": [
        {
          "field_name": "id",
          "file_compress": "no_compressor"
        },
        {
          "field_name": "vector_source_text",
          "file_compress": "no_compressor"
        },
        {
          "field_name": "cate_id",
          "file_compress": "no_compressor"
        },
        {
          "field_name": "vector",
          "file_compress": "no_compressor"
        }
      ],
      "fields": [
        {
          "user_defined_param": {},
          "field_name": "id",
          "field_type": "INT64",
          "compress_type": "equal"
        },
        {
          "field_name": "vector_source_text",
          "field_type": "STRING",
          "compress_type": "uniq"
        },
        {
          "field_name": "cate_id",
          "field_type": "STRING",
          "compress_type": "uniq"
        },
        {
          "user_defined_param": {
            "vector_model": "ops-text-embedding-000",
            "vector_modal": "text",
            "vector_source_field": "vector_source_text"
          },
          "field_name": "vector",
          "field_type": "FLOAT",
          "compress_type": "uniq",
          "multi_value": true
        }
      ]
    }

  6. 配置完成索引表之后,点击发布版本

    image.png

    等待索引表创建完成,点击“下一步”:

索引重建

等待索引表创建完成后,点击下一步:

image.png

选择数据源名称、数据分区、时间戳,点击“下一步”:

image.png

实例配置完成后,点击确定

image.png

变更历史>数据源变更中,等待手动触发全量完成,即可进行查询:

image.png

效果测试

语法介绍

vector:'水壶&modal=text&n=10&search_params={}'&&config=start:0,hit:10,format:json&&kvpairs=formula:proxima_score(vector)&&sort=+RANK
  • modal表示模态类型,modal设置为text

  • n表示指定向量检索返回的top结果数

  • 文本内容需要经过base64编码

通过控制台进行查询测试:

image.png

SDK中检索数据

添加依赖:

pip install alibabacloud-ha3engine

搜索 demo:

# -*- coding: utf-8 -*-


from alibabacloud_ha3engine import models, client
from alibabacloud_tea_util import models as util_models
from Tea.exceptions import TeaException, RetryError
def search():
    Config = models.Config(
        endpoint="参考实例详情页>API入口下的API域名",
        instance_id="",
        protocol="http",
        access_user_name="购买实例时设置的用户名",
        access_pass_word="购买实例时设置的密码"

    )

    # 如用户请求时间较长. 可通过此配置增加请求等待时间. 单位 ms
    # 此参数可在 search_with_options 方法中使用
    runtime = util_models.RuntimeOptions(
        connect_timeout=5000,
        read_timeout=10000,
        autoretry=False,
        ignore_ssl=False,
        max_idle_conns=50
    )

    # 初始化 Ha3Engine Client
    ha3EngineClient = client.Client(Config)

    optionsHeaders = {}

    try:
        # 示例1: 直接使用 ha 查询串进行搜索.
        # =====================================================
        query_str = "config=hit:4,format:json,fetch_summary_type:pk,qrs_chain:search&&query=text_index:'文本内容&modal=text&n=10&search_params={}'&&cluster=general"
        haSearchQuery = models.SearchQuery(query=query_str)
        haSearchRequestModel = models.SearchRequestModel(optionsHeaders, haSearchQuery)
        hastrSearchResponseModel = ha3EngineClient.search(haSearchRequestModel)
        print(hastrSearchResponseModel)
    except TeaException as e:
        print(f"send request with TeaException : {e}")
    except RetryError as e:
        print(f"send request with Connection Exception  : {e}")
说明

其他SDK demo可参考开发指南

注意事项

  • 如果对向量检索耗时有较严格的要求,建议向量索引lock内存

  • 存储文本字段需要设置为STRING。

  • 向量索引需要设置为CUSTOMIZED类型。

  • 该场景支持HA语法、RESTFUL API,不支持SQL。