GB200 上で Evo2 を実行する際の cuFFT エラーの修正
巷で話題の evo2_flash を使って Evo2 を vLLM + GB200 で動かそうと思ったら、CUFFT_INTERNAL_ERROR で止まりました。cuFFT のバージョンを変更すると CUDA 12.9・13.0 の両方で動作したので、環境と手順を記録します。
環境と症状
2026 年 11 月 2 日、GB200 / ARM64、driver 580.178.04 で確認しました。vLLM の公式イメージを Apptainer の SIF に変換し、evo2-flash を追加しています。モデルは Evo2-7B、MTP なしです。
| 項目 | CUDA 12.9 版 | CUDA 13.0 版 |
|---|---|---|
| Image のタグ | v0.26.0-cu129-ubuntu2404 |
v0.26.0-ubuntu2404 |
| PyTorch | 2.11.0+cu129 | 2.11.0+cu130 |
| cuFFT (変更前) | 11.4.1.4 | 12.0.0.61 |
| cuFFT (変更後) | 11.4.0.6 | 12.0.0.15 |
どちらも vllm/vllm-openai の linux/arm64 版です。evo2_flash の README は CUDA 12.9 wheel を指定しています。
CUDA 13.0 版イメージの cuFFT 12.0.0.61 は、PyTorch → cuda-toolkit==13.0.2 → nvidia-cufft==12.0.0.61.* という依存関係で入ります。CUDA Toolkit 13.0.0 の cuFFT は 12.0.0.15、13.0.2 は 12.0.0.61 で、同じ CUDA 13.0 系でも付属する版が異なります。
Evo2 の重みは読み込めますが、Hyena の convolution 内の torch.fft.rfft で落ちます。モデルを使わず、以下を repro_fft.py として実行しても再現しました。
import torch
x = torch.randn(128, 64, device="cuda", dtype=torch.float32).T.contiguous()
torch.fft.rfft(x, n=256)
torch.cuda.synchronize()
RuntimeError: cuFFT error: CUFFT_INTERNAL_ERROR
連続配置・非連続配置、配列長を変えた 6 ケースすべてで失敗しました。Evo2 の実行では、その後に CUDA error: unspecified launch failure も出ています。
cuFFT のバージョン変更
CUDA 12.9 側では、CUDA Toolkit 12.9.0 に含まれる cuFFT 11.4.0.6 を使いました。公式 ARM64 wheel を別ディレクトリに取得します。
python3 -m pip install --no-deps --only-binary=:all: \
--target ./cufft-11.4.0.6 nvidia-cufft-cu12==11.4.0.6
これを、コンテナ内の PyTorch wheel が持つ cuFFT の配置先へ読み取り専用で bind します。普段の apptainer exec に加える指定は次の形です。
CUFFT=/absolute/path/to/cufft-11.4.0.6/nvidia/cufft/lib/libcufft.so.11
TARGET=/usr/local/lib/python3.12/dist-packages/nvidia/cufft/lib/libcufft.so.11
apptainer exec --cleanenv --nv \
--bind "$CUFFT:$TARGET:ro" \
vllm-0.26.0-cu129-arm64.sif python3 repro_fft.py
vllm-0.26.0-cu129-arm64.sif は上の CUDA 12.9 版公式イメージから作った SIF の名前です。CUFFT は手元のライブラリに合わせて変更します。
CUDA 13.0 側では、cuFFT 12.0.0.15 の ARM64 wheel に含まれる libcufft.so.12 を、PyTorch wheel の cuFFT 配置先 /usr/local/lib/python3.12/dist-packages/nvidia/cu13/lib/libcufft.so.12 へ同様に bind しました。
今回の PyTorch wheel では、別の配置先を LD_LIBRARY_PATH の先頭に追加しても元のライブラリが読み込まれたため、実配置先へ直接 bind しています。
各環境でイメージ自体、PyTorch、driver、ほかの CUDA ライブラリ、モデルの FFT の精度設定は変更していません。
確認できたこと
差し替え後は両環境で FFT の 6 ケースがすべて通りました。float64 を基準にした float32 FFT の相対最大誤差は、試した配列長で最大 3.9e-7 程度です。
evo2_flash に付属する精度テストでは、平均 loss は CUDA 12.9 側が 0.347456、13.0 側が 0.347386 で、どちらも公開値 0.3476563 との差が許容差 0.001 以内でした。その後、両方で 3,000 bp の入力から 1,024 bp を生成するところまで動きました。
確認したのは上の GB200・driver・イメージの組み合わせだけです。cuFFT 内部のどの処理が失敗しているかは未確認です (ソースコードが公開されていないため)。