トークン化 入門

LLM がテキストを扱う前にやることは、テキストを小片に切り、各片に整数 ID を引くこと。 その小片をトークンと呼び、切る作業をトークン化(tokenization)と呼ぶ。短い 4 トピック:全体の問題を枠取り する文字 / 単語 / サブワードのトレードオフ;BPE(GPT が使うアルゴリズム);WordPiece、SentencePiece、Unigramの主要 派生;そして現代 LLM の語彙が5 万から 20 万に収まる理由。

01

文字、単語、サブワード?

「単位」の選択が、以後あらゆるコストと能力の形を決める。

テキストから数値へのパイプラインの最初の決定が、最も大きな結果をもたらす:何を 「トークン」とするか? 伝統的な答えは 3 つあり、それぞれに崩れた妥協があった。 サブワード分割が現れて、すべてを静かに置き換えるまでは。

  • 文字レベル。各文字が 1 トークン。語彙は小さい (ASCII ~100、Unicode 数千)、OOV なし —— あらゆるテキストを表現できる。 代償:系列が非常に長くなる。100 単語の文が ~500 トークンに。系列長は Transformer にとって何でも高くつく —— アテンションは O(n²)、KV キャッシュは線形に成長。 可能だが遅い。
  • 単語レベル。各単語が 1 トークン。100 単語の文は 100 トークン。 単位は自然、系列は短い。だが代償が大きい:語彙が爆発(英語だけで複数形、屈折、 複合語、人名を含めれば数百万の語形)、未知の単語はすべて「語彙外(OOV)」 —— モデルは何をすればいいか分からない。
  • サブワード。ハイブリッド:頻出語はそのまま、稀少語を再利用可能な 片に分割。\"unhappiness\" は \"un\" + \"happi\" + \"ness\" に。語彙は小さく (5 万 – 20 万)、系列は短く、未知語も馴染みの片で組み立てられる。OOV なし。 現代の LLM はみなこれ。
トークン化:"The unhappiness ended."文字レベル —— 22 トークンThe unhappiness ended.Theunhappinessended.文字レベル。語彙は小さいが、各文が長くなる。
1 / 3
3 つの粒度:文字(語彙小・系列長い)、単語(語彙大・OOV 問題)、サブワード(現代の妥協点)。

サブワードが勝つ理由は、他の 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 は「前処理に変装した設計判断」だ。

02

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 になる。

小コーパス上の BPE —— "low low low lower lowest"ステップ 0 —— 文字lowlowlowlowerlowest文字から開始。ペアを集計:(l,o) は 5 回。
1 / 4
BPE は文字から始め、最頻の隣接ペアを貪欲に合併する操作を繰り返し、目標サイズの語彙に達するまで続ける。

「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 だけ。

03

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 を使う。
単語 "unhappiness" —— 3 種類のトークナイザGPT(BPE)—— 2 トークンunhappinessunhappinessGPT バイトレベル BPE。"unhappiness" → "un" + "happiness"。2 トークン。
1 / 3
レシピが違えば合併も違い、境界の印付け方も違う。"##" は「前を継続」、"▁" は「単語の開始」。

