このページの目次

トークンとサンプリング

モデルは文字を読み取るのではなく、トークン単位でデコードします。入力側のサブワード分割がコストの基準を決め、出力側のサンプリング戦略が創造性と決定論を決定します——そして2026年、Claudeとローカルモデルの間でこの両端は分岐しています。

概要

モデルは文字を読み取らず、直接文章を出力もしません。⁠入力側では、テキストは トークン に分割されます。⁠出力側では、モデルは一度に「次のトークンが語彙全体で持つ確率分布」のみを生成し、⁠サンプリング戦略 によって1つが選択され、入力に戻されて自己回帰的に1つずつ生成されます。この両端は普段目に見えませんが、実際の開発で頻繁に直面する3つの事象を決定します:⁠コストが正確に計算できるか⁠(課金単位はトークン)、「創造性」を適切に調整できるか⁠(サンプリング戦略)、そして同じプロンプトでも結果が2回で異なる理由⁠(非決定性)。

さらに重要なのは、この両端に関する「常識」が2026年に分岐したことです。⁠オープンソース/ローカルモデル は依然として temperature/top_p/top_k を使ってサンプリングを調整します(ローカルで動作する Qwen など);一方、Claude のマネージド API は Opus 4.7 からこれらのパラメータを完全に削除 しました——これらのパラメータを送信すると即座に 400 エラーになります。同じ概念でも2つの世界があり、この記事では両端のメカニズムとこの分岐を徹底的に解説します。

入力側:テキストがトークンに変換される仕組み

サブワード分割と BPE

現代の LLM は、文字単位でも単語単位でも分割せず、⁠サブワード で分割します。最も一般的なアルゴリズムは BPE(Byte Pair Encoding) です:トレーニング時には文字から始まり、「最も頻繁に出現する隣接するトークンのペア」を新しいトークンとしてマージし、語彙サイズが設定サイズ(通常は数万〜十几万)に達するまでこれを繰り返します。その結果、高頻度の単語は1つのトークンになり、低頻度の単語は複数のサブワードに分解されます。

トレーニング マージルール(例) "t"+"h"→"th" "th"+"e"→"the" "ing" ... 推論 貪欲な分割 "tokenization" token ization → 2トークン "internationalization" intern ational ization → 3トークン 高頻度の部分文字列(例:"the")は単語全体として直接一致します。低頻度/珍しい単語は、学習したルールに基づいて複数のサブワードに段階的に分解されます。

現代の実装では、⁠バイトレベル BPE がよく使われます:これは Unicode 文字ではなくバイト に対して BPE を実行します。利点はOOV(未登録語)が存在しないことです——どんな入力(珍しい文字、絵文字、バイナリ列)でもバイトでフォールバックできるため、絶対に分割できないことがありません。代償として、ASCII 以外(中国語、日本語など)の1文字は多くの場合、複数のバイトおよび複数のトークンを占めます。

直感に反するが重要なポイント

  • トークン ≠ 単語 ≠ 文字。 英語では約 1トークン ≈ 4文字です。⁠中国語では1文字が通常 1–2+ トークンを占め、コード内の句読点やインデントもトークンを消費します。 文字数で長さを推定すると、体系的に低く見積もってしまいます。
  • チャットテンプレートもトークンを消費します。 複数ターン対話では、role マーカー、メッセージ区切り文字、ツール定義のスキーマなどがすべて入力トークンに含まれます——本文だけが課金対象ではありません。
  • モデル間のトークンは互換性がなく、バージョンによって変動します。 Claude のトークナイザー ≠ OpenAI のトークナイザーです。Claude の見積もりに tiktoken を使わないでください⁠(15–20% 少なく見積もり、コードや中国語ではさらに顕著です)。同じメーカーでも、モデル世代が変わると変化します:Opus 4.7 のトークナイザーは、同じテキストを前世代の 1.0–1.35 倍のトークン数に分割する可能性があります。⁠モデルを変更する際は基準を再設定する必要があり⁠、古い倍率を適用しないでください。
  • 正確に計測するには API を呼び出し、サードパーティの近似器を使わないでください:
# 単一セグメントのカウント
n = client.messages.count_tokens(
    model="claude-opus-4-8",
    messages=[{"role": "user", "content": text}],
).input_tokens

