俵言

しがない社会人が書く、勉強とかのこと。最近は機械学習や kaggle 関連がメイン。

CUDA 更新のついでに PyTorch と RAPIDS を poetry の同一環境にゴリ押しで共存させた件

はじめに

皆さんお久しぶりです。本当にいつぶりかわからないくらいですが、久々に CUDA の version を更新をするにあたって書きたいネタが出来たのでまとめることにしました。

更新のたびにやっている作業や関連リンクをまとめるというのが当初の目的でしたが、少し前に RAPIDS が pip への提供を試験的に再開したのを思い出し、

medium.com

じゃあ PyTorch と同じ環境に簡単に入れられるんじゃね?と手を出してしまったのが事の始まりでした(結構苦労した...😇)。

同じことをやりたがっている方を Twitter で見かけたのもあり、自分の 備忘録としても知見の共有としてもやり方を書き残そうと思います。

TL;DR

  • CUDA の version を上げるにあたり RAPIDS が PyPI への提供を試験的に始めていたことを思い出し、PyTorch との共存に挑戦
  • 依存関係に気を付ける必要はあるが PyTorch と RAPIDS を同じ poetry 環境に install することにゴリ押しで成功

  • 方法としては、RAPIDS 関連のライブラリの wheel を直に指定する以下の11行*1pyproject.toml に追加する(要 CUDA >= 11.5)

