日本語に対応した Embedding Model のベクトル検索での精度比較
こんにちは、nouu の白川です。
OpenAI Dev Day、よいリリースがたくさんありましたね!GPT-4 Turbo が出てくれたお陰で、production利用がだいぶ捗りそうです。一方で、Text Embedding に関しては全くリリースはありませんでした。
自分は Text Embedding のモデルとしてちょっと昔は sonoisa/sentence-bert-base-ja-mean-tokens-v2 をよく使っていました。最近は環境を他の人と共有しやすくて楽なので OpenAI の text-embedding-ada-002 をよく使っているのですが、下記のページを見ると、OpenAI を超えるようなモデルがいくつもあって、検証せねばという気分になったので気になるモデルをいくつかピックアップして検証してみました。
コードは下記に公開してあります。
データセットやモデル、評価指標などまだまだ拡充が必要なのですが、現時点でも気づきはあるかなと思い、公開します。PR 等々大歓迎です。
※ 実はもっとよいベンチマークがあるなどご存じの方がいたら是非教えてください。
⚠⚠⚠⚠
⚠注記⚠
⚠⚠⚠⚠
e5はSQuADを学習データに使用しているとの情報をいただきました。本評価は不平等である可能性があります。本記事の情報を鵜呑みにせず、ご自身のデータで検証することをおすすめします。その際には公開したコードをお使いください(datasetを追加し、configで指定すれば動くはずです)。
TL;DR -- やったこと・わかったこと
JSQuAD をもとにベクトル検索の精度検証用のデータを作った
めぼしいモデルに対してベクトル検索精度の検証をした
e5 はベクトルの次元も低く精度も高くかなり良さそう(だが、SQuADで学習しているとの情報ありなので注意)
Update
2023-11-12: モデルを追加したので結果を修正
2023-11-13: e5がSQuADで学習しているとの情報を頂いたので修正
データセット
JSQuAD v1.1 をもとに検証用のデータセットを作りました。JSQuAD は JGLUE という日本語言語モデルの言語理解能力を検証するためのデータセットに含まれる QA タスク用のデータセットです。
JSQuAD は、Wikipedia をベースに作られており、数文程度の長さのパッセージにたいして QA が複数個ついたものが、train データは 15652 パッセージ分、valid データは 1145 パッセージ分含まれています。
今回はここから Q をクエリーとして取り出し、それの属するパッセージをベクトル検索の正解パッセージとして用意しました。基本的にパッセージのみから回答できるようなデータセットのようなので、この方法で Q に答えるためにはそのパッセージをヒットさせるのは自然と判断しています(が、定量・定性の評価はまだ)。
下記のようなデータになります。
データセットのstatsは下記のとおりです。
train であれば、15652個のコンテキストがあり、各クエリー(62859個)ごとにそれに対応するオリジナルのコンテキストをベクトル検索を通じて復元しようと試みることになります。
Embedding Model
MTEB Leaderboard で目についたものと自分がよく使っていたモデル、それと下記のリポジトリ
https://huggingface.co/pkshatech/GLuCoSE-base-ja
で良さそうだったモデルを合わせた下記を検証対象のモデルとしました。
Cohere(embed-multilingual-v3.0)
OpenAI(text-embedding-ada-002)
VertexAI(textembedding-gecko-mulitlingual@001, latest)
simcse
GLuCoSE
sonoisa/sentence-bert-base-ja-mean-tokens-v2
sonoisa/sentence-luke-japanese-base-lite
e5 (small/base/large)
Vector Search
ベクトル検索自体のロジックの精度は無視したかったので、近似検索はせずに厳密検索をしています。
結果
valid データでの結果を示します。
まだ Recall@k の平均しか出すようにしていないですが、これでも大雑把には下記のような関係が見えます。
e5 >> VertexAI = Cohere > OpenAI >> その他
日本語での Embedding & Vector Search を行う場合は、e5 の使用を検討してみても良いかもしれません。e5 はベクトルの次元も低めなのが嬉しいです。
ただし、e5のみ、query/contextでベクトルの頭に `query: ` や `passage: ` という字句を入れる指示があったのでそれに従っています。他のモデルでも類似の工夫(prompt的な?)をすれば精度改善される可能性はあります。
このあたりについても知見がある方がいらっしゃれば是非教えてください!
さいごに
まだまだ未熟なベンチマークなので、検証したほうが良さそうなモデル、データがあればぜひ教えてください!DM 等お待ちしています。
X (Twitter) https://twitter.com/s_tat1204
nouu は、今後も多くの人と分かち合うべき知見を率先して検証していきたいと思っています。また進展があればご報告します。