ONNX RuntimeのCUDAエラー「libcublasLt.so.11: cannot open shared object file」を解決する
こんにちは!
ONNX Runtimeを使用していると、以下のようなエラーに遭遇することがあります
[E:onnxruntime:Default, provider_bridge_ort.cc:1744 TryGetProviderInfo_CUDA]
Failed to load library libonnxruntime_providers_cuda.so with error:
libcublasLt.so.11: cannot open shared object file: No such file or directory
[W:onnxruntime:Default, onnxruntime_pybind_state.cc:870 CreateExecutionProviderInstance]
Failed to create CUDAExecutionProvider.
このエラーは、GPUアクセラレーションが使えずCPUフォールバックで動作している状態を示しています。本記事では、この問題の原因調査から解決までのプロセスを詳しく解説します。
問題の症状
エラーが発生する状況
- ONNX Runtimeでモデルを読み込む際に毎回警告が表示される
- 画像処理や推論処理で処理時間が異常に長い(例:数秒以上)
onnxruntime-gpu
をインストールしているのにGPUが使われない- プログラムを実行するたびに同じ警告が繰り返し表示される
パフォーマンスへの影響
# CPU実行時(エラー発生時)
Model A warmup time: 5.071s
Model B warmup time: 0.029s
# GPU実行時(正常時)の期待値
Model A warmup time: 0.5-1.0s # 5-10倍高速化
Model B warmup time: 0.005-0.01s # 3-5倍高速化
原因調査のプロセス
ステップ1: 環境の現状確認
まずは、ONNX RuntimeがGPUを認識できているか確認しましょう
# インストール済みパッケージの確認
pip list | grep onnx
出力例
onnx 1.16.1
onnxruntime-gpu 1.18.0
# GPUの認識状況を確認
python -c "import onnxruntime; print(onnxruntime.get_device()); print(onnxruntime.get_available_providers())"
出力例
GPU
['TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider']
ステップ2: 問題の分析
この時点で興味深い状況が判明しました
onnxruntime.get_device()
→ GPU(認識されている)- CUDAExecutionProviderが利用可能リストに含まれている
- しかし実行時にはエラーが発生してCPUフォールバック
これは、ONNX Runtime自体はGPUを認識しているが、実行時に必要なCUDAライブラリが不足している状況を示しています。
ステップ3: バージョン不整合の特定
# システムのCUDAバージョン確認
nvcc --version
ls -la /usr/local/ | grep cuda
調査の結果
- システムにはCUDA 12がインストール済み
- ONNX RuntimeがCUDA 11のライブラリ(libcublasLt.so.11)を探している
ということでバージョン不整合が原因と特定できましたー
解決方法の検討
方法1: シンボリックリンク(リスクの評価)
当初、シンボリックリンクで解決することを検討しました
# CUDA 12のライブラリをCUDA 11として認識させる
sudo ln -s /lib/x86_64-linux-gnu/libcublasLt.so.12 /lib/x86_64-linux-gnu/libcublasLt.so.11
ただし、こんな付け焼刃でいいのか、リスクを考えてみます
- メリット:手軽で追加インストール不要
- リスク:ABI互換性の問題、他のCUDA 11依存アプリへの影響
そこで、しらべてみると、
onnxruntime-gpu 1.18.0
は既にCUDA 12対応版であることが判明しました。
つまり、シンボリックリンクは同じCUDA 12系統内での対応となるため、リスクは小さいと判断できました
方法2: 完全な解決策の発見
ただし、このシンボリックリンクだけでは解決しなかったため、さらに調査を進めた結果、cuDNNの不足が判明しました。
ということで、最終的な解決方法です
★最終的な解決方法
ステップ1: cuDNNのインストール
conda install -c conda-forge cudnn=8.9.7.29 -y
このステップが最も重要でcuDNNがないとCUDAExecutionProviderが初期化できません。
ステップ2: シンボリックリンクの作成
# libcublasLt.so.11のシンボリックリンク作成
sudo ln -sf /usr/local/cuda-12/lib64/libcublasLt.so.12 \
/usr/lib/x86_64-linux-gnu/libcublasLt.so.11
# libcublas.so.11のシンボリックリンク作成
sudo ln -sf /usr/local/cuda-12/lib64/libcublas.so.12 \
/usr/lib/x86_64-linux-gnu/libcublas.so.11
# ライブラリキャッシュの更新
sudo ldconfig
ステップ3: ONNX Runtimeの再インストール
# 既存のパッケージをアンインストール
pip uninstall onnxruntime onnxruntime-gpu -y
# GPU版をインストール
pip install onnxruntime-gpu==1.22.0
再インストール時に最新版がインストールされる可能性があるため、バージョン固定が推奨です
なぜシンボリックリンクだけでは不十分だったか
初回の試みでシンボリックリンクだけでは解決しなかった理由
- libcublasLt.so.11 → シンボリックリンクで解決した
- libcudnn.so.8 → 不足していた
- その他のCUDA関連ライブラリ → 不完全
ということで、cuDNNのインストールが必須だったことが判明しました。
動作確認
GPUが使用されているか確認
import onnxruntime as ort
# テスト用のセッション作成
session = ort.InferenceSession(
"your_model.onnx",
providers=['CUDAExecutionProvider', 'CPUExecutionProvider']
)
# 実際に使用されているプロバイダーを確認
print("Active providers:", session.get_providers())
# 成功時の出力: ['CUDAExecutionProvider', 'CPUExecutionProvider']
# 失敗時の出力: ['CPUExecutionProvider']
パフォーマンステスト
import time
import onnxruntime as ort
import numpy as np
# モデル読み込み
session = ort.InferenceSession("model.onnx")
# ダミー入力データ
dummy_input = np.random.randn(1, 3, 224, 224).astype(np.float32)
# ウォームアップ
for _ in range(5):
session.run(None, {"input": dummy_input})
# 実測
start = time.time()
for _ in range(100):
session.run(None, {"input": dummy_input})
print(f"Average inference time: {(time.time() - start) / 100:.4f}s")
トラブルシューティング
デバッグ用チェックリスト
# 1. ONNX Runtimeのバージョン確認
python -c "import onnxruntime; print(onnxruntime.__version__)"
# 2. GPUの認識確認
python -c "import onnxruntime; print(onnxruntime.get_device())"
# 3. 利用可能なプロバイダー確認
python -c "import onnxruntime; print(onnxruntime.get_available_providers())"
# 4. CUDAのインストール確認
nvcc --version
ls -la /usr/local/ | grep cuda
# 5. 必要なライブラリの存在確認
ls -la /usr/lib/x86_64-linux-gnu/ | grep -E "libcublas|libcudnn"
# 6. 依存関係の確認
ldd $(python -c "import onnxruntime; print(onnxruntime.__file__)") | grep "not found"
完全な環境構築手順
requirements.txt
onnxruntime-gpu==1.22.0
setup.sh
#!/bin/bash
echo "=== ONNX Runtime GPU Setup ==="
# 0. 現状確認
echo "Current environment check:"
python -c "import onnxruntime; print('Version:', onnxruntime.__version__); print('Device:', onnxruntime.get_device())" 2>/dev/null || echo "ONNX Runtime not installed"
# 1. cuDNN のインストール
echo "Installing cuDNN..."
conda install -c conda-forge cudnn=8.9.7.29 -y
# 2. シンボリックリンクの作成
echo "Creating symbolic links..."
sudo ln -sf /usr/local/cuda-12/lib64/libcublasLt.so.12 \
/usr/lib/x86_64-linux-gnu/libcublasLt.so.11
sudo ln -sf /usr/local/cuda-12/lib64/libcublas.so.12 \
/usr/lib/x86_64-linux-gnu/libcublas.so.11
# 3. ライブラリキャッシュの更新
echo "Updating library cache..."
sudo ldconfig
# 4. ONNX Runtime のインストール
echo "Installing ONNX Runtime GPU..."
pip uninstall onnxruntime onnxruntime-gpu -y
pip install -r requirements.txt
# 5. 動作確認
echo "Verification:"
python -c "
import onnxruntime as ort
print('ONNX Runtime version:', ort.__version__)
print('Device:', ort.get_device())
print('Available providers:', ort.get_available_providers())
"
echo "Setup complete!"
まとめ
以下のような手順で解決にいたりました
- 初期診断:GPUは認識されているが実行時にエラー
- 原因特定:CUDA 11/12のバージョン不整合とcuDNNの不足
- 解決策:cuDNNインストール + シンボリックリンク + 再インストール
重要なのは、シンボリックリンクだけでは不十分で、cuDNNのインストールが必須だったという点ですね。この3ステップを正しい順序で実行することで、GPUアクセラレーションを有効化し、推論処理を2〜10倍高速化できます。
とくにCPUフォールバックを見逃すと、せっかくのGPUパワーを活かせないので、この警告がでたら、しっかり対応することが必要そうです