این درس شما را قدمبهقدم با اصول و پیادهسازی معماری Transformer آشنا میکند؛ هدف فهم دقیق مکانیزمهای کلیدی، نحوهٔ ساخت بلوکها و نکات عملی برای آموزش و دیباگ مدلهاست.
نگاه کلی و انگیزه
Transformer بهجای توالیمحور بودن (RNN) روی مکانیزم توجه تمرکز میکند که اجازه میدهد مدل ارتباط بین موقعیتهای مختلف توکنها را بهطور مستقیم یاد بگیرد. این رویکرد مزایایی مانند موازیسازی و یادگیری وابستگیهای بلندمدت را فراهم میآورد.
مکانیزم Self-Attention
محاسبه Scaled Dot-Product Attention
برای مجموعهای از Query (Q)، Key (K) و Value (V): وزنهای توجه با ضرب Q و K و نرمالسازی با sqrt(d_k) محاسبه میشوند و سپس Softmax روی سطرها اعمال میشود تا توزیع توجه بدست آید:
Attention(Q,K,V) = softmax(Q K^T / sqrt(d_k)) V
توضیح هندسی و نکات عملی
- scale با sqrt(d_k) از انفجار مقادیر داخلی جلوگیری میکند.
- Softmax باعث میشود که توجه روی مجموعهای از موقعیتها متمرکز شود.
- برای ماسک کردن موقعیتهای آینده (در Decoder) یا پدها از ماسک استفاده میشود.
اجزای اصلی Transformer
Multi-Head Attention
تعداد h سرها اجازه میدهد مدل چند فضای نمایش مختلف را همزمان یاد بگیرد. هر سر projectionهای جداگانهای از Q,K,V دارد و خروجیها concat و با یک ماتریس خطی نهایی میشوند.
Position-wise Feed-Forward
هر token بهصورت مستقل از دیگران از یک شبکهٔ دو لایهی خطی (با non-linearity مانند ReLU یا GELU) میگذرد:
FFN(x) = max(0, xW_1 + b_1) W_2 + b_2
Layer Normalization و Residual
- هر زیرلایه دارای اتصال باقیمانده (residual) و LayerNorm است.
- این ترکیب سرعت همگرایی را بهبود میدهد و پایداری آموزش را افزایش میدهد.
Positional Encoding
چون مدل بر پایه توجه است و ترتیبی ذاتی ندارد، positional encoding (ثابت یا یادگرفتنی) به ورودی اضافه میشود تا اطلاعات ترتیب در توکنها حفظ شود.
| مفهوم | ابعاد/خلاصه |
|---|---|
| Q, K, V | shape = (batch, seq_len, d_model) پس از پروجکشن به d_k / d_v |
| Multi-Head | هر head: d_k = d_model / h |
| Output | concat(heads) → linear → (batch, seq_len, d_model) |
معماری Encoder و Decoder
Encoder
Encoder از چند لایهٔ تکرارشونده شامل Multi-Head Attention و Feed-Forward تشکیل میشود. ورودی توکنها همراه با positional encoding به لایهٔ اول میرود.
Decoder
Decoder علاوه بر self-attention و FFN، یک attention سراسری به خروجی encoder دارد تا اطلاعات منبع را بگیرد. همچنین در self-attention از ماسک causal برای جلوگیری از دیدن توکنهای آینده استفاده میشود.
پیادهسازی گامبهگام (مثال با PyTorch)
در این مثال یک Transformer block ساده با PyTorch نشان داده شده است. هدف فهم ساختار است نه تولید یک پیادهسازی بهینهٔ صنعتی.
import torch
import torch.nn as nn
import math
class SimpleMultiHeadAttention(nn.Module):
def __init__(self, d_model, h):
super().__init__()
assert d_model % h == 0
self.d_k = d_model // h
self.h = h
self.linear_q = nn.Linear(d_model, d_model)
self.linear_k = nn.Linear(d_model, d_model)
self.linear_v = nn.Linear(d_model, d_model)
self.out = nn.Linear(d_model, d_model)
def forward(self, x, mask=None):
batch, seq, _ = x.size()
q = self.linear_q(x).view(batch, seq, self.h, self.d_k).transpose(1,2)
k = self.linear_k(x).view(batch, seq, self.h, self.d_k).transpose(1,2)
v = self.linear_v(x).view(batch, seq, self.h, self.d_k).transpose(1,2)
scores = torch.matmul(q, k.transpose(-2,-1)) / math.sqrt(self.d_k)
if mask is not None:
scores = scores.masked_fill(mask == 0, float('-inf'))
attn = torch.softmax(scores, dim=-1)
context = torch.matmul(attn, v)
context = context.transpose(1,2).contiguous().view(batch, seq, self.h * self.d_k)
return self.out(context)
class TransformerBlock(nn.Module):
def __init__(self, d_model, h, d_ff, dropout=0.1):
super().__init__()
self.attn = SimpleMultiHeadAttention(d_model, h)
self.norm1 = nn.LayerNorm(d_model)
self.ff = nn.Sequential(
nn.Linear(d_model, d_ff),
nn.ReLU(),
nn.Linear(d_ff, d_model)
)
self.norm2 = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x, mask=None):
attn_out = self.attn(x, mask)
x = self.norm1(x + self.dropout(attn_out))
ff_out = self.ff(x)
x = self.norm2(x + self.dropout(ff_out))
return x
نکات آموزشی و تنظیمات هیپر
- batch size بزرگتر باعث پایدارتر شدن محاسبات توجه میشود ولی حافظهٔ بیشتری لازم دارد.
- warmup scheduling برای نرخ یادگیری معمولاً مفید است (linear warmup سپس decay).
- استفاده از label smoothing در مسائل طبقهبندی توکن میتواند overconfidence را کاهش دهد.
خطاهای رایج و رفع اشکال
خطای 1: ماسکها اشتباه تنظیم شدهاند — علامتها یا ابعاد ماسک باید با scores همخوانی داشته باشند. اگر ماسک در ابعاد نادرست اعمال شود، نتیجهٔ attention نادرست خواهد بود.
خطای 2: ناپایداری gradient — مقدار d_k خیلی بزرگ باشد یا نرخ یادگیری بالا؛ از تقسیم توسط sqrt(d_k)، clipping grad و LR schedule استفاده کنید.
خطای 3: ترتیب tokenها نادیده گرفته شده — فراموش نکنید positional encoding را اضافه کنید.
مثال واقعی و مراحل اجرایی
پیادهسازی یک مدل ترجمه مبتنی بر Transformer — مراحل خلاصه:
- پیشپردازش داده: توکنایزینگ، ساخت vocabulary و padding/attention masks.
- ساخت encoder و decoder با تعداد لایهها و head مناسب.
- استفاده از LR schedule با warmup و تابع loss مناسب (CrossEntropy با label smoothing).
- آموزش با checkpoint و ارزیابی مرحلهای (BLEU یا متریک دلخواه).
- استفاده از beam search یا روشهای مکمل در مرحلهٔ inference.
چکلیست قبل از استارت آموزش:
- آیا embedding و positional encoding به درستی جمع شدهاند؟
- آیا ماسکها برای پدها و causal صحیح ساخته شدهاند؟
- آیا ابعاد Q/K/V و headها مطابق d_model تنظیم شدهاند؟
- آیا LR schedule و warmup مناسب انتخاب شدهاند؟
جمعبندی و گامهای بعدی
Transformer ساختاری منعطف و قوی برای مدلسازی توالیها ارائه میدهد. برای تعمیق دانش، گامهای بعدی شامل مطالعهٔ مزایا/معایب انواع positional encoding، مقایسهٔ architectures مبتنی بر attention و آشنایی با بهینهسازیهای مقیاسپذیری (مثل sparse attention, efficient transformers) است.