tiene test tarjeta sistema saber para online memoria laptop grafica diagnosticar dedicada compartida como aumentar memory tensorflow keras theano

memory - test - Keras usa demasiada memoria GPU cuando llama a train_on_batch, fit, etc.



test para tarjeta de video (3)

He estado jugando con Keras, y me gusta hasta ahora. Hay un gran problema que he tenido al trabajar con redes bastante profundas: cuando se llama a model.train_on_batch, o model.fit, etc., Keras asigna significativamente más memoria GPU de la que el modelo en sí mismo debería necesitar. Esto no es causado por tratar de entrenar en algunas imágenes realmente grandes, sino que es el modelo de red en sí el que parece requerir una gran cantidad de memoria GPU. He creado este ejemplo de juguete para mostrar lo que quiero decir. Esto es esencialmente lo que está pasando:

Primero creo una red bastante profunda y uso model.summary () para obtener la cantidad total de parámetros necesarios para la red (en este caso 206538153, que corresponde a unos 826 MB). Luego uso nvidia-smi para ver cuánta memoria GPU ha asignado Keras, y puedo ver que tiene perfecto sentido (849 MB).

Luego compilo la red y puedo confirmar que esto no aumenta el uso de la memoria de la GPU. Y como podemos ver en este caso, tengo casi 1 GB de VRAM disponible en este momento.

Luego intento alimentar una imagen simple de 16x16 y una verdad de 1x1 en la red, y luego todo explota, porque Keras comienza a asignar mucha memoria nuevamente, sin ninguna razón que sea obvia para mí. Algo sobre el entrenamiento de la red parece requerir mucha más memoria que simplemente tener el modelo, lo cual no tiene sentido para mí. He entrenado redes significativamente más profundas en esta GPU en otros marcos, por lo que me hace pensar que estoy usando mal Keras (o hay algo mal en mi configuración, o en Keras, pero por supuesto que es difícil de saber con certeza).

Aquí está el código:

from scipy import misc import numpy as np from keras.models import Sequential from keras.layers import Dense, Activation, Convolution2D, MaxPooling2D, Reshape, Flatten, ZeroPadding2D, Dropout import os model = Sequential() model.add(Convolution2D(256, 3, 3, border_mode=''same'', input_shape=(16,16,1))) model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2))) model.add(Convolution2D(512, 3, 3, border_mode=''same'')) model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2))) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(Convolution2D(1024, 3, 3, border_mode=''same'')) model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2))) model.add(Convolution2D(256, 3, 3, border_mode=''same'')) model.add(Convolution2D(32, 3, 3, border_mode=''same'')) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dense(4)) model.add(Dense(1)) model.summary() os.system("nvidia-smi") raw_input("Press Enter to continue...") model.compile(optimizer=''sgd'', loss=''mse'', metrics=[''accuracy'']) os.system("nvidia-smi") raw_input("Compiled model. Press Enter to continue...") n_batches = 1 batch_size = 1 for ibatch in range(n_batches): x = np.random.rand(batch_size, 16,16,1) y = np.random.rand(batch_size, 1) os.system("nvidia-smi") raw_input("About to train one iteration. Press Enter to continue...") model.train_on_batch(x, y) print("Trained one iteration")

Lo cual me da la siguiente salida:

