Skip to content
Published on

推論強度はモデル選択ではなくリクエスト単位のデプロイパラメータです

シェア
Authors

同じモデルなのにスコアが三つ載っています

新しいモデルが出たのでベンチマークの結果を確認しに行きます。ところがスコアがひとつではありません。三つです。どの数字をSlackに上げればよいのでしょうか。

この状況はもはや例外ではなく既定値に近いです。推論強度を調節できるモデルが増えるにつれ、モデルひとつが点ひとつではなく曲線ひとつとして発表されるようになりました。そしてこの変化は発表形式の変化ではなく、デプロイ設計の変化です。

以前はモデルを選ぶことが決定の終わりでした。どのモデルを使うか決めれば、性能とコストが一緒に決まりました。今はモデルを選んだあとにも決定がひとつ残っており、その決定が性能とコストを両方向へ大きく揺らします。これを設定ファイルに定数として埋め込むと、その揺れを全部諦めることになります。

ARCの結果ページが実際に教えてくれること

ARC PrizeのDeepSeek V4 Flash 0731の結果ページを見てみましょう。2026年7月31日に公開されたモデルで、推論強度の三段階がそれぞれ測定されています。

推論強度ARC-AGI-1ARC-AGI-2
Max89.0%61.4%
High87.0%56.0%
Low84.0%46.0%

コストは最大強度を基準にしてのみ表記されています。ARC-AGI-1の準公開評価で1課題あたり0.02ドル、ARC-AGI-2で1課題あたり0.04ドルです。

強度が買ってくれるものは課題の難度によって三倍違う

この表からすぐ計算できることがひとつあります。強度を最低から最大へ上げたときの利得です。

ARC-AGI-1では84.0から89.0へ5.0ポイント上がります。ARC-AGI-2では46.0から61.4へ15.4ポイント上がります。同じダイヤルを同じだけ回したのに、難しいほうで三倍以上稼ぎました。

向きを逆にして読むともっと実用的です。易しい課題で最大強度を使うのはおおむね無駄です。 ARC-AGI-1で最低強度は最大強度の94パーセント水準をすでに出しています。逆に難しい課題を最低強度で回すのは、性能を大きく捨てる選択です。

だから「このモデルをどの強度で使うか」という問いは、そもそも形が間違っています。強度はモデルの属性ではなく、課題の属性に合わせて決める値です。

リクエスト単位で決めるということの意味

実務ではこの結論は設定ファイルの一行ではなくルーティングのロジックになります。入ってきたリクエストごとに難度を推定し強度を選びます。

難度の推定は完璧である必要はありません。ほとんどのサービスではとても粗い信号でも十分です。入力の長さ、要求された手順の数、過去の同じ種類での失敗率、利用者が明示した緊急度といったものです。

ただしこの推定を一度で当てようとすると、すぐ限界にぶつかります。難度を予測する分類器を付けた瞬間その分類器自体が維持の対象になり、分布が変わるたびに再学習しなければなりません。より頑丈な方法は、推定せずに間違ったときに上げることです。予測の代わりに観測を使うほうが、ほとんどいつでも長持ちします。

はしごは検証者があるときだけ成り立ちます

"""段階上昇のはしご: 安く先に試し、間違いが確認されたら上げる。"""
from typing import Callable, Sequence

LADDER = ("low", "high", "max")


def solve_with_escalation(
    task,
    run: Callable[[object, str], object],       # (task, effort) -> answer
    verify: Callable[[object, object], bool],   # (task, answer) -> 通過したか
    ladder: Sequence[str] = LADDER,
):
    """検証者が通すまで強度を上げる。使った強度も一緒に返す。"""
    attempts = []
    for effort in ladder:
        answer = run(task, effort)
        ok = verify(task, answer)
        attempts.append((effort, ok))
        if ok:
            return answer, effort, attempts
    return answer, ladder[-1], attempts   # 最後まで失敗したら最終試行を返す


def expected_cost(p_pass_by_effort: dict, unit_cost: dict, ladder=LADDER) -> float:
    """はしごの期待コスト。低い段階の通過率が高いほど平均が下がる。"""
    total, reach = 0.0, 1.0
    for effort in ladder:
        total += reach * unit_cost[effort]
        reach *= 1 - p_pass_by_effort[effort]
    return total


p = {"low": 0.80, "high": 0.60, "max": 0.50}     # 各段階に到達したときの通過率
cost = {"low": 0.004, "high": 0.010, "max": 0.020}
print(round(expected_cost(p, cost), 5))          # 最大強度だけを使う場合と比べてみること

