Sentence-BERTとは?文章を個別にベクトル化し、意味検索の比較コストを減らす技術

Sentence-BERT(SBERT)は、BERTを文ペアで学習し、個別に計算した文ベクトルで意味を比較する技術です。重み共有、プーリング、3種類の学習目的、類似度評価と速度の結果から、FAQ検索や重複検出への応用と限界を解説します。

参考文献

Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks

Nils Reimers, Iryna Gurevych

論文を見る

今回の論文

今回取り上げるのは、Nils Reimers、Iryna Gurevychによる「Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks」です。2019年8月27日にarXivで初版が公開され、同年のEMNLP-IJCNLPで発表されました。公開元はACL Anthologyで、研究分野は自然言語処理、文埋め込み、意味類似度計算です。論文の書誌情報と本文を参照できます。

選んだ理由は、検索で何度も使う情報を先に計算しておく、という実装上の工夫を、モデルの学習方法まで含めて実現しているからです。2019年の研究ですが、FAQ検索やRAGの候補抽出を設計するうえで、精度と計算量の関係を理解する手がかりになります。

どんな技術か

Sentence-BERT、略してSBERTは、文章を1本ずつ固定長のベクトルへ変換し、そのベクトル同士で意味の近さを比べられるようにする技術です。事前学習済みのBERTに文章単位の出力をまとめる処理を加え、文同士の関係を使って追加学習します。

例えば「パスワードを忘れました」と「ログイン用の暗証情報を再設定したい」は、使う単語が違っても同じFAQへ案内したい質問です。SBERTの狙いは、こうした意味の近さを、ベクトルの向きの近さとして比較できるようにすることです。ただし、この具体例の検索精度を原論文が検証しているわけではありません。

重要なのは、検索対象の文章を質問とは独立に処理できる点です。FAQをあらかじめベクトル化して保存すれば、新しい質問が来たときは質問を1回ベクトル化し、保存済みの候補と比較できます。質問と各FAQの組を毎回BERTで読み直す方式に比べ、重い計算の再利用がしやすくなります。

課題

通常のBERTを文ペアの判定に使う場合、2つの文章をまとめて入力し、それらの単語間の関係をAttentionで処理できます。この方式は細かい照合に向いていますが、候補が増えるほどモデルに通す組み合わせも増えます。

1件の質問とN件のFAQを比較するなら、基本的にはN組を処理する必要があります。さらに、N件の文章から最も似た組を探すために全ペアを比べると、比較数はN(N−1)/2です。1万文なら49,995,000組になります。問い合わせの重複候補を大量に探す場面では、この違いが大きくなります。

文章を先にベクトル化すればよさそうですが、追加学習していないBERTの出力を単純に平均しても、意味類似度に適した表現になるとは限りません。単語の文脈表現を学ぶ目的と、文全体の距離を意味に合わせる目的には隔たりがあります。

そのため必要なのは、比較処理を軽くする構造と、その構造でも意味を比較できる学習の両方です。SBERTは、文章ごとの独立したエンコードを維持しながら、文ペアの教師情報で出力を整えます。原論文の問題設定とモデル

用語解説

文埋め込み(sentence embedding)
文章全体を固定長の数値ベクトルにした表現です。SBERTでは、保存したベクトルだけで意味を比較できることが、検索対象の事前計算につながります。
Cross-encoder
2つの文章をまとめて読み、関係を判定する構成です。文をまたいで細かく照合できますが、相手が変わるとモデルの計算もやり直すため、大量候補への全件適用には負担があります。
Siamese構造
別々の入力を、重みを共有する同じネットワークで処理する構造です。SBERTの図にはBERTが2つ描かれますが、別々の専門モデルを学ぶのではなく、共通の表現空間を作ります。
プーリング
トークンごとの出力を、文章全体の1本のベクトルへまとめる処理です。原論文の標準設定では平均を使い、文ペアの損失を通じてBERTの重みも更新します。
自然言語推論(NLI)
前提文と仮説文の関係を、含意・矛盾・中立へ分類するタスクです。SBERTではこの教師データを使い、文ベクトルが文章間の意味関係を保持するよう学びます。