# コストの見積もり(公式価格に基づく、変動あり): input_tokens × 単価
# 2つのバージョンの差分を比較: それぞれカウントして引き算——エンドポイントはステートレスなので、自身で差分を取る

count_tokens はステートレスです。「いくつのトークンが変更されたか」を計算するには、それぞれをカウントして引き算します。

出力側:トークン単位でのサンプリング

モデルが各ステップで出力するのは単語ではなく、⁠語彙全体に対するスコアベクトル(logits) です。これらは softmax によって確率分布に変換され、戦略に従ってサンプリングされ、入力に戻されて再帰的に処理されます——これが自己回帰(autoregressive)です。

flowchart LR
    T["テキスト"] --> TK["トークナイザー → トークン"]
    TK --> M["モデル (Transformer)"]
    M --> L["logits<br/>(語彙内の各トークンに対するスコア)"]
    L --> SM["softmax(logits / T)<br/>→ 確率分布"]
    SM --> S["サンプリング戦略<br/>top_p / top_k / greedy"]
    S --> N["次のトークン"]
    N -->|入力に戻し、自己回帰| M

サンプリングのノブ(サポートされているモデルの場合)

戦略メカニズム効果
greedy (argmax)各ステップで確率が最も高いトークンを取得最も決定論的ですが、⁠繰り返しや劣化に陥りやすい
temperature Tsoftmax 前に logits を T で除算T>1 は分布を平坦化→よりランダム;T<1 は尖らせる→より集中;T=0 は greedy に退化
top_p (nucleus)「累積確率が p に達する最小のトークンセット」のみでサンプリング動的に裾を切り捨て、分布の形状に応じて適応
top_k確率が最も高い k 個のトークンのみでサンプリング固定された切り捨て
repetition / presence penalty既に出現したトークンの重みを低下繰り返しを抑制
stop sequence指定された文字列に一致すると停止出力の境界を制御

実務では temperature + top_p の組み合わせ が最も一般的です:温度がランダム性を制御し、nucleus が荒唐無稽な裾を切り落とします。top_k は比較的粗いです。

なぜチャット LLM はビームサーチを使わないのか

古典的な機械翻訳では ビームサーチ⁠(複数の候補パスを同時に維持し、全体として最適なものを選択)が使われます。チャット/オープン生成ではほぼ使われません⁠:これは高確率だが退屈で反復的なテキストを生成する傾向があり(「ニューラルテキストの劣化」)、多様性と自然度を犠牲にします。サンプリング(top_p/温度)は、むしろ人間らしく、情報量豊富なテキストを生成します——これが2020年の nucleus sampling 論文の核心的な結論です。

なぜ T=0 でもバイト単位の再現が保証されないのか

多くの人が「温度 0 = 再現可能」と思っています。⁠できません。 その理由はサンプリングではなく、ハードウェアとスケジューリングにあります:

  • 浮動小数点の非結合性⁠: GPU 上の大量の並列加算における累算順序は固定されておらず、浮動小数点では (a+b)+c ≠ a+(b+c) が成立し、極微小な差異が argmax の臨界点で選択を反転させることがあります。
  • バッチ構成⁠: リクエストがどのバッチに組み込まれるか、カーネルのスケジューリング方法が数値に影響します。
  • MoE ルーティング⁠: MoE モデル のエキスパート選択は数値により敏感です。

「決定論的」であることは、特定のサンプリングパラメータが保証するものではなく、エンジニアリング上の目標(固定プロンプト、低ランダム性、微小なドリフトを許容)です。

分岐:Claude はサンプリングを削除し、ローカルモデルは依然として使用している

Claude Opus 4.7 / 4.8 / Fable 5 世代に至り、temperaturetop_ptop_k削除されました——送信すると即座に 400 エラーになります。これは退化ではなく、設計思想の変化です:

  • 強力な推論モデルにおいて、サンプリング温度を使って「創造性/決定論」を調整しても、そのリターンは限定的で制御不可能です。
  • Anthropic は代わりにより高レベルな2つのツールを提供しています:
    • プロンプティング⁠——決定論を望む場合は指示を固定し、発散を望む場合はプロンプト内で多様性を明確に要求します(例:フロントエンド設計シナリオでモデルに「まず4つの異なる方向性を提示させてから実装する」よう指示、詳細は移行ドキュメントの design セクションを参照);
    • effort(output_config.effort)——どの程度深く考え、どのくらいのトークンを消費するかを制御します(推論と思考 を参照)。

