←Back to Blog

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 内部のどの処理が失敗しているかは未確認です (ソースコードが公開されていないため)。