CUDA

PyTorchのビルド方法(PyTorch 1.5, CUDA 10.2, cuDNN 7.6.5, Windows 10)

PyTorch

PyTorchの公式サイトでは、2020/3/1時点でCUDA 10.1までのパッケージしか提供されていないため、PyTorchをソースコードからCUDA 10.2向けにビルドする手順を残しておきます。

ターゲット環境とビルド環境

今回は以下の環境をターゲットにPyTorchをソースコードからビルドしていきます。本家ではAnacondaの使用を推奨していますが、condaはpipと相容れない部分があるので、今回は純粋なPython環境を使ってビルドします。

  • Windows 10 Pro Version 1909 – 64bit
  • Python 3.8.2(Anacondaではなく純粋なPython)
  • CUDA 10.2
  • cuDNN 7.6.5
  • Intel MKL 2019.0

ビルド環境は次の通りです。

最近PCを組み直して、CPUがIntelからAMDに変わっていますが、Intelの環境でも同様の手順で対応できるはずです。なお、AMDのCPUでもAVX2命令に対応していれば、ちょっとした裏技(非公式)でIntel MKLを利用可能です。

  • CPU: AMD Threadripper 3960X
  • GPU: nVIDIA TITAN RTX
  • Microsoft Visual Studio Community 2019 – Ver 16.4.5

事前準備

PyTorchをソースコードからビルドする前提として、次の環境を整えておく必要があります。

私の場合Intel MKL(Math Kernel Library)2020.0.166をインストールしていますが、MKLをインストールしていなくてもPyTorchでMKLを利用できると思われます。
Intel MKLを個別にインストールしたい場合はIntelのサイトからダウンロード可能です。

TensorRT 7.0 for Windowsも導入してパスを通していますが、PyTorchのビルドでTensorRTは有効化されないようです。環境変数でUSE_TENSORRT=1と指定しても同じでした。

AMDのCPUでIntel MKLを使うための設定

Intel MKLはIntel CPU向けのパッケージなので、そのままではAMDのCPUでは利用できません。しかし、AVX2などの命令セットに対応したCPUであれば、MKL_DEBUG_CPU_TYPEという環境変数でMKLを有効にできます。

Windowsの「システム環境変数の編集」で、システム環境変数に以下の内容を追加します。この環境変数を追加すると、 MKLは「AVX2までの命令セットに対応したCPU」が搭載されている前提で動作するようになります。

  • 変数: MKL_DEBUG_CPU_TYPE
  • 値: 5

この「MKL_DEBUG_CPU_TYPE」という環境変数は、非公式の内容になります。そのため、将来使えなくなる可能性もあります。
また、AVX2命令セットに対応していないCPUを使っている場合は、この設定をすると正しく動作しなくなる可能性があります。

PyTorch 1.5のビルドとwheelモジュール作成

今回は次のフォルダ構成でビルド作業を行っています。

  • ビルド用のPython仮想環境: g:\work\build_pt
  • PyTorchのビルドフォルダ: g:\work\build_pt\pytorch

ビルド用の仮想環境作成

Visual Studio 2019の「x64 Native Tools Command Prompt for VS 2019」を開いて、以下の手順でビルド用のPython仮想環境(build_pt)を作成します。

:: ビルド用の仮想環境作成
python -m venv g:\work\build_pt
g:\work\build_pt\Scripts\activate.bat

cd /d g:\work\build_pt

:: パッケージの更新(任意)
python -m pip install --upgrade pip

:: ビルドに必要なパッケージの導入
:: setuptoolsはデフォルトでインストール済み
:: typingはPython 3.8を使っていれば導入不要
:: wheelは後でパッケージを作るために導入
pip install numpy ninja pyyaml mkl mkl-include cmake cffi wheel

作成した環境の状態を参考までにのせておきます。

