ゆるふわクオンツの日常

wsl2のpoetry/uv環境にcupyとcudf (RAPIDS) をインストールした話

久しぶりに書きます!

手元のwsl環境で、pythonをちょっと高速化させたくなったのでcupyとcudfを入れてみました!

step.1 wsl環境に直接cuda toolkitをインストールする

まずはインストールしたいライブラリのcudaのバージョンの対応状況を確認します。

cupyの対応バージョン確認

こちらのcupyのサイトによると
docs.cupy.dev

ということで、本記事作成時点の最新版であるcuda 12.6まで対応していることがわかりました。

cudfの対応バージョン確認

続いて、cudfのサイトを見ると

docs.rapids.ai

というわけで cuda 12.5 までのようです。

以上を踏まえて、両対応をするために、cudaは12.5をインストールしたいと思います。

cudaのインストール

cuda toolkitのインストールは下記の公式サイトに表示されたコマンドを叩くだけでOKです。

developer.nvidia.com

こちらを順に叩いていきまして、下記の通り .bashrc に下記のpathを通せばOKです。

export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"

動作確認は nvcc -V でうまくインストールできていれば以下のように表示されます。

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2024 NVIDIA Corporation
Built on Thu_Jun__6_02:18:23_PDT_2024
Cuda compilation tools, release 12.5, V12.5.82
Build cuda_12.5.r12.5/compiler.34385749_0

step.2 cupyのpoetry/uv add

あとは通常通り poetry add ないしは uv add していけばよいです。

poetry add cupy-cuda12x
uv add cupy-cuda12x

step.3 cudf (RAPIDS) のpoetry/uv add

ここも先ほどのRAPIDSの公式ページに表示されているインストールコマンドを

poetryに書き換えるだけで大丈夫です。

poetry run pip install \
    --extra-index-url=https://pypi.nvidia.com \
    cudf-cu12==24.10.* dask-cudf-cu12==24.10.* cuml-cu12==24.10.* \
    cugraph-cu12==24.10.* nx-cugraph-cu12==24.10.* cuspatial-cu12==24.10.* \
    cuproj-cu12==24.10.* cuxfilter-cu12==24.10.* cucim-cu12==24.10.* \
    pylibraft-cu12==24.10.* raft-dask-cu12==24.10.* cuvs-cu12==24.10.* \
    nx-cugraph-cu12==24.10.*
uv add --extra-index-url=https://pypi.nvidia.com \
    cudf-cu12==24.10.* dask-cudf-cu12==24.10.* cuml-cu12==24.10.* \
    cugraph-cu12==24.10.* nx-cugraph-cu12==24.10.* cuspatial-cu12==24.10.* \
    cuproj-cu12==24.10.* cuxfilter-cu12==24.10.* cucim-cu12==24.10.* \
    pylibraft-cu12==24.10.* raft-dask-cu12==24.10.* cuvs-cu12==24.10.* \
    nx-cugraph-cu12==24.10.* --index-strategy unsafe-best-match

WSL2上のUbuntu22.04でGPU版 tensorflow / pytorch 環境設定をトトノエル

ちょっと深層強化学習を勉強しようと思いまして、ついでに(?)

windowsのwsl2に新しいubuntu 22.04を入れようと思い立ちましたのでそのメモと、

tensorflowとpytorchのGPU深層学習環境の整備について書いていこうかと思います。

WSL2の初期設定

Linux環境の各種アップデート

sudo apt update
sudo apt upgrade

これでOK。

systemctlの有効化

devblogs.microsoft.com

こちらを参考にsystemctlを使えるようにします。

まず、/etc下にwsl.confを作ります。

sudo touch wsl.conf

wsl.confの中には以下の通り記載します。

[boot]
systemd=true

その後、Ubuntuから一旦抜けて、WSLディストリビューションの再起動を行います。

