쿠버네티스(kubernetes) 위에서 Jupyter를 사용하고 있다. Jupyter Notebook 에서 텐서플로-케라스를 사용하고 있고, GPU 4개를 할당하였다. 주피터에서 노트북을 1개 더 생성해서 작업 할 경우 OOM 에러가 발생하였다.
ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[3,3,128,128] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc [[node conv2d_3/kernel/Initializer/random_uniform/RandomUniform (defined at <ipython-input-2-355421ac90ac>:1) ]] Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.
양쪽 노트북에서 모드 GPU:0을 사용해서 생긴 문제인거 같다. 첫번째 노트북에서 GPU:0의 메모리를 거의 풀로 사용해버린 상태에서, 두번째 노트북에서 GPU:0을 사용하려니 메모리가 부족한 상태가 발생한것이다
서버에서 nvidia-smi
을 실행해보면, 프로세스는 생성되었지만, 할당된 메모리가 작다는것을 알 수 있다.
Every 2.0s: nvidia-smi Thu Aug 8 10:09:46 2019 Thu Aug 8 08:09:46 2019 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 418.67 Driver Version: 418.67 CUDA Version: 10.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 Tesla M40 Off | 00000000:02:00.0 Off | 0 | | N/A 35C P0 63W / 250W | 11302MiB / 11448MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 1 Tesla M40 Off | 00000000:82:00.0 Off | 0 | | N/A 37C P0 62W / 250W | 212MiB / 11448MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 2 Tesla M40 Off | 00000000:85:00.0 Off | 0 | | N/A 35C P0 62W / 250W | 212MiB / 11448MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 3 Tesla M40 Off | 00000000:86:00.0 Off | 0 | | N/A 37C P0 62W / 250W | 212MiB / 11448MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 81475 C /opt/conda/bin/python 11060MiB | | 0 93847 C /opt/conda/bin/python 229MiB | | 1 81475 C /opt/conda/bin/python 99MiB | | 1 93847 C /opt/conda/bin/python 99MiB | | 2 81475 C /opt/conda/bin/python 99MiB | | 2 93847 C /opt/conda/bin/python 99MiB | | 3 81475 C /opt/conda/bin/python 99MiB | | 3 93847 C /opt/conda/bin/python 99MiB | +-----------------------------------------------------------------------------+
알아서 노는 GPU를 사용하면 좋으련만… 어쩔수 없이 GPU 디바이스를 직접 지정하여서 사용핬다.
디바이스 목록 보기
from tensorflow.python.client import device_lib print(device_lib.list_local_devices())
특정 디바이스를 지정해서 모델 처리하기
텐서플로우에서는 tf.device('/gpu:0')
구문으로 특정 GPU 디바이스를 지정해서 모델을 처리할 수 있다.
import tensorflow as tf with tf.device('/gpu:0'): model = keras.models.Sequential() model.add(keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) model.add(keras.layers.MaxPool2D((2, 2))) model.add(keras.layers.Conv2D(64, (3, 3), activation='relu')) model.add(keras.layers.MaxPool2D((2, 2))) model.add(keras.layers.Conv2D(128, (3, 3), activation='relu')) model.add(keras.layers.MaxPool2D((2, 2))) model.add(keras.layers.Conv2D(128, (3, 3), activation='relu')) model.add(keras.layers.MaxPool2D((2, 2))) model.add(keras.layers.Flatten()) model.add(keras.layers.Dense(512, activation='relu')) model.add(keras.layers.Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer=keras.optimizers.RMSprop(lr=1e-4), metrics=['acc']) train_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1./255) validation_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory(train_dir, target_size=(150, 150), batch_size=20, class_mode='binary') validation_generator = validation_datagen.flow_from_directory(validation_dir, target_size=(150, 150), batch_size=20, class_mode='binary') history = model.fit_generator(train_generator, steps_per_epoch=100, epochs=30, validation_data=validation_generator, validation_steps=50)
기타 : 멀티 GPU 사용하기
keras.utils
을 사용하면, 모델을 처리할 때 GPU를 사용할 수 있게 지정할 수 있다.
model = ... model = keras.utils.multi_gpu_model(model, gpus=4) model.compile(loss='binary_crossentropy', optimizer=keras.optimizers.RMSprop(lr=1e-4), metrics=['acc']) ...