Jupyter LabはRAMが足りなくなったときにコンピューターをフリーズさせます-それを防ぐ方法は?


12

私は最近Jupyter Labの使用を開始しましたが、私の問題は、非常に大きなデータセットを操作することです(通常、データセット自体は私のコンピューターのRAMの約1/4です)。いくつかの変換の後、新しいPythonオブジェクトとして保存すると、メモリ不足になる傾向があります。問題は、使用可能なRAM制限に近づいて、別のRAMスペースを必要とする操作を実行すると、コンピューターがフリーズし、それを修正する唯一の方法は再起動することです。これはJupyter Lab / Notebookのデフォルトの動作ですか、それとも設定すべき設定ですか?通常、コンピュータ全体ではなく、プログラムがクラッシュすることを期待します(RStudioなど)。


以前にも同じ問題がありましたが、それは本当に厄介です。私はjupyterの問題をざっと見ても何も見つかりませんでした。IPython(単純なpythonではない)コンソールを実行した場合にも発生しますか?
Bzazz

どのパッケージ/モジュールを使用しましたか?それはどんなOSですか?スワップはありましたか?Jupyter Labのどのバージョンですか?Linuxの場合、カーネルのバージョンは何ですか?
Nizam Mohamed

主にパンダですが、パッケージ関連ではないと思います。OSはUbuntu 16.04.6 LTSで、カーネルバージョンは4.15.0-65-genericです。Jupyter Labのバージョンは1.0.2です。私は、RAMの1.5である12 GB(2つのファイルに割り当て)に設定されたSWAPを持っています。
ジョーク

回答:


5

この問題を解決する最も確実な方法は、Dockerコンテナーを使用することです。Jupyterに割り当てるメモリの量を指定できます。コンテナでメモリが不足しても、それほど大きな問題ではありません(頻繁に保存することを忘れないでくださいが、言うまでもありません)。

このブログでは、ほとんどの方法を紹介します。また、無料で入手でき、公式に管理されているJupyterイメージの1つからJupyter Labを設定するための適切な指示もあります。

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

次にdocker run、チュートリアルで説明されているようにコマンドを変更できます(例:3GBの場合):

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

Dockerメモリオプションの構文については、次の質問を参照してください。

docker runの「--memory」オプションはどのユニットを想定していますか?


4

Ubuntuを使用している場合は、OOMキラーを確認してください。ここから情報を入手できます。

Earlyoomを使用できます。これは、必要に応じて構成できます。たとえば、earlyoom -s 90 -m 15が起動しearlyoom、スワップサイズが%90未満でメモリが%15未満の場合、OOMの原因となるプロセスが強制終了され、システム全体のフリーズが防止されます。プロセスの優先順位を設定することもできます。


2

また、Jupyter Labで非常に大規模なデータセット(3GB)を使用していて、Labsでも同じ問題が発生しています。事前変換されたデータへのアクセスを維持する必要があるかどうかは不明ですが、必要がない場合は、del未使用の大きなデータフレーム変数を必要としない場合に使用し始めました。del変数をメモリから削除します。編集**:私が直面している問題には複数の可能性があります。これは、リモートのjupyterインスタンスを使用している場合や、スパイダーで発生することが多く、大きな変換を実行している場合にも発生します。

例えば

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

大規模なデータワークフローでこのスレッドが役立つ場合もあります。私はDaskを調べてメモリストレージを支援しています。

スパイダーとジュピターで、大容量メモリコンソールの実行中に別のコンソールで作業するとフリーズアップが通常発生することに気付きました。クラッシュするのではなくフリーズする理由については、これはカーネルと関係があると思います。IPython githubにはいくつかのメモリの問題が残っています-#10082と#10117が最も関連性があるようです。ここの 1人のユーザーはjedi、jedi でタブ補完を無効にするか、jediを更新することを提案しています。

10117年に、彼らはの出力をチェックすることを提案していますget_ipython().history_manager.db_log_output。同じ問題があり、設定は正しいですが、確認する価値があります



0

チャンクを使うべきだと思います。そのように:

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をご覧ください。

リストを再度追加しないことをお勧めします(おそらくRAMが再び過負荷になるでしょう)。そのforループでジョブを完了する必要があります。


ここでの問題は、メモリが不足しないようにする方法ではなく、コンピュータがクラッシュして再起動が必要になるのを回避する方法だと思います。Pythonはクラッシュするか、メモリエラーをスローしますが、すべてを台無しにするわけではありません。
Bzazz

0

次の質問の回答をまとめます。プログラムのメモリ使用量を制限できます。以下では、これが関数になります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)

-4

大きなデータフレームの出力全体を表示する理由はありません。大きなデータフレームを表示または操作すると、大量のコンピュータリソースが不必要に使用されます。

あなたがしていることは何でもミニチュアで行うことができます。データフレームが小さい場合、データのコーディングと操作ははるかに簡単です。ビッグデータを扱う最良の方法は、大きなデータフレームの小さな部分または小さなサンプルのみを使用する新しいデータフレームを作成することです。次に、データを探索し、より小さなデータフレームでコーディングを行うことができます。データを調べてコードを機能させることができたら、そのコードをより大きなデータフレームで使用します。

最も簡単な方法は、head()関数を使用して、データフレームから最初のnの最初の行の数を取得することです。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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.