Using Theano backend. Using gpu device 0: GeForce GTX 960 (CNMeM is disabled, cuDNN 5103) /usr/local/lib/python2.7/dist-packages/theano/sandbox/cuda/__init__.py:600: UserWarning: Your cuDNN version is more recent than the one Theano officially supports. If you see any problems, try updating Theano or downgrading cuDNN to version 5. warnings.warn(warn) ____________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ==================================================================================================== convolution2d_1 (Convolution2D) (None, 16, 16, 256) 2560 convolution2d_input_1[0][0] ____________________________________________________________________________________________________ maxpooling2d_1 (MaxPooling2D) (None, 8, 8, 256) 0 convolution2d_1[0][0] ____________________________________________________________________________________________________ convolution2d_2 (Convolution2D) (None, 8, 8, 512) 1180160 maxpooling2d_1[0][0] ____________________________________________________________________________________________________ maxpooling2d_2 (MaxPooling2D) (None, 4, 4, 512) 0 convolution2d_2[0][0] ____________________________________________________________________________________________________ convolution2d_3 (Convolution2D) (None, 4, 4, 1024) 4719616 maxpooling2d_2[0][0] ____________________________________________________________________________________________________ convolution2d_4 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_3[0][0] ____________________________________________________________________________________________________ convolution2d_5 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_4[0][0] ____________________________________________________________________________________________________ convolution2d_6 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_5[0][0] ____________________________________________________________________________________________________ convolution2d_7 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_6[0][0] ____________________________________________________________________________________________________ convolution2d_8 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_7[0][0] ____________________________________________________________________________________________________ convolution2d_9 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_8[0][0] ____________________________________________________________________________________________________ convolution2d_10 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_9[0][0] ____________________________________________________________________________________________________ convolution2d_11 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_10[0][0] ____________________________________________________________________________________________________ convolution2d_12 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_11[0][0] ____________________________________________________________________________________________________ convolution2d_13 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_12[0][0] ____________________________________________________________________________________________________ convolution2d_14 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_13[0][0] ____________________________________________________________________________________________________ convolution2d_15 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_14[0][0] ____________________________________________________________________________________________________ convolution2d_16 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_15[0][0] ____________________________________________________________________________________________________ convolution2d_17 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_16[0][0] ____________________________________________________________________________________________________ convolution2d_18 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_17[0][0] ____________________________________________________________________________________________________ convolution2d_19 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_18[0][0] ____________________________________________________________________________________________________ convolution2d_20 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_19[0][0] ____________________________________________________________________________________________________ convolution2d_21 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_20[0][0] ____________________________________________________________________________________________________ convolution2d_22 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_21[0][0] ____________________________________________________________________________________________________ convolution2d_23 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_22[0][0] ____________________________________________________________________________________________________ convolution2d_24 (Convolution2D) (None, 4, 4, 1024) 9438208 convolution2d_23[0][0] ____________________________________________________________________________________________________ maxpooling2d_3 (MaxPooling2D) (None, 2, 2, 1024) 0 convolution2d_24[0][0] ____________________________________________________________________________________________________ convolution2d_25 (Convolution2D) (None, 2, 2, 256) 2359552 maxpooling2d_3[0][0] ____________________________________________________________________________________________________ convolution2d_26 (Convolution2D) (None, 2, 2, 32) 73760 convolution2d_25[0][0] ____________________________________________________________________________________________________ maxpooling2d_4 (MaxPooling2D) (None, 1, 1, 32) 0 convolution2d_26[0][0] ____________________________________________________________________________________________________ flatten_1 (Flatten) (None, 32) 0 maxpooling2d_4[0][0] ____________________________________________________________________________________________________ dense_1 (Dense) (None, 4) 132 flatten_1[0][0] ____________________________________________________________________________________________________ dense_2 (Dense) (None, 1) 5 dense_1[0][0] ==================================================================================================== Total params: 206538153 ____________________________________________________________________________________________________ None Thu Oct 6 09:05:42 2016 +------------------------------------------------------+ | NVIDIA-SMI 352.63 Driver Version: 352.63 | |-------------------------------+----------------------+----------------------+ | 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 960 Off | 0000:01:00.0 On | N/A | | 30% 37C P2 28W / 120W | 1082MiB / 2044MiB | 9% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 1796 G /usr/bin/X 155MiB | | 0 2597 G compiz 65MiB | | 0 5966 C python 849MiB | +-----------------------------------------------------------------------------+ Press Enter to continue... Thu Oct 6 09:05:44 2016 +------------------------------------------------------+ | NVIDIA-SMI 352.63 Driver Version: 352.63 | |-------------------------------+----------------------+----------------------+ | 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 960 Off | 0000:01:00.0 On | N/A | | 30% 38C P2 28W / 120W | 1082MiB / 2044MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 1796 G /usr/bin/X 155MiB | | 0 2597 G compiz 65MiB | | 0 5966 C python 849MiB | +-----------------------------------------------------------------------------+ Compiled model. Press Enter to continue... Thu Oct 6 09:05:44 2016 +------------------------------------------------------+ | NVIDIA-SMI 352.63 Driver Version: 352.63 | |-------------------------------+----------------------+----------------------+ | 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 960 Off | 0000:01:00.0 On | N/A | | 30% 38C P2 28W / 120W | 1082MiB / 2044MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 1796 G /usr/bin/X 155MiB | | 0 2597 G compiz 65MiB | | 0 5966 C python 849MiB | +-----------------------------------------------------------------------------+ About to train one iteration. Press Enter to continue... Error allocating 37748736 bytes of device memory (out of memory). Driver report 34205696 bytes free and 2144010240 bytes total Traceback (most recent call last): File "memtest.py", line 65, in <module> model.train_on_batch(x, y) File "/usr/local/lib/python2.7/dist-packages/keras/models.py", line 712, in train_on_batch class_weight=class_weight) File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1221, in train_on_batch outputs = self.train_function(ins) File "/usr/local/lib/python2.7/dist-packages/keras/backend/theano_backend.py", line 717, in __call__ return self.function(*inputs) File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 871, in __call__ storage_map=getattr(self.fn, ''storage_map'', None)) File "/usr/local/lib/python2.7/dist-packages/theano/gof/link.py", line 314, in raise_with_op reraise(exc_type, exc_value, exc_trace) File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 859, in __call__ outputs = self.fn() MemoryError: Error allocating 37748736 bytes of device memory (out of memory). Apply node that caused the error: GpuContiguous(GpuDimShuffle{3,2,0,1}.0) Toposort index: 338 Inputs types: [CudaNdarrayType(float32, 4D)] Inputs shapes: [(1024, 1024, 3, 3)] Inputs strides: [(1, 1024, 3145728, 1048576)] Inputs values: [''not shown''] Outputs clients: [[GpuDnnConv{algo=''small'', inplace=True}(GpuContiguous.0, GpuContiguous.0, GpuAllocEmpty.0, GpuDnnConvDesc{border_mode=''half'', subsample=(1, 1), conv_mode=''conv'', precision=''float32''}.0, Constant{1.0}, Constant{0.0}), GpuDnnConvGradI{algo=''none'', inplace=True}(GpuContiguous.0, GpuContiguous.0, GpuAllocEmpty.0, GpuDnnConvDesc{border_mode=''half'', subsample=(1, 1), conv_mode=''conv'', precision=''float32''}.0, Constant{1.0}, Constant{0.0})]] HINT: Re-running with most Theano optimization disabled could give you a back-trace of when this node was created. This can be done with by setting the Theano flag ''optimizer=fast_compile''. If that does not work, Theano optimizations can be disabled with ''optimizer=None''. HINT: Use the Theano flag ''exception_verbosity=high'' for a debugprint and storage map footprint of this apply node.

