LIFULL HOME'SのAI施策におけるSolr活用

1.8K Views

July 21, 22

スライド概要

第27回 Lucene/Solr勉強会 #SolrJP で発表した資料です。
https://solr.doorkeeper.jp/events/138271

profile-image

株式会社LIFULL

@LIFULL

スライド一覧

LIFULL HOME'Sを運営する株式会社LIFULLのアカウントです。 LIFULLが主催するエンジニア向けイベント「Ltech」等で公開されたスライド等をこちらで共有しております。

シェア

埋め込む »CMSなどでJSが使えない場合

各ページのテキスト
1.

LIFULL HOME'Sの AI施策におけるSolr活用 株式会社LIFULL テクノロジー本部プラットフォームグループ 宮崎 泰輔

2.

自己紹介 Solrを使ったAI施策の紹介 ベクトルを使った並び替え 目次 課題 解決策 まとめ

3.

自己紹介 宮崎 泰輔 imishinist ソフトウェアエンジニア @LIFULL 検索システムチームで LIFULL HOME’SのSolrの運用改善や機能追加を担当 検索チームだが好きな言語はGoとBash

4.

Solr9の話はありません 🙇🙇🙇

5.

Solrを使ったAI施策の紹介

6.

Solrを使ったAI施策の紹介(1/2) AIホームズくん 対話から希望や細かなこだわりを理解し「ぴったり度」で 理想の住まいを提案する https://lifull.com/news/22847/

7.

Solrを使ったAI施策の紹介(2/2) AIスコア順 - AI並び順用のフィールドで並び替え フィールドの値は”AI”で計算 AIベクトル順 - ドキュメントごとにベクトルを付与し、 クエリのベクトルとの内積でソート https://lifull.com/news/22847/

8.

ベクトルを使った並び替え

9.

背景 AIチームから相談 ドキュメントごとにベクトルデータを格納して クエリでベクトルを指定してクエリごとに異なるスコアを計算して 並び替えたい🙇🙇🙇 Solr9から入るKnnの機能を使えば実現できそう💡💡💡

10.

課題一覧 I. solr9から入るKNNとは違い検索ではなくソートに使用したい😨😨 A. topKクエリではない II. そもそもSolr8を使用している😰😰😰 A. Solr8にはベクトルのデータ型がない III. ベクトルデータをドキュメントに含まない場合も並び順を コントロールしたい😥😥 IV. 負荷がどうなるのか予測がつかない😱😱😱😱

11.

課題I - 解決策 「solr9から入るKNNとは違い検索ではなくソートに使用したい」 ソートに使用したいが、検索結果全てに計算するのは厳しい🤔🤔 (計算量が明らかにやばい) => ReRankで上位のみベクトル計算して並び替えれば良い🤗 reRankdDocsを検証して決めれば良い👏👏👏

12.

課題一覧 I. ✔solr9から入るKNNとは違い検索ではなくソートに使用したい😨😨 A. topKクエリではない II. そもそもSolr8を使用している😰😰😰 A. Solr8にはベクトルのデータ型がない III. ベクトルデータをドキュメントに含まない場合も並び順を コントロールしたい😥😥 IV. 負荷がどうなるのか予測がつかない😱😱😱😱

13.

課題II - 解決策 「そもそもSolr8を使用している」 ベクトルのプラグインを使う👏👏👏 https://github.com/DmitryKey/solr-vector-scoring

14.

課題II - ベクトルプラグインの仕組み 「solr-vector-scoring」の仕組み ベクトルデータの保存 WhiteSpaceTokenizerで単語を空白区切りにトークナイズ DelimitedPayloadTokenFilterでtermPayloadにベクトルの要素を保存

15.

課題II - ベクトルプラグインの仕組み インデックスの中身 ※ 0|1.0 1|2.0 2|4.0 3|8.0 = [1.0, 2.0, 4.0, 8.0] ※ “|” の 左側が配列のインデックス, 右側がその要素の値 WhitespaceTokenizerで単語に分割される DelimitedPayloadTokenFilterFactoryで、”|”で 区切って左側をtext、右側をpayloadをに設定する ※デフォルトは “|”がデリミター

16.

課題II - ベクトルプラグインの仕組み termsハンドラへの リクエスト結果と 中身のデータ

17.
[beta]
課題II - ベクトルプラグインの仕組み
ベクトルでのクエリ

q=*:*&fl=id,foo*,score&
rq={!rerank reRankQuery=$rqq reRankWeight=1}&
rqq={!vp f=foo_vector base=foo_base
vector="1,1,1,1" cosine=false}

[1,1,1,1] というベクトルと、ドキュメントごとに
ベクトルの内積をとってスコアにする

18.

