コンテンツベースのリコールは、レコメンデーションシステムで比較的一般的なリコール戦略です。ユーザーまたはアイテムに基づく一般的なラベルのリコール、またはユーザーの年齢と地域に基づくリコールがあります。通常、この戦略の実装は、オープンソースソフトウェアElasticseachに基づいています。リコールの結果は比較的合理的ですが、リコールの目新しさと驚きは比較的低いです。たとえば、「アンディ・ラウ」というラベルを使用してリコールすると、基本的にアンディ・ラウを含むすべてのアイテムがリコールされます。「ドーン」、「ジャッキー・チュン」などの4人の王のアイテムがリコールされる可能性はほとんどありません。近年、すべてが埋め込み可能であるため、特にword2vec、item2vec、graph2vec、およびその他のテクノロジーの適用が成功しているため、アイテムベクトルを介してアイテムベクトルをリコールする方法も、レコメンデーションシステムでより一般的に使用されるリコール戦略になっています。この記事では、オープンソースソフトウェアVearchを介したベクトル検索サービスの構築に焦点を当て、画像を使用して画像を検索する機能を実現しました。
前書き
最近、私は小さなビデオの推奨と最適化を行っています。最適化の目標は、一人当たりのスクリーニングです。以前の情報フローの推奨経験によれば、ユーザーの再生記録に基づいて、ユーザーが消費するために、より関連性の高い小さなビデオがリコールされることが望まれます。小さなビデオの推奨シーンは、現在人気のあるDouyinに少し似ています。これは、短いビデオ(約5〜30秒)を自動的に再生することです。小さなビデオは基本的に画面全体を占めます。ユーザーはこの小さなビデオを気に入って共有できます。コメント;気に入らない場合は、上にスワイプして次の小さなビデオを見ることができます。ユーザーが見たいかどうかを決定する要因が、ビデオの下の2行のビデオタイトルである可能性が低いことを考えると、より多くの要因は、ビデオのカバー画像がユーザーの興味をそそることができるかどうかにあります。このプロジェクトの背景をもとに、小さな動画のカバー画像を想起させる画像を検索するサービスを構築したいと思いました。
以前にgRPCを使用してFaissをカプセル化してベクトルリコールサービスを構築し、さらに以前に行った画像分類プロジェクトを使用したため、画像は分類子の入力としてベクトルに変換されます。これを行うには、基本的に2つのことを解決する必要があります。 :
- 画像を前処理し、固定長のベクトルに変換します
- 各画像のベクトルをFaissに入力し、それを使用してベクトル検索のタスクを完了します
たとえば、プロジェクトでのブログ投稿Faissの使用では、作成者はSIFTアルゴリズムを使用して、128次元のベクトルに対応する画像の特徴を抽出します。同様のベクトル想起のために、各画像の特徴ベクトルをファイスに入力します。たとえば、gRPCに基づくFaissサーバーの実践に関するブログ投稿では、MXPlayerの技術チームがFlaskフレームワークに基づいて開発されたユーザー/アイテムベクトルリコールサービスをアップグレードしました。単一マシンの圧力テストQPSは以前の2倍以上になります。 。当初の計画では、現在のビジネスシナリオのニーズに合わせてgRPCに基づくFaissサービスを変更する予定でしたが、偶然、JD.comのオープンソースソフトウェアVearchを見つけました。以前の考えを抑え、このオープンソースソフトウェアを学ぶことにしました。
サービス構成
画像検索サービスは2つの部分で構成されます。1つはVearchが提供するベクトル検索サービスで、もう1つはVearchのプラグインpython-algorithm-pluginが提供する画像の特徴ベクトル抽出です。
ベクター検索サービス-Vearch
Vearchは、大規模な深層学習ベクトルで高性能の類似性検索を実行する柔軟な分散システムです。そのコアは、ファイスに基づくガンマエンジンと呼ばれるベクトル検索です。ただし、ベクター検索に加えて、ガンマはスカラーを含むドキュメントを保存し、これらのスカラーフィールドにすばやくインデックスを付けてフィルタリングすることもできます。率直に言って、スカラーとベクトルの両方がサポートされていますが、一般的に、Elasticsearchはスカラーのみをサポートしています。Faissは単一マシンのベクター検索サービスしか構築できませんが、Vearchはガンマをベクター検索エンジンとして使用し、Raftプロトコルを使用してマルチコピーストレージを実装し、マスターコンポーネントとルーターコンポーネントを提供して、ベクター類似性検索用の柔軟な分散システムを構築します。そのアーキテクチャ図は次のとおりです。図には、マスター、ルーター、PartitionServerの3つの主要コンポーネントがあり、その機能は次のとおりです。
- マスターは、クラスターレベルでのスキーマ管理とソースデータとリソースの調整を担当します
- ルーターは、リクエストの追加、削除、変更、チェック、ルーティングと転送、結果のマージのためのRESTfulAPIを提供します
- PartitionServerは、マルチコピーストレージを実現するために主にraftプロトコルに基づいており、特定のストレージ、インデックス作成、および取得機能はガンマエンジンによって提供されます。上記から、GammaはVearchに対してであり、これはLuceneからElasticsearchに対して同等であることがわかります。
画像処理サービス-Vearchプラグイン
画像処理サービスVearchは、対応するプラグインpython-algorithm-pluginも提供します。Vearchの目標は、高性能の同様の検索エラスティック分散システムを構築することです。テキスト、写真、ビデオはすべてベクターに変換できるため、Vearchチームは、Vearchへの統合を改善するための対応するプラグインを提供します。写真の場合、プラグインはターゲット検出、特徴抽出、類似性検索などの機能を提供します。処理ロジックは次のとおりです。ロジックは、画像からベクトル特徴を抽出してVearchのガンマエンジンに保存し、検索サービスを提供することです。
サービス構築
画像検索サービスは2つのサービスで構成されています。1つはVearchが提供するベクトル検索サービスで、もう1つはVearchのプラグインpython-algorithm-pluginが提供するベクトルとしての画像特徴抽出です。
vearch
VearchはGoで記述され、そのコアエンジンGammaはC ++で記述されているため(結局、FaissもC ++で開発されています)、依存するlibパッケージ(Faiss、Gamma)である限り、サービスのインストールとデプロイは比較的単純で失礼です。 、RocksDB)が設定され、./vearch -conf config.toml
サービスを開始するために直接実行されるスタンドアロンモード用、および./vearch -conf config.toml ps/router/master
構成する最終コマンドパラメーターを介したクラスターサービス用に、コンパイルされたバイナリファイルvearchがあります。
ただし、オンラインサーバーのGccバージョンが低すぎて、Go環境などの要素がないため、Dockerメソッドを使用します。FaissサービスがVearchと呼ばれる柔軟な分散システムにどのように進化したかを詳細に理解するために、ソースコードがコンパイルされてインストールされました。
# 下载源码
git clone https://github.com/vearch/vearch
# 切换到镜像编译目录
cd vearch/cloud
# 打包环境镜像 vearch/vearch_env:3.2.2,将gcc,git,faiss,rocksdb,go等安装好
# 这步打包比较慢,可以直接使用官方镜像 docker pull vearch/vearch_env:3.2.2
sh compile_env.sh
# 使用 vearch_env 编译二进制文件 vearch,主要是拉取 gamma 源码进行编译
sh compile.sh
# 打包 vearch/vearch:3.2.2, 将打包好的二进制文件vearch和依赖的库放到镜像中。
# 可以直接使用官方镜像 docker pull vearch/vearch:3.2.2
sh build.sh
公式の画像パッケージにはまだ最適化の余地があります。パッケージにはcentosソースを使用し、Faiss、RocksDB、Goなどのソースファイルを準備することをお勧めします。
画像処理
画像処理サービスには既製のDockerイメージがなく、Githubウェアハウスで提供されているイメージパッケージに問題があります。パッケージには次のウェアハウスを使用できます。
# 下载源码(使用修正后的 Dockfile 文件)
git clone -b study https://github.com/haojunyu/python-algorithm-plugin
# 切换到镜像目录并打包镜像 vearch/images:3.2.2
# 可以直接使用打包好的镜像 docker pull haojunyu/vimgs:3.2.2
cd python-algorithm-plugin && docker build -t haojunyu/vimgs:3.2.2 .
スウォームスタート
2つのサービスがDockerにパッケージ化されておりdocker stack deploy -c docker-compose.yml vearch
、サービスを開始するコマンドに直接ミラーリングされているため、docker-compose.ymlは次のように読み取ります。
version: '3.3'
services:
vearch:
image: vearch/vearch:3.2.2
ports:
- "8817:8817"
- "9001:9001"
volumes:
- ./config.toml:/vearch/config.toml
- ./data:/datas
- ./logs:/logs
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
logging:
driver: "json-file"
options:
max-size: "1g"
imgs:
image: haojunyu/vimgs:3.2.2
ports:
- "4101:4101"
volumes:
- ./python-algorithm-plugin/src/config.py:/app/src/config.py
- ./images/imgs:/app/src/imgs
command: ["bash", "../bin/run.sh", "image"]
deploy:
mode: replicated
replicas: 3
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
注:マウントファイルpython-algorithm-plugin / src / config.pyは、画像処理サービスの構成ファイルです。通常、状況に応じて次の4つの構成を変更するだけで済みます。
port
画像処理サービスのポートを参照します。デフォルトは4101です。gpus
サービスがgpuを使用するかどうかを指定します。デフォルトは-1ではありませんmaster_address
またrouter_address
、Vearchサービスのマスターサービスとルーターサービスを指します
サービスの利用
画像サービスとVearchサービスが高度に統合されているためです。通常、画像サービスは直接呼び出され、画像ベクトル入力Vearchは処理のために画像サービスに渡されます。Vearchの詳細な操作については、ドキュメントを参照してください。
サービス監視
# 这里master_server指vearch主节点及其对应端口:localhost:8817
# 查看集群状态
curl -XGET http://master_server/_cluster/stats
# 查看健康状态
curl -XGET http://master_server/_cluster/health
# 查看端口状态
curl -XGET http://master_server/list/server
# 清除锁(在创建表时会对集群加锁,若在此过程中,服务异常,会导致锁不能释放,需要手动清除才能新建表。)
curl -XGET http://master_server/clean_lock
# 副本扩容缩容
curl -XPOST -H "content-type: application/json" -d'
{
"partition_id":1,
"node_id": 1,
"method": 0
}
' http://master_server/partition/change_member
図書館と宇宙の運営
ライブラリとスペースの概念は、mysqlのデータベースとテーブルの概念に似ています。
- 図書館運営
# 查看及群众所有的库
curl -XGET http://master_server/list/db
# 创建库
curl -XPUT -H "content-type:application/json" -d '{
"name": "sv_month"
}
' http://master_server/db/_create
# 查看库
curl -XGET http://master_server/db/$db_name
# 删除库(库下存在表空间则无法删除)
curl -XDELETE http://master_server/db/$db_name
# 查看指定库下所有表空间
curl -XGET http://master_server/list/space?db=$db_name
- 表スペース操作
# 在库sv_month下创建表空间test(针对image)
curl -XPUT -H "content-type: application/json" -d '{
"name":"test",
"partition_num":1,
"replica_num":1,
"engine":{
"name":"gamma",
"index_size":70000,
"max_size":10000000,
"id_type":"String",
"retrieval_type":"IVFPQ",
"retrieval_param":{
"metric_type":"InnerProduct",
"ncentroids":256,
"nsubvector":32
}
},
"properties":{
"itemid":{
"type":"keyword",
"index":true
},
"feature1":{
"type":"vector",
"dimension":512,
"model_id":"vgg16",
"format":"normalization"
}
}
}' http://image_server:4101/space/sv_month/_create
データ操作
- データ挿入
# 插入本地图片数据到表空间中
curl -XPOST -H "content-type: application/json" -d' {
"itemid":"COCO_val2014_000000123599",
"feature1":{
"feature":"../images/COCO_val2014_000000123599.jpg"
}
} ' http://image_server:4101/sv_month/test/AW63W9I4JG6WicwQX_RC
- データ検索
# 查询相似结果
curl -H "content-type: application/json" -XPOST -d '{
"query": {
"sum": [ {
"feature":"../images/COCO_val2014_000000123599.jpg", "field":"feature1"
}]
}
}' http://image_server:4101/sv_month/test/_search
サービス効果とローンチ
効果
サービスが正常に構築された後、地図で画像を検索した場合の効果を確認する必要があります。効果の識別は、最初は手動に基づいて行われ、最後にオンラインインジケーターデータに基づいて行われます。次のようなサービスの確立の開始時に、サービスの有効性に期待する必要があります。
- 同じ写真の類似性は100%に近い
- 同じタイプでも、子犬を使用して子犬を検索したり、車を使用して車を検索したりするなど、同じタイプの結果が得られるはずです。
以下は、写真で検索した場合の効果のスクリーンショットです。
全体的に効果はかなり良いです。
オンライン
推奨される戦略のためにオンラインに接続する方法はいくつかあります。
- ソートモデルのようなオンラインの直接サービス。このアプローチには、高い同時実行性、高いパフォーマンス、および高可用性をサポートするサービスが必要です。
- コンテンツ検索のようなオンライン通話+キャッシュ。この方法では、サービスが高パフォーマンスと高可用性をサポートする必要があり、キャッシュがヒットする可能性が高くなります
- 結果は、cf、hotなどのオフラインのキャッシュに書き込まれ、事前に計算できます。
過去7日間に新たに追加された小さな動画と過去30日間に公開された動画の合計90,000のデータが、平均48QPSの2つのバケットの影響をサポートできなかったスタンドアロンのVearchサービスにインポートされました。 2番目の方法は、オンラインの問題を解決するために使用されました。対応するユーザーベクトル(表示された画像ベクトルの平均値)検索画像ベクトル戦略は、3番目の方法で開始されました。
参照
- プロジェクトでのファイスの使用
- faiss-web-service
- gRPCに基づくFaissサーバーの実践
- JD分散ベクトル検索システムvearch
- vearch中国語文書
- vearchコアエンジンガンマ
- vearch画像処理プラグイン
- 画像検索ページ
この記事がお役に立てば、または技術記事に興味がある場合は、WeChatパブリックアカウント:Technical Tea Partyをフォローしてください。関連する技術記事をできるだけ早く受け取ることができます、ありがとうございます。
この記事は、ブロググループ投稿やマルチ投稿などのオペレーティングツールプラットフォームであるOpenWriteによって公開されています。