天天看點

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

Jupyter Notebook是一款非常好用的基于浏覽器的互動式的代碼編寫、運作測試以及富媒體(rich media)輸出的工具。Jupyter Notebook本質上是一個notebook,并不具備代碼執行能力,需要借助其他代碼執行核心才能完成代碼執行,如執行Python代碼的IPython。是以,我們自然而然會想能不能為Jupyter Notebook配置多個kernel呢?本篇部落格将從IPython與Jupyter Notebook講起,記錄Jupyter Notebook配置多個Kernel的全過程。

IPython與Jupyter Notebook

Python的老使用者可能還記得,以前的Jupyter Notebook名稱是IPython Notebook,現在也常看到IPython/Jupyter這種說法,是以很多人可能将IPython與Jupyter混淆。根據官方文檔的定義:

IPython is a growing project, with increasingly language-agnostic components. IPython 3.x was the last monolithic release of IPython, containing the notebook server, qtconsole, etc. As of IPython 4.0, the language-agnostic parts of the project: the notebook format, message protocol, qtconsole, notebook web application, etc. have moved to new projects under the name Jupyter. IPython itself is focused on interactive Python, part of which is providing a Python kernel for Jupyter.

可以看到,在IPython 4.0之前,IPython項目本身就包含notebook功能,是以使用IPython Notebook就能使用notebook功能。但是在IPython4.0 之後,IPython項目中的notebook等被轉移到Jupyter項目中,IPython項目專注于互動式Python開發和為Jupyter提供Python Kernel,是以現在我們使用Jupyter Notebook執行notebook程式,并采用IPython kernel執行Python代碼。

現在兩者的關系終于清楚了,讓我們再分别看看IPython與Jupyter Notebook。

IPython

目前最新版的IPython是IPython 7.5,IPython的目标是為互動式(interactive)和探索性(exploratory)程式設計提供一個全面的環境,是以其包括三個重要子產品:

  1. 一個增強的互動式Python Shell。
  2. 一個解耦的雙程序通信模型,其允許多個用戶端連接配接到同一個計算核心,如Jupyter Notebook。
  3. 一個互動式并行計算架構。

目前,當我們說ipython時通常是指IPython Shell,類似于Python自帶的Python shell,但其更加簡潔明了,并且使用者更強的互動功能,如Tab自動補全,對象内省(檢視文檔和源代碼),執行系統shell指令,曆史檢索,魔術指令等。同時其也可以嵌入到其他程式中,以及直接繪制圖像。

解耦的雙程序模型

該模型是我們能夠使用jupyter的關鍵。IPython對傳統的Read-Evaluate-Print-Loop(REPL)環境進行了抽象與擴充,通過将evaluation解耦為一個單獨的程序,這個程序被稱作Kernel:從用戶端接收執行指令并将結果傳回用戶端。解耦帶來的好處是允許多個用戶端連接配接到同一個kernel,甚至允許用戶端與kernel不在同一台機器上。除了IPython Shell(Terminal IPython)仍然采用的是單程序機制外,目前其他的IPython machinery采用的都是雙程序模型,如jupyter console、jupyter qtconsole和jupyter notebook。它們采用ZeroMQ sockets傳輸JSON資訊實作前端與Kernel的通信。

Terminal IPython與IPython Kernel的關系如下圖:

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

可以看到,Terminal IPython與IPython Kernel共享相同的Python代碼執行器。IPython Kernel的這個設計允許我們基于相同kernel開發不同的前端,同時也使得同一個前端支援不同語言成為可能,隻需要我們開發相應語言的kernel。目前,開發其他語言的kernel存在兩種方式:Wrapper Kernel與Native Kernel。

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

Wrapper Kernel重用IPython的通信機制,是以隻需要實作核心的代碼執行部分。Native Kernel重新實作代碼執行與通信整個過程。

Jupyter Notebook

Jupyter Notebook是Jupyter項目的一個産品,允許使用者通過在浏覽器界面編寫代碼、Markdown文檔、Latex公式、javascript等,以及輸出圖檔、語音、視訊等。其工作流程如下:

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

Notebook前端(浏覽器)可以編輯代碼和顯示輸出,當我們點選儲存時,浏覽器的内容被發送到notebook server,其将浏覽器内容以JSON檔案.ipynb擴充名的形式存儲在本地磁盤上,同時我們也可以從本地磁盤加載notebook檔案。以上這些都不需要kernel的參與,隻有當執行cell中的代碼時,notebook server才會與kernel通信,kernel執行程式并将結果傳回。

Jupyter Notebook支援将notebook檔案轉化為其他多種格式,如:HTML,LaTex,reStructuredText等,其依靠Nbconvert工具實作。

Jupyter Notebook配置多個IPython Kernel

到目前為止,大家應該對IPython和Jupyter Notebook有了一定的了解,可以認為Jupyter Notebook是一款富文本編輯器,IPython負責執行Python程式。IPython與Jupyter Notebook是多對多的關系,一個kernel可以多個連接配接Jupyter Notebook,一個Jupyter Notebook也可以配置多個kernel。下面我們将專注于一個Jupyter Notebook配置多個Kernel的過程。

環境準備

我在阿裡雲上執行本次實驗,我的阿裡雲系統是Ubuntu 16.04 64位,自帶Python3.5.2與Python2.7.12,兩個Python環境都沒有安裝過ipython。

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

首先需要安裝ipython與jupyter,因為需要配置多個IPython Kernel,也就是說需要多個python環境,是以我選擇采用Anaconda建立多個虛拟環境,各個版本的Anaconda可以在Anaconda installer archive中下載下傳。我下載下傳的是Anaconda3-5.3.0-Linux-x86_64.sh,執行如下指令将完成安裝:

bash Anaconda3-5.3.0-Linux-x86_64.sh
           

安裝過程會提示是否将Anaconda加入目前使用者環境變量中,添加環境變量後,python指令将會指向Anaconda中自帶的python,可以起别名區分。編輯.bashrc檔案如下:

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

現在在我的Linux中有3個python,分别是python2.7.12,python3.5.2和python3.7.0,對應的指令分别是:python2、python2.7,python3、python3.5和python、python3.7、pyana。

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

annconda中自帶了ipython和jupyter,并在anaconda3/share/jupyter/kernels檔案夾下已經建立好一個名為python3的kernel(即安裝jupyter會同時安裝ipython kernel),其中的kernel.json儲存了kernel的配置資訊

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻
  • argv:用于啟動kernel的指令行參數清單。
  • display_name:kernel在UI上的顯示名。
  • language:kernel的語言。

是以在安裝好annconda後,我們就能使用jupyter notebook了,輸入指令

jupyter notebook
           

即可,但是阿裡雲沒有浏覽器界面,需要在其他浏覽器上通路,是以需要配置遠端通路。

遠端通路

首先需要生成jupyter notebook的配置檔案,這個檔案預設是不存在的,需要我們手動生成,指令如下:

jupyter notebook --generate-config
           

将在~/.jupyter目錄下生成名為jupyter_notebook_config.py的檔案,此後所有的配置都可以在這個檔案下完成。下面進行遠端通路配置:

1、設定jupyter notebook登入密碼,指令如下:

ipython    # 打開ipython
from notebook.auth import passwd
passwd()    # 生成密碼
           

passwd() 函數将要求使用者輸入密碼,然後會生成sha1的密文,将其拷貝下來。

2、修改配置檔案如下:

c.NotebookApp.ip='*'          #允許所有ip通路
c.NotebookApp.password = u'sha1:...剛才複制的那個密文'
c.NotebookApp.open_browser = False       # 是否打開浏覽器
c.NotebookApp.port = 8888        #指定端口
           

3、在伺服器上啟動jupyter notebook,在本地浏覽器輸入’http://ip:8888/?token=……’ 進行通路。

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

