弊誌はアフィリエイト広告を利用しています。

LLMの出力が毎回変わる問題、原因はGPUではなかった?Thinking Machinesが解決策を発見

 大規模言語モデル(LLM)を利用する際、「同じプロンプトを入力しても、出力が毎回異なる」という現象が発生することがあります。

 普通の自然言語でのチャットのやり取りでは、同じ入力に対してそこまで意味が異なる文章が返ってくることは少ないですが、例えばスクリプトを組んだりAI自身に最適なプロンプト文を作らせてみたりすると、明らかにこちらの意図から外れた挙動が何パターンも繰り返し出力される……という経験をした読者も多いのではないでしょうか。

 この問題に対し、AIスタートアップのThinking MachinesのHorace He氏らが公開した報告「Defeating Nondeterminism in LLM Inference」では、LLMの推論結果が環境やタイミングによって変化する「非決定性(nondeterminism)」と呼ばれるこの問題の根本的な原因を特定したとして、その克服方法を提案しています。

 従来、非決定性の原因としては、GPU内の並列演算や、浮動小数点演算における「非結合性」が挙げられてきました。

 たとえば、NVIDIAのA100やH100に搭載されるTensorFloat-32(TF32)形式では、a+b+cの計算順序が変わるだけでも「丸め誤差」が異なり、結果としてわずかなズレが生じることが知られています。丸め誤差とは、浮動小数点数の表現桁数に限界があるために、演算の際に生じるわずかな誤差のことです。

 しかし、Thinking Machinesの研究では、PyTorchなどの標準的なライブラリを使ってGPU上で単純な行列演算を繰り返したところ、出力がビット単位で完全に一致するケースがあることを確認しています。これにより、GPUや浮動小数点演算そのものが非決定性の原因であるとは限らず、もっと根本的な別の要因がある可能性が示唆されました。

 非決定性の真の原因は、GPUや浮動小数点演算自体ではなく、ソフトウェア側のアーキテクチャ、特に「バッチ不変性(batch invariance)」の欠如にあると結論づけました。バッチ不変性とは、入力のバッチ構成が変わっても、各リクエストの演算結果が変わらないという性質です。LLMの推論エンジンでは、複数のリクエストをまとめて「バッチ」として一括処理する設計になっており、そのバッチのサイズや構成は、他のユーザーのリクエスト状況などに応じて毎回変動します。

 LLMの推論エンジンというのは、サーバーへの複数ユーザーからの同時リクエストを1つの「バッチ」として処理することで効率を最大化しています。このバッチのサイズや構成は、その瞬間に利用している他のユーザーの数に依存するので、完全にランダムです。ここで、LLMの内部処理がこのバッチ構成に応じて演算戦略を動的に切り替えるように設計されている点に原因があるとしています。

 たとえば、RMSNorm(正規化処理)や行列乗算、注意機構(attention)といった演算カーネルは、バッチサイズが変化するたびに分割方式や計算順序を変えます。これにより、同じ入力でも異なるトークン列が生成される可能性があり、再現性が損なわれているとのことです。

 ここまで聞くと、「ローカルのLLM環境で、自分1人が1枚のGPUで使っていれば、常に同じ出力になるのでは?」という考えが頭をよぎった読者の方もいるかもしれません(実際、筆者はそう思いました)。

 しかし、研究チームは、たとえ単一GPU・単一ユーザーの環境であっても、入力の長さや前回の処理状況によって内部のバッチ構成や演算経路が変わる場合があり、それだけで出力が変わる可能性があることを指摘しています。つまり、ユーザーの数や同時実行状況にかかわらず、非決定性が起こる要因が潜んでいるのです。だから、GPU自体にまったく非決定性の原因が無い訳でもないということですね。

 He氏は、この演算処理における非決定性の原因を突き止めた上で、性能をある程度犠牲にしてでも、各処理をバッチ不変な設計に再構成するというアプローチを採用しました。これにより、入力条件が変わっても一貫した出力を保証する、完全な決定性を実現したといいます。

 まずRMSNormでは、従来用いられていた「スプリットリダクション」という手法を廃止し、たとえ非効率でもバッチサイズにかかわらず常に同一の演算パスを通す構成に変更。これにより、並列処理のための分割手法による演算順序の違いを排除し、一貫性が確保できたとのこと。

 次に、行列乗算では、入力サイズやバッチに関係なく、常に同じタイルの分割サイズを使用し、テンソルコアも常に使う、または使わないといった処理を統一。このように演算経路を固定化することで、計算順序を一定に保ち、特定の行列が小さい場合でも、異なる演算命令に切り替わることがなくなります。

 そして最も複雑な注意機構(Attention)では、キャッシュと現在の入力データを、実行前にあらかじめ一貫したメモリレイアウトに統合する処理を導入しました。さらに、処理対象となる系列を常に同じサイズのチャンクに分割し、余った部分は最後のチャンクにまとめて処理するという方式を採用しています。これにより、入力の長さやタイミングに依存する演算順序の変動を防ぎ、計算結果の再現性を実現できたと謳います。

 実際に、この手法を適用したベンチマークでは、出力結果が1000回中1000回すべてビットレベルで一致し、再現性を完全に確保できたとのこと。
 一方で、出力の安定性を確保する代わりに、処理性能には一定の影響が見られます。たとえば、Qwen-3-8Bモデルを使ったベンチマークでは、処理速度が従来に比べておよそ1.5倍ほどの時間がかかり、別の推論タスクでは処理時間が1.6倍(26秒から42秒へ)に伸びるなど、複数のテストで速度の低下が確認されました。先程の説明を踏まえたら当然の結果ですが、それでも、実用上は許容範囲に収まっていると考えられます。

Configuration Time (seconds)
vLLM default 26
Unoptimized Deterministic vLLM 55
+ Improved Attention Kernel 42

 金融・医療・法務をはじめ、出力結果が常に同じでなければならない重要な分野へLLMの導入を検討する上で、今回の研究成果は画期的な進歩と言えるのではないでしょうか。

 また、LLMを活用した強化学習においても、推論と学習の間で結果が一致しないと、本来のオンポリシー学習が事実上のオフポリシー学習になってしまいます。
 出力Aを出した→報酬を与える→「Aを出すように」学習するというのがオンポリシー学習ですが、非決定性があると、ログ上では出力Aだったが、同じ入力でも学習中には出力Bが出る→「Aに対する報酬」で「Bを強化」してしまう→結果として学習が不整合・不安定になる、これが事実上のオフポリシー化です。

 この研究は、こうした微細なずれを排除し、純粋な強化学習の実現にも貢献する技術基盤となり得ます。

 AIというものが、だんだんと技術者たちのおもちゃから人間社会を支えるインフラになりつつあり、今回の研究結果はそのための橋渡しといったところでしょうか。出力の揺らぎは人間なら当たり前ですが、AIの挙動としては全然「機械」らしくないですからね。

すまほん!!を購読しませんか?

Twitterでも最新更新を配信・通知しています

フォローする 再度表示しない