DFlash Eval 对齐分析:你的脚本 vs 官方 benchmark.py
修改总览
| # | 问题 | 影响 | baseline | lora_inject |
|---|---|---|---|---|
| 1 | Acceptance Length 计算方式 | 🔴 数值不同 | ✅ 修 | ✅ 修 |
| 2 | Multi-turn 对话支持 | 🔴 mt-bench 结果不同 | ✅ 修 | ✅ 修 |
| 3 | 样本选择:顺序 vs shuffle | 🔴 子集不同 | ✅ 修 | ✅ 修 |
| 4 | 数据集只有3个,官方10个 | 🔴 覆盖不全 | ✅ 修 | ✅ 修 |
| 5 | stop_token_ids 检查范围 | 🟡 可能提前/延迟停止 | ✅ 修 | ✅ 修 |
| 6 | 分布式聚合方式 | 🟡 丢失per-sample粒度 | ✅ 修 | ✅ 修 |
| 7 | AR baseline 含 draft forward | 🔴 speedup偏高(仅inject) | N/A | ✅ 修 |
| 8 | max_new_tokens 默认值 | 🟡 | ✅ 修 | ✅ 修 |
修改详情
1. Acceptance Length 计算方式
问题: 官方是 per-sample mean 再取 mean,你的是全局池化。
# ❌ 你的(两个脚本都是)
avg_accept_length = total_accept_sum / total_count
# ✅ 官方
tau = np.mean([np.mean(r[block_size].acceptance_lengths) for r in responses])
修改: 收集每个 sample 的 accept_lengths list,先算 per-sample mean,再取 mean。
2. Multi-turn 对话支持
问题: 官方对 mt-bench 等多轮数据集,会逐轮生成并将 assistant 回复加入 context。
# ❌ 你的:只取 turns[0],单轮
messages = [{"role": "user", "content": prompt}]
# ✅ 官方:逐轮生成
for turn_index, user_content in enumerate(instance["turns"]):
messages.append({"role": "user", "content": user_content})
# generate ...
messages.append({"role": "assistant", "content": output_text})
responses.append(response)
修改: 数据加载改为返回 {"turns": [...]} 格式,生成循环改为逐轮。
3. 样本选择
问题: 官方 shuffle 后选取,你的是顺序取前N。
# ❌ 你的
prompts = prompts[:num_samples]
# ✅ 官方
dataset = dataset.shuffle(seed=0).select(range(max_samples))
修改: 改用 HF dataset 的 shuffle + select。
4. 数据集补齐
问题: 缺少 math500, aime24, aime25, mbpp, livecodebench, swe-bench, alpaca 共 7 个。
修改: 直接复用官方 load_and_process_dataset() 函数。
5. stop_token_ids 检查范围
# ❌ 你的 baseline(检查到 start)
output_ids[:, num_input_tokens:start]
# ✅ 官方(检查所有已生成)
output_ids[:, num_input_tokens:]
修改: 改为 output_ids[:, num_input_tokens:]。
6. 分布式聚合
问题: 你用 all_reduce 聚合标量,丢失 per-sample 粒度。
# ❌ 你的:all_reduce sum/count
dist.all_reduce(local_sum, op=dist.ReduceOp.SUM)
# ✅ 官方:gather 完整 response list
responses = dist.gather(responses, dst=0)
修改: 改为 gather per-sample 的 acceptance_lengths + time metrics 到 rank 0 统一计算。
7. AR baseline 含 draft forward (仅 lora_inject)
问题: block_size=1 时仍跑完整的 inject pipeline(包含 draft model),导致 AR 时间偏大、speedup 偏高。
# ❌ 你的 lora_inject AR baseline
spec_generate_inject(..., block_size=1) # 仍会过 draft model layers
# ✅ 应该:纯 target autoregressive
ar_generate(target_model, input_ids, ...) # 只用 target
修改: 新增纯 AR 生成函数,block_size=1 时不经过 draft。
8. max_new_tokens 默认值
# 官方 shell 脚本用 2048(Python 默认 16384)
# 你的默认 2048,和 shell 一致,保持不变
# 但增加提示,显式说明