Jupyter Lab замораживает компьютер, когда не хватает оперативной памяти - как это предотвратить? - PullRequest
10 голосов
/ 15 октября 2019

Я недавно начал использовать Jupyter Lab, и моя проблема в том, что я работаю с довольно большими наборами данных (обычно сам набор данных составляет приблизительно 1/4 от объема ОЗУ моего компьютера). После нескольких преобразований, сохраненных в виде новых объектов Python, у меня заканчивается память. Проблема в том, что когда я приближаюсь к доступному пределу ОЗУ и выполняю любую операцию, для которой требуется другое пространство ОЗУ, мой компьютер зависает, и единственный способ исправить это - перезапустить его. Это поведение по умолчанию в Jupyter Lab / Notebook или это некоторые настройки, которые я должен установить? Обычно я ожидаю сбоя программы (как, например, в RStudio), а не всего компьютера

Ответы [ 7 ]

3 голосов
/ 23 октября 2019

Если вы используете Ubuntu, проверьте OOM killers, вы можете получить информацию от здесь

Вы можете использовать earlyoom . Его можно настроить по своему усмотрению, например, earlyoom -s 90 -m 15 запустит earlyoom, а когда размер подкачки будет меньше, чем% 90, а память меньше, чем% 15, это остановит процесс, который вызывает OOM, и предотвратит зависание всей системы. ,Вы также можете настроить приоритет процессов.

3 голосов
/ 22 октября 2019

Абсолютно самым надежным решением этой проблемы было бы использование контейнеров Docker. Вы можете указать, сколько памяти выделить Jupyter, и если в контейнере не хватает памяти, это не имеет большого значения (просто не забывайте часто экономить, но это само собой разумеется).

Этот блог даст вам большую часть пути туда. Здесь также есть несколько полезных инструкций по настройке Jupyter Lab из одного из свободно доступных, официально поддерживаемых образов Jupyter:

https://medium.com/fundbox-engineering/overview-d3759e83969c

, а затем вы можете изменить команду docker run какописывается в руководстве как (например, для 3 ГБ):

docker run --memory 3g <other docker run args from tutorial here>

Синтаксис опций памяти докера см. в следующем вопросе:

Какой блок запускается докером "-Память "Вариант ожидать?

2 голосов
/ 17 октября 2019

Я также работаю с очень большими наборами данных (3 ГБ) в Jupyter Lab и испытываю ту же проблему в Labs. Неясно, нужно ли вам поддерживать доступ к предварительно преобразованным данным, если нет, я начал использовать del неиспользуемых больших переменных данных, если они мне не нужны. del удаляет переменные из вашей памяти. Изменить **: есть несколько возможностей для проблемы, с которой я сталкиваюсь. Я сталкиваюсь с этим чаще, когда использую удаленный экземпляр jupyter, а также в spyder, когда выполняю большие преобразования.

Например,

df = pd.read('some_giant_dataframe') # or whatever your import is
new_df = my_transform(df)
del df # if unneeded.

Джейкс, вы также можете найти это поток в больших рабочих потоках данных полезно. Я искал Dask , чтобы помочь с памятью.

Я заметил в spyder и jupyter, что зависание обычно происходит при работе в другой консоли, в то время как консоль большой памяти работает,Что касается того, почему он просто зависает, а не падает, я думаю, это как-то связано с ядром. В IPython github открыто несколько проблем с памятью - # 10082 и # 10117 кажутся наиболее актуальными. Один пользователь здесь предлагает отключить завершение табуляции в jedi или обновить джедай.

В 10117 они предлагают проверить вывод get_ipython().history_manager.db_log_output. У меня те же проблемы, и мои настройки верны, но стоит проверить

0 голосов
/ 26 октября 2019

Вы также можете использовать ноутбуки в облаке, например, Google Colab здесь . Они предоставили возможность для рекомендованных ОЗУ и поддерживают ноутбук Jupyter по умолчанию.

0 голосов
/ 25 октября 2019

Я собираюсь обобщить ответы на следующий вопрос . Вы можете ограничить использование памяти вашей программой. В дальнейшем это будет функция ram_intense_foo(). Перед вызовом нужно вызвать функцию limit_memory(10)

import resource
import platform
import sys
import numpy as np 

def memory_limit(percent_of_free):
    soft, hard = resource.getrlimit(resource.RLIMIT_AS)
    resource.setrlimit(resource.RLIMIT_AS, (get_memory() * 1024 * percent_of_free / 100, hard))

def get_memory():
    with open('/proc/meminfo', 'r') as mem:
        free_memory = 0
        for i in mem:
            sline = i.split()
            if str(sline[0]) == 'MemAvailable:':
                free_memory = int(sline[1])
                break
    return free_memory

def ram_intense_foo(a,b):
    A = np.random.rand(a,b)
    return A.T@A

if __name__ == '__main__':
    memory_limit(95)
    try:
        temp = ram_intense_foo(4000,10000)
        print(temp.shape)
    except MemoryError:
        sys.stderr.write('\n\nERROR: Memory Exception\n')
        sys.exit(1)
0 голосов
/ 21 октября 2019

Я думаю, вы должны использовать куски. Вот так:

df_chunk = pd.read_csv(r'../input/data.csv', chunksize=1000000)
chunk_list = []  # append each chunk df here 

# Each chunk is in df format
for chunk in df_chunk:  
    # perform data filtering 
    chunk_filter = chunk_preprocessing(chunk)

    # Once the data filtering is done, append the chunk to list
    chunk_list.append(chunk_filter)

# concat the list into dataframe 
df_concat = pd.concat(chunk_list)

Для получения дополнительной информации проверьте: https://towardsdatascience.com/why-and-how-to-use-pandas-with-large-data-9594dda2ea4c

Я предлагаю не добавлять список снова (возможно, ОЗУ снова будет перегружено). Вы должны закончить свою работу в этом для цикла.

0 голосов
/ 17 октября 2019

Нет причин просматривать весь вывод большого фрейма данных. Просмотр или манипулирование большими фреймами данных будет излишне использовать большие объемы ресурсов вашего компьютера.

Все, что вы делаете, можно сделать в миниатюре. Работать над кодированием и манипулированием данными намного проще, когда фрейм данных мал. Лучший способ работы с большими данными - это создать новый фрейм данных, который занимает только небольшую часть или небольшую выборку большого фрейма данных. Затем вы можете исследовать данные и выполнить кодирование на меньшем фрейме данных. После того, как вы изучите данные и получите свой код работающим, просто используйте этот код в большом фрейме данных.

Самый простой способ - просто взять первые n, число первых строк из фрейма данных с помощью функции head (). Функция head печатает только n, количество строк. Вы можете создать мини-фрейм данных, используя функцию head для большого фрейма данных. Ниже я выбрал первые 50 строк и передал их значение в small_df. Предполагается, что BigData - это файл данных, полученный из библиотеки, которую вы открыли для этого проекта.

library(namedPackage) 

df <- data.frame(BigData)                #  Assign big data to df
small_df <- head(df, 50)         #  Assign the first 50 rows to small_df

Это будет работать большую часть времени, но иногда большой фрейм данных поставляется с предварительно отсортированными или уже переменнымигруппироваться. Если большие данные похожи на эти, вам нужно будет выбрать случайную выборку строк из больших данных. Затем используйте следующий код:

df <- data.frame(BigData)

set.seed(1016)                                          # set your own seed

df_small <- df[sample(nrow(df),replace=F,size=.03*nrow(df)),]     # samples 3% rows
df_small                                                         # much smaller df
...