Keras GPU 사용하기
쿠버네티스(kubernetes) 위에서 GPU 4개를 할당한 Jupyter를 사용하고 있다. Jupyter Notebook 에서 텐서플로-케라스를 사용하고 있는데, 노트북을 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())
특정 디바이스를 사용해서 모델 처리하기
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 사용하기
model = ...
model = keras.utils.multi_gpu_model(model, gpus=4)
model.compile(loss='binary_crossentropy', optimizer=keras.optimizers.RMSprop(lr=1e-4), metrics=['acc'])
...