$ cat ./blog/gen-ai/llm-fundamentals/vi-sao-llm-sai-va-do-nhu-the-nao.md
seriesCách hoạt động của LLMbài 16

Vì sao LLM sai và đo nó thế nào: hallucination, calibration, benchmark và LLM-as-judge

Bài thứ mười sáu trong series Cách hoạt động của LLM: vì sao model bịa ra câu trả lời nghe rất chắc chắn, model có biết mình không biết không, và một con số benchmark thật ra đo cái gì. Đi từ nguồn gốc thống kê của hallucination trong pretraining, cách post-training và cách chấm điểm khuyến khích đoán, calibration và các cách lấy độ tự tin, tới bốn thành phần của một con số benchmark, contamination nhìn từ phía người đo, và thiên kiến của LLM-as-judge khi so sánh model.

~/diagrams/vi-sao-llm-sai-va-do-nhu-the-nao/llm-error-pipeline.htmltương tác
mở riêng ↗
HìnhHàng thứ hai là đường đi từ một fact đến một con số: fact nằm trong dữ liệu pretraining, phổ biến hoặc long-tail; pretraining học phân phối của dữ liệu đó; post-training (SFT, RLHF) đổi cách model trả lời và đổi luôn calibration; model decode ra một câu trả lời đúng, sai hoặc từ chối; câu trả lời được chấm bằng đáp án hoặc bằng một LLM judge; điểm được gộp thành một con số trên leaderboard. Hàng thứ ba là ba chỗ làm lệch phép đo: test set lọt vào dữ liệu train (contamination), độ tự tin lấy từ xác suất của model, và thiên kiến của LLM judge. Hàng trên cùng và dưới cùng là chín hiểu lầm phổ biến, mỗi cái nối với bước mà nó hiểu sai. Mục 12 giải thích từng hiểu lầm.
bước của modelđo và chấm điểmkhung tím: dữ liệu; khung đỏ: nguồn làm lệch con số; khung xám: hiểu lầm

Bài thứ mười lăm kết thúc với rất nhiều con số: 71,0% ở AIME 2024, 56,9% ở GSM8K, pass@k tăng theo số mẫu. Bài này hỏi lại: các con số đó đo đúng tới đâu, và khi model sai thì sai vì đâu.

“Vì sao model sai” là chuyện của dữ liệu, cách train và cách sinh câu trả lời. “Con số đo được có đúng không” là chuyện của benchmark, cách chấm và thống kê. Chúng gặp nhau ở cách chấm điểm: benchmark chỉ chấm đúng/sai thưởng cho model đoán bừa hơn model biết nói “tôi không biết”, và model được tối ưu theo benchmark sẽ học cách đoán. Cách ta đo góp phần tạo ra chính cái lỗi ta đang đo.

Mục 2–6 trả lời câu hỏi thứ nhất, mục 7–11 trả lời câu hỏi thứ hai.

Hình 1 ở đầu trang là đường đi từ một fact trong dữ liệu đến một con số trên leaderboard, kèm chín hiểu lầm mà mục 12 giải thích. Bài chỉ nói về đánh giá bản thân model. Đánh giá một hệ RAG đã có ở series RAG; đánh giá agent và tool use, safety eval và red-teaming nằm ngoài phạm vi bài này.


01Hai câu hỏi khác nhau

Kalai et al. 2025 (Why Language Models Hallucinate) mở đầu bằng một câu hỏi: “Sinh nhật của Adam Tauman Kalai là ngày nào? Nếu biết thì chỉ trả lời dạng DD-MM.” Adam Kalai là tác giả thứ nhất của chính paper đó. Qua ba lần hỏi, DeepSeek-V3 trả lời ba ngày khác nhau: 03-07, 15-06 và 01-01, cả ba đều sai (mục 1). Prompt đã cho phép không trả lời, nhưng model vẫn trả lời.

Ví dụ này chứa cả hai câu hỏi của bài: vì sao model không nói “tôi không biết”, và vì sao một benchmark chấm đúng/sai lại cho model đoán bừa cơ hội khoảng 1/365, còn model nói “không biết” chắc chắn được 0 điểm.

Vì vậy lỗi của LLM có hai lớp. Lỗi của model: câu trả lời sai so với thế giới hoặc với input, do dữ liệu, cách train, cách decode. Lỗi của phép đo: con số trên leaderboard lệch so với năng lực thật, do đề có lỗi, cách hỏi, contamination, nhiễu, thiên kiến của người chấm. Lớp thứ hai quan trọng không kém: một phép đo lệch có hệ thống kéo cả ngành tối ưu theo hướng lệch đó (định luật Goodhart).


02Hallucination là gì

Hai cách phân loại

Hai survey thường được dẫn chia hallucination theo hai trục:

  • Ji et al. 2023 (mục 2.1) chia theo quan hệ với nguồn: intrinsic là output mâu thuẫn với nguồn; extrinsic là output không kiểm chứng được từ nguồn, có thể đúng với thế giới nhưng không có trong nguồn.
  • Huang et al. 2023 (mục 2.3) chia theo cái output phải khớp: factuality hallucination là sai so với kiến thức thế giới; faithfulness hallucination là lệch khỏi input, gồm lệch chỉ dẫn, lệch context được cho và mâu thuẫn logic trong chính câu trả lời.

Bài này dùng trục của Huang et al. và tập trung vào factuality: model nói sai về thế giới khi không có tài liệu nào được đưa vào. Faithfulness với context của RAG đã có ở mục Faithfulness trong bài đánh giá RAG.

Những dạng hay gặp

  • Bịa fact long-tail: ngày sinh, tên luận án của người ít được nhắc tới. Bảng 1 của Kalai et al. 2025 hỏi ba model (GPT-4o, DeepSeek, Llama) tên luận án tiến sĩ của Kalai; không model nào đưa ra đúng tên hay đúng năm.
  • Bịa trích dẫn hoặc API: một paper hay một hàm thư viện có tên rất hợp lý nhưng không tồn tại.
  • Confabulation: Farquhar et al. 2024 dùng từ này cho các câu trả lời vừa sai vừa tuỳ tiện, đổi theo những chi tiết không liên quan như random seed. Ba ngày sinh khác nhau ở trên là confabulation. Paper tách dạng này khỏi trường hợp model sai nhất quán vì học từ dữ liệu sai; phân biệt này quan trọng ở mục 6.

03Nguồn gốc thống kê: từ pretraining

Bài 10 đã nói objective của pretraining: dự đoán token tiếp theo, tối thiểu hoá cross-entropy. Một model làm tốt đúng objective đó có buộc phải hallucinate không?

Fact chỉ xuất hiện một lần

Kalai & Vempala 2024 (Calibrated Language Models Must Hallucinate) trả lời “có”, với một loại fact và dưới các giả định cụ thể. Ý tưởng dựa trên ước lượng Good-Turing: tỷ lệ fact chỉ xuất hiện đúng một lần trong dữ liệu train (monofact rate) ước lượng phần xác suất của những fact model chưa từng thấy. Kết quả chính (Hệ quả 1, mục 5) nói, với xác suất cao:

tỷ lệ hallucination ≥ monofact rate − mức miscalibration − các số hạng nhỏ.

Ví dụ trong paper: nếu một nửa số bài viết thuộc một loại chỉ xuất hiện một lần, model calibrated sẽ hallucinate khoảng một nửa số lần sinh ra fact thuộc loại đó (mục 1). Phạm vi của kết quả hẹp hơn tiêu đề:

  • Chỉ áp dụng cho fact “tuỳ ý”, mà tính đúng sai không suy ra được từ dữ liệu, như ngày sinh. Abstract ghi rõ: không có lý do thống kê nào để pretraining gây hallucination với fact xuất hiện nhiều lần (như các bài báo, sách phổ biến) hay fact có hệ thống (như phép tính số học).
  • Giả định mạnh: dữ liệu i.i.d. và không có lỗi, mỗi document chứa nhiều nhất một fact, sinh văn bản không có prompt, số câu sai nhiều hơn rất nhiều số fact đúng, các fact chưa thấy có xác suất đúng như nhau.
  • “Calibrated” ở mức ngữ nghĩa, không phải mức token: xác suất model gán cho một fact khớp với tần suất của nó trong dữ liệu.
  • Không nói hallucination là tất yếu. Paper viết kết quả “không nên hiểu là hallucination không tránh được” (trang 2): post-training có thể giảm hallucination, đổi lại model kém calibrated đi.

Từ sinh câu sang phân loại câu

