Fine-tune một GPU: đừng vội gọi là xong

Fine-tune một GPU: đừng vội gọi là xong

LoRA trên Colab đáng dùng, nhưng không phải vì nó rẻ. Giá trị thật nằm ở việc tập dượt recipe, checkpoint và quyết định có nên fine-tune hay không.

Bạn có dám giao cho một notebook Colab quyền quyết định chiến lược model của team không?

Mình hỏi thật, vì nhiều team đang làm đúng kiểu đó: thấy một workflow fine-tune chạy được trên single GPU, model trả lời “có vẻ đúng gu hơn”, thế là bắt đầu mơ tới production. Quầy pha mới kéo được một shot espresso ổn không có nghĩa là cả ca sáng mai sẽ không nghẽn đơn.

Luận điểm của bài này hơi trái tai: single-GPU LoRA fine-tuning không nên được xem là cách triển khai rẻ, mà là buổi tổng duyệt kỹ thuật trước khi bạn đốt tiền ở tầng lớn hơn. Nếu đọc xong bạn chỉ nhớ một điều, hãy nhớ: notebook thành công chưa chứng minh model production tốt; nó chỉ chứng minh recipe của bạn đủ đáng để kiểm tra tiếp.

Sơ đồ minh họa cho bài Fine-tune một GPU: đừng vội gọi là xong

Sơ đồ tóm tắt ý chính của bài viết.

Mục tiêu thật: kiểm tra hợp đồng hệ thống

Workflow từ nguồn chính dùng NVIDIA NeMo AutoModel để fine-tune Qwen3-0.6B bằng LoRA trên Google Colab. Nghe như một tutorial, nhưng với builder thì nó là một systems teardown rất gọn: bóc được các lớp quyết định mà production sau này cũng phải đối mặt.

Các lớp đó gồm:

LoRA là cách fine-tune tiết kiệm tham số: thay vì sửa toàn bộ model, bạn thêm một lớp adapter nhỏ để học phần khác biệt. Trong công việc, nó giống việc thêm công thức pha riêng cho một loại đồ uống, không phải thay toàn bộ máy pha.

Recipe ở đây là file cấu hình huấn luyện: model nào, precision nào, batch ra sao, checkpoint lưu ở đâu. Với team build hệ thống, recipe quan trọng hơn cảm giác “model có vẻ thông minh”, vì recipe mới là thứ có thể review, version, rollback và scale.

Checklist trước khi bấm train

Đừng bắt đầu bằng câu “fine-tune model nào?”. Bắt đầu bằng câu: mình đang muốn thay đổi hành vi nào mà prompt hoặc RAG không giải quyết gọn được?

Trước khi chạy notebook, team nên trả lời 7 câu này:

  1. Hành vi cần học là gì? Format trả lời, style nội bộ, taxonomy sản phẩm, hay cách gọi tool?
  2. Dữ liệu có sạch không? Nếu dữ liệu lộn xộn, fine-tune chỉ rang xay lại mẻ hạt đã ẩm.
  3. Baseline là gì? Model gốc trả lời ra sao trước khi train?
  4. Tiêu chí so sánh là gì? Không cần benchmark hoành tráng, nhưng phải có bộ prompt kiểm tra cố định.
  5. Checkpoint sẽ lưu ở đâu? Có đặt tên theo version, dataset, recipe không?
  6. Chi phí lỗi là gì? Sai format thì sửa được; sai chính sách bảo mật thì không vui chút nào.
  7. Có cần fine-tune thật không? Nếu chỉ cần model đọc tài liệu mới, RAG thường là lựa chọn ít rủi ro hơn.

RAG là cách đưa tài liệu liên quan vào prompt tại lúc hỏi, thay vì nhồi kiến thức đó vào trọng số model. Nếu bạn có tài liệu API 200 trang và câu hỏi thay đổi liên tục, RAG hợp lý hơn. Nếu bạn cần model luôn trả lời theo một schema nội bộ, dùng thuật ngữ công ty chuẩn, hoặc bắt chước một kiểu xử lý lặp đi lặp lại, LoRA bắt đầu đáng xem xét.

Bóc lớp triển khai: vì sao Colab vẫn có giá trị