「##」と「▁」の慣習は、踏むまでは恣意的に感じる:

  • BERT の WordPieceは入力がトークン化前にすでに単語分割されていると 仮定。トークン上の ## は「前の単語に続き、前に空白を入れるな」の意。 空白で単語を区切る言語には便利だが、そうでない言語では不器用。
  • SentencePieceは空白について何も仮定しない。元のテキストで前に 空白がある単語のトークンは で始まり、なければ付かない。逆トークン化は を取り除くだけ。対称的、言語中立、「これは継続部か?」のような特別 ロジックがどこにも要らない。
  • GPT の BPEは中間:空白はトークンの一部(先頭の空白はしばしば次の トークンの先頭、例:\" the\" が 1 トークン)、だが継続マーカーはない。

実務的にはあなた自身が tokenizer を選ぶことはほぼなく、基盤モデルが使うものを継承する。 これらの選択は主に歴史的:GPT はバイトレベル BPE を選び、BERT は WordPiece を、 T5 と多言語モデルの多くは SentencePiece を選んだ。違いはモデル系列を跨いだ微調整、 または非標準ドメインで新 tokenizer を訓練する場合に問題になる。

Transformer では:tokenizer はモデル重みと共に出荷される独立成果物。 典型的なモデル公開は(重み、tokenizer、config)の 3 点セット、tokenizer は その中で最小(数百 KB)。重みのセットに間違った tokenizer を使うと、深層学習で最も 静かに失敗するモードの 1 つ —— モデルは自信を持ってゴミを出力する。

04

現代の語彙サイズ —— 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 万の帯。
現代 LLM の語彙サイズ —— 3.2 万から 20 万GPT-2 —— 50,257 トークンGPT-250KLLaMA 232KGPT-4 (cl100k)100KLLaMA 3128KGPT-4o200KGPT-2 は 2019 年に ~50K BPE トークン、数年間「定番」だった。
1 / 3
語彙が大きい → 英文 1 文あたりのトークンが少なくなる(推論が安い)、だが埋め込みテーブルは大きくなり、めったに見ない長い裾尾も増える。

これらの数字の背後にあるトレードオフが、設計の中心問題:

  • 語彙が大きい → テキストあたりのトークンが少ない。各トークンが 平均してより多くの文字をカバー。10 万語彙は \"unhappiness\" を 1 トークンに収め得る; 3 万語彙ではおそらく分割。トークンが少なければ推論が安い(アテンション計算が少なく、 KV キャッシュが小さく、ユーザーの API 価格が低い)。
  • 語彙が大きい → 埋め込みテーブルが大きい。埋め込みテーブルはvocab_size × d_modeld_model = 4096 なら、5 万から 20 万でテーブルは 2 億から 8 億パラメータに —— 訓練と保存で実コスト。現代の LLM は 入力埋め込みと出力射影の重みを共有(\"tied weights\")して半減することが多い。
  • 語彙が大きい → 稀少トークンの長い裾尾。20 万語彙では、訓練中に ほぼ出現しないトークンが数千ある。それらの埋め込みは学習が不十分で、誤って使うと 珍しい入力での品質を損なう(\"glitch token\" 現象 —— SolidGoldMagikarpを検索)。
  • 語彙が大きい → 非英語 / コードカバレッジが良い。5 万から 20 万への 移動の最大の単一理由。GPT-3 で 1000 トークン要する中国語段落が、GPT-4o では 250 トークンになり得る —— 大語彙には中国語固有の多文字トークンが多数あるからだ。 コードも同様 —— 10 万+ 語彙は printfdefconsole.log など一般的な識別子を 1 トークンとして保持できる。

実用的助言、もし語彙サイズを選ぶ機会があれば:気にする言語と形式について許容可能な トークン/文字比を生む最小の語彙を狙う。英語のみの研究なら 3 万 – 5 万で十分。多言語や コード重視の用途では、2026 年の床は 10 万+。強い理由なしにそれ以下にしない; 埋め込みテーブルがボトルネックになることは稀で、系列長の節約はあらゆるプロンプトの あらゆるトークンで複利的に効く。

Transformer では:語彙サイズはモデル全体を挟む両端のパラメータ。 入力側の埋め込み次元と出力側の分類ヘッドの次元を決め、その間はすべて独立。 32K 語彙の 7B LLaMA-2 と 128K 語彙の 7B LLaMA-3 は中央の構造は同じだが、 後者は埋め込み + 出力ヘッドで約 9,600 万パラメータ多い。tokenizer の選択は すべての層に波及する。

前提知識スタックはここまで —— 数学、データ、最適化、ハードウェア、ソフトウェア、 単語埋め込み、トークン化。部品はすべて出揃った。次の primer がついに組み立てる: Transformer。