【CUDA】update-alternativesで複数バージョンを共存管理!「libcudart.so.XX not found」エラー解決法

問題の概要:CUDAバージョン競合によるエラー

AI開発、特に深層学習のモデル訓練を行う際、異なるフレームワークやプロジェクトが要求するCUDAバージョンが異なることに悩まされることはありませんか?例えば、あるプロジェクトではPyTorchがCUDA 11.8を要求し、別のプロジェクトではTensorFlowがCUDA 12.1を要求するといった状況です。このような環境で、以下のような典型的なエラーメッセージに遭遇した経験があるでしょう。

ImportError: libcudart.so.11.0: cannot open shared object file: No such file or directory

または、nvccコマンド実行時にバージョン不一致が発生します。

nvcc fatal : Unsupported gpu architecture 'compute_86' # CUDAバージョンとGPUアーキテクチャの不一致例

これらのエラーの根本原因は、システムのデフォルトCUDAバージョンと、実行したいプログラムが要求するバージョンが一致していないことです。単純にシンボリックリンクを張り替える方法は一時的で、他のプロジェクトを壊すリスクがあります。本記事では、Debian/Ubuntu系ディストリビューションのupdate-alternativesコマンドを用いた、安全で柔軟な複数CUDAバージョン共存管理の方法を詳しく解説します。

原因の解説:なぜバージョン競合が起こるのか

CUDAツールキットは、主に以下のコンポーネントから構成され、それぞれがバージョン依存関係を持っています。

  • ドライバ (nvidia-driver): GPUハードウェアを制御。上位互換性があることが多い。
  • ランタイムライブラリ (libcudart.so): 実行時に必要なコアライブラリ。バージョン一致が厳密に要求される。
  • コンパイラ (nvcc): CUDAコードをコンパイル。生成するコードの互換性はバージョンに依存。
  • 開発ライブラリ (cuBLAS, cuDNNなど): 高速化ライブラリ。CUDAバージョンと組み合わせが決まっている。

問題は、システムの/usr/local/cuda シンボリックリンクが単一のバージョンを指すように設定されている点です。このリンクを直接変更すると、そのバージョンに依存してビルドされた全てのアプリケーションに影響が及び、冒頭のエラーを引き起こす原因となります。update-alternativesは、このシステム全体のデフォルト設定を一元的に管理し、ユーザーやスクリプトが簡単に切り替えられる仕組みを提供します。

解決方法:update-alternativesによる体系的管理

ここでは、CUDA 11.8とCUDA 12.1がそれぞれ/usr/local/cuda-11.8/usr/local/cuda-12.1にインストールされていることを前提に、手順を説明します。

ステップ1:既存のシンボリックリンクの確認とバックアップ

まず、現在のシステム設定を確認します。

ls -l /usr/local/cuda
# 例: lrwxrwxrwx 1 root root 20 Apr 1 10:00 /usr/local/cuda -> /usr/local/cuda-12.1

既存の/usr/local/cudaリンクはupdate-alternativesに管理を移行するため、必要に応じてバックアップを取ります。

sudo mv /usr/local/cuda /usr/local/cuda.backup

ステップ2:update-alternativesシステムの初期化と登録

update-alternativesの「cuda」グループを作成し、各バージョンを登録します。優先度(プライオリティ)は数値が大きい方がデフォルトとして選択されやすいので、新しいバージョンに高い値を設定するのが一般的です。

# CUDA 11.8を登録 (優先度 118)
sudo update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-11.8 118

# CUDA 12.1を登録 (優先度 121)
sudo update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-12.1 121

ステップ3:使用するCUDAバージョンの切り替え

登録したバージョン一覧を確認します。

sudo update-alternatives --config cuda

このコマンドを実行すると、以下のような対話型メニューが表示されます。

There are 2 choices for the alternative cuda (providing /usr/local/cuda).

  Selection    Path                    Priority   Status
