localaiforum
Đăng nhập
Hướng dẫn › Kiến thức nền tảng

Bên trong transformer

Mọi thứ bạn có thể chạy cục bộ đều là transformer, và kiến trúc này vừa vẹn trên một tờ khăn ăn: biến token thành vector, đẩy chúng qua N tầng giống hệt nhau nơi các token nhìn nhau, chiếu vector cuối cùng trở lại thành điểm số trên từ vựng. Không cần vi tích phân — tích vô hướng và một softmax gánh cả buổi diễn. Trang này đi qua con đường ấy một lần, chậm rãi.

Residual stream

Hãy hình dung một băng chuyền chạy xuyên qua mô hình. Tại mỗi tầng, các mô-đun con đọc băng và cộng phần đóng góp của mình trở lại lên đó — không gì bị thay thế, mọi thứ được tích lũy:

x = embed(token_ids) + positions      # token trở thành vector (dim ~4k)
for layer in range(N):                # N ≈ 32 với mô hình 8B
    x = x + attention(x)              # các token trao đổi thông tin
    x = x + ffn(x)                    # mỗi token tự biến đổi chính nó
logits = unembed(x[-1])               # vị trí cuối → điểm cho mỗi mục từ vựng
p = softmax(logits)                   # xác suất cho mọi token kế tiếp
  • Embedding: mỗi ID token đánh chỉ mục vào một bảng vector đã học. Thông tin vị trí được trộn vào (rotary embedding trong các mô hình hiện đại), nên "chó cắn người" khác với "người cắn chó".
  • Các tầng giống hệt nhau về hình dạng, khác nhau về nội dung. Tầng sớm xử lý cú pháp và mẫu bề mặt; tầng sâu hơn mang ý nghĩa, sự kiện và hành vi tác vụ.
  • Unembedding: vector cuối cùng được so với mọi mục trong từ vựng; softmax biến điểm số thành xác suất. Việc lấy mẫu chọn ra một token (lấy mẫu).

Self-attention với bốn token

Cơ chế trao đổi. Vector của mỗi token sinh ra ba vector phái sinh: một query (tôi đang tìm gì), một key (tôi quảng bá gì), và một value (tôi bàn giao gì nếu được chọn). Câu: "The cat sat on". Vị trí của "sat" nên kéo về những gì?

token:          The     cat     sat     on
q·k scores:     1.2     4.1     3.0     0.4      (tích vô hướng, minh họa)
softmax →        0.05    0.60    0.31   0.04     (các trọng số cộng lại bằng 1.0)

output("sat") = 0.05·v(The) + 0.60·v(cat) + 0.31·v(sat) + 0.04·v(on)

"sat" chú ý chủ yếu đến "cat" — chủ ngữ mà nó cần. Mọi vị trí chạy điều này đồng thời. Một ràng buộc biến nó thành mô hình ngôn ngữ: mặt nạ nhân quả — mỗi token chỉ được nhìn các token trước đó, không bao giờ token sau, nhờ đó một lượt đi huấn luyện mọi dự đoán token-kế-tiếp trong chuỗi cùng lúc.

Đó là toàn bộ bộ công cụ toán học: điểm tương đồng (tích vô hướng), được chuẩn hóa thành một hỗn hợp (softmax), trên các vector value.

Dưới dạng công thức, một đầu attention tại một vị trí:

  1. Tính vector query, key và value cho mọi token.
  2. Lấy tích vô hướng của query với key của mỗi token trước đó; thu nhỏ theo √(head_dim).
  3. Softmax các điểm số thành trọng số có tổng bằng 1.
  4. Xuất ra tổng có trọng số của các value của những token ấy.
  5. Nối đầu ra của mọi đầu attention rồi chiếu — đó là phần đóng góp attention của tầng.

Multi-head: các mẫu song song

Một đầu = một bộ ba query/key/value = một loại quan hệ mà nó có thể diễn đạt (chủ ngữ↔động từ, tính từ↔danh từ, đồng tham chiếu). Các tầng chạy nhiều đầu song song (ví dụ 32) trên những lát chiều-thấp hơn và nối kết quả lại. Nhiều đầu nghĩa là nhiều loại quan hệ mỗi tầng — rộng về mẫu hình, không phải sâu về tư duy.

  • Các đầu được cố định lúc huấn luyện; "suy nghĩ" chéo các vị trí chính là thứ attention ghi ngược trở lại residual stream.
  • Chiều đầu (ví dụ 128) × số đầu (ví dụ 32) = chiều ẩn (4096): các đầu là những lát song song của cùng một băng chuyền, không phải các mô hình riêng biệt.

