Googleが開発したオープンソースのサブワードトークナイザー。事前の単語分割を必要とせず、生のテキストから直接トークナイゼーションモデルを学習できる言語非依存のツール。
SentencePieceは、Googleが2018年に公開したオープンソースのトークナイザーライブラリです。従来のBPE実装では事前に空白で単語分割する前処理が必要でしたが、SentencePieceは生のテキストをそのまま入力として受け取り、空白を含めたすべての文字をトークン候補として扱います。これにより日本語・中国語・タイ語など、スペースで単語区切りがない言語でも前処理なしで適用できます。
SentencePieceは複数のサブワードアルゴリズムを統一的なインターフェースで提供します。
| アルゴリズム | 特徴 | 採用例 |
|---|---|---|
| BPE | 頻出ペアを貪欲にマージ | LLaMA 2, Mistral |
| Unigram | 確率モデルで最適分割を選択 | T5, mBART, ALBERT |
| Word | 単語単位(サブワードなし) | 研究用途 |
| Char | 文字単位(サブワードなし) | 研究用途 |
BPEが貪欲にペアをマージするのに対し、Unigramモデルは大きな初期語彙から不要なトークンを削除する「引き算」アプローチです。各トークンに出現確率を付与し、テキストの対数尤度を最大化するように語彙を最適化します。
Unigramの利点は、同じテキストに対して複数の分割候補を確率的にサンプリングできることです。これにより学習時のデータ拡張(Subword Regularization)が可能になり、モデルの汎化性能が向上します。
SentencePieceは空白を特殊文字「▁」(U+2581)に置換して1つの文字として扱います。これにより「▁the」と「the」が別トークンとなり、文頭と文中の単語を区別できます。
入力: "I like NLP"
BPE前処理: ["I", "like", "NLP"] → 空白情報が消失
SentencePiece: ["▁I", "▁like", "▁NL", "P"] → 空白情報を保持
SentencePieceのトークナイゼーションは完全に可逆です。トークン列をデコードすると元のテキストが空白も含めて完全に復元されます。従来のBPE実装では前処理で空白を除去するため、デコード時に空白の復元が不完全になるケースがありました。
# 語彙サイズ32,000のBPEモデルを学習
spm_train --input=corpus.txt \
--model_prefix=tokenizer \
--vocab_size=32000 \
--model_type=bpe \
--character_coverage=0.9995
import sentencepiece as spm
sp = spm.SentencePieceProcessor()
sp.Load("tokenizer.model")
tokens = sp.EncodeAsPieces("自作パソコンを組み立てる")
# ["▁自作", "パソコン", "を", "組み立て", "る"]
ids = sp.EncodeAsIds("自作パソコンを組み立てる")
# [1234, 5678, 91, 2345, 67]
text = sp.DecodeIds(ids)
# "自作パソコンを組み立てる"(完全復元)
| パラメータ | 説明 | 推奨値 |
|---|---|---|
| vocab_size | 語彙サイズ | 32,000〜128,000 |
| model_type | アルゴリズム | bpe / unigram |
| character_coverage | カバーする文字の割合 | 0.9995(多言語) |
| byte_fallback | 未知文字のバイトフォールバック | true(推奨) |
| split_digits | 数字を1桁ずつ分割 | true |
| add_dummy_prefix | 文頭に▁を付与 | true |
学習データに含まれる文字のうち、語彙に含める文字の割合です。英語のみなら0.9995で十分ですが、CJK文字を含む多言語モデルでは0.99995以上に上げないと漢字がバイトフォールバックされます。
SentencePieceはC++実装の独立ライブラリで、学習済みモデルは.modelファイルとして配布されます。Hugging Face tokenizersはRust実装で高速ですが、SentencePieceのモデルをラップして使うケースが多いです。LLaMA系のモデルはSentencePieceの.modelファイルを直接配布しています。
character_coverageを0.99995以上に設定し、語彙サイズを50,000以上にすることで日本語の圧縮率が改善します。byte_fallback=trueにしておけば、語彙にない漢字もバイト表現で分割されOOVが発生しません。
不要です。SentencePieceの学習はCPUで実行され、10GBのコーパスに対して数時間で完了します。メモリは学習データサイズの2〜3倍が目安です。