Jupyter Lab friert den Computer ein, wenn nicht genügend RAM vorhanden ist - wie kann dies verhindert werden?


12

Ich habe kürzlich angefangen, Jupyter Lab zu verwenden, und mein Problem ist, dass ich mit ziemlich großen Datensätzen arbeite (normalerweise macht der Datensatz selbst ungefähr 1/4 meines Computer-RAM aus). Nach einigen Transformationen, die als neue Python-Objekte gespeichert wurden, geht mir häufig der Speicher aus. Das Problem ist, dass mein Computer einfriert, wenn ich mich dem verfügbaren RAM-Limit nähere und einen Vorgang ausführe, der einen anderen RAM-Speicherplatz benötigt. Die einzige Möglichkeit, dies zu beheben, besteht darin, ihn neu zu starten. Ist dies ein Standardverhalten in Jupyter Lab / Notebook oder sind es einige Einstellungen, die ich vornehmen sollte? Normalerweise würde ich erwarten, dass das Programm abstürzt (wie zum Beispiel in RStudio), nicht der gesamte Computer


Ich hatte vorher das gleiche Problem, es ist wirklich böse. Ich habe einen kurzen Blick in die Jupyter-Ausgaben geworfen und nichts gefunden. Kommt es auch vor, wenn Sie die IPython-Konsole (nicht nur Python) verwenden?
Bzazz

Welches Paket / Modul haben Sie verwendet? Welches Betriebssystem ist das? Hattest du einen Tausch? Welche Version von Jupyter Lab? Wenn es Linux wäre, welche Kernel-Version?
Nizam Mohamed

Es sind hauptsächlich Pandas, aber ich denke nicht, dass es paketbezogen ist. Das Betriebssystem ist Ubuntu 16.04.6 LTS und die Kernel-Version ist 4.15.0-65-generic. Jupyter Lab Version ist 1.0.2. Ich habe einen SWAP auf 12 GB eingestellt (2 Dateien zugewiesen), was 1,5 meines RAM entspricht.
Jake

Antworten:


5

Die absolut robusteste Lösung für dieses Problem wäre die Verwendung von Docker-Containern. Sie können angeben, wie viel Speicher Jupyter zugewiesen werden soll. Wenn der Container nicht mehr über genügend Speicher verfügt, ist dies einfach keine große Sache (denken Sie daran, häufig zu speichern, aber das versteht sich von selbst).

Dieser Blog bringt Sie den größten Teil des Weges dorthin. Es gibt auch einige anständige Anweisungen zum Einrichten von Jupyter Lab von einem der frei verfügbaren, offiziell gepflegten Jupyter-Bilder hier:

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

Anschließend können Sie den docker runBefehl wie im Lernprogramm beschrieben ändern (z. B. für 3 GB):

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

Informationen zur Syntax der Docker-Speicheroptionen finden Sie in dieser Frage:

Welche Einheit erwartet der Docker mit der Option "--memory"?


4

Wenn Sie Ubuntu verwenden, schauen Sie sich OOM-Killer an. Informationen erhalten Sie hier

Sie können Earlyoom verwenden . Es kann nach Ihren Wünschen konfiguriert werden, z. B. earlyoom -s 90 -m 15wird das gestartet earlyoomund wenn die Swap-Größe weniger als% 90 und der Speicher weniger als% 15 beträgt, wird der Prozess, der OOM verursacht, abgebrochen und das Einfrieren des gesamten Systems verhindert. Sie können auch die Priorität der Prozesse konfigurieren.


2

Ich arbeite auch mit sehr großen Datenmengen (3 GB) in Jupyter Lab und habe das gleiche Problem in Labs festgestellt. Es ist unklar, ob Sie den Zugriff auf die delvortransformierten Daten beibehalten müssen. Wenn nicht, habe ich begonnen, nicht verwendete große Datenrahmenvariablen zu verwenden, wenn ich sie nicht benötige. delEntfernt Variablen aus Ihrem Speicher. Bearbeiten **: Es gibt mehrere Möglichkeiten für das Problem, auf das ich stoße. Ich stoße häufiger darauf, wenn ich eine Remote-Jupyter-Instanz verwende, und auch auf Spyder, wenn ich große Transformationen durchführe.

