Cơ chế Attention

Bài 6/730 phút

Đọc câu "Con mèo ngồi trên tấm thảm vì nó mệt", ta biết "nó" là con mèo. Attention cho mô hình khả năng đó: mỗi token nhìn mọi token khác và tự quyết định nên chú ý vào đâu.

Mỗi token tạo ra ba vector (bằng phép nhân ma trận học được):

  • Query (Q) — "mình đang tìm thông tin gì?"
  • Key (K) — "mình chứa thông tin gì?"
  • Value (V) — "thông tin mình đưa ra"

Độ hợp nhau giữa token i và j là tích vô hướng qᵢ·kⱼ. Softmax biến các điểm thành trọng số, đầu ra là trung bình có trọng số của V:

Attention(Q, K, V) = softmax(Q Kᵀ / √d) V

attention.py
def attention(Q, K, V):
    d = Q.shape[-1]
    scores = Q @ K.T / np.sqrt(d)           # (n, m): token i chấm điểm token j
    weights = softmax(scores)                # mỗi hàng tổng = 1
    return weights @ V                       # (n, d_v)

Vì sao chia √d? Tích vô hướng của hai vector d chiều có độ lớn tăng theo √d. Điểm quá lớn làm softmax gần như one-hot → gradient gần 0, mô hình khó học. Chia √d giữ phương sai của điểm ổn định.

Mặt nạ nhân quả (causal mask): mô hình sinh văn bản như GPT dự đoán token tiếp theo, nên token ở vị trí t không được nhìn tương lai. Ta đặt điểm của mọi cặp (i, j > i) thành −∞ trước softmax → trọng số tương ứng bằng 0.

Self-attention: Q, K, V đều sinh từ cùng một chuỗi X (Q = XWq, K = XWk, V = XWv). Cross-attention (trong dịch máy): Q từ câu đích, K và V từ câu nguồn.

?Trong causal self-attention với 4 token, token thứ 2 (đếm từ 1) được chú ý tới bao nhiêu token?