FFN: nơi các tham số cư trú

Nửa sau của mỗi tầng là một mạng hai ma trận áp dụng lên từng token độc lập: giãn vector (~4×), phi tuyến, chiếu ngược lại. Trong một mô hình dense điển hình, khoảng hai phần ba số tham số cư trú ở đây, chứ không phải trong attention. Trực giác hữu ích: bộ nhớ khóa-giá-trị — ma trận thứ nhất giữ các mẫu cần phát hiện, ma trận thứ hai giữ thứ cần cộng thêm lên băng khi một mẫu khớp. Phần lớn thứ người ta gọi là "sự thật của mô hình" được lưu trong trọng số FFN (xem tham số).

Thành phần Tỉ lệ tham số (dense 7–9B điển hình)
Attention (Q, K, V, O) ~10–15%
FFN ~60–70%
Embedding + đầu ra ~10–25% (tăng theo kích thước từ vựng)

Tự đếm tham số

Model card công bố năm con số; nhân chúng lại là ra số tham số. Với một mô hình mở thực tế hạng 8B (32 tầng, chiều ẩn 4096, 32 đầu với 8 đầu KV, chiều FFN 14336, từ vựng ~128k):

attention/layer:  q: 4096×4096 + k,v: 2×(4096×1024) + o: 4096×4096
                  ≈ 42M mỗi tầng × 32 tầng          ≈ 1.3B
FFN/layer:        3 × (4096×14336), gated ≈ 176M × 32  ≈ 5.6B
embeddings:       2 × (128k × 4096), đầu vào + đầu ra  ≈ 1.1B
total                                                   ≈ 8.0B

Phép tính khớp với con số "8B" trên model card gần như chính xác. Hai bài học rơi ra: FFN chiếm ưu thế trong số tham số (do đó cả ngân sách bộ nhớ), và một từ vựng lớn tốn chừng một tỉ tham số trước khi tầng đầu tiên kịp chạy — một phần lý do các mô hình đa ngôn ngữ từ vựng lớn nặng hơn vẻ ngoài mà các anh em dense của chúng gợi ý.

GQA: giải pháp chi phí của attention

Trong lúc sinh văn bản, mỗi token mới phải đọc khóa và giá trị của mọi token trước đó — được lưu trong KV cache. Multi-head attention gốc lưu một K và một V cho mỗi đầu, mỗi token. Grouped-query attention (GQA) dùng chung một nhóm nhỏ đầu KV cho nhiều đầu query (ví dụ 32 đầu query, 8 đầu KV), thu nhỏ cache 4 lần với tổn thất chất lượng không đáng kể. Multi-query attention (MQA) dùng chung đúng một đầu KV. Trên thực tế mọi mô hình mở hiện đại đều dùng GQA; khoản tiết kiệm ấy là một phần lớn lý do ngữ cảnh dài dùng được ngay từ đầu (KV cache).

Độ dài ngữ cảnh = tầm attention

Attention cho mọi token thấy mọi token trước đó, nên tính toán prefill tăng theo bình phương độ dài prompt và cache tăng tuyến tính theo mỗi token được sinh ra. Một mô hình "ngữ cảnh 128k" đạt được điều đó bằng các chiêu vị trí và mở rộng có huấn luyện, và chất lượng gần cuối cửa sổ thường yếu hơn gần đầu. Chỉ nhồi đầy cửa sổ dài khi thực sự cần.

Tự kiểm tra: đặt một sự kiện ở đầu cửa sổ, nhồi phần giữa bằng văn bản đệm, hỏi về nó. Đa số mô hình đạt ở gần đầu và cuối cửa sổ và tụt ở giữa — khuôn mẫu "lost in the middle" nổi tiếng. Hãy coi ngữ cảnh quảng cáo là dung tích, không phải cam kết chất lượng.

Vì sao thế này là đủ

Chỉ từ cấu trúc này bạn có thể suy ra các sự kiện thực tế: nhu cầu bộ nhớ = trọng số + KV cache (toán VRAM); tốc độ decode = tốc độ bạn đọc lại được trọng số (prefill vs decode); khả năng bám theo số tham số (tham số); chi phí ngữ cảnh = tầm attention. Kiến trúc đơn giản — hàng tỷ trọng số đã huấn luyện bên trong nó mới là phần không ai viết tay nổi.

Liên quan: LLM là gì · KV cache · prefill vs decode · tham số