トークン化 入門
LLM がテキストを扱う前にやることは、テキストを小片に切り、各片に整数 ID を引くこと。 その小片をトークンと呼び、切る作業をトークン化(tokenization)と呼ぶ。短い 4 トピック:全体の問題を枠取り する文字 / 単語 / サブワードのトレードオフ;BPE(GPT が使うアルゴリズム);WordPiece、SentencePiece、Unigramの主要 派生;そして現代 LLM の語彙が5 万から 20 万に収まる理由。
文字、単語、サブワード?
「単位」の選択が、以後あらゆるコストと能力の形を決める。
テキストから数値へのパイプラインの最初の決定が、最も大きな結果をもたらす:何を 「トークン」とするか? 伝統的な答えは 3 つあり、それぞれに崩れた妥協があった。 サブワード分割が現れて、すべてを静かに置き換えるまでは。
- 文字レベル。各文字が 1 トークン。語彙は小さい (ASCII ~100、Unicode 数千)、OOV なし —— あらゆるテキストを表現できる。 代償:系列が非常に長くなる。100 単語の文が ~500 トークンに。系列長は Transformer にとって何でも高くつく —— アテンションは O(n²)、KV キャッシュは線形に成長。 可能だが遅い。
- 単語レベル。各単語が 1 トークン。100 単語の文は 100 トークン。 単位は自然、系列は短い。だが代償が大きい:語彙が爆発(英語だけで複数形、屈折、 複合語、人名を含めれば数百万の語形)、未知の単語はすべて「語彙外(OOV)」 —— モデルは何をすればいいか分からない。
- サブワード。ハイブリッド:頻出語はそのまま、稀少語を再利用可能な 片に分割。\"unhappiness\" は \"un\" + \"happi\" + \"ness\" に。語彙は小さく (5 万 – 20 万)、系列は短く、未知語も馴染みの片で組み立てられる。OOV なし。 現代の LLM はみなこれ。
サブワードが勝つ理由は、他の 2 つの失敗モードを見れば最も明瞭だ。純粋な文字レベルはすべてを表現できるが、n² のアテンションコストで長文脈推論が非実用に。 純粋な単語レベルは語彙外を表現できず、Web テキストで訓練すると OOV が爆発する。 サブワードは「必要なときは文字、十分なときは単語」。現代の tokenizer は皆この変種。
微妙な点。サブワードトークンの「適切なサイズ」は言語に依存する。英語では典型的に 単語の約半分(平均 3–4 文字)。中国語・日本語では 1 文字、ときに 1 Unicode バイト。 コードではサブキーワード:\"def\" + \" \" + \"function\"。多言語または多形式 コーパスで訓練された tokenizer はこれらを慎重にバランスする —— バランスが悪いと トークン課金が驚くことになる(初期 GPT-3 で中国語は同等の英語の 3 倍トークンに)。
Transformer では:tokenizer はモデルが触れる最初と最後のもの。 入力テキスト → トークン ID → 埋め込み → アテンション層 → ... → 出力ロジット → 次トークン ID → テキストへ復号。Transformer が支払うあらゆるコスト —— VRAM、 計算、レイテンシ、API 価格 —— は tokenizer が生み出したトークン数に比例する。 この意味で、tokenizer は「前処理に変装した設計判断」だ。
BPE —— Byte Pair Encoding
GPT が使う貪欲合併アルゴリズム、もともと 1994 年にデータ圧縮のために発明された。
Byte Pair Encoding は 2026 年のサブワード分割で主流のアルゴリズム。GPT-2 から GPT-4o までの GPT 系列、ほとんどの LLaMA 系モデルがこれを使う。アルゴリズム自体は 意外と小さい。
訓練:
1. 語彙 = コーパス内に現れる文字すべて。
2. 各単語を文字列に分割。
3. target_vocab_size − len(vocab) 回繰り返す:
a. コーパス全体で隣接トークンのペアを集計。
b. 最頻のペア (a, b) を見つける。
c. 新トークン "ab" に合併し、語彙に追加。
d. コーパス全体にこの合併を適用。
トークン化(訓練済みの merges を使う):
1. 入力を文字に分割。
2. 学習順に merges を貪欲に適用。
3. 得られたトークン列を返す。アルゴリズムはこれだけ。大コーパスで十分長く回せば、使える LLM tokenizer になる。
「byte pair encoding」の「byte」に隠れた数点:
- バイトから出発。GPT-2 / GPT-3 / GPT-4 はバイトレベルBPE を使う —— Unicode 文字ではなく 256 個の生バイトから始める。これにより tokenizer は「未知文字」コードを別途持たずに任意の言語・任意のバイト列を扱える。
- 前トークン化。BPE を回す前に、現代の tokenizer は空白と記号で テキストを区切る。これで BPE は単語境界をまたぐ合併をしない。OpenAI tokenizer は 正規表現で連続する文字、数字、空白などをグループ化する。
- 特殊トークン。実語彙には「テキストでない」トークンが含まれる ——
<|endoftext|>、<|im_start|>のようなチャット フォーマットマーカー、パディングトークンなど。これらは BPE 合併から来ず、手で追加され、 語彙先頭の数百 ID を予約する。 - 決定性。訓練後の tokenizer はテキストから ID への決定的関数。 訓練はランダム(コーパスのサブサンプリング)、推論はそうではない。
歴史的に見て BPE が勝った理由は実用主義の物語だ。以前にもサブワード手法は存在した (Morfessor 等)が、BPE は 100 行で実装できるほど単純で、Web 規模コーパスで訓練 できるほど高速で、結果として使える tokenizer を生んだ。Sennrich et al.(2016)が データ圧縮からニューラル機械翻訳に転用し、2 年で既定になった。2019 年の GPT-2 が バイトレベル BPE を自己回帰 LLM の標準として確立した。
Transformer では:あらゆる現代 LLM に同梱される BPE merges ファイルは、学習順のペアリストに過ぎない。tokenizer は起動時に 1 度読み込み、 高速検索用のトライまたはハッシュ表を構築し、各プロンプトに貪欲に適用する。 tiktoken(OpenAI の tokenizer)は数百 MB/s で動く。モデルがテキストを見ることは ない —— その向こうから出てくる整数 ID だけ。
WordPiece、SentencePiece、Unigram
サブワード分割の 3 派生、それぞれ少しずつ違う合併規準。
BPE が唯一のサブワードレシピではない。他に 3 つの手法が並存し、特定の用途では BPE より先んじることもある。生成される tokenizer は性質的に似ている —— 固定語彙、 OOV なし、頻出語はそのまま —— が、語彙の学習方法とテキストの分割方法では細部で異なる。
- WordPiece(Schuster & Nakajima、2012)。もとは Google の 日本語音声認識システムから、BERT が採用。BPE に似るが、頻度ではなく尤度規準を使う: 各ステップで、訓練コーパスの確率(unigram 言語モデル下で)を最大化するペアを合併。 実用上は語彙が似て見えるが、WordPiece はやや長めのサブワードを残しやすい。 継続部には
##接頭辞が付く —— BERT の出力に##ing、##tionが頻出する理由。 - Unigram(Kudo、2018)。確率的な代替案。大きな初期語彙(よく BPE で 初期化)から始め、EM 最適化で最も有用でないトークンを反復的に削る。単語の「最良の 分割」は unigram モデル下で総確率を最大化するもの。固有の特徴:1 つの単語に 複数の合法な分割が存在。訓練時のデータ拡張(\"subword regularization\")に有用。
- SentencePiece(Kudo & Richardson、2018)。新しい合併アルゴリズム ではなく、別の前処理:入力を空白を含む生バイト列として扱う。空白は トークンの一部となる(
▁、U+2581 で表示)。結果:完全に言語非依存、 単語分割の別ステップ不要、中国語・日本語のような空白なし言語やコードでも同様に動く。 SentencePiece はフレームワークであり、BPE や Unigram を内部で動かせる; LLaMA 系モデルは通常 SentencePiece + BPE を使う。
「##」と「▁」の慣習は、踏むまでは恣意的に感じる:
- BERT の WordPieceは入力がトークン化前にすでに単語分割されていると 仮定。トークン上の
##は「前の単語に続き、前に空白を入れるな」の意。 空白で単語を区切る言語には便利だが、そうでない言語では不器用。 - SentencePieceは空白について何も仮定しない。元のテキストで前に 空白がある単語のトークンは
▁で始まり、なければ付かない。逆トークン化は▁を取り除くだけ。対称的、言語中立、「これは継続部か?」のような特別 ロジックがどこにも要らない。 - GPT の BPEは中間:空白はトークンの一部(先頭の空白はしばしば次の トークンの先頭、例:
\" the\"が 1 トークン)、だが継続マーカーはない。
実務的にはあなた自身が tokenizer を選ぶことはほぼなく、基盤モデルが使うものを継承する。 これらの選択は主に歴史的:GPT はバイトレベル BPE を選び、BERT は WordPiece を、 T5 と多言語モデルの多くは SentencePiece を選んだ。違いはモデル系列を跨いだ微調整、 または非標準ドメインで新 tokenizer を訓練する場合に問題になる。
Transformer では:tokenizer はモデル重みと共に出荷される独立成果物。 典型的なモデル公開は(重み、tokenizer、config)の 3 点セット、tokenizer は その中で最小(数百 KB)。重みのセットに間違った tokenizer を使うと、深層学習で最も 静かに失敗するモードの 1 つ —— モデルは自信を持ってゴミを出力する。
現代の語彙サイズ —— 5 万から 20 万
なぜ「適切な語彙サイズ」がこの帯にあり、その中で動くにはどんなコストがかかるか。
LLM 時代の大半(2019–2024)、「語彙サイズ」は誰も触らない調整つまみだった —— 5 万前後が GPT-2 の影響力ある公開で既定となり、その後の多くのモデルが継承した。 最先端はこの 2 年で上がり、現在の帯は大体 5 万から 20 万。理由を見る。
主要モデルの具体的な数字:
- GPT-2(2019):50,257 トークン。英語中心の Web テキストでバイトレベル BPE。 約 5 年間の既定値となった。
- LLaMA 1 / 2(2023):32,000 トークン。効率のため GPT より小さく、 SentencePiece BPE。英語向け中心、多言語サポートは限定。
- GPT-4 / cl100k(2023):100,256 トークン。GPT-2 を約 2 倍、 コード・非英語・現代の技術用語のカバレッジを大幅に改善。
- LLaMA 3(2024):128,256 トークン。LLaMA 2 から大きく跳ね、 特に多言語とコードカバレッジ改善のため。
- GPT-4o(2024):約 20 万トークン。最先端をさらに押し上げた; 非英語テキストが劇的に圧縮される(同じ中国語・日本語の段落で GPT-4 の 1/4 トークン数になることも)。
- Claude 3 / Gemini(2024):非公開だが、噂では 10 万 – 20 万の帯。
これらの数字の背後にあるトレードオフが、設計の中心問題:
- 語彙が大きい → テキストあたりのトークンが少ない。各トークンが 平均してより多くの文字をカバー。10 万語彙は \"unhappiness\" を 1 トークンに収め得る; 3 万語彙ではおそらく分割。トークンが少なければ推論が安い(アテンション計算が少なく、 KV キャッシュが小さく、ユーザーの API 価格が低い)。
- 語彙が大きい → 埋め込みテーブルが大きい。埋め込みテーブルは
vocab_size × d_model。d_model = 4096なら、5 万から 20 万でテーブルは 2 億から 8 億パラメータに —— 訓練と保存で実コスト。現代の LLM は 入力埋め込みと出力射影の重みを共有(\"tied weights\")して半減することが多い。 - 語彙が大きい → 稀少トークンの長い裾尾。20 万語彙では、訓練中に ほぼ出現しないトークンが数千ある。それらの埋め込みは学習が不十分で、誤って使うと 珍しい入力での品質を損なう(\"glitch token\" 現象 ——
SolidGoldMagikarpを検索)。 - 語彙が大きい → 非英語 / コードカバレッジが良い。5 万から 20 万への 移動の最大の単一理由。GPT-3 で 1000 トークン要する中国語段落が、GPT-4o では 250 トークンになり得る —— 大語彙には中国語固有の多文字トークンが多数あるからだ。 コードも同様 —— 10 万+ 語彙は
printf、def、console.logなど一般的な識別子を 1 トークンとして保持できる。
実用的助言、もし語彙サイズを選ぶ機会があれば:気にする言語と形式について許容可能な トークン/文字比を生む最小の語彙を狙う。英語のみの研究なら 3 万 – 5 万で十分。多言語や コード重視の用途では、2026 年の床は 10 万+。強い理由なしにそれ以下にしない; 埋め込みテーブルがボトルネックになることは稀で、系列長の節約はあらゆるプロンプトの あらゆるトークンで複利的に効く。
Transformer では:語彙サイズはモデル全体を挟む両端のパラメータ。 入力側の埋め込み次元と出力側の分類ヘッドの次元を決め、その間はすべて独立。 32K 語彙の 7B LLaMA-2 と 128K 語彙の 7B LLaMA-3 は中央の構造は同じだが、 後者は埋め込み + 出力ヘッドで約 9,600 万パラメータ多い。tokenizer の選択は すべての層に波及する。
前提知識スタックはここまで —— 数学、データ、最適化、ハードウェア、ソフトウェア、 単語埋め込み、トークン化。部品はすべて出揃った。次の primer がついに組み立てる: Transformer。