文档

多模态检索解决方案

更新时间:

针对多模态检索业务场景,PAI提供了端到端的多模态检索解决方案。该解决方案提供了图像、人脸、文本、文图和图文检索等服务,支持您通过调用EAS服务实现注册多模态数据、提取相关特征、基于ID管理多模态数据、基于特征的多模态数据搜索等功能。本文为您介绍该解决方案的使用流程。

背景信息

功能支持

  • 多模态特征提取能力:您可以使用基于Alibaba PAI EasyCV或EasyNLP提供的预训练模型,或者是您使用DSW平台训练获得的图像特征提取模型、文本向量化模型或文图CLIP模型部署服务。

  • 特征检索能力:该服务默认使用基于DocArray-PAI和AliyunOSS的可持久化、可快速检索的特征数据库能力,支持您存储相关特征到AliyunOSS或从AliyunOSS拉起特征。例如:该服务中存储了10万特征,保存数据库并关闭服务,初始化服务时,不需要再注册特征数据,即可搜索特征。您也可以配置其他检索产品,例如AliyunElasticSearch。

服务概览

image
  • 目前,多模态检索解决方案支持部署的服务类型为:图像检索(image_retrieval)、人脸检索(faceid_retrieval),文本检索(text_retrieval)、中文多模态检索(imagetext_retrieval_cn)和英文多模态检索(imagetext_retrieval_en)。

  • 各服务提供的调用接口为:服务初始化接口(init、set_root_path等)、数据库管理层接口(add、delete等)和数据库层接口(db_set、db_get等)。

使用流程

多模态检索解决方案的使用流程如下。

  1. 构建模型

    使用PAI提供的预训练模型,或在DSW平台参考Gallery示例自行构建模型。

  2. 部署模型服务

    通过模型在线服务EAS,您可以将训练好的模型或PAI提供的预训练模型部署为在线服务。

  3. 调用模型服务

    通过RESTful API方式调用服务初始化接口、数据库管理层接口和数据库层接口,实现多模态数据检索。

前提条件

在开始执行操作前,请确认您已完成以下准备工作:

  • 已开通PAI(DSW、EAS)后付费,并创建默认工作空间,详情请参见创建工作空间

  • 已创建OSS存储空间(Bucket),用于存储数据集、训练获得的模型文件和配置文件。关于如何创建存储空间,详情请参见控制台创建存储空间

  • 已创建EAS专属资源组,用于部署训练好的模型。建议创建T4、A10或V100等规格类型的GPU机器,关于如何创建专属资源组,详情请参见使用专属资源组

  • 已创建DSW实例,且运行正常。建议镜像选择Pytorch1.8,GPU机型为P100或V100,内存大于32 GB,详情请参见创建及管理DSW实例

构建模型

您可以使用PAI提供的预训练模型,具体如下表所示。

模型类型

Processor种类

Predictor

模型路径

image_retrieval

(图像检索)

EasyCV

easycv.predictors.feature_extractor.TorchFeatureExtractor

http://pai-vision-data-hz.oss-accelerate.aliyuncs.com/pretrained_models/deepfashion2/df2_1536_easycv061.pth

faceid_retrieval

(人脸检索)

EasyCV

easycv.predictors.feature_extractor.TorchFaceFeatureExtractor

http://pai-vision-data-hz.oss-accelerate.aliyuncs.com/pretrained_models/faceid/resnet50/faceid_resnet50.tar.gz

imagetext_retrieval_cn

(中文CLIP)

EasyNLP

easynlp.appzoo.CLIPPredictor

http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/easynlp_modelzoo/alibaba-pai/clip_chinese_roberta_base_vit_base.tgz

imagetext_retrieval_en

(英文CLIP)

EasyNLP

easynlp.appzoo.CLIPPredictor

http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/easynlp_modelzoo/openai/clip_vit_base_patch32.tgz

text_retrieval

(文本向量化模型)

EasyNLP

easynlp.appzoo.FeatureVectorizationPredictor

http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/easynlp_modelzoo/public/bert-base-uncased.tgz

