古いGPU(CUDA CC=3.0)のためのTorchvisonのビルド(Ubuntu 22.04 on MacBookPro 15" Late2013)
以下の組み合わせで、一部の機能が、一応、動くようになりました。
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 v1.9.1 に続いて、torchvision v0.10.1 をビルドしました。以下、ビルド作業の記録です。
torchvision v0.10.1 のビルドの手順
v0.10.1 の README.md にビルドの手順が記載されています。
https://github.com/pytorch/vision/tree/v0.10.1
これを参照して、ビルドを進めます。
ソースコードのダウンロード
適当なディレクトリを作成して、ソースコードをダウンロードします。
git clone --depth 1 --recursive https://github.com/pytorch/vision -b v0.10.1
ビルド
v0.10.1 の README.md (https://github.com/pytorch/vision/tree/v0.10.1) を参照しつつ、ビルドを進めます。念のために pytorch のビルドの設定と同じ設定にしました。
$ conda install libpng jpeg $ export CMAKE_PREFIX_PATH=${CONDA_PREFIX:-"$(dirname $(which conda))/../"} $ export USE_CUDA=1 USE_CUDNN=1 TORCH_CUDA_ARCH_LIST="3.0" $ export MAX_JOBS=2 (任意) $ python setup.py install
これで、ビルド、インストールが完了しました。
テスト
torchvision のソースコードの vision/test/ には、テスト用のスクリプトがあります。torchvision の以下の記事には、テスト方法の説明があります。
https://github.com/pytorch/vision/blob/v0.10.1/CONTRIBUTING.md#unit-tests=
以下のコマンドにより、複数のテストが順番に行われます。
$ pytest vision/test -vvv
試してみたところ、こんな結果になりました。
= 25 failed, 2233 passed, 108 skipped, 6 xfailed, 1545405 warnings in 783.64s (0:13:03) =
以下のファイルは、ファイル名とタイムスタンプとから、先ほどのテストの失敗の記録と思われます。
vision/.pytest_cache/v/cache/lastfailed
ファイルの中を見てみると、データダウンロードに関するエラー以外に、以下のテストのエラーがありました。
- test_models.py
- test_ops.py
- test_transforms.py
個々にテストを行って結果を見てみます。
$ python vision/test/test_models.py
"CUDA out of memory"のエラーが発生していました(これは、仕方ないです・・・)
$ python vision/test/test_ops.py Ran 66 tests in 229.388s OK
なぜか、エラーは出ませんでした。
$ python vision/test/test_transforms.py ... FAIL: test_adjust_gamma (__main__.Tester)
torchvision.transforms.functional.adjust_gamma の計算にエラーがあるようです。
test_transforms.py の test_adjust_gamma を見てみます。
def test_adjust_gamma(self): x_shape = [2, 2, 3] x_data = [0, 5, 13, 54, 135, 226, 37, 8, 234, 90, 255, 1] x_np = np.array(x_data, dtype=np.uint8).reshape(x_shape) x_pil = Image.fromarray(x_np, mode='RGB') # test 0 y_pil = F.adjust_gamma(x_pil, 1) y_np = np.array(y_pil) torch.testing.assert_close(y_np, x_np) # test 1 y_pil = F.adjust_gamma(x_pil, 0.5) y_np = np.array(y_pil) y_ans = [0, 35, 57, 117, 186, 241, 97, 45, 245, 152, 255, 16] y_ans = np.array(y_ans, dtype=np.uint8).reshape(x_shape) torch.testing.assert_close(y_np, y_ans) # test 2 y_pil = F.adjust_gamma(x_pil, 2) y_np = np.array(y_pil) y_ans = [0, 0, 0, 11, 71, 201, 5, 0, 215, 31, 255, 0] y_ans = np.array(y_ans, dtype=np.uint8).reshape(x_shape) torch.testing.assert_close(y_np, y_ans)
定義済の x_data に対応する x_np と、ガンマ補正(ガンマ=1)を行って得られる y_np を比較してます。また、y_np と定義済の y_ans を比較しています。ガンマ=1なので、比較結果は一致するはずです。python 上で計算を追いかけてみます。
>>> x_shape = [2, 2, 3] >>> x_data = [0, 5, 13, 54, 135, 226, 37, 8, 234, 90, 255, 1] >>> x_np = np.array(x_data, dtype=np.uint8).reshape(x_shape) >>> x_pil = Image.fromarray(x_np, mode='RGB') >>> y_pil = F.adjust_gamma(x_pil, 1) >>> y_np = np.array(y_pil) >>> x_np array([[[ 0, 5, 13], [ 54, 135, 226]], [[ 37, 8, 234], [ 90, 255, 1]]], dtype=uint8) >>> y_np array([[[ 0, 5, 13], [ 54, 136, 227]], [[ 37, 8, 235], [ 90, 255, 1]]], dtype=uint8)
x_np と y_np との間で、いくつかの要素の値が1ずれてます。
さらに続けます。
>>> y_pil = F.adjust_gamma(x_pil, 0.5) >>> y_np = np.array(y_pil) >>> y_ans = [0, 35, 57, 117, 186, 241, 97, 45, 245, 152, 255, 16] >>> y_ans = np.array(y_ans, dtype=np.uint8).reshape(x_shape) >>> y_np array([[[ 0, 36, 58], [118, 186, 241]], [[ 98, 45, 245], [152, 255, 16]]], dtype=uint8) >>> y_ans array([[[ 0, 35, 57], [117, 186, 241]], [[ 97, 45, 245], [152, 255, 16]]], dtype=uint8)
y_np と y_ans との間で、いくつかの要素の値が1ずれてます。
さらに続けます。
>>> y_pil = F.adjust_gamma(x_pil, 2) >>> y_np = np.array(y_pil) >>> y_ans = [0, 0, 0, 11, 71, 201, 5, 0, 215, 31, 255, 0] >>> y_ans = np.array(y_ans, dtype=np.uint8).reshape(x_shape) >>> y_np array([[[ 0, 0, 1], [ 11, 72, 201]], [[ 5, 0, 216], [ 32, 255, 0]]], dtype=uint8) >>> y_ans array([[[ 0, 0, 0], [ 11, 71, 201]], [[ 5, 0, 215], [ 31, 255, 0]]], dtype=uint8)
y_np と y_ans との間で、いくつかの要素の値が1ずれてます。
大間違いはしていませんが、少し残念です。
ソースコードの 関連部分も見ましたが、シンプルに計算してるだけのように見えました(vision/torchvision/transforms/ の functional.py, functional_pil.py, functional_tensor.py)。現時点で、不一致の原因はわかっていません。
いろいろな計算で遊ぶには、十分な気もします。