Тензор потока: "GraphDef не может быть больше, чем 2 ГБ". ошибка при сохранении модели после присвоения переменных

Я хочу использовать предварительно обученную модель, чтобы тепло начать другую модель с небольшой разницей. Просто я создаю новую модель и присваиваю переменные с тем же именем с предварительно подготовленными весами модели. Но при сохранении модели произошла ошибка.

Traceback (most recent call last): File "tf_test.py", line 23, in <module> 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.

Пример кода выглядит следующим образом:

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)

2 ответа

Фабрицио правильно указывает, что существует жесткое ограничение в 2 ГБ на размер буферов протокола, но вы можете задаться вопросом, почему ваша программа достигает этого предела. Проблема проистекает из этих строк:

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

Когда исполнение попадает v.assign(embedding) новые узлы добавляются в граф TensorFlow. В частности, каждый embedding массив преобразуется в tf.constant() тензор, который будет довольно большим (примерно 328 МБ по моей оценке).

Лучший способ избежать этого - загрузить переменные из предыдущей модели непосредственно в новую модель, используя tf.train.Saver, Поскольку модели могут иметь различную структуру, вам может потребоваться указать отображение имен переменных в старой модели на tf.Variable объекты в вашей новой модели.


Альтернативным способом решения вашей проблемы является предварительное создание tf.placeholder() op для присвоения значения каждой переменной. Это может потребовать дополнительной реструктуризации вашего реального кода, но мне помогло следующее:

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)

Существует жесткое ограничение в 2 ГБ для сериализации отдельных тензоров из-за 32-битного размера со знаком в protobuf.

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

Другие вопросы по тегам