Transformer và cơ chế Attention
Từ query–key–value đến masked self-attention và các giới hạn của phép tổng hợp theo trọng số.
Attention tạo biểu diễn của một vị trí bằng cách kết hợp thông tin từ các vị trí khác theo trọng số phụ thuộc dữ liệu. Transformer kết hợp attention với các khối khác; chỉ nhìn một ma trận attention chưa mô tả hết mô hình.
Mục tiêu học tập
- Giải thích Q, K, V và trục softmax.
- Phân biệt self-attention, cross-attention và causal mask.
- Theo dõi shape và chi phí attention cơ bản.
Truy vấn và thông tin được đọc
Hãy nghĩ query như điều một vị trí đang cần, key như nhãn để tìm phần liên quan và value như nội dung được đọc. Một query có thể phối hợp nhiều phần thay vì chỉ chọn một phần. Đây là ẩn dụ về phép toán, không phải ba đoạn văn được lưu nguyên trong mô hình.
Q, K và V thường là các phép chiếu học được từ hidden states. Với self-attention, chúng xuất phát từ cùng chuỗi; cross-attention có query từ một nguồn và key/value từ nguồn khác. Mỗi query tạo trọng số trên các key, rồi cộng các value theo trọng số.
Trong một head, nếu Q có Tq hàng và K có Tk hàng, scores có shape Tq×Tk. V có Tk hàng, nên output có Tq hàng. Nhầm trục softmax làm phép đọc thông tin sai dù code vẫn chạy.
Scaled dot-product attention: M là additive mask nếu dùng; softmax áp dụng theo chiều key. Hệ số scale giúp kiểm soát độ lớn dot product theo giả định của thiết kế.
Không cộng mask Boolean như số 0/1 nếu API cần additive mask có −∞ tại vị trí cấm. Convention giữa thư viện có thể khác; kiểm tra bằng một ví dụ số nhỏ trước khi batch hóa.
Attention trong một Transformer block
Sau khi trao đổi thông tin giữa các vị trí, mỗi vị trí còn được xử lý bởi một mạng nhỏ. Các đường residual giúp giữ và kết hợp thông tin cũ. Vị trí của token cũng cần được biểu diễn, vì thứ tự từ có thể đổi nghĩa câu.
Một block thường gồm multi-head attention, feed-forward network, residual connections và normalization. Positional information có thể được đưa vào bằng nhiều cách. Encoder và decoder có pattern mask khác nhau; decoder autoregressive ngăn đọc token tương lai.
Multi-head cho phép học nhiều phép chiếu; không bảo đảm từng head có một ý nghĩa ngôn ngữ dễ đặt tên. Pre-norm và post-norm là hai cách sắp xếp khác nhau, không nên trộn công thức mà bỏ normalization.
Dense self-attention tạo ma trận T×T nên chi phí attention cơ bản tăng bậc hai theo chiều dài chuỗi, ngoài chi phí projection và FFN. KV caching trong autoregressive decoding tái sử dụng key/value quá khứ nhưng vẫn tốn bộ nhớ và đọc context.
Thuật toán attention tối ưu có thể tránh materialize toàn ma trận hoặc giảm IO; không vì vậy mà mọi cấu hình dense attention tự có chi phí tuyến tính. Báo cụ thể phép đo và phương pháp.
Một query, hai key và hai value
Mã tạo hai score rồi chuyển thành hai trọng số có tổng bằng 1. Output nằm giữa hai vector value trong ví dụ này. Thay query sẽ đổi phần thông tin được ưu tiên, dù các value không đổi.
Trừ score lớn nhất trước exp để softmax ổn định số hơn. Mã chỉ một query và một head, chưa có learned projections, mask, dropout hay batch. Vì thế nó kiểm tra cơ chế weighted sum chứ chưa phải Transformer hoàn chỉnh.
Attention weights không tự là giải thích nhân quả về prediction: output còn qua value projections, residual và nhiều tầng. Để kiểm tra một yếu tố có cần thiết, cần intervention hoặc ablation với protocol rõ, không chỉ chọn heatmap đẹp.
Workflow & kiến trúc
Ứng dụng & giới hạn
- Đọc cơ chế xử lý chuỗi trong mô hình ngôn ngữ.
- Kiểm tra shapes hoặc masks trong implementation attention.
Điểm mạnh
Tạo tương tác phụ thuộc context giữa các vị trí mà không cần recurrence theo từng bước trong training.
Giới hạn cần nhớ
Dense attention dài tốn tài nguyên; attention visualization không tự chứng minh cơ chế suy luận hoặc factual correctness.
Thử trong một project nhỏ
Đổi query thành [0,1] và dự đoán weight nào tăng. Sau đó tự đặt mask chặn key thứ hai; giải thích vì sao mask phải áp dụng trước softmax.
from math import exp, sqrt
q = [1.0, 0.0]
keys = [[1.0, 0.0], [0.0, 1.0]]
values = [[2.0, 0.0], [0.0, 4.0]]
scores = [sum(a*b for a,b in zip(q,k)) / sqrt(len(q)) for k in keys]
m = max(scores)
weights = [exp(s-m) for s in scores]
weights = [w/sum(weights) for w in weights]
output = [sum(weights[i]*values[i][j] for i in range(2)) for j in range(2)]
assert abs(sum(weights) - 1.0) < 1e-12
assert weights[0] > weights[1]
print(weights, output)Single-head attention với số tự chọn; chưa có training, mask, batch hoặc Transformer block.