rmm-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/rmm-cu11/rmm_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
ptxcompiler-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/ptxcompiler-cu11/ptxcompiler_cu11-0.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
cubinlinker-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/cubinlinker-cu11/cubinlinker_cu11-0.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
cudf-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/cudf-cu11/cudf_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
dask-cudf-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/dask-cudf-cu11/dask_cudf_cu11-22.10.0-py3-none-any.whl"}
pylibraft-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/pylibraft-cu11/pylibraft_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
ucx-py-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/ucx-py-cu11/ucx_py_cu11-0.28.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
raft-dask-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/raft-dask-cu11/raft_dask_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
cuml-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/cuml-cu11/cuml_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
pylibcugraph-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/pylibcugraph-cu11/pylibcugraph_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
cugraph-cu11 = {url = "https://developer.download.nvidia.com/compute/redist/cugraph-cu11/cugraph_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}

目次

machine の 環境

  • OS: Ubuntu 18.04.6 LTS
  • CPU: Intel(R) Core(TM) i7-7820X CPU @ 3.60GHz
  • CUDA: 11.2 -> 11.7 (今回の件で更新)

準備

今回の本題は RAPIDS と PyTorch を同じ poetry の環境に入れることですが、その前準備として CUDA の更新と PyTorch のインストールをします。

CUDA の入れ替え

これは昔に比べると本当にスムーズになったと思います。まずこちらの記事を参考に、

misoji-engineer.com

CUDA の関連モジュール等を全て削除します。Docker 等に古い環境が残っていなければ以下のコマンドで多分 OK。

sudo apt-get --purge remove nvidia*
sudo apt-get --purge remove cuda*
sudo apt-get --purge remove cudnn*
sudo apt-get --purge remove libnvidia*
sudo apt-get --purge remove libcuda*
sudo apt-get --purge remove libcudnn*
sudo apt-get autoremove
sudo apt-get autoclean
sudo apt-get update
sudo rm -rf /usr/local/cuda*

次に CUDA と Nvidia-Driver の入れ直しですが、こちらに関しても NVIDIA の 佐々木さんがお書きになられた

medium.com

を参考にすればとっても簡単です。CUDA Toolkit Archive のページ から入れたい version を選択すれば、OS などを選択するうちに必要なコマンドを教えてくれます。

私の場合は ubuntu 18.04 に CUDA 11.7.1*2 を入れるので以下のようなコマンドになりました(※: dev(local) を選んだ場合の実行方法)。

$ 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.7.1/local_installers/cuda-repo-wsl-ubuntu-11-7-local_11.7.1-1_amd64.deb
$ sudo dpkg -i cuda-repo-wsl-ubuntu-11-7-local_11.7.1-1_amd64.deb
$ sudo cp /var/cuda-repo-wsl-ubuntu-11-7-local/cuda-*-keyring.gpg /usr/share/keyrings/
$ sudo apt-get update
$ sudo apt-get -y install cuda
$ sudo apt-get -y install cuda-drivers

PyTorch の poetry での install

少し前まで PyTorch を poetry で入れるのにひと悶着あったらしいのですが、今はライブラリの wheel のリンクを直指定する方法で落ち着いたようです。 PyTorch の wheel のダウンロードリンク一覧 から自分の使う Python と CUDA に合致する version のリンクを探し出して pyproject.toml に直書きすれば install が可能です。 私の場合は CUDA 11.7(cu117), Python 3.9(cp39), Ubuntu(linux_x86_64),なので以下のようになりました。

torch = { url = "https://download.pytorch.org/whl/cu117/torch-1.13.0%2Bcu117-cp39-cp39-linux_x86_64.whl"}
torchaudio = { url = "https://download.pytorch.org/whl/cu117/torchaudio-0.13.0%2Bcu117-cp39-cp39-linux_x86_64.whl"}
torchvision = { url = "https://download.pytorch.org/whl/cu117/torchvision-0.14.0%2Bcu117-cp39-cp39-linux_x86_64.whl"}

RAPIDS の poetry での install

ではここからが本題です。時間がかかりすぎて断念した正当な手順と、ゴリ押しで成功した手順の両方を紹介します。

正当な手順 (断念)

RAPIDsの公式ページ に pip での insall 手順が記載されています。

pip install cudf-cu11 dask-cudf-cu11 --extra-index-url=https://pypi.ngc.nvidia.com
pip install cuml-cu11 --extra-index-url=https://pypi.ngc.nvidia.com
pip install cugraph-cu11 --extra-index-url=https://pypi.ngc.nvidia.com

後ろに見慣れない --extra-index-url が付いていますね。これは、単純に pip install XXX を行っても対応するライブラリが存在しない場合に、ライブラリを置いている場所を明示的に指定してそこを pip に探してもらうために付けるようです。

さて、これと同様のことを行うために poetry では poetry source add を使います。

poetry source add cudf-cu11 https://pypi.ngc.nvidia.com
poetry source add dask-cudf-cu11 https://pypi.ngc.nvidia.com
poetry source add cuml-cu11 https://pypi.ngc.nvidia.com
poetry source add cugraph-cu11 https://pypi.ngc.nvidia.com

source を指定することによって、これらのライブラリを探しに行く場所を指定することが出来ました。 これであとは

poetry add cudf-cu11 dask-cudf-cu11 cuml-cu11 cugraph-cu11

をすればOK!のはずだったのですが...

なんと2時間近く経過しても依存関係解決が終わりませんでした。どうやら、poetry では source の情報を加えた際に例えそのライブラリを install しようとしていなくても すさまじい時間がかかるようです。 今回だけなら良いですが勿論ライブラリは適宜追加する場合があるので1回に2時間とかやってられません。

どうしたものか... と悩んでいた俵に天啓が下ります、「PyTorch と同じ事すればいいんじゃね?」と。

ゴリ押し手順(成功)

というわけで、PyTorch 同様に wheel file の URL を直指定する作戦を思いついたのですが、問題はその URL がわからんということでした。 そこで pip download を用いることでダウンロード先を特定します。例えば cudf-cu11 なら以下のように行います。

(因みに cudf_wheels ディレクトリを作って -d で保存先に指定しているのはのは後で削除するのを楽にするためで、必須ではありません。)

$ mkdir cudf_wheels
$ pip download -d cudf_wheels cudf-cu11 --extra-index-url=https://pypi.ngc.nvidia.com
Looking in indexes: https://pypi.org/simple, https://pypi.ngc.nvidia.com
Collecting cudf-cu11
  Downloading https://developer.download.nvidia.com/compute/redist/cudf-cu11/cudf_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (435.2 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 435.2/435.2 MB 4.5 MB/s eta 0:00:00
Collecting numpy
  Downloading numpy-1.23.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (17.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.1/17.1 MB 50.4 MB/s eta 0:00:00
Collecting cupy-cuda115<12.0.0a0,>=9.5.0
  Downloading cupy_cuda115-10.6.0-cp39-cp39-manylinux1_x86_64.whl (81.5 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 81.5/81.5 MB 21.1 MB/s eta 0:00:00
Collecting cachetools
  Downloading cachetools-5.2.0-py3-none-any.whl (9.3 kB)
Collecting numba>=0.54
  Downloading numba-0.56.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (3.5 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.5/3.5 MB 46.1 MB/s eta 0:00:00
Collecting cubinlinker-cu11
  Downloading https://developer.download.nvidia.com/compute/redist/cubinlinker-cu11/cubinlinker_cu11-0.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.8 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.8/8.8 MB 15.1 MB/s eta 0:00:00
Collecting protobuf<3.21.0a0,>=3.20.1
  Downloading protobuf-3.20.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl (1.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.0/1.0 MB 47.2 MB/s eta 0:00:00
Collecting packaging
  Downloading packaging-21.3-py3-none-any.whl (40 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40.8/40.8 kB 4.6 MB/s eta 0:00:00
Collecting cuda-python<11.7.1,>=11.5
  Downloading cuda_python-11.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.4 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.4/16.4 MB 51.6 MB/s eta 0:00:00
Collecting ptxcompiler-cu11
  Downloading https://developer.download.nvidia.com/compute/redist/ptxcompiler-cu11/ptxcompiler_cu11-0.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.8 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.8/8.8 MB 18.1 MB/s eta 0:00:00
Collecting fsspec>=0.6.0
  Downloading fsspec-2022.11.0-py3-none-any.whl (139 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 139.5/139.5 kB 2.1 MB/s eta 0:00:00
Collecting rmm-cu11
  Downloading https://developer.download.nvidia.com/compute/redist/rmm-cu11/rmm_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.5/3.5 MB 15.2 MB/s eta 0:00:00
Collecting pyarrow==9.0.0
  Downloading pyarrow-9.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (35.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 35.3/35.3 MB 32.8 MB/s eta 0:00:00
Collecting pandas<1.6.0dev0,>=1.0
  Downloading pandas-1.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.2 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.2/12.2 MB 55.5 MB/s eta 0:00:00
Collecting typing-extensions
  Downloading typing_extensions-4.4.0-py3-none-any.whl (26 kB)
Collecting nvtx>=0.2.1
  Downloading nvtx-0.2.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (441 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 441.3/441.3 kB 34.0 MB/s eta 0:00:00
Collecting cython
  Downloading Cython-0.29.32-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (2.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.0/2.0 MB 56.3 MB/s eta 0:00:00
Collecting fastrlock>=0.5
  Downloading fastrlock-0.8.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_24_x86_64.whl (49 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.4/49.4 kB 6.3 MB/s eta 0:00:00
Collecting setuptools
  Downloading setuptools-65.6.3-py3-none-any.whl (1.2 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 50.5 MB/s eta 0:00:00
Collecting llvmlite<0.40,>=0.39.0dev0
  Downloading llvmlite-0.39.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (34.6 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 34.6/34.6 MB 35.6 MB/s eta 0:00:00
Collecting python-dateutil>=2.8.1
  Downloading python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 247.7/247.7 kB 29.1 MB/s eta 0:00:00
Collecting pytz>=2020.1
  Downloading pytz-2022.6-py2.py3-none-any.whl (498 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 498.1/498.1 kB 41.6 MB/s eta 0:00:00
Collecting pyparsing!=3.0.5,>=2.0.2
  Downloading pyparsing-3.0.9-py3-none-any.whl (98 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.3/98.3 kB 13.2 MB/s eta 0:00:00
Collecting six>=1.5
  Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
...

長々と出力を掲載してしまいましたが、 cudf-cu11 のダウンロード先である https://developer.download.nvidia.com/compute/redist/cudf-cu11/cudf_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl を特定することが出来ました。

そして、もうお気づきになられている方もいると思われますが、上の出力をよく見ると cudf-cu11 以外にも https://developer.download.nvidia.com/compute/redist からダウンロードされているライブラリ(cubinlinker-cu11, ptxcompiler-cu11, rmm-cu11, )があります。これが一番のめんどくさポイントで、これらも通常の PyPI では見つからないライブラリであるために URL の直指定を行う必要があります。 cudf-cu11, dask-cudf-cu11, cuml-cu11, cugraph-cu11 の4つだけでいいと思い込んでいて poetry lock が failed したときは焦ったんですが、なるほどなあという感じです。

というわけで、最終的に11個のライブラリの URL を以下のように pyproject.toml で直指定し、

rmm-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/rmm-cu11/rmm_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
ptxcompiler-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/ptxcompiler-cu11/ptxcompiler_cu11-0.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
cubinlinker-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/cubinlinker-cu11/cubinlinker_cu11-0.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
cudf-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/cudf-cu11/cudf_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
dask-cudf-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/dask-cudf-cu11/dask_cudf_cu11-22.10.0-py3-none-any.whl"}
pylibraft-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/pylibraft-cu11/pylibraft_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
ucx-py-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/ucx-py-cu11/ucx_py_cu11-0.28.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
raft-dask-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/raft-dask-cu11/raft_dask_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
cuml-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/cuml-cu11/cuml_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
pylibcugraph-cu11 = { url = "https://developer.download.nvidia.com/compute/redist/pylibcugraph-cu11/pylibcugraph_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}
cugraph-cu11 = {url = "https://developer.download.nvidia.com/compute/redist/cugraph-cu11/cugraph_cu11-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"}

無事に PyTorch と RAPIDS を同じ poetry 環境に入れることが出来ました🎉

おわりに

分析を行う上で PyTorch と RAPIDS を同じ環境で使いたいという欲求は今まで何度かあったのですが、そもそも対応する CUDA が違って無理だったりと中々うまく行きませんでした。今回遂に poetry の同一環境に入れることが出来て感無量なところあります。

Kaggle でも巨大なテーブルデータ(またはログデータ)を扱い、しかも NN と RAPIDS の両方を扱いたいなんてケースは昨今少なくありません。 そういった場合に、「Kaggle Docker 出来れば使いたくないんだよな...」って人にこの記事が役立てば幸いに思います。

それではまた次の記事でお会いしましょう、ではでは 👋

*1:私の環境での話なので、別の環境では異なる wheel file を指定する必要があるかもしれません。

*2:繰り返しになりますが RAPIDS の要件が 11.5 以上だったのでこれにしました