Ubuntu20.04上でのPyTorch+GPU環境構築メモ

何番煎じか知らない話題ですが、表題の通り手元のマシンの Ubuntu 20.04 上に PyTorch 1.10 の動作環境を構築した時のメモです


GPU 周りは 検証時点での PyTorch 1.10 との兼ね合いで CUDA Toolkit 11.3 と対応するバージョンの CUDNN 8.2.1 をインストールしています


PyTorch の動作環境は Anaconda（Miniconda） を使わずに仮想環境の Pipenv & Pyenv を使って構築します


検証時点ではPython の最新の安定版が 3.10 に対して、PyTorch 側で 3.9 までしか対応していない為、Pyenv を利用して仮想環境上で利用する Python の版を切り替えて対応しています


# 使用したマシンのスペック
- CPU
    - Intel Core i9-10900
- GPU
    - GeForce RTX3060 12GB

# 関係する主なソフトウェア類のバージョン
- Ubuntu 20.04 LTS
- CUDA Toolkit 11.3
- CUDNN 8.2.1
- PyTorch 1.10
- Pipenv 2021.11.23
- Pyenv 2.2.2-1-gf2925393

# 環境構築の前提
- Ubuntu 20.04インストール済み
- CUDA Toolkit 11.3に対応可能なNVIDIA製GPU導入済みマシン
- NVIDIA Developerに登録済み


# NVIDIA ドライバのインストール
## 概要
- 利用可能な NVIDIA ドライバを確認してインストール

## 手順
- 端末を開き、パッケージを最新に更新

```
sudo apt update
```

- NVIDIA ドライバの一覧を取得したりする為にインストールしていなければ ubuntu-drivers-common をインストール

```
sudo apt install ubuntu-drivers-common
```

- インストール可能な NVIDIA ドライバの一覧を取得

```
ubuntu-drivers devices
```

- 「recommended」の記述が付いていて、「nvidia-driver-」の後の数字が大きいものをインストール

```
# nvidia-driver-495 をインストールする場合
sudo apt install nvidia-driver-495
```

- 再起動

```
sudo reboot
```


# CUDA Toolkit 11.3 のインストール
## 概要
- NVIDIA 公式の手順を参考にインストール
    - この記事では deb(local) 

## 手順
- 端末を開き、「mkdir」コマンドで作業フォルダを作成

```
mkdir tmp
```

- 作成した作業フォルダ内へ移動後、NVIDIA 公式の手順通りに「wget」コマンドを利用してインストーラをダウンロードしたり、圧縮ファイルを展開したりしてインストール直前まで実施

```
cd tmp
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.3.0/local_installers/cuda-repo-ubuntu2004-11-3-local_11.3.0-465.19.01-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu2004-11-3-local_11.3.0-465.19.01-1_amd64.deb
sudo apt-key add /var/cuda-repo-ubuntu2004-11-3-local/7fa2af80.pub
sudo apt-get update
``` 

- 実施時点の CUDA Toolkit の最新版は 11.5 ですが、PyTorch の要件を満たせないので版を 11.3 に指定してインストール
    - 指定しないと強制的にその時点の最新がインストールされます

```
sudo apt-get -y install cuda-11-3
```

- インストール完了後、不要であれば作業フォルダを削除

# CUDNN 8.2.1 のインストール
## 概要
- NVIDIA 公式の手順通り「2.3.1. Tar File Installation」「2.3.2. Debian Installation」に従って必要なファイルをインストール
    - CUDNN のバージョンによってファイル複製先のディレクトリ名などが細かく異なる為、8.2.1 以外で試そうとしている場合は対応するバージョンの手順を参照して下さい

## 手順
- 過去の CUDNN のダウンロードページへアクセスして「Download cuDNN v8.2.1 (June 7th, 2021), for CUDA 11.x」の欄から以下の項目をダウンロード
    - cuDNN Library for Linux (x86_64)
    - cuDNN Runtime Library for Ubuntu20.04 x86_64 (Deb)
    - cuDNN Developer Library for Ubuntu20.04 x86_64 (Deb)
    - cuDNN Code Samples and User Guide for Ubuntu20.04 x86_64 (Deb)

- ダウンロードしたファイルがあるディレクトリから端末を開き、圧縮ファイルを展開

```
# 「cuDNN Library for Linux (x86_64)」からダウンロードしたファイルが「cudnn-11.3-linux-x64-v8.2.1.32」の場合
tar -xzvf cudnn-11.3-linux-x64-v8.2.1.32.tgz
```

- CUDNN のライブラリを指定のディレクトリへ複製

```
sudo cp cuda/include/cudnn*.h /usr/local/cuda/include 
sudo cp -P cuda/lib64/libcudnn* /usr/local/cuda/lib64 
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
```

- Debian 用に必要なライブラリをインストール

```
# CUDNN 8.2.1.32-1 の場合
sudo dpkg -i libcudnn8_8.2.1.32-1+cuda11.3_amd64.deb
sudo dpkg -i libcudnn8-dev_8.2.1.32-1+cuda11.3_amd64.deb
sudo dpkg -i libcudnn8-samples_8.2.1.32-1+cuda11.3_amd64.deb
```

- インストール完了後、不要であればファイル類を削除


# Pyenv のインストール＆必要な版の Python のインストール
## 概要
- GitHub からPyenv のソースコードを取得してパス類の参照を登録
- Pyenv を利用して必要な版の Python をインストール

## 手順
- 任意のディレクトリで端末を開いて Pyenv のビルドに必要なソフトウェア類をインストール

