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

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

AI開発、特に深層学習フレームワーク(PyTorch, TensorFlowなど)を使用していると、異なるプロジェクトで異なるCUDAバージョンが必要になる場面が多々あります。例えば、あるプロジェクトではPyTorch 1.x系を使うためにCUDA 10.2が必要で、別のプロジェクトでは最新機能を試すためにCUDA 11.xが必要になるケースです。

このような状況で、単一のCUDAバージョンしかシステムにインストールしていない、またはデフォルトのシンボリックリンクが意図しないバージョンを指していると、以下のような典型的なエラーが発生します。

ImportError: libcudart.so.10.2: 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-2020 NVIDIA Corporation
Built on Mon_Oct_12_20:09:46_PDT_2020
Cuda compilation tools, release 11.1, V11.1.105

$ nvidia-smi
Mon Jan 1 12:00:00 2024
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.182.03   Driver Version: 470.182.03   CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+
...

これらのエラーや不一致は、システムのデフォルトCUDAツールキットへのパス(/usr/local/cuda)が、あなたが現在必要としているバージョンを指していないために発生します。手動でシンボリックリンクを張り替える方法もありますが、管理が煩雑でミスの元です。そこで、Debian/Ubuntu系ディストリビューションの強力なツール update-alternatives を活用した、クリーンな管理方法をご紹介します。

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

CUDA Toolkitをインストールすると、主に以下のディレクトリにファイルが配置されます。

  • /usr/local/cuda-<バージョン番号> (例: /usr/local/cuda-11.1, /usr/local/cuda-10.2)
  • そして、汎用パスである /usr/local/cuda は、実際にはいずれかのバージョン特定ディレクトリを指す「シンボリックリンク」として作成されます。

多くのインストーラーやスクリプトは、この /usr/local/cuda を参照してコンパイルや実行を行います。問題は、このシンボリックリンクがシステム全体で「1つ」しか存在せず、最後にインストールしたCUDAバージョン、または手動でリンクを貼り替えたバージョンに固定されてしまう点です。

update-alternatives は、この「システムのデフォルトとして設定されるシンボリックリンク」を一元的に管理するシステムです。複数の候補(今回は複数のCUDAバージョン)を登録しておき、ユーザーが必要に応じてグローバルなデフォルトを切り替えることを可能にします。これにより、環境変数をいちいち書き換えたり、危険な手動リンク編集を行ったりする必要がなくなります。

解決方法:update-alternativesを使ったステップバイステップ管理

ここでは、CUDA 10.2とCUDA 11.1が既に /usr/local/cuda-10.2/usr/local/cuda-11.1 にインストールされていることを前提とします。インストール方法はNVIDIA公式サイトを参照してください。

ステップ1:既存の /usr/local/cuda リンクを確認・削除

まず、現在の状況を確認します。

ls -l /usr/local/cuda

出力が /usr/local/cuda -> /usr/local/cuda-11.1 のようになっていれば、それは単純なシンボリックリンクです。これを後で update-alternatives で管理するために、一旦削除します(ファイル自体は消えません)。

sudo rm /usr/local/cuda

ステップ2:update-alternatives グループの作成と候補の登録

update-alternatives の「グループ」を作成し、そのグループに管理対象となる各CUDAバージョンを「候補」として登録します。グループ名は cuda とします。

まず、CUDA 10.2を登録します。優先度(数字)はバージョン番号が大きいほど高くするのが一般的です(ここでは11.1を優先させたいので110、10.2は102とします)。

sudo update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-10.2 102

次に、CUDA 11.1を登録します。

sudo update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-11.1 110

コマンドの構成:
--install [管理対象のリンクパス] [グループ名] [候補の実体パス] [優先度]

ステップ3:登録の確認とバージョン切り替え

登録された候補を一覧表示して確認します。

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-11.1     110       auto mode
  1            /usr/local/cuda-10.2     102       manual mode
  2            /usr/local/cuda-11.1     110       manual mode

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

ここで、数字を入力してEnterキーを押すだけで、システム全体のデフォルトCUDAバージョンを切り替えることができます。例えば「1」を入力すると、/usr/local/cuda はCUDA 10.2を指すようになります。

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

切り替え後、必ず以下のコマンドで確認しましょう。

ls -l /usr/local/cuda
nvcc --version

ls -l の出力が選択したバージョンのディレクトリを指していること、nvcc --version が選択したバージョンを表示することを確認してください。

コード例・コマンド例:よく使う操作一覧

登録済み候補の一覧表示

sudo update-alternatives --display cuda

現在の選択を「自動モード」に戻す

自動モードでは、最も優先度の高い候補が自動的に選択されます。

sudo update-alternatives --auto cuda

候補の削除

アンインストールしたCUDAバージョンを管理リストから削除します。

sudo update-alternatives --remove cuda /usr/local/cuda-9.0 # 例

環境変数への追加(~/.bashrcなど)

update-alternatives で切り替えた /usr/local/cuda をPATHなどに追加する設定は従来通りです。

# ~/.bashrc に追加する例
export PATH=/usr/local/cuda/bin:${PATH}
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:${LD_LIBRARY_PATH}

設定を反映させます。

source ~/.bashrc

まとめ・補足情報

update-alternatives を使うことで、複数のCUDAバージョンの共存管理が劇的に簡単になり、プロジェクトごとの要求に応じた素早い切り替えが可能になります。これにより、「ライブラリが見つからない」エラーに悩まされる時間を大幅に削減できます。

重要な補足点:

  1. NVIDIAドライバーバージョン: update-alternatives で切り替えられるのはCUDA「ツールキット(コンパイラやライブラリ)」です。GPUドライバー自体のバージョン(nvidia-smiで表示されるCUDA Version)は別物です。ドライバーはインストールされているツールキットの全バージョンに対して十分に新しいものを使用する必要があります(一般的に、ドライバーは上位互換性があります)。
  2. conda環境との併用: PyTorchやTensorFlowをcondaでインストールすると、conda環境内に独立したCUDAライブラリがインストールされることがあります。その場合は、conda環境内ではcondaが提供するライブラリが優先され、システムのCUDAバージョンの影響を受けにくくなります。update-alternatives は主にシステム全体で使うツールキット(nvccなど)や、condaを使わないpipインストール時の依存関係解決に威力を発揮します。
  3. 他のツールへの応用: この方法はCUDAだけでなく、同じくシンボリックリンクでバージョン管理される gcc, python(システムPython)などにも応用できます。統一された方法でシステムツールを管理できるようになると、開発環境の整備が一段と楽になります。

ぜひこの方法を活用して、ストレスのないマルチバージョンCUDA開発環境を構築してください。

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