【问题标题】:Jupyter Lab freezes the computer when out of RAM - how to prevent it?Jupyter Lab 在内存不足时冻结计算机 - 如何防止它?
【发布时间】:2020-02-12 11:23:57
【问题描述】:

我最近开始使用 Jupyter Lab,我的问题是我使用的数据集非常大(通常数据集本身大约是我计算机 RAM 的 1/4)。经过几次转换,保存为新的 Python 对象后,我往往会耗尽内存。问题是,当我接近可用 RAM 限制并执行任何需要另一个 RAM 空间的操作时,我的计算机会冻结,修复它的唯一方法是重新启动它。这是 Jupyter Lab/Notebook 中的默认行为还是我应该设置的一些设置?通常,我希望程序崩溃(例如在 RStudio 中),而不是整个计算机

【问题讨论】:

  • 我之前也遇到过同样的问题,真的很讨厌。我快速查看了 jupyter 问题,但一无所获。如果您通过 IPython(不是纯 Python)控制台运行,是否也会发生这种情况?
  • 你使用了什么包/模块?它是什么操作系统?你有交换吗?什么版本的 Jupyter Lab?如果是Linux内核版本是什么?
  • 主要是 Pandas,但我认为它与包无关。操作系统是 Ubuntu 16.04.6 LTS,内核版本是 4.15.0-65-generic。 Jupyter Lab 版本是 1.0.2。我将 SWAP 设置为 12 GB(分配给 2 个文件),这是我的 RAM 的 1.5。

标签: python jupyter-notebook jupyter-lab


【解决方案1】:

我还在 Jupyter Lab 上处理非常大的数据集 (3GB),并且在 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.

Jakes,您可能还会发现这个thread on large data workflows 很有帮助。我一直在寻找 Dask 来帮助存储内存。

我在 spyder 和 jupyter 中注意到,在运行大内存控制台时,通常会在另一个控制台中工作时发生冻结。至于为什么它只是冻结而不是崩溃,我认为这与内核有关。有几个记忆issues open in the IPython github - #10082 和 #10117 似乎最相关。一位用户here 建议在jedi 中禁用选项卡完成或更新绝地。

在 10117 中,他们建议检查 get_ipython().history_manager.db_log_output 的输出。我有同样的问题,我的设置是正确的,但值得检查

【讨论】:

    【解决方案2】:

    没有理由查看大型数据帧的整个输出。查看或操作大型数据框将不必要地使用大量计算机资源。

    无论您在做什么,都可以在微缩版中完成。当数据框较小时,编码和操作数据要容易得多。处理大数据的最佳方法是创建一个新的数据框,该数据框只占用大数据框的一小部分或小样本。然后您可以探索数据并在较小的数据帧上进行编码。一旦您探索了数据并让您的代码正常工作,那么只需在更大的数据框上使用该代码即可。

    最简单的方法是使用 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
    

    【讨论】:

      【解决方案3】:

      我认为你应该使用块。像这样:

      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 应该崩溃或抛出内存错误,但不要把一切都搞砸。
      【解决方案4】:

      对于这个问题,最可靠的解决方案绝对是使用 Docker 容器。您可以指定分配给 Jupyter 的内存量,如果容器内存不足,这没什么大不了的(记住要经常保存,但这不用说)。

      This blog 将帮助您顺利到达目的地。还有一些不错的说明,可以从此处免费提供、官方维护的 Jupyter 图像之一设置 Jupyter Lab:

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

      然后您可以按照教程中的说明修改docker run 命令(例如对于 3GB):

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

      有关 docker 内存选项的语法,请参阅以下问题:

      What unit does the docker run "--memory" option expect?

      【讨论】:

        【解决方案5】:

        如果您使用的是基于 Linux 的操作系统,请查看 OOM 杀手,您可以从 here 获取信息。我不知道 Windows 的详细信息。

        您可以使用earlyoom。它可以根据需要进行配置,例如earlyoom -s 90 -m 15 将启动earlyoom,当交换大小小于 %90 且内存小于 %15 时,它将杀死导致 OOM 的进程并防止整个系统冻结。您还可以配置进程的优先级。

        【讨论】:

          【解决方案6】:

          我将总结以下question的答案。 您可以限制程序的内存使用量。在下面这将是函数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)
          

          【讨论】:

            【解决方案7】:

            您还可以在云中使用笔记本,例如 Google Colab here。他们为推荐的 RAM 提供了便利,并且默认支持 Jupyter notebook。

            【讨论】:

              猜你喜欢
              • 2011-01-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-08-16
              • 2018-12-13
              • 2017-11-09
              • 2020-07-20
              • 1970-01-01
              相关资源
              最近更新 更多