針對多模態檢索業務場景,PAI提供了端到端的多模態檢索解決方案。該解決方案提供了圖像、人臉、文本、文圖和圖文檢索等服務,支持您通過調用EAS服務實現注冊多模態數據、提取相關特征、基于ID管理多模態數據以及基于特征的多模態數據搜索等功能。本文為您介紹該解決方案的使用流程。
背景信息
功能支持
多模態特征提取能力:您可以使用基于Alibaba PAI EasyCV或EasyNLP提供的預訓練模型,或通過DSW平臺訓練獲得的圖像特征提取模型、文本向量化模型以及文圖CLIP模型部署服務。
特征檢索能力:該服務默認使用基于DocArray-PAI和AliyunOSS的可持久化、可快速檢索的特征數據庫能力,支持您存儲相關特征到AliyunOSS或從AliyunOSS拉起特征。例如:該服務中存儲了10萬特征,保存數據庫并關閉服務以及初始化服務時,不需要再注冊特征數據,即可搜索特征。您也可以配置其他檢索產品,例如AliyunElasticSearch。
服務概覽
目前,多模態檢索解決方案支持部署的服務類型為:圖像檢索(image_retrieval)、人臉檢索(faceid_retrieval),文本檢索(text_retrieval)、中文多模態檢索(imagetext_retrieval_cn)和英文多模態檢索(imagetext_retrieval_en)。
各服務提供的調用接口為:服務初始化接口(init、set_root_path等)、數據庫管理層接口(add、delete等)和數據庫層接口(db_set、db_get等)。
使用流程
多模態檢索解決方案的使用流程如下。
使用PAI提供的預訓練模型,或在DSW平臺參考Gallery示例自行構建模型。
通過模型在線服務EAS,您可以將訓練好的模型或PAI提供的預訓練模型部署為在線服務。
通過API方式調用服務初始化接口、數據庫管理層接口和數據庫層接口,實現多模態數據檢索。
前提條件
在開始執行操作前,請確認您已完成以下準備工作:
已開通PAI(DSW、EAS)后付費,并創建默認工作空間,詳情請參見創建工作空間。
已創建OSS存儲空間(Bucket),用于存儲數據集、訓練獲得的模型文件和配置文件。關于如何創建存儲空間,詳情請參見控制臺創建存儲空間。
已創建DSW實例,且運行正常,詳情請參見創建DSW實例。建議:
鏡像選擇Pytorch1.8,例如
pytorch-develop:1.8pai-gpu-py36-cu101-ubuntu18.04
。資源規格使用GPU機型P100或V100,且內存大于等于32 GB,例如ecs.gn6v-c8g1.2xlarge。
構建模型
您可以使用PAI提供的預訓練模型,具體如下表所示。
模型類型 | Processor種類 | Predictor | 模型路徑 |
image_retrieval (圖像檢索) | EasyCV | easycv.predictors.feature_extractor.TorchFeatureExtractor | |
faceid_retrieval (人臉檢索) | EasyCV | easycv.predictors.feature_extractor.TorchFaceFeatureExtractor | |
imagetext_retrieval_cn (中文CLIP) | EasyNLP | easynlp.appzoo.CLIPPredictor | |
imagetext_retrieval_en (英文CLIP) | EasyNLP | easynlp.appzoo.CLIPPredictor | |
text_retrieval (文本向量化模型) | EasyNLP | easynlp.appzoo.FeatureVectorizationPredictor |
您也可以在DSW平臺參考Gallery示例自行構建模型,具體操作步驟如下。
進入DSW Gallery頁面,詳情請參見DSW Gallery。
在DSW Gallery頁面,構建以下兩種模型。
多模態檢索模型
在名稱或描述文本框中輸入CLIP,然后按回車鍵。在右側的基于EasyNLP的多模態CLIP圖文檢索區域,單擊在DSW中打開。單擊后即會自動將本教程所需的資源和教程文件下載至DSW實例中,并在下載完成后自動打開教程文件。
在打開的教程文件easynlp_clip.ipynb文件中,您可以直接運行對應的步驟的命令,當成功運行結束一個步驟命令后,再順次運行下個步驟的命令。
圖像檢索模型
在名稱或描述文本框中輸入Swin Transformer,然后按回車鍵。在右側的基于SwinTransformer的圖像分類示例區域,單擊在DSW中打開。單擊后即會自動將本教程所需的資源和教程文件下載至DSW實例中,并在下載完成后自動打開教程文件。
在打開的教程文件easycv_classification_Swin.ipynb文件中,您可以直接運行對應的步驟的命令,當成功運行結束一個步驟命令后,再順次運行下個步驟的命令。
部署模型服務
通過模型在線服務EAS,您可以將訓練好的模型部署為在線服務,具體操作步驟如下。
進入模型在線服務(EAS)頁面。
登錄PAI控制臺。
在左側導航欄單擊工作空間列表,在工作空間列表頁面中單擊待操作的工作空間名稱,進入對應的工作空間。
在工作空間頁面的左側導航欄選擇 ,進入模型在線服務(EAS)頁面。
部署模型服務。
在模型在線服務(EAS)頁面,單擊部署服務,然后在自定義模型部署區域,單擊JSON獨立部署。
在JSON獨立部署頁面的編輯框中,配置以下內容。
{ "cloud": { "computing": { "instance_type": "ecs.gn6i-c16g1.4xlarge" } }, "containers": [ { "image": "eas-registry-vpc.<region>.cr.aliyuncs.com/pai-eas/diffuser-inference:easyretrieval1.1.0-pytorch1.8.1-gpu-py309-cu111-ubuntu22.04", "port": 8000, "script": "python /ml/code/app.py --model_type imagetext_retrieval_cn" } ], "features": { "eas.aliyun.com/extra-ephemeral-storage": "100Gi" }, "metadata": { "cpu": 16, "gpu": 1, "instance": 1, "memory": 62000, "name": "<your_service_name>" }, "storage": [ { "mount_path": "/mnt/models", "oss": { "path": "oss://pai-quickstart-{region}/easycv/models/easyretrieval/", "readOnly": true }, "properties": { "resource_type": "model" } } ] }
其中關鍵參數配置說明如下,其他參數使用JSON文件中的配置,更多參數配置說明,請參見服務模型所有相關參數說明。
參數
描述
metadata
name
請配置您自己的服務名稱,同地域內唯一。
containers
image
請將<region>替換為服務所在地域ID,例如華東2(上海)為cn-shanghai。關于如何查詢地域ID,請參見地域和可用區。
storage
oss.path
本方案使用PAI提供的公開預置模型路徑,您只需將<region>替換為服務所在地域ID,例如華東2(上海)為cn-shanghai。關于如何查詢地域ID,請參見地域和可用區。
您也可以使用上述步驟提供的預置模型和DSW平臺訓練得到的模型。
cloud
computing.instance_type
實例規格,必須為GPU類型。
單擊部署。當服務狀態為運行中時,表明服務部署成功。
查看服務訪問地址和Token。
在模型在線服務(EAS)頁面,單擊目標服務的服務方式列下的調用信息。
在調用信息對話框的公網地址調用頁簽,獲取服務訪問地址和Token。
調用模型服務
服務調用方式
完整的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 | 接口名稱,支持以下取值:
|
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://examplebucket/ljh-xiaoling/data/image/000015.jpg', 'text': '', 'group_id': '0', 'intra_id': 0}]] }
服務調用示例
多模態圖像檢索服務首先需要建立多模態圖像檢索數據庫,然后將注冊到數據庫中的多模態數據及圖像進行特征提取,最后從多模態圖像數據庫的數據中,對上傳的多模態數據及圖像進行相似快速檢索。整個過程需要使用的接口包括數據庫初始化、增加數據庫、增加數據及檢索數據等接口。下文提供一個簡單的示例供您參考。
分別創建以下Python腳本。
數據庫初始化腳本retrieval_init.py:
import requests import 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' r = requests.post(hosts, data=datas, headers=head) print(r.content) print("test ending")
其中examplebucket替換為OSS存儲空間(Bucket)名稱,與服務所在地域一致。其他參數配置說明,請參見服務調用方式。
增加數據庫腳本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")
其中hosts和Authorization需要配置為上述步驟已獲取的服務訪問地址和Token。
指定Predictor腳本retrieval_set_predictor.py:
import requests import json ENCODING = 'utf-8' datas = json.dumps({ "function_name": "set_predictor", "function_params": { '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) # r = requests.post("http://0.0.0.0:8000/test", data=datas, timeout=1500) print(r.content) print("test ending")
其中hosts和Authorization需要配置為上述步驟已獲取的服務訪問地址和Token。
增加數據的腳本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")
其中hosts和Authorization需要配置為上述步驟已獲取的服務訪問地址和Token;url配置為圖片的OSS路徑。
檢索數據的腳本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")
其中hosts和Authorization需要配置為上述步驟已獲取的服務訪問地址和Token;url配置為圖片的OSS路徑。
在終端中,分別在腳本文件所在目錄依次執行數據庫初始化腳本、增加數據庫腳本、指定Predictor腳本以及增加數據的腳本。
python <retrieval_xxx.py>
其中<retrieval_xxx.py>需要替換為實際的Python腳本名稱。
針對部署好的數據庫,執行檢索數據的腳本進行目標圖像檢索。
python retrieval_db_search.py
得到的推理預測結果如下所示。
{"request_id": "d4b4c7c5-2330-49d5-8ffb-a15e490b****", "success": true, "info": [[{"scores": 0.0, "uri": "oss://examplebucket/xxx/000001.jpeg", "text": "", "group_id": "0", "intra_id": 0}]]}
從上述模型推理的返回結果可以看出,模型服務返回了該數據庫中與目標圖像相似度最高的圖片的URL。