作者:京东科技隐衷计算产品部 孙晓军
1. Jupyter Notebook 介绍
图 1 Jupter 我的项目整体架构
[https://docs.jupyter.org/en/l…]
Jupyter Notebook 是一套基于 web 的交互式开发环境。用户能够在线开发和分享蕴含代码和输入的交互式文档,反对实时代码,数学方程,可视化和 markdown 等。用处包含:数据清理和转换,数值模仿,统计建模,机器学习等等。
Jupyter Notebook 外部通过内核保护状态并运行代码片段,浏览器显示代码片段和其执行的后果。Jupyter Notebook 提供了一个用户交互式的开发环境,用户能够通过执行一部分代码片段,并察看执行后果。这种交互式设计,使得 Jupyter Notebook 非常适合数据迷信和机器学习的开发工作。
留神本文的代码和脚本,均基于 Jupyter Notebook v6.5.2 稳固版本。
2. Jupyter 的工作形式
图 2 Jupter Notebook 工作形式
[https://docs.jupyter.org/en/l…]
Jupyter 的次要工作单元是 Jupyter Server 和 Kernel。其中 Jupyter Server 用来提供基于 Web 的界面和 API 服务,Kernel 用来执行代码片段。浏览器通过 Http 和 Websockets 的形式和 Jupyter Server 进行交互,Jupyter Server 和 kernel 之间,通过 ZeroMQ 进行数据通信。
Jupyter Server 采纳经典的 MVC 模式,应用了 tornado 作为 web 服务器,用来提供地址映射和控制器逻辑,应用 jinja2 来提供模板视图性能。
Jupyter Notebook(v6.5.2)我的项目的次要模块构造如下:
模块 | 阐明 |
---|---|
notebook | Notebook 功能模块。 |
terminal | 终端模块。为 Jupyter 提供控制台交互能力。 |
view | 文件可视化模块。比方 pdf 文件的显示。 |
tree | 工作区目录树 |
nbconvert | 格局转换模块,能够把 Jupyter Notebook 转换成 html,pdf 等格局 |
kernel | Jupyter Notebook 内核 |
services | Jupyter Notebook REST API 模块 |
i18n | Jupyter Notebook 多语言资源 |
3. 装置 Jupyter Notebook
前置条件
Python 和 pip
不同的 Jupyter Notebook 对 Python 有不同的版本要求。咱们装置的最新的稳固版本 v6.5.2 的 Jupyter Notebook,要求 Python 的最低版本为 3.6。留神这个 Python 的版本,不同于内核的 Python 版本。对于 Jupyter 内核来说,反对的 Python 版本和 Jupyter Notebook 依赖的 Python 版本没有关系。
在 Linux 零碎下装置 Jupyter Notebook
应用 pip 装置 Jupyter notebook 非常简单。如果服务器同时领有 Python2 和 Python3 的 pip,留神须要应用 pip3 来替换命令中的 pip。
# 更新 pip
pip install --upgrade pip
# 装置 jupyter
pip install jupyter
# 查看装置的 jupyter
jupyter --version
// 输入 notebook : 6.5.2
4. 配置和启动 Jupyter
Jupyter 提供了大量的启动参数,用来配置 Jupyter Server。咱们能够在启动 Jupyter 服务时,通过命令行参数的形式配置以后启动的服务,但更广泛的形式是应用 Jupyter 的配置文件。
# 生成配置文件
jupyter notebook --generate-config
// 默认生成的配置文件地位:/root/.jupyter/jupyter_notebook_config.py
# 批改 Jupyter 配置文件...
# 启动 jupyter
jupyter notebook
Jupyter 间接应用一个 Python 文件来配置 Jupyter 服务,所有的配置项均通过 Python 代码来实现。罕用的配置项及其阐明如下:
名称 | 默认值 | 阐明 |
---|---|---|
c.NotebookApp.allow_root | False | 为了平安,Jupyter 默认不容许应用 root 用户启动。如果须要以 root 用户的身份启动 Jupyter,须要开启此设定 |
c.NotebookApp.allow_origin | ” | 当须要 Jupyter 内嵌到 iframe 时,能够设置为“*“来防止跨 origin 的限度 |
c.NotebookApp.ip | localhost | 当须要通过外网地址来拜访 Jupyter 服务时,须要设置一个无效的服务器 IP 地址。 |
c.NotebookApp.port | 8888 | Jupyter server 对外服务端口 |
c.NotebookApp.notebook_dir | / | Jupyter 的工作空间,默认能够拜访服务器上以后用户的所有文件系统 |
c.NotebookApp.open_browser | True | 启动服务后是否立刻通过浏览器关上服务地址 |
c.NotebookApp.default_url | /tree | Jupyter 服务的默认地址 |
c.NotebookApp.extra_static_paths | [] | 扩大动态文件目录 |
c.NotebookApp.extra_template_paths | [] | 扩大模板文件目录 |
c.KernelSpecManager.allowed_kernelspecs | set() | 默认容许应用所有的 kernel |
c.NotebookApp.nbserver_extensions | {} | 容许加载的 Jupyter Server 扩大 |
5. 应用 Jupyter
5.1. 创立 Notebook
启动 Jupyter 后,在浏览器内输出 http:// 服务器地址: 端口 /,Jupyter 会默认重定向到.default_url 指定的工作区目录树地址,默认是工作区目录树的界面。
如果在拜访的过程中,应用了默认的 token 作为其认证形式,那么在首次关上时,须要输出 Jupyter Notebook 的 token 值,这个值能够在启动 Jupyter 时的控制台输入中找到,或者应用 Jupyter 命令来查问
# 查问运行的 jupyter notebook
jupyter notebook list
// 返回后果中蕴含了 http://x.x.x.x:8899?token=ABC 的信息,其中的 ABC 就是咱们须要的 token
图 3 Jupter Notebook 的默认工作区目录树页面
Jupyter Notebook 通过 Jupyter Server 提供基于 Web 的平台无关的工作形式,这使得跨平台开发和合作,代码分享等能力变得比传统 IDE 更加容易。
在 Jupyter 工作区治理界面,用户能够灵便地以相似文件系统的形式管理工作区的数据。能够创立文件和文件夹,编辑文件和文件夹,能够上传和下载文件。通过抉择一个 Jupyter 内核,能够创立一个 Notebook 文件。
图 4 通过 Jupyter 内核创立一个 Notebook
5.2. 应用 Notebook
应用 Python3 内核创立一个 Notebook 后,咱们失去一个 xxx.ipynb(IPython Notebook)文件。这个文件是一个 json 格局的文本文件,其中蕴含了咱们在 Notebook 中编写的代码和文本内容,也蕴含了界面上没有显示的元数据信息。通过在工作区目录界面抉择一个 notebook 文件,点击编辑,咱们能够查看到 ipynb 文件的原始内容。
图 5 ipynb 文件的原始内容
咱们能够像应用其它 IDE 相似的形式来应用 Notebook,在应用 Notebook 上,咱们次要关注下 Jupyter 内核和单元格。
内核是执行单元格代码的外围过程,不同的内核,决定了咱们在单元格中可能编写哪些语言的代码,以及对应了指定的编程语言的哪个版本等信息。
单元格是整个 Notebook 的外围组成部分,咱们编写的代码和文本,通过一些列 Notebook 单元格来组成。Notebook 提供了 Code,Markdown, Raw NBConvert, Heading 四种类型的单元格。
•Code 单元格。用来编写内核指定语言的程序代码
•Markdown 单元格。应用 Markdown 编辑器的语法来编辑富文本
•Raw NBConvert 单元格。原始的文本,不会被当作代码或 markdown 被解释执行
•Heading 单元格。Heading 是 Mardown 的一个子集,对应了 Markdown 中的题目编写语法
Jupyter Notebook 应用了机器学习中检查点的概念,在咱们批改 Notebook 的过程中,Jupyter 会主动保留咱们的批改,咱们也能够通过【文件】->【保留】来手动保留检查点。检查点文件蕴含了咱们编写的 Notebook 内容,以及执行代码单元格之后的输入。咱们能够在工作空间的“.ipynb_checkpoints”文件夹下,找到这些检查点文件。
图 6 应用 Jupyter 单元格来编写交互式代码
5.3. 分享 Notebook
相较于应用传统的 IDE 编写的代码,基于 Web 服务的 Jupyter Notebook 在代码分享上领有着人造的劣势。
在 Jupyter Notebook 中,咱们能够通过两种不同的形式分享咱们创作的 nootbook。
- 交互式 Notebook 文档
传统的技术文档或者说明书,通过动态的文本,配合图片和视频,来形容和解说特定的技术或性能。有了 Jupyter Notebook 后,咱们依然能够应用 Notebook 来编写相似传统的技术文档。在此基础上,咱们能够退出更活泼的代码交互单元格,用户通过查看文档阐明,并与文档中提供的代码进行互动,能够更活泼地介绍产品中的性能和技术。每个 Jupyter Notebook 的 ipynb 文件,都对应了一个独立的拜访地址:http://x.x.x.x:8899/notebooks… , 通过分享此文件的地址,其余用户能够不便地应用蕴含了富文本和可执行的代码的交互式 Notebook 文档。
- 离线 Notebook 文档
咱们通过逐渐执行文档中的所有单元格,失去一个蕴含了咱们编写的阐明和代码,以及代码执行的输入后果的残缺文档。之后点击【文件】->【另存为】,抉择一种适合的文件格式。咱们能够把文档导出为一份动态文件,通过共享此动态文件,咱们实现了 Notebook 文档的离线分享。
5.4. 魔法函数
Jupyter Notebook 提供了一些列魔法函数来加强 Jupyter Code 单元格的性能,通过魔法函数,咱们可能执行 javascript 脚本,html 代码,运行另一个可执行程序等许多额定的性能。
咱们能够在 Jupyter 代码单元格中应用 %lsmagic 命令来查看所有的魔法函数,如果要浏览具体的魔法函数的应用阐明,能够参考:https://ipython.readthedocs.i…
魔法函数分为行魔法函数,单元格魔法函数和会话魔法函数。顾名思义,行魔法函数只对以后行起作用,而单元格魔法函数则作用于整个单元格,会话魔法函数则作用于整个会话期间。
一些罕用的魔法函数:
指令 | 阐明 |
---|---|
%matplotlib | 设置 matplot 绘图的显示模式 |
%%javascript | 单元格内的代码被辨认为 javascript 代码 |
%%html | 单元格内的代码被辨认为 html 代码 |
%run | 执行内部脚本文件 |
%pwd | 获取当前工作的目录地位(非工作空间目录地位) |
%writefile | 以文件模式保留以后单元格代码 |
%timeit | 获取本行代码的执行工夫 |
%debug | 激活调试模式 |
6. 治理 Jupyter
6.1. 多语言
Jupyter Notebook 应用 i18n 目录下的资源来进行多语言翻译。在 Jupyter Notebook 启动时,会加载 i18n 目录下的多语言资源。之后依据 http 申请指定的语言,为响应数据提供对应的多语言翻译。如果没有对应的翻译,则保留原始的多语言标签值(英文)。如果调整了多语言翻译,须要重新启动 Jupyter Notebook 能力应用新的语言包。
Jupyter Notebook 的翻译资源次要散布在三个 po 文件中:
•nbjs.po – js 文件中的多语言数据
•nbui.po – UI 界面中的多语言数据
•notebook.po – notebook 中的多语言数据
原始的 po 文件,须要通过 pybabel 工具,把 po 文件编译成 mo 文件,之后部署在 $notebook/i18n/${LANG}/LC_MESSAGES/ 目录下($notebook 是 notebook 的装置目录),能力在 Jupyter Notebook 中作为多语言的资源包来应用。
# 应用 pybabel 编译多语言 po 文件
pybabel compile -D notebook -f -l ${LANG} -i ${LANG}/LC_MESSAGES/notebook.po -o ${LANG}/LC_MESSAGES/notebook.mo
pybabel compile -D nbui -f -l ${LANG} -i ${LANG}/LC_MESSAGES/nbui.po -o ${LANG}/LC_MESSAGES/nbui.mo
pybabel compile -D nbjs -f -l ${LANG} -i ${LANG}/LC_MESSAGES/nbjs.po -o ${LANG}/LC_MESSAGES/nbjs.mo
图 7 应用了中文语言包后的中文 Notebook 界面
6.2. 内核治理
内核(kernel)是独立于 jupyter 服务和界面之外的用来运行 Jupyter 代码单元格的过程,Jupyter 默认提供了 ipykernel 内核来反对 Python 开发语言。Jupyter 社区提供了 jupyterC, IJava,xeus-cling, xeus-sql 等泛滥其它编程语言的内核,用来反对 C /C++, Java, SQL 等编程语言。
ipykernel 默认应用零碎环境下的 Python 来提供服务。咱们能够应用 ipykernel 装置多个 Python kernel 来提供 Python2.x, Python3.x 等多个 Python 内核环境。
装置 kernel 后,kernel 的信息被保留在 kernel.json 文件中,咱们能够在 /usr/local/share/jupyter/kernels 目录,找到 Jupyter 装置的所有 kernel 以及对应的 kernel.json 文件。
kernel 能够间接继承自装置 kernel 的 Python 指令,也能够应用 Python 虚拟环境。
# 1. 间接继承自 Python 指令的 kernel 装置
# 装置 ipykernel
pip install ipykernel
# 装置 kernel
python -m ipykernel install --name tensorflow2 --display-name "tensorflow2"
# 2. 在 Python 虚拟环境下的 kernel 装置
# 激活虚拟环境
source activate myenv
# 装置 ipykernel
pip install ipykernel
# 装置 kernel
python -m ipykernel install --name myenv --display-name "Python3 (myenv)"
如果须要查看以后的 kernel 列表,以及删除曾经装置的 kernel,能够应用如下的 Jupyter 命令:
# 查看曾经装置的 kernel 列表
jupyter kernelspec list
# 删除列表中指定的 kernel
jupyter kernelspec remove kernelname
6.3. REST API
Jupyter 提供了 REST API 接口来和 Jupyter server 进行交互。借助 REST API 的能力,咱们能够以编程的形式和 Jupyter Server 进行交互,灵便地治理 Jupyter Server。另外 REST API 为现代化的软件开发提供了一个优良的能力:自动化。
借助 Jupyter Notebook REST API,能够实现文件的上传和下载,检查点治理,会话治理,内核治理,终端治理等一些列治理能力。残缺的 Jupyter REST API 接口列表能够参考:https://jupyter-server.readth…
要应用 REST API,须要在申请中携带认证信息。Jupyter 反对间接把 token 作为 query string 的形式来认证,也能够应用规范的 Http Authorization 头信息来实现认证。应用 Authorization 头来认证的格局如下:
Authrozation: token 527a9f1430ccfed995ebcf15517583a2547c2469bc3c47a6
图 8 应用 Postman 来调用 Jupyter REST API 接口
6.4. 平安治理与多人合作
Jupyter 提供了灵便弱小的能力,用以反对在线的交互式文档和代码的编写。但 Jupyter 我的项目本身没有提供精细化的平安管理体系,用以反对多用户下灵便地应用 Jupyter Notebook 的性能。对于文件平安,Jupyter 依赖于启动服务的 linux 用户,正当地配置启动 Jupyter 的用户的权限,能力保障应用 Jupyter 的用户,不会对系统或我的项目造成毁坏。Jupyter 工作空间的设定,仅起到了不便 Jupyter 使用者治理必要文件的易用性,不能阻挡用户拜访和管理工作空间外的文件系统。另外,配合应用 Python 虚拟环境,能够避免 Jupyter Notebook 提供的 pip install ,pip uninstall 性能,对现有我的项目环境造成毁坏。
在多人合作方面,JupyterHub 我的项目提供了多人合作 Jupyter Notebook 和 Jupyter lab 开发的能力。应用 JupyterHub, 不同职能的用户能够在本人独立的空间内进行 Notebook 的编写工作,不同用户间也能够不便地分享各自的 Notebook。
7. 扩大 Jupyter
7.1. 前端扩大
Jupyter Notebook 前端扩大 (front end extension) 是应用 Javascript 语言编写的异步模块,能够用来绘制 Jupyter 界面的仪表盘,Notebook,工具栏等,。定义一个前端扩大必须要实现一个 load_ipython_extension 办法,以后端控件被加载时,Jupyter client 会调用 load_ipython_extension 办法。
Jupyter Notebook 前端扩大能力目前还不是一个稳固的版本,不保障代码可能向后兼容。Jupyter 的 JS API 目前也没有官网的文档,须要通过源代码或者理论加载的 JS 来查看 Jupyter 前端脚本的成员和办法。
咱们实现一个简略的前端扩大脚本,在 jupyter 前端的工具条中,增加一个自定义工具,当点击自定义工具时,弹出提示信息。
define(['base/js/namespace'], function(Jupyter) {function load_ipython_extension() {var handler = function () {alert('欢送应用前端扩大!');
};
var action = {
icon: 'fa-comment-o',
help : '前端扩大',
help_index : 'zz',
handler : handler
};
var prefix = 'my_extension';
var action_name = 'show-alert';
var full_action_name = Jupyter.actions.register(action, action_name, prefix); // returns 'my_extension:show-alert'
Jupyter.toolbar.add_buttons_group([full_action_name]);
}
return {load_ipython_extension: load_ipython_extension};
});
完前端扩大代码后,咱们把脚本保留到 main.js 文件,搁置在 /opt/my_extension 目录下。接下来咱们应用 jupyter nbextension 工具来装置和启用前端扩大
# 装置前端扩大
jupyter nbextension install /opt/my_extension
# 启用前端扩大
jupyter nbextension enable my_extension/main
# 禁用前端扩大
jupyter nbextension disable my_extension/main
# 查看前端扩大列表
jupyter nbextension list
# 卸载前端扩大
jupyter nbextension uninstall my_extension
图 9 在 Notebook 工具条中退出的前端扩大
7.2. 服务端扩大
Jupyter 服务端扩大(server extension)是应用 Python 语言编写的模块,能够用来解决发送到 Jupyter Server 的 Http 申请。应用 Jupyter 服务端扩大,能够更改现有 Jupyter 申请的数据和行为,也能够为 jupyter Server 定义新的服务处理程序。
定义一个服务端扩大模块要实现一个 load_jupyter_server_extension 办法,其中蕴含一个类型为 notebook.notebookapp.NotebookApp 的参数 serverapp,serverapp 的具体属性和办法能够通过 Jupyter Notebook 源代码中的 notebookapp.py 文件来查看。当服务端扩大被加载时,Jupyter Server 会调用 load_jupyter_server_extension 办法。在 load_jupyter_server_extension 办法中,咱们能够通过调用 serverapp 的 web_app 属性的 add_handlers 办法来注册处理程序,用来解决特定的服务端申请。处理程序类须要继承自 Jupyter 的 IPythonHandler 类。在处理程序的办法中,能够应用 Jupyter 提供的 @web.authenticated 装璜器来为办法减少身份认证爱护。
通过服务端扩大,还能够与前端扩大联动,实现一个功能丰富的 Jupyter Notebook 前端控件。
# 定义一个处理程序
from tornado import (gen, web,)
from notebook.base.handlers import IPythonHandler
class HelloWorldHandler(IPythonHandler):
@web.authenticated
@gen.coroutine
def get(self):
self.finish(f'Hello, world!')
# 实现 load_jupyter_server_extension 办法并注册处理程序
def load_jupyter_server_extension(serverapp):
handlers = [('/myextension/hello', HelloWorldHandler)
]
serverapp.web_app.add_handlers('.*$', handlers)
实现服务端扩大代码后,咱们把代码保留为__init__.py 文件,要在 Jupyter Notebook 中应用处理程序,咱们还须要进行服务端扩大的装置和启用。不同于前端扩大,服务端扩大不能间接应用指令来装置,须要咱们手动编写安装程序。此外,Jupyter 提供了主动启用服务端扩大和前端扩大的办法,须要咱们在脚本的根目录提供启用扩大的配置文件。
jupyter-config/
├── jupyter_notebook_config.d/
│ └── my_server_extension.json
└── nbconfig/
└── notebook.d/
└── my_front_extension.json
setup.py
退出了主动启用扩大的配置,咱们的服务端扩大目录构造如下:
hello-extension/
├── __init__.py
jupyter-config/
├── jupyter_notebook_config.d/
└── hello_extension.json
hello_extension.json 文件的内容为:
{
"ServerApp": {
"jpserver_extensions": {"hello_extension": true}
}
}
接下来咱们通过安装程序,装置服务端扩大的信息保留在 /root/.jupyter/jupyter_notebook_config.json 文件中。在装置实现后,咱们能够通过 jupyter serverextesion 工具来股那里服务端扩大
# 启用服务端扩大
jupyter serverextension enable hello_extension
# 禁用服务端扩大
jupyter serverextension disable hello_extension
# 服务端扩大间接卸载的办法,须要咱们通过 pip uninstall 卸载安装程序,# 再通过手工批改 /root/.jupyter/jupyter_notebook_config.json 文件删除扩大信息来实现卸载
图 10 在浏览器中测试装置的服务端扩大程序
7.3. 界面定制
Jupyter 没有提供规范的界面定制的能力,但咱们能够手工调整 jupyter 生成的模板视图文件和款式文件,达到整条调整 jupyter notebook 的界面的能力。
Jupyter Notebook 模板文件的地位为:$notebook/templates,款式和脚本定制举荐的计划是应用~/.jupyter/custom/custom.css 和~/.jupyter/custom/custom.js 文件。咱们能够间接在此基础上对文件进行批改,还能够通过 extra_template_paths 和 extra_static_paths 来引入其它地位的模板和其它动态文件。
图 11 通过间接调整模板文件退出的界面定制按钮
7.4. 小部件
小部件(Widgets)是 Jupyter 交互式可视化数据出现部件。Jupyter Widgets 同时蕴含了拜访后端数据和前端出现的能力,能够用于在 Jupyter Notebook 上活泼地展现服务端的数据和数据变动。
在 v6.5.2 稳固版本上,咱们目前只能应用零碎提供的小部件,还不能开发自定义小部件。在 Jupyter notebook7.x 版本中,开始提供了小部件的自定义开发能力。
# 确保装置了 ipywidgets 和 traitlets
pip install --upgrade traitlets
pip install --upgrade ipywidgets
# 装置和启用小部件
jupyter nbextension install --py widgetsnbextension
jupyter nbextension enable --py widgetsnbextension
在装置和启用了小部件后,咱们能够在 notebook 中间接应用零碎提供的小部件。
图 12 在 Notebook 中应用小部件
残缺的小部件列表和应用形式能够参考:https://ipywidgets.readthedoc…
8. 总结
Jupyter Notebook 以其丰盛的性能,简略易用,弱小的交互能力和扩大能力,成为数据迷信和机器学习开发中的神器。目前,Jupyter Notebook 反对超过 40 种编程语言,被利用于 Google Colab, Kubeflow, 华为云,kaggle 等多个出名我的项目中,大量机器学习和数据迷信的论文中应用到了 Jupyter。Jupyter 在数据可视化,晋升工作效率,改善用户体验和丰盛文档性能方面浮现了微小的威力。除此之外,Jupyter 还提供的灵便弱小的扩大能力,更是为 Jupyter 的深层次应用提供了更广大的设想空间。如果你还没有开始接触 Jupyter,那么就从当初开始吧。