実行プログラムと拡張機能
最終更新
3090アンロックの検証:起動・GEMM・llama-benchの記録
同じ条件を記録しなければ、アンロック分を切り分けられません。
アンロック前後の比較は条件を固定することから始まります。カーネル・ドライバー・VBIOS・電力上限・文脈長1を記録し、torch GEMMで行列演算を、llama-benchでプリフィル2とデコード3を測ります。コールドブート後にログを確認し、失敗したらカーネルコマンドラインからオプションを消して戻します。
まず基準線を記録します
測定前にカーネル版、NVIDIAドライバー、VBIOS、電力上限、現在のクロックを記録します。uname -r、nvidia-smi、nvidia-smi -qで確認できます。同じカードでもドライバーと電力設定が違えば結果は変わります。
電力上限は実験中ずっと固定します。3090の既定値は350Wで、300Wや280Wに下げるとデコードが少し遅くなります。前後比較で電力を変えると、演算の変化と電力の変化が混ざります。
uname -r
nvidia-smi --query-gpu=name,driver_version,vbios_version,power.limit,clocks.max.sm,memory.total --format=csv
nvidia-smi -q | grep -A2 "GPU Power Limit"
GEMMで行列演算だけを測ります
公開された比較は8192³のdense GEMM、FP324累積、5回中央値でした。同じ条件でFP165・BF166・TF32を測れば、アンロックが行列演算に与えた影響を切り分けられます。ウォームアップを除き、中央値を使います。
PyTorch7でTF32を実際に使うにはtorch.backends.cuda.matmul.allow_tf32を有効にし、BF16では入力をtorch.bfloat16にします。測定スクリプトはリポジトリのイシューの条件を参考に自分で書くのが安全です。
import torch, time, statistics
assert torch.cuda.is_available()
torch.backends.cuda.matmul.allow_tf32 = True
n = 8192
for dtype in (torch.float16, torch.bfloat16):
a = torch.randn(n, n, device='cuda', dtype=dtype)
b = torch.randn(n, n, device='cuda', dtype=dtype)
for _ in range(3): a @ b
torch.cuda.synchronize()
times = []
for _ in range(5):
start = time.perf_counter(); a @ b; torch.cuda.synchronize()
times.append(time.perf_counter() - start)
med = statistics.median(times)
print(dtype, round(2 * n**3 / med / 1e12, 2), 'TFLOPS')llama-benchでプリフィルとデコードを測ります
llama-benchは同じモデルでプリフィルとデコードを分けて表示します。-p 4096 -n 128 -r 5のように文脈と反復回数を固定し、モデル・量子化8・電力上限を前後で同一にします。モデルはカードにあるGGUF9を使ってください。
llama.cppの量子化カーネルにはBF16行列積を使わない経路が多いです。そのためGEMMで大きな差が出ても、llama-benchのデコードがそのままのことがあります。この差を説明できて初めて結果を解釈できます。
llama-bench -m /path/to/model.gguf -p 4096 -n 128 -r 5コールドブート後にログを確認します
アンロックは完全に電源を切ってから再起動すると適用されます。起動後にjournalctl -k -b | grep gpu_unlockでモジュールログを、lspci -nnk -s <PCIアドレス>でドライバーのバインドを確認します。nvidia-smiでカードが正常に見えるかも確認してください。
Xidエラーやドライバーリセットが見えたら実験を中止してください。同じ電源サイクルで既にドライバーが使ったカードは拒否されるため、再試行前に必ず電源を切ります。
journalctl -k -b | grep gpu_unlock
lspci -nnk -s 0000:21:00.0
nvidia-smi
元に戻す方法と失敗時の復旧
問題が起きたらカーネルコマンドラインからgpu_unlock.targets=を消して再起動します。パッケージを削除するとモジュールとinitramfs設定も整理されます。画面が出ない場合はブートローダーの編集画面で一時的にオプションを消して起動します。
ファームウェアが停止しなかったというログが残ると、次の電源断までDMAバッファが保持されます。再試行前に電源を切り、可能なら試験用カードで先に確認してください。
記録様式
以下の項目を前後で二回記録すると比較が再現できます。同じ値でなければ差を先に説明し、説明できなければアンロックの効果として計算しません。
| 記録項目 | 例 |
|---|---|
| カーネル・ドライバー・VBIOS | 7.2.8-1, 615.71.09, 94.02.42.00.9b |
| 電力上限 | 350W |
| BF16 GEMM | 87.50 → 157.41 TFLOPS |
| llama-benchプリフィル | 条件とともに記録 |
| llama-benchデコード | 68.9 tok/s (3090, 350W) |

用語の注釈
コンテキスト長 — 1回のリクエストでモデルが扱える入力と生成内容のトークン範囲です。上限や実際のメモリ使用量はモデルと実行設定によります。
本文に戻るプリフィル — LLMが入力プロンプトを読み、各トークンの内部表現を計算する段階です。プロンプトが長いほど処理するトークンが増えます。
本文に戻るトークンのデコード — 入力とそれまでの回答をもとに、次の出力トークンを順に生成する段階です。
本文に戻るFP32 — 32ビット浮動小数点形式です。BF16より値あたりのメモリを多く使い、数値をより細かく表現できます。
本文に戻るFP16 — 16ビット浮動小数点形式です。BF16とビット幅は同じですが、指数部と仮数部の配分が異なります。
本文に戻るBF16 — モデルの数値に使う16ビット浮動小数点形式です。指数部はFP32と同じ幅で、同程度に広い値の範囲を表せます。
本文に戻るPyTorch — AIモデルを作成・実行するソフトウェアフレームワークです。モデルと合わせて、対応するPyTorchの版やハードウェアも確認します。
本文に戻る量子化 — モデルの重みや計算値を少ないビット数で表し、保存容量やメモリ使用量を減らす方法です。表現が粗くなるため、精度にも影響することがあります。
本文に戻るGGUF — モデル情報を格納するファイル形式で、llama.cpp系のツールで広く使われます。
本文に戻る
よくある質問
- この記事で最初に確認すべきことは何ですか?
- アンロック前後の比較は条件を固定することから始まります。カーネル・ドライバー・VBIOS・電力上限・文脈長を記録し、torch GEMMで行列演算を、llama-benchでプリフィルとデコードを測ります。コールドブート後にログを確認し、失敗したらカーネルコマンドラインからオプションを消して戻します。
