PaPoo
cover
technews
Author
technews
世界の技術ニュースをリアルタイムでキャッチし、日本語でわかりやすく発信。AI・半導体・スタートアップから規制動向まで、グローバルテックシーンの「今」をお届けします。

GPUのマトリクス乗算は、なぜ「予測しやすいデータ」で速くなるのか

キーポイント

まず何が起きたのか

この記事の出発点は、かなりシンプルです。

著者の Horace He さんは、GPU向けの高速matmul実装である CUTLASS を試していました。
8192×8192×8192 の大きな行列積をベンチマークすると、最初は CUTLASS が CuBLAS より速いように見えたそうです。これは「お、すごい」と思いますよね。私もここでちょっとテンションが上がります。

でも、Python から同じ CUTLASS を呼び出して比較すると、その差が消えてしまう。
さらに調べると、​入力行列の中身が違うだけで性能が変わることに気づきます。

たとえば、

image_0001.png

という具合です。

ここがかなり不思議です。
普通、行列積は「同じサイズなら、どんな値でも同じ計算量」です。掛け算の回数も、メモリの読み方も、基本は変わらない。
なので、​値の中身で速度が変わるなんておかしい、というのが最初の自然な感覚だと思います。

なぜ値で速度が変わるのか

結論からいうと、犯人は dynamic/switching power でした。

GPUはただ計算しているだけではなく、内部の無数のトランジスタが高速に ON/OFF を繰り返しています。
この「切り替わる回数」が多いほど電力を食います。これが switching power、つまり動的電力です。

一方で、何もしなくても消える電力もあります。これは static/leakage power と呼ばれます。
ざっくり言えば、

image_0004.png

みたいなものです。

GPUには電力上限があり、そこに達すると GPU は clock speed​(動作周波数)を下げて消費電力を抑えます。
この状態が throttling です。つまり、​高い性能を出したくても、電力が足りなければ勝手にスピードを落とされるわけです。

そこで重要になるのが、入力データの「予測しやすさ」です。

その結果、​ゼロのような“おとなしいデータ”のほうが電力を食わず、クロックが落ちにくいので速くなる、というわけです。

率直に言うと、これはかなり気持ちいい発見です。
「計算量は同じなのに速さが違う」というのは、最初はバグっぽい。でも、電力という別の軸を持ち込むと一気に腑に落ちる。ハードウェアってこういう“見えない制約”が本当に効くんですよね。

image_0005.png

どんなデータが速いのか

著者はさまざまなデータ分布でも試しています。たとえば:

ざっくりした傾向としては、

という流れです。

著者の推測では、ゼロや定数ばかりの入力では、演算結果や内部状態の変化が少なくなり、トランジスタのスイッチングも減るのだろう、とのこと。
これはあくまで推測も含みますが、実験結果とはかなり整合しています。

image_0006.png

個人的には、ここで「unstructured sparsity isn’t efficient with tensor cores?」と冗談っぽく言っているのが好きです。
普通は「疎なデータは効率が悪いこともある」とか、逆に「疎なら速い」とか、文脈次第で話がややこしいのですが、少なくとも**“ゼロが多いと電力的に有利”**というのは、かなり直感に反していて面白いです。

電力制限を下げると差が広がる

この記事のもう一つの重要なポイントは、​power limit を変えると差がどう変わるか、です。

著者は、予測しやすい入力(zeros)と予測しにくい入力(randn)を比べています。
すると、power limit を 330W から 100W に下げるにつれて、​zeros の有利さが増すことが分かります。

これは理屈として自然です。

さらに興味深いのは、かなり低い電力制限では、逆に傾向が崩れる場面もあることです。
著者は「GPUがあまりにも電力制約を受けていて、ゼロでもまだ電力を使いすぎるのでは」と推測しています。
ここは完全に断定ではないものの、かなりありそうな話だと思います。電力はほんとうに容赦ないですね。

image_0009.png

clock speed をいじると何が分かるか

著者はさらに、GPUの clock speed を固定して、zeros と randn の差を見ています。

すると、

という結果になります。

これもすごく大事です。
つまり、性能差は「アルゴリズムの違い」ではなく、​電力制約とクロック制御の結果として生まれているわけです。

image_0010.png

このへんは、GPUを単なる「計算機」として見ると見落としやすい。
でも実際には、GPUは“計算する石”であると同時に、“電力と熱に縛られた機械”なんですよね。
私はこの手の話を見るたびに、ハードウェア性能って最終的には物理法則に負けるんだな、としみじみ思います。

Nvidiaの「理論値」と「実測値」がズレる理由

記事の後半では、Nvidiaが広告や仕様表で出している FLOPS と、実際に持続できる性能の差にも触れています。

Nvidiaが示す理論上の FLOPS は、だいたい次のような式で表されます。

FLOPS = Tensor Cores数 × Max Clock Speed × 1 instructionあたりの演算量

たとえば H100 では、Tensor Core の数や最大クロックから計算して、約 989 TFLOPS という数字になる、と著者は説明しています。
ただしこれは、​その最大クロックをずっと維持できる前提です。

でも実際には、電力制限のせいでそこまで維持できない。
そのため、実運用での性能は理論値より低くなります。

image_0012.jpg

ここが実務的にはかなり重要です。
ベンチマークやスペック表を見るとき、つい「このGPUは○○ TFLOPS か!」と思いがちですが、現実には

で、実効性能はかなり変わります。

著者は、H100 は理論上 A100 の3倍近い FLOPS を持っていても、実際には電力制約のせいで「体感的には 2倍くらい」に見えることが多い、と述べています。
これも断言というより観察に基づく話ですが、現場感としてはかなり納得感があります。

何がそんなに面白いのか

この話の面白さは、単に「ゼロのほうが速い」という珍現象ではありません。
本質は、​GPUの速度は演算器の性能だけでは決まらないという点にあります。

多くの人は、GPU性能を「Tensor Core が何個あるか」「理論 FLOPS がいくつか」で見がちです。
でも実際には、

image_0013.jpg

みたいな、かなり泥くさい要素が効いてくる。

私はこのあたり、ハードウェアのロマンを感じます。
ソフトウェアの世界では「同じ計算なら同じ結果」が基本ですが、ハードウェアは「同じ計算でも、物理的な振る舞いは全然同じではない」。
その差が性能として表に出るわけです。

まとめると

この記事が教えてくれるのは、次の一言に尽きます。

GPUの matmul は、計算量だけでなく、データの“おとなしさ”で速さが変わることがある。​

理由は、入力値によってトランジスタの切り替わり方が変わり、それが動的電力に影響し、結果として power limit と throttling に効いてくるからです。

image_0014.png

技術者目線で見ると、

という、かなり重要な教訓が詰まっています。

そして何より、「matmul の速さがデータの値で変わる」という事実は、やっぱりちょっとワクワクします。
コンピュータは論理で動いているようで、最後はちゃんと物理なんだな、と思わされる記事でした。


参考: Strangely, Matrix Multiplications on GPUs Run Faster When Given "Predictable" Data! [short]

同じ著者の記事