A-4:トークン化と語彙構築
A-3では、Transformerの内部でSelf-Attentionの出力を安定して変換するために、正規化と活性化関数が果たす役割を見ました。しかし、Transformerが処理するのは文字列そのものではありません。最初に必要なのは、テキストをモデルが扱える整数列へ変換することです。この入口の設計がトークン化と語彙構築です。
一見すると、トークン化は文章を単語や文字に分ける単純な前処理に見えます。けれど、どの単位に分けるかで、同じ文章のトークン数、未知の表記への対応、計算コスト、多言語での公平さまで変わります。モデルの性能を語るとき、アーキテクチャやパラメータ数だけでなく、どのトークナイザを使うかを見る必要があるのはこのためです。
今回は、文字・単語・サブワードの違いを押さえたうえで、現在のLLMで広く使われるBPEとSentencePieceを扱います。記事の目標は、トークナイザを使えるようになることだけではありません。「なぜこの分割単位なのか?」「語彙サイズを大きくすると何が変わるのか?」を、用途に応じて考えられるようになることです。
1. トークン化は何を変換しているのか?
トークン化とは、文字列をトークンと呼ばれる単位へ分割し、各トークンを語彙表にあるIDへ置き換える処理です。TransformerはIDをEmbedding層でベクトルに変換し、そのベクトル列を処理します。
処理は大きく三段階に分けられます。
- 入力テキストを正規化・前処理する
- 文字列をトークンへ分割する
- トークンを語彙表に対応する整数IDへ変換する
同じ文字列でも、トークナイザが異なればID列もトークン数も変わります。学習済みモデルの重みは、そのモデルが学習時に使った語彙とIDの対応を前提にしています。そのため、既存モデルに別のトークナイザをそのまま組み合わせることはできません。
2. 文字単位・単語単位・サブワード単位は何が違うのか?
分割の粒度には代表的に三つの選択肢があります。それぞれの利点だけでなく、どの問題を引き受けるかを見ることが重要です。
| 単位 | 利点 | 主な課題 |
|---|---|---|
| 文字単位 | 語彙を小さくでき、未知の文字列にも分解して対応しやすい | 系列が長くなり、長距離の計算負荷が増えやすい |
| 単語単位 | 人間が読む単語に近く、系列を短くしやすい | 語彙外語(OOV)が起きやすく、日本語などでは単語境界の定義も必要 |
| サブワード単位 | 頻出語は短く、未知語は細かく分割できる | 分割結果が直感に反する場合があり、語彙設計の影響を受ける |
現在のLLMで主流なのはサブワード単位です。頻出する語や語形を一つのトークンにまとめつつ、初めて見る語はより小さな単位へ分割できます。これは、巨大な単語語彙を持つことと、文字単位で非常に長い系列を処理することの間を取る設計です。
ただし「1トークンは1単語」ではありません。英語の空白、日本語の漢字やひらがな、絵文字、URL、プログラムコードなどで分割のされ方は大きく変わります。トークン数から文章量を推定するときは、この違いを忘れないようにしましょう。
3. BPEはどのように語彙を作るのか?
Byte Pair Encoding(BPE)は、最初は小さな単位から始め、コーパス内で頻繁に隣接するペアを反復的に結合して語彙を作る方法です。自然言語のトークン化では、文字やバイトを初期単位にし、頻出する並びをサブワードとして登録します。
概念的な流れは次の通りです。
- テキストを初期単位へ分割する
- コーパス全体で隣接ペアの頻度を数える
- 最も頻度の高いペアを一つの新しいトークンに結合する
- 目標の語彙サイズになるまで繰り返す
たとえば、あるコーパスでtransformとtransformerが頻繁に現れるなら、共通する文字列が段階的に結合され、より長いサブワードになる可能性があります。どのペアが選ばれるかは、学習コーパス、事前処理、語彙サイズで変わります。
バイトを初期単位にするByte-level BPEには、任意のUnicode文字列をバイト列へ落とせるという利点があります。未知の文字を専用の未知語トークンへ置き換えずに済む場合がある一方、表示上の文字数とトークン数が直感的に対応しにくいことがあります。
4. WordPieceとSentencePieceは何が違うのか?
WordPieceもサブワード方式ですが、一般に尤度の改善につながる分割を選ぶ考え方で説明されます。BERT系で使われた方式として知られています。実装や前処理の細部はモデルごとに異なるため、「WordPieceなら必ず同じ分割になる」とは考えないほうが安全です。
SentencePieceは、空白を特別な文字として扱い、言語に依存せずに生の文字列からトークナイザを学習できるライブラリと手法群です。BPEだけでなく、unigram language modelに基づく分割も扱えます。単語境界が明確ではない日本語や中国語を含む多言語データで使いやすいことが大きな利点です。
| 観点 | BPE | WordPiece | SentencePiece |
|---|---|---|---|
| 基本的な考え方 | 頻出ペアを反復的に結合する | 尤度を基準にサブワードを選ぶ | 生テキストからBPEまたはunigram方式を学習する |
| 空白の扱い | 前処理の設計に依存する | 実装に依存する | 空白を記号として扱える |
| 多言語での使いやすさ | 設計次第 | 設計次第 | 言語非依存の処理を採りやすい |
どの方式を選んでも、コーパスの品質と前処理が不適切なら良い語彙にはなりません。方式の名前だけで判断せず、実データでのトークン数、分割例、下流タスクの結果を確認することが必要です。
5. 語彙サイズは何とトレードオフになるのか?
語彙サイズを大きくすると、頻出する長い文字列を少ないトークン数で表しやすくなります。その一方で、Embedding層と出力層のパラメータが増え、各トークンの出現回数は分散しやすくなります。小さくしすぎると、文字列が細かく分かれて入力系列が長くなり、Self-Attentionの計算量も増えやすくなります。
| 語彙サイズ | 期待できること | 注意点 |
|---|---|---|
| 小さい | 埋め込み・出力層を小さくできる | トークン数が増え、長い系列になりやすい |
| 大きい | 頻出語や表記を短く表せる | 埋め込み・出力層が大きくなり、低頻度トークンが増える |
| 中程度 | 上記のバランスを取りやすい | データと言語に合わせた検証が必要 |
最適な語彙サイズに普遍的な正解はありません。対象言語、コードや数式の比率、想定コンテキスト長、モデル規模、データ量を踏まえて決めます。トークン数が少ないことだけを目標にすると、語彙が過度に大きくなり、学習効率やメモリ使用量で別の問題が出ることがあります。
6. 特殊トークンは何のために必要なのか?
語彙には、通常の文字列以外にも制御用の特殊トークンが含まれることがあります。どのトークンを用意するかは、事前学習、会話形式、分類、バッチ処理などの目的によって異なります。
| 代表例 | 用途 |
|---|---|
| BOS(文頭) | 新しい系列の開始を表す |
| EOS(文末) | 系列の終了を表す。生成停止にも利用できる |
| PAD(埋め草) | 長さの異なる系列を同じ長さにそろえる |
| UNK(未知語) | 語彙にない単位を表す。一部の方式では使わない場合もある |
| 特別な区切りトークン | 会話の役割、文書境界、タスクの境界を表す |
特殊トークンのIDや意味を途中で変えると、学習済みのEmbeddingとの対応が崩れます。特に会話テンプレートを変更する場合は、学習時と推論時で同じ形式になっているかを確認する必要があります。
7. 多言語トークン化で確認すべきことは何か?
一つの語彙で複数言語を扱う場合、言語によって同じ文章量でも必要なトークン数が大きく異なることがあります。ある言語が細かく分割されると、利用可能なコンテキスト長を早く使い切り、学習時の1トークン当たりの情報量も変わります。
日本語では、空白区切りを前提にした単語分割だけでは扱いにくい場面があります。漢字、ひらがな、カタカナ、英数字が混在する表記も多く、学習データの比率が低ければ、日本語の頻出表現が細かく分割される可能性があります。
多言語の語彙を設計するときは、次を測定します。
- 言語ごとの文字数または単語数に対するトークン数
- 低頻度言語でUNKや過度な分割が起きていないか
- コード、URL、数式、絵文字など非自然言語的な入力の分割
- 学習コーパスにおける言語比率と、想定する利用比率の差
「一つのトークナイザで全言語を公平に扱える」とは限りません。分割効率を確認し、必要ならコーパスのサンプリングや語彙サイズを調整することが重要です。
8. トークナイザの挙動を最小コードで確認する
既存の学習済みモデルを使う場合は、対応するトークナイザを読み込み、実際の入力が何トークンに分かれるかを確認するのが最も確実です。以下はHugging Face Transformersを使う最小例です。モデル名は利用するモデルへ置き換えてください。
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
text = "Transformerは文章をトークンIDへ変換します。"
token_ids = tokenizer.encode(text, add_special_tokens=False)
tokens = tokenizer.convert_ids_to_tokens(token_ids)
print(token_ids)
print(tokens)
print(f"トークン数: {len(token_ids)}")
同じコードで英語、日本語、URL、コード断片などを比べると、トークナイザの偏りが見えます。gpt2のトークナイザは日本語向けに最適化されたものではないため、日本語の利用状況を評価する例としては、対象モデルに対応した多言語トークナイザでも確認してください。
9. よくある失敗と確認ポイント
9.1 学習と推論で別のトークナイザを使う
モデルとトークナイザは一組です。語彙ファイル、マージ規則、正規化、特殊トークン、チャットテンプレートのいずれかが変われば、同じ文字列でも異なるID列になる可能性があります。学習済みモデルを使う場合は、モデルとともに配布されるトークナイザ設定を固定します。
9.2 文字数だけでコンテキスト長を見積もる
「何文字まで入るか」は、言語とトークナイザで変わります。特に日本語・中国語・コード・絵文字を含む入力では、英語中心の大まかな換算が外れることがあります。実際の入力をトークン化して計測するのが確実です。
9.3 特殊トークンを通常の本文として扱う
EOSや会話の区切りトークンは、モデルにとって意味を持つIDです。入力へ重複して入れたり、必要な区切りを省いたりすると、生成形式が崩れることがあります。テンプレートを使う場合は、ライブラリが特殊トークンを追加する箇所を確認しましょう。
10. まとめ