Kalai et al. 2025 quy bài toán sinh câu hợp lệ về bài toán phân loại nhị phân Is-It-Valid (IIV): một câu là hợp lệ hay là lỗi? Kết quả (Hệ quả 1, mục 3.1), viết gọn:

tỷ lệ lỗi khi sinh ≥ 2 × tỷ lệ phân loại sai của IIV − |V|/|E| − δ

với |V|/|E| là tỷ lệ giữa số câu hợp lệ và số câu lỗi có thể có (thường rất nhỏ), δ là mức miscalibration. Nếu nhận ra câu hợp lệ đã khó, sinh ra câu hợp lệ còn khó hơn. Với fact tuỳ ý, tỷ lệ lỗi ít nhất bằng singleton rate (tỷ lệ prompt chỉ xuất hiện một lần) trừ đi δ và vài số hạng nhỏ (Định lý 2, mục 3.3.1). Ví dụ ở mục 1.1: nếu 20% fact ngày sinh chỉ xuất hiện đúng một lần trong dữ liệu pretraining, base model được kỳ vọng hallucinate trên ít nhất 20% fact ngày sinh.

Hai điều cần giữ. Giả định vẫn là dữ liệu train không có lỗi; dữ liệu có lỗi thì tỷ lệ lỗi còn cao hơn. Và một mục của paper có tiêu đề “hallucination chỉ tất yếu với base model” (mục 3.1): một hệ thống tra cứu trả lời “không biết” cho mọi thứ ngoài cơ sở dữ liệu sẽ không hallucinate, nó chỉ không calibrated. Kết luận đúng: với fact tuỳ ý mà dữ liệu không đủ để học, model vừa calibrated vừa không bao giờ sai là không thể có, nên phải chọn.

Long-tail: bằng chứng thực nghiệm

Kandpal et al. 2023 đếm số document trong dữ liệu pretraining chứa cả thực thể của câu hỏi lẫn thực thể của đáp án (TriviaQA, Natural Questions), rồi so với độ chính xác QA. Với BLOOM-176B, độ chính xác tăng từ khoảng 25% lên trên 55% khi số document liên quan tăng từ 10 lên 10.000 (mục 3.1, Hình 1). Train lại một model 4,8B sau khi xoá các document liên quan làm độ chính xác ở những câu đó giảm rõ (mục 3.2), gợi ý đây là quan hệ nhân quả.

Tăng kích thước model không phải lối thoát: với câu hỏi có dưới 100 document liên quan, ngoại suy cho thấy cần một model BLOOM hơn 10^18 tham số để đạt mức của một hệ QA có giám sát mạnh (mục 4.2, Hình 6). Retrieval giúp nhiều hơn hẳn, nhất là với câu hỏi hiếm (mục 4.3). Đây là lý do kỹ thuật cho RAG. Data mixture ở bài 5 quyết định fact nào phổ biến, fact nào hiếm trong mắt model.

Reversal curse

Berglund et al. 2023 cho thấy model học phân phối của văn bản, không học “fact” theo nghĩa của con người. Với câu hỏi kiểu “Mẹ của Tom Cruise là ai?”, GPT-4 trả lời đúng 79%, nhưng câu hỏi chiều ngược kiểu “Con trai của Mary Lee Pfeiffer là ai?” chỉ 33% (abstract, mục 2.2). Fine-tune GPT-3-175B trên các câu bịa dạng “Daphne Barrington là đạo diễn của ‘A Journey Through Time’”, hỏi đúng chiều đã học thì đúng 50,0%, hỏi chiều ngược lại thì 0,0% (Bảng 1). Khi “A là B” nằm ngay trong context, model lại suy ra chiều ngược được: đưa kiến thức vào context giải quyết thứ weights không giữ được.


04Post-training và luật chấm khuyến khích đoán

SFT trên kiến thức mới dạy model bịa

Bài 11 đã dẫn lập luận của John Schulman: SFT trên câu trả lời đúng mà model không có kiến thức để tự sinh ra sẽ dạy model giọng tự tin thay vì kiến thức. Gekhman et al. 2024 kiểm chứng bằng thí nghiệm trên PaLM 2-S với bài QA đóng sách ENTITYQUESTIONS. Họ chia ví dụ thành bốn nhóm theo mức model đã biết (HighlyKnown, MaybeKnown, WeaklyKnown, Unknown), rồi fine-tune với tỷ lệ ví dụ Unknown khác nhau:

  • Ví dụ Unknown được học chậm hơn hẳn ví dụ Known (mục 4.3, Hình 1).
  • Học xong phần Unknown thì model sai nhiều hơn: mỗi phần ví dụ Unknown được khớp làm độ chính xác giảm gần bằng mức một phần ví dụ Known làm tăng (hệ số −8,3 so với +7,3, mục 4.4, Bảng 1).
  • Dừng sớm giảm được tác hại (mục 4.2).

Khi gắn lại nhãn các ví dụ Unknown thành “Tôi không biết”, độ chính xác trên các câu model chọn trả lời là 61,8%, so với 43,0% khi trả lời mọi câu, đổi lại model chỉ trả lời 58,7% số câu (mục 7, Bảng 3). Đây là đánh đổi giữa calibration và abstention của mục 5.

Sycophancy và decoding

Sharma et al. 2023 (đã nhắc ở bài 11) đo một nguồn sai khác: model chiều theo người dùng. Khi bị hỏi lại “Tôi không nghĩ vậy. Bạn chắc chứ?”, Claude 1.3 nhận sai ở 98% số câu mà nó trả lời đúng ngay từ đầu (mục 3.2). Gợi ý một đáp án sai làm độ chính xác giảm tới 27% (LLaMA 2, mục 3.3). Preference model dùng cho Claude 2 thích câu trả lời chiều theo hiểu lầm của người dùng hơn câu trả lời trung thực cơ bản 95% số lần (mục 4.3). Gốc nằm ở dữ liệu preference, nơi “khớp với niềm tin của người dùng” là một trong những đặc điểm dự đoán mạnh nhất cho việc được chọn (mục 4.1): một dạng reward hacking đã nói ở bài 11, mục 7.

Decoding chỉ góp phần nhỏ: temperature cao làm token ít khả năng hơn được chọn thường hơn (bài 9, mục 4), nhưng model ở mục 1 bịa ngày sinh vì phân phối của nó không có đỉnh nào ở ngày đúng.

Luật chấm nhị phân thưởng cho việc đoán

Phần quan trọng nhất của Kalai et al. 2025 là lập luận về chấm điểm (mục 4). Trong bài thi trắc nghiệm không trừ điểm câu sai, đoán bao giờ cũng lợi hơn bỏ trống. Paper chỉ ra phần lớn benchmark của LLM chấm đúng như vậy: dưới luật nhị phân, câu trả lời tối ưu không bao giờ là “không biết” (Nhận xét 1, mục 4.1). Trong mười benchmark phổ biến ở Bảng 2, chín cái không cho điểm nào khi trả lời “không biết”; chỉ WildBench cho một phần điểm.

Đề xuất của paper là ghi rõ ngưỡng tự tin trong đề (mục 4.2): “Chỉ trả lời nếu bạn tự tin hơn t, vì câu sai bị trừ t/(1−t) điểm, câu đúng được 1 điểm, ‘tôi không biết’ được 0 điểm.” Với t = 0,5 câu sai bị trừ 1; t = 0,75 trừ 3; t = 0,9 trừ 9; chấm nhị phân là t = 0. Khi đó chiến lược tối ưu là trả lời khi và chỉ khi xác suất đúng lớn hơn t, hành vi mà paper gọi là behavioral calibration.

Code mẫu 2: cùng kiến thức, đổi luật chấm

Code dưới mô phỏng hai model có cùng kiến thức: với mỗi câu, cả hai có cùng xác suất trả lời đúng c. Nửa số câu là kiến thức phổ biến (c trung bình 0,9), nửa còn lại là long-tail (c trung bình 0,2). Model A luôn trả lời; model B nói “không biết” khi c ≤ 0,75.

# Python 3.12.13, numpy 2.5.4. Không cần weights. Chạy: python code2.py
import numpy as np

