L2 · Operator graph
Mô hình transformer biến token thành dự đoán như thế nào
Theo dõi token qua một lớp Transformer để hiểu cách mô hình lấy thông tin từ ngữ cảnh, tạo điểm dự đoán và dùng lại KV cache khi sinh tiếp.
1Định nghĩa
Transformer là mạng nơ-ron biến chuỗi vector biểu diễn token thành các vector đã kết hợp thông tin ngữ cảnh. Trong mô hình sinh văn bản của bài này, mã token từ tokenizer được đổi thành vector, đi qua các lớp Transformer, rồi được LM head chấm điểm trên bảng từ vựng. Hãy phân biệt hai việc: mạng tính điểm cho các token ứng viên; bước chọn token quyết định lấy token nào từ những điểm đó.
Một lớp có hai công việc chính: attention lấy thông tin từ các vị trí được phép nhìn, còn FFN biến đổi riêng vector tại từng vị trí. Chuẩn hóa và residual bao quanh hai nhánh để điều chỉnh biên độ và cộng phần cập nhật vào thông tin cũ. Với decoder causal, mặt nạ nhân quả ngăn vị trí trước đọc vị trí sau. Sau bài học, bạn cần theo được đường đi này trên hình và giải thích vì sao cùng weights có thể xử lý cả prompt hoặc chỉ token mới với KV cache.
Ví dụ đời thường: Hãy hình dung một nhóm biên tập sửa bản thảo qua nhiều vòng. Ở mỗi vòng, một biên tập viên đối chiếu đoạn mình phụ trách với những đoạn được phép đọc, rồi tự sửa đoạn đó; attention tương tự bước đối chiếu, FFN tương tự bước xử lý riêng. Residual giữ bản hiện có để cộng thêm phần sửa. Ví dụ này giúp nhớ hai công việc khác nhau; mạng thực tế chỉ tính trên vector số, không có người đọc hay chuyên gia hiểu câu chữ bên trong từng head.
2Luồng
Cách đọc hình: bắt đầu từ Hidden State ở góc dưới cột 1, đi lên Q/K/V, theo các mũi tên sang attention ở cột 2 và đi lên đầu ra ở cột 4. Cột 3 là nhánh cấp K/V cho attention, không phải công đoạn chỉ bắt đầu sau cột 2. Các mục MHA/GQA/MQA/MLA và Dense/MoE là lựa chọn kiến trúc, không phải các bước phải chạy nối tiếp. Lab bên dưới chọn MHA và Dense SwiGLU.
3Giải pháp
Bắt đầu từ câu hỏi: một token cần biết những gì để dự đoán token tiếp theo? Mã số tự nó chưa đủ. Bảng embedding đổi mã thành vector; ở mỗi lớp, vector đó được chuẩn hóa rồi chiếu thành Q, K và V. Q/K dùng để đối chiếu độ liên quan, V mang nội dung cần gom. Trong kiến trúc minh họa, RoPE xoay Q/K theo vị trí, giúp phép đối chiếu phân biệt trật tự token.
Tiếp theo, hãy theo đường từ 2B đến 2E trên hình. Tích Q với K tạo điểm liên quan, nhưng điểm chưa cho biết nên lấy bao nhiêu thông tin. Causal mask chặn các vị trí tương lai; softmax đổi điểm hợp lệ thành trọng số có tổng bằng 1; nhân trọng số với V mới tạo ra thông tin ngữ cảnh. Đừng nhầm softmax này với phân phối chọn token đầu ra: nó phân bổ trọng số trên các vị trí đầu vào.
Ở cột 3, đặt hai câu hỏi riêng. MHA/GQA/MQA trả lời mỗi Q head dùng bộ K/V nào; KV cache trả lời có thể giữ lại K/V của token nào để khỏi tính lại. Lab chọn MHA, tức mỗi Q head có K/V riêng. Khi sinh tiếp, cache giữ K/V token cũ, còn token mới vẫn phải đi qua attention và FFN. Cột này cấp dữ liệu cho attention, không phải một lớp xử lý đứng sau attention.
Cuối lớp, kết quả các head được ghép và chiếu qua W_O, rồi cộng vào vector đầu vào. Một nhánh chuẩn hóa–FFN–residual tiếp tục cập nhật từng vector. Nếu còn lớp, kết quả đi vào lớp kế; chỉ sau lớp cuối mới chuẩn hóa lần cuối và đưa qua LM head để tạo logits. Sơ đồ có nhánh Dense hoặc MoE; hãy theo nhánh Dense SwiGLU trong lab, không đọc hai lựa chọn này như hai bước nối tiếp.
Khi đã hiểu đường tính, mới xét cách chạy nhanh. Kernel có thể gộp các phép toán và giảm đọc/ghi bộ nhớ mà vẫn giữ kết quả trong sai số cho phép. Ngược lại, thay MHA bằng GQA hoặc Dense bằng MoE là thay cấu trúc model; không thể coi đó chỉ là bật một tùy chọn runtime cho checkpoint bất kỳ.
Để so trọng số attention trên các vị trí với logits trên toàn bộ từ vựng bằng số thật, hãy chạy khối 5 (Transformer × N layers) trong Bài Lab tổng hợp.
4Profiling
- Kiểm tra dữ liệu có đi đúng đường không
Trước khi đo nhanh/chậm, hãy đọc kích thước: ba token, vector bốn số phải tạo đầu vào (3, 4); LM head với sáu token ứng viên phải tạo logits (3, 6). Nếu kích thước sai, quay lại chỗ ghép heads hoặc phép chiếu, không cố giải thích ý nghĩa bảng số sai.
- Kiểm tra token có nhìn trộm tương lai không
Quan sát hàng đầu của trọng số attention: nó chỉ được có trọng số tại chính vị trí đầu. Sau đó thay token cuối và so logits của các vị trí trước. Giữ nguyên weights và các token còn lại; nếu logits trước thay đổi ngoài sai số, kiểm tra mask và vị trí trước khi kết luận model hoạt động đúng.
- Kiểm tra dùng cache có giữ kết quả không
Chạy cùng chuỗi bằng hai đường: tính lại toàn chuỗi và chỉ đưa token mới qua mạng với cache. So hàng logits cuối bằng độ lệch tuyệt đối lớn nhất; lab yêu cầu không vượt 1e-9. Đồng thời kiểm tra prefix cache không bị sửa. Một kết quả khớp xác nhận trường hợp đã thử, không thay cho mọi kiểm thử của model production.
- Chỉ đo tốc độ khi đã giữ cố định điều kiện chạy
Nếu chuyển sang checkpoint thật, đo riêng prefill và decode, ghi độ dài prompt, số token sinh, batch, kiểu số và thiết bị. Lab NumPy này không có benchmark GPU và không đưa ra mức tăng tốc. Cache giảm phần tính lại K/V cũ nhưng attention của token mới vẫn phải đọc thông tin quá khứ; chi phí không biến mất.
5Ví dụ
Cùng một token, ngữ cảnh khác nhau
Giả sử hai chuỗi có cùng token ở vị trí cuối nhưng phần trước khác nhau. Embedding của token cuối giống nhau, nhưng attention được phép đọc các token trước khác nhau nên trạng thái cuối và logits có thể khác. Điều cần nhớ là biểu diễn có ngữ cảnh không chỉ phụ thuộc mã token tại chính vị trí đó.
Xử lý prompt rồi sinh tiếp
Prefill xử lý ba mã [1, 2, 3], tạo ba hàng logits và K/V cho ba vị trí. Hàng logits cuối được dùng để chọn token tiếp theo. Token vừa chọn được đưa vào lượt decode với cache ba vị trí; mạng nối K/V của nó, tạo một hàng logits mới để chọn token sau nữa. Tách rõ chọn token và xử lý token sẽ giúp bạn tránh đếm nhầm số vị trí trong cache.
Huấn luyện khác thực hành này ở đâu?
Khi huấn luyện dự đoán token kế tiếp, logits tại mỗi vị trí được so với nhãn của token sau vị trí đó để tính loss; lan truyền ngược và optimizer mới cập nhật weights. Lab ở cuối trang chỉ chạy forward và kiểm tra tính nhất quán. Việc in PASS không có nghĩa là weights đã học hay mô hình dự đoán đúng từ tiếp theo trong văn bản thật.
6Thuật ngữ
- Hidden state — trạng thái ẩn
- Vector biểu diễn một vị trí ở một thời điểm trong mạng. Đầu lớp nó nhận thông tin từ lớp trước; cuối lớp nó đã được cập nhật bằng attention và FFN.
- Attention head — đầu chú ý
- Một nhánh Q/K/V tạo trọng số và gom thông tin từ các vị trí được phép nhìn. Nhiều head có tham số riêng; không mặc định gán mỗi head cho một nhiệm vụ ngôn ngữ cố định.
- MHA — Multi-Head Attention
- Cách tổ chức attention mà mỗi Q head có K/V riêng. Trong lab có hai head; Q0 dùng K0/V0 và Q1 dùng K1/V1, không dùng chung K/V giữa hai head.
- Residual connection — đường cộng tắt
- Giữ đầu vào của một nhánh rồi cộng với kết quả xử lý. Hãy đọc x + Attention(x) như giữ thông tin cũ và bổ sung phần cập nhật, không phải thay toàn bộ x.
- LM head — đầu ra bảng từ vựng
- Phép chiếu trạng thái ẩn cuối thành một điểm cho mỗi token ứng viên. Nó tạo logits; chọn token từ các điểm này là bước tiếp theo, không phải chính phép chiếu.
Glossary (10)
- Token ID và embedding
- Token ID là số dùng để tra bảng; embedding là vector lấy từ hàng tương ứng trong bảng đó. Hai token có ID gần nhau không vì thế mà có nghĩa gần nhau.
- Query / Key / Value — Q/K/V
- Ba phép chiếu từ vector đã chuẩn hóa. Q và K được so sánh để tạo trọng số; V là nội dung đem gom theo trọng số. Chúng là các vector số, không phải ba câu văn.
- RoPE
- Phép xoay Q và K theo vị trí token, giúp điểm Q·K phản ánh khoảng cách tương đối. V không xoay trong lab; vị trí token mới phải tiếp tục từ độ dài cache, không quay về 0.
- RMSNorm
- Chuẩn hóa biên độ một vector theo căn trung bình bình phương các phần tử. Lab dùng bản không có hệ số học được; mục đích là quan sát luồng tính, không tái tạo đầy đủ checkpoint thật.
- Causal mask — mặt nạ nhân quả
- Quy tắc vị trí i chỉ nhìn vị trí j không lớn hơn i. Lab đặt điểm vị trí tương lai thành âm vô cực trước softmax, khiến trọng số ở đó bằng 0.
- Logits
- Điểm số chưa chuẩn hóa trên bảng từ vựng, không phải xác suất. Đọc hàng cuối để biết điểm cho token đi sau toàn bộ chuỗi đầu vào.
- KV cache
- K/V của các token đã xử lý được giữ lại để dùng ở lượt sau. MHA quyết định head nào có bộ K/V nào; cache quyết định dữ liệu token cũ nào được tái sử dụng.
- Prefill và decode
- Prefill xử lý chuỗi prompt ban đầu. Trong mỗi lượt decode của lab, token vừa chọn được đưa lại vào mạng để tính điểm cho token tiếp theo, đồng thời nối K/V mới vào cache.
- Dense SwiGLU
- FFN dùng một bộ trọng số chung tại mọi vị trí; một nhánh có cổng điều tiết nhánh còn lại. Nó xử lý từng vector riêng, không tự trao đổi thông tin giữa các vị trí như attention.
- Forward pass và weights
- Forward tính đầu ra bằng bộ tham số hiện có, không tự cập nhật tham số. Trong lab weights là số ngẫu nhiên cố định; cần huấn luyện mới học được khả năng ngôn ngữ.
7Bài liên quan
8Nguồn
9Bài lab
Theo dõi ba token đi qua một lớp Transformer
Thực hành NumPy · quan sát cơ chế, không huấn luyện mô hìnhỞ section 2, bạn đã thấy các khối của một lớp Transformer. Bây giờ hãy theo dõi dữ liệu thật đi qua chúng: từ ba mã token đến bảng điểm dự đoán, rồi xử lý thêm một token bằng KV cache. Bạn không cần nhớ hết công thức trước khi chạy; mỗi bước sẽ chỉ ra nên quan sát gì và kết quả có ý nghĩa gì.
Bạn sẽ học được gì?
Sau bài này, bạn cần tự giải thích được ba việc: token lấy thông tin từ đâu; vector sau một lớp được đổi thành điểm dự đoán như thế nào; vì sao có thể dùng lại K/V của token cũ khi xử lý token mới.
Bạn sẽ nối được mỗi kết quả in ra với một vùng 1A–4C trên hình, thay vì chỉ nhớ tên các khối. Hãy đọc lời hướng dẫn trước mỗi bảng số rồi đối chiếu vùng tương ứng.
Đầu vào của bài lab
Đầu vào là DEMO_PROMPT = [1, 2, 3]. Đây là ba mã token giả lập, coi như đã qua tokenizer; chúng không gắn với ba từ tiếng Việt cụ thể. Bảng từ vựng có sáu mã, từ 0 đến 5. Không cần tải dữ liệu hay nhập API key.
Mỗi mã được tra thành vector bốn số. Vì có ba vị trí, bảng vector đầu vào có ba hàng và bốn cột, viết là (3, 4). Khi gặp shape trong output, hãy đọc các con số như số hàng/cột hoặc số head, đừng coi chúng là công thức mới.
Mô hình bạn đang sử dụng
Lab chọn MHA: mỗi Q head có K/V riêng. Có hai head, Q0 dùng K0/V0 và Q1 dùng K1/V1. Mỗi vector head có hai số (d_head = 2); ghép hai head lại được bốn số. MHA trả lời ai dùng bộ K/V nào; tái sử dụng cache trả lời dữ liệu token cũ nào không cần tính lại.
Q/K nhận thông tin vị trí bằng RoPE. Sau attention, lab dùng FFN Dense SwiGLU, không dùng MoE. GQA/MQA/MLA là các lựa chọn khác trên hình, không chạy trong lab này. Mô hình chỉ có một lớp và chưa được huấn luyện: bạn đang kiểm tra cơ chế tính toán, không đánh giá chất lượng sinh văn bản.
KV Cache theo MHA ở đây là mảng NumPy lưu K đã xoay RoPE và V chưa xoay. Hình vẽ minh họa cả HBM/phân trang của hệ thống lớn; lab không có HBM thật, bộ cấp phát phân trang hay GPU.
Cách thực hiện và đọc output
1. Giữ nguyên code và bấm Chạy cell. Lượt đầu xử lý cả ba token được gọi là prefill. Ở 1A–1B, so vector trước/sau chuẩn hóa và trước/sau RoPE để thấy mã token đã trở thành dữ liệu attention như thế nào.
2. Ở 2A–2E, đọc hàng đầu của bảng trọng số head 0. Bạn sẽ thấy [1, 0, 0]: vị trí đầu chỉ nhìn chính nó. Đọc tiếp hàng cuối để thấy thông tin được lấy từ các vị trí hợp lệ theo những trọng số nào. Đây là trọng số trên vị trí đầu vào, không phải xác suất chọn từ trong bảng từ vựng.
3. Ở 3A–3B, xác định bộ K/V riêng của từng head. Cache có shape (2, 3, 2): hai head, ba token, mỗi vector hai số. Nhánh này cung cấp K/V cho attention, nên output in 3A/3B trước 2A–2E dù cột 3 nằm bên phải trong hình.
4. Ở 4A–4C, theo dõi vector được bổ sung qua hai đường residual, rồi đọc hàng cuối bảng logits. Logits là điểm số, không phải xác suất. Lab chọn mã có điểm cao nhất chỉ để tạo token đầu vào cho lượt tiếp.
5. Đọc lượt decode: token vừa chọn đi lại qua một lớp, lần này dùng cache đã có. Cache thành (2, 4, 2); ba vị trí cũ giữ nguyên, chỉ nối thêm một vị trí. Bảng logits mới có một hàng, dùng để dự đoán token sau token vừa xử lý.
Kết quả này chứng tỏ điều gì?
Kiểm tra causal thay token cuối rồi so hai hàng logits trước nó. Hai hàng không đổi cho thấy dữ liệu tương lai không lọt vào các vị trí trước trong demo này. Tổng mỗi hàng trọng số bằng 1 và các ô tương lai bằng 0 xác nhận bước chuẩn hóa/che mặt nạ làm đúng điều ta vừa quan sát.
Kiểm tra cache chạy hai cách với cùng weights và cùng chuỗi: chỉ xử lý token mới bằng cache, hoặc tính lại cả chuỗi. Sai khác logits không vượt 1e-9 cho thấy cách tái sử dụng cache giữ kết quả trong ngưỡng kiểm tra. Đây không phải phép đo tốc độ, cũng không chứng tỏ mô hình hiểu ngôn ngữ.
Kết quả mong đợiBạn sẽ thấy bảng logits kích thước (3, 6): ba hàng ứng với ba vị trí đầu vào, sáu cột ứng với sáu token ứng viên. Đọc hàng cuối để xem điểm cho token đi tiếp sau toàn bộ prompt. Sau đó lab xử lý token vừa chọn, so kết quả dùng cache với tính lại toàn chuỗi và in kết luận kiểm tra.
Bài tập 1 · Token tương lai có làm đổi quá khứ không?
Trước khi chạy, dự đoán hàng logits nào được phép đổi khi thay token cuối của [1, 2, 3] thành 4. Trong code, tìm TRY_PROMPT và đặt [1, 2, 4], rồi chạy lại. Đọc phần THỬ NGHIỆM ở cuối output.
Đối chiếu sau khi tự trả lời
Hai hàng đầu phải giữ nguyên trong sai số; hàng cuối được phép đổi. Vì causal mask chặn nhìn tương lai, vị trí 0 và 1 không đọc token ở vị trí 2. Nếu đổi token đầu, cả ba hàng đều có thể đổi vì cả ba vị trí được phép đọc nó.
Bài tập 2 · Đọc đúng bảng điểm dự đoán
Ở bước 4C của lượt prefill, hãy tự tìm cột có điểm lớn nhất ở hàng cuối. Cột đó tương ứng mã token nào? Đối chiếu với token demo mà lab chọn và giải thích vì sao không đọc hàng đầu để sinh tiếp toàn bộ prompt.
Đối chiếu sau khi tự trả lời
Chỉ số cột lớn nhất là mã token được chọn bằng argmax trong lab. Hàng đầu chỉ dùng thông tin tới vị trí đầu; hàng cuối dùng cả ba token hợp lệ nên cho điểm của token đi sau toàn bộ prompt. Điểm lớn nhất không có nghĩa là từ đó đúng về ngôn ngữ vì weights chưa học.
Bài tập 3 · MHA và KV cache giải quyết hai việc gì?
Không chạy thêm code, hãy dự đoán shape cache khi đã xử lý tổng cộng năm token trong cấu hình này. Giải thích vì sao vẫn cần hai bộ K/V dù cache giúp tránh tính lại token cũ.
Đối chiếu sau khi tự trả lời
Mỗi tensor K hoặc V có shape (2, 5, 2): hai head, năm token, mỗi vector hai số. MHA giữ K/V riêng cho từng Q head; cache chỉ giữ lại kết quả của các token đã xử lý, không biến MHA thành GQA hay MQA.