派玩python之Jupyter使用远程kernel(2)

派玩python之Jupyter使用远程kernel(2)

书接上文, 《派玩python之自部署JupyterLab》

使用树莓派上搭建的JupyterLab使用体验已经非常好了。可以使用python完成常见的绝大多数工作。但是别忘了,python还有很重要的用武之地,就是大规模计算和算法,还有一大票机器学习框架。受限于树莓派空间性能, 如果要跑非常吃CPU的运算,吃GPU的模型训练,就不太合适了。

解决方案就是, 树莓派上只运行Jupyter的Lab,或者Notebook的UI服务,当作云IDE使用。 真正计算运行,放到远程一台性能强大的机器上,不就好了吗?

本期就介绍这种方式。

Jupyter远程调用Kernel的原理(可跳过)

在Jupyter体系里,其实它只管调用Kernel,而Kernel在哪里不关心。也就是说在架构层面已经做了隔离,这就为远程调用提供了可能性。
具体来说, Jupyter可以说是偏前端的方案名,底层服务是依赖IPython的可交互编程组件来工作。其核心原理图如下,摘自IPython官网文档

                                                    图1 Ipython原理

可以看到, 执行器和Kernel之间是靠ZMQ的消息来通信的。 但是, 如果想在两个机器直接直接消息通信不是好主意,数据是明文裸漏的,毫无安全可言。 官方的远程连接文档 是利用ssh 绑定并转发本地的收发消息端口到远端机器的ssh通道实现的,即ssh tunnels。 如果想手动绑定参考这个文档即可,老鸟推荐, 我们本次不使用。

前人栽树,后人乘凉。 网上已经有人将上述手动动作自动化了,并且以remote_ikernel的module发布出来了。它做了几件事:

  • kernel管理,remote_ikernel manage --add增加kernel到本地环境。 这个和ipykernel install功能效果类似。
  • 使用ssh命令,传递本地端口运行配置connection_file到远程机器, 并用此文件启动远程kernel进程, 和直接在远端ipython kernel命令效果类似。
  • 开启数个ssh的同端口tunnels(管道), 使用相同connection_file启动本地的kernel连接。本地以为还在连接本地端口来进行ZMQ通信,其实端口都被转发到远端kernel进程上了。

可以看到,以上逻辑和手动连接过程原理类似的。remote_ikernel的github地址在此。

利用remote_ikernel自动远程连接

依赖官网手动太麻烦了,我们今天使用一个remote_ikernel来连接。
前置准备

  • 安装好jupyter的树莓派(或其他),是jupyter lab或者notebook都可以,docker或非docker均可。下称clientA。具体教程可以参考前文《派玩python之自部署JupyterLab》
  • 一台已经安装好python的远程机,Linux或者Windows。下称serverB。
  • 配置好clientA上ssh免登serverB。(ssh免登方法非常简单,可以自行google)

下面开始

clientA上安装和连接remote_ikernel(远程机serverB是Linux)

  1. 登录clientA,或者在jupyterlab上打开terminal,然后开始安装remote_ikernel
pip install remote_ikernel

然后

remote_ikernel manage --add \
   --kernel_cmd="ipython kernel -f {connection_file}" \
   --name="Remote Python" --interface=ssh \
   [email protected]

注意host要正确。提前测试ssh免登是没问题的,使用docker的要在docker内或者jupyter上terminal测试。

  1. 刷新jupyter UI,在右上角选择切换kernel,会发现已经有上一步的Remote Python已经显示出来了,直接选择即可。 完成。

clientA上安装和连接remote_ikernel(远程机serverB是Windows)

笔者是Windows11专业版,其他版本理论上都OK。 首先假定你已经安装好了OpenSSH服务器并设置好了免登,可参考官方文档,也可以自行google。

下面开始正题。remote_ikernel的当前版本(0.4.x)是不支持连Windows的。我稍微改了一版,不是特别完善但是能用了。

  1. 登录clientA,或者在jupyterlab上打开terminal。 用git clone下载支持windows版remote_ikernel,或者打包下载。
git clone https://github.com/jmu/remote_ikernel
cd remote_ikernel
python setup.py install

这样就手动安装好了

然后下面是我Windows环境用户jmu, 你替换成自己的。 另外下面是我基于conda的Keras命令。替换成默认ipython kernel -f {connection_file}在环境变量没问题情况下也是可以运行的。关键在于--win命令必须有。

remote_ikernel manage --add     --kernel_cmd="D:\\Programs\\anaconda3\\envs\\keras\\python.exe -m ipykernel_launcher -f {connection_file}"     --name="Remote Keras" --interface=ssh     [email protected] --workdir="C:\\User\\jmu" --win --verbose

注意以上命令都在clientA执行的, Windows机本例只需要安装好Python,conda,和Keras和其依赖的TensorFlow

  1. 刷新jupyter UI,在右上角选择切换kernel,会发现已经有上一步的SSH xxxx Remote Keras已经显示出来了,直接选择即可。 完成。

#已知问题:juptyer端shutdown kernel的时候,Windows端的进程不会被杀掉。 为了避免越攒越多,可以手动杀一下。

#已知问题2: 不会自动删除json文件在work目录, 可以手动删一下。

全文完。 下期尝试使用WSL2进行远程连接。