今回の要点を整理します。
- トークン化は、文字列をTransformerが処理できるID列へ変換する入口の設計である
- 現代のLLMでは、頻出表記と未知語対応のバランスを取るサブワード方式が中心である
- BPEは頻出ペアを結合して語彙を作り、SentencePieceは言語に依存しにくい学習方法を提供する
- 語彙サイズは、トークン数、Embedding・出力層の大きさ、低頻度トークンのバランスに関わる
- 多言語では、言語ごとの分割効率を実際のデータで測る必要がある
- 学習済みモデルでは、モデルとトークナイザの対応を必ず保つ
トークナイザは、目立たない前処理ではありません。モデルが何を一単位として読み、どのくらいの長さの文脈を扱うかを決める、アーキテクチャの一部です。
11. 今回のブログの考察:A-5への橋渡し
A-4では、テキストがトークン列となり、Embedding層へ渡るまでの過程を見ました。しかし、トークンを並べただけでは、Transformerはその順序を知りません。「犬が人を追う」と「人が犬を追う」のように、同じトークンを含んでいても並び順で意味が変わる入力を区別するには、位置に関する情報が必要です。
次に考えるべきは、各トークンが系列のどこにあるのか?、そしてトークン同士がどれだけ離れているのか?をどのように表現へ加えるかという問題です。
次回A-5では、絶対位置エンコーディングから相対位置表現、RoPE、ALiBiまでを取り上げます。トークン化によって作られた「単位の列」に、Transformerが順序を読み取るための情報をどう与えるのか?を見ていきましょう。
参考文献
- Sennrich, R., Haddow, B., & Birch, A. (2016). “Neural Machine Translation of Rare Words with Subword Units.” https://arxiv.org/abs/1508.07909
- Schuster, M., & Nakajima, K. (2012). “Japanese and Korean Voice Search.” ICASSP 2012.
- Kudo, T., & Richardson, J. (2018). “SentencePiece: A Simple and Language Independent Subword Tokenizer and Detokenizer for Neural Text Processing.” https://arxiv.org/abs/1808.06226
- Radford, A., Narasimhan, K., Salimans, T., & Sutskever, I. (2018). “Improving Language Understanding by Generative Pre-Training.” OpenAI Technical Report.
- Rust, P., Pfeiffer, J., Vulić, I., et al. (2021). “How Good is Your Tokenizer? On the Monolingual Performance of Multilingual Language Models.” https://arxiv.org/abs/2012.15613
このシリーズの案内
ブログA「Transformer構成」(全7回)では、現代のLLMを支えるTransformerの構成要素を、全体像から実装への接続まで段階的に扱います。
| # | テーマ | 内容 |
|---|---|---|
| A-1 | Transformer構成の基本概念と重要性 | 全体像、部品の役割、データフロー |
| A-2 | Self-Attentionの詳細 | Q・K・V、Causal Mask、マルチヘッド、計算量 |
| A-3 | 正規化と活性化関数 | LayerNorm、RMSNorm、GELU、SwiGLU |
| A-4 | トークン化と語彙構築 | BPE、SentencePiece、語彙サイズの設計(今回) |
| A-5 | 位置エンコーディングの進化 | 絶対位置、相対位置、RoPE、ALiBi |
| A-6 | 構成要素の統合と設計 | Pre-Norm、層構成、スケーリングとの関係 |
| A-7 | 理論の総まとめ | 概念の統合と実装編への橋渡し |


コメント