先把一个误区说破:“DeepSeek Harness”不是一个官方独立发布、有专属文档的评测框架。你看到的那些教程,绝大多数就是拿 lm-evaluation-harness 套了个壳,或者把官方 eval 脚本重新整理了一遍。官方榜单上的分数基本是内部 harness 跑出来的,那套东西没完整开源,所以你拿公开工具去复现,天生就会差一点,这很正常。
既然你 vLLM 已经起好了,思路就很清晰了——别去装什么“DeepSeek Harness”,直接用 lm-eval 走 OpenAI 兼容接口。
起服务的时候记得带上 --served-model-name,不然 lm-eval 里的 model 字段容易对不上。然后装 lm-eval,注意版本,v0.4.x 前后接口差别挺大的,别人的命令直接抄可能报参数不存在。
核心跑法大致是这样:
lm_eval --model local-chat-completions \
--model_args model=你的模型名,base_url= \
--tasks xxx \
--num_fewshot 0 \
--batch_size 1 \
--apply_chat_template \
--log_samples
--log_samples 这个一定要加,出问题全靠它。
然后是对不上分数最常见的几个原因,按踩坑概率排:
第一,prompt 模板对不上。 用 chat 模式还是 completion 模式,结果能差好几个点。官方如果用的是自家 chat template,你 vLLM 加载的 tokenizer 里的 template 版本不一样,分数立刻就飘。模型 revision 和 tokenizer 版本都建议 pin 死,别用 latest。
第二,few-shot 数量。 MMLU 类的一般 5-shot,math 类往往 0-shot 或者 few-shot CoT,你 shot 数错了基本白跑。
第三,数据集 revision。 HF 上好几个 benchmark 被人改过,你拉到的和官方跑的那版根本不是一份数据。用 --dataset_path 指向本地固定副本,或者在 dataset_args 里 pin revision,这一步能救你一半的命。
第四,采样和抽取规则。 数学题答案怎么从输出里抠出来、代码题要不要真跑沙箱、pass@1 还是 pass@k 多次采样取平均——这些都是“隐性配置”,官方文章里经常一笔带过。AIME、GPQA 这类官方多半是 n 次采样取均值,你单跑一次对不上太正常了,波动三五个点都不稀奇。
第五,截断。 vLLM 的 --max-model-len 给小了,长文任务直接被砍,分数往下掉。还有 max_gen_toks 设太小,推理题答案没写完就被截。
至于目录结构,lm-eval 现在基本能直接从 HF 拉数据,不一定非要摆成特定文件夹。真要用官方脚本那种,一般就是 datasets/ 下面按 task 名分目录放 jsonl,再写个 task yaml 描述字段映射,但这条路维护成本高,我建议能用 HF 加载就用 HF 加载。
实际排查的正确姿势只有一个:--log_samples 存下逐条输出,挑几条和官方示例(如果有)对比。看是模型答错了、还是抽取出错了、还是 prompt 本身就不一样。肉眼比十条,比你调三天参数管用。
最后说句实话,复现官方分数能对上 95% 以上就已经算配置完全一致了,差 1~2 个点别较劲,差 5 个点以上再回头查上面这几条。