5.14 Fine-tune reranker của riêng bạn
Trước khi đọc mục này: fine-tune là việc cuối cùng trong Phần 5, không phải việc đầu tiên. Thứ tự đúng là tokenizer → hybrid → chunking → reranker có sẵn → rồi mới fine-tune. Rất nhiều đội nhảy tới đây quá sớm và tốn hàng tuần để mua lại đúng phần mà một model có sẵn đã cho miễn phí.
Khi nào nó thực sự đáng làm
Phần tiêu đề “Khi nào nó thực sự đáng làm”| Dấu hiệu | Đáng fine-tune? |
|---|---|
| Từ vựng miền hẹp mà model chung không hiểu (mã nội bộ, tên sản phẩm, thuật ngữ chuyên ngành) | Có |
| Người dùng hỏi theo lối rất riêng (lẫn Anh–Việt, viết không dấu, tiếng nói của một ngành) | Có |
| “Liên quan” trong sản phẩm của bạn ≠ “liên quan” theo nghĩa thường (ví dụ phải ưu tiên phiên bản đang dùng của khách) | Có — và đây là lý do mạnh nhất |
| Bạn có ≥ vài nghìn cặp nhãn hoặc log click thật | Có |
Chưa đo recall@k của stage 1 | Không. Quay lại 5.4 |
| Chưa thử 2–3 reranker có sẵn | Không |
| Golden set của bạn có 24 truy vấn | Không — không đủ để biết bạn có tiến bộ hay không (5.12) |
Dòng thứ ba đáng nhấn: fine-tune mạnh nhất không phải khi bạn muốn “chính xác hơn” chung chung, mà khi định nghĩa liên quan của bạn khác với định nghĩa mà model công khai được huấn luyện theo. Đó là thứ không model có sẵn nào biết được.
Dữ liệu: ba nguồn, ba mức chất lượng
Phần tiêu đề “Dữ liệu: ba nguồn, ba mức chất lượng”(1) Log truy vấn + click/feedback ← nhiều nhất, nhiễu nhất, MIỄN PHÍ(2) LLM chấm nhãn (distillation) ← nhiều, khá tốt, tốn tiền token(3) Người gán nhãn ← ít, tốt nhất, đắt nhấtCách phối hợp thực dụng: dùng (1) để tìm ứng viên khó (những cặp mà hệ thống hiện tại xếp sai), dùng (2) để gán nhãn hàng loạt cho các ứng viên đó, và dùng (3) cho một tập đánh giá nhỏ mà bạn tuyệt đối không huấn luyện lên.
Tập đánh giá tách riêng là điều kiện tiên quyết. Không có nó, bạn không đo được gì — chỉ đo được model đã học thuộc tập huấn luyện đến đâu.
Hard negative: chỗ quyết định thành bại
Phần tiêu đề “Hard negative: chỗ quyết định thành bại”Đây là chi tiết kỹ thuật quan trọng nhất của việc huấn luyện reranker, và nó giống hệt chuyện xảy ra với embedding (Tầng 1).
Negative ngẫu nhiên dạy được rất ít: model chỉ cần học “hai văn bản này chả liên quan gì nhau” — việc đó dễ, và nó đã biết rồi. Cái nó cần học là phân biệt
"Thanh toán thất bại: giao dịch bị hoàn trong 3–5 ngày" ← ĐÚNG"Hoá đơn VAT: xuất hoá đơn cho đơn hàng đã trừ tiền" ← SAI, nhưng rất giốngHard negative là các tài liệu mà hệ thống hiện tại xếp cao nhưng sai. Cách lấy: chạy stage 1 trên các truy vấn của bạn, lấy top-k, bỏ các tài liệu đúng, phần còn lại là mỏ hard negative.
Hai cái bẫy đi kèm:
| Bẫy | Chuyện gì xảy ra | Cách tránh |
|---|---|---|
| False negative | Một tài liệu bạn dán nhãn “sai” thực ra đúng nhưng chưa được gán nhãn. Model bị dạy điều ngược | Cho LLM/người kiểm lại các negative điểm cao nhất trước khi dùng |
| Quá khó | Chỉ toàn negative cực khó → tín hiệu huấn luyện nhiễu, model không hội tụ | Trộn: một phần hard, một phần trung bình, một phần ngẫu nhiên |
Ba mức can thiệp, từ rẻ đến đắt
Phần tiêu đề “Ba mức can thiệp, từ rẻ đến đắt”| Mức | Việc phải làm | Đổi lại |
|---|---|---|
| 0. Không huấn luyện gì | Dùng reranker có sẵn hỗ trợ chỉ dẫn trong truy vấn, hoặc viết lại truy vấn giàu ngữ cảnh hơn (Tầng 6) | Vài giờ. Thử trước tiên |
| 1. Fine-tune một model nhỏ có sẵn | Vài nghìn cặp + một GPU vài giờ. Xuất phát từ một cross-encoder đã huấn luyện trên MS MARCO (5.5), đừng từ một model chưa biết gì về ranking | Phần lớn giá trị nằm ở đây |
| 2. Distillation từ thầy mạnh | Dùng một LLM hoặc một reranker lớn chấm điểm nhiều cặp, huấn luyện model nhỏ khớp điểm của thầy (không chỉ nhãn 0/1) | Model nhỏ, nhanh, gần chất lượng thầy. Đắt ở bước sinh nhãn |
Chi tiết đáng biết ở mức 2: cho model học điểm liên tục của thầy thay vì nhãn nhị phân truyền được nhiều thông tin hơn hẳn — thầy nói “cái này 0,81 còn cái kia 0,79”, và thứ tự tinh vi đó chính là thứ bạn cần.
Số đo, để bạn biết nên kỳ vọng gì
Phần tiêu đề “Số đo, để bạn biết nên kỳ vọng gì”Ba nguồn có số cụ thể, mỗi nguồn trả lời một câu hỏi khác nhau.
“Fine-tune một reranker mất bao nhiêu công?” — một hướng dẫn tái lập được của
HuggingFace: 99.000 cặp hỏi–đáp mở rộng thành 578.000 cặp có nhãn bằng công cụ đào hard
negative tự động (num_negatives=5, lọc max_score=0.8, margin=0.1 — tức bỏ các
negative điểm quá cao, chính là bước chống false negative ở trên). Kết quả:
| nDCG@10 | |
|---|---|
| Chỉ retriever | 59,12 |
| + reranker vừa fine-tune (rerank top-30) | 77,14 |
| Bản model lớn hơn (396M) | 79,42 |
Thời gian huấn luyện: khoảng 30 phút trên một RTX 3090. Đây là con số đáng biết vì nó phá bỏ ấn tượng “fine-tune reranker là một dự án lớn” — phần khó là dữ liệu, không phải phần huấn luyện.
“Chọn loss và kiến trúc thế nào?” — một bộ ablation trên reranker lớn:
| Thay đổi | nDCG@10 |
|---|---|
| Loss BCE (pointwise) | 0,7230 |
| → InfoNCE (có negative) | 0,7414 (+2,5%) |
| Attention một chiều | 0,7312 |
| → hai chiều | 0,7414 (+1,4%) |
| Tỉa model từ 32 xuống 16 lớp | chỉ mất 1% độ chính xác cho một nửa số tham số |
Dòng cuối là món có ROI cao nhất trong bảng nếu bạn đang lo chi phí phục vụ (5.10).
“Distill từ LLM có thật sự hoạt động?” — có, và số đo khá dứt khoát: với 10.000 truy vấn MS MARCO và một LLM reranker listwise làm thầy, một cross-encoder học được đạt nDCG@10 0,720 / 0,711 trên TREC DL 2019/2020 — so với ~0,687–0,698 khi huấn luyện bằng nhãn MS MARCO gốc, và ngang bằng chính model thầy (chênh lệch không có ý nghĩa thống kê), ở mức 300 ms cho 100 đoạn thay vì ~25 giây.
Đó là lý do 5.7 kết luận: dùng LLM làm thầy, đừng dùng làm đường phục vụ.
Một lý do dùng nhãn từ LLM mà ít người nghĩ tới: một đội quảng cáo ở quy mô lớn đã dùng chuỗi LLM thầy → cross-encoder → bi-encoder *cụ thể để thoát khỏi thiên lệch click, và báo cáo rằng nhãn do LLM sinh tốt hơn việc huấn luyện trên log tìm kiếm/click. Nghĩa là log click không phải luôn là nguồn dữ liệu tốt nhất bạn có — nó là nguồn nhiều nhất, và nó mang theo thiên lệch vị trí (5.12).
Vòng lặp làm việc
Phần tiêu đề “Vòng lặp làm việc”1. Chốt tập đánh giá TRƯỚC (người gán nhãn, không bao giờ huấn luyện lên).2. Đo model có sẵn tốt nhất trên tập đó. ĐÂY LÀ MỐC PHẢI VƯỢT.3. Sinh dữ liệu huấn luyện: truy vấn thật + positive + hard negative đã kiểm.4. Fine-tune từ một cross-encoder đã biết xếp hạng.5. Đo trên tập đánh giá, tách theo lớp truy vấn.6. Không vượt được mốc bước 2 → DỪNG, dùng model có sẵn. Đây là kết cục thường gặp.7. Vượt được → so cả latency và chi phí vận hành (5.9, 5.10) trước khi chốt.8. Ghim lại: phiên bản dữ liệu, phiên bản model, phân phối điểm hôm triển khai (5.13).Bước 6 viết ra để bạn được phép dừng. Một fine-tune không thắng model có sẵn là kết quả hợp lệ và khá phổ biến — biết điều đó sau hai tuần vẫn tốt hơn là duy trì một model riêng mãi mãi vì tiếc công.
Riêng cho tiếng Việt
Phần tiêu đề “Riêng cho tiếng Việt”Một số điều đặc thù cần tính vào trước khi bắt đầu:
- Không dấu. Nếu người dùng thật của bạn gõ không dấu ở tỷ lệ đáng kể (cẩm nang này tính được điểm hoà vốn ≈ 17% cho quyết định fold dấu ở tầng lexical — 3.10 — điểm hoà vốn của việc bỏ dấu), thì tập huấn luyện phải chứa truy vấn không dấu. Model chỉ thấy truy vấn có dấu sẽ hụt đúng ở nhóm người dùng đó.
- Trộn Anh–Việt. Truy vấn thật hay lẫn thuật ngữ tiếng Anh (“lỗi timeout khi call API”). Dữ liệu huấn luyện phải có dạng đó.
- Mã định danh. Reranker cũng có tokenizer riêng của nó, và nó cũng có thể nghiền
E2003thành mảnh vụn — đúng cái lỗi đã tốn của cẩm nang 20,8% ở tầng lexical (Tầng 0 — tokenizer đổi 20,8%). Kiểm bằng tay: đưa vài truy vấn chứa mã định danh vào model và xem nó có xếp đúng tài liệu chứa mã đó lên đầu. - Âm tiết ≠ từ. Xem 3.1. Điều này ảnh hưởng tới việc cắt độ dài chuỗi: cùng một nội dung, tiếng Việt tốn nhiều token hơn tiếng Anh trên phần lớn tokenizer, nên giới hạn seq length siết chặt hơn bạn tưởng (5.9).
→ Nên áp dụng vào AI Agent: trước khi tính đến fine-tune, làm mức 0 cho tử tế và đo lại. Rất nhiều thứ trông như “model không hiểu miền của tôi” thực ra là truy vấn thiếu ngữ cảnh, chunk cắt sai chỗ, hoặc trần recall@k thấp.