← Назад к вопросам
Расскажите про архитектуру Transformer
2.0 Middle🔥 201 комментариев
#NLP и обработка текста#Глубокое обучение
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Архитектура Transformer
История и мотивация
Transformer — это архитектура глубокого обучения, предложенная в статье "Attention is All You Need" (Vaswani et al., 2017). Она полностью основана на механизме attention и стала основой для современных больших языковых моделей (GPT, BERT, LLaMA и др.).
Трансформер был создан для преодоления проблем рекуррентных сетей:
- RNN обрабатывает последовательность последовательно (долго)
- RNN страдает от затухающего градиента при длинных зависимостях
- Сложно распараллелить обучение RNN
Основные компоненты
1. Позиционное кодирование (Positional Encoding)
Так как Трансформер обрабатывает слова параллельно (без рекурсии), нужно добавить информацию о позиции слова в последовательности.
import numpy as np
import torch
def positional_encoding(seq_len, d_model):
"""
Создание матрицы позиционного кодирования.
seq_len: длина последовательности
d_model: размерность модели (обычно 512)
"""
pos = np.arange(seq_len)[:, np.newaxis] # (seq_len, 1)
dim = np.arange(0, d_model, 2)[np.newaxis, :] # (1, d_model//2)
angle_rates = 1 / (10000 ** (dim / d_model))
pe = np.zeros((seq_len, d_model))
pe[:, 0::2] = np.sin(pos * angle_rates) # чётные индексы: sin
pe[:, 1::2] = np.cos(pos * angle_rates) # нечётные индексы: cos
return torch.from_numpy(pe).unsqueeze(0).float() # (1, seq_len, d_model)
2. Multi-Head Attention (Многоголовый внимание)
Это сердце Трансформера. Позволяет моделировать разные виды зависимостей между словами.
import torch
import torch.nn as nn
class MultiHeadAttention(nn.Module):
def __init__(self, d_model, num_heads):
super().__init__()
self.d_model = d_model
self.num_heads = num_heads
self.d_k = d_model // num_heads # размерность каждой головы
self.W_q = nn.Linear(d_model, d_model)
self.W_k = nn.Linear(d_model, d_model)
self.W_v = nn.Linear(d_model, d_model)
self.W_o = nn.Linear(d_model, d_model)
def scaled_dot_product_attention(self, Q, K, V, mask=None):
"""
Scaled Dot-Product Attention:
Attention(Q, K, V) = softmax(Q * K^T / sqrt(d_k)) * V
"""
scores = torch.matmul(Q, K.transpose(-2, -1)) / np.sqrt(self.d_k)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
attention_weights = torch.softmax(scores, dim=-1)
output = torch.matmul(attention_weights, V)
return output, attention_weights
def forward(self, Q, K, V, mask=None):
batch_size = Q.shape[0]
# Линейные преобразования
Q = self.W_q(Q) # (batch, seq_len, d_model)
K = self.W_k(K)
V = self.W_v(V)
# Разделение на num_heads
Q = Q.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
K = K.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
V = V.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
# (batch, num_heads, seq_len, d_k)
# Attention для каждой головы
attn_output, _ = self.scaled_dot_product_attention(Q, K, V, mask)
# Конкатенация и финальная проекция
attn_output = attn_output.transpose(1, 2).contiguous()
attn_output = attn_output.view(batch_size, -1, self.d_model)
output = self.W_o(attn_output)
return output
3. Слой Feed-Forward Network
После Attention идёт полносвязная сеть с двумя слоями:
class FeedForwardNetwork(nn.Module):
def __init__(self, d_model, d_ff):
super().__init__()
self.fc1 = nn.Linear(d_model, d_ff) # обычно d_ff = 4 * d_model
self.fc2 = nn.Linear(d_ff, d_model)
self.relu = nn.ReLU()
def forward(self, x):
return self.fc2(self.relu(self.fc1(x)))
4. Layer Normalization и Residual Connections
class TransformerEncoderBlock(nn.Module):
def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
super().__init__()
self.attention = MultiHeadAttention(d_model, num_heads)
self.feed_forward = FeedForwardNetwork(d_model, d_ff)
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x, mask=None):
# Multi-Head Attention с residual connection
attn_output = self.attention(x, x, x, mask)
x = x + self.dropout(attn_output) # residual
x = self.norm1(x) # layer norm
# Feed-Forward с residual connection
ff_output = self.feed_forward(x)
x = x + self.dropout(ff_output) # residual
x = self.norm2(x) # layer norm
return x
Полная архитектура Transformer
class Transformer(nn.Module):
def __init__(self, vocab_size, d_model, num_heads, num_layers, d_ff, max_seq_len, dropout=0.1):
super().__init__()
self.embedding = nn.Embedding(vocab_size, d_model)
self.positional_encoding = positional_encoding(max_seq_len, d_model)
self.encoder_layers = nn.ModuleList([
TransformerEncoderBlock(d_model, num_heads, d_ff, dropout)
for _ in range(num_layers)
])
self.decoder_layers = nn.ModuleList([
TransformerEncoderBlock(d_model, num_heads, d_ff, dropout)
for _ in range(num_layers)
])
self.output_projection = nn.Linear(d_model, vocab_size)
def forward(self, src, tgt, src_mask=None, tgt_mask=None):
# Embedding + Positional Encoding
src_embedded = self.embedding(src) + self.positional_encoding[:, :src.shape[1], :]
tgt_embedded = self.embedding(tgt) + self.positional_encoding[:, :tgt.shape[1], :]
# Encoder
enc_output = src_embedded
for layer in self.encoder_layers:
enc_output = layer(enc_output, src_mask)
# Decoder с Cross-Attention
dec_output = tgt_embedded
for layer in self.decoder_layers:
dec_output = layer(dec_output, tgt_mask) # Self-attention
# Cross-attention между Decoder и Encoder
dec_output = layer.attention(dec_output, enc_output, enc_output, None)
# Output projection
output = self.output_projection(dec_output)
return output
Преимущества Transformer:
- Параллелизм: обрабатывает весь текст одновременно (не последовательно как RNN)
- Длинные зависимости: Attention может учитывать отношения между любыми токенами
- Масштабируемость: легко добавлять слои и голов без проблем с градиентами
- Универсальность: работает для машинного перевода, классификации, генерации текста
Сложность Transformer:
- Временная сложность: O(n^2 * d) на слой (где n — длина последовательности, d — размерность)
- Память: O(n^2) для матрицы Attention (проблема для очень длинных текстов)
- Решение: sparse attention, linear attention, или окна внимания
Трансформер революционизировал NLP и стал основой для всех современных больших языковых моделей.