Что такое трансформенная архитектура?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое трансформерная архитектура?
Трансформер (Transformer) — это революционная архитектура нейронной сети, представленная в статье "Attention is All You Need" (2017). Она основана на механизме внимания (attention) и полностью отказалась от рекуррентной обработки последовательностей, позволяя параллельно обрабатывать все элементы входной последовательности.
Основные компоненты
1. Multi-Head Attention (Внимание с несколькими головами)
Рассчитывает взвешенную сумму значений на основе сходства запросов и ключей:
import torch
import torch.nn as nn
class MultiHeadAttention(nn.Module):
def __init__(self, d_model, num_heads):
super().__init__()
self.num_heads = num_heads
self.d_model = d_model
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 attention(self, Q, K, V, mask=None):
scores = torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.d_k, dtype=torch.float32))
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
weights = torch.softmax(scores, dim=-1)
return torch.matmul(weights, V)
def forward(self, Q, K, V):
batch_size = Q.shape[0]
Q = self.W_q(Q).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
K = self.W_k(K).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
V = self.W_v(V).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
context = self.attention(Q, K, V)
context = context.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
return self.W_o(context)
2. Feed-Forward Network (Полносвязная сеть)
class FeedForward(nn.Module):
def __init__(self, d_model, d_ff):
super().__init__()
self.fc1 = nn.Linear(d_model, d_ff)
self.fc2 = nn.Linear(d_ff, d_model)
self.relu = nn.ReLU()
def forward(self, x):
return self.fc2(self.relu(self.fc1(x)))
3. Positional Encoding (Кодирование позиций)
Открывает информацию о позиции элементов в последовательности:
import math
class PositionalEncoding(nn.Module):
def __init__(self, d_model, max_len=5000):
super().__init__()
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
self.register_buffer('pe', pe.unsqueeze(0))
def forward(self, x):
return x + self.pe[:, :x.size(1)]
4. Encoder-Decoder архитектура
class TransformerBlock(nn.Module):
def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
super().__init__()
self.mha = MultiHeadAttention(d_model, num_heads)
self.ffn = FeedForward(d_model, d_ff)
self.layernorm1 = nn.LayerNorm(d_model)
self.layernorm2 = nn.LayerNorm(d_model)
self.dropout1 = nn.Dropout(dropout)
self.dropout2 = nn.Dropout(dropout)
def forward(self, x):
# Self-attention блок
attn_output = self.mha(x, x, x)
x = self.layernorm1(x + self.dropout1(attn_output))
# Feed-forward блок
ffn_output = self.ffn(x)
x = self.layernorm2(x + self.dropout2(ffn_output))
return x
Полная архитектура Трансформера
class Transformer(nn.Module):
def __init__(self, vocab_size, d_model, num_heads, num_layers, d_ff, max_len=5000, dropout=0.1):
super().__init__()
self.embedding = nn.Embedding(vocab_size, d_model)
self.positional_encoding = PositionalEncoding(d_model, max_len)
self.encoder_layers = nn.ModuleList([TransformerBlock(d_model, num_heads, d_ff, dropout) for _ in range(num_layers)])
self.fc_out = nn.Linear(d_model, vocab_size)
self.dropout = nn.Dropout(dropout)
def forward(self, x):
x = self.embedding(x)
x = self.positional_encoding(x)
x = self.dropout(x)
for layer in self.encoder_layers:
x = layer(x)
return self.fc_out(x)
Механизм внимания (Attention)
Формула Scaled Dot-Product Attention:
Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) * V
где:
- Q (Query) — запрос
- K (Key) — ключ
- V (Value) — значение
- d_k — размерность ключа
Интуиция:
- Вычисляем сходство между Q и K
- Нормализуем с softmax
- Взвешиваем значения V
# Простой пример
Q = torch.randn(batch_size, seq_len, d_model)
K = torch.randn(batch_size, seq_len, d_model)
V = torch.randn(batch_size, seq_len, d_model)
scores = torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_model))
weights = torch.softmax(scores, dim=-1)
output = torch.matmul(weights, V)
Преимущества Трансформера
1. Параллелизм
Все элементы последовательности обрабатываются одновременно (в отличие от RNN):
RNN: O(n) временные шаги
Трансформер: O(1) временные шаги (для параллельного процессора)
2. Долгосрочные зависимости
Механизм внимания может напрямую связать далёкие элементы без затухающего градиента:
# Каждый элемент имеет прямую связь с каждым другим элементом
# Расстояние = O(1) вместо O(n) в RNN
3. Переносимость (Transfer Learning)
Трансформеры легко переносят знания между задачами:
- BERT, GPT, T5 — все на основе Трансформера
Практический пример: использование готового Трансформера
from transformers import AutoTokenizer, AutoModel
import torch
# Загрузка предтренированной модели
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
model = AutoModel.from_pretrained("bert-base-uncased")
# Токенизация
text = "Hello, how are you?"
inputs = tokenizer(text, return_tensors="pt")
# Предсказание
with torch.no_grad():
outputs = model(**inputs)
last_hidden_state = outputs.last_hidden_state
Варианты Трансформера
| Модель | Назначение | Пример |
|---|---|---|
| Encoder-only | Классификация, NER | BERT, RoBERTa |
| Decoder-only | Генерация текста | GPT-2, GPT-3 |
| Encoder-Decoder | Перевод, summarization | T5, BART |
Сложность и требования
- Временная сложность: O(n^2 * d) из-за Attention
- Память: высокая из-за всех попарных взаимодействий
- Решения: Efficient Transformers (Linformer, Performer)
Трансформер полностью изменил ландшафт NLP и стал основой для современных больших языковых моделей, обеспечивая превосходную обработку последовательностей благодаря механизму внимания и параллелизму.