課題II - ベクトルプラグインの仕組み reRankのスコア計算式 score = score + reRankWeight * reRankScore [id:9001000004の例] q=*:* なので、 score=1 ※ const クエリベクトル : [1,1,1,1], ベクトルデータ : [1,2,4,8] 内積: 1 * 1 + 1 * 2 + 1 * 4 + 1 * 8 = 15 base=100なので、 reRankScore = 15 + 100 = 115 score = 1 + 1 * 115 = 116

19.

課題一覧 I. ✔solr9から入るKNNとは違い検索ではなくソートに使用したい😨😨 A. topKクエリではない II. ✔そもそもSolr8を使用している😰😰😰 A. Solr8にはベクトルのデータ型がない III. ベクトルデータをドキュメントに含まない場合も並び順を コントロールしたい😥😥 IV. 負荷がどうなるのか予測がつかない😱😱😱😱

20.

課題III - 課題整理 「ベクトルデータをドキュメントに含まない場合も 並び順をコントロールしたい😥😥」 どういうこと?? 🤔

21.

課題III - 課題整理 ベクトルデータ生成はAIチーム担当で、API経由で行うが、 全てのドキュメントを入れるために、それなりに高スループットで API呼び出しを行う。 => スケールアウトが間に合わずリクエストに失敗することがある🙄 リクエストに失敗すると 「ベクトルデータをSolrに格納できない」

22.

Solrの現在の構成 API呼び出し

23.

課題III - 期待値整理 期待した並び順について整理 i. APIリクエストに成功したデータ (ベクトルを取得できたもの) ii. APIリクエストに成功したが、今回の施策の対象外のデータ (ベクトルが無いのが正) iii. APIリクエストに失敗したデータ 制約: ベクトル計算後の値の範囲: [-1, 1] スコアが負の値になったらSolr8の仕様で0になってしまう😥😥😥

24.

課題III - 解決策 下駄を履かせ計算結果が負の値になってもプラスになるようにしつつ 下駄を i と ii と iii で変えることで i > ii > iii になるようにする i. vector=[1,2,3,4,…], base=100 ii. vector=[], base=1 iii. vector=[],base= ↑のようにすれば、OK

25.

課題III - 実現のためのクエリ ベクトルのクエリは以下 rq={!rerank reRankDocs=2500 reRankQuery=$rqq reRankWeight=1}& rqq={!vp f=foo_vector vector="1,1,1,1" cosine=false} ただし、このままだとbaseを足せない (クエリも思いつかず)

26.

課題III - 解決策 リポジトリのコードをforkしてbaseパラメータを追加😋😋 rq={!rerank reRankDocs=2500 reRankQuery=$rqq reRankWeight=1}& rqq={!vp f=foo_vector vector="1,1,1,1" cosine=false base=foo_base}

27.

課題一覧 I. ✔solr9から入るKNNとは違い検索ではなくソートに使用したい😨😨 A. topKクエリではない II. ✔そもそもSolr8を使用している😰😰😰 A. Solr8にはベクトルのデータ型がない III. ✔ベクトルデータをドキュメントに含まない場合も並び順を コントロールしたい😥😥 IV. 負荷がどうなるのか予測がつかない😱😱😱😱

28.

課題IV - 課題 負荷がどうなるのか予測がつかない(遅くなることしかわからない) 負荷が高くなるということは 台数を増やす、スケールアップする、設定値の変更など 何かしらの対応が必要 reRankDocsを調整(計算量を減らす)してなんとかならないか?

29.

課題IV - 解決 負荷検証 1. 本番環境のSolrへの クエリログからクエリを抽出 2. 検証用にクエリを変換 3. Solrへリクエスト 4. 分析

30.

課題一覧 I. ✔solr9から入るKNNとは違い検索ではなくソートに使用したい😨😨 A. topKクエリではない II. ✔そもそもSolr8を使用している😰😰😰 A. Solr8にはベクトルのデータ型がない III. ✔ベクトルデータをドキュメントに含まない場合も並び順を コントロールしたい😥😥 IV. ✔負荷がどうなるのか予測がつかない😱😱😱😱

31.

今後の話 - ベクトルデータを圧縮して持てないか模索中 - ベクトルのフィールドが1つ増えるだけで数GB増えている いくつもフィールドが増やしにくい - Solr9のKNNの機能を使って実現できないか模索中 - 今後も増えていくベクトルへの改善を取り込めないのは辛い とはいえ、HNSWのグラフデータで更に容量が増えそう

32.

まとめ - AI施策でのSolr活用事例の紹介 - Solr8でベクトルを使った際の課題と、その解決策について紹介 - reRankで上位のみ重い計算をするようにした 要件を満たせなくて一部forkして機能追加した

33.

Q&A