Zac*_*mzi 5 python printing joblib jupyter jupyter-notebook
因此,我正在使用joblib来并行化一些代码,并且我注意到在jupyter笔记本中使用它时无法打印内容。
我尝试在ipython中使用相同的示例,但效果很好。
这是在jupyter笔记本单元中编写的最小(非)工作示例
from joblib import Parallel, delayed
Parallel(n_jobs=8)(delayed(print)(i) for i in range(10))
Run Code Online (Sandbox Code Playgroud)
所以我得到的输出,[None, None, None, None, None, None, None, None, None, None]但什么都没有打印。
实际上,在检查笔记本进程的日志时,我注意到打印在那里进行。我希望打印发生在笔记本中,而不是笔记本过程的日志中。
我已经打开了一个Github问题,但是到目前为止关注的很少。
我认为这部分是由于Parallel产生子工作者的方式以及 Jupyter Notebook 如何为这些工作者处理 IO 造成的。当启动时没有为 指定值backend,Parallel将默认loky使用池化策略,该策略直接使用 fork-exec 模型来创建子进程。
如果您使用终端从终端启动 Notebook
$ jupyter-notebook
Run Code Online (Sandbox Code Playgroud)
常规stderr和stdout流似乎仍然连接到该终端,而笔记本会话将在新的浏览器窗口中启动。在笔记本中运行发布的代码片段确实会产生预期的输出,但它似乎进入stdout并最终进入终端(如问题中的注释所示)。这进一步支持了这种行为是由loky和 notebook之间的交互以及 notebook 为子进程处理标准 IO 流的方式引起的怀疑。
这让我在 github 上进行了讨论(截至发帖时的过去 2 周内处于活跃状态),notebook 的作者似乎意识到了这一点,但目前似乎没有明显且快速的解决方案.
如果您不介意切换Parallel用于生成子项的后端,您可以这样做:
from joblib import Parallel, delayed
Parallel(n_jobs=8, backend='multiprocessing')(delayed(print)(i) for i in range(10))
Run Code Online (Sandbox Code Playgroud)
使用multiprocessing后端,事情按预期工作。threading看起来也很好用。这可能不是您希望的解决方案,但希望在笔记本作者努力寻找合适的解决方案时就足够了。
我会将这个交叉发布到 GitHub,以防有人愿意添加到这个答案中(我不想误报任何人的意图或把话放在人们的嘴里!)。
测试环境:
MacOS - Mojave (10.14)
Python - 3.7.3
pip3 - 19.3.1
在 2 种配置中测试。证实了同时使用时产生预期的输出multiprocessing,并threading为backend参数。使用pip3.
设置 1:
ipykernel 5.1.1
ipython 7.5.0
jupyter 1.0.0
jupyter-client 5.2.4
jupyter-console 6.0.0
jupyter-core 4.4.0
notebook 5.7.8
Run Code Online (Sandbox Code Playgroud)
设置 2:
ipykernel 5.1.4
ipython 7.12.0
jupyter 1.0.0
jupyter-client 5.3.4
jupyter-console 6.1.0
jupyter-core 4.6.2
notebook 6.0.3
Run Code Online (Sandbox Code Playgroud)
我也成功使用了与“Setup 2”相同的版本,但notebook包版本降级到 6.0.2。
这种方法在 Windows 上不一致。不同的软件版本组合会产生不同的结果。做最直观的事情——将所有东西升级到最新版本——并不能保证它会起作用。
该问题已在最新版本中修复ipykernel。要解决问题就这样做pip install --upgrade ipykernel。
据我了解,任何 6 以上的版本都可以,正如一位维护者在Github 评论中提到的那样。
| 归档时间: |
|
| 查看次数: |
133 次 |
| 最近记录: |