Tokenizer(トークナイザー)とは?LLMの前処理を担う仕組み・BPE/WordPiece/SentencePieceの違いを徹底解説

Tokenizerとは|IT用語辞典プラス

Tokenizer(トークナイザー)とは

Tokenizer(トークナイザー)とは、自然言語処理(NLP)において生のテキストを「トークン」と呼ばれる小さな単位に分割し、数値ID列に変換するコンポーネントである。大規模言語モデル(LLM)はテキストを直接扱えず、トークンID列を入力として受け取って次のトークンIDを予測する仕組みなので、Tokenizerはモデルとテキストを橋渡しする欠かせない前処理を担う。

身近なたとえで言えば、Tokenizerは「言語の翻訳辞書」だ。人間が読む文章を、AIが読める数列(語彙ID)に変換し、AIの出力をまた人間が読める文章に戻す。Claude・GPT・Gemini・Llama などすべてのLLMはそれぞれ専用のTokenizerを持っており、同じ文章でもモデルごとに異なるトークン数になる。これがAPI料金(トークン単位課金)の差にも直結する。

Tokenizerの読み方

トークナイザー

トークナイザ

トークン化器

Tokenizerの仕組み

現代のLLMで使われるTokenizerは、ほぼすべてサブワードトークナイザーと呼ばれるタイプである。単語より細かく文字より粗い「サブワード」単位で分割することで、未知語に強く、語彙サイズを抑えながら多言語にも対応できる。代表的なアルゴリズムに BPE(Byte Pair Encoding)WordPieceSentencePiece の3種類がある。

3大サブワードアルゴリズム

主要トークナイザーアルゴリズム

BPE
頻出ペアを反復マージ。Llama・GPT・Qwen系
WordPiece
尤度ベースの選択。BERT・DistilBERT
SentencePiece
言語非依存・空白も学習。T5・XLM-R・mBART

処理フロー

Tokenizer内部の典型的な処理は以下の流れになる: ① 正規化(NFC・小文字化など)→ ② 事前分割(pre-tokenization、空白や句読点で大まかに切る)→ ③ サブワードアルゴリズムを適用してトークン列に変換 → ④ 語彙テーブルでID変換 → ⑤ 特殊トークン挿入(<s><eos>等)。重要なポイントは、Tokenizer はモデルと必ず一対のペアとして保存・配布されるという点だ。学習時と推論時で別のTokenizerを使うと出力が破綻する。

Tokenizerの使い方・実例

基本的な使い方(Quick Start)

Hugging FaceのtransformersライブラリでLLM用Tokenizerを使うのが最も簡単だ。

from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B")
text = "今日は良い天気ですね"

ids = tok.encode(text)
print(ids)
# [128000, 100129, 17297, 30559, 23039, 16175, 38641]

print(tok.decode(ids))
# 今日は良い天気ですね

encode でテキスト→ID列、decode でID列→テキストに戻す。同じ文章でもモデルが違えばトークン数は変わる。例えば日本語1文字あたり、Llama 3系で約1.5トークン、GPT-4系で約1〜1.5トークン、古いGPT-3で約2〜3トークンが目安だ。

よくある実装パターン

パターンA: トークン数の事前見積り

from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("gpt2")
prompt = "ここにユーザー入力が入る"
n_tokens = len(tok.encode(prompt))
if n_tokens > 4000:
    raise ValueError("コンテキスト超過、要約してから渡す")

向いているケース: API呼び出し前のコスト見積り・コンテキストウィンドウ事前検査

避けるべきケース: 異なるモデルへの送信時にも同じTokenizerで計算(モデルごとに必ず正規のTokenizerを使う)

パターンB: バッチ処理での効率化

texts = ["文1", "文2", "文3"]
batch = tok(texts, padding=True, truncation=True, max_length=512, return_tensors="pt")
# batch["input_ids"], batch["attention_mask"] が得られる

向いているケース: 推論サーバーで複数リクエストをまとめて処理

避けるべきケース: 文長が極端にバラつく場合(無駄なパディングが増える → ソート+bucketingを併用)

アンチパターン: モデルとTokenizerの取り違え

# ⛔ 絶対NG
tok = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B")
ids = tok.encode("hello")
out = model.generate(ids)  # 語彙IDが噛み合わず破綻

TokenizerとModelは必ずペアで使う。実務では AutoTokenizer.from_pretrained(model_name)AutoModel.from_pretrained(model_name) を同じ model_name で呼ぶのが鉄則。覚えておきたいポイントは、ファインチューニングで語彙を拡張した場合、Tokenizer側にもトークン追加が必要な点だ。

Tokenizerのメリット・デメリット

メリット: ① サブワード分割により語彙サイズを抑えつつ未知語に強い。② モデル本体より軽量で起動が速く、文字列処理だけならCPUで十分。③ 多言語を1つの語彙テーブルで扱える(特にSentencePiece)。

デメリット: ① モデルごとに別Tokenizerが必要で、相互運用が難しい。② 日本語・中国語・韓国語など空白で区切らない言語では分割効率がラテン文字より悪く、同じ意味でもトークン数が増えがち。③ 数値や絵文字、コードなど特殊な文字列で過剰分割が起きやすい。実務では、API課金とコンテキストウィンドウの両面でトークン数を意識することが重要だ。

BPEとWordPiece・SentencePieceの違い

