【问题标题】:CUDA_ERROR_OUT_OF_MEMORY in tensorflow张量流中的CUDA_ERROR_OUT_OF_MEMORY
【发布时间】:2017-01-20 18:54:33
【问题描述】:

当我开始训练一些神经网络时,它遇到了CUDA_ERROR_OUT_OF_MEMORY,但训练可以继续进行而不会出错。因为我想使用真正需要的gpu内存,所以我设置了gpu_options.allow_growth = True。日志如下:

I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcurand.so locally
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:925] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_device.cc:951] Found device 0 with properties:
name: GeForce GTX 1080
major: 6 minor: 1 memoryClockRate (GHz) 1.7335
pciBusID 0000:01:00.0
Total memory: 7.92GiB
Free memory: 7.81GiB
I tensorflow/core/common_runtime/gpu/gpu_device.cc:972] DMA: 0
I tensorflow/core/common_runtime/gpu/gpu_device.cc:982] 0:   Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:1041] Creating TensorFlow device (/gpu:0) -> (device:0, name: GeForce GTX 1080, pci bus id: 0000:01:00.0)
E tensorflow/stream_executor/cuda/cuda_driver.cc:965] failed to allocate 4.00G (4294967296 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY
Iter 20, Minibatch Loss= 40491.636719
...

使用nvidia-smi 命令后,得到:

+-----------------------------------------------------------------------------+   
| NVIDIA-SMI 367.27                 Driver Version: 367.27                            
|-------------------------------+----------------------+----------------------+   
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |  
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M.
|===============================+======================+======================|
|   0  GeForce GTX 1080    Off  | 0000:01:00.0     Off |                  N/A |   
| 40%   61C    P2    46W / 180W |   8107MiB /  8111MiB |     96%      Default |   
+-------------------------------+----------------------+----------------------+   
|   1  GeForce GTX 1080    Off  | 0000:02:00.0     Off |                  N/A |   
|  0%   40C    P0    40W / 180W |      0MiB /  8113MiB |      0%      Default |   
+-------------------------------+----------------------+----------------------+   
                                                                              │
+-----------------------------------------------------------------------------+   
| Processes:                                                       GPU Memory |   
|  GPU       PID  Type  Process name                               Usage      |   
|=============================================================================|   
|    0     22932    C   python                                        8105MiB |
+-----------------------------------------------------------------------------+ 

在我评论gpu_options.allow_growth = True后,我再次训练了网络,一切正常。没有CUDA_ERROR_OUT_OF_MEMORY的问题。最后,运行nvidia-smi 命令,得到:

+-----------------------------------------------------------------------------+   
| NVIDIA-SMI 367.27                 Driver Version: 367.27                            
|-------------------------------+----------------------+----------------------+   
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |  
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M.
|===============================+======================+======================|
|   0  GeForce GTX 1080    Off  | 0000:01:00.0     Off |                  N/A |   
| 40%   61C    P2    46W / 180W |   7793MiB /  8111MiB |     99%      Default |   
+-------------------------------+----------------------+----------------------+   
|   1  GeForce GTX 1080    Off  | 0000:02:00.0     Off |                  N/A |   
|  0%   40C    P0    40W / 180W |      0MiB /  8113MiB |      0%      Default |   
+-------------------------------+----------------------+----------------------+   
                                                                              │
+-----------------------------------------------------------------------------+   
| Processes:                                                       GPU Memory |   
|  GPU       PID  Type  Process name                               Usage      |   
|=============================================================================|   
|    0     22932    C   python                                        7791MiB |
+-----------------------------------------------------------------------------+ 

我有两个问题。为什么CUDA_OUT_OF_MEMORY出来了,程序正常进行了?为什么评论allow_growth = True后内存占用变小了。

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    如果它仍然与某人相关,我在第一次运行中止后尝试第二次运行 Keras/Tensorflow 时遇到了这个问题。似乎 GPU 内存仍在分配,因此无法再次分配。解决方法是手动结束所有使用 GPU 的 python 进程,或者关闭现有终端并在新的终端窗口中再次运行。

    【讨论】:

      【解决方案2】:

      默认情况下,tensorflow 会尝试将一部分 GPU 内存per_process_gpu_memory_fraction 分配给他的进程,以避免昂贵的内存管理。 (见GPUOptionscmets)。
      这可能会失败并引发CUDA_OUT_OF_MEMORY 警告。 我不知道这种情况下的回退是什么(使用 CPU 操作或 allow_growth=True)。
      如果此时其他进程使用 GPU,则可能会发生这种情况(例如,如果您启动两个运行 tensorflow 的进程)。 默认行为占用约 95% 的内存(请参阅此 answer)。

      当您使用allow_growth = True 时,GPU 内存不会预先分配,并且能够根据您的需要增长。这将导致更小的内存使用(因为默认选项是使用整个内存)但如果使用不当会降低性能,因为它需要更复杂的内存处理(这不是 CPU/GPU 交互中最有效的部分)。

      【讨论】:

      • 我只启动一个进程。在我评论了allow_growth = True之后,由于默认选项,tensorflow应该使用整个内存,但实际上它只使用了7793M内存,当我使用allow_growth = True时它甚至不大于8107M(这就是我感到困惑的地方)。这种训练可以继续表明网络实际上不需要那么多内存。
      • 默认情况下,tensorflow 仅将 95% 的 gpu 内存视为整个内存,因此 7793MB 似乎是正确的(请参阅额外链接)。 allow_growth 中更多内存的使用应该与您的网络大小有关(我还没有找到任何关于它的来源......)。例如,如果您在 GPU 上分配两个 4GB 变量,它将适合 allow_growth (~8GB) 但不适用于预分配的内存,因此会引发 CUDA_ERROR_OUT_OF_MEMORY 警告
      • 设置 allow_growth=Trueper_process_gpu_memory_fraction=0.5 后,我仍然在 Windows10 GPU RTX 2080 机器上遇到这个错误。这个问题通过将图像大小调整一半来解决。
      【解决方案3】:

      我在尝试背靠背训练模型时遇到了这个问题。我认为由于之前的训练运行,GPU 内存不可用。所以我发现最简单的方法是在每次下一次训练之前手动刷新 GPU 内存。

      使用 nvidia-smi 检查 GPU 内存使用情况:

      nvidia-smi
      
      nvidia-smi --gpu-reset
      

      如果其他进程正在积极使用 GPU,上述命令可能不起作用。

      或者,您可以使用以下命令列出所有正在使用 GPU 的进程:

      sudo fuser -v /dev/nvidia*
      

      输出应该是这样的:

      USER        PID ACCESS COMMAND
      /dev/nvidia0:        root       2216 F...m Xorg
                           sid        6114 F...m krunner
                           sid        6116 F...m plasmashell
                           sid        7227 F...m akonadi_archive
                           sid        7239 F...m akonadi_mailfil
                           sid        7249 F...m akonadi_sendlat
                           sid       18120 F...m chrome
                           sid       18163 F...m chrome
                           sid       24154 F...m code
      /dev/nvidiactl:      root       2216 F...m Xorg
                           sid        6114 F...m krunner
                           sid        6116 F...m plasmashell
                           sid        7227 F...m akonadi_archive
                           sid        7239 F...m akonadi_mailfil
                           sid        7249 F...m akonadi_sendlat
                           sid       18120 F...m chrome
                           sid       18163 F...m chrome
                           sid       24154 F...m code
      /dev/nvidia-modeset: root       2216 F.... Xorg
                           sid        6114 F.... krunner
                           sid        6116 F.... plasmashell
                           sid        7227 F.... akonadi_archive
                           sid        7239 F.... akonadi_mailfil
                           sid        7249 F.... akonadi_sendlat
                           sid       18120 F.... chrome
                           sid       18163 F.... chrome
                           sid       24154 F.... code
      

      从这里,我得到了持有 GPU 内存的进程的 PID,在我的例子中是 24154。

      使用以下命令按进程的 PID 杀死进程:

      sudo kill -9 MY_PID
      

      将 MY_PID 替换为相关的 PID。

      【讨论】:

        【解决方案4】:

        Tensorflow 2.0 alpha

        问题在于,Tensorflow 在分配所有可用 VRAM 时是贪婪的。这会给某些人带来问题。

        对于 Tensorflow 2.0 alpha / 每晚使用这个:

        import tensorflow as tf
        tf.config.gpu.set_per_process_memory_fraction(0.4)
        

        来源:https://www.tensorflow.org/alpha/guide/using_gpu

        【讨论】:

        • 我的代码似乎无法识别配置中的 gpu 对象,我认为实际的实现类似于 tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)
        【解决方案5】:

        我在 Ubuntu 18.10 中遇到内存错误。 当我将显示器的分辨率从 4k 更改为全高清(1920-1080)时,可用内存变为 438mb,神经网络训练开始了。 我对这种行为感到非常惊讶。

        顺便说一句,我有 Nvidia 1080 和 8gb 内存,仍然不知道为什么只有 400mb 可用

        【讨论】:

        • 您可以使用 nvtop 或 nvidia-smi 查看哪些进程正在使用 VRAM
        • TF 预先分配内存,这本身并不是一件坏事。因此 GPU 内存已满并不表示 TF 没有剩余内存。您需要知道还有多少 TF 内部内存可用。
        【解决方案6】:

        环境:
        1.CUDA 10.0
        2.cuNDD 10.0 3.tensorflow 1.14.0
        4.pip安装opencv-contrib-python
        5.git克隆https://github.com/thtrieu/darkflow
        6.允许GPU内存增长

        Reference

        【讨论】:

          猜你喜欢
          • 2019-07-08
          • 1970-01-01
          • 2018-12-13
          • 1970-01-01
          • 1970-01-01
          • 2017-11-05
          • 2018-04-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多