移行のポイント:旧コードの temperature=0.7 は新モデルで削除し、意図をプロンプト + effort に変換します——temperature=0(決定論を求める)→ effort:"low" + 指示の固定;temperature=高(発散を求める)→ プロンプト内で「複数の異なる方向性を提示する」と明確に記述。この移行レシピは プロンプトエンジニアリングと構造化出力 で展開されます。

しかし他方で、サンプリングは依然として存続しています。 ローカル/オープンソースモデル(llama.cpp、vLLM)はこれらのパラメータを依然として受け付けます——ローカル LLM デプロイ でも設定されています。さらに、モデルカードには推奨値が記載されています:Qwen-AgentWorld の公式推奨は temperature 0.6 / top_p 0.95 / top_k 20 です。つまり、「サンプリングの削除」は Claude マネージド API の思想であり、業界全体の標準ではありません——どの世界にいるかによって、どのルールを使うかを決めます。

ベストプラクティス

  • 正確に計測するには count_tokens を呼び出し、サードパーティの近似器を使わないでください。 tiktoken で Claude を見積もると 15–20% 少なく見積もり、中国語/コードではさらに顕著です;チャットテンプレートやツールスキーマもトークンを消費します。
  • モデルを変更する際はトークンの基準を再設定してください。 トークナイザーはバージョンによって変動するため、古い倍率を適用しないでください;2つのバージョンの差異を比較するには、それぞれカウントして引き算します。
  • どの世界にいるかによって、どのルールを使うかを決めます。 ローカル/オープンソースモデルでは temperature/top_p/top_k を通常通り調整(モデルカードの推奨値に従う);Claude マネージド API はサンプリングを削除しており、プロンプト + effort を使用します。
  • ローカルモデルはモデルカードの推奨サンプリング値を設定してください。 例えば AgentWorld の推奨値は 0.6 / 0.95 / 20 です。デフォルト値で発散度を賭けないでください。
  • T=0 でバイト単位の再現を期待しないでください。 浮動小数点の累算、バッチ処理、MoE ルーティングが変動します;厳密な再現を必要とする場合は結果をキャッシュしてください。

トレードオフと失敗パターン

  • 文字数でトークンを推定⁠: 中国語/コードで深刻な過小評価 → count_tokens を使用し、チャットテンプレート/ツールスキーマを含める。
  • モデル間でトークン数や古い温度を適用⁠: トークナイザーとサンプリングの両方が変化する → モデル変更時は基準を再設定し、移行時にサンプリングパラメータを削除。
  • T=0 での再現を期待⁠: バイト単位の一致は不可能 → 固定プロンプト + 低 effort で微小なドリフトを許容;厳密な再現を必要とする場合は結果をキャッシュ。
  • ローカルモデルで推奨サンプリング値を設定しない⁠: デフォルト温度では発散しすぎたり、鈍感すぎたりする可能性がある → モデルカード(例:AgentWorld の 0.6/0.95/20)に従う。

参考

  • Anthropic 公式ドキュメント⁠: トークンカウント、Models API、移行ガイド(サンプリングパラメータの削除)(platform.claude.com)
  • 論文⁠: 「Neural Machine Translation of Rare Words with Subword Units」(BPE、Sennrich 2016)、「The Curious Case of Neural Text Degeneration」(nucleus sampling、Holtzman 2020)
  • モデルカード⁠: Qwen-AgentWorld-35B-A3B(推奨サンプリング値)

Keywords: tokenization, subword, BPE, byte-level BPE, vocabulary, OOV, chat template, token ≠ word, count_tokens, tiktoken, tokenizer drift, logits, softmax, autoregressive, greedy, temperature, top_p, nucleus sampling, top_k, repetition penalty, stop sequence, beam search, text degeneration, 決定論, floating-point non-associativity, サンプリングパラメータの削除, effort