PyTorchのMPSで巨大行列積が誤る条件の調査
Silent Failures Beyond the 32-Bit Index Range: A Differential Characterization of Large-Tensor Matrix Multiplication in PyTorch's MPS Backend
この論文をやさしく読む
ひとことで言うと
PyTorchのMPSで巨大な行列積を行うと、エラーが出ないまま計算結果や勾配が誤る条件を調べた。
何に役立つ?
Apple Silicon上で非常に大きなテンソルを扱う計算の検証や、危険な操作を止めるガードの設計に役立つ。
この研究の面白いところ
2³²要素の境界を少し超えただけで、明示的な例外が無警告の誤計算に変わる。6156件の結果を別環境でも再現した。
どこまで分かった?
調査は観測可能な動作に基づき、非公開のMPSカーネル内部を解析したものではない。要旨に示された範囲は調査したPyTorch版、機器、形状に限られる。
v2のアブストラクトに基づくAI解説。日本語訳とは別に、用途の解釈を含みます。
アブストラクトの日本語訳
大容量のユニファイドメモリを備えたApple Siliconでは、デスクトップGPU上に巨大なテンソルを保持できる。しかし、PyTorchのMetal Performance Shaders(MPS)バックエンドでは、要素数が2³²を超えるバッチ行列積が、警告なしに誤った結果を返すことを発見した。torch bmmと、それを使うmatmulおよびeager attentionは、調べたすべてのPyTorchリリース(2.4.1から2.14.0)で、例外や警告を出さずに相対誤差が1を超えた。データ型、メモリ配置、形状、バッチ数を変え、要素数が2³¹と2³²付近の場合を調べ、各結果をCPUでのfloat64計算と比較した。2.14.0での結果は3つの規則で説明できた。出力が2³²要素を超え、入力の一方が転置ビューの場合、出力全体が誤り、その入力のストライドを無視した計算結果と一致する。それ以外では、2³¹要素以上のビューは例外を起こし、2³²要素を超える連続配置の入力では、その境界を超えたバッチだけが誤り、添字が2³²で折り返された計算結果と一致する。このため、問題を少し大きくしただけで、明示的なエラーが無警告の失敗へ変わり得る。これらの規則は逆伝播にも当てはまり、順伝播が正しくても勾配が無警告で誤る場合がある。別のチップを備えた2台目のマシンでも、2種類のmacOSで、誤った値を含む6156件すべての結果が再現された。同じ条件の調査では、NVIDIA A100上の2530回の実行はすべて正しかった。公開されている感情分類器では、巨大なバッチ1つによって出力の3分の1が壊れ、1クラスに集中した。調査結果は非公開のバックエンドカーネルを参照せず、観測できる動作に基づく。著者らは調査用プログラム、生データ、2³²要素以上に触れるMPS操作を停止する防護機能を、jniimi/mps-silent-failures(https://github.com/jniimi/mps-silent-failures)で公開している。
v2の要旨から自動生成。本文の精読・人による確認は未実施。
- 初稿
- 2026-09-19(UTC)
- 最新改訂
- 2026-09-23 · v2
- 査読・掲載
- 査読状況未確認
更新履歴
取得できた版を表示。版の更新は査読済みを意味しません。過去版の本文差分は未解析です。
原文の要旨
Apple Silicon machines with large unified memory make it possible to hold large tensors on a desktop GPU. However, we found that PyTorch's Metal Performance Shaders (MPS) backend silently returns wrong results for batched matrix multiplication with more than $2^{32}$ elements. torch bmm, including its wrappers matmul and eager attention, returns relative errors above 1 without an exception or a warning in every PyTorch release tested (2.4.1 to 2.14.0). We sweep bmm over dtypes, memory layouts, shapes and batch sizes around $2^{31}$ and $2^{32}$ elements, and judge every result against a float64 computation on the CPU. Three rules account for every outcome on 2.14.0. When the output exceeds $2^{32}$ elements and an operand is a transposed view, the entire output is wrong and equals a computation that ignores that operand's strides. Otherwise, a view with at least $2^{31}$ elements raises an exception, and a contiguous input above $2^{32}$ elements makes exactly the batches beyond that point wrong, equal to a computation whose index wraps at $2^{32}$. A slightly larger problem can thus turn an explicit error into a silent failure. The rules extend to the backward pass, where a correct forward pass can return silently wrong gradients. A second machine with another chip, under two macOS versions, reproduces all 6156 results, including the wrong values, and the same sweeps on an NVIDIA A100 are correct in all 2530 runs. In a public sentiment classifier, one oversized batch corrupts a third of the outputs, which collapse onto one class. All findings come from observable behavior, without access to the backend's closed-source kernels; we release the harness, raw results and a guard that stops any MPS operation touching $2^{32}$ or more elements at jniimi/mps-silent-failures (https://github.com/jniimi/mps-silent-failures).
arXiv ID: 2609.22991 / 要約の誤りについて