您也可以在DSW平台参考Gallery示例自行构建模型,具体操作步骤如下。

  1. 进入DSW Gallery页面,详情请参见功能试用:Gallery

  2. 在DSW Gallery页面,构建以下两种模型。

    • 多模态检索模型

      名称或描述文本框中输入CLIP,然后按回车键。在右侧的基于EasyNLP的多模态CLIP图文检索区域,单击在阿里云DSW打开,并按照控制台操作指引构建多模态检索模型。image.png

    • 图像检索模型

      名称或描述文本框中输入Swin Transformer,然后按回车键。在右侧的基于SwinTransformer的图像分类示例区域,单击在阿里云DSW打开,并按照控制台操作指引构建图像检索模型。image.png

  3. 将训练后得到的模型,上传到OSS,详情请参见控制台上传文件

部署模型服务

通过模型在线服务EAS,您可以将训练好的模型部署为在线服务,具体操作步骤如下。

  1. 进入PAI-EAS 模型在线服务页面。

    1. 登录PAI控制台

    2. 在左侧导航栏单击工作空间列表,在工作空间列表页面中单击待操作的工作空间名称,进入对应工作空间内。

    3. 在工作空间页面的左侧导航栏选择模型部署 > 模型在线服务(EAS),进入PAI-EAS 模型在线服务页面。

  2. 部署模型服务。

    1. PAI-EAS 模型在线服务页面,单击部署服务,在弹出对话框中,选择自定义部署,然后单击确定

    2. 部署服务页面,配置参数。image

      将以下JSON文件内容粘贴到对应配置编辑下的文本框中。

      {
          "data_image": "registry.cn-shanghai.aliyuncs.com/pai-ai-test/eas-service:easy_retrieval_docarray_v203",
          "metadata": {
              "cpu": 12,
              "gpu": 1,
              "instance": 1,
              "memory": 25000,
              "name": "clip_retrieval_0303",
              "resource": "eas-r-shry2upmfr5jod****"
          },
          "model_config": "{\"type\":\"imagetext_retrieval_cn\"}",
          "model_path": "http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/easynlp_modelzoo/alibaba-pai/clip_chinese_roberta_base_vit_base.tgz",
          "name": "clip_retrieval_0303",
          "processor_entry": "./app.py",
          "processor_path": "http://pai-vision-exp.oss-cn-zhangjiakou.aliyuncs.com/wzh-zhoulou/dl_eas_processor/easy_retrieval_docarray/230308/eas_processor_20230113.tar.gz",
          "processor_type": "python"
      }

      其中关键参数配置如下,其他参数使用JSON文件中的配置,更多关于参数配置说明,详情请参见服务部署:控制台&Designer

      参数

      描述

      name

      需要替换为您自己的服务名称,您可以直接在控制台模型服务信息区域修改该参数。

      model_config

      模型类型,支持以下取值,请根据您部署的模型进行替换。

      • {\"type\":\"faceid_retrieval\"}:人脸检索模型。

      • {\"type\":\"image_retrieval\"}:图像检索模型。

      • {\"type\":\"imagetext_retrieval_cn\"}:中文CLIP模型。

      • {\"type\":\"imagetext_retrieval_en\"}:英文CLIP模型。

      • {\"type\":\"text_retrieval\"}:文本向量化模型。

      • {\"type\":\"imagetext_retrieval_cn/en\"}:多模态检索模型。

      model_path

      如果是使用DSW平台自行构建的模型,则需要替换为模型所在的OSS Bucket路径。

      如果是使用PAI提供的预训练模型,则需要替换为构建模型章节中模型路径列内容即可。您可以直接在控制台模型服务信息区域修改该参数。

      resource

      需要替换为您自己的资源组,您可以直接在控制台模型服务信息区域修改该参数。

    3. 单击部署,等待一段时间即可完成模型部署。

调用模型服务

服务调用方式

完整的POST调用代码如下。

import requests, json
head = {
    "Authorization":"xxxxxx"#head为部署服务后,PAI-EAS返回的服务调用密钥Token对应的字符串。
}

our_oss_io_config = dict(ak_id='xxxxxx',
                         ak_secret='xxxxxx',
                         hosts='oss-*****-internal.aliyuncs.com',
                         buckets=['examplebucket'])

datas = json.dumps({
    "function_name": "XXX"  #必选,调用接口的名称。
    "function_params": {
        param1: XXX #参考不同接口对应的参数说明。
        param2:
        ....
    },
})
hosts = "xxxxxx/test"
r = requests.post(hosts, data=datas, headers=head)

其中关键参数配置如下所示。

参数

描述

Authorization

目标服务Token。服务部署完成后,您可以在目标服务服务方式列下的调用信息中获取。

our_oss_io_config.ak_id

阿里云账号的AccessKey ID。

our_oss_io_config.ak_secret

阿里云账号的AccessKey Secret。

our_oss_io_config.hosts

您OSS地域的Endpoint。OSS地域与Endpoint的对应关系,请参见访问域名和数据中心

重要

需要配置为对应地域的内网Endpoint,否则访问不通。

our_oss_io_config.buckets

您创建的OSS存储空间(Bucket)的名称。

function_name

接口名称,支持以下取值:

  • 服务初始化接口,包括init、set_root_path、set_oss_config、set_predictor。

  • 数据库管理层接口,包括add、delete、get、load、save。

  • 数据库层接口,包括db_set、db_get、db_delete、db_search。

function_params

参数配置,详情请参见function_name对应的接口说明。

hosts

公网调用的访问地址,服务部署完成后,您可以在目标服务服务方式列下的调用信息中获取。

接口使用示例如下。

  • 服务初始化接口-set_root_path

    • POST代码示例

      datas = json.dumps({
          "function_name" :"set_root_path",
          "function_params" : {
              "root_path": "oss://examplebucket/ljh-xiaoling/da_test/",
          },
      })
    • POST返回示例(请求成功)

      {
        "request_id": "b576c16e-7fe2-46d4-9502-35771*******",
        "success": True, 
        "info": "None", 
      }
  • 数据库管理层接口-save

    • POST代码示例

      datas = json.dumps({
          "function_name" : "save",
          "function_params" : {},
      })
    • POST返回示例(请求成功)

      {
        "request_id": "f355c3d9-d235-41dd-b262-695966******",
        "success": True, 
        "save": "Done", 
      }
  • 数据库接口-db_search

    • POST代码示例

      datas = json.dumps({
          "function_name": "db_search",
          "function_params": {
              "database_name": "test_1",
              "uri": "oss://examplebucket/ljh-xxxx/da_test/000001.jpeg",
              "search_topk": 2,
              "metric" : "cosine"
          },
      })
    • POST返回示例(请求成功)

      {
        "request_id": "70c2d344-adf9-4b07-b888-cabce0******",
        "success": True, 
        "db_search": [[{'scores': 0.4860914349555969, 'uri': 'oss://pai-vision-exp/ljh-xiaoling/data/image/000015.jpg', 'text': '', 'group_id': '0', 'intra_id': 0}]]
      }

服务调用示例

多模态、图像检索服务首先需要建立多模态、图像检索数据库,然后将注册到数据库中的多模态数据、图像进行特征提取,最后从多模态、图像数据库的数据中,对上传的多模态数据、图像进行相似快速检索。整个过程需要使用的接口包括数据库初始化、增加数据库、增加数据及检索数据等接口。下文提供一个简单的示例供您参考。

  1. 创建数据库初始化的Python脚本retrieval_init.py。

    import requests, json
    head = {
        "Authorization":"xxxxxx"#head为部署服务后,EAS返回的服务调用密钥Token对应的字符串。
    }
    
    our_oss_io_config = dict(ak_id='xxxxxx', # 阿里云账号的AccessKey。
                             ak_secret='xxxxxx', # 阿里云账号的AccessKey Secret。
                             hosts='oss-cn-****-internal.aliyuncs.com', # 内网Endpoint。
                             buckets=['examplebucket']) # OSS Bucket。
    
    datas = json.dumps({
        "function_name": "init",
        "function_params": {
            "backend": "oss",
            "root_path": "oss://examplebucket/xxx",
            "oss_io_config" : our_oss_io_config,
        },
    })
    hosts = 'http://16640818xxxxxx.cn-hangzhou.pai-eas.aliyuncs.com/api/predict/img_retrieval_001'
    head = {
                "Authorization":"NTE3Y2M2ZmEzZGQ3ZGRkOGM4ZDE1MDxxxxxxxxxxxxxx"
            }
    r = requests.post(hosts, data=datas, headers=head)
    print(r.content)
    print("test ending")
  2. 创建增加数据库的Python脚本retrieval_add.py。

    import requests
    import json
    
    ENCODING = 'utf-8'
    datas = json.dumps({
                'function_name': 'add',
                'function_params': {
                    'database_name': 'test_1',
                },
            })
    hosts = 'http://16640818xxxxxx.cn-hangzhou.pai-eas.aliyuncs.com/api/predict/img_retrieval_001'
    head = {
                "Authorization":"NTE3Y2M2ZmEzZGQ3ZGRkOGM4ZDE1MDxxxxxxxxxxxxxx"
            }
    r = requests.post(hosts, data=datas, headers=head)
    print(r.content)
    print("test ending")
  3. 创建注册数据的Python脚本retrieval_set_predictor.py

    增加数据库后,该数据库需要指定Predictor。

    import requests
    import json
    
    ENCODING = 'utf-8'
    datas = json.dumps({
        "function_name": "set_predictor",
        "function_params": {
            "predictor" : 'CLIPPredictor',
            'preprocess': 'load_uri_to_base64str',
        },
    })
    hosts = 'http://16640818xxxxxx.cn-hangzhou.pai-eas.aliyuncs.com/api/predict/img_retrieval_001'
    head = {
                "Authorization":"NTE3Y2M2ZmEzZGQ3ZGRkOGM4ZDE1MDxxxxxxxxxxxxxx"
            }
    r = requests.post(hosts, data=datas, headers=head)
    print(r.content)
    print("test ending")
  4. 创建增加数据的Python脚本retrieval_db_set.py。

    import requests
    import json
    
    ENCODING = 'utf-8'
    datas = json.dumps({
                'function_name': 'db_set',
                'function_params': {
                    'database_name': 'test_1',
                    'uri': [
                        'oss://examplebucket/ljh-xxxx/data/image/000015.jpg', 
                    ],
                    'group_id': ['0'], # 存入该数据的群组名。
                    'embedding_attr': 'uri'
                },
            })
    hosts = 'http://16640818xxxxxx.cn-hangzhou.pai-eas.aliyuncs.com/api/predict/img_retrieval_001'
    head = {
                "Authorization":"NTE3Y2M2ZmEzZGQ3ZGRkOGM4ZDE1MDxxxxxxxxxxxxxx"
            }
    r = requests.post(hosts, data=datas, headers=head)
    print(r.content)
    print("test ending")
  5. 创建检索数据的Python脚本retrieval_db_search.py。

    import requests
    import json
    
    ENCODING = 'utf-8'
    datas = json.dumps({
                'function_name': 'db_search',
                'function_params': {
                    'database_name': 'test_1',
                    'uri': 'oss://examplebucket/ljh-xxxx/da_test/000001.jpeg',
                    'search_topk': 1, # 返回的最相似的k个数据
                    'metric': 'cosine'
                },
            })
    hosts = 'http://16640818xxxxxx.cn-hangzhou.pai-eas.aliyuncs.com/api/predict/img_retrieval_001'
    head = {
                "Authorization":"NTE3Y2M2ZmEzZGQ3ZGRkOGM4ZDE1MDxxxxxxxxxxxxxx"
            }
    r = requests.post(hosts, data=datas, headers=head)
    print(r.content)
    print("test ending")
  6. 将上述创建的Python脚本全部上传至您的任意环境,并在脚本上传后的当前目录依次执行调用命令。

    python <retrieval_xxx.py>

    其中<retrieval_xxx.py>需要替换为实际的Python脚本名称。

  7. 针对部署好的数据库,进行目标图像检索,即调用检索数据脚本。

    python retrieval_db_search.py

    得到的推理预测结果如下所示。

    {"request_id": "d4b4c7c5-2330-49d5-8ffb-a15e490b****", "success": true, "info": [[{"scores": 0.0, "uri": "oss://pai-vision-exp/xxx/000001.jpeg", "text": "", "group_id": "0", "intra_id": 0}]]}

    从上述模型推理的返回结果可以看出,模型服务返回了该数据库中与目标图像相似度最高的图片的uri。

  • 本页导读 (1)
文档反馈