はじめに

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プロブラム言語IPythonPythonの実行環境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-.json という名前で ~/.local/share/jupyter/runtime/ に作成されます。

kernel-.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
switch_kernel.png

仮想環境でのパッケージインストール

あとは、仮想環境に 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 を確認してください。

仮想環境でインストールした パッケージは (‘/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 環境構築を迷っている方の何らかのお役に立てればうれしいです。

参考記事

    • jupyter notebookでvenvを使う

 

    JupyterLabのすゝめ
https://github.com/jupyter/jupyter_client/blob/master/jupyter_client/connect.py ↩

广告
将在 10 秒后关闭
bannerAds