古いハイエンドグラボ(Quadro K6000)をPyTorchで使えるようにした

以前グラボを買い漁ってなんとか丁度いいグラボ(Quadro K2200)を買ってディープラーニングで大活躍してました。

欲が出てきて今度は物体認識をやろうとしたのですが、画像識別よりも計算量が多く、メモリーが足りなくて困っていました。

モリー量が多いグラボを求めて久々にヤフオクを調べてたらメモリー量の割にお手頃だったQuadro K6000を手に入れました。

www.elsa-jp.co.jp

見た目も良くて早速換装して動かすといい感じに動作しました。ドライバ類も問題なく当たりました。

が、いざPyTorchで学習させると、以下のエラーが出てうまく動作しませんでした。

RuntimeError: CUDA error: no kernel image is available for execution on the device

これは以前も見たことのあるエラーで使ってるグラボが古いときにでます。

であれば対応できるCapabilityで使えるようにビルドし直してもいいかなと思ったのですが、メモリとCPUのキャパオーバーでえげつないことになったので諦めました。

notekunst.hatenablog.com

CUDA capabilityは3.5でギリギリいけると思って落札したのになんでだろうと調べたら、どうやらcapabilityが3.5のサポートはPyTorchのバージョンが1.3までだったようです。最新バージョン(1.10)だと対応している最低バージョンは3.7みたいですね。爪が甘かった…

blog.nelsonliu.me

ならば、この記事にある解決策である以下のコマンドをためそうと思います。

pip install torch==1.3.1+cu92 -f https://nelsonliu.me/files/pytorch/whl/torch_stable.html

しかし、以下のエラーが出ました。

ERROR: Could not find a version that satisfies the requirement torch==1.3.1+cu92 (from versions: 0.1.2, 0.1.2.post1, 0.1.2.post2, 1.4.0, 1.4.0+cu100, 1.4.0+cu101, 1.4.0+cu92, 1.5.0, 1.5.0+cu101, 1.5.0+cu102, 1.5.0+cu92, 1.5.1, 1.5.1+cu101, 1.5.1+cu102, 1.5.1+cu92, 1.6.0, 1.6.0+cu101, 1.6.0+cu102, 1.6.0+cu92, 1.7.0, 1.7.0+cu101, 1.7.0+cu102, 1.7.0+cu92, 1.7.1, 1.7.1+cu101, 1.7.1+cu102, 1.7.1+cu92, 1.8.0, 1.8.0+cu101, 1.8.0+cu102, 1.8.0+cu111, 1.8.1, 1.8.1+cu101, 1.8.1+cu102, 1.8.1+cu111, 1.9.0, 1.9.0+cu102, 1.9.0+cu111, 1.9.1, 1.10.0)
ERROR: No matching distribution found for torch==1.3.1+cu92

これは、Pythonのバージョンとかの依存関係の問題でしょうがこれ原因を探るの辛いので、ダメ元でエラーメッセージにあるインストールできる最低バーションをインストールしてみました。

pip install torch==1.4.0+cu92 torchvision==0.5.0+cu92 -f https://nelsonliu.me/files/pytorch/whl/torch_stable.html

今度はインストールは成功しました。あとは、実際に動作確認してみました。

$ python3
Python 3.8.10 (default, Sep 28 2021, 16:10:42) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> torch.cuda.is_available()
True
>>> torch.cuda.device(0)
<torch.cuda.device object at 0x7fcf3412c160>
>>> torch.cuda.get_device_name(0)
'Quadro K6000'

バイスも認識できて問題なさそうです。

続けて、適当なテンソルを作成してちゃんとグラボ側でキャッシュされるか確認してみます。

>>> a = torch.rand(11000, 11000, device='cuda:0')
>>> b = torch.rand(11000, 11000, device='cuda:0')
>>> print('Allocated:', round(torch.cuda.memory_allocated(0)/(1024**2),1), 'MB')
Allocated: 924.0 MB
>>> print('Cached:   ', round(torch.cuda.memory_reserved(0)/(1024**2),1), 'MB')
Cached:    924.0 MB

しっかりキャッシュが使われていることが確認できました。

実際に適当にSSDの学習をぶん回してみましたが、爆速・爆熱・爆音の3拍子で快適に学習を進めることができました(それだけグラボの負荷がヤバイということでもあるw)!

精度がどうなったかはそのうち今回試したSSDの概要を含めてブログを書きます(本当に書くかわかりませんが…)