Chuyển tới nội dung chính

Positional encoding

Sin và cosDấu vân vị tríKéo để khám phá

Positional encoding

Self-attention nhìn cả câu cùng lúc và không biết từ nào đứng trước từ nào. Ta cộng vào mỗi token một vector sin cos theo vị trí để trả lại thứ tự.

Self-attention tính điểm chú ý giữa mọi cặp token, nhưng phép tính đó là một tổng có trọng số nên đổi chỗ các token không làm kết quả đổi. Nói cách khác, tự thân attention coi câu như một túi từ và bỏ qua thứ tự. Với câu mèo đuổi chuộtchuột đuổi mèo, cùng bộ token mà nghĩa ngược nhau, mô hình cần biết ai đứng trước.

Cách chữa của Transformer rất gọn: với mỗi vị trí ta tạo sẵn một vector cùng độ dài với embedding rồi cộng thẳng vào embedding của token ở vị trí đó. Vector này không học mà tính bằng công thức sin và cos: chiều chẵn dùng sin, chiều lẻ dùng cos, và tần số giảm dần khi chỉ số chiều tăng. Nhờ vậy mỗi vị trí mang một dấu vân số riêng, và mô hình đọc được token này đứng thứ mấy.

Thử ngay

Positional encoding · cho mô hình biết thứ tự
vị trí 4mã[0..3] = [-0.76, -0.65, 0.95, 0.30]cos(4, 5) = 0.94mã rất gần
âmdương02456810121416182002468101214chiều →

Thử điều này:

  • Kéo dọc trên bản đồ để đổi Vị trí, xem hàng sáng lên di chuyển và dải thanh bên dưới đổi hình theo.
  • Nhìn theo chiều cột: cột bên trái đổi màu liên tục qua từng hàng (tần số cao), cột bên phải cả chục hàng gần như cùng màu (tần số thấp).
  • Đặt Vị trí so sánh ngay cạnh vị trí đang chọn, ví dụ 45: cosine hiện 0,94, ứng với góc 20,7°. Hai mã gần nhau chứ chưa trùng.
  • Bây giờ thử mọi cặp liền kề khác, 01, rồi 910, rồi 1920: cosine vẫn ra đúng 0,94 ấy. Giá trị này chỉ phụ thuộc độ lệch giữa hai vị trí, không phụ thuộc chúng đứng ở chỗ nào trong câu.
  • Kéo hai vị trí ra thật xa, ví dụ 218, cosine tụt xuống 0,53. Nhưng đừng đọc thành càng xa càng nhỏ: nó chạm đáy 0,46 ở độ lệch 10 rồi ngoi lên 0,80 ở độ lệch 19.

Vì sao sin và cos

Mỗi cặp chiều (2k, 2k+1) dùng chung một tần số nhưng một bên là sin một bên là cos, nên cùng nhau chúng vẽ ra một điểm chạy trên vòng tròn khi vị trí tăng. Vì các cặp có tần số giảm dần theo hàm mũ, cặp quay nhanh phân biệt các vị trí sát nhau còn cặp quay chậm phân biệt các vị trí cách xa, giống kim giây và kim giờ cùng chỉ một thời điểm. Chính bộ đồng hồ nhiều tốc độ này khiến mỗi vị trí có một tổ hợp giá trị không trùng ai, và hai vị trí gần nhau thì các kim lệch rất ít nên mã của chúng cũng gần nhau.

Cách nhìn theo cặp giải thích luôn con số lạ ở trên. Tích vô hướng của hai mã là tổng đóng góp của từng cặp, mà mỗi cặp góp đúng cos của hiệu hai góc quay, tức một đại lượng chỉ phụ thuộc độ lệch vị trí. Chuẩn của mọi vector mã lại bằng nhau, vì mỗi cặp luôn góp sin² + cos² bằng 1, nên với 16 chiều thì mã nào cũng dài đúng √8. Chia hai thứ đó cho nhau, cosine giữa vị trí pp + Δ là một hàm chỉ của Δ: mọi cặp liền kề trên bản đồ đều cho 0,935646, không lệch tới chữ số thứ mười hai.

Điều rút ra

Positional encoding là một dãy đồng hồ sin cos nhiều tốc độ, gắn cho mỗi vị trí một dấu vân riêng để attention vốn mù thứ tự đọc lại được ai đứng trước ai.

Câu hỏi tự kiểm0/3 đúngchưa trả lời
  1. 1Vì sao Transformer cần cộng thêm positional encoding vào embedding của token?
  2. 2Đọc bản đồ theo chiều cột, cột ứng với chiều có chỉ số nhỏ trông thế nào so với cột chỉ số lớn?
  3. 3Trong sim, cosine giữa mã của hai vị trí sát nhau như 4 và 5 phụ thuộc vào cái gì?