AI

トークナイザーとは?BPE・WordPiece・Unigramの違いと日本語での実装判断を解説【2026年版】

トークナイザーは、人間が読む文字列と、モデルが読む整数の列とを相互に変換する部品です。LLMは文字そのものを見ていません。見ているのはトークンIDの並びで、その並びを作るのがトークナイザーの仕事。この記事では、トークナイザーが内部で踏む4段階の処理、BPE・WordPiece・Unigramという3方式の学習則の違い、日本語のトークン消費が英語より膨らむ構造的な理由、そして実装で数え漏れや性能劣化を招く箇所と語彙拡張の採否条件までを、実装者の視点で整理します。

まとめ:トークナイザーの定義と実装で先に決まる結論

トークナイザーとは、生のテキストをモデルが処理できるトークンIDの列へ変換し、生成結果を再び文字列へ戻す仕組みを指します。現在のLLMが採るのはサブワード分割で、単語より細かく文字より大きい単位に切ることで、辞書にない語も既知の部品の組み合わせとして表せる構造。代表的な方式はBPE・WordPiece・Unigramの3つで、いずれも学習データの統計から語彙を自動で構築します。

実装上の結論を先に書きます。トークナイザーは自作するものではなく、使うモデルに付属するものをそのまま読み込むのが既定です。語彙IDは埋め込み行列の行番号と一対一で結び付いているため、別のトークナイザーへ差し替えた瞬間にモデルの出力は壊れます。触ってよい余地は、特殊トークンの扱いとトークン数の測り方だけと考えてください。

そのうえで日本語には固有の事情があります。語彙の割り当てが英語に厚く配分されるため、同じ意味の文章でも日本語のトークン消費は増えます。この差はコストと入力上限の設計を直撃するので、文字数からの換算式で済ませず、代表文書での実測から逆算するのが安全です。

トークナイザーが踏む4段階|正規化から語彙IDへの写像までの流れ

「テキストを切る」という一言で語られがちですが、実際の処理は4段に分かれています。不具合の切り分けは、どの段で起きたかを見極めるところから始まります。

正規化・事前分割・サブワード分割・後処理という4段の役割分担

Hugging Face の tokenizers ライブラリは、正規化(normalization)、事前分割(pre-tokenization)、モデル、後処理(post-processing)という4段のパイプラインで構成されています。正規化はUnicode正規化や小文字化、アクセント除去を担う段で、日本語では全角と半角の揺れがここで吸収されます。事前分割は空白や記号で粗く区切る段。英語なら空白がそのまま境界になりますが、日本語には語の区切りを示す空白がないため、この段はほとんど働きません。続くモデル段が本体のサブワード分割で、後処理が[CLS][SEP]のような特殊トークンを前後に付けます。同ライブラリはRustで実装されており、破壊的な正規化を挟んだ場合でも、どのトークンが原文のどこに対応するかを追跡できる設計になっています。ログから原文の該当箇所を復元したいときに効く性質です。

語彙IDと埋め込み行列が一対一で結び付く構造と差し替え不能の理由

語彙とは、トークン文字列から整数IDへの対応表のこと。そしてそのIDは、モデルの埋め込み行列の何行目を引くかという行番号そのものです。IDが5番のトークンは埋め込み行列の5行目のベクトルを受け取り、出力側のsoftmaxでも5番目の次元がそのトークンの確率になります。つまり語彙表とモデル重みは、学習時に固定された対応関係で縛られている構造。from_pretrainedでモデルと同じリポジトリのトークナイザーを読むよう案内されるのは、この対応を崩さないためです。

現場で起きる事故はここに集中する傾向です。量子化やフォーマット変換の際にtokenizer.jsonを持ち込み忘れる、派生モデルの重みにベースモデルのトークナイザーを組み合わせる、といった操作をすると、エラーは出ないのに出力が意味をなさない文字列になります。モデルの内部構造そのものはTransformerの自己注意の仕組み、IDから引かれるベクトルの側は埋め込みモデルの仕組みと選び方にそれぞれ整理しています。

サブワード3方式の違い|BPE・WordPiece・Unigramの学習則の比較

3方式はどれも「頻出する部品を語彙に登録する」点で共通しますが、何を基準に登録するかが違います。生成される分割結果もそれに従って変わります。

BPEが頻出ペアを結合していく手順と語彙サイズが決める取引関係

