跳转至

第22章 · LLM Evaluation 方法学 · 阶段测试题

题型: 单选 × 8 / 多选 × 4 / 简答 × 5 / 编程 × 2 = 共 19 题 建议用时: 60 分钟


一 · 单选题 (8 题)

1.1 BLEU 衡量的是? - A. Recall - B. n-gram Precision - C. F1 - D. Perplexity

1.2 MMLU 主要衡量什么能力? - A. 代码生成 - B. 多学科世界知识 + 推理 - C. 中文理解 - D. 长文本

1.3 LMSYS Chatbot Arena 用什么排序算法? - A. PageRank - B. Bradley-Terry / ELO - C. SVM - D. K-Means

1.4 下面哪个不是 LLM-as-Judge 的常见 Bias? - A. Position Bias - B. Verbosity Bias - C. Self-Bias - D. Confidence Bias

1.5 Data Contamination 的检测方法不包括? - A. n-gram overlap - B. Membership Inference - C. Random Forest - D. 模型在测试题上的"死记硬背"行为

1.6 HELM 是哪个机构提出的? - A. OpenAI - B. Stanford CRFM - C. DeepMind - D. Microsoft

1.7 lm-evaluation-harness 出品方? - A. OpenAI - B. EleutherAI - C. Anthropic - D. Google

1.8 Benchmark Saturation 是什么意思? - A. Benchmark 太难 - B. Benchmark 被模型刷到 95%+ 已失效 - C. Benchmark 没更新 - D. Benchmark 太少


二 · 多选题 (4 题)

2.1 下面哪些是传统 NLP 指标? (多选) - A. BLEU - B. ROUGE - C. METEOR - D. chrF

2.2 Bradley-Terry 模型应用场景? (多选) - A. LMSYS Arena 排名 - B. 偏好数据建模 - C. 推荐系统 - D. K-Means 聚类

2.3 LLM-as-Judge 的 3 大模式? (多选) - A. Single-Point Grading - B. Pairwise Comparison - C. Reference-based Scoring - D. Multi-Class

2.4 Harness Engineering 5 大支柱? (多选) - A. Eval Harness - B. Inference Harness - C. Agent Harness - D. Safety Harness - E. Data Harness


三 · 简答题 (5 题)

3.1 解释 BLEU 与 BERTScore 的核心区别, 并说明 BERTScore 在哪类任务上更优。

3.2 解释 Construct Validity 概念, 并用具体例子说明"模型在 Benchmark 高分 ≠ 真实能力"。

3.3 设计一个 LLM-as-Judge 的 Prompt 模板, 至少包含 4 个要素 (评分维度 / Few-shot / CoT / JSON Output)。

3.4 解释 MMLU / GSM8K / HumanEval / HellaSwag / TruthfulQA 各测什么能力, 互补关系。

3.5 比较 lm-evaluation-harness / OpenCompass / HELM 三个评测框架的特色和适用场景。


四 · 编程题 (2 题)

4.1 实现 Pairwise LLM-as-Judge (消除 Position Bias)

def pairwise_judge(judge_llm, answer_a, answer_b, prompt):
    """
    judge_llm: callable(str) -> "A" | "B"
    prompt: 评判 prompt
    返回:
      "A" | "B" | "TIE" (交换位置后两次投票)
    """
    pass

4.2 实现 Benchmark Contamination 检测 (n-gram overlap)

def detect_contamination(train_texts, test_texts, n=13):
    """
    检测测试集 n-gram 是否出现在训练集
    返回 contamination_rate (被污染样本比例)
    """
    pass


五 · 参考答案

单选

1.1 B 1.2 B 1.3 B 1.4 D 1.5 C 1.6 B 1.7 B 1.8 B

多选

2.1 ABCD 2.2 AB 2.3 ABC 2.4 ABCDE

简答

3.1 BLEU = n-gram Precision (词级别), 不考虑语义; BERTScore = BERT 上下文 embedding 余弦相似度 (语义级)。BERTScore 在开放式生成 / 摘要 / 翻译上更接近人类判断, 在数学/代码等需要精确匹配的任务上 BLEU/EM 仍有优势。

3.2 Construct Validity = Benchmark 测的是它声称测的能力。例子: GSM8K 测数学推理, 但模型可能只是死记训练数据中相似的题 (Contamination), 高分 ≠ 真推理。检测: 用改写题 (paraphrase) 测试分数是否稳定, 大幅下降说明模型没真推理。

3.3 Prompt 模板示例:

You are evaluating two answers to a question.
Question: {question}
Answer A: {answer_a}
Answer B: {answer_b}

Rate each answer on:
1. Correctness (0-5): 是否正确
2. Reasoning (0-5): 推理过程
3. Clarity (0-5): 表达清晰

Let me think step by step:
[CoT]

Output JSON: {"winner": "A/B/TIE", "scores_a": [...], "scores_b": [...]}

3.4 - MMLU: 多学科知识 (广度) - GSM8K: 多步数学 (推理) - HumanEval: 代码生成 (编程) - HellaSwag: 常识推理 (日常) - TruthfulQA: 真实性 (不撒谎) 5 个互补: 知识 + 数学 + 代码 + 常识 + 真实, 全面评估。

3.5 - lm-evaluation-harness (EleutherAI): 通用 200+ Benchmark, 英文为主, 工业首选 - OpenCompass (上海AI Lab): 中文 + 多模态, 国内模型首选 - HELM (Stanford): 7 维 × 16 场景, 综合排名, 学术研究首选

编程

4.1 参考答案:

def pairwise_judge(judge_llm, answer_a, answer_b, prompt):
    # 第一次: A 在前
    p1 = f"{prompt}\nA: {answer_a}\nB: {answer_b}\nWinner:"
    v1 = judge_llm(p1)  # "A" or "B"
    # 第二次: B 在前 (消除 Position Bias)
    p2 = f"{prompt}\nA: {answer_b}\nB: {answer_a}\nWinner:"
    v2 = judge_llm(p2)
    # 转换 v2 (因为 A/B 角色对调)
    v2_inverse = "A" if v2 == "B" else "B" if v2 == "A" else "TIE"
    if v1 == v2_inverse:
        return v1
    return "TIE"

4.2 参考答案:

def detect_contamination(train_texts, test_texts, n=13):
    # 提取训练集所有 n-grams
    train_ngrams = set()
    for text in train_texts:
        tokens = text.split()
        for i in range(len(tokens) - n + 1):
            train_ngrams.add(tuple(tokens[i:i+n]))
    # 检测测试集
    contaminated = 0
    for text in test_texts:
        tokens = text.split()
        for i in range(len(tokens) - n + 1):
            if tuple(tokens[i:i+n]) in train_ngrams:
                contaminated += 1
                break
    return contaminated / len(test_texts)