Colab không phải môi trường production. Nhưng nó ép bạn đối mặt với những thứ production cũng sẽ đòi, chỉ ở phiên bản nhỏ hơn.

Lớp 1: runtime có nói thật không

Việc kiểm tra GPU, memory và hỗ trợ bfloat16 không phải nghi thức mở màn. bfloat16 là định dạng số giảm bộ nhớ nhưng vẫn giữ dải giá trị rộng; tradeoff là bạn được tiết kiệm tài nguyên, nhưng phải chắc phần cứng và framework hỗ trợ ổn. Nếu không kiểm tra, lỗi sẽ xuất hiện giữa buổi train, đúng lúc cà phê nguội và Slack bắt đầu hỏi “xong chưa”.

Lớp 2: config phải vá được bằng code

Điểm đáng giữ trong workflow NeMo AutoModel là recipe được load rồi patch có chủ đích: chỉnh precision, batch size, checkpointing, scheduler để vừa single GPU. Đây là tư duy production tốt. Bạn không sửa tay một file YAML rồi quên mình đã làm gì; bạn biến thay đổi thành code.

Ví dụ cụ thể: team bạn có recipe gốc cho multi-GPU, nhưng muốn test nhanh trên Colab. Thay vì tạo một bản recipe-final-v7-real.yaml, hãy viết script patch:

# Ví dụ minh họa: ý tưởng patch config, không phải nguyên văn workflow
cfg["trainer"]["precision"] = "bf16-mixed"
cfg["trainer"]["max_steps"] = 100
cfg["model"]["global_batch_size"] = 1
cfg["exp_manager"]["checkpoint_dir"] = "./checkpoints/qwen3-lora-smoke-test"

Điều cần học không phải là bốn dòng này, mà là nguyên tắc: mọi thay đổi làm cho recipe chạy được phải để lại dấu vết.

Lớp 3: checkpoint là sản phẩm, không phải phụ phẩm

Nhiều notebook xem checkpoint như file sinh ra cuối buổi. Với hệ thống thật, checkpoint là artifact triển khai: cần biết nó đến từ dataset nào, recipe nào, commit nào, và so với baseline ra sao.

Ở đây nguồn chính có bước reload LoRA checkpoint và so sánh output giữa model gốc và model fine-tuned. Đây là bước nhỏ nhưng rất đáng giữ. Không reload được checkpoint thì buổi train chỉ là màn biểu diễn. Reload được nhưng không có prompt cố định để so sánh thì vẫn chưa ra quyết định được.

Framework quyết định: fine-tune, RAG hay tối ưu inference?

Nói thẳng ra thì nhiều team chọn fine-tune vì nó tạo cảm giác “mình đã nâng cấp model”, trong khi vấn đề thật nằm ở dữ liệu, retrieval hoặc inference path.

Dùng khung này để chọn:

| Vấn đề chính | Nên thử trước | Vì sao |
|---|---|---|
| Model không biết tài liệu mới | RAG | Kiến thức thay đổi thì đưa vào lúc hỏi dễ kiểm soát hơn |
| Model trả lời sai format lặp đi lặp lại | LoRA | Hành vi ổn định có thể học bằng adapter nhỏ |
| Latency cao, context dài tốn kém | Tối ưu inference | Fine-tune không tự làm attention rẻ hơn |
| Tool calling hay sai tham số | Prompt + eval, rồi mới LoRA | Cần biết lỗi do instruction hay do hành vi nền |
| Domain style quá đặc thù | LoRA nhỏ có kiểm chứng | Hợp khi style lặp lại và dữ liệu đủ sạch |

Nguồn về sparse attention trên Blackwell nhắc một chuyện khác: hiệu năng production đôi khi nằm sâu ở kernel, memory access và load balancing. Sparse attention là cách chỉ chú ý tới một phần token liên quan để giảm chi phí tính toán; tradeoff là triển khai khó vì truy cập bộ nhớ không đều. Bài học cho fine-tune: nếu hệ thống chậm, đừng mặc định train thêm sẽ cứu được. Có khi bạn cần đổi serving stack, batching, cache, hoặc kernel path.

Làm trong một buổi: smoke test có kiểm soát

Nếu team bạn muốn thử workflow kiểu NeMo AutoModel + Qwen3 + LoRA trên single GPU, đây là phiên bản gọn để làm trong một buổi chiều.