BPE(Byte Pair Encoding)は、文字またはバイト単位の状態から出発し、コーパス中で最も頻繁に隣り合うペアを1組ずつ結合していく加算型の手法です。結合のたびにその規則を順序付きで記録し、指定した語彙サイズに達するまで反復します。推論時は記録した規則を同じ順序で適用するだけなので、同じ入力からは常に同じ分割が得られる決定的な処理。

語彙サイズはハイパーパラメータで、ここには明確な取引関係があります。語彙を大きくすると1文あたりのトークン数は減り、入力枠の節約と推論の高速化につながる一方、埋め込み行列と出力層の幅が広がってメモリと学習コストが増える構造です。GPT系が採るバイトレベルBPEは、初期単位をUTF-8のバイトに置くことで、原理上どんな文字列でも未知語を出さずに表現できる構成になっています。

WordPieceとUnigramが採る評価軸の違いと分割結果への現れ方

WordPieceはBERT系で使われる方式で、結合の判断に頻度そのものではなく尤度の増分を使います。ペアの評価値は、結合した並びの頻度を、構成要素それぞれの頻度の積で割った値。この式のため、単体でも頻出する部品どうしは結合されにくくなります。単語の途中から続くトークンには##のような接頭辞が付き、語頭かどうかが区別されます。

Unigramは逆向きに進みます。まず大きめの候補語彙を用意し、各トークンを取り除いたときに全体の損失がどれだけ悪化するかを測って、寄与の小さいものから削っていく減算型。分割時は語彙全体を確率モデルとみなし、確率が最大になる分割系列を選びます。確率モデルである性質から、同じ入力に対して複数の分割候補を確率的にサンプリングでき、学習時のデータ拡張として使えるのが特徴です。

方式 語彙の作り方 選定の基準 主な採用例
BPE 加算(結合を反復) 隣接ペアの出現頻度 GPT系・多くの生成モデル
WordPiece 加算(結合を反復) 結合による尤度の増分 BERT系エンコーダ
Unigram 減算(候補から削る) 削除時の損失悪化量 T5・多くの日本語LLM

SentencePieceが空白を記号へ転義して言語非依存にする設計

SentencePieceは、上の3方式のうちBPEとUnigramを実装したライブラリで、日本語LLMで採用例が多い部品です。公式リポジトリの説明によれば、事前に語彙サイズを決めたうえで生の文からそのまま学習でき、言語固有の前処理を必要としません。鍵になるのが空白の扱いで、空白文字を「▁」(U+2581)というメタ記号へ転義し、語彙の一部として組み込みます。この設計により、トークン列を連結して▁を空白へ戻すだけで原文が完全に復元でき、逆変換が損失なく成立します。

語の境界を空白で示さない日本語・中国語・韓国語にとって、この性質は実務上の意味を持ちます。事前分割器を別途用意しなくても、生のテキストから語彙を学習して運用まで通せるからです。2026年8月3日時点のPyPI公開版は0.2系でした。

日本語でトークン消費が膨らむ理由|語彙配分とバイト分割の実態

同じ内容を書いても、日本語は英語よりトークンを食います。原因はモデルの性能ではなく、語彙の配分にあります。

語彙にない漢字がUTF-8のバイト列へ分解される構造と消費量への影響

語彙は学習コーパスの分布から作られます。英語中心のコーパスで学習したトークナイザーは、当然ながら英語の語や語尾に語彙枠を厚く配分し、日本語の漢字や熟語に回る枠は限られる。語彙に登録されている漢字なら1文字が1トークンで済みますが、登録から漏れた文字はUTF-8のバイト列へ分解され、1文字で2〜3トークンを消費します。文章全体で見れば、英語なら1トークンで済む語が日本語では数トークンに膨らむ、という差の積み上がりになります。

語彙サイズの拡大は、この差を縮める方向に効きました。openai/tiktoken のエンコーディング定義を2026年8月3日時点で確認すると、GPT-3世代のp50k_baseは語彙が5万強、GPT-4世代のcl100k_baseは終端トークンのIDが100257で約10万規模、その次の世代のo200k_baseは終端トークンが199999で約20万規模へ広がっています。枠が倍になった分だけ日本語を含むCJK圏の文字へ割ける語彙が増え、同じ文章の消費量は下がりました。ただし英語との差が消えたわけではありません。

