F · Training Methods & Model Adaptation
Fine-tuning (SFT) · dạy tiếp model đã học bằng cặp yêu cầu – trả lời mẫu
SFT lấy một mô hình đã học nền tảng rồi dạy tiếp bằng các cặp yêu cầu – câu trả lời mẫu, để nó trả lời theo chỉ dẫn và đúng định dạng mong muốn.
1Định nghĩa
Fine-tuning có giám sát (Supervised Fine-Tuning, viết tắt SFT) là cách dạy tiếp một mô hình ngôn ngữ đã qua pretraining bằng một tập nhỏ hơn nhiều gồm các cặp yêu cầu và câu trả lời mẫu. Điểm xuất phát là một checkpoint, tức bản lưu toàn bộ trọng số đã học, chứ không phải số ngẫu nhiên; sau SFT mô hình biết trả lời theo chỉ dẫn, giữ đúng giọng điệu hoặc định dạng như JSON, thay vì chỉ viết tiếp một đoạn văn.
Mỗi mẫu được ghép thành một chuỗi token qua khuôn mẫu hội thoại, dịch đi một vị trí để có đáp án cho từng token kế tiếp, rồi hàm mất mát chỉ chấm điểm phần câu trả lời. Backward và AdamW cập nhật trọng số: toàn bộ trong full fine-tuning, hoặc chỉ một adapter nhỏ nếu dùng LoRA. Sau khi kiểm tra trên câu hỏi chưa thấy, gói trọng số được dùng để phục vụ suy luận hoặc làm điểm xuất phát cho preference training.
Ví dụ đời thường: SFT giống như tuyển một sinh viên đã tốt nghiệp đại học, tức đã có kiến thức nền từ pretraining, vào làm tư vấn viên ngân hàng rồi cho học một bộ tài liệu gồm vài nghìn tình huống khách hỏi và nhân viên trả lời mẫu. Người đó không học lại toàn bộ kiến thức nền mà học cách xưng hô, cách trình bày ngắn gọn và quy định của ngân hàng. Ví dụ này dừng lại ở chỗ: sinh viên có thể tự hỏi lại khi chưa hiểu, còn mô hình chỉ bắt chước phân phối câu chữ trong các mẫu đã thấy.
2Luồng
Luồng đi từ checkpoint nền đến checkpoint SFT (sáu bước huấn luyện) rồi sang phục vụ suy luận (bốn bước). Hai nửa chỉ gặp nhau ở chat template và token kết thúc lượt, nên đó là chỗ lỗi hay xuất hiện nhất. Chọn từng nút để mở bài liên quan.
- Nạp checkpoint nền, giữ đúng tokenizer và config
Điểm xuất phát là trọng số đã pretrain, không khởi tạo ngẫu nhiên; ghi lại model id, revision và phiên bản tokenizer.
- Chuẩn bị cặp yêu cầu – trả lời qua chat template
Gắn vai trò, chèn token điều khiển, tách sẵn tập đánh giá chưa dùng để train.
- Tạo nhãn dịch một vị trí và che phần câu hỏi
Mỗi vị trí học đoán token kế tiếp; chỉ token của câu trả lời giữ nhãn thật.
- Forward và cross-entropy trên token trả lời
Tính xác suất model gán cho đáp án rồi lấy trung bình trên các token hợp lệ.
- Backward và AdamW cập nhật toàn bộ trọng số
Gradient chảy ngược qua mọi lớp; learning rate nhỏ để không phá kiến thức nền.
- Vài epoch, đánh giá độc lập, lưu checkpoint SFT
Chọn checkpoint theo kết quả trên dữ liệu chưa thấy rồi lưu gói chỉ gồm trọng số.
- Phục vụ 1 · Nhận request dạng hội thoại
Hạ tầng giữ nguyên; payload phải là danh sách tin nhắn theo vai trò.
- Phục vụ 2 · Tokenize bằng đúng template và mở lượt trợ lý
Bật add_generation_prompt và căn token kết thúc với template đã train.
- Phục vụ 3 · Prefill rồi decode từng token
Giống hệt model nền; chỉ khác giá trị trọng số.
- Phục vụ 4 · Dừng, giải mã và trả văn bản
Kết thúc bằng token đóng lượt, không có loss hay cập nhật nào lúc phục vụ.
Mã Mermaid
flowchart TD
step1["Nạp checkpoint nền, giữ đúng tokenizer và config"]
step2["Chuẩn bị cặp yêu cầu – trả lời qua chat template"]
step3["Tạo nhãn dịch một vị trí và che phần câu hỏi"]
step4["Forward và cross-entropy trên token trả lời"]
step5["Backward và AdamW cập nhật toàn bộ trọng số"]
step6["Vài epoch, đánh giá độc lập, lưu checkpoint SFT"]
step7["Phục vụ 1 · Nhận request dạng hội thoại"]
step8["Phục vụ 2 · Tokenize bằng đúng template và mở lượt trợ lý"]
step9["Phục vụ 3 · Prefill rồi decode từng token"]
step10["Phục vụ 4 · Dừng, giải mã và trả văn bản"]
step1 --> step2
step2 --> step3
step3 --> step4
step4 --> step5
step5 --> step6
step6 --> step7
step7 --> step8
step8 --> step9
step9 --> step10 3Giải pháp
Bài toán: model đã biết nhiều nhưng chưa biết cư xử
Một mô hình chỉ mới pretrain đã học cách viết tiếp văn bản. Nếu bạn gửi "Thủ đô của Việt Nam là gì?", nó có thể viết tiếp thêm vài câu hỏi giống thế vì trong dữ liệu pretraining, câu hỏi thường đứng cạnh các câu hỏi khác. Nó chưa hề được dạy rằng sau một yêu cầu thì phải đưa ra câu trả lời.
SFT giải đúng bài toán đó. Ta đưa cho mô hình hàng nghìn đến hàng chục nghìn ví dụ về hành vi mong muốn: một yêu cầu, rồi câu trả lời mà ta muốn thấy. Mục tiêu chính là định hình hành vi (làm theo chỉ dẫn, giọng điệu, định dạng đầu ra), không phải nhồi thêm lượng lớn kiến thức mới; việc nạp kiến thức lĩnh vực mới thường thuộc về continued pretraining hoặc truy xuất tài liệu.
Cần phân biệt với Retrieval-Augmented Generation (RAG, tạo câu trả lời có truy xuất): RAG đưa tài liệu vào prompt và không đổi trọng số, còn SFT đổi trọng số hoặc adapter. Hai cách có thể dùng cùng nhau khi ứng dụng cần cả dữ liệu mới lẫn hành vi riêng.
Khái niệm tối thiểu cần nắm trước khi đi vào các bước
Token là một mảnh văn bản (một từ, một phần của từ hoặc một dấu câu). Tokenizer là bộ chuyển văn bản thành dãy token và gán cho mỗi token một số nguyên gọi là token ID; ID đó là chỉ số hàng trong bảng embedding, nên dùng sai tokenizer nghĩa là tra nhầm hàng.
Tại mỗi vị trí, mô hình xuất một danh sách điểm số gọi là logits, mỗi token trong từ điển có một điểm. Hàm softmax đổi các điểm này thành xác suất cộng lại bằng 1. Loss là một con số đo mức sai: với cross-entropy, loss tại một vị trí bằng trừ logarit tự nhiên của xác suất mà mô hình gán cho token đúng. Xác suất 0,5 cho loss khoảng 0,69, xác suất 0,25 cho khoảng 1,39, xác suất gần 1 cho loss gần 0.
Gradient cho biết mỗi trọng số nên tăng hay giảm bao nhiêu để loss giảm. Optimizer (ở đây là AdamW) dùng gradient để sửa trọng số; learning rate là độ lớn của mỗi lần sửa. Một epoch là một lượt đi qua toàn bộ dữ liệu huấn luyện. Các khái niệm này được dạy kỹ hơn ở các bài forward, loss, backward và AdamW; bài này chỉ cho biết SFT đặt chúng vào đâu.
Ví dụ chạy xuyên suốt cả bài
Để theo dõi từng bước, ta dùng một mẫu duy nhất, tự bịa cho mục đích minh họa. Người dùng hỏi: "Giờ mở cửa của ngân hàng là mấy giờ?" Câu trả lời mẫu: "Ngân hàng mở cửa từ 8 giờ đến 16 giờ." Để dễ đọc, ta coi mỗi từ là một token; tokenizer thật thường cắt khác (một từ có thể thành nhiều token).
Bước huấn luyện 1 · Nạp checkpoint nền, không khởi tạo ngẫu nhiên
Đầu vào là checkpoint đã pretrain cùng tokenizer và file cấu hình (config) của nó. Thao tác là nạp bằng đúng bộ nạp của kiến trúc (ví dụ from_pretrained của thư viện Transformers) và ghi lại model id, revision và phiên bản tokenizer. Lý do: tri thức ngôn ngữ nằm sẵn trong trọng số nên khởi tạo lại sẽ buộc phải pretrain lại từ đầu trên hàng nghìn tỷ token; còn tokenizer hay config lệch phiên bản thì token ID trỏ sai hàng embedding và kích thước ma trận không khớp, làm hỏng toàn bộ việc học.
Đầu ra là mô hình nằm trong bộ nhớ, giống hệt bản pretrain. Cách kiểm tra: một lượt forward thử chạy được, kích thước các ma trận khớp config, và loss trên vài mẫu trước khi huấn luyện được ghi lại làm mốc so sánh. Đừng nhầm hai artifact: checkpoint nền là đầu vào của bước này, còn checkpoint SFT là đầu ra của cả quy trình ở bước 6.
Bước huấn luyện 2 · Chuẩn bị cặp yêu cầu – trả lời qua chat template
Đầu vào là các mẫu hội thoại dạng danh sách tin nhắn, mỗi tin nhắn có vai trò system (chỉ dẫn hệ thống), user (người dùng) hoặc assistant (trợ lý). Thao tác là đưa chúng qua chat template của tokenizer: template chèn các token điều khiển đánh dấu chỗ bắt đầu và kết thúc từng lượt, rồi tokenizer đổi thành dãy token ID. Lý do: mô hình phải thấy lúc học đúng bố cục mà nó sẽ thấy lúc phục vụ, và mỗi họ model có bộ token điều khiển riêng, nên không được chép template của model khác dù cùng họ.
Với mẫu xuyên suốt, kết quả (minh họa, tên token điều khiển là giả định) là: [mở lượt user] Giờ mở cửa của ngân hàng là mấy giờ ? [kết thúc lượt] [mở lượt assistant] Ngân hàng mở cửa từ 8 giờ đến 16 giờ . [kết thúc lượt], tổng cộng 25 token. Cách đọc: in vài mẫu đã format và kiểm tra bằng mắt rằng nhãn vai trò đứng đúng chỗ, lượt assistant nằm sau lượt user và token kết thúc lượt có mặt. Ngay bước này cũng phải tách riêng tập đánh giá gồm các câu hỏi mới, vì lẫn vào sau sẽ làm mọi con số đẹp giả.
Bước huấn luyện 3 · Nhãn dịch một vị trí và mặt nạ chỉ câu trả lời
Mô hình ngôn ngữ học bằng cách đoán token kế tiếp: tại vị trí i, đầu vào là token thứ i và đáp án là token thứ i+1. Vì vậy nhãn chính là chuỗi đầu vào dịch sang trái một vị trí (kỹ thuật này ở bài tạo nhãn mục tiêu còn gọi là teacher forcing). Với mẫu 25 token, đầu vào là 24 token đầu, nhãn là 24 token sau.
Bước đặc trưng của SFT là mặt nạ: các nhãn thuộc phần system, user và padding (phần đệm cho các mẫu dài bằng nhau) được thay bằng giá trị bỏ qua, thường là −100. Lý do: câu hỏi của người dùng là ngữ cảnh được cho trước, không phải thứ ta muốn mô hình học cách viết; chấm điểm cả phần đó làm phí dung lượng học và có thể dạy mô hình tự sinh ra câu hỏi. Phần câu hỏi vẫn đi qua mô hình ở bước forward để làm ngữ cảnh.
Trong mẫu xuyên suốt, các nhãn còn lại là 12 token: mười một token của câu trả lời và token kết thúc lượt. Token mở lượt assistant không được chấm vì lúc phục vụ template sẽ tự chèn nó. Việc giữ token kết thúc lượt trong nhãn quan trọng: đó là cách mô hình học cách dừng. Cách đọc: số token góp loss của mỗi mẫu phải bằng độ dài câu trả lời cộng token kết thúc, không bằng độ dài cả chuỗi. Mặt nạ lệch một vị trí khiến mô hình học sai chỗ mà đường loss vẫn trông bình thường, nên phải in input, nhãn và mask của vài mẫu ra để đối chiếu.
Bước huấn luyện 4 · Forward và cross-entropy trên token trả lời
Toàn bộ chuỗi đi qua mô hình trong một lượt forward với causal mask (mỗi vị trí chỉ được nhìn các token bên trái nó). Tại mỗi vị trí, mô hình xuất logits cho cả từ điển, softmax đổi thành xác suất, rồi ta lấy xác suất của token đáp án. Loss tại vị trí đó là trừ logarit tự nhiên của xác suất ấy, và loss của mẫu là trung bình trên các vị trí còn nhãn.
Ví dụ số (minh họa): giả sử tại ba vị trí của câu trả lời mô hình gán xác suất 0,5; 0,25 và 0,8 cho token đúng. Loss từng vị trí lần lượt là 0,693; 1,386 và 0,223, trung bình bằng 0,768. Phải chia cho số token hợp lệ (ở đây là 3), không chia cho độ dài cả chuỗi, nhất là khi các mẫu trong cùng một batch có câu trả lời dài ngắn khác nhau; nếu không, mẫu có câu hỏi dài sẽ bị pha loãng.
Cách đọc: một mô hình hoàn toàn đoán mò đều trên từ điển V token có loss bằng ln V (ví dụ V = 50.000 cho khoảng 10,82); loss thấp hơn nghĩa là mô hình đặt nhiều xác suất hơn lên đáp án mẫu. Đó là xác suất của từng token, chưa phải điều khẳng định rằng cả câu đúng. Trong thực tế, thư viện thường tính loss theo từng khúc và loại sớm các vị trí bị che để không phải giữ một tensor logits quá lớn trong bộ nhớ.
Bước huấn luyện 5 · Backward và cập nhật toàn bộ trọng số bằng AdamW
Từ loss, lượt backward tính gradient cho mọi trọng số bằng quy tắc đạo hàm hợp (chain rule). Dù loss chỉ có ở các vị trí câu trả lời, gradient vẫn chảy ngược qua cả các vị trí của câu hỏi, vì cách mô hình đọc câu hỏi cũng ảnh hưởng đến câu trả lời. Sau đó AdamW cập nhật từng trọng số bằng trung bình trượt của gradient và của bình phương gradient. Với full fine-tuning, learning rate thường rất nhỏ (cỡ 1e-5 đến 2e-5 là mức hay gặp, cần thử trên dữ liệu của bạn) vì learning rate lớn có thể phá kiến thức nền nhanh hơn nhiều so với lúc train từ đầu.
Chi phí bộ nhớ là lý do người ta cân nhắc các lựa chọn khác. Ước tính thô, mang tính minh họa: mô hình 7 tỷ tham số lưu ở BF16 (2 byte mỗi tham số) tốn khoảng 14 GB trọng số và 14 GB gradient; AdamW giữ thêm hai số cho mỗi tham số, nếu mỗi số 4 byte thì thêm khoảng 56 GB, tổng khoảng 84 GB trước khi tính activation (kết quả trung gian giữ lại cho backward). Có ba cách giảm: tính lại activation khi cần, chia trạng thái cho nhiều GPU bằng ZeRO/FSDP, hoặc đóng băng mô hình gốc và chỉ học adapter bằng LoRA.
Cách đọc: theo dõi loss, độ lớn gradient (gradient norm) và độ lớn mỗi lần cập nhật. Gradient norm tăng vọt hoặc xuất hiện NaN (không phải số) thường báo learning rate hay lịch học sai, và nó hiện ra trước khi chất lượng kịp thay đổi. Khi dùng gradient accumulation (cộng dồn gradient qua nhiều micro-batch), phải giữ đúng cách chuẩn hóa loss theo token hợp lệ.
Bước huấn luyện 6 · Vài epoch, đánh giá trên dữ liệu chưa thấy, lưu checkpoint
SFT chỉ chạy vài epoch, thường từ 1 đến 3 trên tập chất lượng cao. Chạy quá nhiều lượt trên tập nhỏ khiến mô hình học vẹt từng câu chữ và quên bớt khả năng chung (catastrophic forgetting). Sau mỗi chặng, đánh giá hai mặt: tác vụ mới trên câu hỏi giữ riêng (độ đúng, đúng định dạng) và khả năng chung trên các bộ đo công khai để phát hiện sụt giảm.
Cách đọc kết quả: loss giảm trên tập train chưa nói lên điều gì về câu hỏi mới. Ví dụ số hoàn toàn minh họa: nếu mô hình trả lời đúng 40/40 câu train nhưng chỉ đúng 3/8 câu giữ riêng, khoảng cách đó cho thấy phần lớn là học thuộc. Hãy chọn checkpoint theo thước đo phản ánh mục tiêu dùng (kết quả trên tập giữ riêng, hoặc điểm preference nếu có), không mặc định lấy epoch cuối hay loss train thấp nhất. Khi chất lượng chững lại thì sửa dữ liệu và bộ đánh giá trước khi tăng số epoch: bài Llama 2 báo cáo rằng vài chục nghìn mẫu chất lượng cao tốt hơn hàng triệu mẫu kém.
Cuối cùng lưu hai loại artifact riêng. Gói để phục vụ chỉ cần trọng số, config, tokenizer và template. Gói để huấn luyện tiếp (resume) cần thêm trạng thái optimizer, scheduler và bộ sinh số ngẫu nhiên. Ghi kèm phiên bản dữ liệu, template, chính sách mặt nạ, công thức huấn luyện và điểm đánh giá để tái lập.
Bước phục vụ 1 · Nhận request: cùng hạ tầng, khác ở định dạng hội thoại
Khi đưa checkpoint SFT ra phục vụ, các khối như gateway, router và inference engine giữ nguyên như với model nền: trọng số được nạp cố định lên bộ nhớ GPU và không có loss hay cập nhật nào. Điều khác là hợp đồng đầu vào: vì model học trên hội thoại có vai trò, client nên gửi danh sách tin nhắn có cấu trúc thay vì chuỗi text tự ghép. Các tham số sinh (số token tối đa, sampling, chuỗi dừng) thuộc về request, không thuộc về trọng số.
Mỗi deployment nên có manifest ghi phiên bản model, tokenizer và template, vì cùng một prompt với template khác sẽ cho token khác và khóa cache khác. Serving không sửa được lỗi của SFT: yêu cầu nằm ngoài phân phối đã train (chỉ dẫn mới lạ, định dạng lạ) vẫn là chuyện của dữ liệu và đánh giá, không phải của cấu hình inference. Phần nhận request được dạy kỹ ở bài tiếp nhận yêu cầu.
Bước phục vụ 2 · Tokenize bằng đúng template và mở lượt trợ lý
Lúc huấn luyện, câu trả lời đã có sẵn nên template được gọi với add_generation_prompt bằng False. Lúc phục vụ, câu trả lời chưa tồn tại nên phải bật add_generation_prompt bằng True: template thêm vào cuối prompt token mở lượt của trợ lý, như một tín hiệu "đến lượt bạn viết". Thiếu tín hiệu này, mô hình có thể viết tiếp câu hỏi thay vì trả lời.
Đồng thời, token kết thúc (EOS, end of sequence) trong cấu hình sinh phải trùng với token đóng lượt mà template đã dùng khi huấn luyện, nếu không câu trả lời sẽ không dừng hoặc bị cắt sớm. Cách kiểm tra: cho cùng một hội thoại đi qua pipeline huấn luyện và pipeline phục vụ, rồi so hai dãy token ID; nếu chúng khác nhau thì đó là lỗi triển khai chứ không phải lỗi mô hình. Xem thêm bài chuyển prompt thành token.
Bước phục vụ 3 · Prefill rồi decode từng token, giống hệt model nền
Prefill xử lý toàn bộ prompt song song để điền KV cache (bộ nhớ giữ các vector key/value của những token đã xử lý) và lấy logits ở vị trí cuối để chọn token đầu tiên. Decode lặp lại: đưa token vừa chọn vào mạng, đọc KV cache cũ, nối thêm K/V mới và chọn token kế bằng sampling. Hai pha này không đổi: SFT không thay số lớp, kích thước ma trận hay thuật toán nên mọi tối ưu của engine như chia nhỏ prefill hay dùng lại tiền tố vẫn dùng được.
Trong suốt vòng lặp, trọng số đứng yên; thứ duy nhất lớn dần theo mỗi token là KV cache của request. Vì vậy mọi cảm giác mô hình tự học trong lúc trò chuyện chỉ là hiệu ứng của ngữ cảnh. Giọng điệu và định dạng đúng chỉ đến từ trọng số đã đổi ở bước 5. Muốn đổi hành vi phải huấn luyện lại, không phải chỉnh decode. Chi tiết hai pha có ở bài prefill và decode.
Bước phục vụ 4 · Dừng, giải mã và trả văn bản
Vòng decode dừng khi mô hình sinh token đóng lượt, khi gặp chuỗi dừng (stop string) hoặc khi chạm số token tối đa. Các token ID được đổi ngược thành văn bản (detokenize), bỏ các token điều khiển ẩn, và khi stream thì phải xử lý từng phần để văn bản stream khớp văn bản cuối. Sau đó KV cache của request được giải phóng hoặc đưa vào diện tái sử dụng.
Nếu câu trả lời không dừng hoặc dừng quá sớm, hãy nghi ngờ EOS và template trước khi nghi ngờ trọng số; nhiều ca chỉ là lỗi so khớp. Đừng mang khái niệm huấn luyện sang đây để gỡ lỗi: ở phía phục vụ chỉ có request, trọng số, KV và văn bản. Bước kết thúc chung được dạy ở bài dừng và trả văn bản.
Kết luận được rút ra và không được rút ra
Có thể kết luận: sau SFT, với loại câu hỏi giống phân phối dữ liệu huấn luyện, mô hình có xu hướng trả lời đúng bố cục và giọng điệu hơn mô hình nền, và điều đó đo được trên tập giữ riêng. Không thể kết luận: loss giảm nghĩa là mô hình hiểu; mô hình đã học được kiến thức mới đáng tin; hoặc mô hình an toàn với mọi chỉ dẫn. Mô hình vẫn có thể bịa nội dung đúng định dạng, nên đúng format không đủ chứng minh đúng nội dung.
Thực hành trên Bài Lab tổng hợp
Giai đoạn 9 (SFT: chat template và response mask) của Bài Lab tổng hợp cho bạn tự quan sát bước 2 và 3 trên dữ liệu thật của lab, dựa trên các giai đoạn 3 đến 6 (forward, cross-entropy, backward, AdamW) đã chạy trước đó. Hãy tự đếm số token của một câu trả lời, dự đoán số token góp loss rồi đối chiếu với kết quả lab in ra. Con số nào lệch thì xem lại mặt nạ trước khi nghi ngờ mô hình.
4Profiling
- Chất lượng tác vụ và khả năng chung
So checkpoint gốc với checkpoint SFT trên cùng bộ đánh giá độc lập, gồm tập câu hỏi mới của tác vụ và bộ đo năng lực chung. Ghi cả độ đúng lẫn việc đúng định dạng, vì hai thước này tách nhau. Kết quả chỉ có nghĩa với tập đã đo; sụt điểm khả năng chung là dấu hiệu cần trộn thêm dữ liệu chung hoặc giảm learning rate.
- Mặt nạ và số token hợp lệ
Ghi lại số token góp loss ở mỗi batch và so với độ dài câu trả lời. Số này phải khớp; lệch là dấu hiệu mặt nạ hoặc template sai, và nó lộ ra ở đây sớm hơn so với khi nhìn chất lượng.
- Chi phí và bộ nhớ
Liệt kê tensor được cập nhật, bộ nhớ optimizer, gradient norm, training loss và validation loss, bộ nhớ đỉnh (gồm cả activation) và thời gian huấn luyện. Không cộng các moment của optimizer vào số tham số của model.
- Template khớp giữa huấn luyện và phục vụ
Cho cùng một hội thoại qua cả hai pipeline và so dãy token ID, kể cả token mở lượt và token kết thúc. Theo dõi tỷ lệ request không hợp lệ và độ dài input để phát hiện client gửi sai định dạng.
Mẹo đo lường: ghim số liệu trên workload thật, ghi cả p50/p95/p99 thay vì chỉ trung bình, và luôn ghi lại điều kiện chạy (batch, cache, đồng thời, phần cứng) trước và sau khi tối ưu. Số đo thiếu điều kiện chạy thì không so sánh được.
5Ví dụ
Model trả kết quả có cấu trúc
Dùng các cặp yêu cầu và kết quả JSON đúng định dạng để tiếp tục huấn luyện một checkpoint. Hãy dự đoán trước: nếu chỉ đo tỷ lệ parse được JSON thì bạn kết luận được gì? Đáp án: chỉ biết định dạng đúng; vẫn phải đo độ đúng nội dung bằng đáp án độc lập, vì mô hình có thể sinh JSON hợp lệ nhưng sai giá trị.
Mặt nạ lệch một vị trí
Giả sử mặt nạ bị dịch sai một vị trí so với nhãn, nên token mở lượt assistant bị chấm còn token kết thúc thì không. Loss vẫn giảm bình thường. Tự kiểm tra: dấu hiệu nào lộ ra lỗi? Đáp án: mô hình thường không dừng đúng chỗ lúc phục vụ, và số token hợp lệ khác độ dài câu trả lời cộng một token kết thúc; chỉ in input, nhãn và mask cạnh nhau mới thấy ngay.
Thích nghi với hội thoại chuyên ngành
Nạp model nền và học trên hỏi đáp đã được kiểm tra. Bộ giữ riêng phải gồm câu hỏi mới chứ không chỉ viết lại mẫu train, và phải theo dõi việc model quên khả năng chung. Thử trả lời: nếu loss train rất thấp nhưng câu hỏi hơi đổi cách diễn đạt thì mô hình sai, bạn nên làm gì? Đáp án: giảm số epoch hoặc learning rate, thêm dữ liệu đa dạng hơn và kiểm tra lại trên tập giữ riêng.
Gỡ lỗi khi model không dừng
Sau khi triển khai, một số câu trả lời kéo dài mãi. Hãy liệt kê thứ tự kiểm tra. Đáp án: so token kết thúc của cấu hình sinh với token đóng lượt của template; kiểm tra add_generation_prompt đã bật; so dãy token ID giữa huấn luyện và phục vụ; chỉ sau đó mới nghi ngờ trọng số.
6Thuật ngữ
- Supervised Fine-Tuning (SFT)
- Tinh chỉnh có giám sát: tiếp tục huấn luyện một checkpoint đã có bằng các cặp yêu cầu và câu trả lời mẫu do người hoặc model khác viết sẵn.
- Full fine-tuning
- Tinh chỉnh toàn bộ: mọi trọng số của model đều nhận gradient và được optimizer cập nhật, khác với việc chỉ học một adapter nhỏ như LoRA.
- Cặp yêu cầu – trả lời (instruction/response pair)
- Một mẫu dữ liệu gồm yêu cầu của người dùng và câu trả lời mong muốn của trợ lý; đây là thứ SFT bắt chước.
- Chat template
- Khuôn mẫu đi kèm tokenizer, biến danh sách tin nhắn theo vai trò (system, user, assistant) thành một chuỗi token có chèn token điều khiển đánh dấu từng lượt nói.
- Token điều khiển (special token)
- Token đặc biệt không phải chữ thường, ví dụ dấu mở lượt của trợ lý hay dấu kết thúc lượt; mỗi họ model có bộ riêng.
- Response mask
- Mặt nạ quy định token nào được tính vào loss; trong SFT chỉ token thuộc câu trả lời của trợ lý được chấm, phần còn lại chỉ làm ngữ cảnh.
- Ignore index (−100)
- Giá trị đặt vào nhãn để báo vị trí đó bị bỏ khỏi phép tính loss, dùng cho phần câu hỏi và padding.
- Cross-entropy / NLL
- Với một token đáp án, loss bằng −ln của xác suất model gán cho token đó; SFT làm trung bình giá trị này trên các token hợp lệ.
- Valid tokens
- Các token không bị che mặt nạ; số này là mẫu số khi lấy trung bình loss.
- Epoch
- Một lượt đi qua toàn bộ tập huấn luyện; SFT thường chỉ chạy vài epoch.
- Held-out evaluation
- Đánh giá trên câu hỏi hoàn toàn mới, chưa từng dùng để cập nhật trọng số, để biết model khái quát hay chỉ học thuộc.
- Catastrophic forgetting
- Hiện tượng model làm tốt tác vụ mới nhưng mất dần khả năng chung đã học lúc pretraining.
- add_generation_prompt
- Cờ của chat template; khi bật lúc phục vụ, template thêm token mở lượt trợ lý vào cuối prompt để model bắt đầu viết câu trả lời.
- Weights-only artifact
- Gói dùng để phục vụ chỉ gồm trọng số, config và tokenizer; không kèm trạng thái optimizer cần để huấn luyện tiếp.
Glossary (15)
- Token và token ID
- Token là một mảnh văn bản (một từ, một phần từ hoặc một dấu); tokenizer gán cho mỗi token một số nguyên gọi là token ID, chính là chỉ số hàng trong bảng embedding.
- Model weights
- Các tham số số học được học và lưu trong checkpoint.
- Checkpoint
- Bản lưu trạng thái model; phạm vi states phụ thuộc mục đích serving hay resume.
- Tokenizer
- Bộ chuyển đổi văn bản và chuỗi mã token theo bảng từ vựng.
- Logits
- Điểm số chưa chuẩn hóa cho các token ứng viên trước khi chọn token.
- Forward pass
- Tính kết quả model từ đầu vào theo weights hiện tại.
- Backward pass
- Tính gradients ngược qua các phụ thuộc của forward graph.
- Mask
- Quy tắc vị trí nào được nhìn nhau hoặc được tính vào loss.
- Batch
- Nhóm công việc hoặc mẫu được xử lý trong một lượt tính.
- Context
- Chuỗi token trước vị trí hiện tại mà model được phép sử dụng.
- Cache
- Bộ nhớ giữ kết quả có thể dùng lại; trong attention thường giữ key/value vectors.
- Prefix
- Phần đầu của một chuỗi token; cache reuse cần phần đầu tương thích.
- Brain Floating Point 16-bit
- Định dạng số 16 bit (BF16) có độ lớn biểu diễn và precision khác định dạng floating point 16 bit.
- Random Number Generator
- Bộ sinh số ngẫu nhiên; trạng thái có thể cần lưu để resume tương ứng.
- Runtime
- Phần mềm quản lý việc thực thi, buffers và phụ thuộc giữa phép toán.