3大サブワードアルゴリズムは、語彙構築の方針に違いがある。下記の比較表で違いを整理する。

観点 BPE WordPiece SentencePiece
マージ基準 最頻ペアを反復結合 尤度向上が最大のペアを選択 unigram言語モデルまたはBPE
事前分割 空白・句読点で必要 空白・句読点で必要 不要(空白も学習対象)
代表モデル GPT-2/3/4、Llama、Mistral、Qwen2 BERT、DistilBERT、ELECTRA T5、XLM-R、mBART、ALBERT
多言語適性 中(バイトレベルなら高) 高(言語非依存)
学習速度 高速 中速 高速(C++実装あり)

つまり「BPEは最頻パターン重視、WordPieceは尤度重視、SentencePieceは言語非依存」と覚えれば混乱しない。最近はBPEとSentencePieceが主流で、BERTのWordPieceは2018年当時の選択だった経緯がある。

Tokenizerに関するよくある誤解

誤解1: 「1単語=1トークンである」

なぜそう誤解されるのか: 「Tokenize」という言葉が「単語に分ける」という意味で使われることがあり、空白区切りの単語=トークンと混同されやすい。Pythonの str.split() のイメージから来る誤解でもある。

正しい理解: 現代のLLMはサブワード単位で分割するため、長い単語は複数トークンに、短い高頻度単語は1トークンに、絵文字や日本語は1文字で複数トークンになる場合がある。例: 英語「hello」は1トークン、「unforgettable」は3〜4トークン、日本語「あ」も2〜3バイト分のトークンに分割されることがある。

誤解2: 「Tokenizerは全モデルで共通である」

なぜそう誤解されるのか: 「テキスト→ID」という機能だけを見ると、モデルが違っても同じものに見える。背景としてWord2Vecなどの古いモデルでは、辞書ベースの単語Tokenizerが汎用的に使われていた歴史がある。

正しい理解: 各モデルは独自の語彙テーブルを持ち、同じ文字列でも異なるID列に変換される。モデル間でTokenizerを混用するとIDの意味が噛み合わず、出力が破綻する。OpenAI、Anthropic、Meta、Googleなど主要ベンダーはそれぞれ別系統のTokenizerを公開している。

誤解3: 「Tokenizerはモデルの精度に影響しない」

なぜそう誤解されるのか: 「前処理だから機械的な変換にすぎない」という見方が一般的で、モデルの中身に比べると軽視されがち。

正しい理解: Tokenizerの選択はモデル精度に強く影響する。日本語特化モデルでSentencePieceを採用するか、BPEで日本語コーパスを学習させるかで、トークン効率が変わり、同じパラメータ数でも実質的な情報密度に差が出る。

Tokenizerの実務での活用シーン

Tokenizerが最も意識される場面は API課金とコンテキスト管理 である。Anthropic Claude APIやOpenAI APIは入出力のトークン数で課金されるため、長いプロンプトを送る前にトークン数を見積もり、不要箇所を圧縮する処理が必要。RAGシステムでは検索結果を渡す前にトークン数を計算してコンテキストウィンドウに収める。多言語チャットボットでは、SentencePieceベースのモデルを選ぶと日本語のトークン数が抑えられて経済的だ。実務では、トークン数を意識しないと予算が想定の数倍に膨らむケースがあるので注意。

Tokenizerに関するよくある質問(FAQ)

Q1. 1トークンは英語何文字に相当しますか?

英語の場合、平均で1トークン≒約4文字(または0.75単語)と言われます。短い単語(「the」「a」など)は1トークン、長い単語は複数トークンに分かれます。OpenAIのドキュメントでは「100トークン≒75単語」が目安とされています。

Q2. 日本語と英語ではトークン消費はどちらが多いですか?

同じ意味を伝える場合、日本語は英語の約1.5〜2倍のトークン数になることが多いです。Claude 3系・GPT-4系では日本語1文字あたり約1〜1.5トークン、英語1単語あたり約1〜1.3トークンが目安です。多言語特化のSentencePiece系モデルでは日本語効率が改善する場合があります。

Q3. Tokenizerを自作することはできますか?

可能です。Hugging Faceのtokenizersライブラリ、Googleのsentencepieceライブラリで自前学習できます。ただし通常のLLM利用では既存Tokenizerをそのまま使うべきで、自作は新言語対応や特殊ドメイン向けの専門ケースに限られます。

Q4. Tokenizerの語彙サイズはどのくらいですか?

モデルにより異なります。BERT系は約30,000、Llama 3系は約128,000、GPT-4は約100,000、SentencePiece系のT5は約32,000です。語彙サイズが大きいほど多様な言語・分野を効率的に表現できますが、埋め込み層が肥大化するというトレードオフがあります。

まとめ

  • Tokenizerはテキストをサブワード単位に分割し数値ID列に変換するNLPの前処理コンポーネント
  • 主流アルゴリズムはBPE(Llama・GPT系)、WordPiece(BERT系)、SentencePiece(T5・XLM-R系)の3種類
  • 正規化→事前分割→サブワード変換→ID化→特殊トークン挿入の流れで処理し、必ずモデルとペアで保存される
  • 言語によってトークン数が大きく変わり、API課金やコンテキストウィンドウ消費に直結する
  • 実務ではAPI料金見積りとコンテキスト超過防止に必須で、Hugging Face transformersで簡単に扱える

参考文献・出典

📚 参考文献・出典

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA