天天看点

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)