2016-12-12 11 views
3

Теперь база tensorflow-char-rnn Я запускаю проект word-rnn, чтобы предсказать следующее слово. Но я обнаружил, что скорость слишком медленная в моем наборе данных поезда. Вот мои учебные детали: размер данныхКак ускорить rnn скорость обучения тензорного потока?

  • Обучение: 1 миллиард слов
  • Словарь Размер: 0.75 миллионов
  • РНН модель: LSTM
  • РНН Слой: 2
  • Размер ячейки: 200
  • Seq length: 20
  • Размер партии: 40 (слишком большой размер партии будет причиной исключения OOM)

Машина детали:

  • Amazon p2 экземпляра
  • 1 ядро ​​K80 GPU
  • 16G видеопамяти
  • 4 ядра процессора
  • 60G памяти

В моем тесте, время обучения данных 1 эпоха - 17 дней! Это действительно слишком медленно, а затем я меняю seq2seq.rnn_decoder на tf.nn.dynamic_rnn, но время все равно 17 дней.

Я хочу найти слишком медленную причину, вызванную моим кодом, или она всегда была такой медленной? Поскольку я слышал некоторые слухи о том, что Tensorflow rnn медленнее, чем другие DL Framework.

Это мой код модели:

class SeqModel(): 
def __init__(self, config, infer=False): 
    self.args = config 
    if infer: 
     config.batch_size = 1 
     config.seq_length = 1 

    if config.model == 'rnn': 
     cell_fn = rnn_cell.BasicRNNCell 
    elif config.model == 'gru': 
     cell_fn = rnn_cell.GRUCell 
    elif config.model == 'lstm': 
     cell_fn = rnn_cell.BasicLSTMCell 
    else: 
     raise Exception("model type not supported: {}".format(config.model)) 

    cell = cell_fn(config.hidden_size) 

    self.cell = cell = rnn_cell.MultiRNNCell([cell] * config.num_layers) 

    self.input_data = tf.placeholder(tf.int32, [config.batch_size, config.seq_length]) 
    self.targets = tf.placeholder(tf.int32, [config.batch_size, config.seq_length]) 
    self.initial_state = cell.zero_state(config.batch_size, tf.float32) 

    with tf.variable_scope('rnnlm'): 
     softmax_w = tf.get_variable("softmax_w", [config.hidden_size, config.vocab_size]) 
     softmax_b = tf.get_variable("softmax_b", [config.vocab_size]) 

     embedding = tf.get_variable("embedding", [config.vocab_size, config.hidden_size]) 
     inputs = tf.nn.embedding_lookup(embedding, self.input_data) 


    outputs, last_state = tf.nn.dynamic_rnn(cell, inputs, initial_state=self.initial_state) 

    # [seq_size * batch_size, hidden_size] 
    output = tf.reshape(tf.concat(1, outputs), [-1, config.hidden_size]) 

    self.logits = tf.matmul(output, softmax_w) + softmax_b 
    self.probs = tf.nn.softmax(self.logits) 

    self.final_state = last_state 


    loss = seq2seq.sequence_loss_by_example([self.logits], 
              [tf.reshape(self.targets, [-1])], 
              [tf.ones([config.batch_size * config.seq_length])], 
              config.vocab_size) 
    self.cost = tf.reduce_sum(loss)/config.batch_size/config.seq_length 

    self.lr = tf.Variable(0.0, trainable=False) 
    tvars = tf.trainable_variables() 
    grads, _ = tf.clip_by_global_norm(tf.gradients(self.cost, tvars), 
             config.grad_clip) 
    optimizer = tf.train.AdamOptimizer(self.lr) 
    self.train_op = optimizer.apply_gradients(zip(grads, tvars)) 

Here is the GPU load during the training

Спасибо очень много.

+0

64 дней, кажется, немного слишком много, вы можете показать код? – sygi

+0

Используете ли вы набор данных Google Billion Words? –

+0

@sygi Код модели выше. Я уменьшаю размер словаря до 0,75 миллиона (1,5 м до) и меняю размер партии до 40 (15 до), длина до 20 (25 до), поэтому я могу переместить вложение слов в GPU (OOM раньше). Но для эпохи все еще нужно 17 дней. –

ответ

3

Как вы упомянули batch_size действительно важно настроить, это может привести к впечатляющему ускорению, но убедитесь, что ваше недоумение сохраняет актуальность.

Мониторинг активности вашего GPU вы можете дать вам подсказки о потенциальном узком месте ввода-вывода.

Главное, используя сэмплированный softmax вместо обычного softmax быстрее. Это потребует от вас использовать [config.vocab_size, config.hidden_size] весовую матрицу вместо вас [config.hidden_size, config.vocab_size]. Это, безусловно, путь к моей точке зрения.

Надеюсь, что это поможет.

pltrdy

+0

Спасибо за ваш ответ. Я попробую позже и даю улучшенный результат. Другой вопрос: Если я использовал предварительно подготовленное слово-вложение и отмечаю его обучаемым = False, могу ли я получить более быстрый результат? –

+0

Сэмплированный softmax - захватывающий, он ускоряет сравнение 6х раньше. Теперь для обучения 1 эпоха требуется 2,6 дня. (nums_sampled = 512) Но для меня все еще слишком медленно, я обнаружил, что во время обучения мой GPU не заполнен, вот снимок: [https://i.stack.imgur.com/2BR1S.png] (Монитор GPU) –

+0

1) О вложениях: Я не уверен, но это звучит интересно, попробуйте! 2) Обычно я увеличиваю свой batch_size, когда GPU не на 100%, поскольку, на мой взгляд, это связано с высоким уровнем ввода-вывода между RAM и GPU, поэтому GPU не может работать на 100%. Увеличьте batch_size, вы можете захотеть взглянуть на ваше использование CPU одновременно. Он может дать вам подсказки (возможно, только операции с процессором «блокируются».) – pltrdy

1

Еще один возможный путь вы можете ускорить обучение, и возможная причина вашего отсутствия использования графического процессора, это вы используете заполнители. Вы должны использовать очереди, если используете Tensorflow < 1.2, а в противном случае - модуль tf.contrib.data.

https://www.tensorflow.org/programmers_guide/threading_and_queues

Смежные вопросы