rng = np.random.default_rng(0)
N = 1000
# Cùng một "kiến thức" cho cả hai model: mỗi câu có xác suất đúng c nếu model trả lời.
# Nửa đầu là kiến thức phổ biến (c trung bình 0,9), nửa sau là long-tail (c trung bình 0,2).
c = np.concatenate([rng.beta(9, 1, N // 2), rng.beta(1, 4, N // 2)])
correct_if_answered = rng.random(N) < c     # model calibrated: đúng với xác suất đúng bằng c

def score(answered, t):
    """Luật chấm có ngưỡng t (Kalai et al. 2025, mục 4.2):
    đúng +1, "không biết" 0, sai -t/(1-t). t = 0 là chấm nhị phân."""
    right = answered & correct_if_answered
    wrong = answered & ~correct_if_answered
    return (right.sum() - t / (1 - t) * wrong.sum()) / N, right.sum(), wrong.sum()

guesser = np.ones(N, dtype=bool)            # model A: luôn trả lời
abstainer = c > 0.75                         # model B: nói "không biết" khi c <= 0,75

print(f"{'luật chấm':<22}{'model':<12}{'đúng':>6}{'sai':>6}{'bỏ qua':>8}{'điểm':>9}")
for t in (0.0, 0.5, 0.75, 0.9):
    rule = "nhị phân (t=0)" if t == 0 else f"t={t}, phạt {t / (1 - t):.0f}"
    for name, answered in (("đoán", guesser), ("từ chối", abstainer)):
        s, r, w = score(answered, t)
        print(f"{rule:<22}{name:<12}{r:>6}{w:>6}{N - answered.sum():>8}{s:>9.3f}")

Output:

luật chấm             model         đúng   sai  bỏ qua     điểm
nhị phân (t=0)        đoán           555   445       0    0.555
nhị phân (t=0)        từ chối        435    38     527    0.435
t=0.5, phạt 1         đoán           555   445       0    0.110
t=0.5, phạt 1         từ chối        435    38     527    0.397
t=0.75, phạt 3        đoán           555   445       0   -0.780
t=0.75, phạt 3        từ chối        435    38     527    0.321
t=0.9, phạt 9         đoán           555   445       0   -3.450
t=0.9, phạt 9         từ chối        435    38     527    0.093

Ba điều đọc được:

  • Dưới luật nhị phân, model đoán thắng: 0,555 so với 0,435, dù nó sai 445 câu, gấp gần 12 lần model từ chối (38 câu).
  • Chỉ cần phạt 1 điểm cho câu sai, thứ hạng đảo chiều, và khoảng cách tăng theo ngưỡng. Hai model có cùng kiến thức; chỉ khác ở việc làm gì khi không chắc.
  • Ngưỡng t = 0,9 phạt cả model B, vì B vẫn trả lời các câu có c trong khoảng 0,75–0,9. Muốn đổi ngưỡng theo đề, model phải ước lượng tốt c: phải calibrated.

05Calibration: model có biết mình không biết?

Định nghĩa và ba thước đo

Định nghĩa calibration đã có ở bài JEV, mục 4: khi model nói 0,8, câu trả lời nên đúng khoảng 80% số lần, và đây là tính chất của một nhóm dự đoán. Ba công cụ đo:

  • Reliability diagram (hay bảng reliability): chia dự đoán vào các bin theo độ tự tin, so độ tự tin trung bình với độ chính xác thật trong từng bin.
  • ECE (Expected Calibration Error): trung bình có trọng số của |độ tự tin − độ chính xác| qua các bin (Guo et al. 2017, mục 2, công thức 3).
  • Brier score: trung bình của (độ tự tin − đúng)², với “đúng” là 1 hoặc 0.

Ví dụ: một model nói “tự tin 0,9” cho cả 100 câu và đúng 60 câu. ECE = |0,9 − 0,6| = 0,3; Brier = (60 × 0,01 + 40 × 0,81) / 100 = 0,33. Nếu nó nói “0,6” cho mọi câu thì ECE = 0, nhưng vẫn không phân biệt được câu nào đúng câu nào sai. Ngoài calibration còn cần khả năng phân biệt, thường đo bằng AUROC.

Base model khá calibrated, post-training làm lệch

Guo et al. 2017 cho thấy mạng neural hiện đại thường quá tự tin: trên CIFAR-100, ResNet-110 có ECE 16,53%, LeNet-5 chỉ 4,85% (Bảng 1). Temperature scaling, chia logits cho một hằng số T học trên tập validation, không đổi accuracy nhưng đưa ECE của ResNet-110 về 1,26%.

Với LLM, Kadavath et al. 2022 cho thấy model 52B của Anthropic calibrated tốt trên câu trắc nghiệm khi format đúng: lựa chọn được liệt kê kèm chữ cái và model chọn bằng chữ cái (mục 2). Calibration tăng theo kích thước model và khi có few-shot (mục 2, Hình 4); thay lựa chọn cuối bằng “không có đáp án nào đúng” làm cả accuracy lẫn calibration giảm rõ (mục 3.1). Model sau RLHF trông “rất miscalibrated”, nhưng temperature scaling với T = 2,5 sửa được phần lớn (mục 3.3).

GPT-4 Technical Report đưa cặp số hay được trích nhất: trên một tập con MMLU, GPT-4 pretrained có ECE 0,007, sau post-training (PPO) là 0,074 (mục 5, Hình 8); report không nói tập con nào và chia bin thế nào. Đây là phía bên kia của đánh đổi ở mục 3: post-training giảm hallucination bằng cách đẩy model khỏi trạng thái calibrated, một phần của “cái giá của alignment” ở bài 11.

Ba cách lấy độ tự tin

  1. Xác suất token: đọc xác suất model gán cho đáp án, như Code 1 dưới đây. Cần logprobs, gọn nhất với câu trả lời ngắn có dạng cố định.
  2. Bảo model tự nói ra độ tự tin. Tian et al. 2023 thấy với model đã qua RLHF (ChatGPT, GPT-4, Claude), độ tự tin nói ra thường calibrated tốt hơn xác suất có điều kiện, giảm ECE khoảng 50% tương đối (abstract); ví dụ GPT-4 trên TriviaQA, ECE từ 0,078 xuống 0,024 (Bảng 2). Với model đóng, “xác suất có điều kiện” ở đây được ước lượng từ 10 mẫu, không phải logprobs thật (mục 2). Xiong et al. 2023 thấy mặt kia: độ tự tin nói ra quá tự tin, phần lớn trong khoảng 80–100% và thường là bội số của 5 (mục 1); AUROC trung bình của GPT-4 chỉ 62,7%, gần mức ngẫu nhiên 50% (Bảng 2).
  3. Độ nhất quán giữa nhiều mẫu: hỏi nhiều lần, xem câu trả lời có giống nhau không. Với GPT-3.5 trên GSM8K, AUROC tăng từ 54,8% (một mẫu, chỉ hỏi độ tự tin bằng lời) lên 92,7% (đo độ nhất quán qua năm mẫu) (Xiong et al., mục 5.3, Bảng 3). Đây là ý của self-consistency ở bài 15, dùng để đo độ chắc chắn thay vì để chọn đáp án.

Xiong et al. cũng cho một ví dụ vì sao cần cả calibration lẫn phân biệt: GPT-4 với chain-of-thought đạt 93,6% trên GSM8K và có ECE 0,064 chỉ bằng cách gán 100% tự tin cho mọi câu (mục 5.2). ECE thấp, nhưng độ tự tin không giúp tìm ra 6,4% câu sai.

Code mẫu 1: đo calibration của Qwen3-0.6B trên MMLU

Code dưới cho Qwen3-0.6B (model đã dùng ở bài 15) trả lời 200 câu MMLU chọn ngẫu nhiên. MMLU có 57 môn, câu trắc nghiệm bốn lựa chọn; bản trên Hugging Face (cais/mmlu) có 14.042 câu test (paper gốc ghi 14.079, Hendrycks et al. 2020, mục 3). Mỗi câu chỉ cần một forward pass: lấy logits của token “ A”, “ B”, “ C”, “ D” ngay sau “Answer:” và softmax trên bốn giá trị đó. Đáp án là chữ cái có xác suất cao nhất, độ tự tin là xác suất đó. Sau đó code chạy lại với thứ tự bốn đáp án bị đảo ngược.

# Python 3.12.13, torch 2.14.1+cpu, transformers 5.20.1, datasets 5.1.0
# CPU Intel i9-9900K, bf16, 8 thread. Chạy: python code1.py 200
import random, sys, time
import torch
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer

MODEL = "Qwen/Qwen3-0.6B"
N = int(sys.argv[1]) if len(sys.argv) > 1 else 200
SEED = 0
LETTERS = ["A", "B", "C", "D"]

tok = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForCausalLM.from_pretrained(MODEL, dtype=torch.bfloat16)
model.eval()
torch.set_num_threads(8)

data = load_dataset("cais/mmlu", "all", split="test")
idx = random.Random(SEED).sample(range(len(data)), N)
# Token id của " A", " B", " C", " D" (có dấu cách đứng trước, như sau "Answer:")
letter_ids = [tok.encode(" " + L, add_special_tokens=False)[0] for L in LETTERS]

def prompt(ex, order):
    subject = ex["subject"].replace("_", " ")
    lines = [f"The following is a multiple choice question about {subject}.", "",
             ex["question"]]
    lines += [f"{L}. {ex['choices'][j]}" for L, j in zip(LETTERS, order)]
    return "\n".join(lines) + "\nAnswer:"

@torch.no_grad()
def probs4(text):
    ids = tok(text, return_tensors="pt").input_ids
    logits = model(ids).logits[0, -1].float()          # một forward pass
    return torch.softmax(logits[letter_ids], dim=-1)   # chuẩn hoá trên 4 chữ cái

def run(order_of):
    rows = []                                          # (độ tự tin, đúng?, nội dung đã chọn)
    for i in idx:
        ex = data[i]
        order = order_of(ex)
        p = probs4(prompt(ex, order))
        k = int(p.argmax())
        rows.append((float(p[k]), order[k] == ex["answer"], order[k]))
    return rows

def report(name, rows, bins=10):
    n = len(rows)
    acc = sum(c for _, c, _ in rows) / n
    brier = sum((p - c) ** 2 for p, c, _ in rows) / n  # Brier trên độ tự tin của đáp án đã chọn
    ece, table = 0.0, []
    for b in range(bins):
        lo, hi = b / bins, (b + 1) / bins
        sel = [(p, c) for p, c, _ in rows if lo < p <= hi]
        if not sel:
            continue
        conf = sum(p for p, _ in sel) / len(sel)
        a = sum(c for _, c in sel) / len(sel)
        ece += len(sel) / n * abs(conf - a)
        table.append(f"  ({lo:.1f}, {hi:.1f}]  n={len(sel):3d}  conf={conf:.3f}  acc={a:.3f}  gap={conf - a:+.3f}")
    print(f"{name}: accuracy={acc:.3f}  avg_conf={sum(p for p, _, _ in rows) / n:.3f}  "
          f"ECE={ece:.3f}  Brier={brier:.3f}")
    print("\n".join(table))

t0 = time.perf_counter()
orig = run(lambda ex: [0, 1, 2, 3])
report("original order", orig)
rev = run(lambda ex: [3, 2, 1, 0])                     # cùng câu hỏi, đảo ngược thứ tự đáp án
report("reversed order", rev)
changed = sum(a[2] != b[2] for a, b in zip(orig, rev))
print(f"chosen answer content changed on {changed}/{N} questions; "
      f"time {time.perf_counter() - t0:.0f}s")

Output:

original order: accuracy=0.410  avg_conf=0.704  ECE=0.294  Brier=0.320
  (0.3, 0.4]  n=  5  conf=0.351  acc=0.000  gap=+0.351
  (0.4, 0.5]  n= 24  conf=0.456  acc=0.417  gap=+0.039
  (0.5, 0.6]  n= 38  conf=0.547  acc=0.211  gap=+0.337
  (0.6, 0.7]  n= 39  conf=0.655  acc=0.436  gap=+0.219
  (0.7, 0.8]  n= 25  conf=0.744  acc=0.400  gap=+0.344
  (0.8, 0.9]  n= 25  conf=0.849  acc=0.480  gap=+0.369
  (0.9, 1.0]  n= 44  conf=0.951  acc=0.568  gap=+0.383
reversed order: accuracy=0.405  avg_conf=0.715  ECE=0.310  Brier=0.325
  (0.2, 0.3]  n=  1  conf=0.290  acc=0.000  gap=+0.290
  (0.3, 0.4]  n=  6  conf=0.345  acc=0.000  gap=+0.345
  (0.4, 0.5]  n= 23  conf=0.458  acc=0.304  gap=+0.154
  (0.5, 0.6]  n= 35  conf=0.555  acc=0.343  gap=+0.212
  (0.6, 0.7]  n= 28  conf=0.635  acc=0.357  gap=+0.278
  (0.7, 0.8]  n= 25  conf=0.751  acc=0.400  gap=+0.351
  (0.8, 0.9]  n= 38  conf=0.851  acc=0.368  gap=+0.483
  (0.9, 1.0]  n= 44  conf=0.951  acc=0.636  gap=+0.314
chosen answer content changed on 137/200 questions; time 504s

Bảng trên là reliability diagram ở dạng bảng: mỗi dòng là một bin, conf là độ tự tin trung bình, acc là độ chính xác thật. Bốn điều đọc được:

  • Model quá tự tin ở mọi bin. Độ tự tin trung bình 0,704, accuracy 0,410, ECE 0,294. Ở bin cao nhất, 44 câu có độ tự tin trung bình 95,1% nhưng chỉ đúng 56,8%. Accuracy 41% vẫn cao hơn đoán ngẫu nhiên 25%: model biết một phần, nhưng xác suất không nói đúng phần nào.
  • Độ tự tin vẫn mang chút thông tin: bin trên 0,9 đúng nhiều hơn bin 0,5–0,6 (56,8% so với 21,1%), dù không đều vì mỗi bin chỉ có 5–44 câu.
  • Đảo thứ tự đáp án, accuracy gần như không đổi (41,0% thành 40,5%), nhưng nội dung đáp án đổi ở 137/200 câu. Một con số tổng hợp ổn định có thể che hành vi rất không ổn định ở từng câu. Mục 8 quay lại hiện tượng này.
  • Đây là minh hoạ cơ chế, không phải điểm MMLU của Qwen3-0.6B. Code dùng zero-shot, không qua chat template, trên một model đã qua post-training; theo Kadavath et al., format và few-shot đều đổi calibration.

Abstention: calibration chỉ có ích khi được dùng

Calibration tự nó không làm model bớt sai. Nó có ích khi hệ thống dùng độ tự tin để từ chối, hỏi lại, gọi công cụ tra cứu hoặc chuyển cho người. Cách đặt ngưỡng theo chi phí của từng loại sai đã có ở bài JEV, mục 5.


06Phát hiện hallucination từ chính model

Với câu trả lời dài và mở, không có logprob cho “đáp án”. Hai phương pháp nổi bật dựa trên ý của cách 3: model biết thì trả lời nhất quán, model bịa thì mỗi lần bịa một kiểu.

SelfCheckGPT

Manakul et al. 2023 sinh thêm N mẫu cho cùng prompt, rồi kiểm tra từng câu trong đoạn văn gốc có được các mẫu kia ủng hộ không, bằng BERTScore, hỏi đáp, n-gram, NLI hoặc hỏi thẳng một LLM. Trên 238 đoạn tiểu sử do GPT-3 sinh với 1.908 câu gán nhãn tay, với N = 20, biến thể dùng LLM đạt AUC-PR 93,42 khi phát hiện câu sai, so với 72,96 của đoán ngẫu nhiên; biến thể NLI đạt 92,50 (Bảng 2).

Semantic entropy

Farquhar et al. 2024 (Nature) giải quyết điểm yếu của việc so chuỗi: “Paris”, “Thủ đô là Paris” và “Đó là Paris” là ba chuỗi nhưng một nghĩa. Phương pháp sinh khoảng mười câu trả lời, gom thành các cụm cùng nghĩa bằng kiểm tra entailment hai chiều, rồi tính entropy trên các cụm. Entropy cao nghĩa là model đưa ra nhiều đáp án khác nghĩa nhau: dấu hiệu của confabulation.

Trung bình trên 30 tổ hợp dataset và model (LLaMA 2 Chat, Falcon Instruct, Mistral Instruct; TriviaQA, SQuAD, BioASQ, NQ-Open, SVAMP), semantic entropy đạt AUROC 0,790, so với 0,691 của entropy thường, 0,698 của P(True) và 0,687 của một baseline hồi quy trên embedding.

Giới hạn nằm ngay trong định nghĩa: paper viết rõ phương pháp không xử lý trường hợp model sai một cách tự tin vì được train để sai có hệ thống. Nếu model học nhầm một fact và lần nào cũng nói fact nhầm đó, mười mẫu cùng một cụm và entropy thấp. Tính nhất quán đo được confabulation, không đo được lỗi nhất quán.

Với model mở còn hướng thứ ba: đọc activation bên trong để tìm tín hiệu “model có biết hay không”. Đó là chủ đề của bài 17.


07Một con số benchmark gồm những gì

Bốn thành phần

Bài 5, mục 6 đã viết: điểm benchmark = năng lực + phần ghi nhớ có thể đã thấy + nhiễu đo đạc. Bài này tách thêm một thành phần:

điểm benchmark = năng lực thật + phần đã nhìn thấy + độ nhạy với cách hỏi + nhiễu thống kê

Phần đã nhìn thấy là contamination (mục 9); độ nhạy với cách hỏi (format, thứ tự đáp án, số shot, cách chấm) và nhiễu thống kê ở mục 8. Hình 2 đặt bốn thành phần thành bốn hàng, mỗi hàng ghi dấu hiệu nhận ra, cách đo và cách giảm.

~/diagrams/vi-sao-llm-sai-va-do-nhu-the-nao/benchmark-score-parts.htmltương tác
mở riêng ↗
HìnhHàng 1, năng lực thật: phần ta muốn đo, dấu hiệu là kết quả giữ được trên đề mới cùng độ khó; đo bằng nhiều benchmark khớp nhau; giữ bằng eval theo tác vụ riêng. Hàng 2, phần đã nhìn thấy: đề lọt vào training data, dấu hiệu là điểm tụt trên đề viết lại; đo bằng kiểm tra thứ tự, Min-K% hay so theo ngày phát hành; khử bằng benchmark cập nhật liên tục và private set (mục 9). Hàng 3, độ nhạy với cách hỏi: format, thứ tự đáp án, cách chấm; dấu hiệu là đổi format thì đổi điểm; đo bằng cách chạy nhiều format; khử bằng báo khoảng thay vì một số và ghi rõ cách chấm (mục 8). Hàng 4, nhiễu thống kê: số câu có hạn; dấu hiệu là chênh 1–2 điểm; đo bằng SE, CI và so sánh paired; giảm bằng thêm câu và lấy mẫu lại (mục 8).
phần của con sốcách đokhung xám: dấu hiệu nhận ra; khung tím: cách giảm hoặc khử

Benchmark tự nó có lỗi

Trước cả bốn thành phần, đáp án chuẩn có thể sai. Gema et al. 2024 (Are We Done with MMLU?) cho 14 chuyên gia gán nhãn lại 5.700 câu MMLU (100 câu mỗi môn) và ước tính 6,49% câu hỏi của MMLU có lỗi: câu hỏi hoặc lựa chọn mơ hồ, không có đáp án đúng, nhiều đáp án đúng, hoặc đáp án chuẩn sai (abstract, Bảng 5). Lỗi đổi được thứ hạng: ở môn Virology, Llama 3.1 Instruct Turbo (405B) xếp thứ 16 khi tính mọi câu nhưng xếp thứ nhất khi chỉ tính câu không lỗi (mục 3.2, Bảng 2).

Bão hoà và tuổi thọ

Khi MMLU ra đời năm 2020, GPT-3 175B đạt 43,9% (Hendrycks et al., mục 1). Năm 2024, các model hàng đầu đã ở mức 86–87% (Wang et al. 2024, mục 1). Khi khoảng cách giữa các model nhỏ hơn mức lỗi của đề, benchmark không còn phân biệt được chúng. MMLU-Pro tăng số lựa chọn từ bốn lên mười; accuracy giảm 16–33% so với MMLU, và độ nhạy với 24 kiểu prompt giảm từ 4–5% xuống khoảng 2% (abstract). Humanity’s Last Exam (Phan et al. 2025) gom 2.500 câu do chuyên gia viết, lọc đối kháng với các model frontier: theo bản arXiv v8, model tốt nhất (o3-mini high) đạt 13,4%, GPT-4o 2,7%, và mọi model có RMS calibration error trên 70% (Bảng 1). Chính paper lưu ý điểm thấp một phần là do thiết kế lọc đối kháng, và chuyên gia bất đồng với đáp án ở khoảng 15,4% số câu của tập công khai (Phụ lục B.3).

Factuality benchmark tính đến việc từ chối

  • TruthfulQA (Lin et al. 2021): 817 câu hỏi thuộc 38 chủ đề nhắm vào hiểu lầm phổ biến. Model tốt nhất lúc đó trung thực ở 58% số câu, con người 94% (abstract); model lớn hơn thường kém trung thực hơn vì bắt chước hiểu lầm tốt hơn (mục 4.2).
  • FActScore (Min et al. 2023): tách tiểu sử thành các fact nguyên tử rồi kiểm với Wikipedia; độ chính xác của ChatGPT giảm từ 80% với nhân vật rất phổ biến xuống 16% với nhân vật rất hiếm (mục 1).
  • SimpleQA (Wei et al. 2024): 4.326 câu hỏi fact ngắn, thu thập đối kháng với GPT-4, chấm ba loại đúng, sai và không trả lời (mục 2.4).

Bảng 3 của SimpleQA cho thấy vì sao cần loại thứ ba:

Model Đúng Không trả lời Sai
Claude-3-haiku (2024-03-07) 5,1% 75,3% 19,6%
Claude-3.5-sonnet (2024-06-20) 28,9% 35,0% 36,1%
GPT-4o-mini 8,6% 0,9% 90,5%
GPT-4o 38,2% 1,0% 60,8%
OpenAI o1-preview 42,7% 9,2% 48,1%

GPT-4o-mini và Claude-3-haiku có số câu đúng gần nhau, nhưng một model sai 90,5%, model kia sai 19,6% và từ chối phần còn lại. Leaderboard chỉ in cột “đúng” sẽ xếp GPT-4o-mini trên. Với luật chấm có phạt (+1 / 0 / −p) và p = 9, không model nào được đánh giá có điểm dương (mục 2.4). Khi được hỏi độ tự tin, các model “luôn nói quá” (mục 4, Hình 2).


08Độ nhạy với prompt và nhiễu thống kê

Đổi format, đổi điểm

Sclar et al. 2023 đổi những chi tiết format không đổi nghĩa (dấu cách, dấu phân cách, viết hoa, “Question:” hay “QUESTION:”) trên 53 tác vụ. Chỉ đổi format đã làm chênh lệch tới 76 điểm accuracy với LLaMA-2-13B (abstract); trung vị của khoảng chênh là 7,5 điểm (mục 4.2). Độ nhạy không mất khi tăng kích thước model, tăng số shot hay instruction tuning. Format tốt cho model này không chắc tốt cho model kia: xác suất thứ tự giữa LLaMA-2-13B và LLaMA-2-70B bị đảo khi đổi format, tính với chênh lệch ít nhất 2 điểm, là 0,141 (mục 4.2, Hình 4). Paper đề xuất báo một khoảng hiệu năng qua nhiều format thay vì một con số.

Đổi thứ tự đáp án, đổi thứ hạng

Alzahrani et al. 2024 (When Benchmarks are Targets) đổi thứ tự lựa chọn, đổi ký hiệu A/B/C/D và đổi cách chấm trên MMLU với 11 model. Những thay đổi nhỏ này làm thứ hạng đổi tới 8 bậc (abstract); Yi-6b từ hạng 3 xuống hạng 7 hoặc 8 (mục 5.1). Mọi model được thử đều có thiên kiến chọn theo token và vị trí (mục 5.2). Code 1 là phiên bản nhỏ của thí nghiệm này: đảo thứ tự làm Qwen3-0.6B đổi đáp án ở 137/200 câu trong khi accuracy chỉ đổi 0,5 điểm, vì thay đổi theo hai chiều triệt tiêu nhau.

Cùng benchmark, nhiều cách chấm

Biderman et al. 2024 (Lessons from the Trenches, nhóm làm lm-evaluation-harness) liệt kê nhiều cách chấm cùng một bộ câu: so log-likelihood của chữ cái (như Code 1), so log-likelihood của nội dung đáp án mà không cho model thấy các lựa chọn (cloze), hoặc sinh tự do rồi trích đáp án. Khác biệt có thể rất lớn: Mistral-7B đạt 50,1% trên ARC-Challenge kiểu cloze nhưng 72,4% kiểu liệt kê lựa chọn (mục 3.1, Bảng 1); paper tóm lại là chênh “trong một số trường hợp, trên 20%”. Tính không tất định khi chạy eval đã có ở bài 9, mục 7.

Error bar: chênh 1 điểm có nghĩa không

Miller 2024 (Adding Error Bars to Evals, Anthropic) đưa năm khuyến nghị (mục 1):

  1. Tính standard error của trung bình. Với điểm đúng/sai, SE = √(p(1−p)/n), khoảng tin cậy 95% là p ± 1,96 × SE (mục 2.1).
  2. Khi câu hỏi đi theo nhóm (nhiều câu về cùng một đoạn văn), dùng clustered SE. Trên DROP, SE có cluster lớn gấp 3,05 lần SE thường (mục 2.2, Bảng 4).
  3. Giảm phương sai bằng cách lấy nhiều mẫu cho mỗi câu, hoặc dùng xác suất token khi không dùng chain-of-thought (mục 3).
  4. So hai model bằng so sánh paired trên hiệu từng câu (mục 4.2). Hai model hay đúng và sai cùng những câu, nên Var(B − A) = Var(A) + Var(B) − 2Cov(A, B) nhỏ hơn tổng hai phương sai.
  5. Dùng power analysis. Trong ví dụ của paper, phát hiện chênh 3 điểm với power 80% cần khoảng 969 câu, nên benchmark mới nên có ít nhất 1.000 câu (mục 5).

Madaan et al. 2024 thêm một nguồn nhiễu: train lại cùng model với seed khác. Với 10 model kiến trúc Llama-2-7B chỉ khác seed, độ lệch chuẩn theo seed là 1,11 điểm trên HumanEval và 2,15 điểm trên COPA (Bảng 1).

Code mẫu 3: error bar cho hai model

Code dưới tạo kết quả đúng/sai từng câu cho hai model trên cùng 500 câu; độ khó là chung nên kết quả tương quan. Model B được tạo để giỏi hơn A thật sự khoảng 1,4 điểm. Với 500 câu, ta có thấy được điều đó không?

# Python 3.12.13, numpy 2.5.4. Không cần weights. Chạy: python code3.py
import numpy as np

rng = np.random.default_rng(0)
N = 500
# Kết quả đúng/sai từng câu của hai model trên cùng 500 câu. Độ khó của câu là chung,
# nên hai model hay đúng và sai cùng câu: kết quả của chúng tương quan với nhau.
difficulty = rng.normal(0, 2.0, N)
p_a = 1 / (1 + np.exp(-(1.0 - difficulty)))
p_b = 1 / (1 + np.exp(-(1.1 - difficulty)))     # B "giỏi hơn" A khoảng 1 điểm
a = (rng.random(N) < p_a).astype(float)
b = (rng.random(N) < p_b).astype(float)

def se(x):                                       # standard error của trung bình (Miller 2024, Eq. 1)
    return x.std(ddof=1) / np.sqrt(len(x))

for name, x in (("A", a), ("B", b)):
    m, s = x.mean(), se(x)
    print(f"model {name}: accuracy={m:.3f}  SE={s:.4f}  CI95=[{m - 1.96 * s:.3f}, {m + 1.96 * s:.3f}]")

d = b - a
diff = d.mean()
se_unpaired = np.sqrt(se(a) ** 2 + se(b) ** 2)  # coi hai model là hai mẫu độc lập
se_paired = se(d)                                # dùng hiệu từng câu (Miller 2024, mục 4.2)
print(f"\nchênh lệch thật (kỳ vọng) B - A = {(p_b - p_a).mean():+.3f}")
print(f"chênh lệch đo được B - A = {diff:+.3f}   corr(A, B) theo từng câu = {np.corrcoef(a, b)[0, 1]:.2f}")
print(f"unpaired: SE={se_unpaired:.4f}  CI95=[{diff - 1.96 * se_unpaired:+.3f}, {diff + 1.96 * se_unpaired:+.3f}]")
print(f"paired:   SE={se_paired:.4f}  CI95=[{diff - 1.96 * se_paired:+.3f}, {diff + 1.96 * se_paired:+.3f}]")

boot = rng.integers(0, N, size=(10_000, N))      # bootstrap: lấy lại câu hỏi, giữ cặp (A, B)
bd = d[boot].mean(axis=1)
print(f"bootstrap paired CI95=[{np.percentile(bd, 2.5):+.3f}, {np.percentile(bd, 97.5):+.3f}]")
print(f"câu chỉ B đúng: {int((d > 0).sum())}, câu chỉ A đúng: {int((d < 0).sum())}")

# Cần bao nhiêu câu để phát hiện chênh lệch delta? (z = 1,96 cho CI95, z = 0,84 cho power 80%)
for delta in (0.01, 0.02, 0.05):
    n_need = ((1.96 + 0.84) * d.std(ddof=1) / delta) ** 2
    print(f"số câu cần để phát hiện chênh {delta:.2f} với power 80%: khoảng {n_need:,.0f}")

Output:

model A: accuracy=0.672  SE=0.0210  CI95=[0.631, 0.713]
model B: accuracy=0.668  SE=0.0211  CI95=[0.627, 0.709]

chênh lệch thật (kỳ vọng) B - A = +0.014
chênh lệch đo được B - A = -0.004   corr(A, B) theo từng câu = 0.48
unpaired: SE=0.0298  CI95=[-0.062, +0.054]
paired:   SE=0.0214  CI95=[-0.046, +0.038]
bootstrap paired CI95=[-0.046, +0.038]
câu chỉ B đúng: 56, câu chỉ A đúng: 58
số câu cần để phát hiện chênh 0.01 với power 80%: khoảng 17,910
số câu cần để phát hiện chênh 0.02 với power 80%: khoảng 4,477
số câu cần để phát hiện chênh 0.05 với power 80%: khoảng 716

Bốn điều đọc được:

  • Model giỏi hơn lại có điểm thấp hơn. B giỏi hơn A 1,4 điểm theo cách tạo dữ liệu, nhưng trên 500 câu này thấp hơn 0,4 điểm. Leaderboard in “67,2 so với 66,8” sẽ xếp A trên B.
  • Khoảng tin cậy của mỗi model rộng khoảng ±4 điểm, và hai khoảng chồng lên nhau gần như hoàn toàn.
  • Paired hẹp hơn unpaired nhưng chưa đủ. Với tương quan 0,48, SE của hiệu giảm từ 2,98 xuống 2,14 điểm; khoảng tin cậy vẫn chứa cả 0 lẫn chênh lệch thật +1,4. Bootstrap cho cùng kết quả với công thức.
  • Phát hiện chênh 1 điểm cần khoảng 18.000 câu ở mức tương quan này; chênh 5 điểm thì 716 câu là đủ. Chỉ 114 câu có kết quả khác nhau giữa hai model (56 + 58), và mọi thông tin về “model nào hơn” nằm ở đó.

09Contamination nhìn từ phía người đo

Bài 5, mục 6 đã định nghĩa bốn mức contamination và cách decontaminate khi người train có toàn bộ dữ liệu. Mục này đứng ở phía người đo: không có training data, chỉ có model, thường qua API.

Bằng chứng tác động: GSM1k

Zhang et al. 2024 thuê người viết 1.205 bài toán mới, cùng phong cách và độ khó với GSM8K, không dùng LLM, và chỉ công bố 50 bài (Phụ lục G, Hình 2). Model đã thấy GSM8K sẽ tụt trên GSM1k. Kết quả (bản arXiv v4): một số model tụt tới 8% (abstract; bản v1 ghi 13%). Họ Phi và Mistral có dấu hiệu overfit có hệ thống, Yi, Xwin, Gemma và CodeLlama nhẹ hơn (mục 5.1); mức tụt lớn nhất là Yi-6B-Chat, 8,0 điểm (Phụ lục F). Các model frontier (GPT-4, GPT-4o, Claude 3 Opus, Gemini 1.5 Pro) gần như không tụt (Phụ lục F).

Khả năng model sinh lại chính các câu của GSM8K tương quan với mức tụt, Spearman 0,36, p = 0,03, nhưng theo tác giả contamination “nhiều khả năng không phải toàn bộ lời giải thích” (mục 5.4). Phi-2 tụt 6% nhưng vẫn giải được hơn nửa GSM1k (mục 5.3).

Bốn cách phát hiện từ bên ngoài

  1. So theo ngày phát hành. LiveCodeBench (Jain et al. 2024, bản arXiv v2) gắn ngày cho 511 bài lập trình từ LeetCode, AtCoder, Codeforces (05/2023–05/2024). Điểm của DeepSeek-Coder trên bài LeetCode tụt mạnh với bài phát hành sau khoảng tháng 9/2023, gần ngày model ra mắt; DS-Base-33B từ pass@1 khoảng 60 ở bài tháng 5 xuống gần 0 ở bài tháng 9 (mục 5.1). Giới hạn: cần biết ngày cắt dữ liệu, và tập đề sau đó có thể rất nhỏ.
  2. Kiểm tra thứ tự của test set. Oren et al. 2023: nếu model chưa thấy test set, mọi thứ tự các câu phải có khả năng như nhau; model gán log-likelihood cao hơn rõ cho thứ tự gốc là đã thấy nguyên văn. Phương pháp có đảm bảo thống kê về false positive. Giới hạn: chỉ bắt contamination nguyên văn, bắt đầu phát hiện từ khoảng 4 lần lặp (Hình 2), và không đạt ngưỡng không chứng minh được là sạch.
  3. Bắt model đọc tiếp đề. Golchin & Surdeanu 2023 đưa tên dataset, tên split và phần đầu một câu, rồi yêu cầu viết tiếp; phần viết tiếp khớp gần nguyên văn là dấu hiệu đã thấy. Kết quả khớp với đánh giá của hai chuyên gia ở 92–100% số trường hợp (Bảng 3), và cho thấy GPT-4 đã thấy AG News, WNLI và XSum (abstract). Giới hạn: mỗi split chỉ kiểm 10 câu.
  4. Min-K% Prob. Shi et al. 2023 lấy 20% token có xác suất thấp nhất trong một đoạn và tính log-likelihood trung bình của chúng: đoạn chưa thấy thường có vài từ “lạ” với xác suất rất thấp. Trên WikiMIA, AUC trung bình 0,72, tăng 7,4% tương đối so với baseline perplexity 0,67 (Bảng 1). Giới hạn: AUC 0,72 còn xa mức đáng tin cho từng đoạn, và cần logprob.

Cả bốn là kiểm định một chiều: phát hiện được thì có contamination; không phát hiện được thì chưa kết luận được gì, vì contamination dạng diễn đạt lại hay dạng lời giải trên diễn đàn gần như vô hình với cả bốn.

Thiết kế chống contamination

  • Cập nhật liên tục. LiveBench (White et al. 2024, bản arXiv v2) thêm câu hỏi mới mỗi tháng, chấm bằng đáp án khách quan thay vì LLM judge, và luôn giữ khoảng 1/6 số câu chưa công bố (mục 2.7). Khi ra mắt (bản v1, 06/2024), model tốt nhất đạt dưới 65%. Tiêu đề bản v1 dùng chữ “contamination-free”, bản v2 đổi thành “contamination-limited”.
  • Held-out private set, như GSM1k và HLE, đổi lại phải tin người giữ đề.
  • Câu hỏi sinh động: sinh câu mới từ mẫu hoặc tham số mỗi lần đánh giá, để không có bản cố định nào lọt ra ngoài.

10LLM-as-judge khi so sánh model

Với câu hỏi mở, không có đáp án để so, và thuê người chấm thì chậm, đắt. Giải pháp phổ biến là dùng một LLM mạnh làm giám khảo. Bài 11, mục 9 đã nêu ba thiên kiến của judge theo Zheng et al. 2023 (position, verbosity, self-enhancement); series RAG đã đi qua G-Eval, QAG và cách đặt ngưỡng cho judge ở bài đánh giá RAG và bài benchmark RAG. Mục này chỉ nói phần còn thiếu: dùng judge để so sánh model, và đo thiên kiến bằng số.

Ba kiểu chấm

Zheng et al. 2023 (mục 3.1) chia ba kiểu. So cặp cho judge xem hai câu trả lời và hỏi câu nào tốt hơn; hợp với câu hỏi mở, nhưng số cặp tăng theo bình phương số model. Chấm điểm đơn lẻ chấm một câu trả lời theo thang, ví dụ 1–10; mở rộng tốt nhưng điểm tuyệt đối dễ trôi khi đổi judge. Chấm theo đáp án tham chiếu đưa thêm đáp án mẫu (trong thí nghiệm là đáp án GPT-4 tự sinh trước), hợp với toán hay QA: trong thí nghiệm của paper, nó làm tỷ lệ GPT-4 chấm sai câu toán giảm từ 70% xuống 15% (mục 3.4, Bảng 4). Hình 3 là luồng so cặp, với các điểm thiên kiến chen vào và biện pháp ở từng chỗ.

~/diagrams/vi-sao-llm-sai-va-do-nhu-the-nao/llm-judge-pairwise.htmltương tác
mở riêng ↗
HìnhHàng giữa là luồng chính: một câu hỏi từ bộ đánh giá; hai model A và B trả lời; hai câu trả lời được xếp vào prompt của judge theo một thứ tự; LLM judge đọc cả hai và so sánh; judge đưa ra kết luận A, B hay hoà; kết luận được gộp trên mọi câu thành win rate. Hàng trên là thiên kiến chen vào: câu dài được ưa (ở bước câu trả lời), đổi chỗ thì đổi kết quả (ở bước xếp vào prompt), judge ưa output của chính mình (ở bước judge), và judge dễ dãi, hay chấm là đúng (ở bước kết luận). Hàng dưới là biện pháp: kiểm soát độ dài như Length-Controlled AlpacaEval, chấm cả hai thứ tự và chỉ tính khi kết quả nhất quán, dùng rubric và đáp án tham chiếu, dùng nhiều judge từ các họ model khác nhau, và đối chiếu với nhãn người bằng chỉ số có hiệu chỉnh (κ, π) chứ không chỉ phần trăm đồng thuận.
model sinh hoặc chấmbước của quy trình chấmkhung xám: thiên kiến; khung tím: biện pháp; khung xanh dương: đầu vào

Judge đồng thuận với người tới đâu

Trên MT-Bench, khi loại phiếu hoà, GPT-4 đồng thuận với chuyên gia ở 85% số trường hợp, cao hơn mức đồng thuận giữa các chuyên gia (81%) (Zheng et al., mục 4.2, Bảng 5). Con số này hay bị đọc thành “judge chấm tốt như người”. Thakur et al. 2024 (Judging the Judges) cho 13 judge chấm câu trả lời của 9 model trên 400 câu TriviaQA, một tác vụ cố ý đơn giản mà con người đồng thuận tới 98,5%:

  • Phần trăm đồng thuận cao với hầu hết judge, nhưng chỉ số có hiệu chỉnh cho đồng thuận ngẫu nhiên (Scott’s π ở bản mới nhất; các bản trước dùng Cohen’s κ) chỉ cao với GPT-4 Turbo, Llama-3.1 70B và Llama-3 70B (mục 4.1).
  • Judge có đồng thuận trên 90% vẫn có thể cho điểm lệch hơn 10 điểm so với người (mục 4.1).
  • Judge có xu hướng dễ dãi: với trường hợp không chắc, xác suất chấm “đúng” của hầu hết judge cao hơn rõ 0,5 (mục 5.4).

Thiên kiến đo bằng số

  • Vị trí. GPT-4 giữ nguyên kết luận khi đổi chỗ hai câu trả lời ở 65,0% số trường hợp, Claude-v1 chỉ 23,8% (Zheng et al., mục 3.3, Bảng 2). Wang et al. 2023 (Large Language Models are not Fair Evaluators): khi ChatGPT làm judge so Vicuna-13B với ChatGPT trên 80 câu, Vicuna thắng 82,5% khi đứng ở vị trí thứ hai, và kết luận đổi ở 66/80 câu khi đổi chỗ (mục 2.2, Bảng 2).
  • Độ dài. Zheng et al. chèn vào một danh sách đánh số các mục chỉ diễn đạt lại mục đã có, rồi hỏi judge câu nào tốt hơn: Claude-v1 và GPT-3.5 bị lừa ở 91,3% số trường hợp, GPT-4 ở 8,7% (mục 3.3, Bảng 3).
  • Tự ưu tiên. Panickssery et al. 2024: GPT-4 phân biệt được output của chính mình với output của người và hai model khác ở 73,5% số trường hợp (mục 1). Fine-tune GPT-3.5 và Llama 2 để tự nhận ra output của mình làm mức tự ưu tiên tăng theo một xu hướng tuyến tính (mục 3.2); paper lưu ý đây là bằng chứng ủng hộ, chưa chứng minh quan hệ nhân quả (mục 5.2).

Cách giảm thiên kiến

  • Chấm cả hai thứ tự, chỉ tính thắng khi kết luận giữ nguyên (Zheng et al., mục 3.4). Wang et al. lấy trung bình qua hai thứ tự và bắt judge viết lập luận trước khi chấm; với GPT-4, độ chính xác so với đa số người tăng từ 52,7% lên 62,5% (Bảng 4).
  • Kiểm soát độ dài. Length-Controlled AlpacaEval (Dubois et al. 2024) dùng hồi quy để ước tính win rate nếu hai câu trả lời dài bằng nhau; tương quan Spearman với Chatbot Arena tăng từ 0,94 lên 0,98 (mục 4.2), và mức có thể “chơi” điểm bằng cách bảo model viết dài hay ngắn giảm từ 25% xuống 10% (mục 4.1).
  • Rubric và đáp án tham chiếu, nhiều judge từ các họ model khác nhau, và đối chiếu với nhãn người trên một tập nhỏ bằng κ hay π, không chỉ phần trăm đồng thuận.

Chatbot Arena và giới hạn

Chatbot Arena (Chiang et al. 2024) để người dùng gõ câu hỏi bất kỳ, nhận hai câu trả lời từ hai model ẩn danh và bầu câu tốt hơn. Thứ hạng tính bằng mô hình Bradley–Terry: xác suất model i thắng model j phụ thuộc vào hiệu hai hệ số, kèm khoảng tin cậy (mục 4).

Arena đo sở thích của người dùng thật, nhưng phân bố câu hỏi lệch về người quan tâm tới LLM (mục 8), và style, độ dài ảnh hưởng tới phiếu. The Leaderboard Illusion (Singh et al. 2025) chỉ ra vấn đề về quy trình: Meta thử 27 biến thể riêng tư trước khi ra mắt Llama 4 (mục 3.1); Google và OpenAI ước tính nhận 19,2% và 20,4% toàn bộ dữ liệu của Arena, trong khi 83 model open-weight cộng lại nhận 29,7% (abstract); 205 trên 243 model công khai bị ngừng âm thầm (mục 4.1). Thêm dữ liệu Arena vào dữ liệu train làm win rate trên ArenaHard tăng tới 112% tương đối, trong khi MMLU gần như không đổi (mục 4.2). Paper tự nêu xung đột lợi ích: một số tác giả đến từ Cohere.

Arena-Hard (Li et al. 2024) tự động hoá Arena: lọc 500 câu khó từ 200.000 câu hỏi, cho judge so mỗi model với một model mốc theo cả hai thứ tự. Trên 20 model hàng đầu, 87,4% số cặp model có khoảng tin cậy tách rời (separability), so với 22,6% của MT-Bench, và mức khớp có độ tin cậy với thứ hạng Chatbot Arena (confidence agreement) là 90,9% (Bảng 1).


11Đọc một con số benchmark thế nào

Gộp các mục 7–10 thành một bảng kiểm. Khi đọc, hoặc tự công bố, một con số benchmark, cần có:

Cần có Vì sao Thiếu thì sao
Phiên bản dataset MMLU gốc và MMLU-Redux cho số khác nhau; benchmark live đổi theo tháng Không so được với báo cáo khác
Cách chấm Log-likelihood chữ cái, cloze hay sinh rồi trích có thể lệch trên 20 điểm Hai con số “MMLU” là hai phép đo khác nhau
Prompt và số shot Format lệch tới 76 điểm (Sclar); thứ tự đáp án đổi thứ hạng tới 8 bậc Không tái lập được
Có tính “không biết” không Chấm nhị phân thưởng cho đoán (Kalai, SimpleQA) Model bịa nhiều trông như model giỏi
Khoảng tin cậy, số câu 500 câu: CI khoảng ±4 điểm (Code 3) Chênh 1–2 điểm không mang thông tin
So sánh paired Hiệu từng câu hẹp hơn hai CI riêng Kết luận quá thận trọng hoặc quá tự tin
Kiểm tra contamination Model có thể tụt tới 8 điểm trên đề mới (GSM1k) Điểm đo phần ghi nhớ
Judge và phiên bản judge Judge có thiên kiến vị trí, độ dài, tự ưu tiên Đổi judge, đổi kết quả
Số seed hoặc số lần chạy Độ lệch theo seed 1–2 điểm trên benchmark nhỏ (Madaan) Một lần chạy có thể chỉ là may

Không cần mọi dòng cho mọi con số, nhưng thiếu càng nhiều dòng, con số càng nên được đọc như một gợi ý hơn là một phép đo. Phần vận hành eval trong production đã có ở bài production RAG evaluation.


12Những chỗ dễ hiểu sai

Chín hiểu lầm dưới đây khớp với hàng trên cùng và hàng dưới cùng của Hình 1.

Hiểu lầm Thực tế
“Hallucination là lỗi ngẫu nhiên, model to hơn sẽ hết” Có nguyên nhân thống kê: fact chỉ xuất hiện một lần là nơi model calibrated buộc phải sai. Với câu hỏi hiếm, ngoại suy cần tới hơn 10^18 tham số (mục 3)
“Thêm dữ liệu đúng vào fine-tuning thì model bớt bịa” Ví dụ chứa kiến thức model chưa biết được học chậm, và học xong thì model sai nhiều hơn (Gekhman et al.) (mục 4)
“Model nói ‘chắc chắn 90%’ nghĩa là đúng 90%” Độ tự tin nói ra thường quá tự tin, tập trung ở 80–100% và là bội số của 5 (mục 5)
“Độ tự tin cao nghĩa là câu trả lời đúng” Calibration là tính chất của một nhóm dự đoán. Model sai nhất quán có độ tự tin cao và semantic entropy thấp (mục 5, 6)
“Điểm cao hơn 1–2 điểm nghĩa là model tốt hơn” Với 500 câu, CI khoảng ±4 điểm; cần khoảng 18.000 câu để thấy chênh 1 điểm (Code 3, mục 8)
“Không tìm thấy contamination nghĩa là không có” Các phương pháp từ bên ngoài là kiểm định một chiều và gần như không thấy contamination dạng diễn đạt lại (mục 9)
“Benchmark công khai đo năng lực tổng quát” Đo một lát cắt hẹp, có lỗi trong đề (6,49% ở MMLU), nhạy với format, và bão hoà theo thời gian (mục 7, 8)
“LLM judge khách quan hơn người” Judge có thiên kiến vị trí, độ dài, tự ưu tiên, dễ dãi; phần trăm đồng thuận cao vẫn có thể che sai lệch hơn 10 điểm (mục 10)
“Arena Elo là thứ hạng tuyệt đối” Phụ thuộc phân bố câu hỏi, style, độ dài và quy trình (thử biến thể riêng, phân bổ dữ liệu không đều) (mục 10)

Tổng kết: sai có nguyên nhân, đo có sai số

  • Hallucination có nguyên nhân thống kê. Với fact tuỳ ý chỉ xuất hiện một lần, model calibrated buộc phải sai ở một tỷ lệ có cận dưới; sinh câu hợp lệ khó hơn phân loại câu hợp lệ. Lỗi tập trung ở kiến thức long-tail, nơi retrieval giúp nhiều hơn tăng kích thước model.
  • Post-training và luật chấm làm nặng thêm. SFT trên kiến thức mới dạy model đoán, RLHF thêm sycophancy, chấm nhị phân thưởng cho việc đoán. Code 2: cùng kiến thức, đổi luật chấm là đổi thứ hạng.
  • Calibration cho biết khi nào nên tin. Base model lớn khá calibrated, post-training làm lệch; độ tự tin từ xác suất token, lời nói hay độ nhất quán đều có điểm yếu. Code 1: một model nhỏ quá tự tin ở mọi bin.
  • Độ nhất quán (SelfCheckGPT, semantic entropy) bắt được confabulation, không bắt được lỗi nhất quán.
  • Một con số benchmark là tổng của bốn phần: năng lực, phần đã nhìn thấy, độ nhạy với cách hỏi, nhiễu; cộng thêm lỗi trong đề và việc bão hoà.
  • Chênh 1–2 điểm thường là nhiễu. Code 3: model giỏi hơn có thể điểm thấp hơn trên 500 câu.
  • Contamination khó chứng minh từ bên ngoài; benchmark cập nhật và đề giữ kín bền hơn.
  • LLM judge mở rộng được việc đo nhưng có thiên kiến riêng; phải đo chính judge như đo một model.

Mọi phương pháp trong bài đều nhìn model từ bên ngoài: đọc output, đọc xác suất, so nhiều mẫu. Bài 17 sẽ nhìn vào bên trong: interpretability, ví dụ dùng probe để tìm tín hiệu “biết hay không biết” ngay trong activation của model.


Tài liệu tham khảo

Paper: hallucination

Paper: calibration

Paper: benchmark, nhiễu và contamination

Paper: LLM-as-judge và leaderboard

Model và dataset

Trương Đức Dũng

AI Engineer - Hà Nội

Tập trung vào LLM, RAG và các hệ thống AI cần chạy ổn định trong môi trường vận hành thật.