В чем причина этого странного поведения при сбое, связанного с Python, Anaconda, Matplotlib, MKL и Jupyter?
Мы довольно озадачены этой проблемой сбоев, так как мы не получаем никаких трассировок или других сообщений о том, что на самом деле не так, поэтому было сложно отлаживать. Во всяком случае, здесь идет.
У нас есть рабочая станция для проведения аналитической работы на Python. Суть проблемы в том, что когда мы работаем с ноутбуками (или запускаем тестовый скрипт, показанный ниже), происходит сбой системы. Авария состоит из зависания ОС и перезагрузки. Ничто не говорит нам о том, что произошло, просто машина зависает и перезагружается.
Сбои происходят чаще всего, когда мы запускаем блокнот и просим блокнот делать слишком много графиков. Мы не можем точно определить "слишком много графиков", но приведенный ниже пример - крайний случай, чтобы вызвать проблему. Скрипт иногда вызывает сбой быстро, а иногда занимает немного времени. Но неизбежно, это приведет к краху.
Вот некоторые из вещей, которые мы выполняем, и которые, судя по нашим исследованиям, пока что являются частью проблемы:
- Ubuntu 18.04
- Анаконда 5.2.0 с МКЛ
- Numpy 1.16.2
- Matplotlib 3.0.3
- Jupyter 1.0.0
Краткое изложение выводов:
- Базовая установка Anaconda использует Numpy с MKL и связывает Matplotlib со своими зависимостями в дистрибутиве Anaconda. Выполнение тестового сценария ниже с Python вызывает сбой каждый раз. ETA: Мы пробовали разные бэкэнды для Matplotlib, но это не имело значения.
- Если мы запустим тестовый скрипт из дистрибутива Anaconda, где Numpy был установлен Conda, но не с MKL, а Matplotlib был установлен через pip, а не через Conda, то скрипт будет работать нормально. Если мы используем MKL или Conda вместо pip для установки Matplotlib, мы получим сбой. Мы также можем нормально запустить скрипт с дистрибутивом, отличным от Anaconda, со всем, что установлено через pip (и без других ссылок MKL).
- Если мы создадим версию скрипта для ноутбука Jupyter (по одному графику на ячейку) и запустим все ячейки, сбой ноутбука приведет к сбою. Таким образом, все наши достижения в пункте 2 уничтожаются только с помощью Jupyter.
- Обычно мы запускаем Jupyter в контейнере Docker и за обратным прокси-сервером Nginx. Мы исключили это как причину, потому что образы Docker также являются Ubuntu 18.04, и мы выполнили тесты непосредственно на хост-компьютере, чтобы исключить любые проблемы с Docker.
- Когда мы отслеживаем использование ресурсов, мы, естественно, обнаруживаем, что с MKL загрузка ЦП достигает 300-400%. У нас 12-ядерный процессор, и мы обычно достигаем более высоких значений%. Мы почти не используем гигабайт памяти при запуске тестового скрипта, имея емкость 128 ГБ, и регулярно проводим анализ данных, который значительно увеличивает наш 1 ГБ.
Это касается обложек, что мы смогли выяснить. Поскольку сбои были так сильно привязаны к построению графика, казалось вполне очевидным, что изменения в Matplotlib создали хотя бы частичное исправление. Кроме того, проблема MKL добавила загадочного спутника, но мы подумали, что у нас есть обходной путь. Но затем, когда мы вернулись, чтобы протестировать его в Jupyter, оказалось, что, хотя мы запустили скрипт, пункт 4 по-прежнему показывает, что мы не все полностью исправили.
И это подводит нас к этому посту. Ничто из того, что я видел в Интернете, близко не соответствует тому, что мы наблюдаем, и я никогда не видел ничего подобного. У меня совершенно нет идей, и я не сомневаюсь, что это аппаратная проблема.
Любая помощь взлома этого ореха будет принята с благодарностью. Я думаю попробовать это на нашей рабочей станции с дистрибутивом Linux, отличным от Ubuntu.
# 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
Это приемлемо для нас, но если у кого-то есть реальное исправление или объяснение или действительно что-нибудь, чтобы добавить к этому, я - все уши.
У меня были точно такие же проблемы со свежей системой Ubuntu 18.04.2 LTS и последней свежей установкой Anaconda. Интересно, что у меня было точно такое же поведение (зависание + сбой системы) в Windows 10 Pro (полностью обновленный).
AFAIK, 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 будет зависать в самом конце своего выключения питания с этими настройками, и мне придется вручную выключить машину. Не уверен, что это технически отлично подходит для оборудования.