Что такое трансформерная архитектура (Transformer)?

«Что такое трансформерная архитектура (Transformer)?» — вопрос из категории NLP и трансформеры, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Трансформер (Transformer) — это архитектура нейронной сети, представленная в 2017 году в работе «Attention Is All You Need». Ее ключевая инновация — полный отказ от рекуррентных (RNN) и сверточных (CNN) слоев для обработки последовательностей в пользу механизма внимания (attention), что позволило эффективно распараллеливать вычисления и лучше улавливать долгосрочные зависимости.

Основные компоненты архитектуры (на примере энкодера):

  1. Входные эмбеддинги: Слова преобразуются в векторы.
  2. Позиционное кодирование (Positional Encoding): Добавляет информацию о порядке слов, так как сам механизм внимания не учитывает последовательность.
  3. Слой самовнимания (Self-Attention): Позволяет каждому элементу последовательности «взвешивать» влияние всех остальных элементов. Вычисляется как взвешенная сумма значений (Value), где веса определяются совместимостью запроса (Query) с ключом (Key). [ text{Attention}(Q, K, V) = text{softmax}(frac{QK^T}{sqrt{d_k}})V ]
  4. Многоголовое внимание (Multi-Head Attention): Несколько независимых механизмов самовнимания работают параллельно, что позволяет модели фокусироваться на разных типах взаимосвязей (например, синтаксических и семантических).
  5. Позиционно-зависимая полносвязная сеть (Position-wise Feed-Forward Network): Применяется независимо к каждому позиционному вектору после слоя внимания.
  6. Остаточные связи (Residual Connections) и нормализация слоя (LayerNorm): Стабилизируют обучение глубокой сети.

Упрощенная реализация самовнимания на PyTorch:

import torch
import torch.nn as nn
import torch.nn.functional as F

class SelfAttention(nn.Module):
    def __init__(self, embed_size, heads):
        super(SelfAttention, self).__init__()
        self.embed_size = embed_size
        self.heads = heads
        self.head_dim = embed_size // heads
        assert self.head_dim * heads == embed_size, "Embed size must be divisible by heads"
        self.values = nn.Linear(self.head_dim, self.head_dim, bias=False)
        self.keys = nn.Linear(self.head_dim, self.head_dim, bias=False)
        self.queries = nn.Linear(self.head_dim, self.head_dim, bias=False)
        self.fc_out = nn.Linear(heads * self.head_dim, embed_size)
    def forward(self, values, keys, query, mask=None):
        N = query.shape[0]
        value_len, key_len, query_len = values.shape[1], keys.shape[1], query.shape[1]
        # Разделение эмбеддингов на головы
        values = values.reshape(N, value_len, self.heads, self.head_dim)
        keys = keys.reshape(N, key_len, self.heads, self.head_dim)
        queries = query.reshape(N, query_len, self.heads, self.head_dim)
        energy = torch.einsum("nqhd,nkhd->nhqk", [queries, keys]) / (self.head_dim ** 0.5)
        if mask is not None:
            energy = energy.masked_fill(mask == 0, float("-1e20"))
        attention = torch.softmax(energy, dim=3)
        out = torch.einsum("nhql,nlhd->nqhd", [attention, values])
        out = out.reshape(N, query_len, self.heads * self.head_dim)
        return self.fc_out(out)

Применение:

  • NLP: Является основой для BERT (двунаправленный энкодер), GPT (авторегрессионный декодер), T5 и других SOTA-моделей.
  • Компьютерное зрение: Vision Transformer (ViT) разбивает изображение на патчи и обрабатывает их как последовательность.
  • Мультимодальные задачи: Модели типа CLIP, DALL-E.

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