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

問題の概要:CUDAバージョン不一致によるエラー

AI開発、特に深層学習のモデルトレーニングや推論を行う際、CUDAはGPUを活用する上で不可欠なツールキットです。しかし、異なるプロジェクトやフレームワーク(TensorFlow, PyTorch等)が要求するCUDAバージョンが異なる場合、システムに一つのバージョンしかインストールされていないと、以下のような頻出エラーに遭遇します。

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

または、nvcc --versionnvidia-smi で表示されるCUDAバージョンが異なり、混乱することがあります。

$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Wed_Sep_21_10:33:58_PDT_2022
Cuda compilation tools, release 11.8, V11.8.89

$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.105.17   Driver Version: 525.105.17   CUDA Version: 12.0     |
+-----------------------------------------------------------------------------+

このような状況では、システムに複数のCUDAツールキット(例: CUDA 11.8 と CUDA 12.1)をインストールし、プロジェクトやシェルセッションごとに柔軟に切り替えられる環境が理想的です。本記事では、Debian/Ubuntu系ディストリビューションの標準ツール update-alternatives を用いて、この課題をスマートに解決する方法を解説します。

原因の解説:シンボリックリンクとパスの管理

エラーの根本原因は、システムの「デフォルト」として設定されているCUDAバージョンと、アプリケーションが求めているバージョンとの不一致です。Linuxでは、/usr/local/cuda というシンボリックリンクが、デフォルトで使用するCUDAインストールディレクトリを指しています。

手動でこのリンクを張り替えることも可能ですが、複数バージョンを管理するには煩雑でミスの元です。update-alternatives は、この「デフォルトとして指し示すシンボリックリンク」をグループ(「スレーブ」を含む)として体系的に管理するためのツールです。これにより、一つのコマンドで、nvcc, cuda-gdb, 主要なライブラリへのパスなど、関連する全てのシンボリックリンクを一括で切り替えることができます。

解決方法:update-alternativesを使ったCUDAバージョン管理

ここでは、CUDA 11.8 と CUDA 12.1 がそれぞれ /usr/local/cuda-11.8/usr/local/cuda-12.1 にインストールされていることを前提に、ステップバイステップで設定します。

ステップ1: 既存の手動シンボリックリンクを削除

まず、既に存在するかもしれない /usr/local/cuda リンクを削除します。

sudo rm -f /usr/local/cuda

ステップ2: alternativesグループを作成し、各バージョンを登録

update-alternatives の「cuda」グループを作成し、インストール済みの各バージョンを登録します。優先度(数値)は、バージョン番号が高いほど大きな値を設定するのが一般的です。

CUDA 11.8を登録:

sudo update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-11.8 118 
--slave /usr/local/cuda/bin/nvcc nvcc /usr/local/cuda-11.8/bin/nvcc 
--slave /usr/local/cuda/bin/cuda-gdb cuda-gdb /usr/local/cuda-11.8/bin/cuda-gdb

CUDA 12.1を登録:

sudo update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-12.1 121 
--slave /usr/local/cuda/bin/nvcc nvcc /usr/local/cuda-12.1/bin/nvcc 
--slave /usr/local/cuda/bin/cuda-gdb cuda-gdb /usr/local/cuda-12.1/bin/cuda-gdb

このコマンドは以下のように動作します:

  • --install /usr/local/cuda cuda /usr/local/cuda-11.8 118: マスターリンク /usr/local/cuda を「cuda」グループとして管理し、その選択肢の一つとして /usr/local/cuda-11.8 を優先度118で登録。
  • --slave ...: マスターリンクが切り替わった時に、連動して切り替わるスレーブリンクを指定。ここではコンパイラ(nvcc)とデバッガ(cuda-gdb)を設定。

ステップ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:

使用したいバージョンの番号(ここでは例として1)を入力し、Enterキーを押します。

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

切り替えが正しく行われたか、nvcc --version/usr/local/cuda リンクの指す先を確認します。

$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Wed_Sep_21_10:33:58_PDT_2022
Cuda compilation tools, release 11.8, V11.8.89  # CUDA 11.8に切り替わった!

$ ls -l /usr/local/cuda
lrwxrwxrwx 1 root root 22 Apr 20 10:00 /usr/local/cuda -> /usr/local/cuda-11.8/

コード例・コマンド例:よく使う操作と応用

現在の設定を確認する

update-alternatives --display cuda

登録されている全選択肢と、現在の設定状態が詳細に表示されます。

手動で特定のバージョンに設定する(非対話的)

シェルスクリプト内などで使いたい場合。

sudo update-alternatives --set cuda /usr/local/cuda-12.1

登録されているCUDAバージョンを一覧表示する

update-alternatives --list cuda

環境変数PATHへの追加(必須ステップ)

update-alternatives でリンクを切り替えても、シェルが実行ファイルを探すパスに /usr/local/cuda/bin が含まれている必要があります。通常、~/.bashrc~/.zshrc に以下を追加します。

export PATH=/usr/local/cuda/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

変更を反映するには、設定ファイルを再読み込みするか、新しいターミナルを起動します。

source ~/.bashrc

より多くのスレーブを登録する例

主要なライブラリのリンクも管理したい場合は、登録コマンドを拡張します。

sudo update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-11.8 118 
--slave /usr/local/cuda/bin/nvcc nvcc /usr/local/cuda-11.8/bin/nvcc 
--slave /usr/local/cuda/bin/cuda-gdb cuda-gdb /usr/local/cuda-11.8/bin/cuda-gdb 
--slave /usr/local/cuda/include/cuda.h cuda.h /usr/local/cuda-11.8/include/cuda.h 
--slave /usr/local/cuda/lib64/libcudart.so libcudart.so /usr/local/cuda-11.8/lib64/libcudart.so

まとめ・補足情報

update-alternatives を用いることで、複数バージョンのCUDAをシステムに安全に共存させ、必要に応じて素早く切り替える環境を構築できます。これにより、プロジェクトごとのCUDAバージョン要求に対応する手間が大幅に軽減され、「ライブラリが見つからない」エラーに悩まされる時間を減らすことができます。

重要な補足点:

  1. NVIDIA Driverの互換性: インストールするCUDAツールキットのバージョンは、システムにインストールされているNVIDIA Driverのバージョンと互換性がある必要があります。ドライバが古すぎると新しいCUDAは動作しません。nvidia-smiで表示される「Driver Version」と、NVIDIAの公式ドキュメントで互換性を確認してください。
  2. Python環境との連携: この方法はシステムレベルのCUDAツールキットを管理します。PyTorchやTensorFlowなどのPythonパッケージは、pipやcondaでインストールする際に特定のCUDAバージョン用のビルドを選択する必要があります(例: torch==2.0.1+cu118)。システムのCUDAとPythonライブラリのCUDAバージョンは一致させることが成功のカギです。
  3. conda環境内でのCUDA: condaは非常に強力な環境分離ツールです。conda環境内で conda install cudatoolkit=11.8 のようにインストールされたCUDAは、その環境内に閉じられ、システムのCUDA設定に影響を受けません。プロジェクトごとにconda環境を分ける方法も併せて検討することをお勧めします。

update-alternatives はCUDA以外にも、gcc, java, python (システムPython) など、複数バージョンを管理するあらゆるソフトウェアで応用可能な汎用的な技術です。この機会に習得し、開発環境の管理をよりスマートに行いましょう。

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