Tensorflow: “GraphDef no puede tener más de 2 GB”. Error al guardar el modelo después de asignar variables

Quiero usar un modelo pre-entrenado para comenzar con calor otro modelo con una pequeña diferencia. Simplemente, creo un nuevo modelo y asigno las variables con el mismo nombre con ponderaciones de modelo pre-entrenadas. Pero, al guardar el modelo, se produjo un error.

Traceback (most recent call last): File "tf_test.py", line 23, in save_path = saver.save(sess, "./model.ckpt") File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/saver.py", line 1308, in save self.export_meta_graph(meta_graph_filename) File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/saver.py", line 1331, in export_meta_graph graph_def=ops.get_default_graph().as_graph_def(add_shapes=True), File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 2268, in as_graph_def result, _ = self._as_graph_def(from_version, add_shapes) File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 2231, in _as_graph_def raise ValueError("GraphDef cannot be larger than 2GB.") ValueError: GraphDef cannot be larger than 2GB.

El código de ejemplo es el siguiente:

 import tensorflow as tf import numpy as np v1 = tf.get_variable("L_enc", [400000, 1024]) v2 = tf.get_variable("L_dec", [400000, 1024]) init_op = tf.initialize_all_variables() saver = tf.train.Saver(tf.all_variables()) with tf.Session() as sess: sess.run(init_op) for v in tf.trainable_variables(): embedding = np.random.uniform(-1, 1, (400000, 1024)) sess.run(v.assign(embedding)) # Save the variables to disk. save_path = saver.save(sess, "./model.ckpt") print("Model saved in file: %s" % save_path) 

Fabrizio señala correctamente que hay un límite de 2 GB en el tamaño de los búferes de protocolo, pero es posible que se pregunte por qué su progtwig alcanza ese límite. El problema proviene de estas líneas:

 for v in tf.trainable_variables(): embedding = np.random.uniform(-1, 1, (400000, 1024)) sess.run(v.assign(embedding)) 

Cuando la ejecución llega a v.assign(embedding) , se agregan nuevos nodos al gráfico TensorFlow. En particular, cada matriz de embedding se convierte en un tensor tf.constant() , que será bastante grande (según mi estimación, aproximadamente 328 MB).

La mejor manera de evitar esto es cargar las variables del modelo anterior directamente en su nuevo modelo usando un tf.train.Saver . Dado que los modelos pueden tener una estructura diferente, es posible que deba especificar una asignación de los nombres de las variables en el modelo anterior a los objetos tf.Variable en su nuevo modelo.


Una forma alternativa de resolver su problema sería crear tf.placeholder() una tf.placeholder() para asignar un valor a cada variable. Esto podría requerir una mayor reestructuración de su código real, pero lo siguiente funcionó para mí:

 v1 = tf.get_variable("L_enc", [400000, 1024]) v2 = tf.get_variable("L_dec", [400000, 1024]) # Define a separate placeholder and assign op for each variable, so # that we can feed the initial value without adding it to the graph. vars = [v1, v2] placeholders = [tf.placeholder(tf.float32, shape=[400000, 1024]) for v in vars] assign_ops = [v.assign(p) for (v, p) in zip(vars, placeholders)] init_op = tf.global_variables_initializer() saver = tf.train.Saver(tf.all_variables()) with tf.Session() as sess: sess.run(init_op) for p, assign_op in zip(placeholders, assign_ops): embedding = np.random.uniform(-1, 1, (400000, 1024)) sess.run(assign_op, {p: embedding}) # Save the variables to disk. save_path = saver.save(sess, "./model.ckpt") print("Model saved in file: %s" % save_path) 

Hay un límite duro de 2 GB para serializar tensores individuales debido al tamaño firmado de 32 bits en protobuf.

https://github.com/tensorflow/tensorflow/issues/4291