C:\>wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu                 Running         2
C:\>wsl -t Ubuntu
この操作を正しく終了しました。
C:\>wsl -d Ubuntu

これでsystemctlが使えるようになっているはずです。

gitの設定

続いて、git関連の設定を行います。

qiita.com

こちらに従ってsshの設定をします。

自分のgithubアカウントにssh接続できるように以下で公開鍵と秘密鍵を作ります。

cd  ~/.ssh
ssh-keygen -t rsa

あとはこの公開鍵部分をgithubに手動で登録すればOKです。

動作確認は

ssh -T git@github.com

続いてconfig設定。

gitのユーザーネームとメールアドレスを設定します。

git config --global user.name "hoge"
git config --global user.email hoge@hoge.com

pyenv & python & poetryについて

各分析プロジェクトは、python本体をpyenvで、

pythonに付随するライブラリをpoetryでコントロールする環境を構築したいので以下を設定します。

poetry

まず、pythonライブラリのバージョン管理用にpoetryを使うのでinstallします。

これも公式がわかりやすいのでそのコマンドを打つだけです。

python-poetry.org

curl -sSL https://install.python-poetry.org | python3 -

パスを通せ、と言われたら従ってください。

あと、仮想環境は各プロジェクトフォルダに作りたいので以下のブログのように設定をします。

https://maasaablog.com/development/backend/python/5161/#toc2maasaablog.com

poetry config virtualenvs.in-project true
poetry config virtualenvs.prefer-active-python true

pyenv

次にpyenvを入れていきます。

git clone https://github.com/pyenv/pyenv.git ~/.pyenv

あとは~/.bashrcに以下を書き込みます。

# pyenv
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"

上記の .bashrc を読み込むためにターミナルを再起動することで

pyenvコマンドが使えるようになっていると思います。

ちなみに

https://github.com/pyenv/pyenv#getting-pyenv

によると、以下のコマンドを実行することでpyenvの挙動が早くなるみたいです。

なお、build-essentialがないとgccがなくてコマンドに失敗するので合わせて入れておきます。

sudo apt install build-essential
cd ~/.pyenv && src/configure && make -C src

python

そんでもって miniforge の(この記事執筆時点で)一番新しいpythonを入れたいと思います。

pyenv install miniforge3-22.9.0-3
pyenv global miniforge3-22.9.0-3

GPU版 tensorflow

www.tensorflow.org

だいたい、この公式ドキュメントに沿って進めていきますが、

condaでの環境切り分けではなくpyenvで環境を切り分けます。

まず、この記事執筆時点では上記の公式ドキュメントでは3.9系のpythonが使用されているため、

python3.9系のminiforgeを探します(→ miniforge3-4.13.0-1)。

pyenv install miniforge3-4.13.0-1
pyenv global miniforge3-4.13.0-1
conda update conda

続いて、 CUDAcuDNN を公式ドキュメント同様condaで入れます。

conda install -c conda-forge cudatoolkit=11.2 cudnn=8.1.0

そのあとは環境変数の設定部分ですが、とりあえず以下を打ち込みます。

export LD_LIBRARY_PATH=":/home/ユーザーネーム/.pyenv/versions/miniforge3-4.13.0-1/lib/"

(これでとりあえずは問題なく動くのですが、上記の環境変数の設定だと何かの拍子に消えてたりするので、

ここは公式サイトのように環境切り替え時に自動で環境変数を設定したほうがよさそうです。

が、やり方わからないので一旦放置します。)

そしてtensorflowを入れていきます

pip install --upgrade pip
pip install tensorflow

注意すべきは、TensorFlow を conda でインストールしてはダメということです。

TensorFlow は PyPI にのみ公式にリリースされているため、pip が推奨されるそうです。

このへん含めて、環境は切り分けておいた方が無難ですね。

完了すれば、動作確認です。

python -c "from tensorflow.python.client import device_lib; print(device_lib.list_local_devices())"

