这是 jupyter 笔记本中长期缺少的功能。我使用几乎相同的设置:我的笔记本在远程服务器的 tmux 会话中运行,我在本地使用 ssh 隧道。
在做任何工作之前,我在第一个单元格中运行以下代码段:
import sys
import logging
nblog = open("nb.log", "a+")
sys.stdout.echo = nblog
sys.stderr.echo = nblog
get_ipython().log.handlers[0].stream = nblog
get_ipython().log.setLevel(logging.INFO)
%autosave 5
现在假设,我运行一个需要一段时间才能完成的单元(如训练运行)。就像是:
import time
def train(num_epochs):
for epoch in range(num_epochs):
time.sleep(1)
print(f"Completed epoch {epoch}")
train(1000)
现在train(1000)
正在运行,在前 10 秒后,我想做其他事情并关闭浏览器,并断开我的远程连接。
(注意修改后的短自动保存持续时间;我补充说,因为我经常忘记在关闭浏览器选项卡之前保存笔记本。)
500 秒过去后,我可以重新连接到远程服务器并在浏览器中打开笔记本。我的这个单元格的日志将在“完成 epoch 9”之后停止打印,即当我断开连接时。但是,内核实际上仍会train
在后端运行,并且还会显示“忙碌”。
我们现在可以简单地打开文件nb.log
,我们会找到所有日志,包括我们关闭浏览器和连接后的日志。我们可以在闲暇时不断刷新nb.log
文件,新的日志会不断出现,直到内核完成运行train()
。
现在如果我们想train()
在它完成之前停止,我们可以在 jupyter 中按下中断按钮。内核将被释放,我们可以运行其他东西(并且键盘中断错误消息也将显示在您的 nb.log 文件中)。我们所有预先计算的笔记本变量和导入的库仍然存在,因为内核实际上并没有断开连接。
虽然这不是一个非常复杂的解决方案,但我发现它很容易实现