Sinh Văn Bản Nâng Cao (Advanced Text Generation)¶
Sinh văn bản nâng cao đi xa hơn giải mã tự hồi quy (autoregressive decoding) thông thường để cải thiện chất lượng, khả năng điều khiển và tốc độ. File này bao quát các mô hình khuếch tán văn bản (D3PM, MDLM), OCR, RLHF và DPO để căn chỉnh (alignment), các phương pháp ngữ cảnh dài (RoPE scaling, ring attention), sinh tăng cường truy xuất (retrieval-augmented generation) và giải mã suy đoán (speculative decoding) để suy luận nhanh hơn.
-
Sinh tự hồi quy chuẩn (file 04) tạo văn bản một token mỗi lần, từ trái sang phải. Cách này đơn giản và hiệu quả, nhưng về bản chất là tuần tự, không cho phép lập kế hoạch toàn cục, và hạn chế khả năng điều khiển đầu ra. File này bao quát các phương pháp vượt xa giải mã tự hồi quy thông thường: các mô hình khuếch tán cho văn bản, nhận dạng ký tự quang học (OCR), sinh có điều khiển thông qua phản hồi của con người, xử lý ngữ cảnh dài, sinh tăng cường truy xuất, và giải mã suy đoán để suy luận nhanh hơn.
-
Các mô hình khuếch tán văn bản (Text diffusion models) áp dụng khung khuếch tán (được giới thiệu cho ảnh trong chương 08) vào văn bản rời rạc. Thách thức cốt lõi là văn bản mang tính rời rạc: bạn không thể thêm nhiễu Gaussian liên tục vào token như cách bạn thêm nhiễu vào pixel. Một số cách tiếp cận giải quyết vấn đề này.
-
D3PM (Discrete Denoising Diffusion Probabilistic Models, Austin et al., 2021) định nghĩa một quá trình làm hỏng tiến (forward corruption process) trực tiếp trên các token rời rạc sử dụng ma trận chuyển tiếp. Tại mỗi bước tiến, một token có xác suất bị thay thế bằng token khác (nhiễu đồng đều), bị mặt nạ (absorbing state - trạng thái hấp thụ), hoặc giữ nguyên. Quá trình ngược học để khử nhiễu, dự đoán token sạch từ token bị hỏng. Ma trận chuyển tiếp \(Q_t\) tại bước \(t\) điều khiển việc làm hỏng:
- với \(\text{Cat}\) là phân bố phân loại (categorical distribution) và \(x\) là một vector one-hot. Quá trình tiến đa bước \(q(x_t \mid x_0)\) có dạng đóng: \(q(x_t \mid x_0) = \text{Cat}(x_t ; \, x_0 \bar{Q}_t)\) với \(\bar{Q}_t = Q_1 Q_2 \cdots Q_t\) là tích của tất cả ma trận chuyển tiếp đến bước \(t\). Huấn luyện tối thiểu hóa một chặn dưới biến phân (ELBO) phân rã theo các bước thời gian, tương tự trường hợp liên tục (chương 08):
-
Số hạng thứ nhất đảm bảo phân bố bị làm hỏng hoàn toàn khớp với tiên nghiệm (đồng đều hoặc all-mask). Tổng các số hạng KL huấn luyện mô hình đảo ngược mỗi bước làm hỏng: hậu nghiệm ngược thật sự \(q(x_{t-1} \mid x_t, x_0)\) có thể được tính dưới dạng đóng sử dụng quy tắc Bayes và các ma trận chuyển tiếp đã biết, và mô hình \(p_\theta(x_{t-1} \mid x_t)\) được huấn luyện để khớp với nó.
-
Vì cả hai phân bố đều là phân loại, phân kỳ KL là một tổng đơn giản trên các mục từ vựng. Số hạng cuối cùng đo chất lượng tái tạo từ trạng thái ít bị hỏng nhất.
-
MDLM (Masked Diffusion Language Models, Sahoo et al., 2024) đơn giản hóa D3PM bằng cách dùng mặt nạ làm thao tác làm hỏng duy nhất: quá trình tiến dần dần thay thế token bằng token [MASK], và quá trình ngược dự đoán các token gốc. Cách này kết nối khuếch tán văn bản với mô hình hóa ngôn ngữ có mặt nạ (BERT, file 04), với bước thời gian khuếch tán kiểm soát tỷ lệ token bị mặt nạ. Tại \(t = 0\), văn bản hoàn toàn sạch; tại \(t = T\), nó hoàn toàn bị mặt nạ.
-
Khuếch tán văn bản liên tục (Continuous text diffusion) vòng qua bài toán rời rạc bằng cách làm việc trong không gian embedding liên tục. Các token trước hết được ánh xạ tới các vector embedding của chúng (chương 06), nhiễu được thêm vào trong không gian liên tục này, và một mô hình khử nhiễu (thường là Transformer) học để đảo ngược quá trình. Tại thời điểm sinh, mô hình tạo ra các vector liên tục được ánh xạ ngược thành token rời rạc bằng cách tìm embedding gần nhất. Thách thức là các sai số nhỏ trong không gian liên tục có thể ánh xạ đến các token hoàn toàn sai, nên cần làm tròn và kẹp một cách cẩn thận.
-
Sức hấp dẫn của khuếch tán văn bản là nó tạo ra tất cả token đồng thời thông qua tinh chỉnh lặp (iterative refinement), thay vì từ trái sang phải. Điều này cho phép mạch lạc toàn cục và dễ dàng điền khuyết (generating missing text in the middle of a passage), nhưng các mô hình khuếch tán văn bản hiện tại vẫn còn thua kém các mô hình tự hồi quy về chất lượng sinh cho văn bản dài.
-
OCR Văn bản (Text OCR - Optical Character Recognition) là nhiệm vụ trích xuất văn bản từ ảnh. Dù theo truyền thống không được xếp cùng nhóm với sinh ngôn ngữ, các hệ thống OCR hiện đại được tích hợp sâu với NLP và ngày càng sử dụng các thành phần mô hình ngôn ngữ.
-
Phát hiện văn bản trong cảnh (Scene text detection) xác định vùng chữ trong ảnh tự nhiên (biển báo đường phố, nhãn sản phẩm, biển số xe). Điều này đầy thách thức vì chữ trong thế giới thực xuất hiện ở các góc, tỷ lệ, phông chữ tùy ý, và trên nền lộn xộn. Các phương pháp phát hiện thường dùng CNN hoặc Transformer backbone để tạo hộp giới hạn (bounding boxes) hoặc mặt nạ phân đoạn quanh vùng chữ.
-
CRNN (Convolutional Recurrent Neural Network, Shi et al., 2017) là một kiến trúc nhận dạng văn bản kinh điển. Một CNN trích xuất đặc trưng thị giác từ ảnh chữ, bản đồ đặc trưng được cắt thành một chuỗi các cột (mỗi cột cho một vị trí ngang), và một bidirectional LSTM đọc chuỗi này để mô hình hóa ngữ cảnh. Đầu ra được giải mã bằng CTC (Connectionist Temporal Classification), xử lý sự căn chỉnh giữa các cột đầu vào và các ký tự đầu ra mà không cần phân đoạn tường minh.
-
Vấn đề cơ bản mà CTC giải quyết: mô hình tạo \(T\) phân bố đầu ra (một cho mỗi cột đầu vào), nhưng văn bản mục tiêu có \(L \leq T\) ký tự.
-
Chúng ta không biết cột nào tương ứng với ký tự nào. CTC giới thiệu một token trắng (blank token) \(\epsilon\) và định nghĩa một ánh xạ nhiều-một \(\mathcal{B}\) thu gọn các ký tự lặp và loại bỏ token trắng: \(\mathcal{B}(\text{"HH-ee-ll-ll-oo"}) = \text{"Hello"}\) (với "-" là blank).
-
Xác suất của chuỗi mục tiêu \(y\) là tổng trên tất cả các căn chỉnh đầu vào thu gọn thành \(y\):
-
với \(\pi\) là một đường căn chỉnh (alignment path) độ dài \(T\) (một nhãn trên mỗi cột, bao gồm blank). Tính tổng ngây thơ trên tất cả các đường là cấp số nhân, nhưng thuật toán tiến (forward algorithm) (chương 05 HMM) tính tổng này hiệu quả trong thời gian \(O(T \cdot L)\) sử dụng quy hoạch động.
-
Token trắng rất thiết yếu: nếu không có nó, các ký tự lặp như "ll" trong "Hello" sẽ không thể phân biệt với một "l" đơn. Huấn luyện cực đại hóa \(\log P(y \mid x)\), và tại thời điểm suy luận, đường tốt nhất được tìm bằng beam search hoặc greedy decoding trên đầu ra CTC.
-
OCR Tài liệu (Document OCR) xử lý các tài liệu có cấu trúc (hóa đơn, biểu mẫu, bài báo khoa học) và phải hiểu bố cục ngoài việc nhận dạng ký tự. Các hệ thống hiện đại như LayoutLM kết hợp nhận dạng văn bản với các đặc trưng vị trí không gian: mỗi token có cả embedding văn bản và một embedding vị trí mã hóa tọa độ \((x, y)\) của nó trên trang. Điều này cho phép mô hình hiểu rằng một con số xuất hiện dưới "Tổng cộng:" là tổng số tiền.
-
Các mô hình OCR thị giác-ngôn ngữ (Vision-language OCR) như TrOCR xem nhận dạng văn bản như sinh ảnh-thành-văn bản: một bộ mã hóa Vision Transformer xử lý ảnh, và một bộ giải mã mô hình ngôn ngữ sinh văn bản từng ký tự một. Cách này tận dụng sức mạnh của các mô hình thị giác và ngôn ngữ đã được tiền huấn luyện và xử lý các hệ thống chữ viết, phông chữ và bố cục đa dạng mà không cần kỹ thuật đặc trưng thủ công.
-
Sinh có điều khiển (Controllable generation) là thách thức dẫn dắt một mô hình ngôn ngữ để tạo ra các đầu ra với các thuộc tính mong muốn: một phong cách, chủ đề, cảm xúc, mức độ an toàn, hoặc độ chính xác thực tế cụ thể. Mô hình nên tuân theo chỉ dẫn trong khi vẫn trôi chảy và mạch lạc.
-
Hướng dẫn không phân lớp (Classifier-free guidance - CFG) cho văn bản thích ứng một kỹ thuật từ sinh ảnh. Trong huấn luyện, tín hiệu điều kiện (ví dụ: prompt) thỉnh thoảng bị loại bỏ ngẫu nhiên với một xác suất nào đó, huấn luyện cả mô hình có điều kiện và không điều kiện trong cùng một mô hình. Lúc suy luận, các logit đầu ra được nội suy:
-
với \(w > 0\) khuếch đại ảnh hưởng của điều kiện. \(w\) cao hơn làm đầu ra bám sát prompt hơn nhưng giảm tính đa dạng.
-
RLHF (Reinforcement Learning from Human Feedback, Ouyang et al., 2022) là phương pháp chủ đạo để căn chỉnh mô hình ngôn ngữ với sở thích của con người. Quy trình có ba giai đoạn:
-
Đầu tiên, tinh chỉnh có giám sát (supervised fine-tuning - SFT): tinh chỉnh mô hình ngôn ngữ cơ sở trên một tập dữ liệu các phản hồi chất lượng cao do con người viết cho các prompt.
-
Thứ hai, huấn luyện mô hình phần thưởng (reward model training): thu thập các so sánh của con người (với prompt \(x\) và hai phản hồi \(y_1, y_2\), cái nào tốt hơn?) và huấn luyện mô hình phần thưởng \(r_\phi(x, y)\) để dự đoán sở thích của con người. Mô hình phần thưởng được huấn luyện với mất mát xếp hạng cặp (pairwise ranking loss):
-
với \(y_w\) là phản hồi được ưa thích và \(y_l\) là phản hồi không được ưa thích.
-
Thứ ba, tinh chỉnh RL: tối ưu hóa mô hình ngôn ngữ để cực đại hóa phần thưởng trong khi giữ gần với mô hình SFT (để ngăn suy sụp mode - mode collapse). Cách này dùng PPO (Proximal Policy Optimisation, từ chương 06) với một phạt KL:
- Số hạng KL ngăn mô hình trôi đi quá xa khỏi mô hình cơ sở và khai thác các điểm bất thường của mô hình phần thưởng ("reward hacking").
- DPO (Direct Preference Optimisation, Rafailov et al., 2023) đơn giản hóa RLHF bằng cách loại bỏ hoàn toàn mô hình phần thưởng. Nhận thức toán học then chốt là mục tiêu RL có ràng buộc KL ở trên có chính sách tối ưu dạng đóng:
- với \(Z(x)\) là hàm phân hoạch chuẩn hóa. Sắp xếp lại cho phần thưởng ta được \(r(x, y) = \beta \log \frac{\pi^\ast(y \mid x)}{\pi_{\text{ref}}(y \mid x)} + \beta \log Z(x)\). Thay phần thưởng tiềm ẩn này vào mô hình sở thích Bradley-Terry \(P(y_w \succ y_l) = \sigma(r(x, y_w) - r(x, y_l))\) làm các số hạng \(Z(x)\) khó tính triệt tiêu, đưa đến mất mát DPO trực tiếp:
-
Cách này tương đương về mặt toán học với RLHF nhưng gộp việc huấn luyện mô hình phần thưởng và RL thành một bước có giám sát duy nhất.
-
Biểu thức bên trong sigmoid có thể được đọc như sau: "tăng xác suất tương đối của phản hồi được ưa thích và giảm xác suất tương đối của phản hồi không được ưa thích, đo đạc so với mô hình tham chiếu."
-
Tham số \(\beta\) kiểm soát mức độ chính sách có thể lệch khỏi tham chiếu. Trong thực tế, DPO đơn giản hơn nhiều để cài đặt (chỉ cần tính log-xác suất dưới mô hình hiện tại và mô hình tham chiếu cho cả hai hoàn thiện) và tránh được sự bất ổn định của huấn luyện PPO.
-
AI Hiến pháp (Constitutional AI) (Bai et al., 2022) tự động hóa các phần của quy trình căn chỉnh. Thay vì thu thập các so sánh của con người, nó dùng chính mô hình ngôn ngữ để phê bình và sửa lại đầu ra của nó theo một tập các nguyên tắc ("hiến pháp"), chẳng hạn như "chọn phản hồi ít gây hại hơn." Các so sánh do AI tạo ra sau đó được dùng cho huấn luyện sở thích (RLAIF: RL from AI Feedback).
-
Các phương pháp ngữ cảnh dài (Long-context methods) giải quyết chi phí \(O(n^2)\) về bộ nhớ và tính toán của tự-chú ý chuẩn, thứ giới hạn độ dài chuỗi. Khi \(n\) tăng lên hàng chục hoặc hàng trăm nghìn token, chú ý chuẩn trở nên bất khả thi.
-
Chú ý thưa (Sparse attention) thay thế ma trận chú ý \(n \times n\) dày đặc bằng một mẫu thưa trong đó mỗi token chỉ chú ý đến một tập con các token khác. Các mẫu phổ biến bao gồm chú ý cục bộ (local attention) (mỗi token chú ý đến một cửa sổ kích thước cố định các lân cận), chú ý có bước nhảy (strided attention) (chú ý đến mỗi token thứ \(k\)), và chú ý ngẫu nhiên (random attention) (chú ý đến một tập con ngẫu nhiên). Tổ hợp các mẫu này (dùng trong BigBird, Longformer) đạt độ phức tạp \(O(n)\) hoặc \(O(n \sqrt{n})\) trong khi vẫn duy trì khả năng nắm bắt cả phụ thuộc cục bộ và toàn cục.
-
Chú ý cửa sổ trượt (Sliding window attention) giới hạn mỗi token chỉ chú ý đến \(w\) token trước đó (cửa sổ cục bộ của nó). Cách này có độ phức tạp \(O(nw)\) thay vì \(O(n^2)\), nhưng thông tin tầm xa phải lan truyền qua các cửa sổ chồng lấp xuyên các lớp. Với \(L\) lớp và kích thước cửa sổ \(w\), trường tiếp nhận hiệu dụng là \(L \times w\) token.
-
Chú ý vòng (Ring attention) phân phối các chuỗi dài qua nhiều thiết bị bằng cách sắp xếp chúng thành một tô-pô vòng. Mỗi thiết bị giữ một phần của chuỗi và tính chú ý cho phần của nó trong khi đồng thời gửi các khối key-value đến thiết bị kế tiếp trong vòng. Cách này chồng lấp tính toán với giao tiếp và cho phép các chuỗi có độ dài tùy ý, chỉ bị giới hạn bởi tổng bộ nhớ trên tất cả thiết bị, chứ không phải bộ nhớ của một thiết bị đơn lẻ.
-
Các mô hình bộ nhớ tăng cường (Memory-augmented models) mở rộng ngữ cảnh bằng cách trang bị cho Transformer một ngân hàng bộ nhớ bên ngoài. Tại mỗi lớp, mô hình có thể đọc từ và ghi vào bộ nhớ này sử dụng chú ý. Các Memorizing Transformers lưu đệm các cặp key-value từ các phần trước và chú ý đến chúng trong các phần sau, mở rộng ngữ cảnh vượt ra ngoài cửa sổ huấn luyện. Việc truy xuất là xấp xỉ (dùng \(k\) lân cận gần nhất trên các khóa đã lưu đệm) để giữ hiệu quả.
-
Các phương pháp trên là các giải pháp kiến trúc cho ngữ cảnh dài. Quan trọng không kém là cách các mô hình được huấn luyện để sử dụng ngữ cảnh dài một cách hiệu quả.
-
Mở rộng ngữ cảnh tiến dần (Progressive context extension) là cách tiếp cận chuẩn. Huấn luyện trên các chuỗi rất dài từ đầu là quá tốn kém (chi phí chú ý \(O(n^2)\)), nên các mô hình được tiền huấn luyện ở độ dài ngữ cảnh ngắn (thường 4K–8K token) và sau đó tiếp tục tiền huấn luyện (continued pre-training) mở rộng đến độ dài mục tiêu theo từng giai đoạn.
-
Llama 3.1 mở rộng từ 8K lên 128K qua 800B token với độ dài chuỗi tăng dần. DeepSeek-V3 huấn luyện ở 4K, rồi mở rộng lên 32K, rồi 128K.
-
Mỗi giai đoạn dùng một số lượng token khiêm tốn (so với tổng ngân sách tiền huấn luyện) vì mô hình chỉ cần học cách sử dụng các vị trí dài hơn, chứ không phải học lại chính ngôn ngữ.
-
Mã hóa vị trí phải được điều chỉnh trong quá trình mở rộng. Nội suy RoPE (RoPE interpolation) giảm tỷ lệ các chỉ số vị trí sao cho mô hình thấy các góc quay giống như nó đã được huấn luyện, chỉ là trải dài trên một chuỗi dài hơn. Nếu mô hình được huấn luyện ở độ dài \(L\) và bạn muốn mở rộng lên \(L' = 4L\), bạn chia tất cả chỉ số vị trí cho 4.
-
Điều này có nghĩa là mô hình không bao giờ thấy một góc quay nào chưa từng gặp, nhưng độ phân giải hiệu dụng giữa các vị trí kề nhau giảm xuống.
-
Ngoại suy RoPE (RoPE extrapolation) giữ nguyên các chỉ số vị trí gốc và chỉ đơn giản áp dụng RoPE cho các vị trí vượt quá \(L\), phụ thuộc vào khả năng tổng quát hóa của mô hình đến các góc chưa thấy.
-
Nội suy ổn định hơn nhiều; ngoại suy suy giảm nhanh nếu không điều chỉnh tần số cơ sở (ABF).
-
YaRN (Yet another RoPE extensioN) cải tiến trên nội suy ngây thơ bằng cách nhận ra rằng không phải mọi chiều RoPE đều nên được đối xử như nhau.
-
Các chiều tần số cao (\(i\) nhỏ trong \(\theta_i = \theta_{\text{base}}^{-2i/d}\)) quay nhiều lần trong độ dài huấn luyện và có thể ngoại suy tốt.
-
Các chiều tần số thấp (\(i\) lớn) quay chậm và nhạy cảm hơn với mở rộng độ dài.
-
YaRN nội suy chỉ các chiều tần số thấp, ngoại suy các chiều tần số cao, và áp dụng một tỷ lệ nhiệt \(t\) lên các logit chú ý để bù đắp cho sự dịch chuyển phân bố:
-
với \(t > 1\) làm phẳng phân bố chú ý, ngăn mô hình chú ý quá mạnh vào các token gần khi các tín hiệu vị trí bị nén lại.
-
Tuyển chọn dữ liệu ngữ cảnh dài (Long-context data curation) là một thách thức quan trọng và thường bị đánh giá thấp. Hầu hết các kho ngữ liệu tiền huấn luyện đều gồm các tài liệu ngắn (bài báo tin tức, trang web, bài đăng mạng xã hội).
-
Huấn luyện ngữ cảnh dài đòi hỏi một mix dữ liệu thực sự sử dụng toàn bộ cửa sổ ngữ cảnh: sách, kho mã nguồn, bài báo khoa học dài, nhật ký hội thoại nhiều lượt, và các tài liệu có liên quan theo chủ đề được ghép nối.
-
Nếu mô hình chỉ được huấn luyện trên các tài liệu ngắn được đệm hoặc đóng gói để lấp đầy cửa sổ ngữ cảnh, nó sẽ học cách bỏ qua các token xa vì chúng không bao giờ có liên quan.
-
Đóng gói chuỗi (Sequence packing) là một kỹ thuật hiệu quả huấn luyện: nhiều tài liệu được ghép vào một chuỗi huấn luyện duy nhất để tránh lãng phí đệm, với các mặt nạ chú ý ngăn chặn chú ý xuyên tài liệu.
-
Đối với huấn luyện ngữ cảnh dài, chiến lược đóng gói rất quan trọng: đóng gói nhiều tài liệu ngắn không liên quan dạy mô hình rằng các token xa là nhiễu, trong khi đóng gói ít tài liệu thực sự dài dạy mô hình sử dụng toàn bộ ngữ cảnh.
-
Một dạng hỏng hóc đã biết là hiện tượng "lạc ở giữa" (lost in the middle) (Liu et al., 2023): các mô hình ngôn ngữ có xu hướng sử dụng thông tin ở đầu và cuối cửa sổ ngữ cảnh một cách hiệu quả nhưng gặp khó khăn với thông tin đặt ở giữa.
-
Điều này giống với hiệu ứng vị trí nối tiếp (serial position effect) trong trí nhớ con người (primacy and recency).
-
Nó phát sinh một phần từ các phân bố dữ liệu huấn luyện (thông tin quan trọng thường ở đầu hoặc cuối tài liệu) và một phần từ các mẫu chú ý tập trung vào các token gần và đầu tiên.
-
Huấn luyện ngữ cảnh dài với vị trí đa dạng của thông tin chính giảm thiểu nhưng không giải quyết triệt để vấn đề này.
-
Đánh giá "kim trong bó cỏ" (Needle-in-a-haystack) kiểm tra xem một mô hình có thể truy xuất một sự kiện cụ thể ("cây kim") được đặt ở các vị trí khác nhau trong một ngữ cảnh sao lãng dài ("bó cỏ") hay không.
-
Một mô hình có khả năng ngữ cảnh dài thực sự sẽ đạt được truy xuất gần như hoàn hảo bất kể cây kim được đặt ở đâu.
-
Bài kiểm tra này phơi bày hiệu ứng lạc-ở-giữa một cách rõ ràng và được dùng để đánh giá chuẩn các phương pháp mở rộng ngữ cảnh.
-
Tinh chỉnh ngữ cảnh dài (Long-context fine-tuning) sau tiền huấn luyện sử dụng dữ liệu SFT có mục tiêu: hội thoại nhiều lượt dài, QA tài liệu với bằng chứng rải rác qua hàng nghìn token, tóm tắt dài, và hiểu mã nguồn cấp kho.
-
Qwen3 sử dụng Dual Chunk Attention (DCA) trong giai đoạn này, xử lý các chuỗi dài thành các cặp phần trong đó chú ý trong phần là đầy đủ và chú ý giữa các phần là hiệu quả, đạt dung lượng chuỗi hiệu dụng gấp 4x trong quá trình tinh chỉnh.
-
Các Mô hình Không gian Trạng thái (State Space Models - SSMs) đưa ra một cách tiếp cận khác về cơ bản cho mô hình hóa chuỗi dài. Thay vì sửa đổi cơ chế chú ý, chúng thay thế nó hoàn toàn bằng một hệ thống động lực học tuyến tính lấy cảm hứng từ lý thuyết điều khiển thời gian liên tục.
-
Một SSM ánh xạ một chuỗi đầu vào \(u(t)\) thành đầu ra \(y(t)\) thông qua một trạng thái tiềm ẩn \(x(t) \in \mathbb{R}^N\) được điều chỉnh bởi:
-
với \(A \in \mathbb{R}^{N \times N}\) là ma trận chuyển tiếp trạng thái, \(B \in \mathbb{R}^{N \times 1}\) là phép chiếu đầu vào, \(C \in \mathbb{R}^{1 \times N}\) là phép chiếu đầu ra, và \(D\) là một kết nối tắt (skip connection).
-
Để áp dụng cho các chuỗi rời rạc (token), hệ thống liên tục được rời rạc hóa (discretised) sử dụng một kích thước bước \(\Delta\). Phép rời rạc zero-order hold cho ta:
-
Hệ thức truy hồi rời rạc khi đó trở thành \(x_k = \bar{A} x_{k-1} + \bar{B} u_k\), \(y_k = C x_k + D u_k\), trông giống như một RNN: xử lý một token mỗi lần với một trạng thái ẩn.
-
Khác với RNN, hệ thức truy hồi này cũng có thể được mở ra như một tích chập toàn cục (global convolution): vì hệ thống là tuyến tính, đầu ra là \(y = \bar{K} \ast u\) với kernel \(\bar{K} = (C\bar{B}, \, C\bar{A}\bar{B}, \, C\bar{A}^2\bar{B}, \ldots)\) chỉ phụ thuộc vào các tham số cố định.
-
Quan điểm kép (dual view) này — truy hồi cho suy luận tự hồi quy hiệu quả (\(O(1)\) mỗi bước) và tích chập cho huấn luyện song song hiệu quả (\(O(n \log n)\) qua FFT) — là nhận thức trung tâm của các SSM.
-
S4 (Structured State Spaces for Sequence Modeling, Gu et al., 2022) làm cho SSM trở nên thực tế bằng cách giải quyết thách thức số học then chốt: ma trận trạng thái \(A\) phải nắm bắt các phụ thuộc tầm xa, nhưng tham số hóa nó một cách ngây thơ dẫn đến động lực học biến mất hoặc bùng nổ (cùng vấn đề với RNN thông thường).
-
S4 khởi tạo \(A\) sử dụng ma trận HiPPO (High-order Polynomial Projection Operators), được dẫn xuất từ lý thuyết xấp xỉ đa thức tối ưu của tín hiệu liên tục. Ma trận HiPPO có một cấu trúc cụ thể có thể chứng minh được cho phép trạng thái duy trì một biểu diễn nén của toàn bộ lịch sử đầu vào với sự suy giảm nhẹ nhàng:
-
Cấu trúc tam giác dưới này đảm bảo rằng trạng thái hoạt động như một xấp xỉ trực tuyến của tín hiệu đầu vào sử dụng các đa thức Legendre. Tính \(\bar{A}^k\) cho các kernel dài rất tốn kém, nên S4 dùng thực tế là ma trận HiPPO có thể được phân rã thành tổng của các số hạng hạng thấp và đường chéo, cho phép tính kernel \(O(n \log n)\).
-
Mamba (Gu and Dao, 2023) giới thiệu cải tiến quan trọng của không gian trạng thái chọn lọc (selective state spaces): làm cho các tham số SSM phụ thuộc vào đầu vào. Trong S4, các ma trận \(A\), \(B\), \(C\), và kích thước bước \(\Delta\) là cố định — cùng một động lực học áp dụng cho mọi token bất kể nội dung. Mamba làm cho \(B\), \(C\), và \(\Delta\) trở thành hàm của đầu vào:
-
Tính chọn lọc này cho phép mô hình quyết định, tại mỗi vị trí, thông tin nào cần lưu vào trạng thái và thông tin nào cần bỏ qua — tương tự như cách chú ý chọn các token có liên quan, nhưng không có chi phí bậc hai. Kích thước bước \(\Delta_k\) điều khiển "cổng": \(\Delta\) lớn làm trạng thái tích hợp mạnh đầu vào hiện tại (động lực học liên tục tiến một bước lớn, làm mới trạng thái), trong khi \(\Delta\) nhỏ giữ nguyên trạng thái hiện có và bỏ qua đầu vào hiện tại.
-
Sự đánh đổi là các tham số phụ thuộc đầu vào phá vỡ quan điểm tích chập (kernel không còn cố định), nên Mamba không thể sử dụng huấn luyện dựa trên FFT. Thay vào đó, nó sử dụng một thuật toán quét song song ý thức phần cứng (hardware-aware parallel scan) khai thác tính kết hợp của hệ thức truy hồi: cập nhật trạng thái \((x_k, u_k) \mapsto x_{k+1}\) có thể được biểu diễn như một chuỗi các thao tác kết hợp và được song song hóa sử dụng prefix sum (scan), tương tự như phép cộng tiền tố song song trong thiết kế phần cứng. Cách này chạy trong thời gian \(O(n)\) với độ sâu \(O(\log n)\) trên GPU, gần bằng hiệu quả của tích chập.
-
Mamba đạt được suy luận thực sự \(O(1)\) mỗi token (chỉ cần cập nhật trạng thái kích thước cố định, không có bộ đệm KV phình to theo ngữ cảnh), khiến nó về cơ bản tốn ít bộ nhớ hơn Transformers ở các độ dài chuỗi dài. Kích thước trạng thái \(N\) (thường là 16) nhỏ hơn nhiều so với bộ đệm KV của Transformer, thứ lưu trữ \(O(n \cdot d)\) giá trị. Trong thực tế, Mamba đạt hoặc vượt chất lượng Transformer tại cùng số tham số trên các benchmark mô hình hóa ngôn ngữ, với suy luận nhanh hơn đáng kể trên các chuỗi dài.
-
Các kiến trúc lai (Hybrid architectures) kết hợp các tầng SSM với các tầng chú ý, sử dụng SSM cho phần lớn các tầng (lan truyền tầm xa hiệu quả) và rải rác một vài tầng chú ý (truy xuất dựa trên nội dung chính xác). Các mô hình như Jamba và Zamba xen kẽ các khối Mamba và Transformer, đạt chất lượng tốt hơn SSM thuần túy trong khi vẫn duy trì phần lớn lợi thế hiệu quả suy luận. Điều này gợi ý rằng chú ý và SSM nắm bắt các khả năng bổ sung: SSM vượt trội ở lan truyền trạng thái tầm xa mượt mà, trong khi chú ý vượt trội ở tra cứu phụ thuộc vào nội dung chính xác.
-
Sinh tăng cường truy xuất (Retrieval-Augmented Generation - RAG) giải quyết các hạn chế về kiến thức của mô hình ngôn ngữ bằng cách cho chúng truy cập vào một cơ sở tri thức bên ngoài tại thời điểm suy luận. Thay vì chỉ dựa vào kiến thức được mã hóa trong tham số mô hình trong quá trình huấn luyện, RAG truy xuất các tài liệu có liên quan và điều kiện hóa sinh dữ liệu dựa trên chúng.
-
Kiến trúc truy xuất-đọc (retriever-reader architecture) kinh điển có hai thành phần. Bộ truy xuất (retriever) nhận một truy vấn và lấy top-\(k\) đoạn văn có liên quan nhất từ một kho ngữ liệu. Bộ đọc (reader) (một mô hình ngôn ngữ) sinh câu trả lời dựa trên cả truy vấn và các đoạn văn đã truy xuất. Bộ truy xuất có thể sử dụng phương pháp thưa (BM25, mở rộng TF-IDF từ file 02) hoặc phương pháp dày đặc.
-
Truy xuất đoạn văn dày đặc (Dense passage retrieval - DPR) sử dụng kiến trúc bộ mã hóa kép: một bộ mã hóa ánh xạ câu hỏi thành vector, một bộ mã hóa khác ánh xạ đoạn văn thành vector. Cả hai thường dựa trên BERT. Tại thời điểm đánh chỉ mục, tất cả đoạn văn được mã hóa và lưu trữ. Tại thời điểm truy vấn, câu hỏi được mã hóa và các đoạn văn gần nhất được tìm bằng tìm kiếm lân cận gần nhất xấp xỉ (như FAISS). Độ tương tự là tích vô hướng giữa vector câu hỏi và vector đoạn văn.
-
Các chiến lược chia đoạn (Chunking strategies) ảnh hưởng đáng kể đến chất lượng truy xuất. Tài liệu phải được chia thành các đoạn văn đủ nhỏ cho bộ truy xuất xử lý, nhưng đủ lớn để chứa các ý hoàn chỉnh. Chia đoạn kích thước cố định (ví dụ: 256 token với chồng lấp 50 token) đơn giản nhưng có thể cắt câu một cách vụng về. Chia đoạn ngữ nghĩa (semantic chunking) chia tại ranh giới đoạn văn hoặc phần. Chia đoạn phân cấp (hierarchical chunking) tạo ra một cây các tóm tắt ở các mức chi tiết khác nhau.
-
RAG cung cấp một số lợi thế: cơ sở tri thức có thể được cập nhật mà không cần huấn luyện lại mô hình, mô hình có thể trích dẫn nguồn, và hiện tượng hallucination giảm vì mô hình có thể neo câu trả lời vào văn bản đã truy xuất. Các thách thức chính là chất lượng truy xuất (nếu các đoạn văn sai được truy xuất, mô hình có thể tạo ra câu trả lời sai một cách tự tin) và độ trễ (truy xuất thêm một bước vào suy luận).
-
Giải mã suy đoán (Speculative decoding) tăng tốc sinh tự hồi quy bằng cách sử dụng một mô hình dự thảo (draft model) nhỏ, nhanh để đề xuất nhiều token song song, sau đó được xác minh bởi mô hình mục tiêu (target model) lớn trong một lượt truyền xuôi duy nhất.
-
Thuật toán hoạt động như sau: mô hình dự thảo tạo \(k\) token ứng viên một cách tự hồi quy (nhanh vì mô hình dự thảo nhỏ).
-
Mô hình mục tiêu sau đó chấm điểm tất cả \(k\) token đồng thời trong một lượt truyền xuôi duy nhất (hiệu quả vì công việc được gộp batch).
-
Với mỗi token ứng viên \(t\) được lấy mẫu từ phân bố dự thảo \(p_d(t)\), nó được chấp nhận với xác suất \(\min(1, \, p_{\text{target}}(t) / p_d(t))\). Nếu bị từ chối, một token được sửa chữa được lấy mẫu lại từ phân bố đã điều chỉnh (adjusted distribution) \(p_{\text{adj}}(t) = \max(0, \, p_{\text{target}}(t) - p_d(t))\), được chuẩn hóa.
-
Sơ đồ chấp nhận-từ chối này đảm bảo rằng phân bố đầu ra đồng nhất với mô hình mục tiêu đơn thuần.
-
Để giải thích tại sao, hãy xem xét xác suất hiệu dụng của việc phát ra token \(t\). Nó có thể được chấp nhận trực tiếp (xác suất \(p_d(t) \cdot \min(1, p_{\text{target}}(t)/p_d(t))\)) hoặc được tạo ra thông qua lấy mẫu lại.
-
Với các token mà \(p_{\text{target}}(t) \leq p_d(t)\), việc chấp nhận trực tiếp đóng góp \(p_{\text{target}}(t)\). Với các token mà \(p_{\text{target}}(t) > p_d(t)\), chấp nhận trực tiếp đóng góp \(p_d(t)\) và lấy mẫu lại đóng góp phần còn lại \(p_{\text{target}}(t) - p_d(t)\) (sau khi tính đến xác suất từ chối).
-
Trong cả hai trường hợp, tổng xác suất phát ra \(t\) bằng \(p_{\text{target}}(t)\). Mô hình dự thảo chỉ ảnh hưởng đến tốc độ, không phải chất lượng.
-
Mức tăng tốc phụ thuộc vào tỷ lệ chấp nhận: nếu mô hình dự thảo căn chỉnh tốt với mô hình mục tiêu, hầu hết các token được chấp nhận và thời gian trên đồng hồ gần bằng thời gian của mô hình dự thảo. Mức tăng tốc điển hình là 2-3x mà không suy giảm chất lượng.
-
Medusa (Cai et al., 2024) thực hiện một cách tiếp cận khác: thay vì một mô hình dự thảo riêng biệt, nó thêm nhiều đầu dự đoán nhẹ vào chính mô hình mục tiêu. Mỗi đầu dự đoán một vị trí token tương lai khác nhau đồng thời (\(k = 1, 2, 3, \ldots\) bước phía trước). Tại mỗi bước, Medusa đề xuất một số ứng viên tiếp theo sử dụng cấu trúc cây, và một lượt truyền xuôi duy nhất qua các tầng chú ý của mô hình mục tiêu xác minh các ứng viên nào nhất quán. Cách này tránh hoàn toàn nhu cầu về một mô hình dự thảo riêng biệt.
-
Các phương pháp sinh song song (Parallel generation) nói chung nhằm phá vỡ nút thắt tuần tự của giải mã tự hồi quy. Giải mã Jacobi (Jacobi decoding) khởi tạo tất cả vị trí bằng các dự đoán và tinh chỉnh chúng song song cho đến khi hội tụ, coi sinh dữ liệu như một phép lặp điểm bất động. Các mô hình phi tự hồi quy (NAT) tạo tất cả token đồng thời trong một lượt truyền xuôi duy nhất nhưng thường bị suy giảm chất lượng và cần các kỹ thuật như tinh chỉnh lặp, mất mát CTC, hoặc chưng cất kiến thức từ các giáo viên tự hồi quy để thu hẹp khoảng cách.
-
Các kỹ thuật trên — căn chỉnh, ngữ cảnh dài, truy xuất, giải mã hiệu quả, mô hình không gian trạng thái — kết hợp với nhau trong các LLM sản xuất hiện đại.
-
Phần còn lại của file này khảo sát các cải tiến kiến trúc trong các mô hình tiên phong, cho thấy các ý tưởng lý thuyết từ các file 01–04 và các phương pháp trên được kết hợp trong thực tế như thế nào.
-
Chú ý truy vấn theo nhóm (Grouped Query Attention - GQA) là kỹ thuật hiệu quả chú ý được áp dụng rộng rãi nhất. Chú ý đa đầu (MHA) chuẩn duy trì các phép chiếu key và value riêng biệt trên mỗi đầu, đòi hỏi \(n_{\text{heads}} \times d_{\text{head}}\) giá trị được lưu đệm mỗi token. GQA nhóm nhiều đầu truy vấn để chia sẻ một đầu key-value duy nhất.
-
Với 64 đầu truy vấn và 8 đầu KV (một cấu hình phổ biến trong Llama 3, Qwen, Gemma), mỗi đầu KV được chia sẻ bởi 8 đầu truy vấn, giảm bộ đệm KV xuống 8 lần so với MHA.
-
Chất lượng đầu ra gần như giống hệt MHA vì các truy vấn vẫn có thể chú ý đến các mẫu khác nhau, chúng chỉ chia sẻ cùng một không gian con key-value. Chú ý đa truy vấn (MQA) là trường hợp cực đoan với một đầu KV duy nhất cho tất cả truy vấn, nhưng GQA cung cấp sự đánh đổi chất lượng-hiệu quả tốt hơn.
-
Chú ý tiềm ẩn đa đầu (Multi-head Latent Attention - MLA), được giới thiệu trong DeepSeek-V2, đạt nén bộ đệm KV mạnh mẽ hơn nữa. Thay vì lưu đệm các phép chiếu key-value đầy đủ (ngay cả với GQA), MLA chiếu xuống trạng thái ẩn thành một vector tiềm ẩn (latent vector) hạng thấp \(c_t \in \mathbb{R}^{d_c}\) với \(d_c \ll n_{\text{heads}} \times d_{\text{head}}\):
-
Chỉ vector nén này được lưu đệm. Tại thời điểm chú ý, các biểu diễn key và value đầy đủ được tái tạo qua phép chiếu lên: \(k_t = W_{\text{up}}^K c_t\), \(v_t = W_{\text{up}}^V c_t\). Trong DeepSeek-V3 (671B tổng tham số, 37B kích hoạt), chiều nén là \(d_c = 512\) so với \(128 \times 128 = 16{,}384\) cho MHA đầy đủ, giảm 93% bộ đệm KV.
-
Một tinh tế: RoPE chuẩn phụ thuộc vào vị trí và không tương thích với nén chia sẻ, nên MLA sử dụng RoPE tách rời (decoupled RoPE): một luồng nhỏ riêng biệt của truy vấn và key (64 chiều mỗi đầu) mang thông tin vị trí qua RoPE, trong khi phần lớn biểu diễn chảy qua đường tiềm ẩn nén.
-
Mã hóa vị trí ở quy mô lớn đã phân kỳ đáng kể so với sơ đồ sinusoidal gốc. Tất cả các mô hình tiên phong đều sử dụng RoPE (file 04), nhưng với các sửa đổi then chốt cho ngữ cảnh dài. Tần số cơ sở \(\theta_{\text{base}}\) trong công thức RoPE gốc \(\theta_i = \theta_{\text{base}}^{-2i/d}\) thường là 10,000, thứ giới hạn khả năng ngoại suy vượt quá độ dài huấn luyện.
-
Điều chỉnh tần số cơ sở (Adjusted Base Frequency - ABF) chỉ đơn giản tăng \(\theta_{\text{base}}\) lên 500,000 (Llama 3) hoặc 1,000,000 (Qwen3, Gemma 3), kéo dài các chu kỳ quay để mô hình gặp ít vòng quay đầy đủ hơn trong quá trình huấn luyện và có thể ngoại suy xa hơn.
-
YaRN (Yet another RoPE extensioN) áp dụng nội suy phụ thuộc tần số: các chiều tần số thấp được nội suy (giảm tỷ lệ), các chiều tần số cao được ngoại suy, và một hệ số nhiệt điều chỉnh phân bố chú ý. DeepSeek-V3, Qwen, và Kimi K2 đều sử dụng mở rộng dựa trên YaRN để đạt ngữ cảnh 128K từ các mô hình tiền huấn luyện ở 4K–8K.
-
iRoPE (interleaved RoPE), được giới thiệu trong Llama 4, thực hiện một cách tiếp cận triệt để hơn: mỗi tầng chú ý thứ 4 sử dụng không có mã hóa vị trí nào cả (NoPE), trong khi các tầng khác sử dụng RoPE chuẩn với chú ý theo phần (chunked attention).
-
Các tầng NoPE có thể chú ý đến mọi vị trí mà không có thiên kiến vị trí, trong khi các tầng RoPE cung cấp thứ tự cục bộ. Kết hợp với tỷ lệ nhiệt trong suy luận, điều này cho phép cửa sổ ngữ cảnh 10M token của Llama 4 Scout — lớn hơn nhiều bậc so với bất kỳ phương pháp RoPE thuần túy nào.
-
Hỗn hợp chuyên gia ở quy mô lớn đã trở thành kiến trúc thống trị cho các mô hình tiên phong (file 04 giới thiệu các nguyên tắc cơ bản của MoE). Các lựa chọn thiết kế then chốt là số lượng chuyên gia, độ thưa định tuyến, và cân bằng tải.
-
Độ thưa định tuyến (Routing sparsity) thay đổi đáng kể: DeepSeek-V3 sử dụng 256 chuyên gia với định tuyến top-8 (độ thưa 32x), Qwen3 sử dụng 128 chuyên gia với top-8 (độ thưa 16x), Mixtral sử dụng 8 chuyên gia với top-2 (độ thưa 4x), và Llama 4 Maverick sử dụng 128 chuyên gia với top-1 cộng một chuyên gia chia sẻ (độ thưa 128x).
-
Độ thưa cao hơn có nghĩa là nhiều tổng tham số hơn cho cùng tính toán hoạt động, nhưng đòi hỏi cân bằng tải và cơ sở hạ tầng giao tiếp cẩn thận hơn.
-
Cân bằng tải không cần mất mát phụ trợ (Auxiliary-loss-free load balancing) (DeepSeek-V3) thay thế mất mát cân bằng tải truyền thống (file 04) vốn được phát hiện là làm giảm chất lượng mô hình. Thay vào đó, mỗi chuyên gia duy trì một số hạng thiên kiến động được điều chỉnh theo mỗi bước huấn luyện: các chuyên gia quá tải có thiên kiến giảm (nhận ít token hơn), các chuyên gia dưới tải có thiên kiến tăng. Cách này đạt được định tuyến cân bằng mà không có bất kỳ mất mát phụ trợ nào làm ô nhiễm tín hiệu huấn luyện chính.
-
Các chuyên gia chia sẻ (Shared experts) xuất hiện trong hầu hết các thiết kế MoE: một hoặc nhiều FFN chuyên gia xử lý mọi token bất kể định tuyến. Chúng xử lý các mẫu phổ biến mà mọi token đều cần (cú pháp cơ bản, từ chức năng), giải phóng các chuyên gia được định tuyến để chuyên môn hóa. Llama 4 sử dụng 1 chuyên gia chia sẻ cộng 1 chuyên gia được định tuyến trên mỗi token (rất thưa); DeepSeek-V3 sử dụng 1 chia sẻ cộng 8 được định tuyến.
-
Xen kẽ các tầng dày đặc và MoE cung cấp một trục thiết kế khác. Gemma 2 và 3 xen kẽ các tầng chú ý cục bộ/toàn cục (tỷ lệ 5:1 trong Gemma 3, nơi các tầng cục bộ sử dụng cửa sổ trượt 1,024 token và chỉ các tầng toàn cục lưu đệm toàn bộ ngữ cảnh 128K).
-
Llama 4 Maverick xen kẽ các tầng FFN dày đặc với các tầng MoE. Kimi K2 sử dụng các tầng độ thưa lai (một tầng dày đặc xen giữa các tầng chuyên gia). Thiết kế không đồng nhất này cho phép các tầng khác nhau phục vụ các chức năng khác nhau.
-
Dự đoán đa token (Multi-token prediction - MTP), được sử dụng trong DeepSeek-V3, huấn luyện mô hình dự đoán không chỉ token kế tiếp mà còn cả token sau đó. Tại mỗi vị trí, một mô-đun dự đoán thứ cấp (chia sẻ embedding của mô hình chính) dự đoán thêm một token tương lai. Mất mát MTP có trọng số 0.1–0.3 so với mất mát next-token chính. Ngoài việc cải thiện chất lượng biểu diễn trong quá trình huấn luyện, các đầu MTP có thể phục vụ như các đầu dự thảo cho giải mã suy đoán tại thời điểm suy luận, cung cấp một sự tăng tốc miễn phí.
-
Chưng cất kiến thức (Knowledge distillation) là một chiến lược huấn luyện nơi đầu ra của một mô hình "giáo viên" lớn hướng dẫn huấn luyện của một mô hình "học sinh" nhỏ hơn. Gemma 2 và 3 sử dụng chưng cất rộng rãi: các mô hình nhỏ hơn (2B, 4B) được huấn luyện trên lượng dữ liệu gấp 50x so với mức tối ưu tính toán với các phân bố xác suất của giáo viên làm mục tiêu mềm. Đây là lý do tại sao Gemma 3-4B ngang bằng Gemma 2-27B về chất lượng.
-
Mất mát chưng cất thay thế hoặc bổ sung cho cross-entropy chuẩn: học sinh tối thiểu hóa phân kỳ KL giữa phân bố đầu ra của nó và của giáo viên:
-
DeepSeek-R1 đã chưng cất mô hình suy luận 671B của nó thành các mô hình dày đặc nhỏ tới 1.5B sử dụng 800K mẫu chain-of-thought đã được tuyển chọn, tạo ra các mô hình nhỏ với khả năng suy luận mạnh mẽ không tương xứng.
-
Suy luận thông qua học tăng cường (Reasoning via reinforcement learning) đại diện cho tiến bộ gần đây nhất và quan trọng nhất trong các khả năng của LLM. DeepSeek-R1 chứng minh rằng học tăng cường thuần túy trên một mô hình cơ sở (không có tinh chỉnh có giám sát) có thể kích thích suy luận chain-of-thought, tự xác minh và sửa lỗi — các hành vi xuất hiện tự phát khi mô hình được thưởng cho các câu trả lời cuối cùng đúng.
-
DeepSeek-R1 sử dụng GRPO (Group Relative Policy Optimisation), loại bỏ mạng giá trị (value network) mà PPO yêu cầu. Với mỗi prompt, GRPO lấy mẫu một nhóm \(G\) đầu ra, tính phần thưởng của chúng, và chuẩn hóa các lợi thế (advantages) trong nhóm:
-
Gradient chính sách sau đó sử dụng các lợi thế tương đối theo nhóm này với một mục tiêu bị cắt (tương tự như clipping của PPO).
-
Loại bỏ mạng critic làm giảm một nửa bộ nhớ và yêu cầu tính toán của huấn luyện RL, khiến việc huấn luyện mô hình 671B tham số với RL trở nên khả thi.
-
Một lựa chọn thiết kế quan trọng: DeepSeek-R1 sử dụng phần thưởng dựa trên quy tắc (rule-based rewards) (kiểm tra câu trả lời toán học so với đáp án đúng, chạy các ca kiểm thử mã) thay vì mô hình phần thưởng nơ-ron, vì các mô hình phần thưởng nơ-ron được phát hiện là dễ bị reward hacking ở quy mô này.
-
Chế độ suy nghĩ lai của Qwen3 (Qwen3's hybrid thinking mode) tích hợp suy luận (với các tag
<think>cho chain-of-thought từng bước) và phản hồi trực tiếp nhanh trong một mô hình duy nhất, cho phép người dùng kiểm soát "ngân sách suy nghĩ" (thinking budget) — đánh đổi độ trễ lấy độ sâu suy luận. -
Điều này đạt được bằng cách huấn luyện trên cả dữ liệu suy nghĩ và không suy nghĩ, chứ không phải qua các checkpoint mô hình riêng biệt.
-
Ổn định huấn luyện ở quy mô lớn đòi hỏi các kỹ thuật mới vượt xa các thực hành chuẩn. Soft-capping logit (Logit soft-capping) (Gemma 2) truyền các điểm chú ý qua \(s \cdot \tanh(\text{logits} / s)\) với một mũ mềm (soft cap) \(s\) (thường 30–50) để ngăn tăng trưởng không giới hạn.
-
QK-Norm (Qwen3) áp dụng RMSNorm cho các vector truy vấn và key trước khi tính điểm chú ý, thay thế nhu cầu về QKV bias. QK-Clip (bộ tối ưu hóa MuonClip của Kimi K2) giám sát logit chú ý tối đa trong quá trình huấn luyện và điều chỉnh tỷ lệ các ma trận trọng số query-key khi chúng vượt quá một ngưỡng, cho phép tiền huấn luyện ổn định các mô hình 1T tham số với không có sự kiện mất ổn định nào.
-
Huấn luyện độ chính xác hỗn hợp FP8 (DeepSeek-V3) sử dụng số chấm động 8-bit cho các phép nhân ma trận nặng tính toán trong các lượt truyền xuôi và ngược trong khi giữ trọng số chính (master weights) ở độ chính xác cao hơn.
-
Điều này xấp xỉ tăng gấp đôi thông lượng so với huấn luyện BF16/FP16 với suy giảm chất lượng không đáng kể. DeepSeek-V3 đã huấn luyện mô hình 671B tham số chỉ trong 2.8M GPU-giờ H800 — một phần nhỏ so với các mô hình tương đương — phần lớn là nhờ tối ưu hóa kỹ thuật này và các tối ưu hóa kỹ thuật khác.
Bài tập lập trình (dùng CoLab hoặc notebook)¶
-
Cài đặt một đường ống sinh tăng cường truy xuất đơn giản từ đầu. Đánh chỉ mục một tập tài liệu sử dụng TF-IDF (file 02), truy xuất đoạn văn có liên quan nhất cho một truy vấn, và thêm nó vào prompt.
import jax.numpy as jnp import math from collections import Counter # Cơ sở tri thức: một tập các đoạn văn ngắn knowledge_base = [ "The Eiffel Tower is a wrought-iron lattice tower in Paris, France. It was constructed from 1887 to 1889 as the centerpiece of the 1889 World's Fair.", "The Great Wall of China is a series of fortifications built along the northern borders of China. Construction began in the 7th century BC.", "Photosynthesis is the process by which plants convert sunlight, water, and carbon dioxide into glucose and oxygen using chlorophyll.", "The theory of general relativity, published by Albert Einstein in 1915, describes gravity as the curvature of spacetime caused by mass and energy.", "Python is a high-level programming language known for its simple syntax and readability. It was created by Guido van Rossum and released in 1991.", "The mitochondria are organelles found in eukaryotic cells. They generate most of the cell's supply of ATP, used as a source of chemical energy.", ] # Xây dựng chỉ mục TF-IDF (tái sử dụng các khái niệm từ file 02) def tokenise(text): return text.lower().split() vocab = sorted(set(w for doc in knowledge_base for w in tokenise(doc))) word2idx = {w: i for i, w in enumerate(vocab)} V = len(vocab) N = len(knowledge_base) # Tần số tài liệu doc_freq = Counter() for doc in knowledge_base: for w in set(tokenise(doc)): doc_freq[w] += 1 def tfidf_vector(text): words = tokenise(text) counts = Counter(words) vec = jnp.zeros(V) for w, c in counts.items(): if w in word2idx: tf = 1 + math.log(c) idf = math.log(N / (doc_freq.get(w, 0) + 1)) vec = vec.at[word2idx[w]].set(tf * idf) return vec # Đánh chỉ mục tất cả tài liệu doc_vectors = jnp.stack([tfidf_vector(doc) for doc in knowledge_base]) def cosine_sim(a, b): return jnp.dot(a, b) / (jnp.linalg.norm(a) * jnp.linalg.norm(b) + 1e-8) def retrieve(query, top_k=2): """Truy xuất top-k đoạn văn có liên quan nhất cho một truy vấn.""" q_vec = tfidf_vector(query) sims = jnp.array([cosine_sim(q_vec, doc_vectors[i]) for i in range(N)]) top_indices = jnp.argsort(-sims)[:top_k] return [(int(i), float(sims[i]), knowledge_base[int(i)]) for i in top_indices] # Kiểm tra truy xuất queries = [ "Who built the Eiffel Tower?", "How do plants make food?", "What did Einstein discover?", ] for query in queries: results = retrieve(query, top_k=1) print(f"\nQuery: '{query}'") for idx, sim, passage in results: print(f" Retrieved (sim={sim:.3f}): '{passage[:80]}...'") # Tạo prompt kiểu RAG context = results[0][2] rag_prompt = f"Context: {context}\n\nQuestion: {query}\nAnswer:" print(f" RAG prompt:\n {rag_prompt[:120]}...") -
Cài đặt giải mã suy đoán với một mô hình dự thảo và mục tiêu đồ chơi. Chứng minh rằng đầu ra được chấp nhận khớp với phân bố của mô hình mục tiêu.
import jax import jax.numpy as jnp # Mô phỏng mô hình dự thảo (nhanh, kém chính xác) và mô hình mục tiêu (chậm, chính xác) vocab_size = 8 seq_len = 5 key = jax.random.PRNGKey(42) # Mô hình mục tiêu: trả về logits khi nhận một chuỗi def target_model(seq, key): """Mô hình mục tiêu mô phỏng: tạo logit token (tốn kém).""" k1, k2 = jax.random.split(key) logits = jax.random.normal(k1, (len(seq), vocab_size)) * 2 for i in range(len(seq)): logits = logits.at[i, (seq[i] + 1) % vocab_size].add(3.0) return logits def draft_model(seq, key): """Mô hình dự thảo mô phỏng: tương tự nhưng nhiều nhiễu hơn (rẻ).""" k1, k2 = jax.random.split(key) logits = jax.random.normal(k1, (len(seq), vocab_size)) for i in range(len(seq)): logits = logits.at[i, (seq[i] + 1) % vocab_size].add(2.0) return logits def sample_token(logits, key): return jax.random.categorical(key, logits) def speculative_decode(prefix, draft_steps=3, key=jax.random.PRNGKey(0)): """Giải mã suy đoán: dự thảo đề xuất, mục tiêu xác minh.""" seq = list(prefix) total_accepted = 0 total_proposed = 0 for _ in range(4): key, *subkeys = jax.random.split(key, draft_steps + 3) draft_tokens = [] draft_probs = [] draft_seq = list(seq) for i in range(draft_steps): d_logits = draft_model(jnp.array(draft_seq), subkeys[i]) d_probs = jax.nn.softmax(d_logits[-1]) tok = sample_token(d_logits[-1], subkeys[i]) draft_tokens.append(int(tok)) draft_probs.append(d_probs) draft_seq.append(int(tok)) target_logits = target_model(jnp.array(draft_seq), subkeys[draft_steps]) target_start = len(seq) - 1 accepted = 0 for i in range(draft_steps): t_probs = jax.nn.softmax(target_logits[target_start + i]) d_prob = draft_probs[i][draft_tokens[i]] t_prob = t_probs[draft_tokens[i]] accept_prob = jnp.minimum(1.0, t_prob / (d_prob + 1e-10)) key, accept_key = jax.random.split(key) if jax.random.uniform(accept_key) < accept_prob: seq.append(draft_tokens[i]) accepted += 1 else: key, resample_key = jax.random.split(key) adjusted = jnp.maximum(0, t_probs - draft_probs[i]) adjusted = adjusted / (adjusted.sum() + 1e-10) new_tok = jax.random.categorical(resample_key, jnp.log(adjusted + 1e-10)) seq.append(int(new_tok)) break total_accepted += accepted total_proposed += draft_steps return seq, total_accepted, total_proposed prefix = [0, 1] result_seq, accepted, proposed = speculative_decode(prefix) acceptance_rate = accepted / proposed if proposed > 0 else 0 print(f"Prefix: {prefix}") print(f"Generated sequence: {result_seq}") print(f"Draft proposals: {proposed}") print(f"Accepted: {accepted}") print(f"Acceptance rate: {acceptance_rate:.1%}") print(f"Speedup potential: {(accepted + proposed) / proposed:.2f}x") -
Xây dựng một vòng lặp huấn luyện DPO đơn giản. Với các cặp hoàn thiện được ưa thích và không được ưa thích, cập nhật một mô hình nhỏ sử dụng mất mát DPO.
import jax import jax.numpy as jnp # Mô hình ngôn ngữ tí hon: phép chiếu tuyến tính từ one-hot sang logits vocab_size = 10 seq_len = 4 key = jax.random.PRNGKey(42) k1, k2 = jax.random.split(key) # Tham số chính sách hiện tại (có thể huấn luyện) theta = jax.random.normal(k1, (vocab_size, vocab_size)) * 0.1 # Tham số chính sách tham chiếu (bản sao đông lạnh của theta ban đầu) theta_ref = theta.copy() def log_prob_sequence(params, sequence): """Tính log P(sequence) dưới một mô hình tự hồi quy đơn giản.""" total = 0.0 for t in range(1, len(sequence)): logits = params[sequence[t-1]] log_probs = jax.nn.log_softmax(logits) total += log_probs[sequence[t]] return total def dpo_loss(theta, theta_ref, preferred, dispreferred, beta=0.1): """Mất mát Tối ưu hóa Ưu tiên Trực tiếp cho một cặp.""" log_pi_w = log_prob_sequence(theta, preferred) log_pi_l = log_prob_sequence(theta, dispreferred) log_ref_w = log_prob_sequence(theta_ref, preferred) log_ref_l = log_prob_sequence(theta_ref, dispreferred) return -jax.nn.log_sigmoid( beta * ((log_pi_w - log_ref_w) - (log_pi_l - log_ref_l)) ) # Tập dữ liệu ưu tiên: (prompt_prefix, preferred_completion, dispreferred_completion) preferences = [ (jnp.array([1, 3, 5, 7]), jnp.array([1, 3, 5, 2])), (jnp.array([0, 2, 4, 6]), jnp.array([0, 2, 4, 9])), (jnp.array([3, 3, 3, 3]), jnp.array([3, 3, 3, 0])), (jnp.array([5, 6, 7, 8]), jnp.array([5, 6, 7, 1])), ] grad_fn = jax.jit(jax.grad(dpo_loss)) lr = 0.05 print("Training DPO...") for epoch in range(100): total_loss = 0.0 for preferred, dispreferred in preferences: loss = dpo_loss(theta, theta_ref, preferred, dispreferred) grads = grad_fn(theta, theta_ref, preferred, dispreferred) theta = theta - lr * grads total_loss += loss if (epoch + 1) % 20 == 0: avg_loss = total_loss / len(preferences) print(f" Epoch {epoch+1}: avg DPO loss = {avg_loss:.4f}") print("\nPreference check after DPO training:") for preferred, dispreferred in preferences: lp_w = log_prob_sequence(theta, preferred) lp_l = log_prob_sequence(theta, dispreferred) print(f" Preferred {list(preferred.astype(int))}: logP={lp_w:.3f} " f"Dispreferred {list(dispreferred.astype(int))}: logP={lp_l:.3f} " f"{'correct' if lp_w > lp_l else 'WRONG'}")