Algunas cosas a tener en cuenta:

  • He probado los backends de Theano y TensorFlow. Ambos tienen los mismos problemas y se quedan sin memoria en la misma línea. En TensorFlow, parece que Keras asigna una gran cantidad de memoria (alrededor de 1,5 GB) por lo que nvidia-smi no nos ayuda a rastrear lo que está sucediendo allí, pero obtengo las mismas excepciones de falta de memoria. De nuevo, esto apunta a un error en (mi uso de) Keras (aunque es difícil estar seguro de tales cosas, podría ser algo con mi configuración).
  • Intenté usar CNMEM en Theano, que se comporta como TensorFlow: preasigna una gran cantidad de memoria (aproximadamente 1,5 GB) pero se cuelga en el mismo lugar.
  • Hay algunas advertencias sobre la versión CudNN. Intenté ejecutar Theano backend con CUDA pero no con CudNN y obtuve los mismos errores, así que esa no es la fuente del problema.
  • Si desea probar esto en su propia GPU, es posible que desee hacer que la red sea más profunda / menos profunda según la cantidad de memoria de la GPU que tenga para probar esto.
  • Mi configuración es la siguiente: Ubuntu 14.04, GeForce GTX 960, CUDA 7.5.18, CudNN 5.1.3, Python 2.7, Keras 1.1.0 (instalado a través de pip)
  • Intenté cambiar la compilación del modelo para usar diferentes optimizadores y pérdidas, pero eso no parece cambiar nada.
  • Intenté cambiar la función train_on_batch para usar fit en su lugar, pero tiene el mismo problema.
  • Vi una pregunta similar aquí en StackOverflow: ¿Por qué este modelo de Keras requiere más de 6 GB de memoria? - pero por lo que puedo decir, no tengo esos problemas en mi configuración. Nunca tuve instaladas varias versiones de CUDA, y he comprobado por duplicado mis variables PATH, LD_LIBRARY_PATH y CUDA_ROOT más veces de las que puedo contar.
  • Julius sugirió que los parámetros de activación ocupen la memoria de la GPU. Si esto es cierto, ¿alguien puede explicarlo un poco más claramente? He intentado cambiar la función de activación de mis capas de convolución a funciones que están claramente codificadas, sin parámetros aprendibles hasta donde yo sé, y eso no cambia nada. Además, parece poco probable que estos parámetros ocupen casi tanta memoria como el resto de la red.
  • Después de pruebas exhaustivas, la red más grande que puedo entrenar es de aproximadamente 453 MB de parámetros, de mis ~ 2 GB de memoria RAM de la GPU. ¿Esto es normal?
  • Después de probar Keras en algunas CNN más pequeñas que caben en mi GPU, puedo ver que hay picos muy repentinos en el uso de la memoria RAM de la GPU. Si ejecuto una red con aproximadamente 100 MB de parámetros, el 99% del tiempo durante el entrenamiento utilizará menos de 200 MB de RAM de la GPU. Pero de vez en cuando, el uso de la memoria aumenta a 1,3 GB. Parece seguro suponer que son estos picos los que están causando mis problemas. Nunca he visto estos picos en otros marcos, pero ¿podrían estar ahí por una buena razón? Si alguien sabe qué los causa, y si hay una manera de evitarlos, ¡por favor, toque!

