はじめに
Jupyter notebook (Lab) を使って機械学習を勉強していると 各Notebook で 環境 (IPython Kernel) を分離したい場面がでてきます。
本記事では WSL (Ubuntu) 上の JupyterLab 環境で 複数の IPython Kernel を使う 方法について記載します。
環境
- Python 3.8+ venv
- WSL2[^1] (Ubuntu 20.04 LTS)
やりたいこと
WSL上に JupyterLab 環境を作って 複数の Jupyter Kernel を管理することが目的です。
そのためには Python の 仮想環境(venv
) を作成して分離すれば良いのですが、JupyterLab の設定や拡張機能など共通で使いたいものもあります。
そこで、共通で使用するものはユーザ個別の環境(~/.local/
) に、Notebook 用途で分けたいものは venv
にインストールすることにしました。
目的 | 方法 |
---|---|
Jupyterの設定や拡張機能は共通で使いたい | JupyterLab は、ユーザ個別環境(~/.local )にインストールする。 |
Notebook 用途で環境を分離したい | 仮想環境(venv ) 内で Jupyter Kernel (ipython kernel) を分離する。 |
/home/ubuntu/
├── .local ( Pythonの共通環境: JupyterLab / Extension インストール)
├── notebook
│ ├── notebook1
| | └─venv (仮想環境 / IPython Kernel分離)
│ ├── notebook2
| | └─venv (仮想環境 / IPython Kernel分離)
..
WSL2環境
Ubuntu 20.04 をインストールし、ubuntu
ユーザを作成しました。 以降の例では ubuntu
ユーザでの操作となります。
ホームディレクトリの場所
ユーザのホームディレクトリは 既定の場所 (Linux のルートファイルシステム:rootfs) を使用します。rootfs 以外の場所に変更すると、パーミッション変更できないなど面倒なことがあるので、特別な理由がなければ既定の場所で良いかと思います。
Ubuntu-20.04 の場合 Windows から見える WSL home の場所は以下の通りです。
# Windows10
\\wsl$\Ubuntu-20.04\home
# Windows11
\\wsl.localhost\Ubuntu-20.04\home
パスワードなしで sudo
ここは任意の設定です。利便性を優先してパスワードなしで sudo を使えるようにします。
$ sudo vi /etc/sudoers.d/ubuntu
# enable NOPASSWD for user
ubuntu ALL=(ALL) NOPASSWD:ALL
パーミッションの変更
# all files in this directory should be mode 0440.
$ sudo chmod 440 /etc/sudoers.d/ubuntu
Python 環境の準備
Python3 と venv をインストールします。
# Python 3.8.10
$ sudo apt update -y
$ sudo apt install python3-pip python3-venv -y
# upgrade pip
$ python3 -m pip install --upgrade pip
Jupyter 環境の準備
JupyterLab のインストール
JupyterLab 環境 は 各 notebook 共通で使いたいので --user
オプションを付けて、ホームディレクトリ配下(~/.local/
) にインストールします。
$ python3 -m pip install jupyterlab --user
バージョンは 3.4.2
でした。(2022/6 現在)
$ python3 -m pip show jupyterlab
Name: jupyterlab
Version: 3.4.2
..
~/.local/
に初めてインストールする場合は PATH が通っていないので おそらく以下のような警告がでます。
WARNING: The script pyjson5 is installed in
'/home/ubuntu/.local/bin' which is not on PATH.
でも、この PATH(~/.local/bin
) は ~/.profile
によって ログイン時に環境変数の PATH に追加されるので問題ありません。
...
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
..
この先作成する仮想環境でも 共通の JupyterLab を使うには、この PATH が通っていることが必要になります。WSLをログインし直して パスが追加されているのを確認します。
$ env |grep PATH
PATH=/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:....... <以下略>
ブラウザ連携
JupyterLab を起動してもブラウザが連動して起動しない場合、設定ファイルに c.NotebookApp.use_redirect_file = False
を追加します。
コンフィグを作成を作成します。
$ jupyter lab --generate-config
設定ファイルに に下の項目を追加します。
$ vi ~/.jupyter/jupyter_lab_config.py
# Disabling this setting to False will disable this behavior, allowing the
# browser to launch by using a URL and visible token (as before).
# Default: True
# c.ServerApp.use_redirect_file = True
c.ServerApp.use_redirect_file = False
Jupyter Lab のバージョンが Version: 2.0.x
の場合は、以下の設定となります。
参考: Launching notebook to browser on WSL #4594
$ vi ~/.jupyter/jupyter_notebook_config.py
# Disabling this setting to False will disable this behavior, allowing the
# browser to launch by using a URL and visible token (as before).
#c.NotebookApp.use_redirect_file = True
c.NotebookApp.use_redirect_file = False
JupyterLab がブラウザと連動して起動すれば OK です。
$ jupyter lab
ブラウザが連動して起動しない場合は、環境変数 BROWSER
にブラウザのパス をしてしてみてください。詳細は JupyterLab を起動してもブラウザが連動して起動しない を参照してください。
複数の IPython Kernel を管理する
Kernel とは?
実は私は Kernel について よく分かっていなかったのですが、Jupyter で使える Kernel (Jupyter kernels) を見て直感的に理解できました。 IPython の他、R, Julia, bash や Ansible も使えます。JupyterLab/Console 等 は フロントエンド、Kenrnel は バックエンドと考えると分かりやすいかと思います。
The IPython kernel is the Python execution backend for Jupyter.
https://ipython.readthedocs.io/en/stable/install/kernel_install.html
Jupyter(IPython) 環境の構成要素は 以下のように整理できます。
構成要素 | 役割 |
---|---|
Python | プロブラム言語 |
IPython | Pythonの実行環境 |
IPython Kernel (ipykernel) | バックエンド(IPython をJupyter で使えるようにする) |
Jupyter Lab/Notebook/Console.. | フロントエンド(ユーザインタフェース) |
仮想環境の作成
以降は、IPython Kernel
を複数使う場合の手順です。手順は Qiita で記事を書かれている方と同じなので 少し詳しく書いてみたいと思います。
Kernel は 各 notebook 用の仮想環境で作成します。下の例では、venv
という名前で作成していますが 分かりやすい名前を付けても良いです。
(venv)
は、仮想環境のプロンプトです。
# Change directory to your notebook directory
$ cd <your notebook>
# Use python3
$ python3 -m venv venv
# Activate
$ . venv/bin/activate
# Upgrade Pip
# 仮想環境に入ったら venv 配下の Python に を参照するので Python3 としなくても良い
(venv) $ python -m pip install --upgrade pip
IPython Kernel のインストール
venv
内で ipykernel
をインストールします。 これを忘れると Kernel をインストールしたのに、module が見つからないトラブルに遭遇(後述) します。
ipykernel
パッケージのインストール
(venv) $ pip install ipykernel
IPython Kernel
のインストール
--name
に kernel の名前を指定します。表示名を変えたい場合は --display-name
を指定します。
(venv) $ ipython kernel install --user --name myenv --display-name "Python (myenv)"
--user
を付けると ~/.local/share
にコピーされます。(オプションなしの場合は、 /usr/local/share/jupyter
)
Kernel の表示
(venv) $ jupyter kernelspec list
Available kernels:
coursera /home/ubuntu/.local/share/jupyter/kernels/coursera
myenv /home/ubuntu/.local/share/jupyter/kernels/myenv
python3 /home/ubuntu/.local/share/jupyter/kernels/python3
Kernel のフォルダには、resources フォルダの中身(ロゴの画像)と kernel.json
があります。
(venv) $ ls -ltr /home/ubuntu/.local/share/jupyter/kernels/coursera
total 12
-rw-r--r-- 1 ubuntu ubuntu 2180 Mar 20 11:41 logo-64x64.png
-rw-r--r-- 1 ubuntu ubuntu 1084 Mar 20 11:41 logo-32x32.png
-rw-r--r-- 1 ubuntu ubuntu 183 Mar 20 11:46 kernel.json
kernel.json
には、 Kernel を起動するときのパラメータが入っています。(仮想環境 の python
が指定されています)
{
"argv": [
"/home/ubuntu/notebook/Coursera/venv/bin/python",
"-m",
"ipykernel_launcher",
"-f",
"{connection_file}"
],
"display_name": "Coursera",
"language": "python"
余談ですが kernel.json
にある {connecton_file}
は、Kernel の 起動時に kernel-<kernel uuid>.json
という名前で ~/.local/share/jupyter/runtime/
に作成されます。
kernel-<kernel uuid>.json
には、Kernel の 各種サービスの port 番号 や session key など の情報が記載されています。このファイルは JupyterLab 終了時には 自動で 削除されます。1
$ ls -ltr ~/.local/share/jupyter/runtime
total 16
-rw------- 1 ubuntu ubuntu 45 Mar 15 19:35 notebook_cookie_secret
-rw-r--r-- 1 ubuntu ubuntu 272 Mar 22 14:32 nbserver-1150.json
-rw-r--r-- 1 ubuntu ubuntu 670 Mar 22 14:32 nbserver-1150-open.html
-rw------T 1 ubuntu ubuntu 263 Mar 22 14:32 kernel-7018c3c8-dd15-4d9a-ada6-aabde48e2513.json
Kernel の アンインストール
Kernelは 以下のコマンドでアンインストールできます。
(venv) $ jupyter kernelspec uninstall <kernel name>
JupyterLab でカーネルを選択
JupyterLab を起動すると、画面右上で Kernel が選択できるようになっています。
(venv) $ jupyter lab
仮想環境でのパッケージインストール
あとは、仮想環境に pip でパッケージをインストールするだけです。JupyterLab の再起動は必要ありません。
各notebootk で requirements.txt に必要パッケージをまとめておくと、環境を再構築するときに便利です。
(venv) $ pip install -r requirements.txt
例:Coursera 用
keras==2.0.7
Pillow==7.0.0
tensorflow==1.2.1
scipy==1.4.1
pydot==1.4.1
opencv-python==4.1.2.30
Faker==0.8.10
tqdm
babel
h5py
numpy
matplotlib
pandas
pydub
sklearn
よくあるトラブル
Kernel を選択しているのに ModuleNotFoundError
仮想環境に パッケージをインストールして、Kernel も選択できたのに ModuleNotFoundError:
で import できない場合は、jupyter Lab で site-packages
の path を確認してください。
仮想環境でインストールした パッケージは ('<notebook path>/venv/lib/python3.8/site-packages'
) から読み込まれます。
# Jupyter Lab で確認
[1]: import sys; from pprint import pprint; pprint(sys.path)
['/home/ubuntu/notebook/kalman_filter',
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'',
'/home/ubuntu/notebook/kalman_filter/venv/lib/python3.8/site-packages'] # ←これ
この PATH がない場合は、仮想環境内で ipykernel
がインストールされていない可能性があります。ipykernel
を仮想環境に インストールして Kernel の再作成をしてみてください。
sys.path
は手動で追加することができますが、Kernel を切り替えるだけ の方が分かりやすいと思います。
# 環境変数に追加する場合
$ export PYTHONPATH=<site-package path>
# JupyterLab/IPython 上 で追加する場合
import sys; sys.path.append(<site-package path>)
JupyterLab を起動してもブラウザが連動して起動しない
Jupyter lab を起動してもブラウザが起動しない場合があります。 (2023.4.15 追記)
$ jupyter lab
..
[W 2023-04-15 10:38:19.952 ServerApp] No web browser found: Error('could not locate runnable browser').
発生した環境:
Ubuntu 22.04.2 LTS (WSL2)
Python 3.10.6
jupyterlab 3.6.3
環境変数 BROWSER
に ブラウザのパスを指定します。~/.bashrc
に書いておきます。
# ~/.bashrc
# WSL2から見えるWindowsのパスを指定する。環境に合わせて変更してください。
export BROWSER="/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
ちなみに設定ファイル(~/.jupyter/jupyter_lab_config.py
) の c.ServerApp.browser
に指定してもダメでした。
## Specify what command to use to invoke a web
# browser when starting the server. If not specified, the
# default browser will be determined by the `webbrowser`
# standard library module, which allows setting of the
# BROWSER environment variable to override it.
# Default: ''
c.ServerApp.browser = '/mnt/c/Program Files/Google/Chrome/Application/chrome.exe'
おわりに
Python環境が混沌としてきたので自分用のメモも兼ねてまとめました。これから機械学習を始めようと思っている方や、Windows 上での Python 環境構築を迷っている方の何らかのお役に立てればうれしいです。