これでGPUらしきものが返ってくればOKです。

なお、warningやinfoが山盛りで見ずらい場合は、

WとIのログを非表示にするオプションも検討してみるといいかもしれません。

TF_CPP_MIN_LOG_LEVEL=2 python -c "from tensorflow.python.client import device_lib; print(device_lib.list_local_devices())"

GPU版 pytorch

tensorflowと同じような感じで進めていきます。

python3.10系のminiforgeを探します(miniforge3-4.14.0-2あたり)。

pyenv install miniforge3-4.14.0-2
pyenv global miniforge3-4.14.0-2
conda update conda
conda install python=3.10 # 初期バージョンがシステムと同じだったので少しバージョンを上げましたが特にしなくても問題ないです。

ちなみにpythonのバージョンに強いこだわりはないです。

次にpytorchのサイトで、どんなふうにインストールするかを決めていきます。

どうやらこの記事執筆時点ではcuda 11.7 が最新のようですので、

それでインストールしていこうかとおもいます。

conda install pytorch torchvision torchaudio pytorch-cuda=11.7 -c pytorch -c nvidia

動作確認は

import torch
torch.cuda.is_available()

でTrueと返ってくればOKです

Poetryでpytorch環境を作るには(deprecated)

上記の conda install の代わりにpoetryでも簡単に設定でき(pytorchのサイトでpipを使ったインストールコマンドを参考に)

poetry add torch torchvision torchaudio

でも環境設定できます。

もちろん torch.cuda.is_available() もTrueになるのでご安心。

Poetryでpytorch環境を作るには(追記2023/10/08)

久しぶりに環境を作ったら poetry add torch torchvision torchaudio がエラーになったのでその対応について記載します。

基本的に以下に記載の内容をそのまま行えばよいです。

zenn.dev

まず、Pytorch公式サイトから、cudaのurlを取得します。

上記のurlを参考に、poetryにcudaのリンクを追加を行います。

poetry source add torch_cu118 --priority=explicit https://download.pytorch.org/whl/cu118

上記のソース追加が終われば、Pytorch公式サイトのコマンドを実行して完了です。

poetry add torch torchvision torchaudio --source torch_cu118

おまけ(GPU版 jax & flax)

このtorch環境のcudaとcudnnはGPU版のjax(とそのラッパー的なflax)にも対応できるのでついでに入れてみました。

(conda listすると、cuda11.7_cudnn8.5.0_0と記載がありました)

github.com

github.com

pip install "jax[cuda11_cudnn82]" -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html
pip install flax

動作確認は

import jax
jax.default_backend()

GPUが返ってくればOKです。

Chromebookに論文執筆環境(TeXLive+TeXworks)を設定する!

どうもお久しぶりです!

諸事情により全然ブログが更新できず、ぐぬぬって感じです。

まぁあと2,3年はこんな感じが続きそうですが、すきを見て書ければと思います。

で、今回はChromebookに論文執筆環境を設定するお話です。

今時Overleafもあるので普通にブラウザだけあればなんとかなるのでは?

という声も聞こえてきそうですが、

やはりVScodeが使えると何かと便利だったりするのでね。

あと、最近はノートPCを持ち歩いて開発したりすることもあんまりなかったので

今までのノートPC=macbook pro生活からChromebookに乗り換えてみようとも思いまして。

なお、今回の虎の巻は以下の通りです。

www.tug.org

端末

jp.ext.hp.com

この度こちらの端末をHPのアウトレットストアにて購入しました~

見た目がそこそこ良さそうでArm系のCPUでファンレス

そしてバッテリー持ちがめっちゃ良さそうだったので買ってみました!

Step.1 Linuxコンテナのactivate

ChromebookにはデフォルトでLinuxモードが存在します。

そちらをオンにすればOKです。

これは普通に設定アプリからボタンをクリックするだけなので問題ないかと思います。

Step.2 DebianLinux)のupdate

