Computer Science/DL, ML

TensorFlow, Keras GPU 메모리 문제(Out of Memory) 발생 시 시도해볼 방법

TwinParadox 2020. 8. 13. 12:16
728x90

빅데이터 처리나 딥러닝을 하다보면 자연스럽게 마주하는 문제가 바로 메모리 문제다. 빅데이터 처리 같은 경우 그냥 파이썬에서 Numpy나 Dataframe을 사용하는 과정에서 발생하는 일이 흔하고, 그때마다 gc를 호출하거나, 처리하는 데이터의 양을 분할하는 방법, 변수 타입 변경 등 다양한 방법이 있어서 해결하기 쉬운데, 딥러닝은 그게 쉽지가 않다. 그래도 시도해볼 방법은 있다.

 

주로 메모리 에러를 마주할 때 보게 되는 메세지는 아래 부류들이다.

 

OOM(Out of Memory)Resource exhausted: OOM when allocating tensor with shape

 

Failed to get convolution algorithm. This is probably because cuDNN failed to initialize, so try looking to see if a warning log message was printed above.

 

 

GPU를 추가적으로 늘릴 수 있다면, 크게 개의치 않는 오류일 수 있으나 대부분은 그렇지 못하기 때문에 이 문제를 해결해야 한다. 아래 내용에서 제시하는 시도해볼만한 해결책(이라고 쓰지만 우회)을 시도해보고 다른 방법을 찾아보도록 하자.

 

 

다른 프로세스의 GPU 점유

우리의 생각보다 GPU가 활용되는 프로세스는 생각보다 많다. 스트리밍 서비스, 게임 등... 특히 Nox 같은 가상화 프로그램들은 아예 컴퓨터의 자원을 고정 할당하므로, 딥러닝 작업 시에는 종료해야 한다. Windows에서는 작업 관리자에서 GPU 메모리가 점유되어 있는지 확인할 수 있고, 어떤 프로세스가 GPU를 사용하는지도 확인할 수 있기 때문에 쉽게 파악할 수 있다.

 

 

Batch Size

여러 이유(대부분 학습 속도)로 Batch Size를 늘리게 되는데, 이러면 학습 시 데이터의 양 때문에 문제가 발생할 수 있다. Feature가 많지 않은 Raw Data에서는 보기 힘든 문제지만, Image로 넘어가는 그 순간 가장 먼저 확인해야 할 것이 바로 Batch Size다. 메모리 문제가 발생한다면 불가피하게 2의 제곱수로 적당한 선에서 그 크기를 줄여주도록 하자.

 

 

메모리 할당 방식 변경

기본적으로 TensorFlow와 그걸 백엔드로 사용하는 Keras는 메모리 파편화를 방지하기 위해서 GPU 메모리를 최대한 매핑한다. 그러다 보니까, 메모리가 필요 이상으로 잡혀 있어서, 정작 필요한 곳에서는 할당을 못해줘서 두 번째 에러 메세지를 나타내는 메모리 초과 문제가 발생할 수 있다.

 

이럴 때는 런타임에 메모리를 할당하게 해서 문제를 해결할 수 있다.

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
    try:
    # Currently, memory growth needs to be the same across GPUs
    for gpu in gpus:
        tf.config.experimental.set_memory_growth(gpu, True)
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
    except RuntimeError as e:
    # Memory growth must be set before GPUs have been initialized
        print(e)        

 

아니면, 아예 처음부터 매핑하는 건 허락하되, 매핑되는 메모리 크기를 제한할 수도 있다.

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # 텐서플로가 첫 번째 GPU에 1GB 메모리만 할당하도록 제한
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
  except RuntimeError as e:
    # 프로그램 시작시에 가상 장치가 설정되어야만 합니다
    print(e)

 

 

[Reference]

https://www.tensorflow.org/guide/gpu

https://stackoverflow.com/questions/43147983/could-not-create-cudnn-handle-cudnn-status-internal-error

https://stackoverflow.com/questions/53698035/failed-to-get-convolution-algorithm-this-is-probably-because-cudnn-failed-to-in

728x90