Python、Anaconda、Matplotlib、MKL、Jupyter に関連するこの奇妙なクラッシュ動作の原因は何ですか?

Python、Anaconda、Matplotlib、MKL、Jupyter に関連するこの奇妙なクラッシュ動作の原因は何ですか?

このクラッシュの問題については、トレースバックや実際の問題に関するその他のメッセージが得られず、デバッグが困難であるため、かなり困惑しています。とにかく、やってみます。

私たちは、Python で分析作業を実行するためのワークステーションを持っています。問題の要点は、ノートブックで作業しているとき (または以下に示すテスト スクリプトを実行しているとき) に、システムがクラッシュすることです。クラッシュは、OS のフリーズとその後の再起動で構成されます。何が起こったかを示すものは何もなく、マシンがフリーズして再起動するだけです。

クラッシュは、ノートブックを実行して、ノートブックに少し多すぎるプロットを要求したときに最も頻繁に発生します。「プロットが多すぎる」ことを正確に定義することは不可能ですが、以下の例は問題を強制するための極端なケースです。スクリプトは、すぐにクラッシュを引き起こす場合もあれば、少し時間がかかる場合もあります。しかし、必然的にクラッシュを引き起こします。

これまでの調査に基づいて、問題の一部であると思われる実行中のものの一部を以下に示します。

  • ウブントゥ 18.04
  • MKL 付き Anaconda 5.2.0
  • ナンピー1.16.2
  • マトプロットライブラリ 3.0.3
  • ジュピター 1.0.0

調査結果の要約は次のとおりです。

  1. 基本的な Anaconda インストールでは、Numpy と MKL が使用され、Matplotlib が Anaconda ディストリビューション内の依存関係にリンクされています。以下のテスト スクリプトを Python で実行すると、毎回クラッシュが発生します。ETA: Matplotlib のさまざまなバックエンドを試しましたが、違いはありませんでした。
  2. CondaによってNumpyがインストールされているAnacondaディストリビューションからテストスクリプトを実行すると、ないMKLとMatplotlibはpip経由でインストールされ、ないConda経由でスクリプトを実行すると、スクリプトは正常に動作します。MKLまたはMatplotlib をインストールするために pip ではなく Conda を使用すると、クラッシュが発生します。また、すべてが pip 経由でインストールされ (他の MKL リンクがない)、Anaconda 以外のディストリビューションでもスクリプトを正常に実行できます。
  3. スクリプトの Jupyter ノートブック バージョン (セルごとに 1 つのプロット) を作成し、すべてのセルを実行すると、ノートブックがクラッシュします。つまり、ポイント 2 で得たすべての利点は、Jupyter を使用するだけで消えてしまいます。
  4. 通常、Jupyter は Docker コンテナ内で Nginx リバース プロキシの背後で実行されます。Docker イメージも Ubuntu 18.04 であるため、これを原因として除外し、Docker の問題を排除するためにホスト マシンで直接テストを実行しました。
  5. リソースの使用状況を追跡すると、当然のことながら、MKL では CPU 使用率が 300 ~ 400% の範囲になることがわかります。当社には 12 コアの CPU があり、より高い % 値が定期的に記録されています。テスト スクリプトを実行するときにメモリをほとんど使用しませんが、128 GB の容量があり、定期的にデータ分析を実行すると、1 GB をはるかに超えるメモリが使用されます。

私たちが解明できたことはこれでほぼすべてです。クラッシュはプロットに大きく関係していたため、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

回避策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問題は解決しました。

しかし、ACPI は Windows が期待するものなので、これでは Windows パーティションの問題は解決されませんでした。アルゼンチン人の同僚 (本当に素晴らしい人です) が、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=disablematplotlib を最新バージョンに保つと、jupyter ノートブックでこれを実行できるようになりました。

更新: この方法の欠点の 1 つは、システムが適切に電源を切らないことです :/ これらの設定では、Ubuntu は電源を切る最後のほうでハングアップし、手動でマシンの電源を切る必要があります。ハードウェアにとって技術的に優れているかどうかはわかりません。

関連情報