文章目录
-
- [1. HealthBench 的 7 大主题](#1. HealthBench 的 7 大主题)
- [2. 你的项目:DPO → GRPO 对齐方案怎么讲](#2. 你的项目:DPO → GRPO 对齐方案怎么讲)
- [3. 常见测评集速记表](#3. 常见测评集速记表)
- [4. 三种对比数据筛选方法](#4. 三种对比数据筛选方法)
- [5. 面试可背金句](#5. 面试可背金句)
- [1. 结论:你的 SFT 数据筛选思路是否合理?](#1. 结论:你的 SFT 数据筛选思路是否合理?)
- [2. 面试中推荐讲法](#2. 面试中推荐讲法)
- [3. 这个方法的亮点](#3. 这个方法的亮点)
-
- [亮点 1:不是单纯外部打分,而是 model-oriented](#亮点 1:不是单纯外部打分,而是 model-oriented)
- [亮点 2:和 MoDS 思路一致,但更轻量](#亮点 2:和 MoDS 思路一致,但更轻量)
- [亮点 3:比 Superfiltering 更贴近目标模型](#亮点 3:比 Superfiltering 更贴近目标模型)
- [4. 最大风险:已有相似工作,需要准备差异化](#4. 最大风险:已有相似工作,需要准备差异化)
- [5. 面试官可能质疑什么?怎么回答?](#5. 面试官可能质疑什么?怎么回答?)
- [6. 建议你补强的实验](#6. 建议你补强的实验)
- [7. 简洁八股文](#7. 简洁八股文)
- [[ L_{DPO}](#[ L_{DPO})
-
- [-\mathbb{E} \log \sigma \left( \beta \left[ \log \frac{\pi_\theta(y_w|x)}{\pi_{ref}(y_w|x)}](#-\mathbb{E} \log \sigma \left( \beta \left[ \log \frac{\pi_\theta(y_w|x)}{\pi_{ref}(y_w|x)})
- [[ L_{GRPO}](#[ L_{GRPO})
-
- [-\mathbb{E} \left[ \frac{1}{G} \sum_i \frac{1}{|o_i|} \sum_t \min \left( \rho_{i,t}A_i, \text{clip}(\rho_{i,t},1-\epsilon,1+\epsilon)A_i \right)](#-\mathbb{E} \left[ \frac{1}{G} \sum_i \frac{1}{|o_i|} \sum_t \min \left( \rho_{i,t}A_i, \text{clip}(\rho_{i,t},1-\epsilon,1+\epsilon)A_i \right))
- [d. 如何判断预训练、SFT、对齐可以进入下一阶段?](#d. 如何判断预训练、SFT、对齐可以进入下一阶段?)
- [e. 你是如何进行多卡训练的?2 卡 H200 + 梯度累积](#e. 你是如何进行多卡训练的?2 卡 H200 + 梯度累积)
- [[ B_{eff}](#[ B_{eff})
-
- [f. 梯度累积的作用是什么?](#f. 梯度累积的作用是什么?)
- [g. DeepSpeed ZeRO 1/2/3 阶段](#g. DeepSpeed ZeRO 1/2/3 阶段)
- [h. 什么是 harness engineering?和普通 agent 区别?](#h. 什么是 harness engineering?和普通 agent 区别?)
- [i. 你具体如何取得每个样本的 hidden state?](#i. 你具体如何取得每个样本的 hidden state?)
- [问题 1:DPO 五个维度和官方 DPO loss 是什么关系?](#问题 1:DPO 五个维度和官方 DPO loss 是什么关系?)
- [[ \mathcal L_{DPO}](#[ \mathcal L_{DPO})
-
- [-\mathbb E \log \sigma \left( \beta [ \log \frac{\pi_\theta(y_c|x)}{\pi_{ref}(y_c|x)}](#-\mathbb E \log \sigma \left( \beta [ \log \frac{\pi_\theta(y_c|x)}{\pi_{ref}(y_c|x)})
- 那五个维度是什么?
- 具体实现路径
-
- [Step 1:重构偏好对](#Step 1:重构偏好对)
- [Step 2:转成 TRL DPO 格式](#Step 2:转成 TRL DPO 格式)
- [Step 3:标准 DPO 训练](#Step 3:标准 DPO 训练)
- 面试官视角评估
- [问题 2:测评框架实践怎么讲?](#问题 2:测评框架实践怎么讲?)
- [问题 3:hidden state 分类器 MLP 怎么设计?](#问题 3:hidden state 分类器 MLP 怎么设计?)
- [问题 5:医疗数据筛选 GPT-5.2 打分 prompt 怎么写?](#问题 5:医疗数据筛选 GPT-5.2 打分 prompt 怎么写?)
- 最后给你的统一面试表述
1. HealthBench 的 7 大主题
OpenAI HealthBench 是 5,000 条医疗对话、48,562 条医生编写 rubric、用 GPT-4.1 作为 grader 的医疗评测集;7 大主题是:(OpenAI)
- Emergency referrals:急诊/转诊识别
- Responding under uncertainty:不确定性下的保守回答
- Health data tasks:健康数据/医学信息处理
- Global health:全球健康/公共卫生
- Expertise-tailored communication:按用户专业水平沟通
- Context seeking:主动补问上下文
- Response depth:回答深度与完整性
2. 你的项目:DPO → GRPO 对齐方案怎么讲
一句话版本
我先用 DPO v2 修正医疗偏好数据中的错误偏好方向和低质量 rejected/chosen,再发现 DPO 主要优化 pairwise preference,不能稳定解决开放式医疗问答中的 急诊识别、上下文追问、保守表达和沟通质量 。所以我继续用 GRPO 做行为层面的强化学习对齐,用多维 reward shaping 引导模型在这些 HealthBench 相关维度上改进。
DPO 暴露出的问题
原始 medical pairwise 数据存在几个问题:chosen/rejected 方向不可靠;chosen 往往只是更长,不一定更安全或更准确;缺少上下文追问、hedging、急诊转诊等能力;直接 DPO 容易学到旧论坛式回答风格。你的 DPO v2 因此把目标拆成 accuracy、communication_quality、context_awareness、emergency_referrals、hedging 五类。(GitHub)
数据上,你把训练集重构为 train 3,800 / valid 100 / test 100 ,其中 train 全部被修改,swap_count 为 2,198;主要 issue tags 包括 poor_communication、missing_context_awareness、factual_risk、too_generic、overconfidence、label_direction_wrong。(GitHub)
训练后你发现 DPO 的内部 valid 太容易:step 30 pairwise accuracy 就饱和到 1.0,因此"内部 DPO 指标最优"不等于"真实医疗开放问答最优"。这是你继续做 GRPO 的动机。(GitHub)
GRPO 方案怎么设计
GRPO 不再使用 chosen/rejected pair,而是使用 prompt-only 数据,让模型对同一 prompt 采样多个回答,然后用 reward function 对同组回答打分,组内归一化后更新策略。你的 GRPO 数据来自 DPO v2 train 和高质量 holdout,重点覆盖五类 slice:communication、global_health、hedging、context_seeking、emergency 。(GitHub)
你在 v1 中加强了 emergency 和 context 的占比:train 共 3,000 条,valid 300 条;其中 emergency 550、context_seeking 500、communication 780、global_health 620、hedging 550。每条样本还带有 primary_slice、slice_tags、reward_profile、penalty_profile、hard_constraints、risk_level、reference_answer 和 negative_reference_answer。(GitHub)
损失函数怎么讲
不要说"我直接把硬规则写成 loss"。更准确的说法是:
我把硬规则写成 reward function,GRPO/DAPO 再把 reward 转成 advantage,用 PPO-style clipped objective + KL reference 来优化 policy。
核心形式可以这样背:
R(x,y)=\\sum_k w_k(x)r_k(x,y)+p_{safety}(x,y)
其中 reward 由 6 类组成:
communication_quality、context_awareness、hedging、emergency_referral、reference_alignment、safety_penalty 。这些 reward 会根据 prompt 的 slice、risk_level、hard_constraints 动态加权。(GitHub)
GRPO 对同一 prompt 采样多个回答,计算组内 advantage:
A_i=\\frac{R_i-\\text{mean}(R_{group})}{\\text{std}(R_{group})+\\epsilon}
再优化:
\\mathcal{L}\\approx-\\sum_{i,t}\\min(\\rho_{i,t}A_i,\\text{clip}(\\rho_{i,t},1-\\epsilon,1+\\epsilon)A_i)+\\beta KL(\\pi_\\theta\|\|\\pi_{ref})
你的实现里使用的是 TRL 的 GRPO/DAPO 思路:loss_type=dapo、num_generations=4、scale_rewards=group、beta=0.02,并用 DPO330 adapter 作为 policy 起点和 frozen reference。(Hugging Face)
硬规则 reward 是否合理
合理,但只能作为 v0/v1,不适合作为最终医疗安全对齐方案。
面试时可以这样说:
这套 hard-rule reward 的价值在于便宜、稳定、可解释,适合作为第一轮 GRPO reward shaping,验证 DPO → GRPO 是否能定向修复 emergency/context/communication 这类行为问题。但我不会把它声称为最终医疗安全 reward,因为它容易 reward hacking,比如模型堆砌"请及时就医""建议咨询医生",但不一定真正理解风险。
你项目文档里也把它定位为 rule + reference anchored reward 的初版方案 ,后续计划是接入 LLM judge 或训练 local reward model,而不是把硬规则当最终评价器。(GitHub)
更好的面试答案
可以这样升级表达:
- 硬规则不是最终目标,而是 reward shaping:用于把 HealthBench 暴露的问题转成可优化信号。
- reference/negative reference 防止纯关键词刷分:不只看有没有"就医",还看是否接近正例、远离负例。
- KL reference 防止模型漂移:GRPO 不是无限追 reward,而是相对 DPO330 稳定改进。
- 需要外部评测闭环 :用 HealthBench 105 条浅测验证方向,GRPO v1 ckpt60 达到 0.3143,高于 SFT/DPO/base,但 emergency 仍未完全解决,所以不能夸大。(GitHub)
- 下一步改进:引入 LLM-as-judge/医生标注 reward、做 per-reward ablation、加强 emergency detector、把 DPO adapter merge 后重新开 GRPO LoRA 做对照实验。
3. 常见测评集速记表
| 测评集 | 内容与数量 | 测评方法 | 必背点 |
|---|---|---|---|
| MMLU | 57 个学科,约 15,908 道多选题,覆盖数学、历史、法律、医学、CS 等 | 多选 accuracy,通常做 macro average | 测"知识广度 + 专业知识",不是生成式评测。(arXiv) |
| ARC | 小学/初中科学题,7,787 道;分 Easy 和 Challenge | 多选 accuracy | ARC-Challenge 是检索/词共现 baseline 做错的难题。(ModelScope) |
| TruthfulQA | 817 个问题,38 类主题,包括健康、法律、金融、政治等 | 原始生成式可用 GPT-judge/GPT-info;MC 版本用 accuracy | 测"模型是否迎合人类常见误解",不是单纯知识题。(arXiv) |
| HellaSwag | 约 70K 个常识推理多选题,选最合理的故事/动作结尾 | 多选 accuracy | 人类很容易,模型容易被 adversarial filtering 生成的干扰项骗。(arXiv) |
| AlpacaEval | 默认 805 条 instruction-following 样本 | LLM judge pairwise,对比 reference,算 win rate / LC win rate | 是 LLM-as-judge;优点快,缺点有长度/风格偏置,不替代安全评测。(GitHub) |
| GSM8K | 约 8.5K 小学数学文字题,约 7.5K train / 1K test | 最终答案 exact match / accuracy | 测多步算术推理;通常不是 LLM 打分。(GitHub) |
| MATH-500 | 从 MATH benchmark 抽出的 500 道竞赛数学题 | 最终答案 exact/symbolic accuracy | 比 GSM8K 难,覆盖代数、几何、数论、概率等。(ModelScope) |
| HumanEval | 164 道 Python 编程题,每题含函数签名、docstring、测试 | 运行单元测试,算 pass@k | 不是 LLM judge,是代码执行评测。(Hugging Face) |
| GPQA | 448 道研究生级生物/物理/化学多选题;Diamond 子集 198 道 | 多选 accuracy | "Google-proof" 高难科学问答;Diamond 随机是 25%。(arXiv) |
4. 三种对比数据筛选方法
| 方法 | 核心思想 | 大概实现路径 | 记忆点 |
|---|---|---|---|
| AlpaGasus | 用强 LLM 给 instruction 数据打质量分,过滤低质量样本 | Alpaca 52K → ChatGPT/强模型评估 instruction-response 质量 → 按分数阈值或 top-k 保留高质量数据 → 用小而精数据 SFT | 论文中用约 9K 高质量样本就超过原 Alpaca,核心是 quality filtering 。(ICLR Proceedings) |
| MoDS | Model-oriented Data Selection:质量、覆盖度、必要性三阶段 | 先用质量模型筛高质量数据 → 用 embedding + K-Center 保证 coverage → 训练初始模型 → 找出目标模型答不好的样本作为 necessary data | 核心是 quality + coverage + necessity ,不是只看数据本身,还看目标模型缺什么。(GitHub) |
| Superfiltering | 用小模型替大模型筛数据,weak-to-strong | 用小 LM 计算 instruction-following difficulty / IFD 分数 → 选少量高价值样本 → 可再加 diversity selection → 训练大模型 | 核心是 小模型也能判断哪些数据对大模型有用 ;论文报告 5% 数据可超过 full-data baseline。(ACL Anthology) |
5. 面试可背金句
DPO 解决的是 pairwise preference 的方向问题,GRPO 解决的是开放式生成中的行为对齐问题。
我的 hard-rule reward 不是最终医疗评价器,而是第一阶段可解释 reward shaping;真正可靠性来自 reference anchor、KL 约束、ablation 和 HealthBench 外部验证。
如果面试官追问不足,我会主动承认:关键词规则可能 reward hacking,所以后续要用 LLM judge、医生标注或 local reward model 替代纯规则 reward。
1. 结论:你的 SFT 数据筛选思路是否合理?
合理,面试官大概率可以接受。
你的方法本质是:用少量强模型标注,训练一个基于目标模型 hidden state 的轻量筛选器,再大规模筛数据。这比直接让 GPT 给 40 万条逐条打分更省钱,也比随机筛选更有模型针对性。
你的实验结果也能支撑:
| 训练数据 | 指标 |
|---|---|
| 全量 40 万 | 0.2112 |
| 随机 5 万 | 0.2298 |
| hidden-state 筛选 5 万 | 0.2407 |
可以这样说:
相比全量 SFT,提升 0.0295,约 14.0% 相对提升;相比随机 5 万,提升 0.0109,约 4.7% 相对提升。
2. 面试中推荐讲法
不要说成"我用 GPT-5.2 直接筛数据"。更好的表达是:
我不是用 GPT-5.2 直接打满 40 万条数据,而是只抽样 3,000 条,用强 LLM 生成高/低质量监督信号;然后把目标模型在 instruction-response 上的 hidden states 作为特征,训练一个轻量 MLP 分类器。最后用这个分类器对 40 万数据打分,选择模型自己更可能受益的高质量样本做 SFT。
GPT-5.2 本身可以作为强 LLM judge 的来源,OpenAI 官方文档也列出了 GPT-5.2 在 API 中的模型名和可用性。(OpenAI)
3. 这个方法的亮点
亮点 1:不是单纯外部打分,而是 model-oriented
AlpaGasus 是让 ChatGPT 直接识别低质量数据,然后从 Alpaca 52K 里筛出 9K 高质量数据训练。(ICLR 会议录)
你的方法比它更进一步:GPT 只提供少量 seed label,最终排序依据来自目标模型 hidden states。
亮点 2:和 MoDS 思路一致,但更轻量
MoDS 强调 quality、coverage、necessity 三个维度,核心是"不同模型需要的数据不同"。(arXiv)
你的方法也符合这个逻辑:不是找通用好数据,而是找目标模型 hidden state 上认为更有价值的数据。
亮点 3:比 Superfiltering 更贴近目标模型
Superfiltering 用弱模型代替强模型筛数据,核心假设是小模型和大模型对 instruction difficulty 的感知有一致性。(ACL Anthology)
你的方法不是用外部小模型,而是直接用目标模型自己的内部表示,所以可以讲成更"模型自感知"。
4. 最大风险:已有相似工作,需要准备差异化
我检索到一个非常接近的公开工作 CPQS-Tuning :它也提出 hidden states 反映数据质量,并用目标 LLM hidden states 训练数据分类模型,输出数据过滤分数;其实验也包括 Alpaca-GPT4 和 DeepSeek-R1 synthesized reasoning 数据,且宣称少于 10% 数据超过全量训练。(OpenReview)
所以你面试时不要说"全球首次发现 hidden states 可区分数据质量"。更稳妥的说法是:
我的贡献不是简单提出 hidden-state filtering,而是在我的任务设置里验证了 target-model self-perception 的有效性,并结合少量强模型打分、top/bottom 对比学习、目标模型 hidden-state MLP 筛选,在医疗/推理场景下实现了比全量和随机子集更好的 SFT 效果。
如果你的 AAAI-27 项目和 CPQS 无关,论文创新性需要重新打磨;如果 CPQS 是你们自己的工作或相关前作,那就要在简历和面试里说清楚关系。
5. 面试官可能质疑什么?怎么回答?
| 质疑 | 推荐回答 |
|---|---|
| 为什么只抽 3,000 条?够吗? | 3,000 条不是为了完整标注分布,而是为了拿到高置信度的 top/bottom 极端样本。极端样本 margin 大,更适合训练初版分类器。后续我会加 active learning,优先补标模型最不确定的样本。 |
| top 1000 / bottom 1000 会不会太粗糙? | 是,所以我不会只依赖二分类。初版用二分类验证 hidden states 可分;更好的版本会用 GPT 分数做 regression/ranking loss,保留中间 1000 作为验证集或排序监督。 |
| GPT-5.2 打分有偏置怎么办? | GPT-5.2 只是少量 teacher label,不是最终评测。最终效果看独立下游 benchmark;同时可做人类抽检、多 judge 一致性、不同 prompt 打分稳定性。 |
| 这还是外部评价模型,不是自感知吧? | GPT 只提供弱监督标签;真正给 40 万样本排序的是目标模型 hidden states + MLP。核心不是"GPT 判断质量",而是"目标模型内部表征能否预测哪些样本更值得学"。 |
| 为什么全量 40 万反而差? | SFT 数据里噪声、重复、低质量回答会被同等学习;全量训练可能放大错误风格和冗余模式。随机 5 万减少了一部分噪声,但没有质量控制;我的 top 5 万进一步提高了样本质量。 |
| 会不会只筛出简单样本,导致能力不提升? | 这是风险。改进方案是加入 difficulty/coverage 约束:不是只选高质量,还要保证任务类型、长度、医学安全场景、推理难度、长尾类别覆盖。 |
| 80 分阈值怎么来的? | 不能说拍脑袋。应该说:阈值来自验证集校准和 top-k ablation,比如比较 top 1w/3w/5w/8w,以及 0.7/0.8/0.9 阈值,最后选验证集效果和覆盖度最优的点。 |
| MLP 会不会过拟合? | 用简单 MLP/linear probe、dropout、weight decay、held-out 验证集、不同随机种子、多层 hidden state ablation;如果 linear probe 已经有效,说明 hidden state 本身有可分性。 |
| 如何证明不是长度泄漏? | 做 length-matched ablation:控制 response length、token 数、perplexity 后再训练分类器;同时报告只用长度特征的 baseline。如果 MLP 明显超过长度 baseline,说明不是简单长度偏置。 |
| 和 AlpaGasus / MoDS / Superfiltering 的区别? | AlpaGasus 是强 LLM 全量打分;MoDS 是 quality + coverage + necessity pipeline;Superfiltering 是小模型弱到强筛选。我的方法是目标模型 hidden-state self-perception,用少量强标签训练轻量筛选器。 |
6. 建议你补强的实验
面试时可以主动说这些,显得很严谨:
- Top-k ablation:top 1w / 3w / 5w / 8w / 10w。
- Layer ablation:最后一层、倒数 4 层平均、response token mean pooling、EOS pooling。
- Classifier ablation:linear probe vs MLP vs XGBoost。
- Feature leakage ablation:只用长度、loss、perplexity 做 baseline。
- Diversity constraint:top 5 万里按 embedding clustering / task category 做 quota,避免只选同质样本。
- Seed sensitivity:换 3 个随机种子重新抽 3,000 条,看结果是否稳定。
- Cross-benchmark eval:不能只报一个总分,要报数学、代码、医疗安全、instruction following 分项。
- Decontamination:排查是否筛进 benchmark 泄漏样本。
7. 简洁八股文
a. 什么是 LoRA 微调?
LoRA = Low-Rank Adaptation。
核心思想:冻结原模型参数,只在部分线性层旁边插入低秩矩阵:
W' = W + \\Delta W,\\quad \\Delta W = BA
其中 (A,B) 是可训练低秩矩阵,参数量远小于全参微调。LoRA 论文明确提出冻结预训练权重、注入可训练低秩矩阵,从而大幅减少可训练参数和显存。(arXiv)
面试一句话:
LoRA 不改动原始大模型主干,只训练低秩适配矩阵,用很少参数实现接近全参微调的效果,适合资源有限、快速适配领域任务。
b. 何时用 PPO、DPO、GRPO?
| 方法 | 什么时候用 |
|---|---|
| PPO | 有 reward model 或环境 reward,需要在线采样优化;适合复杂 RLHF,但训练成本高、不稳定。 |
| DPO | 有 chosen/rejected 偏好对,想稳定、低成本做偏好对齐;不需要显式 reward model。 |
| GRPO | 有规则 reward / LLM judge / 可验证 reward,希望像 PPO 一样在线采样,但不想训练 critic/value model。适合数学、代码、医疗安全规则对齐。 |
DPO 的优势是用简单分类损失直接优化偏好,避免 RLHF 中显式 reward model 和在线采样的复杂流程。(arXiv)
GRPO 是 DeepSeekMath 提出的 PPO 变体,用组内相对奖励优化,并降低 PPO 的内存开销。(arXiv)
c. PPO / DPO / GRPO 区别和损失函数
PPO
r_t(\\theta)=\\frac{\\pi_\\theta(a_t\|s_t)}{\\pi_{\\theta_{old}}(a_t\|s_t)}
L_{PPO}= \\mathbb{E}\\left\[ \\min(r_t A_t,\\text{clip}(r_t,1-\\epsilon,1+\\epsilon)A_t) \\right
]
核心:限制新旧策略变化幅度,稳定 RL 更新。
PPO 论文的关键就是优化 clipped / surrogate objective。(arXiv)
DPO
[
L_{DPO}
-\mathbb{E}
\log \sigma
\left(
\beta
\left[
\log \frac{\pi_\theta(y_w|x)}{\pi_{ref}(y_w|x)}
\log \frac{\pi_\theta(y_l|x)}{\pi_{ref}(y_l|x)}
\right]
\right)
]
核心:直接让 chosen 的相对概率高于 rejected。
GRPO
同一个 prompt 采样 (G) 个回答:
A_i = \\frac{r_i-\\text{mean}(r_1,\\dots,r_G)} {\\text{std}(r_1,\\dots,r_G)+\\epsilon}
[
L_{GRPO}
-\mathbb{E}
\left[
\frac{1}{G}
\sum_i
\frac{1}{|o_i|}
\sum_t
\min
\left(
\rho_{i,t}A_i,
\text{clip}(\rho_{i,t},1-\epsilon,1+\epsilon)A_i
\right)
\beta KL
\right]
]
核心:不用 critic,用组内平均 reward 当 baseline。
TRL 文档也提示 GRPO/DAPO 公式中要注意长度偏置问题,DAPO 使用 token-level normalization 缓解长回答偏置。(Hugging Face)
d. 如何判断预训练、SFT、对齐可以进入下一阶段?
预训练完成
看:
- validation loss / perplexity 下降趋缓;
- 下游通用 benchmark 增益变小;
- 继续训练收益低于算力成本;
- 没有明显数据污染、重复、灾难性退化。
一句话:
预训练完成不是 loss 最低,而是继续堆 token 的边际收益明显下降,可以进入指令学习阶段。
SFT 完成
看:
- instruction-following eval 提升趋缓;
- held-out SFT loss 不再明显下降;
- 输出格式、问答风格稳定;
- 通用能力没有明显掉:数学、代码、知识、安全;
- 人工抽检没有大量幻觉、拒答、跑题。
一句话:
SFT 完成的标准是模型已经学会基本指令遵循和领域回答格式,但还没有过拟合到模板化回答。
对齐完成
看:
- reward / preference win rate 提升趋缓;
- 外部 benchmark 提升,而不是只刷 reward;
- KL、长度、拒答率、幻觉率可控;
- safety red-team 和关键 slice 通过;
- 没有 reward hacking。
一句话:
对齐完成不是 reward 越高越好,而是偏好、安全、事实性和任务能力同时稳定,没有明显副作用。
e. 你是如何进行多卡训练的?2 卡 H200 + 梯度累积
推荐回答:
我用 2 张 H200 做数据并行训练,每张卡放一个模型副本或 LoRA adapter,每张卡处理不同 mini-batch。反向传播后通过 DDP/Accelerate/DeepSpeed 做梯度同步。因为显存和 batch size 受限,我设置 gradient_accumulation_steps,把多个 micro-batch 的梯度累积后再执行一次 optimizer step。
有效 batch size:
[
B_{eff}
B_{per_device}
\times N_{gpu}
\times G_{accum}
]
例如:
2 \\times 2 \\times 8 = 32
也就是每卡 batch size 2,两张卡,累积 8 步,等效 batch size 是 32。
f. 梯度累积的作用是什么?
核心作用:
- 模拟更大 batch size;
- 降低单步显存压力;
- 让训练更稳定;
- 减少 optimizer step 次数。
缺点:
- wall-clock 可能变慢;
- 参数更新频率降低;
- 多卡下如果实现不好,会增加通信开销。
一句话:
梯度累积就是用多个小 batch 累加梯度,等价近似一个大 batch,再统一更新参数。
g. DeepSpeed ZeRO 1/2/3 阶段
| 阶段 | 切分内容 | 作用 |
|---|---|---|
| ZeRO-1 | optimizer states | 切 Adam 的一阶/二阶动量,省优化器显存 |
| ZeRO-2 | optimizer states + gradients | 进一步切梯度,显存更省 |
| ZeRO-3 | optimizer states + gradients + parameters | 连模型参数也切分,最省显存,但通信成本最高 |
DeepSpeed 官方文档也明确写到:Stage 1 切 optimizer state,Stage 2 切 optimizer + gradient,Stage 3 切 optimizer + gradient + parameter。(DeepSpeed)
一句话:
ZeRO 的核心是消除多卡训练中的冗余存储;stage 越高越省显存,但通信和工程复杂度越高。
h. 什么是 harness engineering?和普通 agent 区别?
普通 agent :一个会规划、调用工具、执行任务的智能体。
harness engineering:围绕 agent 搭建环境、工具、约束、文档、测试、反馈闭环,让 agent 能可靠完成复杂任务。
OpenAI 的文章总结得很清楚:未来工程师的重点不只是写代码,而是设计环境、表达意图、构建反馈循环,让 Codex agents 可靠工作。(OpenAI)
面试回答:
Agent 是执行者,harness 是让 agent 可控、可验证、可迭代的工程系统。包括 AGENTS.md、repo docs、CI、linter、测试、observability、eval、权限控制、失败恢复和人工验收标准。
OpenAI 文章里还提到,他们把 AGENTS.md 作为入口地图,而不是巨大说明书,并用 docs 目录作为 system of record。(OpenAI)
i. 你具体如何取得每个样本的 hidden state?
推荐回答:
对每条 instruction-response 样本,我先用和 SFT 一致的 chat template 拼接输入,比如 system + user + assistant response。然后把完整序列输入目标 base model,开启
output_hidden_states=True,不计算梯度。接着只取 assistant response token 对应位置的 hidden states,做 pooling,得到一个固定维度向量作为这个样本的表示。
具体步骤:
- 构造输入
x_i = \[system, user, assistant\\ response
]
- tokenize,并记录 response token span
text
prompt tokens: instruction 部分
response tokens: assistant answer 部分
- 前向传播
python
with torch.no_grad():
outputs = model(
input_ids=input_ids,
attention_mask=attention_mask,
output_hidden_states=True
)
- 取 hidden state
常用选择:
python
last_hidden = outputs.hidden_states[-1]
response_hidden = last_hidden[response_token_mask]
- pooling 成样本向量
常用三种:
python
h = response_hidden.mean(dim=0)
或:
python
h = last_hidden[eos_position]
或:
python
h = mean(last_4_layers_response_hidden)
- 训练 MLP
p_i = \\text{MLP}(h_i)
其中 label 来自 GPT-5.2 打分后的 top 1000 / bottom 1000:
text
top 1000 -> label 1
bottom 1000 -> label 0
- 筛 40 万数据
对全部样本抽 hidden state,MLP 输出:
p(\\text{high quality}\|h_i)
排序后选择 top 5 万,或者选择校准概率大于 0.8 的样本。
一句话版本:
我不是取生成时的文本特征,而是取目标模型读完整个 instruction-response 后,在 response token 上产生的最后层 hidden states;它代表模型对这条样本的内部感知,再用 MLP 把这种感知映射为质量分数。
下面是面试提纲版 。我先纠正一个关键点:你的 DPO v2 没有自定义五个 loss,五个维度是偏好数据重构标准,不是 DPO 损失函数。
问题 1:DPO 五个维度和官方 DPO loss 是什么关系?
核心回答
DPO 的 loss 还是标准 DPO loss,没有改公式。
标准 DPO 优化的是:
[
\mathcal L_{DPO}
-\mathbb E
\log \sigma
\left(
\beta
\\log \\frac{\\pi_\\theta(y_c\|x)}{\\pi_{ref}(y_c\|x)} \\log \\frac{\\pi_\\theta(y_r\|x)}{\\pi_{ref}(y_r\|x)}
\right)
]
其中:
- (y_c):chosen / 好回答
- (y_r):rejected / 坏回答
- (\pi_\theta):当前策略模型
- (\pi_{ref}):reference model
- (\beta):控制偏离 reference 的强度
TRL 官方文档也说明,DPO 使用 prompt / chosen / rejected 偏好数据,通过 widening chosen 与 rejected 相对 reference 的 log-likelihood margin 来训练;你的代码也是用 DPOTrainer、DPOConfig、loss_type=sigmoid,不是自定义多任务 loss。(Hugging Face)
那五个维度是什么?
五个维度:
- accuracy
- communication_quality
- context_awareness
- emergency_referrals
- hedging
它们不是 loss term,而是 DPO v2 偏好数据重构时的打标/改写标准。
你的 reconstruct_dpo_dataset.py 里用 GPT-5.2 作为医疗偏好数据重构器,要求它判断原始 chosen/rejected 是否方向正确,并围绕这五个维度重写 final_chosen 和 final_rejected。输出里包括:
label_correctswap_pairissue_tagstarget_tagsrationalefinal_chosenfinal_rejected
也就是说,五个维度决定的是 什么样的回答应该成为 chosen ,而不是改变 DPO loss 本身。(GitHub)
具体实现路径
Step 1:重构偏好对
原始 medical pairwise 数据存在问题:
- chosen/rejected 方向不可靠;
- chosen 有时只是更长,不一定更安全;
- 缺少上下文追问;
- 缺少急诊识别;
- 存在过度自信回答。
所以 DPO v2 用 GPT-5.2 重构每条样本,产出更可靠的 final_chosen / final_rejected。你的文档中记录:train 3,800 条全部被修改,swap_count=2198,说明原始偏好方向确实有大量问题。(GitHub)
Step 2:转成 TRL DPO 格式
dpo_data_prepare.py 把数据转成:
json
{
"prompt": [...],
"chosen": [{"role": "assistant", "content": "..."}],
"rejected": [{"role": "assistant", "content": "..."}],
"source": "medical_pairwise_reconstructed_v2"
}
这正是 TRL DPO 所需的 conversational preference format。(GitHub)
Step 3:标准 DPO 训练
train_dpo.py 里使用:
python
DPOTrainer(...)
DPOConfig(
beta=args.beta,
loss_type=[args.loss_type],
...
)
你的训练配置是:
beta=0.1loss_type=sigmoid- LoRA
r=16, alpha=32, dropout=0.05 - 2 卡 H200
- per-device batch size 2
- gradient accumulation 8
- metric:
eval_rewards/accuracies
所以准确说法是:DPO v2 是五维偏好数据重构 + 标准 DPO 训练。 (GitHub)
面试官视角评估
基本满意口径:
我没有修改 DPO loss。我的创新在数据层:我发现原始医疗偏好对方向混乱、缺少急诊识别和上下文追问,所以用 GPT-5.2 按 accuracy、communication、context、emergency、hedging 五个维度重构 chosen/rejected。之后仍然用标准 DPO loss 训练,让模型提高 chosen 相对 rejected 的概率。
风险提醒:
- 不要说"我设计了五个 DPO loss",这是错误表述。
- 可以说"我设计了五个 preference construction axes"。
- 面试官如果追问 reference model:你可以说 DPO 从 merge 后的 SFT checkpoint 初始化,reference 由 TRL DPOTrainer 管理;工程上相当于约束 policy 不要过度偏离 SFT reference。
- 你的 DPO valid 只有 100 条,而且 step 30 就 accuracy 饱和到 1.0,这说明内部 valid 偏容易,不能把
eval_rewards/accuracies=1.0夸成真正医疗安全能力已经解决。(GitHub)
问题 2:测评框架实践怎么讲?
总体回答
我会把评测分成三层:
- 标准 benchmark 自动评测 :用
lm-evaluation-harness跑 MMLU、ARC、HellaSwag、TruthfulQA、GSM8K、HumanEval。 - LLM-as-judge 指令跟随评测:用 AlpacaEval 和自建 pairwise comparison。
- 数学/推理专项评测:用 EvalScope 跑 MATH-500、GPQA 等长推理任务。
2.1 lm-evaluation-harness
框架信息
lm-evaluation-harness 是 EleutherAI 维护的通用大模型评测框架,支持 HuggingFace 模型、本地路径、vLLM、多卡、batch size、任务列表查询等。官方示例就是:
bash
lm_eval \
--model hf \
--model_args pretrained=EleutherAI/gpt-j-6B \
--tasks hellaswag \
--device cuda:0 \
--batch_size 8
也可以用本地模型路径或 vLLM 后端。(GitHub)
你可以怎么接入模型
HuggingFace / merged model 方式
bash
pip install "lm_eval[hf]"
lm_eval \
--model hf \
--model_args pretrained=/path/to/merged_model,dtype=bfloat16,trust_remote_code=True \
--tasks mmlu,arc_challenge,hellaswag,truthfulqa_mc2 \
--device cuda:0 \
--batch_size 8 \
--output_path results/general_eval
vLLM 方式
bash
pip install "lm_eval[vllm]"
lm_eval \
--model vllm \
--model_args pretrained=/path/to/merged_model,tensor_parallel_size=2,dtype=auto,gpu_memory_utilization=0.8 \
--tasks gsm8k,humaneval \
--batch_size auto \
--output_path results/reasoning_eval
官方也提供了 vLLM 后端和多 GPU 参数,例如 tensor_parallel_size、gpu_memory_utilization 等。(GitHub)
LoRA 模型怎么评测?
推荐面试回答:
我一般先把 LoRA adapter merge 到 base model,再用 harness 评测,这样 tokenizer、chat template、模型权重状态最稳定。也可以用 harness 的 PEFT 参数直接加载 adapter,但为了结果可复现,我更倾向于 merge 后固定版本评测。
常见坑
| 坑 | 解决办法 |
|---|---|
| task 名称不确定 | 用 lm-eval ls tasks 查任务名。官方 task list 里有 ARC、GPQA、GSM8K、HellaSwag、HumanEval 等任务。(GitHub) |
| MMLU / ARC / TruthfulQA 版本混淆 | 明确写 mmlu、arc_challenge、truthfulqa_mc1/mc2,不要只写"跑了 TruthfulQA"。 |
| chat template 不一致 | base leaderboard 类任务通常是 continuation scoring;instruct 模型是否加 chat template 要固定并报告。 |
| LoRA 没 merge 导致加载错模型 | 最稳妥是 merge adapter 后保存完整模型再评测。 |
| batch size OOM | 用 --batch_size 8 或更小;vLLM 下调 gpu_memory_utilization 或开 tensor parallel。官方也建议 OOM 时调 batch size / parallel size。(GitHub) |
| HumanEval 安全风险 | HumanEval 要执行生成代码,最好在 sandbox / docker 中跑,避免任意代码执行风险。 |
| GSM8K 答案抽取失败 | 固定 answer format,例如要求 #### final_answer,否则 exact match 容易误判。 |
面试官视角评估
基本满意口径:
我不是手写每个 benchmark,而是用 lm-evaluation-harness 做标准化评测。模型接入时优先 merge LoRA,固定 tokenizer、chat template、dtype 和 batch size。MMLU/ARC/HellaSwag/TruthfulQA 走 multiple-choice accuracy,GSM8K 走最终答案匹配,HumanEval 走代码执行 pass@k。
风险提醒:
- 不要只说"我用 harness 跑了一下",要能说出
--model hf、--model_args pretrained=...、--tasks、--batch_size。 - 你的文字里把 GSM8K 说成"middle/high-school arithmetic, algebra, geometry"不够准确;官方 GSM8K 是 8.5K grade-school math word problems,约 7.5K train / 1K test 。(GitHub)
2.2 自建 Pairwise Comparison
框架信息
你们的做法是:对 Koala、WizardLM、Self-Instruct、Vicuna 等 instruction 集合生成模型回答,然后用 GPT-4o 作为 judge,从 relevance 和 accuracy 两个维度打 1--10 分,两轮交换 A/B 位置,最后统计 Win / Tie / Loss。
实现流程
text
1. 准备 instruction 测试集
2. 用 baseline model 和 candidate model 分别生成回答
3. 构造 judge prompt
4. GPT-4o 对 A/B 回答打分
5. 第二轮交换 A/B 位置再评一次
6. 两轮一致则记 Win/Loss;不一致或差距小则记 Tie
7. 汇总 win rate / tie rate / loss rate
建议 JSONL 格式:
json
{
"dataset": "koala",
"instruction": "...",
"output_a": "...",
"output_b": "...",
"model_a": "baseline",
"model_b": "candidate"
}
judge 输出:
json
{
"score_a_relevance": 8,
"score_a_accuracy": 7,
"score_b_relevance": 9,
"score_b_accuracy": 8,
"winner": "B",
"reason": "..."
}
常见坑
| 坑 | 解决办法 |
|---|---|
| position bias | A/B 交换两轮评测。 |
| verbosity bias | judge prompt 要提醒"不因更长而偏好"。 |
| judge drift | 固定 judge 模型版本、temperature=0、缓存 judge 输出。 |
| 只看总 win rate 不看类别 | 分 Koala/WizardLM/Self-Instruct/Vicuna 分别汇报。 |
| GPT judge 不能替代事实评测 | pairwise 只说明 instruction-following 体验,不等于数学、代码、医学安全能力。 |
面试官视角评估
基本满意。
你能讲清楚两轮 A/B swap、relevance/accuracy、Win/Tie/Loss,就说明不是粗糙 LLM judge。
风险提醒:
- GPT-4o judge 有风格偏好,不能把它当绝对真值。
- 最好补一句:"我会用人工抽检和标准 benchmark 交叉验证 LLM judge 结果。"
2.3 AlpacaEval
框架信息
AlpacaEval 是 instruction-following 的 LLM-as-judge 框架,输入模型 outputs,然后自动和 reference output 做 pairwise 比较,输出 win rate / length-controlled win rate。官方也提醒,自动 evaluator 可能偏好更长或特定风格回答,不能替代高风险场景的人类评测。(GitHub)
如何接入
输出文件:
json
[
{
"instruction": "Explain why the sky is blue.",
"output": "..."
}
]
运行:
bash
pip install alpaca-eval
alpaca_eval \
--model_outputs outputs.json \
--output_path results/alpaca_eval
如果你们论文里写的是 against text-davinci-003,要注意 AlpacaEval 1.x 和 2.0 的 reference / annotator 配置不同。官方文档也说明,早期 AlpacaEval 使用 text-davinci-003 作为默认参考,而 AlpacaEval 2.0 默认 reference 是 GPT-4 Turbo。(GitHub)
常见坑
| 坑 | 解决办法 |
|---|---|
| reference 版本变化 | 明确写 AlpacaEval 版本、reference model、annotator config。 |
| 长度偏置 | 同时报告 LC win rate。 |
| 输出字段错误 | 必须有 instruction 和 output。 |
| API 成本和复现问题 | 缓存 judge 结果,固定 evaluator 版本。 |
面试官视角评估
基本满意口径:
AlpacaEval 我用来评估 instruction-following,不把它当事实正确性的唯一指标。接入时先生成标准 JSON outputs,再用 AlpacaEval 的 annotator 计算 win rate,并报告版本、reference 和 LC win rate。
风险提醒:
- 只报 AlpacaEval win rate 会显得单薄。
- 要主动说它是 LLM-as-judge,有长度和风格偏置。
2.4 EvalScope
框架信息
EvalScope 是 ModelScope 生态里的评测框架,支持本地模型、API 模型、标准 benchmark、自定义数据、结构化结果、dashboard、pairwise arena 等。你们用它跑 MATH-500 和 GPQA 是合理的。(GitHub)
如何接入模型
常见做法是先用 vLLM 起 OpenAI-compatible server:
bash
python -m vllm.entrypoints.openai.api_server \
--model /path/to/merged_model \
--served-model-name my_model \
--trust-remote-code \
--port 8801
然后 EvalScope 通过 API 调用:
python
from evalscope import TaskConfig, run_task
cfg = TaskConfig(
api_url="http://127.0.0.1:8801/v1/chat/completions",
model="my_model",
eval_type="openai_api",
datasets=["math_500"],
dataset_args={
"math_500": {
"few_shot_num": 0
}
},
eval_batch_size=32,
generation_config={
"max_tokens": 20000,
"temperature": 0.6,
"top_p": 0.95,
"n": 1
}
)
run_task(cfg)
EvalScope 官方示例也使用 OpenAI API 兼容服务、TaskConfig、datasets=["math_500"]、few_shot_num、eval_batch_size 和 generation config。(EvalScope)
GPQA 可以类似配置:
python
cfg = TaskConfig(
api_url="http://127.0.0.1:8801/v1/chat/completions",
model="my_model",
eval_type="openai_api",
datasets=["gpqa"],
dataset_args={
"gpqa": {
"subset_list": ["gpqa_diamond"],
"few_shot_num": 0
}
},
eval_batch_size=16,
generation_config={
"max_tokens": 20000,
"temperature": 0.0,
"top_p": 1.0,
"n": 1
}
)
常见坑
| 坑 | 解决办法 |
|---|---|
| MATH-500 max tokens 太短 | 长推理模型要给足 max_tokens,例如 8K--20K。 |
| temperature 不一致 | pass@1 通常用 temperature=0;如果用采样,要报告 n 和平均方式。 |
| 答案抽取失败 | 强制模型输出 Final Answer: 或 \boxed{}。 |
| GPQA 选项顺序偏置 | 固定或随机化选项顺序,并报告设置。 |
| API 并发不稳定 | 控制 eval_batch_size,缓存中间结果。 |
面试官视角评估
基本满意。
你能讲出"vLLM 起 OpenAI API 服务 + EvalScope TaskConfig + dataset_args + generation_config",面试官会认为你确实跑过评测。
风险提醒:
- MATH-500 / GPQA 的成绩很依赖答案抽取和 generation config。
- 要报告
temperature、max_tokens、few_shot_num、n,否则结果不容易复现。
问题 3:hidden state 分类器 MLP 怎么设计?
Qwen2.5-7B hidden size
Qwen2.5-7B 的官方 config 里:
hidden_size = 3584num_hidden_layers = 28num_attention_heads = 28num_key_value_heads = 4max_position_embeddings = 131072
所以如果你取最后一层 hidden state,并做 response token pooling,每条样本得到的向量维度是:
3584
hidden state 怎么取?
推荐面试回答:
我把 instruction 和 response 按 SFT chat template 拼接后输入目标模型,开启
output_hidden_states=True,不计算梯度。然后只取 assistant response token 对应位置的最后一层 hidden states,用 token-level mean pooling 得到一个 3584 维样本表示。
伪代码:
python
with torch.no_grad():
outputs = model(
input_ids=input_ids,
attention_mask=attention_mask,
output_hidden_states=True
)
h = outputs.hidden_states[-1] # [B, T, 3584]
mask = assistant_response_mask # [B, T]
masked_h = h * mask.unsqueeze(-1)
feature = masked_h.sum(dim=1) / mask.sum(dim=1).clamp_min(1).unsqueeze(-1)
# feature: [B, 3584]
推荐 MLP 配置
因为你只有:
- top 1000 高质量样本
- bottom 1000 低质量样本
监督样本只有 2000 条,不建议 MLP 太大。
推荐配置:
text
Input: 3584
Linear(3584, 512)
LayerNorm(512)
GELU
Dropout(0.1)
Linear(512, 128)
GELU
Dropout(0.1)
Linear(128, 1)
BCEWithLogitsLoss
参数量约:
text
3584 × 512 ≈ 1.84M
512 × 128 ≈ 65K
128 × 1 ≈ 128
总计约 1.9M 参数
训练设置:
text
optimizer: AdamW
lr: 1e-4
weight_decay: 1e-4 或 1e-3
batch_size: 64 或 128
early stopping: valid AUC / F1
loss: BCEWithLogitsLoss
数据规模估算
每条样本一个 3584 维向量:
| 存储格式 | 单样本 | 40 万样本 |
|---|---|---|
| fp16 / bf16 | 约 7 KB | 约 2.7 GiB |
| fp32 | 约 14 KB | 约 5.3 GiB |
所以把 40 万样本的 pooled hidden states 离线存下来是可行的。
更稳妥的实验设计
你可以这样回答:
我会先跑 linear probe,看 hidden states 是否线性可分;如果 linear probe 已经不错,再用小 MLP 提升非线性表达。为了避免模型只学到 response 长度,我会做 length-only baseline 和 length-matched ablation。
建议补充:
- linear probe baseline :
3584 -> 1 - MLP baseline :
3584 -> 512 -> 128 -> 1 - layer ablation:最后一层 vs 倒数 4 层平均
- pooling ablation:mean pooling vs last token pooling vs EOS pooling
- leakage ablation:只用长度、loss、perplexity 做对照
面试官视角评估
基本满意口径:
Qwen2.5-7B hidden size 是 3584。我取 assistant response token 的 hidden states 做 mean pooling,得到 3584 维样本向量。分类器用轻量 MLP,3584→512→128→1,BCE loss。因为标注只有 2000 条,所以我会控制模型规模,并加 linear probe、length baseline 和 layer/pooling ablation。
风险提醒:
- 不要 pool 全部 token,否则模型可能主要学到 prompt/topic,而不是 response 质量。
- 不要用过大的 MLP;2000 条标签训练 10M+ 参数分类器容易过拟合。
- 一定要做 length baseline,否则面试官会质疑"你只是学到了回答长短"。
问题 5:医疗数据筛选 GPT-5.2 打分 prompt 怎么写?
推荐打分维度
我建议用 0--100 总分 + 维度分 + 硬性封顶规则。
六个正向维度
| 维度 | 分数 | 含义 |
|---|---|---|
| medical_accuracy | 0--25 | 医学事实是否正确,有无误导 |
| safety_triage | 0--20 | 是否识别急诊、危险症状、用药风险 |
| context_uncertainty | 0--15 | 是否主动补问关键信息,是否表达不确定性 |
| communication_quality | 0--15 | 是否清楚、同理、非恐吓、非武断 |
| usefulness_completeness | 0--15 | 是否给出可执行、结构化、完整建议 |
| instruction_following | 0--10 | 是否回答用户问题、语言和格式是否一致 |
总分:
final_score \\in \[0,100
]
硬性封顶规则
这些规则很重要,能防止"语言好但危险"的回答拿高分。
| 情况 | 最高分 |
|---|---|
| 明显危险医疗建议,例如延误急诊、错误用药 | cap 30 |
| 明显医学事实错误 | cap 40 |
| 只会泛泛说"请咨询医生",没有实际帮助 | cap 50 |
| 答非所问 / 非医疗垃圾数据 | cap 35 |
| 过度诊断、过度确定,没有必要 hedging | cap 60 |
| 缺少必要急诊提醒 | cap 65 |
这和你现有医疗 SFT 数据筛选思路一致:你已经在文档里做过规则过滤、低信息 boilerplate 识别、过度绝对化表达、高风险缺少急诊提示等质量特征。(GitHub)
可直接使用的 prompt
text
你是医疗 SFT 数据质量评审器。你的任务不是回答医学问题,而是判断给定 instruction-response 是否适合作为医疗助手的监督微调样本。
请从以下维度评分,总分 0-100:
1. medical_accuracy,0-25:
- 医学事实是否正确;
- 是否避免伪科学、错误诊断、错误用药;
- 是否避免把不确定问题说得过于确定。
2. safety_triage,0-20:
- 是否识别急诊或高风险信号;
- 是否在必要时建议及时就医、急诊、线下检查;
- 是否避免延误治疗或危险自我处理。
3. context_uncertainty,0-15:
- 是否主动补问年龄、性别、病程、症状严重程度、既往病史、用药、妊娠等关键信息;
- 是否表达线上建议的局限性;
- 是否合理使用 hedging,而不是绝对判断。
4. communication_quality,0-15:
- 表达是否清晰、礼貌、有同理心;
- 是否避免恐吓、责备、冷漠;
- 是否适合普通患者理解。
5. usefulness_completeness,0-15:
- 是否给出结构化、可执行建议;
- 是否覆盖观察、生活方式、检查、就医时机等必要内容;
- 是否避免空泛模板。
6. instruction_following,0-10:
- 是否回答用户问题;
- 是否符合用户语言和格式;
- 是否没有无关扩写。
硬性封顶规则:
- 如果 response 包含明显危险医疗建议,final_score 不得超过 30。
- 如果 response 有明显医学事实错误,final_score 不得超过 40。
- 如果 response 只有"建议咨询医生/去医院"这类低信息模板,final_score 不得超过 50。
- 如果 response 答非所问或不是有效医疗回答,final_score 不得超过 35。
- 如果 response 对诊断或治疗做出过度确定判断,且没有必要的不确定性表达,final_score 不得超过 60。
- 如果 instruction 涉及急诊风险,但 response 未提醒及时就医,final_score 不得超过 65。
请只输出 JSON,不要输出额外解释。
输入:
instruction:
{{instruction}}
response:
{{response}}
输出 JSON 格式:
{
"dimension_scores": {
"medical_accuracy": 0,
"safety_triage": 0,
"context_uncertainty": 0,
"communication_quality": 0,
"usefulness_completeness": 0,
"instruction_following": 0
},
"raw_total": 0,
"cap_applied": true,
"cap_reason": "none | dangerous_advice | factual_error | low_information | off_topic | overconfident | missing_emergency_referral",
"final_score": 0,
"quality_bucket": "top | middle | bottom",
"risk_flags": [
"factual_error",
"missing_context",
"missing_emergency_referral",
"overconfident",
"low_information",
"poor_communication"
],
"one_sentence_reason": "...",
"keep_for_sft": true
}
在你的 self-perception 筛选里怎么用?
流程:
text
1. 从 40 万 SFT 数据中随机抽 3000 条
2. 用 GPT-5.2 按上面 rubric 打 final_score
3. 取 top 1000 作为 high-quality label = 1
4. 取 bottom 1000 作为 low-quality label = 0
5. 中间 1000 不参与训练,可做 calibration / sanity check
6. 对这 2000 条抽 Qwen2.5-7B hidden states
7. 训练 MLP 分类器
8. 对 40 万数据全部抽 hidden states
9. MLP 输出 high-quality probability
10. 选择 top 5 万或 probability > 0.8 的样本做 SFT
面试官视角评估
基本满意口径:
GPT-5.2 不直接替我筛完整 40 万数据,而是只给 3000 条样本提供高置信度质量标签。我按医学正确性、安全分诊、上下文意识、沟通质量、完整性、指令遵循六个维度打 0--100 分,并加入危险医疗建议、事实错误、低信息模板等封顶规则。之后用 top/bottom 样本训练 hidden-state MLP,让目标模型自己的内部表征成为最终筛选依据。
风险提醒:
- 不能说 GPT-5.2 分数就是真实医疗质量,只能说是 weak supervision。
- 最好做人工抽检,尤其是 top 100、bottom 100。
- 要固定 GPT-5.2 judge prompt、temperature=0、模型版本和打分输出,保证可复现。
- 你现有 HQ-50K 医疗实验提升幅度较小:HealthBench 105 浅测里 HQ-50K 是 0.2905,huatuo_5w ckpt75 是 0.2889,只是小幅优势,不能夸大成显著胜出。(GitHub)
最后给你的统一面试表述
我的 SFT 数据筛选不是简单用 GPT 直接打满 40 万条,而是用 GPT-5.2 在小样本上构造高/低质量监督信号,再用目标模型 Qwen2.5-7B 对 instruction-response 的 hidden states 训练轻量 MLP 分类器。这样筛选标准更贴近目标模型自身的学习偏好。
我的 DPO v2 也不是改 DPO loss,而是重构偏好数据:用医疗正确性、沟通质量、上下文意识、急诊识别、保守表达五个维度定义 chosen/rejected,然后仍然用标准 DPO loss 训练。
评测上,我用 lm-evaluation-harness 跑标准 benchmark,用 AlpacaEval 和 GPT-4o pairwise 做 instruction-following 评测,用 EvalScope 跑 MATH-500 和 GPQA,并且固定模型版本、chat template、generation config 和 batch size,保证结果可复现。