設計への反映は単純です。トークン消費はトークナイザーごとに違うため、文字数に係数を掛ける社内標準の換算式は当てになりません。代表的な文書を3〜5本選んで実際にエンコードし、その実測値で入力上限とコストを見積もってください。上限そのものの数え方はコンテキストウィンドウのトークン上限と溢れ対策で詳しく扱っています。

形態素解析とサブワード分割の役割の違いと実務で併用が要る場面

日本語の文を切る技術として先にあったのが形態素解析です。混同されやすいのですが、両者は目的が違います。形態素解析は辞書と文法規則を使って言語学的に意味のある単位へ切る処理で、品詞や原形といった情報を伴う。対してサブワード分割は、言語知識を持たず統計だけで頻出する部分文字列を切り出します。「トークナイザー」を「トーク」「ナイ」「ザー」と切っても、統計的に効率が良ければそれが正解として採用される世界です。

LLMへ文章を投げる際に、事前の形態素解析は不要です。トークナイザーが生文をそのまま受け取ります。ただし日本語特化モデルを新規に学習する場面では、事前分割器としてMeCabなどを挟み、語彙の切れ目を語境界に揃える構成を採ることがある。もう一つ現役なのが検索側で、BM25や転置索引を組む場合は形態素解析が必要な構成です。ベクトル検索とキーワード検索を併用するハイブリッド構成では、サブワード分割と形態素解析が同じシステム内に同居する形になります。基礎は形態素解析の仕組みとツールの選び方、実装はMeCabの定義と概要、分野全体の位置づけは自然言語処理の仕組みと導入判断にまとめています。

実装で踏みやすい箇所|特殊トークン・版差・語彙拡張の採否基準

トークナイザー起因の障害は、静かに起きて後段まで気づかれない性質があります。頻出する3つを挙げます。

特殊トークンとチャットテンプレートが生む数え漏れを防ぐ確認手順

トークン数の見積もりがずれる原因の筆頭が、本文だけを数えていることです。実際のリクエストには、文頭・文末を示す特殊トークン、役割を示すマーカー、ツール定義などが乗ります。チャット形式のモデルでは、メッセージ配列にテンプレートを適用した結果が実際の入力になるため、本文の文字列を単独でエンコードした値とは一致しません。実測するなら、テンプレートを適用したうえで特殊トークンを含めて数えるのが正しい手順です。

もう一点、ユーザー入力を扱う実装では特殊トークンの解釈にも注意が要ります。ユーザーが入力した文字列の中に特殊トークンと同じ綴りが含まれていた場合、それを制御用のトークンとして解釈させると、役割の境界を書き換えられる余地が生まれます。外部から受け取る文字列は、特殊トークンとして解釈しない設定でエンコードしてください。

ライブラリの版と実装差で分割結果がずれる場合の実務上の確認手順

2026年8月3日にPyPIで確認した公開版は、tiktoken が0.13系、tokenizers が0.23系、sentencepiece が0.2系、transformers が5.14系でした。AutoTokenizerはこれらをラップして呼び分ける入口にあたります。

注意したいのは、同じモデルでもRust実装の高速版とPython実装の低速版とで、細かな分割結果が一致しない場合があることです。学習時と推論時で別の側を使うと、評価では出なかった劣化が本番で出る。切り分けの順序は、まずtokenizer.jsonのリビジョンが学習時と同一かを確認し、次に高速版と低速版で同じ入力をエンコードして差分を取り、最後に正規化設定を比較する流れが早いです。分割結果のずれは例外にならず数値の列として流れていくため、意識して比べない限り表面化しません。

語彙拡張を採用してよい条件と見送るべき条件の実務上の判断基準

「日本語のトークン効率を上げたいので語彙を足す」という相談は多く来ます。ここは判断を言い切ります。継続事前学習の計算予算が確保できていないなら、語彙拡張は見送ってください。

理由は構造にあります。語彙を追加するとは、埋め込み行列に新しい行を足すこと。追加された行は初期化されただけの状態で、意味のあるベクトルを持ちません。既存の重みは古い語彙での分割を前提に学習されているため、拡張後は入力の分割パターン自体が変わり、学習済みの対応関係がずれます。これを埋め戻すには、数十億トークン規模の継続事前学習が要る。指示チューニングだけで済ませようとすると、日本語のトークン数は減ったのに応答品質が落ちる状態になります。