------------------------------------------------------------
* 0            /usr/local/cuda-12.1    121       auto mode
  1            /usr/local/cuda-11.8    118       manual mode
  2            /usr/local/cuda-12.1    121       manual mode

Press <enter> to keep the current choice[*], or type selection number:

ここで、切り替えたいバージョンの番号(例:CUDA 11.8を使いたい場合は1)を入力し、Enterキーを押します。

ステップ4:切り替えの確認

切り替えが正しく行われたか、以下のコマンドで確認します。

# シンボリックリンクの確認
ls -l /usr/local/cuda
# 例(11.8に切り替えた場合): lrwxrwxrwx 1 root root 20 May 20 14:30 /usr/local/cuda -> /usr/local/cuda-11.8

# nvccコンパイラのバージョン確認
nvcc --version
# 出力の最後の行を確認: "Cuda compilation tools, release 11.8, V11.8.89"

# ランタイムバージョンの確認(Pythonから)
python3 -c "import torch; print(torch.version.cuda)"  # PyTorchの場合

コード例・コマンド例:よくある操作と自動化

対話型メニューを使わない切り替え

シェルスクリプト内などで自動的に切り替えたい場合は、--setオプションを使用します。

# CUDA 11.8に設定
sudo update-alternatives --set cuda /usr/local/cuda-11.8

# CUDA 12.1に設定
sudo update-alternatives --set cuda /usr/local/cuda-12.1

登録の解除

アンインストールしたCUDAバージョンを管理対象から外すには、--removeオプションを使います。

sudo update-alternatives --remove cuda /usr/local/cuda-10.2

環境変数PATHの更新(オプションだが推奨)

update-alternatives/usr/local/cudaの指す先を変えても、シェルのキャッシュによって古いパスが参照されることがあります。特にターミナルを開きっぱなしにしている場合に発生します。変更後は、関連するパスを明示的に環境変数に設定するか、新しいターミナルセッションを開始しましょう。.bashrc.zshrcに以下の設定を追加しておくことを強くお勧めします。

# ~/.bashrc または ~/.zshrc に追加
export CUDA_HOME=/usr/local/cuda
export PATH=${CUDA_HOME}/bin:${PATH}
export LD_LIBRARY_PATH=${CUDA_HOME}/lib64:${LD_LIBRARY_PATH}

設定を反映させます。

source ~/.bashrc  # または source ~/.zshrc

まとめ・補足情報

update-alternativesを使ったCUDAバージョン管理は、システムのデフォルト設定を一元的かつ安全に切り替えるための強力な方法です。これにより、プロジェクトごとに必要なCUDAバージョンを柔軟に選択できるようになり、「ライブラリが見つからない」エラーに悩まされる時間を大幅に削減できます。

重要な補足点:

  1. cuDNNなどの依存ライブラリ: CUDA自体の切り替えだけでは不十分な場合があります。cuDNNやTensorRTなどの関連ライブラリも、使用するCUDAバージョンと互換性のあるものを別途インストール/配置し、そのパスをLD_LIBRARY_PATHなどで適切に設定する必要があります。
  2. 仮想環境の活用: Pythonプロジェクトレベルでの依存関係管理には、condavenvによる仮想環境が最も効果的です。CondaはCUDAランタイムやcuDNNも環境内に独立してインストールできるため、システムのCUDAに依存しない完全に分離された環境を構築できます。update-alternativesは、システム全体で使うツール(nvcc等)や、仮想環境を使わないグローバルなライブラリのバージョン管理に適しています。
  3. コンテナ技術の選択肢: DockerやNVIDIA Container Toolkitを利用すれば、プロジェクトに最適化されたCUDA環境全体をコンテナイメージとしてパッケージ化できます。再現性の面ではこれが最も優れた方法です。

状況に応じて、update-alternatives、仮想環境、コンテナ技術を組み合わせることで、多様なCUDAバージョンを要求するAI開発プロジェクトをスムーズに進めることができるでしょう。

この記事は役に立ちましたか?