Bước 1 — Chốt câu hỏi thí nghiệm

Viết một câu duy nhất:

“Sau fine-tune, model phải làm tốt hơn baseline ở ______, đo bằng ______.”

Ví dụ minh họa: “Sau fine-tune, model phải trả lời ticket support theo đúng 5 trường JSON, đo bằng 30 prompt cố định và kiểm tra schema tự động.”

Bước 2 — Tạo bộ kiểm tra trước train

Chuẩn bị 20-50 prompt nhỏ. Mỗi prompt có expected behavior. Đừng chờ train xong mới nghĩ cách chấm.

{
  "prompt": "Khách báo lỗi thanh toán bị treo, hãy tạo ticket.",
  "expected": {
    "fields": ["issue", "severity", "next_action", "missing_info"]
  }
}

Bước 3 — Chạy recipe nhỏ, giới hạn rõ

Dùng recipe chính thức làm nền, patch xuống batch nhỏ, steps thấp, checkpoint rõ tên. Mục tiêu không phải tạo model hay nhất, mà là kiểm tra đường ống: install, train, save, reload, compare.

Bước 4 — So sánh model gốc và LoRA adapter

Chạy cùng bộ prompt qua hai phiên bản. Ghi lại:

Hallucination là hiện tượng model bịa nhưng trình bày như thật. Sau fine-tune, hallucination không tự biến mất; đôi khi nó chỉ mặc đồng phục công ty nhìn thuyết phục hơn.

Bước 5 — Đóng gói quyết định, không đóng gói cảm xúc

Cuối buổi, chỉ chọn một trong ba quyết định:

Bẫy dễ dính khi mang từ notebook sang production

Bẫy đầu tiên là dependency trôi. Hôm nay notebook chạy, tuần sau package cập nhật và lỗi khác xuất hiện. Gợi ý từ workflow uvx cache-friendly trong GitHub Actions rất đáng mượn: khóa mốc thời gian hoặc version để dependency không tự trôi mỗi lần CI chạy. Với training pipeline, chuyện này còn quan trọng hơn, vì chỉ cần một library đổi default là kết quả có thể lệch.

Bẫy thứ hai là so sánh bằng mắt. Model fine-tuned trả lời nghe hợp gu hơn chưa chắc tốt hơn. Hãy dùng prompt cố định, schema check, regression cases và log output.

Bẫy thứ ba là quên serving. LoRA adapter train được chưa có nghĩa là deploy ngon. Bạn còn phải quyết định merge adapter hay load động, batch request ra sao, quantization có làm lệch output không, rollback thế nào.

Bẫy cuối cùng: dữ liệu nhỏ nhưng niềm tin lớn. Single-GPU test nên được đối xử như cupping ở quầy pha: giúp bạn phát hiện mùi vị lệch sớm, không phải chứng nhận cả chuỗi cửa hàng đã sẵn sàng mở bán.

Nếu là mình, mình sẽ triển khai thế này

Mình sẽ không đưa notebook fine-tune thẳng vào roadmap production. Mình sẽ dùng nó như một cổng kiểm tra:

  1. Có baseline và eval nhỏ chưa?
  2. Recipe có patch bằng code chưa?
  3. Checkpoint có reload và truy vết được chưa?
  4. LoRA có thắng rõ ở hành vi mục tiêu không?
  5. Serving path có kế hoạch riêng chưa?

Nếu 5 câu đều ổn, fine-tune đáng đi tiếp. Nếu không, quay lại sửa tầng đúng: dữ liệu, retrieval, prompt, eval hoặc inference.

Sau bài này, điều mình muốn bạn nghĩ khác là: fine-tune không phải nút “nâng cấp model”; nó là một quyết định hệ thống cần bằng chứng ở từng lớp. Chạy được trên một GPU là khởi đầu tốt, nhưng production không trả lương cho notebook chạy đẹp — production trả lương cho thứ reload được, đo được, rollback được.

Cà phê pha thử có thể thơm, nhưng đừng mở quán khi bạn chưa biết sáng mai ai rửa máy.

---
Bụi Wire — nghiện đọc release notes lúc 2 giờ sáng

Nguồn tham khảo