科学・技術
悪いベンチマークと評価:Senior SWE-Bench、ナプキン計算、そして冬用タイヤ
Bad benchmarks and evals: Senior SWE-Bench, napkin math, and winter tires (danluu.com)
要約
この記事は、AIモデルの評価(Senior SWE-Bench)、パフォーマンスの概算(ナプキン計算)、そして冬用タイヤの性能という3種類のベンチマークについて考察しています。著者は、特に「ナプキン計算」のベンチマークにおけるランダムメモリ読み書きのレイテンシやSSDのランダム読み込みの数値に疑問を呈し、それらが実際のハードウェアの挙動を正確に反映していない可能性を指摘しています。また、冬用タイヤに関する一般的な認識も、実際の性能評価の難しさを示唆する例として取り上げています。
全文翻訳
ここでは3種類の異なるベンチマークを見ていきます。パフォーマンスの「ナプキン計算」による概算値のセット、AIモデルの評価のセット、そして車のタイヤに関するセットです。物事に対する私の直感を養うために、説明を見る前にそれらについて考えるのが好きなので、もしあなたの考えをまとめる前に私の考えを見たい場合は、ベンチマーク情報を先に提示し、説明を後にします。
29. 知人がコンピュータパフォーマンスの面接の準備のためにオーダーマグニチュードをレビューしていて、https://github.com/sirupsen/napkin-math (スター5.4k) がトップヒットであることを見つけました。READMEの表には以下が含まれています。
Napkin Math パフォーマンス推定
操作
レイテンシ
スループット
1 MiB
1 GiB
シーケンシャルメモリ R/W (64バイト)
0.5 ns
├ シングルスレッド
20 GiB/s
50 μs
50 ms
├ スレッド
200 GiB/s
5 μs
5 ms
ネットワーク 同ゾーン
10 GiB/s
100 μs
100 ms
├ VPC内
10 GiB/s
100 μs
100 ms
├ VPC外
3 GiB/s
300 μs
300 ms
ハッシュ、暗号化セーフでない (64バイト)
10 ns
5 GiB/s
200 μs
200 ms
ランダムメモリ R/W (64バイト)
20 ns
3 GiB/s
300 μs
300 ms
高速シリアライゼーション [8] [9] †
N/A
1 GiB/s
1 ms
1s
高速デシリアライゼーション [8] [9] †
N/A
1 GiB/s
1 ms
1s
システムコール
300 ns
N/A
N/A
N/A
ハッシュ、暗号化セーフ (64バイト)
100 ns
1 GiB/s
1 ms
1s
シーケンシャルSSD読み込み (8 KiB)
1 μs
8 GiB/s
100 μs
100 ms
コンテキストスイッチ [1] [2]
10 μs
N/A
N/A
N/A
シーケンシャルSSD書き込み、-fsync (8KiB)
2 μs
3 GiB/s
300 μs
300 ms
TCPエコーサーバー (32 KiB)
50 μs
500 MiB/s
2 ms
2s
ランダムSSD読み込み (8 KiB)
100 μs
70 MiB/s
15 ms
15s
解凍 [11]
N/A
1 GiB/s
1 ms
1ms
圧縮 [11]
N/A
500 MiB/s
2 ms
2s
ソート (64ビット整数)
N/A
500 MiB/s
2 ms
2s
プロキシ: Envoy/ProxySQL/Nginx/HAProxy
50 μs
???
同一リージョン内ネットワーク
250 μs
2 GiB/s
500 μs
500 ms
プレミアムネットワーク (同一ゾーン/VPC内)
250 μs
25 GiB/s
50 μs
40 ms
シーケンシャルSSD書き込み、+fsync (8KiB)
300 μs
30 MiB/s
30 ms
30s
{MySQL, Memcached, Redis, ..} クエリ
500 μs
???
シリアライゼーション [8] [9] †
N/A
100 MiB/s
10 ms
10s
デシリアライゼーション [8] [9] †
N/A
100 MiB/s
10 ms
10s
シーケンシャルHDD読み込み (8 KiB)
10 ms
250 MiB/s
2 ms
2s
ランダムHDD読み込み (8 KiB)
10 ms
0.7 MiB/s
2 s
30m
ブロブストレージ GET, if-not-match 304
30 ms
ブロブストレージ GET, 1 conn (128KiB)
80 ms
100 MiB/s
10 ms
10s
ブロブストレージ GET, n conn (オフセット)
80 ms
NW制限
ブロブストレージ LIST
100 ms
ブロブストレージ PUT, 1 conn (128KiB)
200 ms
100 MiB/s
10 ms
10s
ブロブストレージ PUT, n conn (マルチパート)
200 ms
NW制限
10 ms
10s
リージョン間ネットワーク [6]
変動
25 MiB/s
40 ms
40s
ネットワーク NA Central <-> East
25 ms
25 MiB/s
40 ms
40s
ネットワーク NA Central <-> West
40 ms
25 MiB/s
40 ms
40s
ネットワーク NA East <-> West
60 ms
25 MiB/s
40 ms
40s
ネットワーク EU West <-> NA East
80 ms
25 MiB/s
40 ms
40s
ネットワーク EU West <-> NA Central
100 ms
25 MiB/s
40 ms
40s
ネットワーク NA West <-> Singapore
180 ms
25 MiB/s
40 ms
40s
ネットワーク EU West <-> Singapore
160 ms
25 MiB/s
40 ms
40s
完全な表を表示
このベンチマークの何が問題なのか?
30. 人々が、自分の好きなモデルが他の人の好きなモデルより優れていることや、一般的に良いベンチマークであると「証明」するために、DeepSWEやSenior SWE-Benchを頻繁に参照しているのを目にします。例えば、What's wrong with these benchmarks? という記事でも同様です。
31. 人々は、冬の寒い時期には冬用タイヤがオールシーズンタイヤよりも優れていると頻繁に言います。例えば、「オールシーズンタイヤ 冬の寒さ」でGoogle検索すると(引用符なし)、Google AIの要約は次のように始まります。「オールシーズンタイヤは、凍えるような冬の気温ではトラクションを失い、硬くなります。それらのゴム化合物は暖かい気候向けに設計されており、7°C(45°F)以下では硬くなり、ブレーキ距離が大幅に長くなり、グリップが低下します...オールシーズンタイヤのゴムは、零以下の温度で柔軟性を維持できず、雪や氷の上では硬いプラスチックのように機能します。」トレーニングデータには多くのインターネットコメントが含まれているため、これは妥当なコメントです。なぜなら、どのタイヤを使うべきかという議論では、このコメントのバリエーションを頻繁に見かけるからです。このベンチマークの何が問題なのか?
29. ナプキン計算の数値
ランダムメモリアクセスのレイテンシ
私の友人(ジェイミー)がすぐに奇妙だと感じたのは、ランダムメモリ R/W が 20ns とリストされていることでした。なぜなら、ランダムメモリ R/W は実際のDRAM読み込み(キャッシュヒットとは対照的に)を意味すると想定されるため、彼はオーダーマグニチュードの推定値としては約100nsになるはずだと感じていたからです。彼と話していると、彼はREADMEがレイテンシではないものに「レイテンシ」という用語を使っていると指摘しました。そして、ランダムメモリ読み込みレイテンシのコードを調べたとき、彼は以下のものを見つけました(もし別の演習をしたいなら、以下の説明を読む前に以下のコードの何が問題か考えてみてください):
while test.i < test.vec.len() {
let random_index = test.order[test.i];
black_box(test.vec[random_index]);
test.i += 1;
}
ジェイミーは、ループの繰り返し間にデータ依存性がないため、メモリ読み込みは並列に発生すると指摘しました。 alleged レイテンシ番号はアクセスごとの平均時間を調べることで決定されるため、これは不正確です。なぜなら、CPUは同時に複数のロードをインフライトさせることができるからです。もしレイテンシをこのように測定したいのであれば、重複アクセスを防ぐために、ロード間に依存性を導入する必要があるでしょう(このシリーズのパート4でカバーされている、演習19の関連トピックについて議論しました)。
ランダムSSD読み込み
私はジェイミーのコメントすべてに同意しますが、レイテンシという用語の使用法については、それが場合によってはレイテンシの略語であり、他の場合(例えば逆スループットのようなもの)ではレイテンシに似た何かである可能性があるため、テーブルをよりシンプルにするために、私自身はそれをフラグしませんでした。メモリレイテンシの数値以外で最初に私の注意を引いたのは、他のいくつかの数値でした。例えば、ランダムSSD読み込みは100μs / 70MB/sとリストされています。より高速な(そしてより遅い)SSDも入手可能です。例えば、高速な(しかしエキゾチックではない、例えばOptaneではない)デバイスの場合、40μs未満のレイテンシが見られるかもしれません。例えば、Kioxia CD9P-Rはここで約30μsと測定されました。些細なスクリプト以外では、ディスクパフォーマンスを気にするような作業をしたことがないので、心に留めておくべき数値についての直感はありませんが、ランダム読み込みレイテンシとスループットのために単一の数値を持つことが、DRAMアクセスの場合よりも有用性が低いのではないかとも疑問に思います。ディスクベンチマークを見るたびに、読み込みサイズ、キューの深さ、ジョブの数(例えば、Kioxia CD9P-Rに関する前のリンクを参照)に基づいて結果に大きなばらつきがあるように見えます。もちろん、DRAMのレイテンシと帯域幅に影響を与える同様の要因がありますが、メモリアクセスについて考える際に、1つか2つの数値を知っていることが役立つ領域にいることが多いように思われます。ディスクパフォーマンスについては何も知らないので、Postgresのディスクパフォーマンスに取り組んだことのあるPeter Geogheganに尋ねました。彼は同意し、またディスクパフォーマンスの複雑さについて以下の追加コメントを書いてくれました。
このSSDランダム読み込み数値のコードを見ると、ジェイミーがランダムメモリ読み込みコードについて感じたのと同じように、私にはおかしく感じられます。それは、以下のコードでオフセットを生成します。
for i in 0..(buffer.len() / page_size) {
pages.push((i * page_size + 1) as u64);
}
そして8KiBの読み込みを行います(オフセットはランダム読み込みを作成するためにシャッフルされます)。
正しくないと思われる点がいくつかあります。
+1 は、すべての読み込みをアラインメントされていないものにします。
4KiBのページサイズの場合、これは1回の読み込みで3ページに触れることになります。
異なるオフセットは同じページをオーバーラップする可能性があり、ページキャッシュからの意図しない読み込みを引き起こす可能性があります。
ページサイズによっては、読み込みがファイルの末尾を超えてしまい、パニックを引き起こす可能性があります。
「buffer.len() / page_size」という構成は、アクセスを範囲内に保つことを意図しているようですが、これはアクセス長とは無関係です。もし正確なオフセットを考えずに怠惰になりたいなら、例えば4GiBのような巨大なアクセス長を考えてみてください(バッファサイズは8GiBです)。それは確実にオーバーフローします。もしより正確になりたいなら、オーバーフローケースは4KiBページと8KiBアクセス長のようなものになりますが、同じ考え方が適用されます。
最後のオフセットは SIZE - 4096 + 1 になります。これにより、4095バイトにアクセスできますが、8192バイトにアクセスしようとします。ベンチマークは5秒間しか実行されないため、EOFを読み越して失敗するかどうかは実際には試さないかもしれませんが、バグがあります。