Từ 13M tham số đến một executor code nhỏ có kiểm chứng
Đây là bản tổng kết công khai ở mức research preview. Một số recipe, grammar sinh dữ liệu, đường dẫn hạ tầng, checkpoint và chi tiết triển khai được giữ lại để tránh làm sai lệch ưu tiên công bố sau này.
Tóm tắt
Dự án bắt đầu từ một câu hỏi rất thực dụng: liệu có thể huấn luyện từ số 0 một mô hình code nhỏ, ưu tiên tiếng Việt, biết trả lời cơ bản, biết hỏi lại hoặc từ chối khi thiếu chắc chắn, và quan trọng nhất là không được đánh giá chỉ bằng loss?
Trong vài ngày, pipeline đã đi qua nhiều thế hệ: tạo corpus và tokenizer; pretrain/SFT mô hình khoảng 13M tham số; tối ưu recipe trên một GPU Blackwell; xây bộ kiểm thử thực thi; thử self-distillation; mở rộng curriculum; tăng lên khoảng 52M; và cuối cùng tách phần “suy luận thuật toán” khỏi phần “chép identifier” bằng một lớp giao diện tất định.
Kết quả quan trọng nhất không phải một con số duy nhất. Đó là một bản đồ khá rõ về thứ gì thực sự có tác dụng:
- Dung lượng model phá được trần mà model 13M không vượt qua.
- Thiết kế giao diện có thể quan trọng hơn việc tăng thêm tham số.
- Độ phủ cấu trúc và độ sâu của dữ liệu quyết định vùng generalization.
- Self-distillation chỉ có ích khi model đã sinh được lời giải đúng.
- GPU utilization cao không đồng nghĩa chất lượng cao hơn.
- Promotion gate và checkpoint lineage cứu cả dự án khỏi những run lỗi hoặc metric đẹp giả.
1. Giai đoạn dữ liệu và smoke training
Pipeline ban đầu thu thập code Python, lọc bằng AST, khử trùng lặp, ghi provenance, xây tokenizer và tạo hai nhóm SFT:
- Bài code tiếng Việt có assertions chạy thật.
- Hành vi giao tiếp: hỏi lại khi thiếu dữ kiện, thừa nhận không chắc, và từ chối yêu cầu gây hại.
Smoke run trên GPU phổ thông chứng minh chuỗi A-to-Z hoạt động: dữ liệu có thể được chuẩn bị, tokenizer được khóa, model được pretrain/SFT và checkpoint được đưa lên object storage. Mô hình khoảng 12,66M tham số nhìn thấy 24,47M token train; pretrain loss giảm từ 9,7476 xuống 5,8610 và SFT loss giảm từ 6,6090 xuống 2,2739.
Đây chưa phải coding assistant. Giá trị của nó là xác nhận pipeline và tìm ra những lỗi rất thật: file test compiler/formatter có thể chứa cú pháp bệnh lý; compile toàn cây AST đôi khi chạm lỗi nội bộ; và dữ liệu “hợp lệ với compiler” chưa chắc là dữ liệu “tốt để học code”.
2. V3.2: trainer nghiên cứu trên một Blackwell
V3.2 chuyển sang một RTX PRO 6000 Blackwell 96 GB và thêm các yếu tố của một trainer nghiêm túc: resume giữa epoch, grouped split, best-validation checkpoint, GQA, RoPE, RMSNorm, SwiGLU, Q/K normalization và các objective phụ được kiểm soát.
Mô hình 12,72M chỉ có khoảng 1,92 unique token trên mỗi tham số. Sau bốn vòng lặp corpus, main validation loss giảm từ 5,8361 xuống 5,1485. Run ổn định và checkpoint đầy đủ, nhưng đây cũng là bằng chứng đầu tiên rằng pipeline có thể đúng về kỹ thuật mà vẫn thiếu dữ liệu để đạt năng lực mong muốn.
3. V4.1: tối ưu bằng đối chứng, không bằng cảm giác
Thay vì mặc định batch lớn, masked-input regularization, multi-token prediction hay optimizer mới là tốt, V4.1 tổ chức tournament từ cùng checkpoint và nhiều seed.
Winner theo chất lượng/chi phí là AdamW với next-token objective thuần, khoảng 32k token mỗi update và learning rate trung bình. Các objective phụ giảm throughput mạnh nhưng chỉ thay đổi validation loss rất nhỏ. Continuation đưa main validation từ 5,0340 xuống 4,8261; sau compile, throughput vượt một triệu token/giây.
Nhưng executable evaluation cho kết quả tỉnh táo hơn:
- Syntax hợp lệ: 100%.
- Pass@1: 0%.
- Action accuracy trong evaluator ban đầu: 0%.
Model đã học “hình dạng code” nhưng chưa tuân thủ hợp đồng hàm và evaluator hành vi lại bị lệch lớp. Đây là ví dụ điển hình cho việc loss và syntax có thể che giấu thất bại năng lực.
4. V5-V7: sửa capability, self-distillation và curriculum
V5 đưa vào exact-signature completion, identifier augmentation và policy router bốn lớp. Router đạt macro-F1 khoảng 0,896 trên checkpoint lưu, nhưng code generalization vẫn bằng 0.
V6 thử verified self-distillation theo hướng incremental: không chạy lại các phase cũ, chỉ resume checkpoint từ stage, sinh nhiều candidate, chạy verifier và chỉ distill lời giải đúng. Kết quả là 0 lời giải đúng trong 8.064 candidate. Đây là negative result quan trọng: nếu reward gần như toàn số 0, tăng pass@k chỉ làm đốt compute.
V7 chuyển sang curriculum có kiểm chứng với 260 algorithm family, chia family-level trước khi tạo biến thể. Dataset gồm 14.080 train, 320 validation, 352 test và 352 robustness example. Tuy nhiên model 13M vẫn không tạo được executable pass@1 khác 0. Kết luận lúc này khá mạnh: với recipe và dữ liệu hiện tại, 13M đã chạm một capacity wall thực dụng.
5. Bước nhảy 52M và phát hiện về interface
Một capacity probe khoảng 52M tham số đạt raw pass@1 khoảng 52% trên một sample synthetic 100 bài, trong khi model 13M vẫn ở 0. Điều này cho thấy tăng dung lượng có tác dụng thật.
Tuy nhiên, lỗi phổ biến còn lại không phải thuật toán mà là identifier binding: model có thể chọn đúng cấu trúc vòng lặp nhưng sử dụng tên biến từ một mẫu trước đó. Cách giải quyết hiệu quả nhất không phải bắt model học chép tên ngày càng lạ, mà là thay đổi giao diện:
- Chuẩn hóa chữ ký về không gian canonical ngắn.
- Model sinh code trong không gian đó.
- AST gắn lại tên thật một cách tất định.
- Chạy assertions.
Trên synthetic held-out grammar, cùng model 52M đạt khoảng 83% test, 94% identifier robustness và 100% syntax. Đây là kết quả mạnh nhất của dự án, nhưng phạm vi phải được nói rõ: đây là benchmark synthetic có grammar xác định, chưa phải coding assistant tổng quát.
6. Cấu trúc chương trình, độ sâu và giới hạn generalization
Một probe tiếp theo cho thấy metric “novel combination” cao ban đầu vẫn có thể chỉ là slot filling trong một template cố định. Khi đổi thứ tự thao tác, lặp filter hoặc lặp transform, model từng thất bại 0/6.
Sau khi curriculum chứa nhiều cấu trúc pipeline hơn, kết quả tăng lên 5/6 trên probe cấu trúc và gần 99% trên held-out synthetic set cùng không gian primitive. Bài học là thêm primitive mới và thêm cấu trúc mới là hai việc khác nhau.
Depth coverage cho thấy quy luật rất nhất quán:
- Train tới depth 3: depth 4 rơi còn khoảng 16%.
- Train tới depth 6: depth 6 khoảng 90%, depth 7 khoảng 44%.
- Train tới depth 8: depth 8 khoảng 92%, depth 9 khoảng 88%, depth 10 khoảng 74%; xa hơn giảm dần.
Coverage đẩy biên generalization ra xa và làm đường suy giảm mềm hơn, nhưng không tạo extrapolation vô hạn.
7. STaR và trần pass@k
Khi model đã có pass@k khác 0, verified self-training bắt đầu có tác dụng. Trộn lời giải tự sinh đã được test với replay dữ liệu nền và learning rate thấp đã nâng greedy performance ở nhóm depth khó.
Sau một vòng, pass@1 gần bằng pass@32: khoảng 0,633 ở depth 7 và 0,617-0,633 ở depth 8. Tăng số sample không còn tìm thêm lời giải. Điều này cho thấy STaR chuyển “sample-time khả dụng” thành greedy capability, nhưng không tự tạo primitive hoặc cấu trúc chưa có trong phân phối.
8. Inference scaffolding: mạnh nhưng phải mô tả trung thực
Khi operation list đúng đã có sẵn, một chương trình depth 16 có thể được chia thành các chunk ngắn, cho model giải từng chunk rồi compose bằng hàm. Trong harness synthetic, direct pass@1 chỉ khoảng 15% nhưng chunked execution đạt 100%; depth 24-40 cũng có thể đạt 100%.
Kết quả này chứng minh model là một executor tốt khi nhận được decomposition chính xác. Nó không chứng minh model tự đọc tiếng Việt rồi tự suy ra decomposition. Đây là ranh giới quan trọng giữa neuro-symbolic scaffolding và autonomous planning.
9. Blackwell: đo thay vì đoán
Saturation lab tách raw kernel headroom khỏi end-to-end training:
- Raw BF16 FFN GEMM: 413,1 TFLOP/s.
- Raw FP8 FFN GEMM: 781,9 TFLOP/s.
- Peak sustained training: 224,7 TFLOP/s, MFU 0,547 ở model khoảng 1,45B.
- Naive FP8 end-to-end chỉ đạt 22.688 token/s, trong khi BF16 đạt 72.431 token/s trên cùng bài test khoảng 0,44B.
Raw FP8 nhanh không có nghĩa một implementation FP8 tự ghép sẽ nhanh. Quantization, scaling, layout, backward và kernel fusion quyết định kết quả thực tế.
Với model 13M-52M, vấn đề chính không phải thiếu VRAM. Lấp đầy 95 GB bằng batch lớn có thể làm giảm số optimizer update hoặc tiêu tốn compute mà không tăng capability. Blackwell hữu ích nhất ở giai đoạn này cho ablation nhanh, batched generation và verifier-heavy experiments.
10. Guardrail đáng giá hơn một run đẹp
V8 được thiết kế như một model 52M hoàn chỉnh với curriculum identifier, hard-example repair và promotion gate. Nhưng một lỗi schema làm mất phần mô tả nhiệm vụ khi tái dựng prompt. Run cho metric gần 0 và bị từ chối promote.
Điều quan trọng là pipeline đã không ghi đè active checkpoint. V8 trở thành một case study về ba nguyên tắc:
- Schema phải được kiểm tra trên dữ liệu thật, không chỉ trên giả định local.
- Metric bất thường phải được đối chiếu với probe độc lập.
- Candidate thất bại vẫn có giá trị chẩn đoán, nhưng không được tự động trở thành production artifact.
11. Kiến trúc hệ thống đã hình thành
Dự án dần chuyển từ “một language model sinh text” thành một hệ thống gồm:
- Model nhỏ học các pattern có thể kiểm chứng.
- Policy router tách answer/clarify/abstain/refuse.
- Giao diện tất định giảm lỗi identifier và formatting.
- Execution verifier cung cấp tín hiệu đúng/sai thật.
- Promotion gate chỉ cập nhật active checkpoint khi validation cải thiện.
- Stage-resume và lineage hash giúp mọi phase tiếp tục tăng dần thay vì chạy lại từ đầu.
12. Những gì có thể kết luận - và những gì chưa thể
Có thể kết luận
- 13M không đủ cho curriculum code hiện tại dù pipeline và loss đều tốt.
- 52M phá được capacity wall trên benchmark synthetic.
- Canonical interface + AST binding loại bỏ một bottleneck identifier lớn.
- Structural diversity và depth coverage trực tiếp mở rộng vùng generalization.
- Self-distillation cần successful trajectories và dừng có ích khi pass@1 chạm pass@k.
- Promotion gate, verifier và lineage là thành phần cốt lõi, không phải phụ kiện.
Chưa thể kết luận
- Model hiểu code tổng quát hoặc thay thế coding assistant hiện đại.
- Decomposition 100% là autonomous reasoning; harness hiện dùng cấu trúc đúng có sẵn.
- Kết quả synthetic sẽ chuyển nguyên vẹn sang repository thật, multi-file code hoặc API thay đổi theo phiên bản.
- Phương pháp đạt state of the art hay đủ bằng chứng cho một paper hoàn chỉnh.
13. Hướng tiếp theo
Hướng nghiên cứu tiếp theo hợp lý nhất là bỏ oracle decomposition: model phải tự biến đặc tả tiếng Việt thành một IR nhỏ, IR được compiler tất định chuyển thành code, rồi verifier kiểm tra. Điều này tách ba năng lực:
- Hiểu yêu cầu.
- Lập kế hoạch có cấu trúc.
- Thực thi code đúng.
Sau đó mới mở rộng sang chuỗi, từ điển, nhiều tham số, nested control flow và benchmark độc lập ngoài grammar sinh dữ liệu.
Kết
Bài học lớn nhất của dự án không phải “cứ tăng tham số là được”. Nó là:
Một model nhỏ có thể trở nên hữu ích khi bài toán được chia đúng giữa model, compiler và verifier; nhưng mọi con số phải đi kèm phạm vi benchmark, negative result và guardrail chống tự lừa mình.
Bản công khai này cố ý không chứa toàn bộ recipe, raw checkpoint, tài khoản hạ tầng hoặc grammar sinh dữ liệu. Những thành phần đó được giữ trong gói handoff riêng cho nghiên cứu tiếp tục.