これはいつもの sudo apt updatesudo apt upgrade ですね。

Step.3 TeXLiveのインストール

まずは、インストール作業を行うディレクトリを作成します。

ただの作業場なのであとで削除できるのでどこでもいいですが、今回は /usr/local とします。

sudo mkdir /usr/local/tex
cd /usr/local/tex

続いてインストールファイルのダウンロード&解凍を行います。

sudo wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz
sudo tar xvzf install-tl-unx.tar.gz

解凍されたフォルダに入りまして、インストールコマンドの実行をします。

cd install-tl-****
sudo ./install-tl

このコマンドは結構時間がかかるので座して待ちましょう。

これでインストール自体は完了です。

インストールが終わったら、.bashrc にpathを通すために

vimで.bashrcを開きます。

cd ~
vi .bashrc

これでvimで書き込み画面になるかと思いますが、

最後に一つトラップがあって、pathがcpuによって異なります。

ARM系は export PATH=$PATH:/usr/local/texlive/2022/bin/aarch64-linux
Intel系は export PATH=$PATH:/usr/local/texlive/2022/bin/x86_64-linux を.bashrcに追加です。

今回のPCはARM系のほうを追加しました。

そしておまけで、以下のコマンドで作業フォルダを削除します。

sudo rm -r /usr/local/tex

Step.4 動作確認

pathが通っていればターミナルを再起動して以下のコマンドで動作確認しましょう。

platex -version

これでそれっぽいversionが帰ってくれば一件落着です。

私の環境では以下が返ってきました。

e-pTeX 3.141592653-p4.0.0-220214-2.6 (utf8.euc) (TeX Live 2022)
kpathsea version 6.3.4
ptexenc version 1.4.0
Copyright 2022 D.E. Knuth.
There is NO warranty.  Redistribution of this software is
covered by the terms of both the e-pTeX copyright and
the Lesser GNU General Public License.
For more information about these matters, see the file
named COPYING and the e-pTeX source.
Primary author of e-pTeX: Peter Breitenlohner.

なお、windowsならtexliveに標準でついてくるtexworks editorをインストールするには

sudo apt install texworks

でOKです。

インストールが終わったらLinuxアプリとして追加されているかと思います。

今回の関連書籍

LaTeXを初めて使う人は、とりあえずこういった本が一冊あると良いかなと思います。

ラデマッハ複雑度と一様大数の法則のお気持ちについて

大数の法則はいろいろな書籍で言及される超有名な法則なわけですが、

昨今の機械学習などではこれを少し発展させて、

所々の仮定のもとで以下の一様大数の法則を用いたりします。

 \displaystyle \sup_{g \in G} |\frac{1}{n}\sum_{i=1}^{n}g(X_{i})-E[g(X)]| \xrightarrow{p} 0

いわゆる大数の法則との違いは関数クラスでsupをとっているところです。

機械学習では学習した関数が(全ての)訓練データに依存する構造になっているので、

そこの依存関係を考慮した上で確率収束の議論をやりたいからです。

つまり、何らかの学習を経て得られた g n個のデータに依存して決まっており、

 g(X_i)が独立ではないため、通常の大数の法則が適用できなくなっています。

そこで、supを考えることでデータ依存をなくした議論をしようとしているわけです。

てなわけで、

今回は一様大数の法則と密接に関連するラデマッハ複雑度について見ていきます。

Rademacher complexity

 ||g||_{\infty} \le M \forall g \in Gとする。

このとき、関数族 Gに対してラデマッハ複雑度を以下のように定義します。

 \sigma_iを以下を満たすiidなラデマッハ変数とする。
 \displaystyle P(\sigma_i=1)=P(\sigma_i=-1)=\frac{1}{2}
このとき、観測データ x_1, x_2,...を用いて以下のように定義される変数を経験ラデマッハ複雑度といい
 \displaystyle \hat{R}_{n}(G)=E_{\sigma}[\sup_{g\in G}|\frac{1}{n}\sum_{i=1}^{n}\sigma_i g(x_i)| ]
