Jupyter Lab zawiesza komputer po wyjściu z pamięci RAM - jak temu zapobiec?

12

Niedawno zacząłem używać Jupyter Lab, a moim problemem jest to, że pracuję z dość dużymi zestawami danych (zwykle sam zestaw danych stanowi około 1/4 pamięci RAM mojego komputera). Po kilku przekształceniach zapisanych jako nowe obiekty Pythona zabrakło mi pamięci. Problem polega na tym, że kiedy zbliżam się do dostępnego limitu pamięci RAM i wykonuję dowolną operację wymagającą innej pamięci RAM, mój komputer zawiesza się, a jedynym sposobem na jego naprawę jest ponowne uruchomienie. Czy jest to domyślne zachowanie w Jupyter Lab / Notebook, czy też należy wprowadzić pewne ustawienia? Normalnie oczekiwałbym, że program się zawiesi (jak na przykład w RStudio), a nie cały komputer

jakes
źródło
Miałem wcześniej ten sam problem, to naprawdę paskudne. Rzuciłem okiem na problemy z jupyter i nic nie znalazłem. Czy dzieje się tak również wtedy, gdy uruchomisz konsolę IPython (nie zwykły python)?
Bzazz
Jakiego pakietu / modułu użyłeś? Jaki to jest system operacyjny? Czy miałeś zamianę? Jaka wersja Jupyter Lab? Jeśli to był Linux, jaka jest wersja jądra?
Nizam Mohamed
Są to głównie Pandy, ale nie sądzę, żeby były powiązane z paczką. System operacyjny to Ubuntu 16.04.6 LTS, a wersja jądra to 4.15.0-65-generic. Wersja Jupyter Lab to 1.0.2. Mam SWAP ustawiony na 12 GB (przypisany do 2 plików), co stanowi 1,5 mojej pamięci RAM.
jakes

Odpowiedzi:

5

Absolutnie najbardziej niezawodnym rozwiązaniem tego problemu byłoby użycie kontenerów Docker. Możesz określić, ile pamięci ma zostać przydzielone do Jupytera, a jeśli w pojemniku zabraknie pamięci, po prostu nie jest to wielka sprawa (pamiętaj, aby często zapisywać, ale to oczywiste).

Ten blog zapewni Ci większość możliwości. Istnieje również kilka przyzwoitych instrukcji konfigurujących Jupyter Lab z jednego z darmowych, oficjalnie utrzymywanych obrazów Jupyter tutaj:

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

a następnie możesz zmodyfikować docker runpolecenie zgodnie z opisem w samouczku jako (np. dla 3 GB):

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

Aby uzyskać składnię opcji pamięci dokera, zobacz to pytanie:

Jakiego urządzenia oczekuje okno dokowane z opcją „--memory”?

kd88
źródło
4

Jeśli używasz Ubuntu, sprawdź zabójców OOM, możesz uzyskać informacje tutaj

Możesz skorzystać z wczesnej wersji . Można go skonfigurować dowolnie, np. earlyoom -s 90 -m 15Uruchomi się, earlyooma gdy rozmiar wymiany będzie mniejszy niż% 90, a pamięć będzie mniejsza niż% 15, zabije proces powodujący OOM i zapobiegnie zamrożeniu całego systemu. Możesz także skonfigurować priorytet procesów.

emremrah
źródło
2

Pracuję również z bardzo dużymi zestawami danych (3 GB) w Jupyter Lab i mam ten sam problem w Labs. Nie jest jasne, czy musisz zachować dostęp do wstępnie przetworzonych danych, jeśli nie, zacząłem używać delnieużywanych dużych zmiennych ramki danych, jeśli ich nie potrzebuję.delusuwa zmienne z pamięci. Edycja **: istnieje wiele możliwości napotkanego problemu. Spotykam się z tym częściej, gdy używam zdalnej instancji jupyter, a także w spyderze, gdy wykonuję duże transformacje.

na przykład

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

Jakes, ten wątek może również okazać się pomocny w przepływach pracy dużych danych . Szukałem w Dask, aby pomóc z pamięcią.

Zauważyłem w spyder i jupyter, że zamrażanie zwykle następuje podczas pracy w innej konsoli, gdy działa duża konsola pamięci. Jeśli chodzi o to, dlaczego po prostu zawiesza się zamiast się zawiesić, myślę, że ma to coś wspólnego z jądrem. W githubie IPython otwartych jest kilka problemów z pamięcią - # 10082 i # 10117 wydają się najbardziej odpowiednie. Jeden użytkownik tutaj sugeruje wyłączenie uzupełniania tabulacji jedilub aktualizację jedi.

W 10117 proponują sprawdzenie wyjścia get_ipython().history_manager.db_log_output. Mam te same problemy i moje ustawienie jest prawidłowe, ale warto to sprawdzić

Elizabeth
źródło
1

Możesz także używać notesów w chmurze, takich jak Google Colab tutaj . Udostępniono funkcję zalecanych pamięci RAM, a obsługa notebooka Jupyter jest domyślnie.

Jishan Shaikh
źródło
0

Myślę, że powinieneś użyć kawałków. Tak:

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)

Aby uzyskać więcej informacji, sprawdź: https://towardsdatascience.com/why-and-how-to-use-pandas-with-large-data-9594dda2ea4c

Sugeruję, aby nie dodawać ponownie listy (prawdopodobnie pamięć RAM ponownie się przeładuje). Powinieneś zakończyć pracę w pętli.

Berkay
źródło
Myślę, że problemem nie jest to, jak nie zabraknąć pamięci, ale jak uniknąć awarii komputera i konieczności ponownego uruchomienia. Python powinien ulec awarii lub wyrzucić błąd pamięci, ale nie wszystko zepsuć.
Bzazz
0

Mam zamiar podsumować odpowiedzi na następujące pytanie . Możesz ograniczyć wykorzystanie pamięci przez program. Poniżej będzie to funkcja ram_intense_foo(). Przed wywołaniem należy wywołać funkcję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)
v.tralala
źródło
-4

Nie ma powodu, aby przeglądać całe dane wyjściowe dużej ramki danych. Wyświetlanie dużych ramek danych lub manipulowanie nimi niepotrzebnie zużywa duże ilości zasobów komputera.

Cokolwiek robisz, możesz zrobić w miniaturze. Znacznie łatwiej jest pracować nad kodowaniem i manipulowaniem danymi, gdy ramka danych jest mała. Najlepszym sposobem pracy z dużymi danymi jest utworzenie nowej ramki danych, która pobiera tylko niewielką część lub małą próbkę dużej ramki danych. Następnie możesz eksplorować dane i kodować w mniejszej ramce danych. Po przejrzeniu danych i uruchomieniu kodu, wystarczy użyć tego kodu w większej ramce danych.

Najprostszym sposobem jest po prostu pobranie pierwszego n, liczby pierwszych wierszy z ramki danych za pomocą funkcji head (). Funkcja głowy drukuje tylko n, liczbę rzędów. Możesz utworzyć mini ramkę danych, używając funkcji head na dużej ramce danych. Poniżej wybrałem pierwsze 50 wierszy i przekazałem ich wartość do small_df. Zakłada się, że BigData jest plikiem danych pochodzącym z biblioteki otwartej dla tego projektu.

library(namedPackage) 

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

Będzie to działało przez większość czasu, ale czasami ramka dużych danych jest dostarczana ze wstępnie ustawionymi zmiennymi lub ze zmiennymi już zgrupowanymi. Jeśli duże dane są w ten sposób, należy pobrać losową próbkę wierszy z dużych danych. Następnie użyj następującego kodu:

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
Szary
źródło