使Jupyter笔记本持续运行的方法

1,379 阅读4分钟

当你的浏览器与Jupyter笔记本断开连接时,这是很令人沮丧的事情

在土星云,我们管理着一个数据科学平台,提供Jupyter笔记本、Dask集群以及部署模型、仪表盘和作业的方法。因此,我们经常帮助客户排除笔记本的故障,而网络断开是一个常见的问题。

我们已经得到了一些客户,他们正在为长时间运行的Jupyter笔记本而苦恼--这些笔记本需要几个小时甚至更长时间才能执行。通常他们会来找我们,因为这些长时间运行的笔记本会在某些时候失去服务器和浏览器之间的连接,这在云服务中很常见。通常情况下,云服务会优雅地重新连接,没有任何问题,但在Jupyter的情况下,如果连接丢失,Jupyter会停止保存任何输出。Jupyter笔记本在浏览器中存储了所有的状态,这意味着如果运行代码的服务器和查看代码的浏览器之间出现连接问题,笔记本的状态就会丢失。

如果我们的客户长期运行的代码中出现了错误,而连接被切断,那么用户就没有能力看到代码的输出和它所产生的错误信息。试图在没有输出的情况下调试这些模型是一种徒劳的做法。在本地使用Jupyter时,这不是一个问题,因为计算机与自身的连接是无限稳定的,但在云端工作时,这就是一个问题。

背景

Jupyter笔记本在浏览器中存储所有的状态,因此需要持续的网络连接。这是一个众所周知的设计问题,有很多影响。虽然网络问题不会导致笔记本中的代码停止执行,但它会影响输出被保存到笔记本中的方式。

Jupyter笔记本的流程是。

  • 服务器将输出推送给你的浏览器。
  • 您的浏览器将其添加到笔记本对象中(并将其渲染到屏幕上)。
  • 你的浏览器将笔记本保存到服务器上。

在网络中断的情况下,这个流程就会中断,而且没有输出被保存。长期的解决方案是对Jupyter本身进行修改以处理间歇性的连接,这是一个相当活跃的讨论领域。目前还没有将其添加到开源Jupyter中的时间表。

然而,有一个短期的策略。

解决方案

我们可以只用一撮代码来调整Jupyter,使其直接将输出保存到服务器上的一个文件。这样做,即使网络连接被切断,服务器仍然会有输出存储到它。这并不完美--在一个理想的世界里,这个输出仍然会显示在笔记本本身,但把它们储存在某个地方而不是丢失,是一个进步。把这段代码放在你的长期运行的笔记本的顶部。

在你的笔记本的顶部执行这个代码。_TADA!_现在,当你运行笔记本时,所有的输出都将在data.log平面文件中得到镜像。

**它是如何工作的。**在Jupyter笔记本中,正常的stdout和stderr文件对象被替换成ipykernel.iostream.OutStream对象(这就是它们在浏览器中的显示方式)。这个对象有一个echo对象,默认为None,可以传播输出。所以第一组行用一个Python文件对象代替echo,你所有正常的stdout和stder现在也被复制到磁盘上了。异常情况由python日志系统处理。在默认配置中,它不向stdout或stderr输出,所以第二组行将它修补成这样,并设置日志级别。

结论

有了这个解决方法,长时间运行Jupyter笔记本的最大痛苦就没有了。也就是说,在Saturn,我们通常建议使用更好的硬件(GPU)或并行化(Dask),以避免等待10个小时来运行你的笔记本。然而,如果你的问题不是可并行化的--这是一个合理的解决方法。然而,如果你不知道如何并行化,但又希望你能做到,你应该和我们谈谈!我们在这方面真的很擅长。我们真的很擅长这个!

免责声明:我是土星云的CTO。我们让你的团队与云资源的连接变得简单。想使用Jupyter和Dask?部署模型、仪表板或作业?从你的笔记本电脑或4TB的Jupyter实例工作?完全透明地了解谁在消耗什么云资源?我们能做到这一切,甚至更多。