技術の仕組み

文章を独立に処理し、同じ空間へ写す

基本的な処理は文章 → BERT → プーリング → 文ベクトルです。BERTの内部では、その文章のトークン同士がAttentionを通じて影響し合います。一方、ペアの相手の文章は、そのエンコード処理には入りません。

文章Aから得たベクトルをu、文章Bから得たベクトルをvとすると、推論時の類似度はcos(u, v)で計算できます。コサイン類似度はベクトルの長さを除いて方向の近さを測ります。同じ文章のベクトルを別の比較へ使い回せることが、この構成の利点です。

プーリングは平均、各次元の最大値、先頭の特殊トークンであるCLSの出力という3種類を比較し、標準設定は平均です。単に平均するだけでSBERTになるわけではなく、以降の学習でエンコーダ自体を調整することが重要です。

NLI分類で文ベクトルを学ぶ

代表的な学習では、文ペアを同じBERTで個別に処理し、次の情報を結合して分類器へ渡します。

分類器への入力 = [u, v, |u−v|]

|u−v|は各次元の差の絶対値です。分類器は、この情報から含意・矛盾・中立の3クラスを予測します。予測の誤りを交差エントロピー損失で測り、分類器とBERTの重みを更新します。学習中は両側のBERTが同じ重みを共有します。

論文ではSNLIとMultiNLIを組み合わせ、1エポック学習しています。バッチサイズ16、Adamの学習率は2×10⁻⁵、最初の10%で学習率を立ち上げる設定です。これは原論文の再現条件であり、どの業務データでも最適という意味ではありません。

検索で使うときは、この3クラス分類器を通しません。学習で整えた文ベクトルを取り出してコサイン類似度を計算します。NLIの分類結果を、そのまま検索スコアとして返す方式ではありません。原論文第3節の学習構造

データに応じて、回帰と三つ組の学習も使う

原論文はNLI分類だけでなく、別の教師情報に対応する学習目的も扱っています。文章ペアに連続値の類似度が付いている場合は、コサイン類似度と正解値の二乗誤差を小さくする回帰を使います。

また、基準文a、近づけたい文p、区別したい文nがある場合は、三つ組の損失を使います。

損失 = max(距離(a,p) − 距離(a,n) + マージン, 0)

これは、正例が負例より一定以上近くなるよう求めるものです。論文の三つ組実験ではユークリッド距離とマージン1を使います。分類・回帰・三つ組を常に全部同時に使うのではなく、データと実験の目的に応じて使い分けています。

教師ペアを用意しにくい場合には、後続研究のSimCSEが使うドロップアウトによる教師なし対照学習が別の学習信号の作り方を示します。SBERTのNLI分類とは、入力から教師信号を得る方法が異なります。

推論を事前計算とオンライン処理に分ける

検索用途では、まず候補文のベクトルをまとめて計算し、文章IDと一緒に保存します。質問が来たら同じモデルと前処理で質問をベクトル化し、候補のベクトルとの類似度を計算して上位を返します。

全件との厳密な比較は、候補数Nとベクトル次元dに対してO(Nd)の計算を要します。候補が多ければ、近似最近傍探索で比較先を絞る設計も考えられます。ただし、それは索引側の追加設計です。SBERTだけで全ペアのスコア計算が線形になるわけではなく、全ペアを厳密に調べれば比較自体は二乗個残ります。

実験と結果

BERTの出力を、そのまま平均する場合との違い

原論文の表1は、STS12〜16、STS Benchmark、SICK-Rという7つの意味類似度タスクを評価しています。コサイン類似度と人手ラベルの順位の一致をSpearman相関で測り、100倍した値を報告しています。正解率ではありません。

手法7タスクの平均相関×100
GloVe単語ベクトルの平均61.32
追加学習前のBERT出力の平均54.81
追加学習前のBERTのCLS出力29.19
Universal Sentence Encoder71.22
SBERT-NLI-base74.89
SBERT-NLI-large76.55

ここでいうSTSの教師なし評価は、STS固有の学習データを使わないという意味です。SBERT-NLI自体はNLIの教師データで学んでいるため、ラベルを一切使わない手法と読んではいけません。原論文の表1と第4.1節

