Trọng tâm: Self-attention, embedding vị trí và intuition.
Thời gian: 40 phút đọc, 15 phút viết lại.
Mục tiêu cần hiểu
Nắm kiến trúc tổng thể của Transformer gồm encoder, decoder và các layer lặp lại.
Giải thích được self-attention bằng query, key, value và attention weights.
Hiểu vì sao multi-head attention cho model nhiều cách nhìn quan hệ giữa token.
Biết feed-forward layer đóng vai trò biến đổi biểu diễn sau attention.
Câu hỏi dẫn đường
Self-attention tính “chú ý” giữa các token như thế nào?
Vì sao Transformer cần positional embeddings?
Tôi có thể giải thích attention mà không dùng công thức không?
Ghi chú trong khi đọc
Transformer ban đầu được thiết kế cho các bài toán sequence-to-sequence như machine translation: encoder đọc câu nguồn, decoder sinh câu đích từng token.
Sau đó, encoder block và decoder block được tách ra dùng như các kiến trúc độc lập. Vì vậy rất nhiều model Transformer hiện đại có thể gom vào ba nhóm lớn:
Encoder-only: dùng phần encoder để tạo representation giàu ngữ cảnh cho input. Ví dụ BERT, RoBERTa, DistilBERT. Phù hợp với understanding tasks như classification, NER, semantic similarity.
Decoder-only: dùng phần decoder để sinh token tiếp theo theo kiểu autoregressive. Ví dụ GPT. Phù hợp với generation tasks như chat, completion, text generation.
Encoder-decoder: giữ cả encoder và decoder để map từ một sequence sang một sequence khác. Ví dụ T5, BART. Phù hợp với translation, summarization, seq2seq.
Cách phân loại này giúp mình chọn model theo task: nếu cần hiểu input thì nghĩ encoder-only; nếu cần sinh tiếp văn bản thì nghĩ decoder-only; nếu cần biến đổi input thành output sequence khác thì nghĩ encoder-decoder.
Một encoder layer nhận vào một sequence các embeddings rồi đưa chúng qua hai sublayers chính:
Fully connected feed-forward layer: áp dụng cùng một mạng MLP nhỏ lên từng token embedding một cách độc lập.
Mental model của encoder layer: attention là bước “trao đổi thông tin giữa các token”, còn Feed-Forward Layer là bước “xử lý/biến đổi representation của từng token sau khi đã có context”.
Vì feed-forward layer được áp dụng cho từng vị trí riêng biệt nên nó còn được gọi là position-wise feed-forward layer. Nó không tự trộn thông tin giữa các token; việc trộn thông tin đã do self-attention làm trước đó.
Tóm tắt phần The Feed-Forward Layer: sau khi attention đã trộn thông tin giữa các token, feed-forward layer nhận từng contextualized embedding và biến đổi nó bằng một MLP nhỏ. Mỗi token đi qua cùng một mạng, nhưng đi độc lập với các token khác.
Công thức thường gặp:
FFN(x)=W2σ(W1x+b1)+b2
Trong đó W1 thường mở rộng chiều hidden sang một intermediate dimension lớn hơn, activation σ như GELU/ReLU thêm phi tuyến, rồi W2 chiếu về lại hidden size ban đầu.
Ví dụ nếu hidden size là 768, feed-forward layer có thể mở rộng lên 3072 chiều rồi nén lại 768 chiều. Attention quyết định token lấy thông tin từ đâu; feed-forward quyết định biến đổi representation đã có context như thế nào.
Điểm dễ nhầm: feed-forward layer không phải là layer “đọc tiếp sequence”. Nó không biết token bên cạnh nếu không có thông tin đã được attention đưa vào trước đó.
Mỗi sublayer trong encoder không chỉ chạy riêng lẻ mà còn đi kèm skip/residual connection và Layer Normalization. Đây là hai kỹ thuật chuẩn giúp train deep neural networks ổn định hơn.
Skip connection nghĩa là output của sublayer được cộng lại với input ban đầu của chính sublayer đó. Nhờ vậy model không phải học lại toàn bộ representation từ đầu; nó chỉ cần học phần thay đổi cần thêm vào.
Layer normalization chuẩn hóa activation trong một layer để scale ổn định hơn, giúp gradient dễ học hơn khi xếp nhiều encoder layers.
Mental model: mỗi sublayer không “xóa rồi viết lại” representation, mà “chỉnh sửa representation hiện có”, sau đó normalize để giữ tín hiệu ổn định.
Ý tưởng chính của self-attention: thay vì giữ một embedding cố định cho mỗi token, model dùng toàn bộ sequence để tạo embedding mới có ngữ cảnh cho từng token.
Nếu input là các token embeddings x1,...,xn, self-attention tạo ra embeddings mới x1′,...,xn′. Mỗi xi′ là tổ hợp tuyến tính có trọng số của tất cả embeddings ban đầu:
xi′=j=1∑nwjixj
Các hệ số wji là attention weights và được chuẩn hóa để tổng bằng 1. Vì vậy có thể hiểu self-attention như một dạng weighted average của các token embeddings.
Điểm quan trọng không phải là lấy trung bình đều, mà là mỗi token học cách đặt trọng số khác nhau lên các token khác trong câu.
Ví dụ từ flies nếu đứng một mình có thể gợi nghĩa “con ruồi”, nhưng trong câu "time flies like an arrow", context như time và arrow làm rõ flies là động từ. Self-attention tạo representation mới cho flies bằng cách cho các token liên quan trọng số cao hơn.
Embedding mới sinh ra theo cách này gọi là contextualized embedding: cùng một token có thể có vector khác nhau tùy câu/ngữ cảnh.
Để tính attention weights, Transformer dùng scaled dot-product attention:
Project mỗi token embedding thành ba vector: query, key và value.
Tính attention scores bằng dot product giữa query của từng token và key của các token khác.
Với sequence có n tokens, attention scores tạo thành ma trận n×n: mỗi hàng/cột thể hiện mức một token chú ý tới các token còn lại.
Chia scores cho dk để scale, tránh giá trị quá lớn làm softmax bị quá sắc và training kém ổn định.
Đưa scores qua softmax để thành attention weights wji, tức các trọng số không âm và tổng bằng 1.
Nhân attention weights với value vectors v1,...,vn để tạo representation mới.
Công thức gọn:
Attention(Q,K,V)=softmax(dkQKT)V
Ở mức từng token, output mới được tính bằng:
xi′=j∑wjivj
Mental model: query là “tôi đang tìm thông tin gì”, key là “tôi có tín hiệu gì để được chú ý”, value là “nội dung tôi sẽ đóng góp nếu được chú ý”.
Ví dụ trực quan với 3 token time, flies, arrow: giả sử ta đang cập nhật representation cho token flies. Query của flies được so với key của cả 3 token. Nếu model thấy time và arrow giúp giải thích nghĩa của flies, sau softmax attention weights có thể giống như:
time: 0.45
flies: 0.10
arrow: 0.45
Khi đó output mới cho flies là:
xflies′=0.45vtime+0.10vflies+0.45varrow
Các số trên chỉ để minh họa, không phải giá trị thật của model. Ý chính là embedding mới của flies không còn chỉ là embedding cố định của từ flies; nó đã được trộn thêm nhiều thông tin từ time và arrow, nên nghiêng về nghĩa động từ “trôi qua/bay” thay vì nghĩa “con ruồi”.
Multi-Head Attention mở rộng self-attention bằng cách chạy nhiều attention heads song song. Mỗi head có bộ projection query/key/value riêng, nên mỗi head có thể học một kiểu quan hệ khác nhau giữa các token.
Nếu self-attention một head giống một góc nhìn duy nhất, multi-head attention giống nhiều góc nhìn cùng nhìn vào một câu:
một head có thể chú ý quan hệ chủ ngữ - động từ;
một head có thể chú ý đại từ và danh từ mà nó tham chiếu;
một head có thể chú ý token gần nhau;
một head có thể chú ý keyword quan trọng cho classification.
Công thức trực giác:
MultiHead(X)=Concat(head1,...,headm)WO
Mỗi headh tự chạy scaled dot-product attention với Qh, Kh, Vh riêng. Sau đó outputs của các heads được concat lại và project qua WO để trở về hidden size chung.
Ví dụ với câu "The cat sat on the mat because it was tired", khi cập nhật token it, một head có thể chú ý cat, một head chú ý tired, một head chú ý because. Các head không nhất thiết diễn giải được rõ ràng như vậy trong model thật, nhưng đây là mental model tốt: nhiều heads giúp model học nhiều loại quan hệ song song.
Điểm cần nhớ: multi-head attention không chỉ là “attention lớn hơn”; nó là nhiều attention distributions khác nhau cho cùng một token.
Bidirectional Attention xuất hiện khi nói về encoder-only models như BERT, RoBERTa, DistilBERT. Representation của một token được tính từ cả context bên trái và context bên phải của token đó.
Điểm chính: trong encoder self-attention, mỗi token có thể “nhìn” các token khác trong cùng input sequence, không bị giới hạn chỉ nhìn về quá khứ.
Ví dụ với câu "time flies like an arrow", token flies có thể dùng thông tin từ time, like, an, arrow để hiểu nó là động từ. Nếu chỉ nhìn token bên trái, model có ít tín hiệu hơn.
Bidirectional attention phù hợp với các task understanding như text classification, named entity recognition, sentiment analysis, semantic matching, vì toàn bộ input đã có sẵn ngay từ đầu.
Nó khác với causal/autoregressive attention trong decoder-only models như GPT. Ở causal attention, token hiện tại chỉ được nhìn các token trước nó để tránh “ăn gian” token tương lai khi sinh văn bản.
Encoder-only model học representation giàu ngữ cảnh cho từng token. Decoder-only model học cách dự đoán token tiếp theo.
Vì bidirectional attention được nhìn cả hai phía, nó rất mạnh cho việc hiểu câu; nhưng nó không tự nhiên phù hợp để generate từ trái sang phải nếu không thay đổi objective/architecture.
Mental model: bidirectional attention giống đọc cả câu trước khi giải thích từng từ; causal attention giống viết từng từ từ trái sang phải và không được biết trước phần sau.
Viết lại bằng lời của tôi
Transformer gốc sinh ra cho bài toán dịch máy, tức là một dạng sequence-to-sequence: đọc một chuỗi đầu vào rồi sinh một chuỗi đầu ra. Nhưng sau đó người ta nhận ra encoder và decoder đều có giá trị riêng, nên tách chúng thành các family model khác nhau.
Encoder-only giống một bộ đọc hiểu: nó nhìn toàn bộ input và tạo representation tốt cho từng token hoặc cả câu. Decoder-only giống một bộ viết tiếp: nó chỉ nhìn phần đã có và dự đoán token tiếp theo. Encoder-decoder giống một hệ chuyển đổi: encoder hiểu input, decoder sinh output mới dựa trên input đó.
Mental model ngắn: encoder để hiểu, decoder để sinh, encoder-decoder để chuyển đổi chuỗi.
Một encoder layer có thể hiểu như một block gồm hai bước: trước hết multi-head self-attention cho token lấy thông tin từ các token khác; sau đó feed-forward layer xử lý từng token embedding đã được contextualize. Attention trả lời câu hỏi “token này nên lấy thông tin từ đâu?”, còn feed-forward trả lời “sau khi có thông tin đó, nên biến đổi representation này như thế nào?“.
Hai sublayers này thường được bọc bởi skip connection và layer normalization. Skip connection giữ lại input gốc để thông tin/gradient đi qua dễ hơn; layer normalization giữ scale activation ổn định. Nhờ vậy Transformer có thể xếp nhiều encoder layers sâu hơn mà training không quá dễ vỡ.
Self-attention biến fixed token embedding thành contextualized embedding. Với mỗi token, model lấy weighted average của toàn bộ sequence; token nào giúp giải thích nghĩa hiện tại thì có attention weight lớn hơn. Vì vậy cùng một từ như flies có thể có representation khác nhau trong "time flies" và trong câu nói về côn trùng.
Attention weights được tính bằng cách so query của token hiện tại với key của các token khác. Dot product càng lớn thì hai vector càng “khớp”, sau softmax token đó nhận trọng số cao hơn. Cuối cùng model lấy tổng có trọng số của value vectors để tạo embedding mới.
Multi-head attention cho model nhiều attention patterns song song. Thay vì bắt một head duy nhất phải học mọi quan hệ, Transformer chia hidden dimension thành nhiều heads nhỏ hơn; mỗi head tự tính Q/K/V, tự tạo attention weights, rồi các output được nối lại. Vì vậy cùng một token có thể vừa chú ý quan hệ ngữ pháp, vừa chú ý coreference, vừa giữ local context.
Feed-forward layer là bước MLP position-wise sau attention. Nó thường có dạng linear → activation → linear: mở rộng hidden dimension, áp dụng phi tuyến, rồi chiếu về lại hidden size. Nếu attention là bước “lấy context từ token khác”, feed-forward là bước “tái xử lý representation của từng token sau khi đã có context”.
Bidirectional attention nghĩa là khi model tạo representation cho một token, nó không chỉ dựa vào những token đứng trước mà còn dùng cả những token đứng sau. Trong BERT/DistilBERT, input đã có đầy đủ, nên model có quyền đọc toàn câu trước khi quyết định ý nghĩa của từng token.
Điều này rất hợp với bài toán hiểu ngôn ngữ. Khi phân loại cảm xúc, nhận diện thực thể, hoặc hiểu nghĩa một từ đa nghĩa, thông tin phía sau token có thể quan trọng ngang hoặc hơn thông tin phía trước.
Causal attention thì ngược lại: nó che phần tương lai để model chỉ nhìn quá khứ. Cách đó cần cho text generation vì khi sinh token tiếp theo, model không được biết các token chưa sinh.
Tóm lại, bidirectional attention tối ưu cho hiểu context đầy đủ, còn causal attention tối ưu cho sinh chuỗi từng bước.
Điều chưa rõ
Bidirectional attention được triển khai bằng attention mask như thế nào trong encoder-only models?
Khi fine-tune BERT cho classification, [CLS] token có dùng bidirectional context của toàn bộ câu không?
Encoder-decoder models dùng attention mask khác nhau thế nào giữa encoder self-attention, decoder causal self-attention và cross-attention?
Thứ tự chính xác giữa residual connection và layer normalization trong các biến thể Transformer khác nhau có giống nhau không?
Tại sao query/key/value cần là ba projection khác nhau thay vì dùng cùng một embedding ban đầu?