Transformer: các họ kiến trúc và thực hành
Sau Transformer 2017, nhiều họ mô hình vẫn giữ lõi Transformer nhưng thay đổi cách dùng encoder, decoder và mask. Ba nhóm quan trọng nhất để đọc bài báo và chọn mô hình là:
- encoder-only;
- decoder-only;
- encoder-decoder.
Mục tiêu học tập
Sau bài này, bạn cần:
- phân loại được BERT, GPT, T5 theo kiến trúc;
- giải thích được mask và mục tiêu huấn luyện điển hình của từng họ;
- biết chọn họ kiến trúc theo dạng đầu vào - đầu ra;
- chạy được một Transformer encoder nhỏ bằng PyTorch;
- gỡ được các lỗi kích thước tensor/mask thường gặp.
1. Bản đồ ba họ Transformer
2. Encoder-only: đọc toàn bộ ngữ cảnh
Ví dụ kinh điển: BERT.
Mỗi token trong encoder self-attention có thể nhìn cả bên trái và bên phải. BERT gốc học trước biểu diễn hai chiều bằng masked language modeling, cùng nhiệm vụ phụ next-sentence prediction trong thiết kế ban đầu.
Phù hợp tự nhiên với các bài toán cần biểu diễn hoặc hiểu đầu vào:
- text classification;
- token classification;
- gán nhãn chuỗi;
- extractive question answering;
- embedding/trích xuất đặc trưng, tùy mô hình và cách huấn luyện.
3. Decoder-only: sinh từ trái sang phải
Ví dụ kinh điển: GPT.
Decoder-only dùng causal self-attention:
Mỗi vị trí chỉ dùng được quá khứ. Đây là cấu trúc phù hợp trực tiếp với bài toán dự đoán token kế tiếp và sinh tự hồi quy.
Ứng dụng:
- sinh văn bản hoặc mã nguồn;
- làm theo chỉ dẫn sau các giai đoạn tinh chỉnh phù hợp;
- hoàn thành đoạn đang viết;
- nhiều tác vụ được biểu diễn dưới dạng prompt → phần tiếp nối.
4. Encoder-decoder: đọc đầu vào rồi sinh đầu ra
Ví dụ: Transformer gốc, T5.
Encoder xử lý toàn bộ đầu vào. Decoder sinh đầu ra và dùng cross-attention để truy xuất các trạng thái của encoder.
Phù hợp với dạng:
chuỗi đầu vào chuỗi đầu ra
Ví dụ:
- dịch máy;
- tóm tắt;
- chuyển đổi văn bản;
- question answering dạng sinh;
- text-to-text multitask.
5. So sánh nhanh
| Họ | Attention chính | Mục tiêu học trước điển hình | Đầu ra tự nhiên |
|---|---|---|---|
| Encoder-only | bidirectional self-attention | dự đoán token bị che | vector/nhãn/span |
| Decoder-only | causal self-attention | dự đoán token kế tiếp | chuỗi sinh tự hồi quy |
| Encoder-decoder | encoder self-attention + decoder causal + cross-attention | khử nhiễu/span corruption hoặc mục tiêu seq2seq | chuỗi đầu ra có điều kiện theo đầu vào |
Bảng này mô tả mẫu kiến trúc điển hình, không phải luật tuyệt đối cho mọi mô hình hiện đại.

