Обучение Transformer в OpenNMT-tf: Инициализация модели

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

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

Обучение Transformer

Инициализация

Обучение модели начинается с инициализации этого процесса. Следующие шаги происходят последовательно при запуске обучения:

  • файл конфигурации считывается и финализируется (файлы auto_config и user config объединяются);

├── config = self._finalize_config() модуль runner.py

├── def _finalize_config() модуль runner.py

├── def auto_config() модуль transformer.py

  • Устанавливается тип расчета tensorflow;

При обучении со смешанной точностью (FP16) set_global_policy («mixed_float16») передается в tensorflow.

├── mixed_precision = self._mixed_precision и misc.enable_mixed_precision() модуль runner.py

├── def enable_mixed_precision() модуль misc.py

  • Инициализируется модель Transformer (или другой тип модели, определенный пользователем);

Модель инициализируется только после установки типа расчета, поскольку тип расчета зафиксирован в закрытых атрибутах модели.

Если инициализировать модель до инициализации типа расчета, значение в атрибутах модели не изменится и будет по умолчанию float32:

_dtype_policy: <Policy “float32”>

_compute_dtype_object: <dtype: 'float32'>

├── model = self._init_model (config) модуль runner.py

├── def _init_model() модуль runner.py

  • оптимизатор модели определен и инициализирован.

Из автоконфигурации модели Transformer берется имя оптимизатора, которое по умолчанию установлено на LazyAdam. Этот оптимизатор реализован в библиотеке TensorFlow Addons.

Функция затухания NoamDecay инициализируется следующими параметрами:

━ 1) scale - задается значение из параметра Learning rate файла конфигурации обучения (в нашем примере значение равно 2);

━ 2) model_dim - задается значение из параметра num_units (размер Rnn) файла конфигурации обучения (в нашем примере значение равно 4);

━ 3) warmup_steps - задается значение из параметра Warmup steps файла конфигурации обучения (в нашем примере значение равно 8000).

Класс-оболочка ScheduleWrapper инициализируется для дополнения поведения планировщика скорости обучения следующими параметрами:

━ 1) schedule— инициализируется выше функции затухания NoamDecay;

━ 2) step_start — задается значение из параметра start_decay_steps файла конфигурации обучения (значение по умолчанию 0 );

━ 3) step_duration — задается значение из параметра decay_step_duration файла конфигурации обучения (значение по умолчанию 1 );

━ 4) minimum_learning_rate — задается значение из параметра Minimum learning rate файла конфигурации обучения (в нашем примере значение равно 0,0001).

Класс оптимизатора LazyAdam инициализируется следующими параметрами:

━ 1) l earning_rate - класс ScheduleWrapper, инициализированный выше;

━ 2) kwargs - словарь бета-коэффициентов из параметра optimizer_params файла конфигурации обучения (в нашем примере {'beta_1': 0.9, 'beta_2': 0.998} );

━ 3) при обучении со смешанной точностью (FP16) класс LazyAdam наследуется от класса tf.keras. mixed_precision . LossScaleOptimizer, который инициализирует следующие параметры:

  • initial_scale = 32 768 - значение, на которое будет скорректировано значение, полученное из функции потерь;
  • dynamic_growth_steps = 2 000 - как часто обновлять значение, до которого будет скорректировано значение функции потерь.

├── optimizer = model.get_optimizer() модуль runner.py

├── def get_optimizer() модуль model.py

├── def make_learning_rate_schedule() модуль schedules/lr_schedules.py

├── def init() class NoamDecay (tf.keras.optimizers.schedules.LearningRateSchedule) модуль schedules/lr_schedules.py

├── def init() class ScheduleWrapper schedules/lr_schedules.py

├── ef make_optimizer() модуль optimizers/utils.py

  • установлен на batch_size_multiple;

Если активирована функция смешанной точности или Jit-компиляции, batch_size_multiple будет равен 8, в противном случае — 1.

├── batch_size_multiple = (...) модуль runner.py

  • создана функция создания и преобразования набора данных;

├── dataset_fn = (...) модуль runner.py

  • если передано значение effective_batch_size, вычисляется значение, при котором будет обновляться градиент;

├── accum_steps = _count_batch_accum() модуль runner.py

├── def _count_batch_accum() модуль runner.py

  • Инициализируются эмбеддинги для source и для target;

Размерность вложений будет определяться размером словаря и размером параметра num_units (размер Rnn ), где m — количество токенов в словаре, n — значение num_units. (Изображение 1 — matrix_m_n )

Вложения инициализируются через объект tf.keras.Layer, функцию add_weight, которая вызывается через функцию def build() класса WordEmbedder.

├── source_inputter = inputters.WordEmbedder(embedding_size=num_units)

├── def build()

├── target_inputter = inputters.WordEmbedder(embedding_size=num_units)

├── def build()

Например, для словаря размером 700 токенов и num_units (размер Rnn) со значением 8 будет сгенерирована матрица, содержащая 700 строк по 8 чисел в каждой. Вложения будут выглядеть примерно так:

Значения, представленные в матрице внедрения, формируются по определенному механизму. Например, для матрицы размерностью 700x8:

У нас будет матрица размерностью 700 x 8, где значения будут от -0,0920 до 0,0920, взятые случайным образом из равномерного распределения. Описанный выше механизм называется инициализацией Ксавье. Реализация в tensorflow:

├── class GlorotNormal().init()

├── class VarianceScaling().call()

  • инициализируются веса (слои) модели;

├── encoder = SelfAttentionEncoder() модуль transformer.py

├── self.layer_norm = common.LayerNorm() модуль self_attention_encoder.py

├── LayerNorm() модуль common.py

├── SelfAttentionEncoderLayer() модуль self_attention_encoder.py

├── self.self_attention = MultiHeadAttention() модуль layers/transformer.py

├── def build() модуль layers/transformer.py

├── TransformerLayerWrapper(self.self_attention) модуль layers/transformer.py

├── self.ffn = FeedForwardNetwork() модуль layers/transformer.py

├── TransformerLayerWrapper(self.ffn) модуль layers/transformer.py

├── decoder = SelfAttentionDecoder() модуль transformer.py

├── self.layer_norm = common.LayerNorm() модуль self_attention_decoder.py

├── LayerNorm() модуль common.py

├── SelfAttentionDecoderLayer() модуль self_attention_decoder.py

├── self.self_attention = MultiHeadAttention() модуль layers/transformer.py

├── def build() модуль layers/transformer.py

├── TransformerLayerWrapper(self.self_attention) модуль layers/transformer.py

├── attention = MultiHeadAttention() модуль layers/transformer.py

├── TransformerLayerWrapper(attention) модуль layers/transformer.py

├── self.ffn = FeedForwardNetwork() модуль layers/transformer.py

├── TransformerLayerWrapper(self.ffn) модуль layers/transformer.py

Как изначально выглядит модель, веса и их значения показаны на примере небольшой размерности сети:

  • vocab: 26
  • num_units: 4
  • num_layers: 1
  • num_heads: 2
  • ffn_inner_dim: 1
  • maximum_relative_position: 8

Модель можно схематически изобразить следующим образом. (Изображение 2 - модель)

Ядерные (т.е. основные) веса модели инициализируются с помощью механизма «Инициализация Ксавье», описанного выше. Запросы, ключи, значения и выходные слои инициализируются через tf.keras.layers.Dense с добавлением вектора смещения 'use_bias': True. Веса FeedForwardNetwork также инициализируются через tf.keras.layers.Dense с активацией линейного слоя tf.nn.relu. Слой нормализации инициализируется через tf.keras.layers.LayerNormalization, где бета-измерение будет представлено нулями, а гамма-измерение — единицами.

Нормализация слоя (нормализация слоя, LN) — это метод глубокого обучения, используемый для стабилизации процесса обучения и повышения производительности нейронных сетей. Он решает проблему внутреннего ковариационного сдвига (ICS), когда распределение активаций внутри слоя изменяется в процессе обучения, что затрудняет эффективное обучение сети. Статья, в которой была представлена ​​методика нормализации слоя Layer Normalization

При инициализации модели должно выполняться следующее условие: num_units % num_heads, т.е. размерность эмбеддингов (и соответственно запросов, ключей и значений) должна быть кратна количеству голов в MultiHeadAttention.

По сути, матрицы queries, keys и values делятся на указанное в параметре num_heads число и формируются матрицы меньшего размера, количество которых равно num_units // num_heads. Алгоритм реализован в функции split_heads модуля transformer.py. (Изображение 3 - Multi Head Attention)

Рассмотрим алгоритм разбиения матриц queries, keys и values по количеству голов. Для простоты восприятия примем размерность num_units равной 4, а количество голов num_heads равным 2.

Например, у нас есть партия токенов:

Для каждого токена из матрицы встраивания извлекается векторное представление токена (механизм описан ниже) и формируется матрица векторов. Вычисляется размерность батча: input_shapes = [2, 3, 4]. В пакетах есть 2 последовательности, каждая последовательность имеет 3 токена, каждый токен представлен вектором размерности 4. Следующий шаг — изменение размерности матрицы входов:

- outputs = tf.reshape(inputs, [shape[0], shape[1], num_heads, shape[2] // num_heads]) → tf.reshape(inputs, [2, 3, 2, 4 // 2])

- outputs = tf.transpose(outputs, perm=[0, 2, 1, 3])

После изменения размерности мы получаем матрицы меньшей размерности. (Изображение 4 — Матрица изменения формы)

Это конец процесса инициализации модели. После этого начинается сам процесс обучения.

Заключение

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


Вас ждет еще больше увлекательного чтения

Основы машинного перевода

Основы машинного перевода

December 5, 2025

Машинный перевод для бизнеса

Машинный перевод для бизнеса

November 25, 2025

Машинный перевод

Машинный перевод

November 10, 2025

×