:: pipパッケージ
(build_pt) g:\work\build_pt>pip list
Package      Version
------------ -----------
cffi         1.14.0
cmake        3.16.3
intel-openmp 2019.0
mkl          2019.0
mkl-include  2019.0
ninja        1.9.0.post1
numpy        1.18.1
pip          20.0.2
pycparser    2.19
PyYAML       5.3
setuptools   41.2.0
wheel        0.34.2

:: 利用するツールやライブラリの確認(念のため)
(build_pt) g:\work\build_pt>where git
C:\Program Files\Git\cmd\git.exe

(build_pt) g:\work\build_pt>where cl
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\bin\Hostx64\x64\cl.exe

(build_pt) g:\work\build_pt>where cmake
g:\work\build_pt\Scripts\cmake.exe
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe

:: CUDA関連ライブラリの確認
(build_pt) g:\work\build_pt>where nvcc
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\bin\nvcc.exe

(build_pt) g:\work\build_pt>where nvvp.exe
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\libnvvp\nvvp.exe

(build_pt) g:\work\build_pt>where cuda*102.dll
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\bin\cudart32_102.dll
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\bin\cudart64_102.dll

:: cuDNN
(build_pt) g:\work\build_pt>where cudnn*.dll
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\bin\cudnn64_7.dll

:: MKL(Intel MKLやpipで取得したMKLへのパスが通っているわけではない)
(build_pt) g:\work\build_pt>where mkl*
C:\Windows\System32\mkl_core.dll
C:\Windows\System32\mkl_def.dll
C:\Windows\System32\mkl_intel_thread.dll
C:\Windows\System32\mkl_sequential.dll

:: AMDのCPUを使う場合MKL_DEBUG_CPU_TYPEが設定されているかどうか
:: IntelのCPUを使っている場合は不要
(build_pt) g:\work\build_pt>set | find "MKL_DEBUG_CPU_TYPE"
MKL_DEBUG_CPU_TYPE=5

PyTorchのソースコード取得

以下の手順で、PyTorchのソースコードとサブモジュールを取得してきます。
最新のファイルを取得するとビルドに失敗する可能性があるため、ここでは2020/3/1 13:24時点にコミットされたソースセットを利用しています。

:: 作業場所確認
(build_pt) g:\work\build_pt>cd
g:\work\build_pt

:: ソース取得
:: 本家サイトの手順とは違って、サブモジュールは後から取得する
git clone https://github.com/pytorch/pytorch

:: PyTorchのフォルダに移動
cd pytorch

:: 変更 2020/03/01 13:24 時点の状態に切り替え
git checkout ace2b4f

:: サブモジュールの取得
git submodule sync
git submodule update --init --recursive

ビルド

ソースコードを取得した後は、以下コマンドでPyTorchのビルドを行います。
本家サイトでは、オプションの環境変数設定がいくつか提示してありますが、今回のビルドでは「全て設定不要」です。

なお、ビルドに30GBくらいのディスク容量が必要になります。
デフォルトでは搭載しているCPUの全コアを使ってビルドが行われるため、Threadripper 3960X(24コア48スレッド)では、20分弱でビルドが完了しました。

:: ビルド実行(インストールまで)
python setup.py install

CUDAのGPUのアーキテクチャ番号などは、ビルド環境で使っているGPUに合わせて自動で設定されます。例えばTuringアーキテクチャのTITAN RTXを使っている場合は、Turing用のアーキテクチャ番号(7.5)が自動設定されます。

python setup.py installで、PyTorchのインストールまで行われますが、ビルド用のディレクトリ(g:\work\build_pt\pytorch)でPyTorchを使おうとすると「ModuleNotFoundError: No module named ‘torch._C’」というエラーが表示されます。

これは、ビルドに失敗しているわけではなく、他のディレクトリ(g:\work\build_ptなど)に移動すれば正しくPyTorchを使えるのでご安心ください。

wheelモジュールの作成

ビルドしたPyTorchを他の環境でも再利用できるように、Wheelモジュールを以下の手順で作成します。Wheelモジュールを作成しておけば、pipを使って簡単にインストールできるようになります。

