一つの設定で生成トークン数1/27・レイテンシ1/4・コスト1/5を実現した
翻訳が遅い理由は「モデル」ではなかった——分解したら、モデルは訳す前に"考えて"いた
1行の翻訳に、モデルは数百トークンを使っていた。訳文ではない。答える前の”考え”だ。
遅さの原因はモデルの性能ではなく、モデルが答える前に考えていたことだった。効いたレバーは「速いモデルに乗り換える」ではなく、「同じモデルに、考えるのをやめさせる」。トークン27倍・レイテンシ4倍が、1倍に戻った。
しかも前提が変わると、選択肢の景色まで変わった。思考をオフにして条件を揃え直すと、中型モデルは軽量モデルより速く、品質も上だった。
注:レイテンシは N=300 の中央値で、思考オン側は実測「約4倍」からの換算。トークン約27倍・コスト約5倍は実測ログの比。
これは「計測の達人」の話ではない
正直に言うと、私は最初から賢く計測していたわけではない。翻訳が遅い原因を、ずっと”モデル”だと思い込んでいた。体感が遅いと浮かぶのは「もっと速いモデルに」「もっと大きいモデルに」ばかりだった。
当時使っていた API は翻訳結果しか返さず、どこで時間を使っているのかが見えなかった。見えないから、犯人を”モデル”だと決めつけるしかなかった。
転機は、翻訳プロバイダを乗り換えたときだった。移った先のレスポンスには、見慣れない使用量の内訳——待ち時間、入力処理、そして生成にかかった時間とトークン数——がそのまま入っていた。「どこで時間を食ってるか、全部書いてあるじゃないか」。これで、“遅い”を一つの塊で眺めるのをやめ、内訳をログに吐いて見る癖がついた。
最初から計測の態度があったわけではない。たまたまログの数字に目が留まって、そこから癖になった。この順序が、あとで効いてくる。
1行の翻訳が、数百トークンを生成していた
内訳を見ると、時間の大半は「生成」に食われていた。ここまでは想定どおりだ。だが、トークン数がおかしかった。
翻訳の出力は、せいぜい十数トークンのはずだ。なのに、モデルは1回の翻訳で数百トークンを生成していた。中身を覗いて、理由が分かった。モデルは訳す前に、“考えて”いた——「この文の主語は…前の文脈は…だから訳は…」という思考の下書き(chain-of-thought)を、答えの前に延々と吐いていたのだ。
賢いモデルほど、答える前に考える。難問ではそれが効く。だが翻訳は——少なくともこの用途では——脊髄反射でいい機械的なタスクだ。そこにモデルが長考していた。1回の翻訳で、モデルが生成したトークンの内訳はこうだった(生成の時間は、ほぼトークン数に比例する)。
| モデルが生成したもの | トークン | 割合 |
|---|---|---|
| 思考(reasoning) | 500+ | 〜96% |
| 実際の翻訳(出力) | 18 | 〜4% |
生成の96%が、翻訳ではなく”考え”だった。結果、思考オフと比べて、
- トークン量 約27倍
- コスト 約5倍
- レイテンシ 約4倍
(LLM APIは処理したトークン数で課金し、生成にかかる時間もトークン数にほぼ比例する。だからこの”考え”のトークンは、訳には一切使われないのに、そのままコストと待ち時間に化ける。なお、生成トークンが27倍でも総レイテンシが4倍・コストが5倍にとどまるのは、レイテンシには通信の往復、コストには入力プロンプト分という”固定費”が乗るからだ——増えるのは生成の分だけで、27倍がそのまま27倍にはならない。)
生成が重かったのは、翻訳が重いからではなかった。モデルが、翻訳ではなく”考えること”に時間を使っていたのだ。
レバーは「モデルを変える」でなく「考えるのをやめさせる」
ここで分かったのは、効くレバーが「速いモデルへ乗り換える」ではない、ということだった。打ち手は——モデルに考えるのをやめさせることだった。
幸い、そのモデルには思考を完全にオフにする設定(reasoning=none)があった。オンにすると500トークンの思考、オフにすると即座に十数トークンの訳だけ。オフにした状態を実測すると、1回の翻訳は中央値253ms・出力18トークン(N=300)に収まった——思考オンのときは、この約4倍かかっていた。トークン27倍が1倍に戻り、レイテンシもコストも一緒に落ちた。モデルは変えていない。同じモデルに、考えるのをやめさせただけだ。
翻訳のような機械的タスクに、モデルの”賢さ”(=考える力)は要らない。むしろ純負債になる。ここから、ひとつの原則が生まれた——リアルタイム用途では、脊髄反射で答えるモデル(reasoning=none)を使う。
(もっとも、モデルによっては思考を完全にはオフにできない。そういうモデルは、賢くてもリアルタイムでは使えない——この話は第3回で。)
「賢い=遅い」が、崩れた
この「reasoning=none」を前提に置くと、モデル選定の景色が変わった。思考オフを揃えて複数のモデルを公平に測り直すと、驚くことに——思考をオフにした中型モデルは、軽量モデルより”速かった”(生成の中央値 253ms < 308ms)。しかも品質は大きく上(合格率 +14.7pt)。
注:N=300・同一プロンプト・人手校正judge。生成の中央値で、通信の往復や待ち行列は含まない。
短い出力では、モデルの大小による生成速度の差は、通信の往復に飲まれて消える。だから思考さえ切れば、「賢い=遅い」は崩れる。より賢いモデルを、速度の代償なしに使える——reasoning=none が、その扉を開けた。(この比較の全体像と、そこから始まるモデル選定の物語は第3回へ。)
後日談 —— ボトルネックは、また動いた
思考をオフにして生成が軽くなったあと、癖になった計測をまた回した。すると内訳はさらに変わっていた。かつて時間を支配していた生成は、いまや全体のわずか10%。支配項は、通信の往復と待ち行列に移っていた。
ボトルネックは、一度潰すとまた動く。だから一度測って満足せず、測り続ける。(この続きは第2回。)
教訓
- 生成の”中身”まで見る。 生成が重いとき、それが「翻訳」なのか「モデルの考え」なのかは、まったく別の問題だ。機械的なタスクにモデルが長考していないか、トークンの中身を疑う。
- レバーは「モデルを変える」だけではない。 「考えるのをやめさせる」はモデルを変えずに27倍を1倍へ戻し、さらに前提が変わると「賢い=遅い」も崩れて、より良いモデルが速度の代償なしに使えた。
- 見えないものは、疑えない。 気づけたのは、ログがトークンの内訳を見せてくれたからだ。1行の翻訳が数百トークン、という異常にたまたま目が留まった。
付録:生データ
| 項目 | 実測 | 条件・留保 |
|---|---|---|
| 思考の暴発 | 1行翻訳(想定出力18トークン)に思考トレース500超 → トークン約27x / コスト約5x / レイテンシ約4x | 設定(reasoning=none)で完全オフにできるモデルと、できないモデルがある |
| 思考オフ前提の公平比較 | 軽量 69.7% / 308ms、中型(思考オフ)84.3%(+14.7pt)/ 253ms、大型 87.7%(+18.0pt)/ 320ms | N=300・同一プロンプト・人手校正judge(詳細は第3回)。中型が軽量より速い=「軽量=速い」の否定 |
| 後日の再計測 | 生成は全体の約10%まで低下 | 支配項は待ち行列と地理的距離へ(→第2回) |