200M params para GPU de 2 Gb es demasiado. Además, su arquitectura no eficiente, utilizando los cuellos de botella locales será más eficiente. También debe pasar de un modelo pequeño a grande, y no al revés, ahora tiene una entrada 16x16, con esta arquitectura que significa que al final la mayoría de su red tendrá "relleno cero" y no se basará en las características de entrada. Las capas de modelo dependen de su entrada, por lo que no puede establecer un número arbitrario de capas y tamaños, necesita contar la cantidad de datos que se pasarán a cada uno de ellos, y comprender por qué lo hacen. Te recomendaría que veas este curso gratuito http://cs231n.github.io


Es un error muy común olvidar que las activaciones y los degradados también toman vram, no solo los parámetros, lo que aumenta el uso de la memoria bastante. Los propios cálculos de la prótesis hacen que la fase de entrenamiento tome casi el doble de la VRAM del uso directo / de inferencia de la red neuronal.

Entonces, al principio, cuando se crea la red, solo se asignan los parámetros. Sin embargo, cuando se inicia el entrenamiento, se asignan las activaciones (por cada minibatch), así como los cálculos de backprop, lo que aumenta el uso de la memoria.


Tanto Theano como Tensorflow aumentan el gráfico simbólico que se crea, aunque ambos de manera diferente.

