Transformer không phải cơ sở dữ liệu chứa sẵn câu hay bộ suy luận ký hiệu. Về cốt lõi, nó là chương trình khả vi liên tục trộn thông tin giữa các vị trí token rồi biến đổi từng vị trí độc lập. Huấn luyện điều chỉnh hàng tỷ tham số để chương trình dự đoán phần tiếp theo hữu ích.
Bài viết sẽ theo một tensor xuyên qua transformer decoder-only, kiến trúc đứng sau phần lớn mô hình ngôn ngữ lớn có khả năng sinh, đồng thời giữ kích thước tensor luôn hiện rõ.
Từ văn bản đến vector có vị trí
Mạng nơ-ron nhận số chứ không nhận chuỗi. Tokenizer ánh xạ văn bản thành dãy ID token nguyên, thường theo đơn vị từ con hoặc dẫn xuất từ byte. Mảnh phổ biến có thể chiếm một token, còn từ hiếm bị tách thành nhiều token. Tokenization mang tính xác định với bộ từ vựng cố định nhưng không trung lập về ngôn ngữ: cùng lượng nội dung có thể cần số token khác nhau.
Với bộ từ vựng kích thước V, mô hình sở hữu bảng embedding . Tra cứu T ID token tạo ra
trong đó là batch size, là độ dài chuỗi và là chiều rộng mô hình. Embedding không phải định nghĩa từ điển mà là vector được học qua cách các layer sau xử lý nó.
Self-attention không biết thứ tự, nên mô hình phải đưa thông tin vị trí vào. Transformer nguyên bản cộng vector hình sin cố định; mô hình khác học absolute position embedding hoặc xoay query và key bằng RoPE. Tất cả đều giúp “chó cắn người” khác với “người cắn chó”.
Nếu cộng trực tiếp position embedding, layer đầu nhận
RoPE thay vào đó sửa query và key bên trong attention. Dù theo cách nào, mọi block đều có thể sử dụng cả danh tính token lẫn vị trí.
Note
Token là đơn vị riêng của từng mô hình, không đồng nghĩa với ký tự hay từ. Giới hạn context, giá API và độ trễ sinh đều được đo bằng token, nên cùng một câu có thể có chi phí khác nhau với các tokenizer khác nhau.
Q, K, V và scaled dot-product attention
Từ hidden state , ba phép chiếu tuyến tính được học tạo ra ba góc nhìn:
Mọi token đều sinh đủ cả ba. Query mã hóa điều vị trí hiện tại muốn tìm; key mã hóa điều mỗi vị trí nguồn cung cấp; value mang thông tin được lấy về. Ý nghĩa ấy do mô hình học chứ không được gán trước.
Với một attention head, độ tương đồng là tích vô hướng . Softmax biến mỗi hàng thành các trọng số không âm có tổng bằng một, rồi tổng có trọng số lấy thông tin từ :
là chiều rộng head và là mask. Không scale sẽ khiến phương sai tích vô hướng tăng theo , làm softmax quá sắc và gradient nhỏ. Chia cho giữ logit ở thang dễ huấn luyện.
Decoder dùng causal mask: vị trí chỉ được attend đến vị trí . Logit của token tương lai nhận trước softmax nên xác suất bằng không. Padding mask còn có thể ẩn token giữ chỗ khi các mẫu dài ngắn khác nhau nằm trong cùng batch.
Multi-head attention chạy phép toán song song trong nhiều không gian con. Mô hình rộng 768 với 12 head thường có mỗi head rộng 64. Các head học kiểu định tuyến khác nhau; đầu ra được nối lại rồi trộn bằng một phép chiếu khác.
Implementation PyTorch sau thể hiện rõ kích thước. Boolean mask có thể broadcast thành [B, H, Tq, Tk], trong đó True nghĩa là được nhìn thấy.
import math
import torch
from torch import Tensor, nn
def scaled_dot_product_attention(
query: Tensor,
key: Tensor,
value: Tensor,
mask: Tensor | None = None,
) -> tuple[Tensor, Tensor]:
# query: [B, H, Tq, Dh], key/value: [B, H, Tk, Dh]
scores = query @ key.transpose(-2, -1)
scores = scores / math.sqrt(query.size(-1))
if mask is not None:
scores = scores.masked_fill(~mask, float("-inf"))
weights = torch.softmax(scores, dim=-1)
output = weights @ value
return output, weights
class CausalMultiHeadAttention(nn.Module):
def __init__(self, d_model: int, num_heads: int) -> None:
super().__init__()
if d_model % num_heads != 0:
raise ValueError("d_model must be divisible by num_heads")
self.num_heads = num_heads
self.head_dim = d_model // num_heads
self.qkv = nn.Linear(d_model, 3 * d_model, bias=False)
self.output = nn.Linear(d_model, d_model, bias=False)
def forward(self, hidden: Tensor) -> Tensor:
# hidden: [B, T, D]
batch, tokens, width = hidden.shape
qkv = self.qkv(hidden)
qkv = qkv.view(batch, tokens, 3, self.num_heads, self.head_dim)
qkv = qkv.permute(2, 0, 3, 1, 4)
query, key, value = qkv.unbind(dim=0) # each [B, H, T, Dh]
causal_mask = torch.ones(
tokens, tokens, dtype=torch.bool, device=hidden.device
).tril()
causal_mask = causal_mask.view(1, 1, tokens, tokens)
attended, _ = scaled_dot_product_attention(
query, key, value, causal_mask
)
attended = attended.transpose(1, 2).contiguous()
attended = attended.view(batch, tokens, width)
return self.output(attended)
Đây là code tham chiếu đúng về mặt toán học, không phải kernel production tối ưu tốc độ. Hệ thống thực dùng implementation hợp nhất như FlashAttention để không phải hiện thực hóa toàn bộ ma trận điểm trong bộ nhớ băng thông cao.
Phần còn lại của transformer block
Attention giao tiếp giữa các vị trí, nhưng mới là nửa block. MLP biến đổi riêng từng token: thường mở rộng chiều rộng khoảng bốn lần, áp dụng GELU hoặc SwiGLU, rồi chiếu về . Attention định tuyến thông tin; MLP tính toán trên thông tin đã đến.
Residual connection cộng đầu vào của sublayer vào đầu ra. Trong decoder block kiểu pre-normalization, phép tính xấp xỉ là
Đường residual cho gradient lối đi trực tiếp qua mạng sâu và cho mỗi sublayer học phần hiệu chỉnh. LayerNorm hoặc RMSNorm kiểm soát thang activation. Pre-norm chuẩn hóa trước sublayer và thường ổn định hơn post-norm nguyên bản.
Sau hàng chục hoặc hàng trăm block, một bước normalization cuối đi vào phép chiếu đầu ra có một logit cho mỗi token trong bộ từ vựng. Phép chiếu này thường dùng chung trọng số với bảng input embedding. Softmax có thể đổi logit thành xác suất, dù code huấn luyện thường truyền thẳng logit vào hàm cross-entropy ổn định số học.
| Thành phần | Trộn các vị trí token? | Có tham số được học? | Nhiệm vụ chính |
|---|---|---|---|
| Token embedding | Không | Có | Ánh xạ ID vào không gian mô hình |
| Cơ chế vị trí | Gián tiếp | Tùy loại | Biểu diễn thứ tự và khoảng cách |
| Self-attention | Có | Có | Định tuyến thông tin ngữ cảnh |
| MLP | Không | Có | Biến đổi feature tại từng vị trí |
| Residual path | Không | Không | Giữ tín hiệu và luồng gradient |
| Norm | Không | Thường có | Ổn định thang activation |
Warning
Attention weight là hệ số định tuyến, không bảo đảm là lời giải thích cho quyết định của mô hình. Trọng số thấp không chứng minh thông tin không liên quan, vì thông tin có thể đã di chuyển qua layer trước hoặc được MLP biến đổi.
Huấn luyện song song, sinh token tuần tự
Trong pretraining, mô hình dự đoán mỗi token từ prefix và tối thiểu hóa negative log-likelihood trung bình:
Input và target là cùng chuỗi lệch một vị trí. Causal mask cho phép xử lý song song mà không lộ token tương lai. Backpropagation tính gradient; optimizer như AdamW cập nhật tham số. Instruction tuning và preference optimization có thể uốn hành vi nhưng vẫn dùng bộ máy dự đoán token kế tiếp này.
Khi inference, mô hình xử lý prompt, chọn token tiếp theo từ logit, nối nó vào chuỗi rồi lặp lại. Greedy decoding chọn logit lớn nhất; temperature, top-k và top-p điều khiển sampling. Chúng đổi cách chọn chứ không đổi tri thức đã học.
| Khía cạnh | Huấn luyện | Inference tự hồi quy |
|---|---|---|
| Token sẵn có | Toàn bộ chuỗi huấn luyện | Prompt và prefix đã sinh |
| Xử lý vị trí | Song song sau causal mask | Một vị trí mới mỗi bước |
| Cập nhật tham số | Có, qua gradient | Không |
| Áp lực bộ nhớ chính | Activation và trạng thái optimizer | Trọng số mô hình và KV cache |
| Cách chọn đầu ra | Cross-entropy với target | Greedy hoặc sampling |
Teacher forcing tạo độ lệch: khi huấn luyện, mỗi vị trí thấy token trước đúng từ dữ liệu; khi sinh, nó thấy lựa chọn trước của chính mình. Một lựa chọn yếu có thể đổi mọi phân phối về sau. Mô hình liên tục nối dài prefix, không truy xuất câu trả lời hoàn chỉnh.
KV cache, chi phí context và giới hạn cứng
Cách sinh ngây thơ chạy lại toàn bộ prefix cho mỗi token mới. Trong causal decoder, hidden state cũ không đổi, nên mỗi layer cache tensor và đã chiếu. Bước kế tiếp chỉ tính QKV cho token mới, nối K và V vào cache, rồi cho query attend trên lịch sử.
Với batch size , số layer , số head , độ dài cache và chiều rộng head , dung lượng KV tỷ lệ với
Hệ số 2 đại diện cho key và value. Nhân với số byte mỗi phần tử để ước lượng bộ nhớ. Grouped-query attention và multi-query attention làm cache nhỏ hơn bằng cách chia sẻ ít key/value head hơn cho nhiều query head. Cache lượng tử hóa đánh đổi một phần độ chính xác để lấy dung lượng.
Cache khiến mỗi bước decode rẻ hơn nhiều so với tính lại prefix, nhưng không làm context dài trở thành miễn phí. Query mới vẫn tương tác với mọi vị trí đã cache, bộ nhớ cache tăng tuyến tính theo context, và prefill trên prompt ban đầu vẫn đắt. Khối lượng tính toán của attention chuẩn trong huấn luyện và prefill tăng bậc hai theo độ dài chuỗi, kể cả khi kernel hợp nhất làm giảm lưu lượng bộ nhớ.
Transformer còn có giới hạn về bản chất. Context window hữu hạn khiến thông tin cũ phải bị cắt, tóm tắt hoặc truy xuất lại. Huấn luyện next-token thưởng cho continuation có vẻ hợp lý chứ không thưởng trực tiếp cho sự thật, nên mô hình có thể bịa đặt đầy tự tin. Tính toán mức token có thể thiếu ổn định với số học chính xác và thuật toán dài. Dữ liệu huấn luyện tạo ra knowledge cutoff và thiên lệch. Nhiều tham số và context hơn cải thiện năng lực nhưng không xóa các giới hạn do mục tiêu huấn luyện.
Tip
Retrieval-augmented generation có thể cung cấp bằng chứng mới, công cụ có thể thực thi phép toán chính xác, và constrained decoding có thể ép cấu trúc đầu ra. Chúng bổ sung cho mô hình; chúng không biến phân phối xác suất thành bảo đảm sự thật.
Điều cần nhớ
- Tokenizer đổi văn bản thành ID riêng của mô hình; embedding và cơ chế vị trí biến các ID ấy thành vector có thứ tự.
- Phép chiếu được học tạo query, key và value. Tích vô hướng đã scale tính trọng số định tuyến, còn causal mask chặn truy cập vị trí tương lai.
- Nhiều head định tuyến thông tin trong các không gian con song song; MLP tiếp tục biến đổi từng vị trí. Residual connection và normalization giúp stack sâu có thể huấn luyện.
- Huấn luyện dự đoán song song mọi target đã dịch vị trí dưới causal mask. Inference phải chọn một token, đưa ngược nó vào rồi mới tính token tiếp theo.
- KV cache tái sử dụng key và value cũ, giảm phép tính lặp nhưng dùng bộ nhớ tăng theo độ dài context.
- Transformer là mô hình chuỗi có điều kiện rất mạnh, không phải nhà tiên tri. Kiến trúc, mục tiêu, tokenizer, context window và dữ liệu cùng định hình điều nó làm được và không làm được.
Khi kích thước tensor đã rõ, vẻ thần bí trở thành một vòng lặp được thiết kế cụ thể: biểu diễn token, định tuyến ngữ cảnh, biến đổi feature, chấm điểm bộ từ vựng rồi lặp lại. Quy mô của nó phi thường; các phép toán thì hoàn toàn hữu hình.