Bỏ qua để đến nội dung
Search & RAG

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í.

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)
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)
“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) — 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
Chưa đo recall@k của stage 1Không. Quay lại 5.4
Chưa thử 2–3 reranker có sẵnKhông
Golden set của bạn có 24 truy vấnKhô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.

(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ất

Cá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.

Đâ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ống

Hard 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ẫyChuyện gì xảy raCách tránh
False negativeMộ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ượcCho 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
MứcViệ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ẵnVà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ề rankingPhần lớn giá trị nằm ở đây
2. Distillation từ thầy mạnhDù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.

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ỉ retriever59,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 đổinDCG@10
Loss BCE (pointwise)0,7230
→ InfoNCE (có negative)0,7414 (+2,5%)
Attention một chiều0,7312
→ hai chiều0,7414 (+1,4%)
Tỉa model từ 32 xuống 16 lớpchỉ 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).

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.

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 E2003 thà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.

Phần 5 — Reranker