Para analizar cómo está sucediendo el consumo de memoria, puede comenzar con un modelo más pequeño y hacer que crezca para ver el crecimiento correspondiente en la memoria. Del mismo modo, puede aumentar el batch_size de batch_size para ver el crecimiento correspondiente en la memoria.

Aquí hay un fragmento de código para aumentar batch_size función de su código inicial:

from scipy import misc import numpy as np from keras.models import Sequential from keras.layers import Dense, Activation, Convolution2D, MaxPooling2D, Reshape, Flatten, ZeroPadding2D, Dropout import os import matplotlib.pyplot as plt def gpu_memory(): out = os.popen("nvidia-smi").read() ret = ''0MiB'' for item in out.split("/n"): if str(os.getpid()) in item and ''python'' in item: ret = item.strip().split('' '')[-2] return float(ret[:-3]) gpu_mem = [] gpu_mem.append(gpu_memory()) model = Sequential() model.add(Convolution2D(100, 3, 3, border_mode=''same'', input_shape=(16,16,1))) model.add(Convolution2D(256, 3, 3, border_mode=''same'')) model.add(Convolution2D(32, 3, 3, border_mode=''same'')) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dense(4)) model.add(Dense(1)) model.summary() gpu_mem.append(gpu_memory()) model.compile(optimizer=''sgd'', loss=''mse'', metrics=[''accuracy'']) gpu_mem.append(gpu_memory()) batches = [] n_batches = 20 batch_size = 1 for ibatch in range(n_batches): batch_size = (ibatch+1)*10 batches.append(batch_size) x = np.random.rand(batch_size, 16,16,1) y = np.random.rand(batch_size, 1) print y.shape model.train_on_batch(x, y) print("Trained one iteration") gpu_mem.append(gpu_memory()) fig = plt.figure() plt.plot([-100, -50, 0]+batches, gpu_mem) plt.show()

Además, para la velocidad, Tensorflow almacena toda la memoria GPU disponible. Para detener eso y necesita agregar config.gpu_options.allow_growth = True en get_session()

# keras/backend/tensorflow_backend.py def get_session(): global _SESSION if tf.get_default_session() is not None: session = tf.get_default_session() else: if _SESSION is None: if not os.environ.get(''OMP_NUM_THREADS''): config = tf.ConfigProto(allow_soft_placement=True, ) else: nb_thread = int(os.environ.get(''OMP_NUM_THREADS'')) config = tf.ConfigProto(intra_op_parallelism_threads=nb_thread, allow_soft_placement=True) config.gpu_options.allow_growth = True _SESSION = tf.Session(config=config) session = _SESSION if not _MANUAL_VAR_INIT: _initialize_variables() return session

Ahora, si ejecuta el fragmento prev, obtiene tramas como:

Theano: Tensorflow:

Theano: después de model.compile() cualquiera que sea la memoria que se necesite, durante el inicio del entrenamiento, casi se duplica. Esto se debe a que Theano aumenta el gráfico simbólico para hacer la retro-propagación y cada tensor necesita un tensor correspondiente para lograr el flujo hacia atrás de los gradientes. Las necesidades de memoria no parecen crecer con batch_size y esto es inesperado para mí ya que el tamaño del marcador de posición debería aumentar para acomodar la entrada de datos desde CPU-> GPU.

Tensorflow: no se asigna ninguna memoria GPU incluso después de model.compile() ya que Keras no llama a get_session() hasta ese momento que realmente llama a _initialize_variables() . Tensorflow parece encerrar la memoria en fragmentos de velocidad y por lo tanto la memoria no crece linealmente con batch_size .

Habiendo dicho todo eso, Tensorflow parece estar hambriento de memoria, pero para los gráficos grandes es muy rápido ... Theano, por otro lado, es muy eficiente en cuanto a la memoria gpu, pero le lleva mucho tiempo inicializar el gráfico al comienzo del entrenamiento. Después de eso también es bastante rápido.