はじめに
Tensorflow 2.11からWindowsのGPU対応バージョンがリリースされなくなりました。Tensorflow 2.11以降のバージョンを動かしたければOSをLinuxにするかWin+WSL2上で動かす(か自力でTensorflowをビルドする)しかありません。
そこでWSL2上で動かすとどれほどパフォーマンスが変わるか比較してみます。どちらもGPU対応されているTensorflow 2.10で比較を行いました。また最後のGPU対応バージョンなのでインストール方法もメモとして残しておきますので参考になればと思います。
環境
Windows10Pro 22H2
Intel Core i7-6850K
NVIDIA GeForce GTX 1070
WSL2
CUDA 11.8
Miniconda3(Python 3.10)
Tensorflow 2.10
上記の環境とは別のWin11マシンでもインストールしましたが、インストールの流れは同じです。
環境① Miniconda+Tensorflowインストール
まずはWindowsにMinicondaとTensorflowをインストールする手順です。
CUDAインストール
Tensorflow 2.10はCUDA 12では動かないようなので、CUDA 11.8をインストールします。
以下からダウンロードしてインストールします。
・CUDA 11.8
https://developer.nvidia.com/cuda-11-8-0-download-archive
・cuDNN v8.9.1 (May 5th, 2023), for CUDA 11.x
https://developer.nvidia.com/rdp/cudnn-download
CUDAをインストールした場所(C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8)にコピーします
・zlibwapi.dll
https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html#install-zlib-windows
zlibwapi.dllをC:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\binなどパスの通ったところに入れておきます。
Minicondaインストール
機械学習の環境を構築する際にPython単独でインストールするのではなく、numpyなどの数値計算パッケージが高速に動作するAnacondaを用いている方も多いと思いますが、2020年にAnacondaの利用が200人以上の企業では有償となりました。そのため、Minicondaをインストールし、conda-forgeのチャンネルを使用すれば無償として使えるということでこの方法でインストールしてみます。
・Miniconda3-py310_23.3.1-0-Windows-x86_64.exe
https://docs.conda.io/en/latest/miniconda.html
PowerShellを起動して
PS >conda update conda
を実行
もし、CondaSSLErrorというエラーが出たら、
C:/Users/ユーザー名/AppData/Local/miniconda3/Library/bin/libcrypto-1_1-x64.dll
C:/Users/ユーザー名/AppData/Local/miniconda3/Library/bin/libssl-1_1-x64.dll
の2つのファイルを
C:/Users/ユーザー名/AppData/Local/miniconda3/DLLs
にコピーしてPCを再起動(←必須)
PowerShellから
PS >conda config --set ssl_verify false
とするとSSLの証明なしでアクセスできます。
チャンネルの変更
企業でなければこの手順は不要です。
PS >conda config --show channels
channels:
- defaults
チャンネルを conda-forge に変更します。
PS >conda config --add channels conda-forge
PS >conda config --remove channels defaults
確認する。
PS >conda config --show channels
channels:
- conda-forge
設定は以下に保存されています。
C:/Users/ユーザー名/.condarc
数値計算ライブラリなどのインストール
とりあえず以下をインストールしておけば十分でしょう。
PS >conda install numpy scipy sympy matplotlib scikit-learn pandas jupyter notebook ipykernel jupyterlab graphviz pydot
Tensorflow 2.10のインストール
PS >pip install tensorflow==2.10
SSLエラーがでたら以下のように実行します。
PS >pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org tensorflow==2.10
以下のスクリプトを実行してGPUデバイス名が表示されればOKです。
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
PS >python Device.py
環境② WSL2+Miniconda+Tensorflowインストール
同じWindowsシステムにWSL2環境を構築し、その上にMinicondaをインストールします。
WSL2のインストール
[コントロールパネル]-[プログラムと機能]-[Windowsの機能]を選択し、以下にチェックを入れて再起動します。
☑Hyper-V
☑Linux用Windowsサブシステム
☑Windowsハイパーバイザープラットフォーム
☑仮想マシンプラットフォーム
Ubuntuをインストールします。
PS >wsl --update
PS >wsl --install -d Ubuntu
以下を実行しVERSIONが2になっていればOKです。
PS >wsl -l -v
スタートメニューから Ubuntu を起動する。”WslRegisterDistribution failed with error:”というエラーが出てきてしまった場合は、以下の順にインストールします。
・上記[Windowsの機能]4つをアンインストール
・PS >wsl --install
これで[仮想マシンプラットフォーム]とUbuntuがインストールされます。
・最後に以下をチェックする
☑Hyper-V
☑Linux用Windowsサブシステム
☑Windowsハイパーバイザープラットフォーム
Ubuntu を起動しapt-getをアップデートしておきます。
$ sudo apt-get update
$ sudo apt-get upgrade
WSL2上にCUDAをインストール
以下のページから [Linux]-[x86_64]-[WSL-Ubuntu]-[2.0]-[deb (local)] を選択すると
https://developer.nvidia.com/cuda-11-8-0-download-archive
次のようなコマンドが出てくるので、そのままWSLのUbuntuにコピー&ペーストします。
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda-repo-wsl-ubuntu-11-8-local_11.8.0-1_amd64.deb
sudo dpkg -i cuda-repo-wsl-ubuntu-11-8-local_11.8.0-1_amd64.deb
sudo cp /var/cuda-repo-wsl-ubuntu-11-8-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda
パスを通しておきます。
echo 'export CUDA_PATH=/usr/local/cuda-11.8' >> ${HOME}/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-11.8/lib64:${LD_LIBRARY_PATH}' >> ${HOME}/.bashrc
echo 'export PATH=/usr/local/cuda-11.8/bin:${PATH}' >> ${HOME}/.bashrc
以下を実行してバージョンが表示されればOkです。
$ source ~/.bashrc
$ nvcc --version
WSL2上にcuDNNをインストール
cuDNNをダウンロードします。
https://developer.nvidia.com/rdp/cudnn-download
[Download cuDNN v8.9.1 (May 5th, 2023), for CUDA 11.x]-[Local Installer for Ubuntu22.04 x86_64 (Deb)]
エクスプローラで、cudnn-local-repo-ubuntu2204-8.9.1.23_1.0-1_amd64.deb を Linux/Ubuntu/home/ユーザー名/ に移動
$ sudo dpkg -i cudnn-local-repo-ubuntu2204-8.9.1.23_1.0-1_amd64.deb
以下のようなコマンドが出てくるので、コピー&ペースト。
$ sudo cp /var/cudnn-local-repo-ubuntu2204-8.9.1.23/cudnn-local-*-keyring.gpg /usr/share/keyrings/
ライブラリをインストールします。
$ sudo apt-get update
$ sudo apt-get -y install libcudnn8 libcudnn8-dev libcudnn8-samples
WSL2上にMinicondaをインストール
$ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
$ bash Miniconda3-latest-Linux-x86_64.sh
ライセンスを読んで home ディレクトリにインストール。全てyesでOK。
環境変数を更新
$ source ~/.bashrc
チャンネルをconda-forgeに変更します。
$ conda config --show channels
channels:
- defaults
$ conda config --add channels conda-forge
$ conda config --remove channels defaults
$ conda config --show channels
channels:
- conda-forge
condaをアップデートします。
$ conda update conda
数値計算ライブラリなどのインストール
環境①と同様にパッケージをインストールします。
$ conda install numpy scipy sympy matplotlib scikit-learn pandas jupyter notebook ipykernel jupyterlab graphviz pydot
Tensorflow 2.10のインストール
こちらも環境①と同様です。
$ pip install tensorflow==2.10
Device.py
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
PS >python Device.py
パフォーマンスの比較
以下のような CIFAR-10 のコードを動かしてみます。
import tensorflow as tf
import numpy as np
cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
y_train = y_train.flatten()
y_test = y_test.flatten()
input_shape = (32, 32, 3)
x_train=x_train.reshape(x_train.shape[0], x_train.shape[1], x_train.shape[2], 3)
x_train=x_train / 255.0
x_test = x_test.reshape(x_test.shape[0], x_test.shape[1], x_test.shape[2], 3)
x_test=x_test / 255.0
y_train = tf.one_hot(y_train.astype(np.int32), depth=10)
y_test = tf.one_hot(y_test.astype(np.int32), depth=10)
batch_size = 32
num_classes = 10
epochs = 50
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, 3, padding='same', input_shape=x_train.shape[1:], activation='relu'),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Dropout(0.25),
tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
tf.keras.layers.Conv2D(64, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Dropout(0.25),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(num_classes, activation='softmax'),
])
model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=0.0001, decay=1e-06),
loss='categorical_crossentropy', metrics=['acc'])
history = model.fit(x_train, y_train, batch_size=batch_size,
epochs=epochs)
まずはMiniconda上のTensorflowをCPUだけで動作させてみます。
Epoch 1/50
1563/1563 [==============================] - 69s 44ms/step - loss: 1.8482 - acc: 0.3217
Epoch 2/50
1563/1563 [==============================] - 69s 44ms/step - loss: 1.4917 - acc: 0.4600
Epoch 3/50
1563/1563 [==============================] - 69s 44ms/step - loss: 1.3445 - acc: 0.5182
Epoch 4/50
1563/1563 [==============================] - 71s 46ms/step - loss: 1.2434 - acc: 0.5605
Epoch 5/50
1563/1563 [==============================] - 71s 45ms/step - loss: 1.1599 - acc: 0.5917
次にMiniconda上のTensorflowをGPUで動かしてみます。
Epoch 1/50
1563/1563 [==============================] - 20s 11ms/step - loss: 1.8236 - acc: 0.3341
Epoch 2/50
1563/1563 [==============================] - 17s 11ms/step - loss: 1.4996 - acc: 0.4562
Epoch 3/50
1563/1563 [==============================] - 19s 12ms/step - loss: 1.3622 - acc: 0.5111
Epoch 4/50
1563/1563 [==============================] - 21s 14ms/step - loss: 1.2606 - acc: 0.5508
Epoch 5/50
1563/1563 [==============================] - 21s 14ms/step - loss: 1.1751 - acc: 0.5865
GPUは効いているようです。
最後にWSL2+MinicondaでTensorflowをGPUで動かしてみます。
1563/1563 [==============================] - 24s 14ms/step - loss: 1.8202 - acc: 0.3296
Epoch 2/50
1563/1563 [==============================] - 23s 15ms/step - loss: 1.5129 - acc: 0.4499
Epoch 3/50
1563/1563 [==============================] - 25s 16ms/step - loss: 1.3676 - acc: 0.5090
Epoch 4/50
1563/1563 [==============================] - 26s 16ms/step - loss: 1.2706 - acc: 0.5476
Epoch 5/50
1563/1563 [==============================] - 26s 16ms/step - loss: 1.1897 - acc: 0.5770
Miniconda上で動かした場合に比べると1.2倍くらい遅くなる結果となりました。仮想環境だと若干遅くなることは避けられないみたいですね。今のところTensorflow 2.10で十分ですが、どのタイミングでTensorflowをアップデートしようか悩みどころですね。