Создайте свою собственную модель Transformer с нуля с помощью PyTorch
В этом уроке мы создадим базовую модель Transformer с нуля, используя PyTorch. Модель Transformer, представленная Vaswani et al. в статье «Attention is All You Need» — это архитектура глубокого обучения, предназначенная для последовательных задач, таких как машинный перевод и суммирование текста. Она основана на механизмах внутреннего внимания и стала основой для многих современных моделей обработки естественного языка, таких как GPT и BERT.
Чтобы построить нашу модель, мы выполним следующие шаги:
- Импортируем необходимые библиотеки и модули
- Определим основные строительные блоки: Multi-Head Attention, Position-wise Feed-Forward Networks, Positional Encoding
- Создадим слои кодировщика и декодера
- Объединим слои кодировщика и декодера, чтобы создать полную модель
- Подготовим образцы данных
- Обучим модель
Начнём с импорта необходимых библиотек и модулей:
Теперь мы определим основные строительные блоки модели Transformer.
Multi-Head Attention
Механизм Multi-Head Attention вычисляет внимание между каждой парой позиций в последовательности. Он состоит из нескольких элементов, которые фиксируют различные аспекты входной последовательности.
Код MultiHeadAttention инициализирует модуль входными параметрами и слоями линейного преобразования. Он вычисляет показатели внимания, преобразует входной тензор в несколько элементов и объединяет все их результаты.
Position-wise Feed-Forward Networks
Класс PositionWiseFeedForward расширяет nn.Module PyTorch и реализует сеть прямой связи с учётом позиции. Класс инициализируется двумя слоями линейного преобразования и функцией активации ReLU. Прямой метод последовательно применяет эти преобразования и функцию активации для вычисления выходных данных. Этот процесс позволяет модели учитывать положение входных элементов при прогнозировании.
Positional Encoding
Позиционное кодирование используется для ввода информации о положении каждого токена во входную последовательность. Он использует функции синуса и косинуса разных частот для генерации позиционного кодирования:
Класс PositionalEncoding инициализируется входными параметрами d_model и max_seq_length, создавая тензор для хранения значений позиционного кодирования. Класс вычисляет значения синуса и косинуса для чётных и нечётных индексов соответственно на основе коэффициента масштабирования div_term. Прямой метод вычисляет позиционное кодирование, добавляя сохранённые значения позиционного кодирования к входному тензору, позволяя модели собирать информацию о позиции входной последовательности.
Теперь мы создадим слои кодировщика и декодера.
Слой кодировщика
Слой кодировщика состоит из слоя Multi-Head Attention, слоя Position-wise Feed-Forward и двух слоёв Layer Normalization.
Класс EncoderLayer инициализируется входными параметрами и компонентами, включая модуль MultiHeadAttention, модуль PositionWiseFeedForward, двухуровневые модули нормализации и слой исключения. Прямые методы вычисляют выходные данные уровня кодировщика, применяя собственное внимание, добавляя выходные данные внимания к входному тензору и нормализуя результат. Затем он вычисляет вывод прямой связи по положению, объединяет его с нормализованным выводом собственного внимания и нормализует окончательный результат перед возвратом обработанного тензора.
Слой декодера
Слой декодера состоит из двух слоёв Multi-Head Attention, слоя Position-wise Feed-Forward layer и трёх слоев Layer Normalization.
DecoderLayer инициализируется входными параметрами и компонентами, такими как модули MultiHeadAttention для маскированного внутреннего и перекрёстного внимания, модуль PositionWiseFeedForward, трехуровневые модули нормализации и слой исключения.
Прямой метод вычисляет выходные данные уровня декодера, выполняя следующие шаги:
- Вычисление замаскированного вывода собственного внимания и добавление его к входному тензору с последующим отсевом и нормализацией слоя.
- Вычисление вывода перекрёстного внимания между выходами декодера и кодировщика и добавление его к нормализованному замаскированному выводу собственного внимания с последующим отсевом и нормализацией слоя.
- Расчёт выходных данных с прямой связью по положению и объединение их с нормализованными выходными данными перекрёстного внимания с последующим отсевом и нормализацией слоев.
- Возвращение обработанного тензора.
Эти операции позволяют декодеру генерировать целевые последовательности на основе ввода и вывода кодера.
Теперь давайте объединим оба слоя, чтобы создать полную модель Transformer.
Модель Transformer
Объединяем всё вместе:
Класс Transformer объединяет ранее определённые модули для создания полной модели Transformer. Во время инициализации модуль Transformer устанавливает входные параметры и инициализирует различные компоненты, в том числе встраивающие слои для исходной и целевой последовательностей, модуль PositionalEncoding, модули EncoderLayer и DecoderLayer для создания сложенных слоев, линейный слой для проецирования выходных данных декодера и слой исключения.
Метод generate_mask создаёт двоичные маски для исходной и целевой последовательностей, чтобы игнорировать маркеры заполнения и не допускать, чтобы декодер обращался к будущим маркерам. Прямой метод вычисляет выходные данные модели Transformer с помощью следующих шагов:
- Генерация исходной и целевой маски с помощью метода generate_mask.
- Вычисление исходного и целевого встраивания, а также применение позиционного кодирования и отсев.
- Обработка исходной последовательности через слои кодировщика, обновив тензор enc_output.
- Обработка целевой последовательности через слои декодера, используя enc_output и маски, и обновление тензора dec_output.
- Применение слоя линейной проекции к выходным данным декодера, получив выходные логиты.
Эти шаги позволяют модели Transformer обрабатывать входные последовательности и генерировать выходные последовательности на основе объединенной функциональности её компонентов.
Подготовка выборочных данных
В этом примере мы создадим маленький набор данных для демонстрационных целей. На практике вы должны использовать больший набор данных, предварительно обработать текст и создать сопоставление словарей для исходного и целевого языков.
Обучение модели
Теперь мы будем обучать модель, используя образцы данных. На практике вы должны использовать больший набор данных и разделить его на наборы для обучения и проверки.
Мы можем использовать этот способ для создания простой модели Transformer с нуля в Pytorch. Все большие языковые модели используют эти блоки кодировщика или декодера Transformer для обучения. Следовательно, понимание сети, с которой всё началось, чрезвычайно важно. Надеюсь, эта статья поможет всем, кто хочет глубже погрузиться в LLM.
Рекомендации
Attention is all you need
А. Васвани , Н. Шазир , Н. Пармар , Дж. Ушкорейт , Л. Джонс , А. Гомес , {. Кайзер , И. Полосухин . Достижения в области нейронных систем обработки информации, стр. 5998–6008. ( 2017 )