BPE (バイトペアエンコーディング)
テキストを頻出するバイト (文字) の組み合わせに基づいてサブワード単位に分割するアルゴリズム。GPT シリーズなど、大規模言語モデルのトークナイザーとして広く採用されている。
BPE (Byte Pair Encoding、バイトペアエンコーディング) は、もともと 1994 年にフィリップ・ゲージがデータ圧縮アルゴリズムとして提案した手法です。2015 年にセネリッヒらが機械翻訳のサブワード分割へ応用して以降、自然言語処理の標準的なトークン化手法となりました。GPT シリーズや LLaMA のトークナイザーは BPE 系ですが、BERT のトークナイザーは WordPiece という別方式です。WordPiece も語より小さい単位へ分割する同じ系統の手法で、統合するペアの選び方が出現頻度そのものではない点が異なります。「大規模言語モデルのトークナイザーはすべて BPE」とまとめると外れます。
BPE の学習アルゴリズムは直感的です。まず、訓練テキストを文字 (またはバイト) 単位に分割します。次に、最も頻繁に隣接するペアを見つけ、そのペアを 1 つの新しいトークンとして統合します。この統合を語彙サイズが目標に達するまで繰り返します。たとえば「low」「lower」「lowest」というテキストから、「l」+「o」→「lo」、「lo」+「w」→「low」のように頻出ペアが順次統合されます。
BPE の強みは、未知語 (out-of-vocabulary) の問題を小さくできることです。単語単位のトークン化では、訓練データに含まれない単語を処理できません。BPE ならどんな単語もサブワードの組み合わせに分解できます。「unhappiness」は「un」+「happiness」や「un」+「happ」+「iness」のように分割され、各サブワードは語彙に含まれています。
ただし「未知語が絶対に出ない」わけではありません。語彙を文字単位から作った場合、語彙に無い文字が入力されると表現できず、未知語を表す専用トークン (BERT なら [UNK]) に置き換えられます。約 3 万語の語彙を持つ BERT がこの形です。これを避ける方式がバイトレベル BPE で、テキストをいったん UTF-8 のバイト列に変換してから統合を学習するため、どんな文字列でも必ず表現できます。GPT-2 系や RoBERTa などがこの方式で、絵文字や珍しい漢字も細かく割れはするものの欠落しません。
日本語の BPE トークン化には特有の課題があります。日本語はスペースで単語が区切られないため、事前に形態素解析で単語分割してから BPE を適用する方法と、文字レベルから直接 BPE を学習する方法があります。GPT-4 のトークナイザー (cl100k_base) は後者のアプローチで、日本語の漢字 1 文字が 1 トークンになることもあれば、ひらがなの連続が 1 トークンにまとまることもあります。cl100k_base の分割規則には、語の直前にある空白をその語のトークンへ取り込む働きがあり、英語では同じ語でも直前が空白かどうかで分割が変わります。日本語は語の間に空白を置かないため、この働きはありません。
トークン数と文字数の関係は言語によって異なります。英語なら 1 トークンあたり 4 文字程度、日本語なら 1 トークンあたり 1〜2 文字程度が目安です。同じ文字数の文章なら、日本語のほうがトークン数は多くなりやすいと考えておけば大きくは外しません。ただしこの目安は内容や表記でぶれます。入力上限や料金を見積もるときは、そのモデルのトークナイザーで実際に数えるのが確実です。上限のトークン数はモデルによって違い、トークナイザーが違えば同じ文章でも数え方の結果が変わります。
文字数とトークン数は別物として扱うのが実務的です。入力欄の制限や表示の折り返しは文字数で決まりますが、モデルに入りきるか、費用がいくらになるかはトークン数で決まります。BPE は頻出するペアを統合して語彙を作る仕組みなので、よく使われる表記は少ないトークンにまとまり、珍しい表記や記号の羅列、独自の固有名詞は細かく割れてトークン数が増えます。長いプロンプトを縮めたいときは、文字数を削るよりも、繰り返しや変わった表記を普通の書き方へ直すほうが効きやすい、という見当が付けられます。