このxが確率分布に従っているとして、期待値をラデマッハ複雑度といいます。
 R_{n}(G)=E_{X}[\hat{R}_{n}(G)]

ここで、 \hat{R}_{n}(G)において、サンプル平均 \displaystyle \frac{1}{n}\sum_{i=1}^{n}g(x_i) ではなく

 \displaystyle \frac{1}{n}\sum_{i=1}^{n}\sigma_i g(x_i)のように \sigma_iを挟んだものを考えています。

これは、ランダムなノイズ \sigma_i g(x_i)の相関みたいなものを表していて、

関数クラスGにおいてその相関をどれくらい高めることができるか

というのがラデマッハ複雑度の直感的なイメージかと思います。

別の言い方をすると、

ランダムノイズに対してGがどれくらい追従出来るかの指標ですかね。

なお、今後

 \displaystyle Pg = E[g(X)], P_ng = \frac{1}{n}\sum_{i=1}^{n}g(X_{i})とする。

で、

早速このラデマッハ複雑度にまつわる定理を見ていきます!

Thm (対称化)
 E_{X_i}[ \sup_{g\in G}|(P-P_n)g| ] \le 2R_n(G)

この定理、一様大数の法則と似ていますよね!

この期待値の中身は実は結構解析しにくかったりするので、

このようにラデマッハ複雑度で上から抑えて、

そしてそのラデマッハ複雑度をさらに何かで抑えたりするのがよく使われる手法です。

それではこれを証明していきます。

左辺は、X_iと同じ分布に従うX_i'を用いて以下のように変形でき

 \displaystyle = E_{X_i}[ \sup_{g \in G}|E_{X_i'}[ \frac{1}{n}\sum_{i=1}^n g(X_i') ]-\frac{1}{n}\sum_{i=1}^n g(X_i)|]

イェンセンの不等式( E[|・|] \ge |E[・]|, E[sup(・)] \ge sup(E[・]))より

 \displaystyle \le E_{X_i,X_i'}[ \sup_{g \in G} |\frac{1}{n}\sum_{i=1}^n(g(X_i')-g(X_i))|]

X_iX_i'は同じ分布に従うので

 \displaystyle = E_{\sigma_i} E_{X_i,X_i'}[ \sup_{g \in G} |\frac{1}{n}\sum_{i=1}^n \sigma_i(g(X_i')-g(X_i))|]

三角不等式より

 \displaystyle \le E_{\sigma_i} E_{X_i'}[ \sup_{g \in G} |\frac{1}{n}\sum_{i=1}^n \sigma_ig(X_i')|] + E_{\sigma_i} E_{X_i}[ \sup_{g \in G} |\frac{1}{n}\sum_{i=1}^n \sigma_ig(X_i)|]

フビニの定理より

 = 2R_n(G)

とまぁこれで、

確率変数 \sup_{g\in G}|(P-P_n)g|の期待値を上から抑えることに成功しました。

続いて、この確率変数の裾確率について見ていきます。

Thm
 \displaystyle P(\sup_{g\in G}|(P-P_n)g| \ge 2R_n(G)+ M \sqrt{\frac{2\log{\frac{1}{\delta}}}{n}}) \le \delta

これは、   \sup_{g\in G}|(P-P_n)g| の期待値が 2R_n(G) で抑えられることを思い出すと、

   \sup_{g\in G}|(P-P_n)g| が期待値からどれくらいずれうるのかを示しています。

これを示すために以下の関係性を利用します。