結果は、BERTを使うだけでは文ベクトルの類似度が十分でなく、文関係に合わせた学習が効くことを示します。ただし全データセットで優位ではなく、SICK-RではUniversal Sentence EncoderがSBERT-NLI-largeを上回っています。

精度を完全に維持できるとは限らない

STS Benchmarkの学習データにも適応した表2では、NLI学習後のBERT cross-encoderのbase版が88.33 ± 0.19、SBERTのbase版が85.35 ± 0.17でした。いずれもテスト集合でのSpearman相関×100で、10個の乱数シードを使う評価です。原論文の表2

したがって「独立にエンコードすれば、文同士を直接照合する方式と常に同じ精度になる」とは言えません。比較の再利用と引き換えに、相手の文章を見ながら細部を読む経路を省いています。

高速化の中心は、重い推論の回数を減らすこと

論文冒頭では、1万文の全ペアをBERTで処理する約65時間に対し、SBERTの1万文のエンコードは約5秒、その後のコサイン類似度計算は約0.01秒という例を示しています。これは論文内の計測条件に基づく説明であり、一般的なAPI応答時間や、任意のクラスタリング処理全体を保証する値ではありません。

第7節の速度評価では、STS Benchmarkの文章をIntel i7-5820KとTesla V100で処理しています。SBERT-baseのGPU処理速度は毎秒1,378文、長さの近い文章を同じバッチにまとめるsmart batchingでは毎秒2,042文でした。CPUではそれぞれ44文、83文です。原論文の計算効率評価と表7

SBERTは1回のエンコードを無条件に軽量化する技術ではありません。候補ごとのペア推論を、各文章のエンコードと安価なベクトル比較へ分解することが主な効果です。バッチ内の不要なパディングを減らす実装も処理速度へ影響します。

何に使える?

以下は、原論文の構造から考えられる実務への応用です。日本語の業務システムやRAGで、ここに挙げる効果を直接検証した結果ではありません。

FAQや過去問い合わせから候補を探す

FAQの質問文や過去の問い合わせを事前にベクトル化し、新しい問い合わせに近い候補を探せます。候補が共通で、質問だけが変わるシステムほど事前計算を再利用しやすくなります。

短い質問と長い回答本文では意味関係が非対称になるため、まず質問同士の検索から試すと評価を設計しやすいでしょう。検索したFAQの回答を提示する前に、製品の版や契約条件も確認する必要があります。

重複チケットや類似障害の候補を集める

障害報告や要望の文をベクトル化し、類似する既存チケットを提示できます。人が重複判定する前に候補を狭められれば、全件を直接読み比べる負担を減らせます。

ただし「保存できない」と「保存できるが遅い」のような近い表現でも、対応は異なります。類似度だけで自動的にチケットを統合せず、担当者へ候補を提示するところから始める設計が考えられます。

RAGの検索と精密な再判定を分担する

保存済みベクトルで候補を抽出し、上位候補だけをcross-encoderで再評価する構成に応用できます。一次検索は候補を落とさないこと、再判定は候補内の順位を整えることに役割を分けます。

SBERTの原論文は、この構成によるRAGの回答品質を直接評価していません。候補抽出で根拠を落とすと後段では復活できないため、検索のRecall@kと最終回答の品質を分けて測る必要があります。

開発や事業へのヒント

再利用できる単位を、モデル構造から考える

この論文の設計から得られるヒントは、何を事前計算できるかを学習段階から考えることです。候補文を独立に処理できれば、毎回の入力と切り離して保存できます。文ペアを一緒に読む精密さが必要な部分だけ、後段へ残せます。

小規模なプロダクトなら、少数のFAQをベクトル化して保存し、質問との比較だけを実行する構成から試せます。最初から大規模な索引が必要とは限りません。候補数と応答時間を測り、索引が必要になる規模を判断するとよいでしょう。

「意味が近い」と「業務上、同じ扱い」を分ける

言い換えを検索したいのか、同じ部署へ送る文章をまとめたいのかで、学びたい関係は変わります。一般的な意味類似度が高くても、別の処理へ送るべき問い合わせはあります。

