与 Python、Anaconda、Matplotlib、MKL 和 Jupyter 相关的这种奇怪的崩溃行为的原因是什么?

与 Python、Anaconda、Matplotlib、MKL 和 Jupyter 相关的这种奇怪的崩溃行为的原因是什么?

我们对这个崩溃问题感到很困惑,因为我们没有收到任何回溯或其他关于实际错误的信息,所以很难调试。无论如何,开始吧。

我们有一个工作站,用于运行 Python 中的分析工作。问题的关键在于,当我们在笔记本上工作(或运行下面显示的测试脚本)时,系统崩溃了。崩溃包括操作系统冻结,然后重新启动。没有任何信息告诉我们发生了什么,只是机器冻结并重新启动。

当我们运行笔记本并要求笔记本进行过多的绘图时,崩溃最常发生。我们无法准确定义“过多的绘图”,但下面的示例是一个极端情况,可以强制解决此问题。该脚本有时会很快导致崩溃,有时会花一点时间。但不可避免地,它会导致崩溃。

根据我们目前的研究,我们正在运行的一些内容似乎是问题的一部分:

  • Ubuntu 18.04
  • 带有 MKL 的 Anaconda 5.2.0
  • Numpy 1.16.2
  • Matplotlib 3.0.3
  • Jupyter 1.0.0

研究结果总结如下:

  1. 基本 Anaconda 安装使用 Numpy 和 MKL,并将 Matplotlib 链接到 Anaconda 发行版中的依赖项。使用 Python 运行下面的测试脚本每次都会导致崩溃。ETA:我们尝试了不同的 Matplotlib 后端,但没有什么不同。
  2. 如果我们从 Anaconda 发行版运行测试脚本,其中 Numpy 由 Conda 安装,但是不是通过 pip 安装 MKL 和 Matplotlib,不是通过 Conda,那么脚本可以正常运行。如果我们使用 MKL或者使用 Conda 而不是 pip 安装 Matplotlib 时,我们遇到了崩溃。我们还可以使用非 Anaconda 发行版顺利运行该脚本,所有东西都通过 pip 安装(无需其他 MKL 链接)。
  3. 如果我们创建脚本的 Jupyter 笔记本版本(每个单元格一个图)并运行所有单元格,笔记本将导致崩溃。因此,仅使用 Jupyter,我们在第 2 点的所有收益都会被抹去。
  4. 我们通常在 Docker 容器中并在 Nginx 反向代理后面运行 Jupyter。我们排除了这个原因,因为 Docker 镜像也是 Ubuntu 18.04,我们直接在主机上运行测试以排除任何 Docker 问题。
  5. 当我们跟踪资源使用情况时,我们自然而然地发现,使用 MKL 时,CPU 使用率会达到 300-400% 的范围。我们有一个 12 核 CPU,并且经常达到更高的 % 值。在运行测试脚本时,我们几乎不使用 1GB 的内存,而容量为 128GB,并且经常运行数据分析,这会使我们的内存使用量远远超过 1GB。

这大概涵盖了我们能够弄清楚的内容。由于崩溃与绘图密切相关,因此对 Matplotlib 的调整似乎至少可以部分修复。MKL 问题在此基础上增加了一个令人费解的混杂因素,但我们认为我们有一个解决方法。但是当我们回到 Jupyter 中测试它时,结果发现,即使我们运行了脚本,第 4 点仍然表明我们还没有完全修复所有问题。

这就是我们写这篇文章的原因。我在网上看到的任何东西都与我们观察到的完全不符,我从未见过类似的东西。我完全没有主意,也没法再去想这是否真的是硬件问题。

任何帮助解决这个问题的帮助都将不胜感激。我正在考虑在我们的工作站上使用 Ubuntu 以外的 Linux 发行版尝试一下。

# Test Script
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# None of the dataframe stuff seems to matter nor the figure size, just 
# that we're trying to plot a bunch
n = 100000
figsize = (8, 6)

df = pd.DataFrame(
    {
        'A': np.cumsum(np.random.rand(n)) / np.arange(1, n+1, 1),
        'B': np.cumsum(np.random.rand(n)) / np.arange(1, n+1, 1),
        'C': np.cumsum(np.random.rand(n)) / np.arange(1, n+1, 1)
    },
    index=pd.date_range('2001-01-01 12:00:00', freq='S', periods=n)
)
df.plot(figsize=figsize)
# closing the figures just in case, but doesn't make a difference
plt.close(plt.gcf())

...
# Repeat the dataframe and plotting snippet a lot, like ~100x
...

补充:我的同事今天早上发现了这个帖子。对硬件问题进行了更强有力的论证。https://forum.manjaro.org/t/python-matplotlib-script-crashes-system/44052/10

修订更新:在 BIOS 中关闭超线程不起作用。但按照 manjaro.org 上那篇文章的启动建议做过有帮助,只要它们不是与关闭 BIOS 中的超线程一起完成的。

答案1

A解决方法apci=off是使用此论坛帖子中提到的 启动设置:https://forum.manjaro.org/t/python-matplotlib-script-crashes-system/44052/10

这对我们来说是可以接受的,但如果有人有实际的解决方案或解释,或者真的有任何补充,我洗耳恭听。

答案2

我在全新 Ubuntu 18.04.2 LTS 系统和最新 Anaconda 全新安装中遇到了完全相同的问题。有趣的是,我在 Windows 10 Pro(完全最新)上遇到了完全相同的行为(冻结 + 系统崩溃)。

据我所知,Windows 不允许在没有 ACPI 的情况下启动。但是,Ubuntu 允许,并且通过添加更改 grub 启动设置acpi=off解决了该问题。

但是,这并没有解决 Windows 分区的问题,因为 Windows 需要 ACPI。我的阿根廷同事(他真的很棒)建议尝试使用较早版本的 matplotlib。因此,我使用该命令conda install matplotlib=2.2.3降级到版本 2.2.3。

降级立即解决了 Ubuntu 和 Windows 上的问题!因此,我建议暂时降级,直到 matplotlib 开发人员解决此问题。这也意味着您不必禁用 ACPI 或任何其他选项,这些选项(在这个新手的估计中)可能在后台执行一些好事,因此最好继续使用。

实际上,这对于 matplotlib 图库中的第一个示例有效。但在通过脚本和 jupyter 笔记本尝试了更多示例后,它仍然在 2.2.3 中崩溃。因此,我升级回最新的 matplotlib 并重新添加acpi=off,但这仍然导致在 jupyter 笔记本中绘制直方图时冻结 + 崩溃。因此,我添加intel_pstate=disable并保留了最新版本的 matplotlib,这样就可以在 jupyter 笔记本中运行。

更新:这样做的一个缺点是系统无法正常关机 :/ Ubuntu 会在关机结束时挂起,我必须手动关闭机器。不确定从技术上来说这对硬件来说是否很好。

相关内容