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

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

AI開発、特に深層学習のモデルトレーニングや推論を行う際、異なるフレームワークやプロジェクトが要求するCUDAバージョンが異なることがよくあります。例えば、PyTorch 1.x系はCUDA 10.2を、TensorFlow 2.5はCUDA 11.2を要求するといったケースです。このような状況で、単一のCUDAバージョンしかシステムにインストールしていないと、プロジェクトを切り替えるたびにCUDAの再インストールが必要となり、非効率です。

複数のCUDAバージョンをインストールした後でも、システムのデフォルトCUDAバージョンを手動で切り替え忘れると、以下のような典型的なエラーが発生します。

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

または、nvcc --version コマンドで確認できるコンパイラバージョンと、nvidia-smi で表示されるドライバに付属するCUDAバージョンが一致せず、混乱を招きます。

$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Sun_Feb_14_21:12:58_PST_2021
Cuda compilation tools, release 11.2, V11.2.152

$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.182.03   Driver Version: 470.182.03   CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+

この問題の根本原因は、/usr/local/cuda シンボリックリンクが指す先が固定されており、環境変数(PATH, LD_LIBRARY_PATH)の管理が煩雑なことです。

原因の解説:シンボリックリンクと環境変数の管理不足

通常、CUDA Toolkitは /usr/local/cuda-{バージョン番号} (例: /usr/local/cuda-11.6, /usr/local/cuda-12.1)にインストールされます。そして、利便性のために /usr/local/cuda というシンボリックリンクが、使用するバージョンのディレクトリを指すように設定されます。

多くのインストールガイドは、このシンボリックリンクを手動で貼り替える(sudo rm /usr/local/cuda && sudo ln -s /usr/local/cuda-11.6 /usr/local/cuda)か、シェルの設定ファイル(.bashrc など)に環境変数を直接書き込む方法を提案します。

# ~/.bashrc への従来の記述例(問題あり)
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH

この方法には以下の欠点があります。

  • グローバルな変更: シンボリックリンクの切り替えはシステム全体に影響し、他のユーザーやサービスに予期せぬ影響を与える可能性があります。
  • 環境変数の競合: LD_LIBRARY_PATH を安易に設定すると、システムライブラリの検索順序が乱れ、別のエラーの原因になることが知られています。
  • 手動管理の煩雑さ: プロジェクトごとに切り替えるのが面倒で、ミスが発生しやすい。

これらの問題を解決するために、Debian/Ubuntu系ディストリビューションに標準搭載されている update-alternatives ユーティリティを活用した体系的な管理方法が有効です。

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

update-alternatives は、システム上に存在する複数の同種ソフトウェア(例: gcc, python, cuda)を登録し、システム全体またはユーザーセッション単位でデフォルトとして使用するバージョンを切り替えるためのツールです。ここでは、CUDAの管理グループを作成し、シンボリックリンク /usr/local/cuda をこのシステムで管理させる手順を説明します。

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

まず、既存の /usr/local/cuda リンクが手動で作成されたものであれば削除します。

sudo rm -f /usr/local/cuda

ステップ2: update-alternativesシステムにCUDAを登録

インストール済みの各CUDAバージョンを、update-alternatives --install コマンドで登録します。このコマンドは、「管理グループ名」「グローバルシンボリックリンクのパス」「実際のインストール先」「優先度」を指定します。

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

# 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.6   116       manual mode
  2            /usr/local/cuda-12.1   121       manual mode

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

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

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

シンボリックリンクが正しく切り替わったか確認します。

ls -l /usr/local/cuda
# 期待する出力例:
# lrwxrwxrwx 1 root root 22 Oct 10 15:30 /usr/local/cuda -> /usr/local/cuda-11.6

nvcc --version
# 選択したCUDAバージョンのコンパイラ情報が表示される

ステップ5: 環境変数の設定(オプションと注意点)

update-alternatives/usr/local/cuda リンクを管理することで、PATH の設定は簡素化できます。しかし、多くのAIフレームワークはランタイム時に LD_LIBRARY_PATH を必要とします。より安全な方法は、仮想環境やプロジェクトごとに必要なときだけ設定するか、ldconfig を利用することです。

方法A: 仮想環境内でのみ設定する(推奨)
Pythonの仮想環境(venv, conda)の activate スクリプト内で設定します。

# 仮想環境の activate スクリプトや .env ファイル内で
export CUDA_HOME=/usr/local/cuda
export PATH=$CUDA_HOME/bin:$PATH
export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH

方法B: システムにライブラリパスを登録する
新しいCUDAバージョンを選択した後、そのライブラリパスをシステムのキャッシュに登録します。

sudo ldconfig /usr/local/cuda/lib64

この方法は、システム全体に影響を与えますが、LD_LIBRARY_PATH を設定するよりは安全です。

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

登録されている全CUDAバージョンの確認

sudo update-alternatives --display cuda

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

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

sudo update-alternatives --auto cuda

登録の削除(アンインストール時)

CUDA 11.6 をアンインストールし、管理リストからも削除する場合。

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

シェルスクリプトによるプロジェクト別切り替え例

#!/bin/bash
# switch_cuda.sh
echo "Current CUDA:"
ls -l /usr/local/cuda

echo "Switching to CUDA 11.6..."
sudo update-alternatives --set cuda /usr/local/cuda-11.6

echo "Updated CUDA:"
ls -l /usr/local/cuda
nvcc --version

まとめ・補足情報

update-alternatives を活用したCUDAバージョン管理は、システムの主要シンボリックリンクを一元的に管理できるため、手動でのリンク貼り替えミスを防ぎ、複数バージョンのクリーンな共存を実現します。特に、複数のプロジェクトを並行して進めるAI開発者や、異なるCUDAバージョンを要求するソフトウェアをテストする環境では、作業効率とシステムの安定性が大幅に向上します。

重要な補足点:

  • NVIDIAドライバ: ここで管理するのはCUDA Toolkit(コンパイラやライブラリ)です。GPUドライバは別で、常に最新の安定版または必要なバージョンをインストールしておきます。ドライバのCUDAバージョン(nvidia-smi 表示)は、そのドライバがサポートする最大のCUDA Runtimeバージョンです。通常、Toolkitバージョン ≦ ドライバがサポートするバージョンであれば動作します。
  • conda環境: PyTorchやTensorFlowをcondaでインストールすると、conda環境内に独立したCUDAライブラリがインストールされることがあります。その場合、conda環境内ではcondaが提供するCUDAが優先され、システムのCUDAは使われません。これは意図された挙動です。
  • 永続性: update-alternatives による変更はシステム全体に適用され、再起動後も持続します。

この方法を導入することで、「libcudart.so not found」エラーに悩まされる時間を減らし、本質的なAIモデルの開発に集中できる環境を構築しましょう。

⚡ GPU環境をすぐに使いたいなら

ハードウェアの購入・セットアップなしで、すぐにGPU環境を使えるクラウドサービスがおすすめです。

  • RunPod — RTX 4090/A100/H100を即座に利用可能
  • Vast.ai — 最安のGPUクラウド、オークション方式で低コスト
  • RTX 5090をAmazonで見る — 自宅GPU環境を構築するなら
この記事は役に立ちましたか?