採用してよいのは、次の3条件がそろう場合に限られます。自社ドメイン固有の語彙がテキスト全体の相当な割合を占めていること。継続事前学習を回す計算資源と時間が確保されていること。そして拡張前後で既存タスクの性能が落ちていないことを確かめる評価セットが手元にあること。逆に、コスト削減が主目的である、追加学習はLoRAだけで済ませたい、評価セットがない、のいずれかに当てはまるなら見送りが正解です。その場合は語彙に触らず、プロンプトの冗長な定型文を削るほうが、労力あたりの削減効果が大きくなります。

導入前に決める項目|トークン設計の初期条件と外注時の確認事項

ここまでの判断を、着手前に固定できる形へ落とします。要件定義に書ける粒度まで具体化しておくと、後戻りが減ります。

着手前に固定する4項目と要件定義へ落とすときの記述粒度の基準

先に決めておくのは次の4点です。

  1. 使うモデルとトークナイザーの組(配布元リポジトリのリビジョンまで固定する)
  2. トークン数の測り方(チャットテンプレート適用後・特殊トークン込みで数える)
  3. 日本語の実消費量(代表文書3〜5本を実際にエンコードした値。文字数換算は使わない)
  4. 語彙拡張の可否(実施する場合は継続事前学習の予算と非劣化評価の方法まで)

優先度が高いのは1と2です。この2つが曖昧なまま進むと、負荷試験やコスト試算の段階で前提が崩れ、設計をやり直すことになります。3は運用開始後の計測で精度を上げられる領域。4は初期は「実施しない」と決め切ってしまって構いません。

日本語LLMの実装を外注するとき見積書で確認する技術要件一覧

日本語を扱うLLM実装を外部に委託する場合、見積書で確認したい項目は絞り込めます。想定する入力トークン量と、その根拠になった実測サンプルが示されているか。使用するモデルとトークナイザーのリビジョンが固定されているか。語彙拡張を提案されている場合、継続事前学習の工数と非劣化評価が見積もりに含まれているか。トークン消費量の見積もり方法が受け入れ条件として書かれているか。この4点が抜けた見積もりは、日本語でコストが想定を超えたときの責任範囲が曖昧になります。生成AI導入支援では、こうしたトークン設計と検証条件を含めて要件定義から実装まで請け負っています。モデル選定そのものの考え方はLLMの仕組みと企業導入の判断基準に整理しました。

よくある質問

トークナイザーの検討で実際に問い合わせが多い論点を5つ挙げます。

トークナイザーとトークンの違いは何ですか?

トークンはテキストを分割した後の1つ1つの単位で、トークナイザーはその分割を実行する部品を指します。材料と道具の関係にあたります。混同しやすいのがトークンIDとの区別で、こちらはトークンに割り振られた整数の識別子。モデルが実際に受け取るのはこのID列で、文字列そのものではありません。

トークナイザーは自分で学習させる必要がありますか?

既存のLLMを使う実装では必要ありません。モデルの配布元が公開しているトークナイザーをそのまま読み込みます。自前で学習させる場面は、モデルを事前学習から作る場合と、既存モデルに継続事前学習を掛けながら語彙を組み替える場合に限られる。既存モデルを使いながらトークナイザーだけを差し替える運用は、語彙IDと重みの対応が崩れるため成立しません。

日本語は英語の何倍トークンを消費しますか?

倍率はトークナイザーの世代と文章の内容で変わるため、固定値として扱わないでください。語彙が約10万規模の世代と約20万規模の世代とでは、同じ日本語文でも消費量に差が出ます。専門用語や固有名詞が多い技術文書ほど語彙から漏れてバイト分割へ落ちるため、消費は増えがち。代表的な文書を実際にエンコードして測るのが唯一確実な方法です。

形態素解析とトークナイザーは同じものですか?

別物です。形態素解析は辞書と文法規則で言語学的な単位へ切り、品詞などの情報を返します。サブワード分割は言語知識を持たず、統計的に頻出する部分文字列を切り出すだけで、切れ目が語の意味と一致するとは限りません。LLMへの入力に形態素解析は不要ですが、キーワード検索の索引を作る用途では今も必要になります。

モデルを変えたらトークン数の見積もりはやり直しですか?

やり直しになります。トークナイザーが変わると同じ文章でもトークン数が変わるため、入力上限の設計もコスト試算も前提が動きます。特に語彙サイズが異なる世代をまたぐ場合、日本語では差が大きく出る。モデル比較の段階で、候補ごとに代表文書のトークン数を測って並べておくと、単価だけでは見えない実効コストの差が見えます。

関連記事

資料請求

RELATED POSTS 関連記事