z.B

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

Jakes, Sie finden diesen Thread möglicherweise auch in Workflows mit großen Datenmengen hilfreich. Ich habe Dask untersucht , um bei der Speicherung zu helfen.

Ich habe bei Spyder und Jupyter festgestellt, dass das Einfrieren normalerweise auftritt, wenn in einer anderen Konsole gearbeitet wird, während eine große Speicherkonsole ausgeführt wird. Ich denke, dass dies etwas mit dem Kernel zu tun hat, warum es nur einfriert, anstatt auszufallen. Im IPython-Github sind einige Speicherprobleme offen - # 10082 und # 10117 scheinen am relevantesten zu sein. Ein Benutzer hier schlägt vor, die Tab-Vervollständigung in jedijedi zu deaktivieren oder zu aktualisieren.

10117 schlagen sie vor, die Ausgabe von zu überprüfen get_ipython().history_manager.db_log_output. Ich habe die gleichen Probleme und meine Einstellung ist korrekt, aber es lohnt sich zu überprüfen


1

Sie können auch Notebooks in der Cloud nutzen auch, wie Google Colab hier . Sie bieten die Möglichkeit für empfohlene RAMs und die Unterstützung für Jupyter-Notebooks ist standardmäßig.


0

Ich denke, Sie sollten Brocken verwenden. So wie das:

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)

Weitere Informationen finden Sie unter: https://towardsdatascience.com/why-and-how-to-use-pandas-with-large-data-9594dda2ea4c

Ich schlage vor, keine Liste mehr anzuhängen (wahrscheinlich wird der RAM wieder überlastet). Sie sollten Ihren Job in dieser for-Schleife beenden.


Ich denke, das Problem hier ist nicht, wie man nicht über genügend Speicher verfügt, sondern wie man verhindert, dass der Computer abstürzt und neu gestartet werden muss. Python sollte abstürzen oder einen Memoryerror auslösen, aber nicht alles durcheinander bringen.
Bzazz

0

Ich werde die Antworten aus der folgenden Frage zusammenfassen . Sie können die Speichernutzung Ihres Programms einschränken. Im Folgenden wird dies die Funktion sein ram_intense_foo(). Bevor Sie dies aufrufen, müssen Sie die Funktion aufrufenlimit_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

Es gibt keinen Grund, die gesamte Ausgabe eines großen Datenrahmens anzuzeigen. Das Anzeigen oder Bearbeiten großer Datenrahmen beansprucht unnötig große Mengen Ihrer Computerressourcen.

Was auch immer Sie tun, können Sie in Miniatur tun. Es ist viel einfacher, Daten zu codieren und zu bearbeiten, wenn der Datenrahmen klein ist. Der beste Weg, um mit Big Data zu arbeiten, besteht darin, einen neuen Datenrahmen zu erstellen, der nur einen kleinen Teil oder eine kleine Stichprobe des großen Datenrahmens enthält. Dann können Sie die Daten untersuchen und Ihre Codierung auf dem kleineren Datenrahmen durchführen. Wenn Sie die Daten untersucht und Ihren Code zum Laufen gebracht haben, verwenden Sie diesen Code einfach für den größeren Datenrahmen.

Am einfachsten ist es, mit der Funktion head () das erste n, die Nummer der ersten Zeilen, aus dem Datenrahmen zu nehmen. Die Kopffunktion gibt nur n Zeilen aus. Sie können einen Mini-Datenrahmen erstellen, indem Sie die Kopffunktion für den großen Datenrahmen verwenden. Unten habe ich die ersten 50 Zeilen ausgewählt und ihren Wert an small_df übergeben. Dies setzt voraus, dass BigData eine Datendatei ist, die aus einer Bibliothek stammt, die Sie für dieses Projekt geöffnet haben.

library(namedPackage) 

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

Dies funktioniert die meiste Zeit, aber manchmal enthält der Big-Data-Frame vorsortierte Variablen oder bereits gruppierte Variablen. Wenn die Big Data so sind, müssten Sie eine zufällige Stichprobe der Zeilen aus den Big Data ziehen. Verwenden Sie dann den folgenden Code:

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.