Vertex AI Matching Engineをつかった類似商品検索APIの開発

こんにちは。ソウゾウの Software Engineer の @wakanapo です。
連載:メルカリShops 開発の裏側 Vol.2の8日目を担当させていただきます。

この記事では Vertex AI Matching Engine を使ったメルカリShopsの類似商品検索APIについて、メルカリ写真検索での経験もふまえながら紹介します。

類似商品検索APIはメルカリShopsに出品されている商品に対して、それに似ている商品を返すAPIです。現状これを使った機能でリリースされているものはありませんが、今後レコメンデーションなどに使っていきたいと考えています。

類似ベクトル検索について

類似ベクトル検索とはベクトル空間上で距離の近いものを探すというものです。すべてのベクトルを比較して正確に距離の近いものを探すには非常にコストがかかるので、正確でなくていいのである程度の精度で近いものをさがす近似近傍探索 (approximate nearest neighbor, ANN) のアルゴリズムの研究が盛んに行われています。
機械学習モデルによって画像、テキスト、表など様々な種類のデータをベクトルで表すことができるため、類似するベクトルが検索できるということは、似ている画像やテキストを探せるということです。それによって、似ている商品を検索したり、似ているお客様を探してレコメンデーションに利用したり、様々な機能を実現することができます。

メルカリにおける類似ベクトル検索(画像ベクトル)活用事例

しかしながら、類似ベクトル検索のシステムを自前で作成するのは非常に大変です。メルカリ写真検索では Faissという近似近傍探索ライブラリを用いて実装したシステムを Kubernetes 上で運用していましたが、頻繁に障害を経験し数多くのバグに遭遇しました。

メルカリShopsでも、類似ベクトル検索はこれから様々な機能を改善していくにあたって間違いなく必要になる基盤の1つです。しかしながら、人数も限られているソウゾウの現状ではメルカリと同じような構成のシステムは現実的ではありませんでした。そこで目をつけたのが VertexAI Matching Engine です。

VertexAI Matching Engine とは

Vertex AI Matching Engine (以下 Matching Engine) は Google Cloud Platform (GCP) が提供しているサービスで、ベクトルの近似最近傍探索をしてくれます。内部実装は ScaNN というGoogle が2020年に発表した高パフォーマンスな類似ベクトル検索アルゴリズムを用いています。

Matching Engine の魅力

メルカリ写真検索での経験から、Matching Engine は次の2点が特に魅力的だと感じました。

  1. id として custom な UTF-8 の文字列を使える
  2. deploy されている index の更新を安全にやってくれる

1. id として custom な UTF-8 の文字列を使える

メルカリ写真検索で用いていた Faiss では、類似ベクトル検索では indexing の際に順番に内部的なidが振られます。検索結果もその id で返されるので、それを自分たちで item id などのサービスで意味を持つidにマッピングする必要があります。しかしながら、index の追加/削除は頻繁に行われるため、この マッピングを正しい状態で保つのは難しく、メルカリ写真検索でもこのマッピングの整合性が原因の障害を何度も経験しました。

ライブラリを使った実装:indexのidをitem idなどに自分たちで変換する必要がある

Matching Engineでは item id などをそのまま index の id として使うことができます。そのため、ユーザーは上で述べた例のように index の id から item id へのマッピングを管理する必要がありません。indexのマッピングを管理する必要がないということは、それに伴う障害のリスクもないので、これだけで運用がかなり楽になるはずです。

Matching Engineの場合: 検索結果がはじめからitem idで返ってくる

2. deployされている index の更新を安全にやってくれる

類似ベクトル検索では、サービスを停止せずに index を更新したいという状況がよくあります。例えば、メルカリ写真検索では毎時新しく出品された商品の index を追加しています。この部分の設計は考慮しなくてはいけない要素が多く、とてもめんどくさい部分です。メルカリ写真検索でも、以下に示すように何度も改修を重ねていました。

1st generation: 毎時新しい index を含むサービスを deploy。request が来たら proxy service が並列に全 index に問い合わせ結果を集約して返す。毎時の index だと数が多くなりすぎるので一日, ひと月置きに daily, monthly の index にまとめ直すという処理もしていた。
2nd generation: 毎時 background で現状の index に新しい index を追加。それが終わり次第 index service を deploy し直す。処理としてはシンプルだが background の job が複数同時に走った場合にコンフリクトするなどの問題があった。

Matching Engineでは、この部分は完全に内部で実装してくれているため、ユーザーは自分で考える必要がありません。index の update メソッドを呼ぶだけで、内部で index の更新から deploy まで非同期的に行ってくれ、deploy されている index も安全に更新することができます。

メルカリShops類似商品検索APIの開発

実際に、Matching Engineを用いて、メルカリShopsの類似商品検索を作成しました。
今回は商品名・商品詳細・カテゴリー名のテキスト情報を用いることにしました。

次のような手順で実装は完了です。

  1. 商品名+商品詳細+カテゴリー名の文字列をWord2Vecを用いて200次元のベクトルに変換
  2. 以下の形式でファイルを作成しGoogle Cloud Storageにアップロード
    {"id": “product_1”, "embedding": [0.1, 0.2, ..., 0.0, 0.1]}
    {"id": “product_2”, "embedding": [0.2, 0.0, ..., 0.1, 0.1]}
  3. contentsDeltaUri に2で作成したファイルの path を指定してIndex を作成
  4. IndexEndpoint を作成し、3で作成した Index を deploy

検索してみるとこのような結果になりました。(※テキストのベクトルで商品を検索をしていますが、結果はわかりやすいように画像を表示しています。)



画像検索やキーワード検索とは異なる、なんとなく似た商品が検索できているかなと思います。

現在まだ類似商品検索APIを使った機能はリリースされていませんが、引き続き改善を重ね、「メルカリShops」がより良いものになるように貢献していきたいと思います。

—–

ソウゾウではメンバーを大募集中です。メルカリShopsの開発やソウゾウに興味を持った方がいればぜひご応募お待ちしています。詳しくは以下のページをご覧ください。

またカジュアルに話だけ聞いてみたい、といった方も大歓迎です。こちらの申し込みフォームよりぜひご連絡ください。

  • X
  • Facebook
  • linkedin
  • このエントリーをはてなブックマークに追加