啟動指令中‘–allow-root’是因為jupyter notebook不允許以root使用者身份啟動,想要以root身份啟動就需要加上‘–allow-root’參數,第一個警告是因為我在配置時将‘c.NotebookApp.password’寫成了‘c.NotebookApp.passwd’,第二個警告是因為‘c.NotebookApp.ip=’*’’配置了監聽所有IP,這是不推薦的。另外需要注意的是“Serving notebooks from local directory:”訓示的是‘/root’,因為我是在‘/root’目錄下啟動的jupyter notebook,也就是說在哪個目錄啟動jupyter notebook,工作目錄就是哪個目錄,如果需要固定工作目錄可以在配置檔案中進行配置:

c.NotebookApp.allow_root=True        # 允許root使用者啟動
c.NotebookApp.notebook_dir='/jupyter_workspace'       #指定工作空間
c.PAMAuthenticator.encoding='utf8'        # 指定utf-8編碼,解決讀取中文路徑或者檔案亂碼問題
           

再次啟動如下:

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

添加其他IPython Kernel

因為系統中已經存在python2.7和python3.5,是以我們可以直接在這兩個python環境中安裝ipython kernel,然後配置到jupyter中即可。

python3.5中添加ipython kernel

python3 -m pip --version    # 檢查pip版本
python3 -m pip install --upgrade pip     # 更新pip版本
python3 -m pip install ipykernel      # 安裝ipykernel
python3 -m ipykernel install --user --name python35 --display-name "python35"     # 配置ipykernel到jupyter中
           

第一二兩個指令檢查以及更新pip,不是必須的。最後一條指令“–name”用于指定這個kernel在系統中的名稱,“–display-name”用于指定kernel在UI中的名稱。再次啟動jupyter notebook,可以看到現在有python2和python3.5兩個kernel供選擇。

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

值得注意的是,如果不指定kernel名稱,系統将自動根據python版本命名,是以可能覆寫原始kernel,本人一開始就忘記指定kernel名稱了。

find . -name 'kernel.json'         # 查找所有包含'kernel.json'的檔案
jupyter kernelspec list             # 列舉所有的kernel
jupyter kernelspec remove python3      # 解除安裝kernel python3
           
Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

可以看到“kernel.json”的數目是3個,但可用的kernel隻有2個,因為有兩個叫“python3”的kernel,并且可用的是我們後來配置的那個。

python2.7中添加ipython kernel

目前直接在系統自帶的python2.7中添加ipython kernel還沒有成果,原因是支援python2的IPython版本是IPython5.x,但是采用pip安裝會自動下載下傳最新版的IPython,不知道是不是因為阿裡雲鏡像的原因,一個可行的方法是手動下載下傳符合版本的ipykernel,ipython以及相關依賴包,但相關實驗還沒進行。

在anaconda虛拟環境中添加ipython kernel

在添加其他IPython Kernel之前,我們需要在anaconda中建立python虛拟環境,然後進入虛拟環境。如果對anaconda不熟悉,可以參考我之前的部落格。

conda env list       # 列舉可用虛拟環境
conda create --name python27 python=2.7     # 建立虛拟環境
source activate python27      # 進入虛拟環境
conda install ipykernel    # 安裝ipython kernel
python -m ipykernel install --user --name pyana27 --display-name "pyana27"     # 配置ipykernel到jupyter中
           

在虛拟環境中輸入python,調用的就是該環境中的python,是以不需要擔心python到底指的是哪個python問題,但是非root使用者在使用sudo後,調用的将不再是環境中的python。

Jupyter Notebook配置多個IPython Kernel詳細過程記錄(IPython與Jupyter Notebook介紹、IPython、Jupyter安裝配置)IPython與Jupyter NotebookJupyter Notebook配置多個IPython Kernel參考文獻

至此就完成了在Jupyter Notebook配置多個IPython Kernel的實驗,關于IPython與Jupyter的更多内容可以參考IPython與Jupyter的文檔。

參考文獻

How IPython and Jupyter Notebook work

jupyter_client document

Installing the IPython kernel

linux系統環境python和anaconda安裝python共存

Jupyter Notebook 進階設定

如何在阿裡ECS雲端運作Jupyter Notebook進行機器/深度學習?

How do I add python3 kernel to jupyter (IPython)