【问题标题】:Printed output not displayed when using joblib in jupyter notebook在 jupyter notebook 中使用 joblib 时不显示打印输出
【发布时间】:2019-09-21 03:29:51
【问题描述】:

所以我使用joblib 来并行化一些代码,我注意到在 jupyter 笔记本中使用它时无法打印。

我尝试在 ipython 中使用相同的示例,并且效果很好。

这是一个在 jupyter 笔记本单元格中编写的最小(非)工作示例

from joblib import Parallel, delayed
Parallel(n_jobs=8)(delayed(print)(i) for i in range(10))

所以我得到了[None, None, None, None, None, None, None, None, None, None] 的输出,但没有打印任何内容。

我期望看到的(实际打印顺序可能是随机的):

1
2
3
4
5
6
7
8
9
10
[None, None, None, None, None, None, None, None, None, None]

注意:

您可以在笔记本进程的日志中看到打印。但我希望打印发生在笔记本中,而不是笔记本进程的日志中。

编辑

我打开了一个Github issue,但到目前为止很少有人关注。

【问题讨论】:

    标签: python parallel-processing jupyter-notebook jupyter joblib


    【解决方案1】:

    我认为这部分是由于Parallel 产生子工作者的方式,以及 Jupyter Notebook 如何为这些工作者处理 IO。在没有为backend 指定值的情况下启动时,Parallel 将默认为loky,它利用直接使用 fork-exec 模型创建子进程的池化策略。

    如果您使用

    从终端启动 Notebook
    $ jupyter-notebook
    

    常规的stderrstdout 流似乎仍然连接到该终端,而笔记本会话将在新的浏览器窗口中开始。在笔记本中运行发布的代码 sn-p 确实会产生预期的输出,但它似乎会转到 stdout 并最终出现在终端中(如 Note中所暗示的) > 在问题中)。这进一步支持了这种行为是由loky 与 notebook 之间的交互以及 notebook 为子进程处理标准 IO 流的方式引起的怀疑。

    这将我带到了 github 上的 this discussion(在发布后的过去 2 周内活跃),notebook 的作者似乎意识到了这一点,但似乎没有明显且快速的解决方案目前的问题。

    如果您不介意切换 Parallel 用于生成子代的后端,您可以这样做:

    from joblib import Parallel, delayed
    Parallel(n_jobs=8, backend='multiprocessing')(delayed(print)(i) for i in range(10))
    

    使用multiprocessing 后端,一切正常。 threading 看起来也可以正常工作。这可能不是您希望的解决方案,但希望在笔记本作者努力寻找合适的解决方案时它就足够了。

    我会将这个交叉发布到 GitHub,以防有人愿意添加到这个答案中(我不想误报任何人的意图或把话放在人们的嘴里!)。


    测试环境:
    MacOS - 莫哈韦 (10.14)
    Python - 3.7.3
    pip3 - 19.3.1

    在 2 种配置中进行了测试。确认将multiprocessingthreading 用于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
    

    设置 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
    

    我也成功使用了与“设置 2”相同的版本,但将 notebook 软件包版本降级为 6.0.2。

    注意:

    此方法在 Windows 上的工作方式不一致。软件版本的不同组合产生不同的结果。做最直观的事情 - 将所有内容升级到最新版本 - 并不能保证它会起作用。

    【讨论】:

    • 我可以确认这在 Colab 中有效,但是我刚刚使用 Jupyter Notebook v6.0.2 和 JupyterLab v1.2.4 (Python v3.6.8) 进行了测试,但两者都不起作用,我只是看到stdout 中的打印并获取 None 返回的数组。您使用的是哪个版本的 Jupyter Notebook?
    • 我更新了答案以包含有关测试环境的详细信息。除了 6.0.3 之外,我使用您提到的两个版本的 Notebook 都得到了预期的结果。我使用的是 Python 3.7,但如果这是问题所在,我会感到有些惊讶。你是如何安装软件包的?您使用的是 MacOS/Linux,还是使用 Windows?
    • 我使用的是 Windows,这实际上可能有所不同。
    • 我确认它可以在 Linux 上运行。我想我们发现了另一个仅与 Windows 相关的错误。请更新您的答案以提及这一点。感谢您的帮助,这个问题让我很头疼! :-)
    • @spizwhiz 实际上昨天刚刚检查过这个。不幸的是,自 2 月以来,讨论此问题的 GitHub 上的线程没有太多活动,所以我怀疑在不久的将来会有修复。
    【解决方案2】:

    在 Z4-tier 的 git link scottgigante 的方法在 Windows 中工作,但与提到的结果相反:在 Jupyter notebook 中,“多处理”后端永远挂起,但默认的 loky 运行良好(python 3.8.5 和 notebook 6.1.1 ):

    from joblib import Parallel, delayed
    import sys
    def g(x):
        stream = getattr(sys, "stdout")
        print("{}".format(x), file=stream)
        stream.flush()
        return x
    Parallel(n_jobs=2)(delayed(g)(x**2) for x in range(5))
    
    executed in 91ms, finished 11:17:25 2021-05-13
    [0, 1, 4, 9, 16]
    

    更简单的方法是延迟使用恒等函数:

    Parallel(n_jobs=2)(delayed(lambda y:y)([np.log(x),np.sin(x)]) for x in range(5))
    executed in 151ms, finished 09:34:18 2021-05-17
    [[-inf, 0.0],
     [0.0, 0.8414709848078965],
     [0.6931471805599453, 0.9092974268256817],
     [1.0986122886681098, 0.1411200080598672],
     [1.3862943611198906, -0.7568024953079282]]
    

    或者这样使用:

    Parallel(n_jobs=2)(delayed(lambda y:[np.log(y),np.sin(y)])(x) for x in range(5))
    executed in 589ms, finished 09:44:57 2021-05-17
    [[-inf, 0.0],
     [0.0, 0.8414709848078965],
     [0.6931471805599453, 0.9092974268256817],
     [1.0986122886681098, 0.1411200080598672],
     [1.3862943611198906, -0.7568024953079282]]
    

    【讨论】:

      猜你喜欢
      • 2022-08-19
      • 2021-03-03
      • 2023-04-07
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多