Jupyter入门指南


ipython-jupyter


**Jupyter**项目是一系列旨在提供一个通用的多语言交互环境,项目的前身是ipython项目。现如今它已经支持许多编程语言了并且对python的支持相当成熟。除了提供交互环境,还提供了一种非常实用的数据格式notebook,现在学界和工业界很多时候用它研究算法原型。

1. 安装与运行

  • 支持语言

    • PyPyGolangJavascript
    • RScalaSparkItorch
    • C/C++SchemeHaskell
  • 安装 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. 格式转换

nbconvertjupyter notebook的格式转换工具,它支持把notebook转化为markdownpdfhtml等格式的文件。

  • 它依赖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文件

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录