古いGPU(CUDA CC=3.0)のためのPyTorchのビルド(Ubuntu 22.04 on MacBookPro 15" Late2013)
CUDA, cuDNN, pytorch のいろいろなバージョンの組み合わせを試してみました。
以下の組み合わせで、一部の機能が、一応、動くようになりました。
GPU | GeForce GT 750M (Compute Capability 3.0) |
---|---|
Display Driver | 418.113 (nvidia-smiによると470.129.06) |
CUDA | 10.2 |
cuDNN | 7.6.5 |
pytorch | 1.9.1 |
torchvision | 0.10.1 |
torchaudio | 0.9.1 |
pytorch v0.3.1 のリリースノートには、以下の説明があります。
「バイナリから CUDA capability 3.0 と 5.0 のサポートが削除されました(今のところソースからビルドすれば動作しますが、今後のサポートは削除されます)」
https://github.com/pytorch/pytorch/releases?page=3
できるだけ新しい pytorch を使いたかったので、現時点の最新版(v1.12.0)から遡りつつ順番にビルドしてみました。
v1.12.0 から v1.10.2 までは、 GPU の機能不足("__funnelshift_r"が無いなど)により、ビルドできませんでした。
v1.9.1 は、ソースコードを修正して、なんとかビルドに成功しました。
以下、ビルド作業の記録です。
pytorch v1.9.1 のビルドの手順
v1.9.1 の README.md の "From Source"にビルドの手順が記載されています。
https://github.com/pytorch/pytorch/tree/v1.9.1#from-source
これを参照して、ビルドを進めます。
ソースコードのダウンロード
適当なディレクトリを作成して、ソースコードをダウンロードします。
git clone --depth 1 --recursive https://github.com/pytorch/pytorch -b v1.9.1
ソースコードの修正
以下の3項目を修正しました。
(1) torch/utils/cpp_extension.py の修正
(2) MAGMA initialization のバグフィックス
(3) テスト用のデータの URL の修正
torch/utils/cpp_extension.py の修正
torch/utils/cpp_extension.py に '3.0' を追加する修正を行います。以下の下線部を追加しました。
named_arches = collections.OrderedDict([ ('Kepler+Tesla', '3.7'), ('Kepler', '3.0;3.5+PTX'), ... supported_arches = ['3.0','3.5', ...
MAGMA initialization のバグフィックス
v1.9.1 には、MAGMAの初期化に失敗するバグがあります。v1.10.0 には、このバグフィックスが取り込まれました。以下のコミットを参照して、同じようにソースコードを修正します。
https://github.com/pytorch/pytorch/commit/296d2a4399923370dccc5f3f4fc0f5fd12db4d19
このバグフィックスでは、以下の4つファイルが修正されます。
(1) aten/src/THC/CMakeLists.txt
(2) aten/src/THC/THCTensorMathMagma.cu -> .cpp
(3) aten/src/THC/THCTensorMathMagma.cuh -> .h
(4) aten/src/THC/generic/THCTensorMathMagma.cu -> .cpp
(2) (3) (4)のファイルの拡張子が変更され、(1) (2) (4)のファイル内容が修正されます。
大規模な修正ではなかったので、手作業でソースコードを修正しました。
テスト用のデータの URL の修正
torch/testing/_internal/common_utils.py に記載されている2つの url を以下のように修正します。
... #url = "https://raw.githubusercontent.com/pytorch/test-infra/master/stats/slow-tests.json"(旧URLをコメントアウト) url = "https://raw.githubusercontent.com/pytorch/test-infra/generated-stats/stats/slow-tests.json"(新URLに設定) ... #url = 'https://raw.githubusercontent.com/pytorch/test-infra/master/stats/disabled-tests.json'(旧URLをコメントアウト) url = 'https://raw.githubusercontent.com/pytorch/test-infra/generated-stats/stats/disabled-tests.json'(新URLに設定)
これらの url は、ビルド後のテストで参照するデータを示しています。
conda の仮想環境の作成
私は conda の仮想環境下でビルドを進めました。まず、pytorch 用の仮想環境を作成します(以下のXXXXXは、任意の仮想環境名です)。
$ conda create -n XXXXX python=3.8 setuptools=58.0.4 $ conda activate XXXXX
setuptools=58.0.4 を指定する理由は、ビルド時の以下のエラーを避けるためです。
「AttributeError: module 'distutils' has no attribute 'version'」
ネットで調べると、このエラーは、setuptools が新しい場合に発生し、setuptools のバージョンを 59.5.0 までダウングレードすればエラーが解消するようです。conda search setuptools で検索したところ、59.5.0 は見つかりませんが 58.0.4 が見つかりました。そこで、setuptools=58.0.4 を指定しました。
ビルドの準備
v1.9.1 の README.md (https://github.com/pytorch/pytorch/tree/v1.9.1#from-source) の "From Source" を参照しつつ、準備を進めます。
$ conda install astunparse numpy ninja pyyaml mkl mkl-include cmake cffi typing_extensions future six requests dataclasses (ここで、setuptools を省略します) $ conda install -c pytorch magma-cuda102 $ conda install typing pytest scipy parameterized hypothesis pillow $ export CMAKE_PREFIX_PATH=${CONDA_PREFIX:-"$(dirname $(which conda))/../"} $ export USE_CUDA=1 USE_CUDNN=1 TORCH_CUDA_ARCH_LIST="3.0"
ここで setuptools が更新されないように気をつけます。
TORCH_CUDA_ARCH_LIST には "3.0" を設定します。
追加のツール typing, pytest, scipy, parameterized, hypothesis, pillow のインストールは、pytorch, torchvision, torchaudio のテストのためです。scipy をインストールすると、blas, intel-openmp, libgfortran-ng, mkl, numpy, numpy-base がダウングレードされてしまいます。pytorch のビルドの後にダウングレードが生じると、pytorch の再ビルドが必要になるので、ビルドの前にインストールします。
ビルド開始
ビルドには、数時間かかります。時間に余裕がある場合、"MAX_JOBS" を設定してスレッド数を少なくするといいかもしれません(MacBookPro 15" Late 2013では、最大は 8 です)。ビルド時間が更に長くなりますが、長時間の発熱によるダメージは軽減されると思います。
$ export MAX_JOBS=2 (任意) $ python setup.py install
これで、ビルド、インストールが完了しました。
テスト
pytorch のソースコードの pytorch/test/ には、テスト用のスクリプトがあります。pytorch の以下の記事には、テスト方法の説明があります。
https://github.com/pytorch/pytorch/blob/v1.9.1/CONTRIBUTING.md#unit-testing=
"test_"で始まるファイルのそれぞれが、テスト用のスクリプトです。
以下のコマンドにより、複数のテストが順番に行われます。
$ python pytorch/test/run_test.py
以下のように1つのテストを実行することもできます。
$ python pytorch/test/test_cuda.py
run_test.py では、変数 TESTS にテストのリストが設定されています。沢山のテストが準備されています。テストの実行には、かなり時間がかかります。エラーが発生すると、そこでテストが中断します。私は、完了したテストとエラーのあるテストをコメントアウトして、続きのテストを進行しました。例えば、以下のように最初の'test_import_time'から'test_cuda'までをコメントアウトすれば、'test_jit_cuda_fuser'からテストを開始できます。
TESTS = [ # 'test_import_time', # 'test_public_bindings', ... # 'distributed/test_c10d_spawn_nccl', # 'test_cuda', 'test_jit_cuda_fuser', ...
現時点でのテスト結果は、こんな感じです
from "test_import_time" to "distributed/test_c10d_spawn_nccl" | OK |
---|---|
"test_cuda" | CUDA out of memory |
"test_jit_cuda_fuser" | a PTX JIT compilation failed |
from "test_cuda_primary_ctx" to "distributions/test_constraints" | OK |
"distributions/test_distributions" | ValueError (relative tolerance) |
from "test_dispatch" to "test_foreach" | OK |
"test_indexing" | CUDA out of memory |
"test_jit" | "__ldg" is undefined |
"test_linalg" | CUDA out of memory, no kernel image is available |
from "test_logging" to "test_numba_integration" | OK |
"test_nn" | CUDA out of memory, "__ldg" is undefined |
テストに時間がかかるので、一部の項目しか確認できていません。
これらの結果を簡単に検討してみました。
- "CUDA out of memory" については、仕方ないと思います(本機の GPU メモリは 2GB なので)。
- JIT のエラーについては、要検討です。
- "__ldg" は Capability 3.0 には無い機能なので、仕方ないと思います。"__ldg" を従来の関数を用いて定義し直せば、エラーを解消できるかもしれません。
- "distributions/test_distributions"の計算エラーについては、要検討です。ネットで検索すると、scipy のバージョンを変えたらテスト結果が変わる、という話を見つけました。https://github.com/pytorch/pytorch/issues/60347 これが今回の件に当てはまるのか、未確認です。
- "test_linalg" の "no kernel image is available" については、エラーメッセージで指摘された関数(torch.linalg.cond など)のサンプルコードを実行したところ、正常に動作しました。エラーの原因は linalg の関数とは別のところにあるのかもしれません。なお、linalg のサンプルコードは、pytorch のドキュメントの各関数のページにあります。https://pytorch.org/docs/1.9.1/linalg.html
未確認の多数のテストが残っていますが、それらについては、またそのうちに・・・。
とりあえず、"__ldg"、JITなどの一部の機能を用いなければ、いろいろな計算で遊べると思います。