McDiamid の不等式
 X_1, ...,X_nを独立な(同一とは限らない)確率変数とする。
 fを可測関数とし
 |f(x_1,...,x_i,...,x_n)-f(x_1,...,x_{i'},...,x_n)| \le C_{i}
が任意の x_1,...,x_n,x_{n'}について成り立つとき、
 \displaystyle P(f(X_1,...,X_n)-E[f(X_1,...,X_n)] \ge \epsilon) \le \exp\{-\frac{2\epsilon^2}{\sum_{i=1}^{n}c_{i}^2}\}

いま、 ||g||_{\infty} \le Mより

 \displaystyle f(x_1,...,x_n) = \sup_{g \in G}|\frac{1}{n}\sum_{i=1}^n g(x_i)-Pg| とおくと

 f(x_1,...,x_n) - f(x_1,...,x_{i'},...,x_n)

 \displaystyle = \sup_{g \in G}|\frac{1}{n}\sum_{j\neq i}^n g(x_i) + \frac{g(x_{i})}{n} + \frac{g(x_{i}^{'})}{n} - \frac{g(x_{i}^{'})}{n} -Pg| - \sup_{g \in G}|\frac{1}{n}\sum_{j\neq i}^n g(x_j) + \frac{g(x_{i}^{'})}{n} -Pg|

 \displaystyle \le \sup_{g \in G}|\frac{1}{n}\sum_{j\neq i}^n g(x_i) + \frac{g(x_{i}^{'})}{n} -Pg| + \sup_{g \in G} |\frac{g(x_{i})}{n} - \frac{g(x_{i}^{'})}{n}|- \sup_{g \in G}|\frac{1}{n}\sum_{j\neq i}^n g(x_j) + \frac{g(x_{i}^{'})}{n} -Pg|

 \displaystyle \le \frac{2M}{n}

同様にして \displaystyle f(x_1...,x_{i'},...,x_n) - f(x_1,,...,x_n) \le \frac{2M}{n} も成り立つので

McDiamidの不等式に代入することで、

 \displaystyle P(\sup_{g\in G}|(P-P_n)g| \ge 2R_n(G)+ M \sqrt{\frac{2\log{\frac{1}{\delta}}}{n}}) \le \delta

が得られる。

 

閑話休題

 

具体的に線形関数の集合  G=\{g(x)=w^T x\} のラデマッハ複雑度を考えると

 \displaystyle R_n(G) \le \frac{A}{\sqrt{n}}というように \frac{1}{\sqrt{n}}で抑えられることがわかります。

そうとわかれば、対称性を用いて、

 \displaystyle E[\sup_{g \in G} |\frac{1}{n}\sum_{i=1}^{n}g(X_{i})-E[g(X)]| ] \le 2R_n(G) \xrightarrow{p} 0 と0に収束することがわかり

裾確率の議論を用いて、 \displaystyle \sup_{g \in G} |\frac{1}{n}\sum_{i=1}^{n}g(X_{i})-E[g(X)]|が確率収束していることも

なんとなくわかりそうです(一様大数の法則)。

このように、やや取り扱いにくい \sup_{g\in G}|(P-P_n)g|のような変数を、

上から抑えられ、比較的解析しやすいのがラデマッハ複雑度の良さでしょうか。

あまり汎化誤差解析を体系だって学んだことがないのですが、

こういう議論も面白いですね!

今回の関連書籍

内容もしっかりしているいい本だと思います。

Ubuntu 22.04(WSL2)にアップグレードしたらRstudioが動かなくなったので色々探して動くようにした件

新しい物好きなのでwsl2上のUbuntuを以下の記事に従って22.04にアップデートしたところ、

zenn.dev

見事にRstudioが動かなくなりました!!

今回は対応策について調べたことをまとめておきます!

といっても以下のRstudioのコミュニティのissueが全てではありました。

community.rstudio.com

Ubuntu 22.04になることでDependency errorになってしまうのですが、

開発中ではあるものの、Ubuntu 22.04対応のrstudioが以下のリンク先にあるとのとこ。

dailies.rstudio.com

上記リンク先のRstudioをインストールすることで無事動くようになりました。

めでたしめでたし