Запуск объединенного тензорного потока на графическом процессоре с помощью Colab

#tensorflow #google-colaboratory #tensorflow-federated

#тензорный поток #google-совместная лаборатория #объединенный тензорный поток

Вопрос:

Есть ли способ использовать графический процессор, предоставляемый Colab, для ускорения учебных сессий TFF? Для обучения объединенных моделей требуется более 1 часа, и кажется, что использование среды выполнения GPU вообще не дает никакой пользы.

Страница высокопроизводительного моделирования TFF по-прежнему пуста, и я не могу найти никакого руководства по использованию GPU с TFF.

Есть предложения? Спасибо!

версии tf и tff:

 2.4.0-dev20200917 
0.16.1
  

Количество клиентов в каждом раунде:

 70
  

Спецификация элемента входных данных:

 OrderedDict([('x',
          OrderedDict([('start_place',
                        TensorSpec(shape=(8, 8), dtype=tf.int32, name=None)),
                       ('start_hour_sin',
                        TensorSpec(shape=(8, 8), dtype=tf.float64, name=None)),
                       ('start_hour_cos',
                        TensorSpec(shape=(8, 8), dtype=tf.float64, name=None)),
                       ('week_day_sin',
                        TensorSpec(shape=(8, 8), dtype=tf.float64, name=None)),
                       ('week_day_cos',
                        TensorSpec(shape=(8, 8), dtype=tf.float64, name=None)),
                       ('weekend',
                        TensorSpec(shape=(8, 8), dtype=tf.int32, name=None)),
                       ('month',
                        TensorSpec(shape=(8, 8), dtype=tf.int32, name=None))])),
         ('y', TensorSpec(shape=(8, 8), dtype=tf.int32, name=None))])
  

Аналогично руководству по генерации текста, в котором я работаю с последовательностью мест, модель очень похожа:

     # Create a model
def create_keras_model(number_of_places, batch_size):
  
        # Shortcut to the layers package
  l = tf.keras.layers


  # Now we need to define an input dictionary.
    # Where the keys are the column names
    # This is a model with multiple inputs, so we need to declare and input layer for each feature
  feature_inputs = {
    'start_hour_sin': tf.keras.Input((N-1, ), batch_size=batch_size, name='start_hour_sin'),
    'start_hour_cos': tf.keras.Input((N-1, ), batch_size=batch_size, name='start_hour_cos'),
    'weekend': tf.keras.Input((N-1, ), batch_size=batch_size, name='weekend'),
    'week_day_sin': tf.keras.Input((N-1, ), batch_size=batch_size, name='week_day_sin'),
    'week_day_cos': tf.keras.Input((N-1, ), batch_size=batch_size, name='week_day_cos'),
  }

  
  # We cannot use anarray of features as always because we have sequences and we cannot match the shape otherwise
  # We have to do one by one
  start_hour_sin = feature_column.numeric_column("start_hour_sin", shape=(N-1))
  hour_sin_feature = l.DenseFeatures(start_hour_sin)(feature_inputs)

  start_hour_cos = feature_column.numeric_column("start_hour_cos", shape=(N-1))
  hour_cos_feature = l.DenseFeatures(start_hour_cos)(feature_inputs)

  weekend = feature_column.numeric_column("weekend", shape=(N-1))
  weekend_feature = l.DenseFeatures(weekend)(feature_inputs)
  
  week_day_sin = feature_column.numeric_column("week_day_sin", shape=(N-1))
  week_day_sin_feature = l.DenseFeatures(week_day_sin)(feature_inputs)

  week_day_cos = feature_column.numeric_column("week_day_cos", shape=(N-1))
  week_day_cos_feature = l.DenseFeatures(week_day_cos)(feature_inputs)

  
    # We have also to add a dimension to then concatenate
  hour_sin_feature = tf.expand_dims(hour_sin_feature, -1)
  hour_cos_feature = tf.expand_dims(hour_cos_feature, -1)
  weekend_feature = tf.expand_dims(weekend_feature, -1)
  week_day_sin_feature = tf.expand_dims(week_day_sin_feature, -1)
  week_day_cos_feature = tf.expand_dims(week_day_cos_feature, -1)

  # Declare the dictionary for the places sequence as before
  sequence_input = {
      'start_place': tf.keras.Input((N-1,), batch_size=batch_size, dtype=tf.dtypes.int32, name='start_place') # add batch_size=batch_size in case of stateful GRU
  }


  # Handling the categorical feature sequence using one-hot
  places_one_hot = feature_column.sequence_categorical_column_with_vocabulary_list(
      'start_place', [i for i in range(number_of_places)])
  
  # Embed the one-hot encoding
  places_embed = feature_column.embedding_column(places_one_hot, embedding_dim)


  # With an input sequence we can't use the DenseFeature layer, we need to use the SequenceFeatures
  sequence_features, sequence_length = tf.keras.experimental.SequenceFeatures(places_embed)(sequence_input)

  input_sequence = l.Concatenate(axis=2)([ sequence_features, hour_sin_feature, hour_cos_feature, weekend_feature, week_day_sin_feature, week_day_cos_feature])

  # Rnn
  recurrent = l.GRU(rnn_units,
                        batch_size=batch_size, #in case of stateful
                        return_sequences=True,
                        dropout=0.5,
                        stateful=True,
                        recurrent_initializer='glorot_uniform')(input_sequence)


    # Last layer with an output for each places
  dense_1 = layers.Dense(number_of_places)(recurrent)

    # Softmax output layer
  output = l.Softmax()(dense_1)
    
    # To return the Model, we need to define it's inputs and outputs
    # In out case, we need to list all the input layers we have defined 
  inputs = list(feature_inputs.values())   list(sequence_input.values())

    # Return the Model
  return tf.keras.Model(inputs=inputs, outputs=output)
  

