Jupyter入门指南
**Jupyter**项目是一系列旨在提供一个通用的多语言交互环境,项目的前身是ipython项目。现如今它已经支持许多编程语言了并且对python的支持相当成熟。除了提供交互环境,还提供了一种非常实用的数据格式notebook,现在学界和工业界很多时候用它研究算法原型。
1. 安装与运行
- 支持语言
- PyPy、Golang、Javascript
- R、Scala、Spark、Itorch
- C/C++、Scheme、Haskell
- 安装 Jupyter
# 安装依赖 $ yum install zeromq openssl # Jupyter现在需要独立安装 $ pip install jupyter
- 运行 Jupyter
# 可以通过Web端来访问,默认在localhost:8888启动 $ jupyter notebook
# 使用配置文件可以避免繁琐的参数配置,配置文件在~/.jupyter目录下 # 设置外网可以访问 c.NotebookApp.ip = '0.0.0.0' # 服务启动不打开浏览器 c.NotebookApp.open_browser = False # 设置端口 c.NotebookApp.port = <port>
2. 安全措施
jupyter notebook直接暴露在外显然是不安全的,解决安全问题有两个思路:加密、使用私有通道。
- 加密 – 访问密码
# [step1] # jupyter可以使用如下命令创建密码 $ jupyter notebook password # [step2] # 创建完成后他会保存在~/.jupyter目录下,如下所示 { "NotebookApp": { "password": "sha1:xxxxxxxxx" } } # [step3] # 将其中的password内容复制到上面的配置文件中 # 那么访问的时候如果浏览器没有cookie保存着这个信息就会要求输入密码了 c.NotebookApp.password = u'xxxx'
- 加密 – ssl 密文通信
# 启动的时候加上如下参数,就可以使用ssl加密通信了(https) $ jupyter notebook --certfile=mycert.pem --keyfile mykey.key # 当然更好的方式是修改配置文件 c.NotebookApp.certfile = u'/absolute/path/to/your/certificate/mycert.pem' c.NotebookApp.keyfile = u'/absolute/path/to/your/certificate/mykey.key'
- 使用私有通道 – ssh 隧道技术
- ssh隧道技术简单说就是将一个远端端口映射到本地一个端口,这样信息就都是通过ssh来传递了
# 启动方式 ssh -N -f -L [remote port]:localhost:[local port] -p [ssh port] -l [username] [公网IP]
# 将远端7777端口映射到本地7777端口,那么在远端启动的时候配置文件如下 c.NotebookApp.ip = 'localhost' c.NotebookApp.open_browser = False c.NotebookApp.port = 7777 # 然后使用jupyter启动服务,就可以使用本地的浏览器访问远端的notebook了。后台启动可以使用nohup或者使用supervisor统一管理都可以
3. 多用户访问
使用ssh私有通道的方式可能更加安全些,但这没有改变一个问题,那就是多用户下的文件修改冲突问题,而官方的解决方案是使用jupyterhub工具。
- 特点介绍
- 动时需要sudo权限
- 专门用来管理多用户
- 默认使用服务器机器上的用户作为用户
- 安装 jupyterhub
# 安装jupyterhub $ python3 -m pip install jupyterhub $ npm install -g configurable-http-proxy
- 创建配置文件模板
# jupyterhub也可以创建一个配置文件模板 # 创建的配置文件名称为jupyterhub_config.py $ jupyterhub --generate-config
- 修改配置文件
# 正常的运行需要修改配置文件如下 # 让admin账号可以控制或者进入非admin账户 c.JupyterHub.admin_access = True # 将当前的系统账号设为白名单 c.Authenticator.whitelist = {<你当前的系统账号>} # 将当前的系统账号设为admin账号 c.Authenticator.admin_users={<你当前的系统账号>} # 设置外网可以访问 c.JupyterHub.ip = '0.0.0.0' # 设置端口 c.JupyterHub.port = 5888 # 将jupyterhub-singleuser写死 c.Spawner.cmd = ['/path/to/jupyterhub-singleuser'] # 设置ssl的证书文件地址,不用https可以不设置 c.JupyterHub.ssl_cert = '' # 设置ssl的证书的key文件地址,不用https可以不设置 c.JupyterHub.ssl_key = ''
- 运行 jupyterhub
# 指定配置文件运行 $ sudo jupyterhub -f jupyterhub_config.py
4. 代码调试
- 异常抛出精简
- 可以使用%xmode Plain和%xmode Verbose来在精简模式和运来模式间切换
def f1(a,b): return a/b def f2(x): a = x b = x-1 return f1(a,b) %xmode Plain Exception reporting mode: Plain f2(1) %xmode Verbose Exception reporting mode: Verbose f2(1)
- 用户调试错误
- 使用%debug会在报错时进去调试模式
def f1(a,b): return a/b def f2(x): a = x b = x-1 return f1(a,b) %debug
- 运行时间检查
- 常用的就是%timeit <func>命令
In [1]: time sum(map(lambda x:x**2,range(10000000))) CPU times: user 6.15 s, sys: 61.9 ms, total: 6.21 s Wall time: 6.41 s
5. 优化性能
- 用 Cython 优化性能
# 原版程序 def fib(n): if n<2: return n return fib(n-1)+fib(n-2) %timeit fib(20) 5.04 ms ± 94.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# 直接用cython加速,时间上和原版俩差了3倍的速度 %%cython def fib_cython(n): if n<2: return n return fib_cython(n-1)+fib_cython(n-2) %timeit fib_cython(20) 1.66 ms ± 164 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
- 使用静态编译优化
# 使用静态编译,速度直线上升,快了100倍不止! %%cython cpdef long fib_cython_type(long n): if n<2: return n return fib_cython_type(n-1)+fib_cython_type(n-2) %timeit fib_cython_type(20) 56.7 µs ± 1.8 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
- 使用缓存计算优化
# 可以大大减少运算量 from functools import lru_cache as cache @cache(maxsize=None) def fib_cache(n): if n<2: return n return fib_cache(n-1)+fib_cache(n-2) %timeit fib_cache(20) 181 ns ± 5.27 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
- 使用缓存和 Cython 加速优化
# 只有1微秒左右 %%cython from functools import lru_cache as cache @cache(maxsize=None) def fib_cache_cython(n): if n<2: return n return fib_cache_cython(n-1)+fib_cache_cython(n-2) %timeit fib_cache_cython(20) 218 ns ± 13 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
- 使用 numba 加速
# 略不如Cython的最终版本 from numba import jit @jit def fib_seq_numba(n): if n < 2: return n a,b = 1,0 for i in range(n-1): a,b = a+b,a return a %timeit fib_seq_numba(20) 293 ns ± 5.73 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
6. 格式转换
nbconvert是jupyter notebook的格式转换工具,它支持把notebook转化为markdown、pdf、html等格式的文件。
- 它依赖pandoc,所以先要安装pandoc,另外如果要转成pdf格式,还要安装latex和一些依赖
# 安装依赖 $ sudo tlmgr install ucs $ sudo tlmgr install collectbox $ sudo tlmgr install adjustbox $ sudo tlmgr install cyrillic $ sudo tlmgr install collection-langcyrillic
- 之后要使用nbconvert只需要
# 转换格式 $ jupyter nbconvert --to <output format> <input notebook>
- input notebook可以使用通配符来指定复数的.ipynb文件