Paperspace gradientでpythonのversionを変える

# はじめに
最近PaperspaceでStablediffusionを動かして画像生成をするのにはハマっている。
しかしPaperspace gradientにデフォルトで導入されているPythonのバージョンは3.9であり、[web-uiのreadme](https://github.com/AUTOMATIC1111/stable-diffusion-webui#installation-and-running)にもある通り推奨されているバージョン(python3.10)ではない。

デフォルトの3.9でも動いているからヨシ！...でもいいのだが、気になってしまったので解決法を考えてみる。

# Paperspace gradientについて
そもそもPaperspaceってなんぞや？という方もいるかもしれないので簡単な説明。
>Hello, we're Paperspace
>Paperspace is the cloud platform built for the future. Tens of thousands of individuals, startups >and enterprises use Paperspace to power a range of next-generation applications.
>
>[About - paperspace](https://www.paperspace.com/about)

Paperspaceはクラウド上で仮想マシンやクラウドGPUを提供している企業。
この企業が提供しているサービスの1つが[gradient](https://www.paperspace.com/gradient)であり、クラウドベースで機械学習やDeepLearningに必要なインフラ、ツール、フレームワークなどを提供している。

gradientで魅力的なのは手元に高性能なGPUがなくてもクラウド上で使える点、そしてプラン設定にもよるがQuadroA4000やTeslaA100などのつよつよGPUを無料で使えてしまう点(有料プランの月額課金が必要)だ。

アカウントを作成すれば有料プランでなくても完全無料のGPU(QuadroM4000、GTX1650相当)が利用できるので試してみるのもよいだろう。

# 動作環境
* Paperspace gradient -pro
* [Paperspace_nios_tmp](https://note.com/ai_nios/n/n2203de79bc16#142ea6a0-dd47-4b24-83ad-584dfaecc49b)(私がweb-uiを実行するのに使用しているJupyterNotebookの配布元)
* [camenduru/stable-diffusion-webui](https://github.com/camenduru/stable-diffusion-webui/branches) v2.1
* Pytorch = 1.13.1+cu116
* CUDA 11.6
* xformers = 0.0.16


# 1. apt install で直接入れる
多くに人が最初にやりそうな方法。
インストール自体はできるが、バージョンを確認すると元の3.9のままになっている。

```shell-session
root@nwg6ka6716:/notebooks# apt -y install python3.10
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libpython3.10-minimal libpython3.10-stdlib python3.10-minimal
Suggested packages:
  python3.10-venv binfmt-support

----省略

Setting up python3.10 (3.10.11-1+focal1) ...
Processing triggers for mime-support (3.64ubuntu1) ...
Processing triggers for man-db (2.9.1-1) ...

root@nwg6ka6716:/notebooks# python -V
Python 3.9.16
root@nwg6ka6716:/notebooks# python3 -V
Python 3.9.16
```

インストール先を見るとpythonの入っている場所がデフォルトと違う。

```shell-session
root@nwg6ka6716:/notebooks# which python
/usr/local/bin/python
root@nwg6ka6716:/notebooks# which python3
/usr/local/bin/python3
root@nwg6ka6716:/notebooks# which python3.10
/usr/bin/python3.10
```

`python3.10`と指定して呼び出せば3.10が利用できた。

```shell-session
root@nwg6ka6716:/notebooks# python3.10 -V
Python 3.10.11
```

`pip`も普通に呼び出すとデフォルトのpythonにインストールされてしまうので、`python3-pip`をインストールして使う。

```shell-session
root@nbhzad3rho:/notebooks# apt install -y python3-pip
Reading package lists... Done
Building dependency tree       

----省略

Setting up python3-pip (20.0.2-5ubuntu1.8) ...
Processing triggers for man-db (2.9.1-1) ...
root@nbhzad3rho:/notebooks# pip -V
pip 22.3.1 from /usr/local/lib/python3.9/dist-packages/pip (python 3.9)
root@nbhzad3rho:/notebooks# python3.10 -m pip -V
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)
```

:::note info
`python3.10 -m pip install モジュール名`で`ImportError: cannot import name 'html5lib' from 'pip._vendor'`エラーが出た場合、`pip`のアップグレードを行う。
```shell-session
# curl -sS https://bootstrap.pypa.io/get-pip.py | python3.10
```
:::
## web-uiを動かしてみる
今まで使っていたJupyterNotebookの`python`を`python3.10`に、`pip install`を`python3.10 -m pip install`に置き変えてから起動してみる。

```JupyterNotebook:RunWebUi.ipynb
%cd /notebooks
!python3.10 -m pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116 -U
!python3.10 -m pip install -q xformers==0.0.16
!python3.10 -m pip install -q triton==2.0.0

%cd /notebooks/stable-diffusion-webui
#実行
```

```shell-session
Python 3.10.11 (main, Apr  5 2023, 14:15:10) [GCC 9.4.0]
Commit hash: a9fed7c364061ae6efb37f797b6b522cb3cf7aa2
Installing gfpgan
Installing clip

----省略

Model loaded in 27.8s (calculate hash: 21.1s, load weights from disk: 0.2s, create model: 1.1s, apply weights to model: 2.9s, apply half(): 0.5s, load VAE: 1.4s, move model to device: 0.6s).
*Deforum ControlNet support: enabled*
Running on local URL:  http://127.0.0.1:7860
Running on public URL: https://**********-49d0.gradio.live

This share link expires in 72 hours. For free permanent hosting and GPU upgrades (NEW!), check out Spaces: https://huggingface.co/spaces
Startup time: 82.3s (import gradio: 1.7s, import ldm: 0.8s, other imports: 5.1s, list extensions: 1.5s, setup codeformer: 0.4s, load scripts: 38.8s, load SD checkpoint: 28.0s, create ui: 4.4s, gradio launch: 1.5s).
```
web-ui側でも`python3.10.11`が確認できた。
![qiita_paperspace5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998315/ec58b507-e117-f923-a808-45829f6d193a.jpeg)


# 2. Notebook作成時に任意のコンテナイメージを指定する
Notebookを作成時、コンテナイメージを指定するフィールドがあるので、そこに自分の欲しい環境のイメージを入れる方法。
詳しくは(というかほとんど)[Paperspaceのドキュメント](https://docs.paperspace.com/gradient/notebooks/runtimes/#how-to-specify-a-custom-container)を見れば書いてあるが、それだと記事の意味がないので詳しい手順も載せる。

## Notebookを作成
Notebooksを作成するページのここ(画像赤枠)にAdvanced optionsがあり、
![qiita_paperspace1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998315/69e71ffe-e5f4-e839-d040-13a33238ad23.jpeg)

この部分(画像赤枠)にコンテナイメージを指定することができる。(この状態はPaperspaceのデフォルト)
![qiita_paperspace2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998315/5c73b0f2-6a26-cedb-5c18-058bb431b639.jpeg)

指定するイメージはDockerHubとかで探すこともできる(paperspaceとかgradientとかで検索すると出てくる)。
今回は[stable-diffusion-paperspace](https://github.com/Engineer-of-Stuff/stable-diffusion-paperspace)に指定されているコンテナを使う。

https://hub.docker.com/r/cyberes/gradient-base-py3.10

`cyberes/gradient-base-py3.10:latest`と入力して、`START NOTEBOOK`する。
![qiita_paperspace4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998315/2113d2ca-b115-4153-0abb-d1a2f491dace.jpeg)

machineがスタートしたら確認してみる。
```shell-session
root@nyw3jf3nx9:/notebooks# python -V
Python 3.10.10
```
python3.10が入っていることを確認した。

## web-uiを動かしてみる
もう一度web-uiをインストールして動かしてみる。
```JupyterNotebook:RunWebUi.ipynb
%cd /notebooks
!pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116 -U
!pip install -q xformers==0.0.16
!pip install -q triton==2.0.0

%cd /notebooks/stable-diffusion-webui
#実行
```
特にモジュールのインストールなどで詰まることもなく起動できた。

```shell-session
Python 3.10.10 (main, Feb  8 2023, 14:50:01) [GCC 9.4.0]
Commit hash: a9fed7c364061ae6efb37f797b6b522cb3cf7aa2
Installing gfpgan
Installing clip

----省略

Model loaded in 37.4s (calculate hash: 28.4s, create model: 1.7s, apply weights to model: 2.3s, apply half(): 1.0s, load VAE: 3.3s, move model to device: 0.6s).
*Deforum ControlNet support: enabled*
Running on local URL:  http://127.0.0.1:7860
Running on public URL: https://*************.gradio.live

This share link expires in 72 hours. For free permanent hosting and GPU upgrades (NEW!), check out Spaces: https://huggingface.co/spaces
Startup time: 110.0s (import gradio: 3.3s, import ldm: 7.2s, other imports: 4.2s, list extensions: 3.6s, setup codeformer: 0.3s, load scripts: 43.6s, load SD checkpoint: 37.6s, create ui: 4.6s, gradio launch: 5.4s).
```
web-ui側でも`Python3.10.10`が確認できた。
![qiita_paperspace3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998315/af3d2515-67d8-060c-9f1e-1fe31b5eebc6.jpeg)

# おわりに
私の検証した範囲内ではどちらの方法もpythonのバージョンを上げてweb-uiを起動できた。
1の直接インストールする方法はPaperspaceの仕様上、毎回pythonとpipのインストールをしなくてはいけなく、
2の方法はもう一度新しくNotebookを作成しないといけないというデメリットがある。
どちらが良いかは私の知識では断言できない(2の方がスマートかも？)のでいろいろ試してみてほしい。

# 記事について
この記事はpythonやPaperspace、Stablediffusionに精通していない人間が書いており、間違っている点や不正確な情報が記載されている可能性があります。
ご意見、ご指摘、不明な点がありましたらお気軽にコメントよろしくお願いします。なるべく早く回答させていただきます。

# 変更履歴
2023/05/10: 動作環境の記述が間違っていたため修正

# 参考サイト

https://www.yoshimura-s.jp/2021/09/free-gpu-paperspace-gradient/

https://zenn.dev/flutternyumon/articles/c9f82972a470e6

https://bobbyhadz.com/blog/python-importerror-cannot-import-name-html5lib-from-pip-vendor

https://docs.paperspace.com/gradient/notebooks/runtimes/#how-to-specify-a-custom-container

https://github.com/Engineer-of-Stuff/stable-diffusion-paperspace#a-note-about-python-310

https://github.com/camenduru/stable-diffusion-webui

https://note.com/ai_nios/n/n2203de79bc16#142ea6a0-dd47-4b24-83ad-584dfaecc49b