0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ベンチで「効果を見つけた」と思ったら、測定のぶれだった

0
Posted at

この記事は tk3.biz のブログ からの転載です。

はじめに

第2回で、KV キャッシュの量子化を使わないと決めました。理由はこう書いています。

q8_0 は f16 と同等の perplexity を示し品質劣化はほぼ無い。しかし f16 が収まる環境では f16 のほうが速い。毎トークン逆量子化が走るため。

この判断には弱点がありました。根拠が他所の計測だったことです。「64K 深度で f16 比 55% まで落ちる」という報告を読んで、自分の環境では測らずに不採用にしていました。

その後コンテキストを 16K から 64K に広げたので、前提を確かめる必要が出てきました。測りました。そして一度、間違った結論を出しました。その記録です。

何を測るか

llama-bench には -d(n-depth)があります。KV キャッシュに指定トークン数を積んだ状態から生成を始めるので、「会話が長くなったとき、生成がどれだけ遅くなるか」を直接測れます。

llama-bench -hf <model> -ngl 99 -fa 1 -b 8192
            -p 0 -n 128 -d 0,4096,16384,32768

-p 0 でプロンプト処理を外し、生成だけを切り出します。

まず f16 で測り、次に -ctk q8_0 -ctv q8_0 で同じことをやりました。

1 回目: 判断が覆った(と思った)

深度 f16 q8_0 差
0 16.79 18.36 +9.4%
4,096 16.27 18.17 +11.7%
16,384 15.05 16.54 +9.9%
32,768 14.29 15.38 +7.6%

全深度で q8_0 が速い。 しかもばらつきも小さい。

このとき、説明まで思いついていました。

この機体は一貫して帯域律速だった。密 27B より MoE が 5.7 倍速いのも、-b は効くが -ub は効かないのも、全部帯域で説明がついた。KV を量子化すれば読み出しが減る。帯域律速の環境では q8_0 が有利なのではないか。

筋が通って聞こえます。第2回が参照した報告はおそらく dGPU のもので、そちらは演算律速だから逆量子化のコストがそのまま損になる。こちらは帯域律速だから得をする——。

もっともらしい説明ほど危ない、という話をこれから書きます。

引っかかった点

表を眺めていて、深度 0 で 9.4% の差がついているのが気になりました。

深度 0 は KV キャッシュが空です。空のキャッシュを量子化しても、読むものが無いのだから速度は変わらないはずです。

帯域律速の仮説が正しいなら、差は深いところほど大きくなるべきで、深度 0 ではゼロに近いはずでした。実際の表は逆で、深度 0 がいちばん差が大きく、深くなるほど縮んでいます。

説明と観測が合っていません。

2 回目: 測り直した

llama-bench は条件をカンマ区切りで受け取れます。1 回の起動の中で f16 と q8_0 を交互に、各 5 回ずつ測りました。

llama-bench ... -d 0,32768 -ctk f16,q8_0 -ctv f16,q8_0 -r 5

結果が逆になりました。

type_k type_v 深度 0 深度 32,768
f16 f16 18.57 ± 0.51 15.65 ± 0.23
f16 q8_0 17.60 ± 0.99 14.14 ± 0.41
q8_0 f16 17.58 ± 0.35 15.10 ± 0.35
q8_0 q8_0 17.71 ± 1.03 14.06 ± 0.37

f16 が最速です。 深度 32K で q8_0 比 +11.3%(15.65 対 14.06)、誤差範囲も重なっていません。

そして深度 0 では、差が消えました。18.57 ± 0.51 と 17.71 ± 1.03 は範囲が重なります。KV が空なら量子化は効かない、という物理どおりです。

第2回の判断は正しかったわけです。

何が起きていたのか

1 回目と 2 回目で、同じ f16 / 深度 0 の値が違います。

1 本目: 16.79
3 本目: 18.57   ← 同じ設定なのに +10.6%

同じ設定なのに実行するたび10%動く様子。1本目のf16が16.79、2本目のq8_0が18.36で「q8_0が速い」と誤読、3本目の交互計測ではf16が18.57でq8_0が17.71。同じf16のぶれ幅が16.79から18.57まで広がっている

**実行間のばらつきが約 10% ありました。**測ろうとしていた差(約 9%)が、そっくりその中に埋もれていたわけです。

1 本目と 2 本目は別プロセスで、順番に走らせました。その間にウォームアップの状態も、電力もサーマルも変わります。2 本目が有利な条件で走っただけでした。

「q8_0 のほうが速い」という観測は、条件の差ではなく順番の差を見ていたことになります。

帯域律速の仮説も外れていた

ついでに、私が立てた説明も間違っていました。

KV を量子化すれば読み出しは確かに減ります。しかし逆量子化のコストのほうが上回っていました。帯域律速の環境でも、です。

細かい発見として、V を量子化するほうが K より損でした。

深度 32,768
K も V も f16 15.65
K だけ q8_0 15.10
V だけ q8_0 14.14
K も V も q8_0 14.06

K だけなら劣化 3.5%、V だけだと 9.7%。q8_0 にするなら K から、というのは覚えておく価値がありそうです。

収穫: 深度による劣化は緩やかだった

誤りは誤りとして、新しく分かったこともあります。

コンテキスト深度による生成速度の劣化。深度0で16.79、4096で16.27、16384で15.05、32768で14.29と、32Kまで積んで15%減に留まる

深度 tg128 深度 0 比
0 16.79 —
4,096 16.27 −3%
16,384 15.05 −10%
32,768 14.29 −15%

32K まで積んでも 15% 減です。第2回が参照した「64K 深度で f16 比 55%」という報告に比べると、傾きがかなり緩いことになります。

長い会話やコードレビューで深いコンテキストを使っても、速度面の心配は小さいと言えます。

この 4 点は 1 回の起動の中で深度だけを振った値なので、互いに比較できます。さっき批判した測り方をここではしていません。

教訓

差が 10% 前後なら、まず測定系のばらつきを確かめる。

効果の大きさを測る前に、同じ条件を 2 回測ってどれだけ動くかを見るべきでした。それをやっていれば、1 回目の表を見た瞬間に「この差はノイズの範囲だ」と分かりました。

別々に起動したベンチは比較できない。

llama-bench に限らず、プロセスを分けた時点でウォームアップ・電力・サーマル・キャッシュの状態が揃わなくなります。比較したい条件は、1 回の起動の中で振る。

-ctk f16,q8_0 -ctv f16,q8_0 -r 5

説明が思いついたときこそ疑う。

今回いちばん危なかったのは、「帯域律速だから q8_0 が有利」という説明がすぐ出てきてしまったことです。しかもこれまでの観測と整合していました。

もっともらしい説明は、間違った数字に説得力を与えてしまいます。助かったのは、説明のほうが別の予測(深度 0 では差が出ないはず)を持っていたからでした。その予測が外れていたので、測り直す気になりました。

**説明できたと思ったら、その説明が他に何を予測するかを確かめる。**そこが合っていなければ、説明か数字のどちらかが間違っています。

まとめ

  • 過去の判断(KV は f16 のまま)を検証したら、一度は逆の結論が出た
  • 深度 0 で差が出るのは物理的におかしいと気づき、測り直したら元の判断が正しかった
  • 原因は実行間のばらつき 10%。測ろうとした差がその中に埋もれていた
  • 設定は変更なし。深度 32K での劣化は 15% と緩やかという収穫は残った
  • q8_0 を使うなら K から。V の量子化のほうが損が大きい

検証して「やっぱり正しかった」で終わる話でしたが、途中で間違えた過程のほうが、自分には収穫でした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?