```
sudo apt install -y libffi-dev libssl-dev zlib1g-dev liblzma-dev tk-dev libbz2-dev libreadline-dev libsqlite3-dev libopencv-dev build-essential git
```

- GitHub から Pyenv のソースコードを取得
    - 現在のユーザのホームディレクトリ内へ配置

```
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

- 現在のユーザの .bashrc へパス類を登録＆反映
    - 以下手順を全て終えても Pyenv が実行出来なければ「sudo reboot」を実行してマシンを再起動する

```
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
source ~/.bashrc
exec $SHELL -l
```

- Pyenv を利用して必要な Python の版をインストール
    - PyTorch 1.10 に対応している中でも最新の版は 3.9.9 

```
pyenv install 3.9.9
```

# Pipenv のインストール
## 概要
- 「pip3」コマンドを利用してインストール

## 手順
- 任意のディレクトリから端末を開き、Pipenv のインストールに必要なソフトウェア類をインストール

```
sudo apt-get -y install python3-pip python3-distutils python3-dev 
sudo pip3 install --upgrade setuptools
```

- Pipenv をインストール

```
sudo pip3 install pipenv
```

- （任意）Pipenv を利用して仮想環境を作成した際、仮想環境で利用するソフトウェア類の管理場所を Pipenv の設定ファイルである Pipfile と同じディレクトリへ保存する様に .bashrc へ設定＆反映
    - 特に Visual Studio Code でデバッグの設定を行う際に楽になる

```
echo "export PIPENV_VENV_IN_PROJECT=true" >> ~/.bashrc
source ~/.bashrc
```

# 仮想環境の構築＆ PyTorch のインストール
## 概要
- Pipenv を実行して仮想環境を作成
- Pipfile を編集して PyTorch をインストール

## 手順
- 仮想環境を作成するディレクトリから端末を開き、Pipenv を利用して Python 3.9 環境の仮想環境を作成

```
pipenv --python 3.9
```

- 作成された Pipfile をエディタで開いて「[packages]」の欄を以下の様に編集
    - 端末から「pipenv install torch〜」を実行してもそんな版はないと言われてインストール出来ない

```
[packages]
torch = {file = "https://download.pytorch.org/whl/cu113/torch-1.10.0%2Bcu113-cp39-cp39-linux_x86_64.whl"}
torchvision = {file = "https://download.pytorch.org/whl/cu113/torchvision-0.11.1%2Bcu113-cp39-cp39-linux_x86_64.whl"}
torchaudio = {file = "https://download.pytorch.org/whl/cu113/torchaudio-0.10.0%2Bcu113-cp39-cp39-linux_x86_64.whl"}
```

- Pipfile 内の記述に従って PyTorch を含むモジュールをインストール

```
pipenv shell
pipenv install
```

- Pipenv の仮想環境が有効な状態で以下の様に Python のコンソールからGPUが参照出来るかどうかのチェックを実行して「True」が表示されれば環境構築完了
    - Python の実行コマンドは「python[Python の版]」

```
# 端末
python3.9
# ここから Python のコンソール
>>> import torch
>>> print(torch.cuda.is_available())
True
```


# 余談
- Pipenv の版が古いと「+」に対応したURLエンコードである「%2B」を更にURLエンコードして「%252B」とする必要がある場合もあって面倒なので、極力最新の Pipenv を使った方が良いと思います


# 参考
## CUDA Toolkit 周り
- Ubuntu: NVIDIAのドライバはどれをインスールすればよいのだ？
    - https://qiita.com/abetomo/items/a114a3c423f110460549
- Installing Multiple CUDA & cuDNN Versions in Ubuntu
    - https://towardsdatascience.com/installing-multiple-cuda-cudnn-versions-in-ubuntu-fcb6aa5194e2
- NVIDIA 公式の CUDA Toolkit インストール手順
    - https://developer.nvidia.com/cuda-11.3.0-download-archive?target_os=Linux&target_arch=x86_64&Distribution=Ubuntu&target_version=20.04&target_type=deb_local
 のdeb(local)

## CUDNN 周り
- 過去の CUDNN のダウンロードページ
    - https://developer.nvidia.com/rdp/cudnn-archive
- CUDNN 8.2.1 のドキュメント
    - https://docs.nvidia.com/deeplearning/cudnn/archives/cudnn-821/install-guide/index.html
- CUDNN 各版ドキュメントのリンクページ
    - https://docs.nvidia.com/deeplearning/cudnn/archives/index.html

## Pyenv 周り
- ubuntu 20.04 / 18.04 に pyenv をインストール
    - https://zenn.dev/neruo/articles/install-pyenv-on-ubuntu

## Pipenv 周り
- Ubuntu 20.04にpipenvとmoviepyをインストールする 
    - http://serverarekore.blogspot.com/2020/08/ubuntu-2004pipenvmoviepy.html

## PyTorch 周り
- [PyTorch] Windows10 + Pipenv で PyTorch(GPU)を導入する
    - https://qiita.com/Haaamaaaaa/items/69b30d1dbbfcea834a9d
- 安定版 PyTorch のリポジトリ一覧
    - https://download.pytorch.org/whl/torch_stable.html
- PyTorch installation with pipenv fails (pipenv install torch) #4422 
    - https://github.com/pypa/pipenv/issues/4422#issuecomment-866542148
- Can't install from URL with percent-encoding #4089 
    - https://github.com/pypa/pipenv/issues/4089