Nguồn hình: Sebastian Raschka, Build a Large Language Model (From Scratch), Figure 1.5; dùng như minh hoạ khái niệm.
6. Chọn kiến trúc theo bài toán
Không nên chọn theo tiêu chí “mô hình nào đang nổi nhất”.
Trường hợp A — Phân loại ticket IT
Đầu vào: một đoạn văn bản. Đầu ra: một nhãn.
Encoder-only thường là mốc khởi đầu rất tự nhiên vì ta cần biểu diễn toàn bộ đầu vào rồi dự đoán nhãn.
Trường hợp B — Sinh câu trả lời dài
Đầu vào: prompt. Đầu ra: văn bản mới với độ dài linh hoạt.
Decoder-only phù hợp tự nhiên với sinh tự hồi quy.
Trường hợp C — Dịch/tóm tắt có nguồn rõ ràng
Đầu vào và đầu ra là hai chuỗi khác nhau. Encoder-decoder tách rõ biểu diễn của câu nguồn và quá trình sinh câu đích.
Nhưng thực tế
Decoder-only LLM hiện đại vẫn có thể làm phân loại, dịch hoặc tóm tắt bằng prompting/fine-tuning. Kiến trúc “phù hợp tự nhiên” không có nghĩa các họ khác không làm được.
7. Thực hành: Transformer encoder nhỏ bằng PyTorch
Ví dụ dưới đây chỉ nhằm theo dõi tensor, không phải mô hình dùng trong sản phẩm thật.
import torch
import torch.nn as nn
torch.manual_seed(0)
B = 2
T = 8
VOCAB = 100
D_MODEL = 64
N_HEAD = 4
N_LAYER = 2
# Token IDs: [B, T]
tokens = torch.randint(0, VOCAB, (B, T))
# 1) Token embedding
embedding = nn.Embedding(VOCAB, D_MODEL)
x = embedding(tokens) # [B, T, D_MODEL]
# 2) Learned position embedding for demo
position = nn.Embedding(T, D_MODEL)
pos_ids = torch.arange(T).unsqueeze(0) # [1, T]
x = x + position(pos_ids)
# 3) Transformer encoder
layer = nn.TransformerEncoderLayer(
d_model=D_MODEL,
nhead=N_HEAD,
dim_feedforward=4 * D_MODEL,
dropout=0.0,
batch_first=True,
norm_first=True,
)
encoder = nn.TransformerEncoder(layer, num_layers=N_LAYER)
y = encoder(x)
print("tokens:", tokens.shape) # [2, 8]
print("x:", x.shape) # [2, 8, 64]
print("y:", y.shape) # [2, 8, 64]
Điều cần hiểu
Độ dài chuỗi vẫn là 8 và hidden size vẫn là 64. Transformer encoder biến đổi nội dung biểu diễn, không nhất thiết đổi kích thước tensor.
8. Từ đầu ra theo token sang phân loại
Một encoder cho đầu ra:
[B, T, D]
Muốn phân loại cả câu, ta cần gom thông tin của chuỗi thành vector [B, D].
Ví dụ mean pooling:
sentence_vec = y.mean(dim=1) # [B, D]
classifier = nn.Linear(D_MODEL, 3)
logits = classifier(sentence_vec) # [B, 3]
Trong mô hình thật, pooling có thể dùng token đặc biệt, masked mean pooling hoặc một head riêng.
9. Theo dõi một tensor qua block
Với:
B = 2
T = 8
D = 64
H = 4
d_head = 16
luồng cơ bản:
đầu vào [2, 8, 64]
projection Q/K/V [2, 8, 64]
tách heads [2, 4, 8, 16]
điểm attention [2, 4, 8, 8]
values đã trộn [2, 4, 8, 16]
gộp heads [2, 8, 64]
projection đầu ra [2, 8, 64]
FFN [2, 8, 64] -> [2, 8, 256] -> [2, 8, 64]
đầu ra block [2, 8, 64]
Nếu đọc được bảng này, bạn đã có nền tảng để tự gỡ phần lớn lỗi tensor trong Transformer cơ bản.
10. Vì sao FFN thường mở rộng chiều rồi nén lại?
Một block thường dùng:
với .
Bài báo Transformer gốc dùng và . Không cần học thuộc con số; điều quan trọng là FFN tăng khả năng biến đổi đặc trưng tại từng token rồi trả về đúng để kết nối dư cộng được.
11. Decoder-only block trong mô hình kiểu GPT
Luồng khái quát:
Sơ đồ trên là pre-norm để gần với nhiều cài đặt kiểu GPT hiện đại. Transformer 2017 gốc dùng post-norm. Khi so bài báo với code, hãy kiểm tra vị trí normalization.
12. BERT, GPT, T5 khác nhau không chỉ ở việc “giữ nửa nào” của Transformer
Cách nói:
- BERT = encoder;
- GPT = decoder;
- T5 = encoder-decoder;
rất hữu ích ở mức kiến trúc, nhưng chưa đủ để giải thích toàn bộ mô hình. Chất lượng còn phụ thuộc vào:
- mục tiêu học trước;
- tokenizer;
- dữ liệu;
- scale;
- normalization/activation;
- cách biểu diễn vị trí;
- optimizer và công thức huấn luyện;
- tinh chỉnh/căn chỉnh hành vi.
Vì vậy, không nên suy luận hiệu năng chỉ từ nhãn “encoder-only” hay “decoder-only”.
13. Checklist gỡ lỗi
Shape
d_model % n_head == 0;- batch-first hay sequence-first phải thống nhất;
- logits cho phân loại phải có kích thước
[B, C]; - logits của mô hình ngôn ngữ thường có kích thước
[B, T, vocab_size].
Mask
- encoder bidirectional: không dùng causal mask trừ khi bài toán yêu cầu;
- decoder-only: phải causal;
- padding mask phải chặn
[PAD]; - cross-attention mask không giống decoder causal mask.
Position
Nếu tự code mô hình mà quên thông tin vị trí, mô hình không có cơ chế chuẩn để mã hóa thứ tự chỉ từ self-attention thuần.
Huấn luyện/đánh giá
Dropout phải tắt khi eval:
model.eval()
with torch.no_grad():
...
14. Bài tập
Bài 1 — Chọn họ kiến trúc
Cho 6 bài toán:
- sentiment classification;
- named entity recognition;
- code completion;
- machine translation;
- abstractive summarization;
- sentence embedding.
Chọn một kiến trúc khởi đầu hợp lý và giải thích. Không được trả lời chỉ bằng tên mô hình.
Bài 2 — Shape tracing
Với [B=4,T=32,D=128,H=8], ghi kích thước của Q/K/V, ma trận điểm, đầu ra từng head và đầu ra sau concat.
Bài 3 — Bỏ position embedding
Chạy cùng một encoder với hai chuỗi chứa cùng token nhưng đảo thứ tự. Thảo luận điều gì xảy ra nếu bỏ hoàn toàn thông tin vị trí.
Bài 4 — Encoder vs causal encoder
Dùng cùng TransformerEncoderLayer, thêm causal mask rồi so sánh đầu ra. Giải thích vì sao thay mask có thể đổi bản chất thông tin mà mỗi token được phép sử dụng.
15. Tóm tắt
- Encoder-only phù hợp tự nhiên với biểu diễn/hiểu đầu vào.
- Decoder-only phù hợp tự nhiên với sinh token kế tiếp.
- Encoder-decoder phù hợp tự nhiên với sinh chuỗi có điều kiện theo đầu vào.
- Mask quyết định luồng thông tin, không chỉ là chi tiết code.
- Theo dõi kích thước tensor qua từng block là kỹ năng gỡ lỗi nền tảng.
- Kiến trúc chỉ là một phần; mục tiêu học, dữ liệu và công thức huấn luyện cũng quyết định hành vi mô hình.
Tài liệu tham khảo
- Devlin et al. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. https://arxiv.org/abs/1810.04805
- Radford et al. Improving Language Understanding by Generative Pre-Training. https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf
- Raffel et al. Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer. JMLR 2020. https://www.jmlr.org/papers/v21/20-074.html
- Vaswani et al. Attention Is All You Need. https://arxiv.org/abs/1706.03762
- PyTorch Transformer building blocks. https://docs.pytorch.org/tutorials/intermediate/transformer_building_blocks.html
- Raschka. Build a Large Language Model (From Scratch). Manning, 2025. https://www.sebastianraschka.com/llms-from-scratch/