:: PyTorchをビルドしたときのフォルダに移動
cd /d g:\work\build_pt\pytorch

:: Wheelパッケージの作成
:: g:\work\build_pt\pytorch\distフォルダにwhlファイルが作成される
python setup.py bdist_wheel

これで、pytorchのdistフォルダにwheelパッケージ(torch-1.5.0a0+ace2b4f-cp38-cp38-win_amd64.whlなど)が作成されます。

TorchVisionのビルドとwheelモジュール作成

PyTorchと併せてtorchvisionを使うケースも多いため、torchvisionについてもビルドとwheelモジュール作成までの手順を示しておきます。

:: PyTorchのビルド用に作成した仮想環境をそのまま利用
g:\work\build_pt\Scripts\activate.bat
cd /d g:\work\build_pt

:: torchvisionに必要なパッケージを追加
pip install six pillow

:: ソースコード取得
git clone https://github.com/pytorch/vision.git
cd vision

git checkout b2e9565

:: ビルド(数分くらいで完了)
python setup.py install

:: wheelパッケージの作成
python setup.py bdist_wheel

これでdistフォルダにtorchvisionのwheelパッケージが作成されます。

利用環境のセットアップ方法

新しいPythonの仮想環境にビルドしたPyTorchとtorchvisionを導入する手順は次のようになります。このとき、上記で作成したPyTorchとtorchvisionのwheelパッケージファイル(~.whl)が必要になります。

ここでは「c:\venvs」配下に「ml」という仮想環境を作成するケースの例です。

:: 仮想環境の作成
python -m venv c:\venvs\ml
c:\venvs\ml\Scripts\activate.bat
cd /d c:\venvs\ml

:: パッケージの更新(任意)
python -m pip install --upgrade pip

:: パッケージの導入
:: ninja, pyyaml, mkl-include, cmake, cffi, wheelは入れなくてもOK
pip install numpy mkl six pillow

:: 独自にビルドしたPyTorchとtorchvisionの導入
:: ~.whlファイルのパスは、各自の環境に合わせて読み替えてください
pip install "torch-1.5.0a0+ace2b4f-cp38-cp38-win_amd64.whl"
pip install "torchvision-0.6.0a0+b2e9565-cp38-cp38-win_amd64.whl"

これで、新しく作成した仮想環境にPyTorchとtorchvisionを導入できました。以下のコマンドで導入されたパッケージの内容確認や、動作確認が行えます。

:: パッケージの確認
(ml) C:\venvs\ml>pip list
Package      Version
------------ ---------------
intel-openmp 2019.0
mkl          2019.0
numpy        1.18.1
Pillow       7.0.0
pip          20.0.2
setuptools   41.2.0
six          1.14.0
torch        1.5.0a0+ace2b4f
torchvision  0.6.0a0+b2e9565

:: PyTorchの動作確認
python -c "import torch; print(torch.__version__)"
1.5.0a0+ace2b4f

python -c "import torch; print('CUDA:', torch.cuda.is_available())"
CUDA: True

python -c "from __future__ import print_function; import torch; x = torch.rand(5, 3); print(x)"
tensor([[0.4569, 0.7402, 0.7894],
        [0.9506, 0.9800, 0.5858],
        [0.9339, 0.4714, 0.8279],
        [0.8572, 0.0945, 0.8779],
        [0.9573, 0.6105, 0.1938]])

:: torchvisionの確認
(ml) C:\Users\Kurozumi>python -c "import torch;import torchvision;print(torchvision.__version__)"
0.6.0a0+b2e9565

CUDAやMKLを有効にしてPyTorchをビルドした場合は、CUDAへのパスが通っていて、MKLなどのパッケージを導入しておく必要があります。

必要なパッケージなどが見つからない場合、PyTorchをimportした時点で「ImportError: DLL load failed while importing _C: このオペレーティング システムでは %1 は実行されません。」というようなエラーが表示されます。