少量のカテゴリラベルで分類先に合わせて文埋め込みを調整する例として、SetFitのペア学習と分類器を組み合わせる方法があります。SBERTのような文表現を、具体的な分類目的へ適応させる判断材料になります。

埋め込み更新を、データ更新として扱う

モデルの重みやプーリングを変えると、同じ文章でも別のベクトルになります。検索側だけ新モデルにして、保存済み候補を旧モデルのままにすると、比較の前提が崩れます。

実装上は、モデルの版、前処理、最大入力長、正規化の有無を記録し、候補ベクトルを同じ条件で更新する必要があります。これは原論文の性能主張ではなく、独立した文ベクトルを保存する構造から導ける運用上の要件です。

限界

精度面では、文章を固定長ベクトルにまとめるため、相手の文を見ながら条件や否定を照合するcross-encoderほど細部を扱えない場合があります。原論文の議論文類似度評価でも、未知の話題をテストにする設定ではcross-encoderとの差が広がります。似ている文章の検索と、同じ回答を返せるかの判定は区別してください。原論文の話題を分けた評価

データ面では、NLIで学んだ関係が業務上の関連性と一致するとは限りません。原論文の中心評価は英語で、日本語や社内略語に同じ結果を適用できる保証はありません。また、BERTの入力長には上限があり、長い文書を丸ごと表現できる技術ではありません。切り詰めや文書分割で何を失うかも確認が必要です。

計算面では、初回の全候補エンコード、モデル更新時の再計算、ベクトル保存用メモリが必要です。全ペア比較のスコア数自体も二乗で増えます。索引で高速化する場合は、近似探索による取りこぼしも別途測ります。

再現には、基盤モデル、学習データ、損失関数、プーリング、バッチ条件をそろえる必要があります。Sentence-BERTの原論文の方式と、現在Sentence Transformersという名前で扱われる多様なモデル・学習方法も、同一視しないことが大切です。

よくある質問

Q. BERTの出力を平均すればSentence-BERTですか?

A. 平均するだけでは十分ではありません。SBERTはプーリングに加えて、文ペアの関係を使ってBERTの重みを調整します。原論文では、追加学習前の平均BERT表現よりNLIで学習したSBERTが意味類似度で高い相関を示しています。

Q. 学習図にBERTが2つありますが、推論にも2モデル必要ですか?

A. 重みを共有しているため、別々の重みを持つ2モデルを用意する必要はありません。同じエンコーダで各文章を処理します。検索候補を保存しておけば、質問が来たときは質問側だけを新しくエンコードできます。

Q. NLIの含意・矛盾・中立を検索時にも判定しますか?

A. 標準的な類似度推論では判定しません。NLI分類器は文表現を学ぶために使い、検索時は文ベクトルとコサイン類似度を使います。そのスコアが含意の確率や回答の正しさを表すわけではありません。

Q. 日本語RAGへそのまま導入できますか?

A. 構成は応用できますが、日本語を扱う能力と検索対象への適合を確認する必要があります。原論文の英語STSの相関だけでは導入判断はできません。日本語の実際の質問と正しい候補を用意し、候補のRecall@k、応答時間、後段の回答品質を測ってください。

Q. 候補数が増えても検索コストは一定ですか?

A. 一定ではありません。候補ごとのBERT推論は事前計算できますが、保存済みベクトルとの全件比較は候補数に比例して増えます。近似索引を使う場合も、索引の構築・更新・メモリと検索精度のトレードオフが残ります。

今日の学び

この論文は、文ペアを毎回BERTで読むと比較数が増えすぎることと、そのままのBERT表現では意味の距離を測りにくいことを扱いました。重みを共有して文章を独立にエンコードし、教師データで文表現を調整することで、重い計算を文章ごとに再利用できるようにしています。

得られるヒントは、推論を速くするには、モデル1回の実行速度だけでなく「同じ情報を何度計算しているか」を見直すことです。独立した表現で候補を集め、必要な部分を詳しく照合する構成は、検索機能を作るときの有力な設計案になります。