Функция для создания модели:

 def create_tff_model():
  # TFF uses an `input_spec` so it knows the types and shapes
  # that your model expects.
  input_spec = preprocessed_example_dataset.element_spec
  keras_model_clone = create_keras_model(number_of_places, batch_size=BATCH_SIZE)
  return tff.learning.from_keras_model(
      keras_model_clone,
      input_spec=input_spec,
      loss=tf.keras.losses.SparseCategoricalCrossentropy(),
  

Объединенный средний

 # This command builds all the TensorFlow graphs and serializes them: 
fed_avg = tff.learning.build_federated_averaging_process(
    model_fn=create_tff_model,
    client_optimizer_fn=lambda: tf.keras.optimizers.Adam(learning_rate=0.001),
    server_optimizer_fn=lambda: tf.keras.optimizers.Adam(learning_rate=0.06))
          metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])
  

Инициализация состояния:

 state = fed_avg.initialize()
  

Цикл обучения:

 NUM_ROUNDS = 10

  for round_num in range(1, NUM_ROUNDS   1):
    print('Round {r}'.format(r=round_num))
    state, metrics = fed_avg.next(state, train_data)
    train_metrics = metrics['train']
    print('tTrain: loss={l:.3f}, accuracy={a:.3f}'.format(l=train_metrics['loss'], a=train_metrics['sparse_categorical_accuracy']))
  

Комментарии:

1. Можете ли вы предоставить более подробную информацию? Какую версию TF и TFF вы используете? Какую модель и задачу вы тренируете? Сколько клиентов за раунд вы используете? Все подобные дополнительные сведения, возможно, фрагмент кода о том, как вы предоставляете данные, были бы полезны.

2. Пожалуйста, предоставьте автономную общедоступную записную книжку, которая воспроизводит патологии производительности, которые вы наблюдаете.

3. Извини @JakubKonecny, Боб. Я добавил дополнительные сведения и фрагменты

4. Не могли бы вы прокомментировать размеры train_data ? Существует 70 клиентов, но на скольких примерах, пакетах и эпохах настраиваются наборы данных?

5. @ZacharyGarrett среднее количество обучающих пакетов на пользователя составляет около 13, в то время как количество эпох на клиента равно 2

Ответ №1:

Следует отметить, что эта модель выполняет 0 клиентов * 13 шагов SGD за раунд (около 1000), хотя один час все еще кажется очень долгим. 70 клиентов на одной машине выходят за рамки моделирования, когда их число становится намного больше, мы начинаем рассматривать настройки для нескольких машин с использованием удаленного исполнителя.

Некоторые вещи, которые нужно исследовать:

  • Привязан ли к моделированию ввод-вывод? Как быстро среда Python может выполнять итерации по одному клиентскому набору данных? В TF for batch in dataset: и время, сколько времени это займет, может быть полезно здесь.
  • Связано ли моделирование с вычислениями? Возможно, посмотрите на загрузку процессора и графического процессора. Сколько времени требуется для запуска keras_model.fit() с одним клиентским набором данных? Моделирование TFF примерно выполняет это 70 раз за раунд (один раз для каждого клиента).

Комментарии:

1. Использование одного и того же набора данных в общем централизованном контексте заняло у меня 4 минуты за эпоху и 7 мс / шаг. keras_model.fit(), вызываемый в одном клиентском наборе данных, занимает примерно 3 секунды, чтобы вычислить 2 эпохи, которые я установил для клиентов (2 секунды обучения и 1 секунда для запуска с момента вызова функции); Таким образом, только для fit () клиентов должно потребоваться что-то вроде 70 * 3 секунд = 210 секунд, что примерно соответствует времени, которое требуется за раунд (в среднем 170 секунд)