Jupyter Lab congela il computer quando è fuori RAM: come prevenirlo?


12

Di recente ho iniziato a utilizzare Jupyter Lab e il mio problema è che lavoro con set di dati abbastanza grandi (di solito il set di dati stesso è circa 1/4 della mia RAM del computer). Dopo alcune trasformazioni, salvate come nuovi oggetti Python, tendo a rimanere senza memoria. Il problema è che quando mi sto avvicinando al limite di RAM disponibile ed eseguo qualsiasi operazione che richiede un altro spazio RAM, il mio computer si blocca e l'unico modo per risolverlo è riavviarlo. È un comportamento predefinito in Jupyter Lab / Notebook o è necessario impostare alcune impostazioni? Normalmente, mi aspetto che il programma si blocchi (come in RStudio per esempio), non l'intero computer


Ho avuto lo stesso problema prima, è davvero brutto. Ho dato una rapida occhiata ai problemi di Giove e non ho trovato nulla. Succede anche se si esegue la console IPython (non il semplice Python)?
Bzazz,

Quale pacchetto / modulo hai usato? Che sistema operativo è? Hai scambiato? Quale versione di Jupyter Lab? Se fosse Linux quale versione del kernel?
Nizam Mohamed,

Sono principalmente panda, ma non penso che sia correlato al pacchetto. Il sistema operativo è Ubuntu 16.04.6 LTS e la versione del kernel è 4.15.0-65-generica. La versione di Jupyter Lab è 1.0.2. Ho uno SWAP impostato su 12 GB (assegnato a 2 file) che è 1,5 della mia RAM.
Jakes

Risposte:


5

La soluzione più affidabile a questo problema sarebbe utilizzare i contenitori Docker. È possibile specificare la quantità di memoria da allocare a Jupyter e se il contenitore esaurisce la memoria, semplicemente non è un grosso problema (ricordarsi di salvare frequentemente, ma è ovvio).

Questo blog ti porterà per lo più lì. Ci sono anche alcune istruzioni decenti per configurare Jupyter Lab da una delle immagini Jupyter disponibili gratuitamente e mantenute ufficialmente qui:

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

e quindi puoi modificare il docker runcomando come descritto nel tutorial come (ad esempio per 3 GB):

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

Per la sintassi delle opzioni di memoria della finestra mobile, vedere questa domanda:

Quale unità si aspetta che l'opzione docker esegua "--memory"?


4

Se stai usando Ubuntu, controlla i killer OOM, puoi ottenere informazioni da qui

Puoi usare earlyoom . Può essere configurato come desideri, ad esempio earlyoom -s 90 -m 15avvierà earlyoome quando la dimensione dello scambio è inferiore a% 90 e la memoria è inferiore a% 15, ucciderà il processo che causa OOM e impedirà il blocco dell'intero sistema. È inoltre possibile configurare la priorità dei processi.


2

Lavoro anche con set di dati molto grandi (3 GB) su Jupyter Lab e ho riscontrato lo stesso problema su Labs. Non è chiaro se è necessario mantenere l'accesso ai dati pre-trasformati, in caso contrario, ho iniziato a utilizzare delvariabili di frame di dati di grandi dimensioni inutilizzate se non ne ho bisogno. delrimuove le variabili dalla tua memoria. Modifica **: ci sono più possibilità per il problema che sto riscontrando. Lo incontro più spesso quando utilizzo un'istanza remota di jupyter e anche in spyder quando sto eseguendo grandi trasformazioni.

per esempio

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

Jakes potresti anche trovare utile questa discussione su grandi flussi di lavoro di dati . Ho cercato Dask per aiutare con l'archiviazione della memoria.

Ho notato in spyder e jupyter che il blocco si verifica di solito quando si lavora in un'altra console mentre è in esecuzione una console di memoria di grandi dimensioni. Per quanto riguarda il motivo per cui si blocca invece di schiantarsi, penso che questo abbia qualcosa a che fare con il kernel. Ci sono un paio di problemi di memoria aperti nel github di IPython - # 10082 e # 10117 sembrano i più rilevanti. Un utente qui suggerisce di disabilitare il completamento della scheda jedio l'aggiornamento di jedi.

Nel 10117 propongono di verificare l'output di get_ipython().history_manager.db_log_output. Ho gli stessi problemi e la mia impostazione è corretta, ma vale la pena controllare


1

Puoi anche utilizzare i notebook nel cloud, come Google Colab qui . Hanno fornito la possibilità di RAM consigliate e il supporto per il notebook Jupyter è di default.


0

Penso che dovresti usare pezzi. Come quello:

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)

Per maggiori informazioni, consulta: https://towardsdatascience.com/why-and-how-to-use-pandas-with-large-data-9594dda2ea4c

Suggerisco di non aggiungere di nuovo un elenco (probabilmente la RAM si sovraccaricherà di nuovo). Dovresti finire il tuo lavoro in questo per loop.


Penso che il problema qui non sia come non esaurire la memoria, ma come evitare il crash del computer e la necessità di riavviare. Python dovrebbe arrestarsi in modo anomalo o generare un errore di memoria, ma non rovinare tutto.
Bzazz,

0

Ho intenzione di riassumere le risposte dalla seguente domanda . È possibile limitare l'utilizzo della memoria del programma. Di seguito questa sarà la funzione ram_intense_foo(). Prima di chiamare è necessario chiamare la funzionelimit_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)

-4

Non vi è alcun motivo per visualizzare l'intero output di un frame di dati di grandi dimensioni. La visualizzazione o la manipolazione di frame di dati di grandi dimensioni utilizzerà inutilmente grandi quantità di risorse del computer.

Qualunque cosa tu stia facendo, puoi farlo in miniatura. È molto più semplice lavorare sulla codifica e manipolare i dati quando il frame di dati è piccolo. Il modo migliore per lavorare con i big data è creare un nuovo frame di dati che richiede solo una piccola parte o un piccolo campione del frame di dati di grandi dimensioni. Quindi è possibile esplorare i dati ed eseguire la codifica su un frame di dati più piccolo. Dopo aver esplorato i dati e fatto funzionare il tuo codice, usa semplicemente quel codice nel frame di dati più grande.

Il modo più semplice è semplicemente prendere il primo n, numero delle prime righe dal frame di dati usando la funzione head (). La funzione head stampa solo n, numero di righe. È possibile creare un mini frame di dati utilizzando la funzione head sul frame di dati di grandi dimensioni. Di seguito ho scelto di selezionare le prime 50 righe e di passare il loro valore a small_df. Ciò presuppone che BigData sia un file di dati che proviene da una libreria aperta per questo progetto.

library(namedPackage) 

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

Funzionerà la maggior parte delle volte, ma a volte il frame di big data viene fornito con variabili preordinate o con variabili già raggruppate. Se i big data sono così, allora dovresti prendere un campione casuale delle righe dai big data. Quindi utilizzare il codice che segue:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.