ChatGPTに質問すると、AIはまず「トークナイゼーション(Tokenization)」という処理を実行します。これは、テキストを「トークン」と呼ばれる小さな単位に分割する作業で、LLM(大規模言語モデル)がテキストを理解する最初のステップです。
トークナイゼーションの仕組みを理解すると、なぜAPIの料金がトークン数で決まるのか、なぜ日本語が英語より高コストなのか、コンテキストウィンドウをどう節約できるかが見えてきます。本記事では、その技術的背景を平易に解説します。
トークナイゼーションとは何か?
トークナイゼーションは、テキストを機械学習モデルが処理できる単位に分割する技術です。例えば、以下のように変換されます。
入力: "人工知能は面白い"
トークン分割(GPT-4の場合):
["人工", "知", "能", "は", "面白", "い"]
トークンID(数値化):
[12345, 67890, 11234, 56789, 99876, 54321]
この数値IDが、ニューラルネットワークに入力されます。なぜ単語そのままではなく、トークンに分割するのでしょうか?
トークナイゼーションの目的
- 語彙サイズの制限: 世界のすべての単語を覚えるのは不可能なので、頻出する「部分文字列」のリストを作る
- 未知語への対応: 新しい単語も、既存トークンの組み合わせで表現できる
- 多言語対応: 異なる言語を同じトークン体系で扱える
トークナイゼーションの歴史
単語分割(Word-level Tokenization)
初期の自然言語処理では、空白やカンマで単語を分割していました。
"I love AI" → ["I", "love", "AI"]
問題点:
– 語彙が膨大(英語だけで数十万語)
– 「run」「running」「runs」を別の単語として扱う
– 未知語(typoや新語)を処理できない
文字分割(Character-level Tokenization)
文字1つ1つをトークンとする方法です。
"AI" → ["A", "I"]
問題点:
– 文字の並びから意味を学習するのが困難
– 長い文章で処理が非効率
サブワード分割(Subword Tokenization)
現代のLLMは、単語と文字の中間的な「部分文字列」をトークンとします。これがBPEやSentencePieceです。
"running" → ["run", "ning"]
"AI技術" → ["AI", "技", "術"]
頻出する部分は1トークン、まれな部分は複数トークンに分割されます。
BPE(Byte Pair Encoding):GPTの標準手法
GPTシリーズは、BPE(バイトペアエンコーディング)というアルゴリズムを採用しています。
BPEの仕組み
- 初期化: すべての文字を個別のトークンとする
- 頻出ペアの統合: 最も頻繁に隣接する文字ペアを1つのトークンに統合
- 繰り返し: 目標の語彙サイズ(例:50,000トークン)に達するまで繰り返す
例:
初期: ["l", "o", "w", "e", "s", "t"]
"e", "s"が頻出 → ["l", "o", "w", "es", "t"]
"es", "t"が頻出 → ["l", "o", "w", "est"]
"l", "o"が頻出 → ["lo", "w", "est"]
この学習済みトークンリストを使って、新しいテキストを分割します。
GPT-4のトークナイゼーション例
OpenAIのTokenizer Toolで実際に試してみましょう。
入力: "ChatGPTは便利です"
トークン分割:
["Chat", "G", "PT", "は", "便利", "です"]
→ 6トークン
英語版:
入力: "ChatGPT is useful"
トークン分割:
["Chat", "GPT", " is", " useful"]
→ 4トークン
日本語が6トークン、英語が4トークンで、日本語の方がトークン数が多いことがわかります。これが料金に影響します。
SentencePiece:言語非依存のトークナイゼーション
Googleが開発したSentencePieceは、空白に依存しない多言語対応のトークナイザーです。LLaMA、PaLM、Claude、Geminiなどで採用されています。
BPEとの違い
- 言語非依存: 日本語・中国語など空白がない言語も統一的に処理
- 生テキスト学習: 前処理なしで学習し、トークン境界を自動決定
- バイトフォールバック: 未知文字をバイト列として扱える
Unigram Language Model
SentencePieceは、BPEだけでなく「Unigram LM」というアルゴリズムも選択できます。これは、確率的に最適な分割を計算する手法です。
"人工知能" → 以下の候補から最尤を選択
- ["人工", "知能"] (確率: 0.6)
- ["人", "工", "知", "能"] (確率: 0.3)
- ["人工知能"] (確率: 0.1)
日本語トークナイゼーションの特殊性
日本語は英語と異なり、以下の特徴があります。
空白がない
英語は空白で単語が分かれますが、日本語は「私は人工知能を学んでいます」のように連続しています。そのため、トークナイザーは文字の連なりからトークン境界を推定する必要があります。
文字種の混在
ひらがな、カタカナ、漢字、アルファベット、数字が混在し、エンコーディングが複雑です。
トークン効率の低さ
GPT-4の場合、日本語は英語の約1.5〜2倍のトークン数になります。
英語: "Artificial Intelligence" → 2トークン
日本語: "人工知能" → 3トークン
これが、日本語でのAPI利用コストが高くなる理由です。
日本語特化トークナイザー
rinna、CyberAgentなどの日本企業が開発する日本語LLMは、日本語に最適化したトークナイザーを使用し、トークン効率を改善しています。
トークン数と料金の関係
OpenAI APIの料金は、トークン数に基づいて課金されます(2026年3月時点)。
GPT-4 Turboの料金例
- 入力: $0.01 / 1,000トークン
- 出力: $0.03 / 1,000トークン
料金計算例
ユーザー: "東京の観光名所を5つ教えてください"(8トークン)
GPT-4: "東京の主要観光名所は以下の通りです...(200トークン)"
入力コスト: 8 × $0.01 / 1,000 = $0.00008
出力コスト: 200 × $0.03 / 1,000 = $0.006
合計: $0.00608 ≈ 0.6円
大量の文書をプロンプトに含めるRAGシステムでは、入力トークン数が数千〜数万に達するため、コスト管理が重要です。
トークン数を減らす実践テクニック
1. 簡潔なプロンプト
不要な丁寧語や冗長な表現を削ります。
悪い例:
お忙しいところ恐縮ですが、もしよろしければ、
以下の文章を要約していただけますでしょうか。
→ 20トークン
良い例:
以下を要約してください。
→ 5トークン
2. チャンク分割
長文を小さな塊に分割し、必要な部分だけをLLMに送ります。
# 10,000トークンの文書を500トークンずつに分割
chunks = split_into_chunks(document, chunk_size=500)
# 関連するチャンクのみを検索で抽出
relevant_chunks = search(query, chunks, top_k=3)
# 1,500トークン程度に圧縮
3. 要約の活用
長い会話履歴を要約し、トークンを節約します。
過去100ターンの会話(10,000トークン)
↓ 要約
要約版(500トークン)→ プロンプトに追加
4. トークン効率の良いモデル選択
Claude 3は、日本語のトークン効率がGPT-4より優れている場合があります。用途に応じて使い分けます。
トークナイゼーションとエンベディング
トークナイゼーションは、エンベディングの前処理として機能します。
- トークナイゼーション: テキスト → トークンID列
- エンベディング: トークンID → 数値ベクトル
- Transformer処理: ベクトル列を処理
例えば「猫」というトークンは、常に同じID(例:12345)に変換され、同じエンベディングベクトルが割り当てられます。このエンベディングが、TransformerのAttention機構で文脈を考慮しながら更新されます。
トークナイゼーションの実装例
OpenAI APIでトークン数を取得
import tiktoken
# GPT-4のトークナイザーを読み込み
encoding = tiktoken.encoding_for_model("gpt-4")
text = "人工知能は未来を変える"
tokens = encoding.encode(text)
print(f"トークン数: {len(tokens)}") # 出力: 7
print(f"トークンID: {tokens}") # [12345, 67890, ...]
print(f"デコード: {encoding.decode(tokens)}") # 元のテキスト
HuggingFaceのトークナイザー
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
text = "Artificial Intelligence"
tokens = tokenizer.tokenize(text)
print(tokens) # ['Art', 'ificial', ' Intelligence']
token_ids = tokenizer.encode(text)
print(token_ids) # [3163, 9542, 9345]
トークナイゼーションの未来
動的トークナイゼーション
文脈に応じてトークン境界を動的に調整する研究が進んでいます。例えば「AI」は1トークンだが、「AI技術」では「AI」「技術」と分割する、といった適応的な処理です。
バイトレベルモデル
トークナイゼーションを完全に廃止し、バイト(8ビット)単位で直接処理するモデルも登場しています。これにより、未知語や多言語の問題が根本的に解決される可能性があります。
マルチモーダルトークン
テキスト・画像・音声を統一的なトークン体系で扱う研究が進んでいます。GPT-4Vは、画像を仮想的な「画像トークン」として扱い、テキストと同時に処理します。
FAQ
Q1. トークンと単語の違いは何ですか?
トークンは、モデルが処理する最小単位で、単語より小さい場合があります。「running」は1単語ですが、トークナイゼーションでは「run」「ning」の2トークンになることがあります。日本語では、1文字が1トークンになることも多いです。
Q2. トークン数の上限はどう決まっていますか?
モデルごとにコンテキストウィンドウ(一度に処理できるトークン数)が決まっています。GPT-4 Turboは128,000トークン、Claude 3 Opusは200,000トークンです。この上限を超えると、古い部分が切り捨てられます。
Q3. トークン数を事前に確認する方法はありますか?
OpenAIのTokenizer Toolや、tiktokenライブラリで確認できます。API呼び出し前に確認し、コストを見積もることが推奨されます。
Q4. 同じテキストでもモデルによってトークン数が変わりますか?
はい。GPT-4、Claude、LLaMAなど、モデルごとに異なるトークナイザーを使用しているため、同じテキストでもトークン数が異なります。料金やコンテキスト制限を比較する際は、各モデルのトークナイザーで確認が必要です。
関連記事
出典
- Sennrich, R., et al. (2016). “Neural Machine Translation of Rare Words with Subword Units”. ACL.
- Kudo, T., & Richardson, J. (2018). “SentencePiece: A simple and language independent approach to subword tokenization”. EMNLP.
- OpenAI (2023). “Tokenizer”. https://platform.openai.com/tokenizer
- Radford, A., et al. (2019). “Language Models are Unsupervised Multitask Learners”. OpenAI Blog.


コメント