この構造の前提はverifyです。検証が不可能ならはしごは成り立たず、残る選択肢は最初から高い強度で回すことだけです。だから強度の最適化をしたいなら、まず問うべき質問は「強度をどう選ぶか」ではなく、間違っていることを安く知る方法があるかです。

もうひとつ注意すべき点は遅延時間です。はしごは平均コストを下げますが最悪の場合の遅延を増やします。三段階を全部踏んだリクエストは、一度に最大強度で回したリクエストより遅く終わります。だから利用者が待っている同期経路でははしごを二段階に減らすか、低い段階を先にストリーミングで見せて上位の結果と差し替える、といった設計が必要です。バッチ処理ならこの悩みは要りません。

検証者を作れないときの代替信号

完全な検証者が無くても、部分的な信号はたいてい作れます。

コード生成ならコンパイルとテスト実行がそのまま検証者です。構造化された出力ならスキーマ検証と参照整合性の検査がかなりの部分を捕まえます。検索に基づく回答なら、引用された文が原文に実際に存在するかを文字列照合で確認できます。

こういうものすらない自由記述の課題なら、信号を結果ではなく過程に探します。同じ入力を低い強度で二度回して答えが互いに大きく違えば、そのリクエストはこのモデルにとって難しいリクエストである可能性が高いです。二度回すコストが一段階上げるコストより安い区間では、この方法が実用的です。

ここで答えが違うという判定をまたモデルに任せると、コスト面の利点が消えます。文の埋め込みのコサイン距離や、答えから抽出した主要な数値と固有名詞の集合比較のように、安上がりな照合で十分な場合が多いです。検証者は正確である必要はなく、安くて片側にだけ間違えればよいのです。見逃す失敗があっても構いませんが、正しい答えを間違いと判定することはまれでなければ、はしごが無駄なく回りません。

このページで確認できないこと

正直に押さえておくべき部分があります。前の表には強度別のスコアが三行ありますが、コストは最大強度基準の一行だけです。低い強度の1課題あたりのコストは、このページからは確認できません。

だからコストあたりの限界精度を、このデータだけで完全に計算することはできません。上のコードの単価は構造を見せるための例に過ぎず、実際の値は各自が自分のトラフィックで測らなければなりません。そしてこれはこのページの欠陥というより、今の業界全体の発表慣行です。強度別のスコアは増えたのに、強度別のコストはまだ一緒に出てきません。

測定は難しくありません。自分の評価セット100件を三つの強度でそれぞれ回し、精度と実際に課金されたトークンを一緒に記録すれば曲線が出ます。この実験は半日で終わり、以後すべての強度決定の根拠になります。

もうひとつ留意すべきなのは、ベンチマークの難度分布と自分たちのトラフィックの難度分布が違うという点です。ARCの課題は意図的に難しく設計された問題の集まりであり、実際のサービスのトラフィックはたいてい易しいリクエストが圧倒的に多いロングテール分布です。だから上の表から得るべき教訓は「うちも最大強度を使うべきだ」ではなく、難度の区間ごとにダイヤルの値打ちが違うという事実そのものです。

デプロイパラメータとして扱うために残すべきもの

最後は記録です。強度をリクエスト単位で決め始めると、強度をログに残さない瞬間、すべての指標が解釈不能になります。

最低限この四つを応答と一緒に保存します。実際に使われた強度、はしごで試行した回数、各試行の検証結果、そして総消費トークンです。ここにリクエストをどの難度区間に分類したかまで残せば、あとでルーティング規則をデータで調整できます。これがあれば、のちに「先週比で精度が上がったがコストも上がった」という状況で原因を即座に切り分けられます。無ければモデルのせいなのかルーティングのせいなのかトラフィック構成の変化のせいなのか、永遠に分かりません。

最初の問いに戻ると、Slackに上げるべき数字は三つのうちのひとつではありません。三つ全部を上げて、自分たちの課題がどちら寄りかを一緒に書くのが正しいです。

参考資料

  • DeepSeek V4 Flash 0731 — ARC Prize結果ページ — 強度別スコア三行、最大強度基準の1課題あたりコスト、モデルの公開日がこのページの内容です。本文の5.0ポイントと15.4ポイントは、その表から引き算で出した値です。
  • ARC Prize — 準公開評価と公開評価の区別、評価方式についての説明があります。
  • はしごのコードの通過率と単価は構造の説明のための例の数字であり、ARCのページから取ってきた値ではありません。
  • このブログの関連記事: 100倍安いという主張は課題を狭めたときにだけ真です