前シリーズの続編です。1台の DGX Spark(GB10, 128GB)で TensorFold のネイティブCUDAエンジン(Zig実装)を追い、
バージョンごとのprefill/decodeの変化と、途中で踏んだ Secure Boot とドライバの罠 をまとめます。
数値は手元1台の実測です。IP・ホスト名はプレースホルダに置き換えています。
TL;DR
- TensorFold 1.1.xのネイティブCUDAは、当初 0.6.6(Python実装)の3〜10倍遅いprefillだった。
- 1.1.4 で27Bのcold prefillが最大5倍改善し、1.1.6 で80kが536秒→83.4秒まで短縮。
- ただし0.6.6(53.9秒)にはまだ及ばず、decodeは1.1.6で0.6.6と同等まで回復。
- 途中、Secure Boot有効のDGX SparkでDKMSビルドのドライバがロードできず、GPUが使えなくなった。
- 正解は Canonicalの署名済みモジュール。DKMSは使わない。615系はCDMMの変更に注意。
1. 何を測ったか
ネイティブCUDAサーバ(tensorfold-native)で、27B(MLX-4bit + DFlash2)を同一条件で測りました。
- ストリーミングでTTFT(=prefill)とdecodeを分離
- 各プロンプトに固有の接頭辞を付け、プロンプトキャッシュのヒットを排除
-
--kv-cache fp8、--parallel 8、context 262144
比較対象は 0.6.6(Python実装、Docker)。
2. バージョン別の推移
prefill(cold、TTFT)
| 長さ | 0.6.6 | 1.1.1 | 1.1.2 | 1.1.6 |
|---|---|---|---|---|
| 9k | 4.4秒 | 14.7秒 | 14.8秒 | 7.3秒 |
| 32k | 約20秒 | 98.3秒 | 99.5秒 | 28.1秒 |
| 64k | 約43秒 | 351.4秒 | — | 63.4秒 |
| 80k | 53.9秒 | 536.0秒 | — | 83.4秒 |
decode
| 長さ | 0.6.6 | 1.1.1 | 1.1.6 |
|---|---|---|---|
| 9k | 49.7 | 39.2 | 48.8 |
| 32k | — | 30.2 | 42.2 |
| 80k | 39.4 | 23.0 | 32.5 |
| 1.1.1の時点では「prefillが10倍遅い・decodeも遅い」状態で、実用になりませんでした。 |
3. 何が変わったのか
1.1.4: プロンプトのレシピ変更
リリースノートに「Qwen3.8-27BのcoldプロンプトがCUDAで最大5倍高速化」とあります。
On a GB10, cold prefill goes from 834 to 1,281 tokens/s at 2k (+54%), 612 to 1,266 at 8k (+107%), 326 to 1,165 at 32k (+258%) …
手元の実測(1.1.2→1.1.6)でも、32kが99.5秒→28.1秒(3.5倍)、80kが536秒→83.4秒(6.4倍)と一致します。
1.1.6: 同時リクエストのprefill共有
同時に到着したリクエストが同じ新しいプレフィックスをそれぞれprefillしなくなりました。GB10で8チャット×28kの最後の最初のトークンが201秒→31秒になります。
長文を同時に投げたときの「全員分を読むまで沈黙する」問題への対策です。
それでも0.6.6に届かない理由
- 0.6.6は
--prefill-fp8でFP8のプロンプトmatmulを使える(ネイティブではこのフラグ自体が拒否される) - 0.6.6は長年の最適化が入っている
1.1.6は 0.6.6の1.5〜1.6倍遅いところまで来ましたが、単発の速度ではまだ負けます。FNに切り替えると、この差はQSAとFP4 QADで逆転します(別記事参照)。
4. ドライバの壁:Secure BootとDKMS
ここからが本題です。1.1.xのネイティブCUDAは CUDA 13.3(ドライバ610.43以降) を要求しますが、DGX Sparkの公式ドライバは 580.178.04(DGX OS 7.6.0)です。互換モードで動かしていましたが、性能が出ない一因とも考え、615系への更新を試しました。
起きたこと
-
apt install nvidia-driver-615-openで615を導入 - 再起動すると
nvidia-smiがGPUと通信できない - カーネルログに:
Loading of module with unavailable key is rejected
原因
- DGX Sparkは Secure Boot が有効
- 615はUbuntuのportsリポジトリのパッケージで、DKMSがローカルビルドする
- DKMSはローカルのMOKキーで署名するが、そのキーがファームウェアに未登録 → ロード拒否
NVIDIAフォーラムでも「DGX SparkはSecure Boot有効。自分のモジュールをロードするにはMOKキーを先に登録する必要がある」と回答されています。
正しい方法
DGX Sparkでは DKMSを使わず、Canonicalの署名済みモジュールを使います。
sudo apt install nvidia-driver-615-open \
linux-modules-nvidia-615-open-nvidia-hwe-24.04
linux-modules-nvidia-*-nvidia-hwe-24.04 はDGX Sparkの linux-nvidia カーネル向けにCanonicalが署名したパッケージで、MOK登録もSecure Boot無効化も不要です。
復旧手順(580に戻す)
sudo apt install linux-modules-nvidia-580-open-nvidia-hwe-24.04
sudo apt remove --purge nvidia-dkms-580-open nvidia-dkms-615-open
sudo dpkg --configure -a
sudo update-initramfs -u
sudo reboot
modinfo nvidia で signer: Canonical Ltd. Kernel Module Signing が出れば成功です。
5. 615系のもう一つの罠:CDMM
615系はメモリ管理が変わります。
R615 defaults to CDMM (Coherent Driver-based Memory Management)
CDMMでは safetensorsのmmapコピーが約5MB/sまで低下する既知の問題があり、vLLMが「チェックポイント読み込み0%」でハングしたように見えます。
回避策はドライバオプションです。
options nvidia NVreg_CoherentGPUMemoryMode=numa
options nvidia-uvm uvm_disable_sam_migration=false
もっとも、DGX OS 7.6.0の公式ドライバは580で、615はNVIDIA未検証です。1.1.xの検証のためだけに入れる価値は低く、筆者は580に戻しました。
6. 現在の構成
| 項目 | 内容 |
|---|---|
| ドライバ | 580.178.04(Canonical署名済みモジュール) |
| エンジン | TensorFold 1.1.6(systemdで常設) |
| モデル | Flash Next FP4 QAD(Miaレシピ) |
| 旧構成 | TensorFold 0.6.6(Docker、待避) |
| 1.1.xがさらに成熟すれば、ネイティブCUDA+VADの組み合わせで0.6.6を超える可能性があります。ドライバが610系に上がり、互換モードが不要になれば、prefillの差も縮まるかもしれません。 |
まとめ
- TensorFold 1.1.xのネイティブCUDAは、1.1.4でprefillが最大5倍改善し、1.1.6で80kが536秒→83.4秒になった
- それでも0.6.6(53.9秒)には届かず、単発の速度ではPython実装が上
- DGX Sparkでドライバを更新するときは DKMSを使わずCanonical署名済みモジュール
- 615系はCDMMでmmapが遅くなる罠がある
- 公式サポートは580。無理に上げず、エンジン側の成熟を待つのが安全
数値は筆者環境での実測です。ドライバ・エンジンのバージョン・チェックポイントで変動します。