1. 背景

在昇腾环境中,我使用 AISBench 通过 OpenAI-compatible vLLM API,对 Qwen3.6-35B-A3B 模型进行能力评测。

在完成 BoolQ 和 GSM8K 后,mentor 希望进一步评价模型在中文金融、经济和法律专业知识方面的表现,因此从 CEval 中选择了六个相关子任务:

ceval_all_sets = [
    'college_economics',
    'business_administration',
    'accountant',
    'tax_accountant',
    'law',
    'legal_professional',
]

六科验证集共计 233 道单项选择题,评价指标为 Accuracy。


2. 实验环境

操作系统:Linux
Python:3.10
环境名称:py310
评测框架:AISBench Benchmark
模型服务:vLLM OpenAI-compatible API
服务地址:http://127.0.0.1:8006/v1/chat/completions
模型:qwen3.6-35b-a3b
任务类型:0-shot 单项选择题

3. CEval 数据集配置

自定义数据集配置文件:

ais_bench/benchmark/configs/datasets/ceval/
ceval_finance_compliance_strict.py

核心 prompt:

prompt=(
    f'以下是中国关于{_ch_name}考试的单项选择题,请选出正确答案。\n'
    f'你必须只输出一行,格式为:answer:A、answer:B、answer:C 或 answer:D。\n'
    f'不要解释,不要输出思考过程,不要输出其他任何内容。\n\n'
    f'{{question}}\n'
    f'A. {{A}}\n'
    f'B. {{B}}\n'
    f'C. {{C}}\n'
    f'D. {{D}}\n'
    f'答案:'
)

答案后处理:

ceval_eval_cfg = dict(
    evaluator=dict(type=AccEvaluator),
    pred_postprocessor=dict(
        type=last_option_postprocess,
        options='ABCD'
    )
)

4. 问题一:六个 CEval 任务全部 code 1

第一次运行:

ais_bench \
  --models vllm_api_general_chat \
  --datasets ceval_finance_compliance_gen_0_shot_noncot_chat_prompt \
  --summarizer example

AISBench 能识别六个任务,但六个 infer 任务全部失败:

OpenICLInfer[...] failed with code 1

summary 中所有结果均为:

-

日志中显示六个子任务在推理阶段和评估阶段均失败。

根因

进一步打开子任务 .out 日志,定位到:

CEvalDataset is not in the ais_bench::load_dataset registry

虽然类文件存在:

ais_bench/benchmark/datasets/ceval.py

但模块初始化时未导入该类,因此注册装饰器没有被执行。

解决方法

修改:

ais_bench/benchmark/datasets/__init__.py

加入:

from .ceval import CEvalDataset

随后验证:

python - <<'PY'
from ais_bench.benchmark.datasets import CEvalDataset
print("CEvalDataset import ok")
PY

输出:

CEvalDataset import ok

至此解决数据集注册失败问题。


5. 问题二:任务能跑完,但 Accuracy 只有 0%~3.64%

修复注册问题后,AISBench 能正常生成 summary,但结果严重异常:

college_economics        3.64
business_administration  3.03
accountant               0.00
tax_accountant           0.00
law                      0.00
legal_professional       0.00

对于四选一任务,随机猜测通常也会接近 25%,因此 0%~3% 显然不是正常模型能力结果。

检查 prediction 文件

读取 prediction JSON 后发现:

ceval-college_economics:55 条中 53 条为空
ceval-business_administration:33 条中 32 条为空
ceval-accountant:49 条中 49 条为空
ceval-tax_accountant:49 条中 49 条为空
ceval-law:24 条中 24 条为空
ceval-legal_professional:23 条中 23 条为空

典型样本:

gold: B
prediction: ''

因此初始低分实际是大量空预测造成的,而不是模型专业知识只有 0 分。


6. 问题三:Received 满了、Failed 为 0,为什么 prediction 仍为空

AISBench 日志可能显示:

Post: 49
Received: 49
Failed: 0

但同时又出现:

Request ... has no output

这里容易产生误解。

Received=49 只能说明 HTTP 层收到了 49 个响应,并不代表每个响应中都存在有效的最终答案。

检查原始 API 响应后发现:

{
  "message": {
    "content": null,
    "reasoning": "模型的思考过程"
  },
  "finish_reason": "length"
}

AISBench 当前主要读取:

message["content"]

由于 content=null,最终 prediction 被记录为:

''

完整问题链路为:

CEval 题目发送到模型
        ↓
模型进入 reasoning/thinking
        ↓
reasoning 消耗全部 max_tokens
        ↓
finish_reason=length
        ↓
最终 content 尚未生成
        ↓
AISBench 无法取得答案
        ↓
prediction=''
        ↓
Accuracy 接近 0

该问题及 content=nullreasoning 非空、finish_reason=length 的对应关系在原始记录中已有明确体现。


7. 为什么 prompt 中的 /no_think 没有解决

最初 prompt 中已经写入:

不要解释,不要输出思考过程。/no_think

但模型仍然返回 reasoning。

这说明 /no_think 只是文本提示,不一定被当前模型服务使用的 chat template 稳定识别。

因此:

在 prompt 中要求模型不要思考

和:

从模型请求参数层关闭 thinking

不是同一件事。

真正有效的控制参数是:

"chat_template_kwargs": {
  "enable_thinking": false
}

8. 先用 curl 做最小验证

测试请求:

curl http://127.0.0.1:8006/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.6-35b-a3b",
    "messages": [
      {
        "role": "user",
        "content": "CEval题目……"
      }
    ],
    "temperature": 0.0,
    "max_tokens": 16,
    "chat_template_kwargs": {
      "enable_thinking": false
    }
  }'

返回:

{
  "content": "answer:B",
  "reasoning": null,
  "finish_reason": "stop"
}

说明:

  1. 模型服务正常。
  2. 题目 prompt 正常。
  3. enable_thinking=false 可以可靠关闭 reasoning。
  4. 关闭 thinking 后,16 个输出 token 已足够完成选择题回答。

9. 检查 AISBench 是否支持传递 chat_template_kwargs

不能仅凭 curl 成功就直接修改配置,还需要确认 AISBench 是否会将参数原样发送到 API。

检查 VLLMCustomAPIChat 源码后发现,其流程为:

generation_kwargs = self.generation_kwargs.copy()
generation_kwargs.update({"max_tokens": max_out_len})
generation_kwargs.update({"model": self.model})

response = self.client.request(cache_data, generation_kwargs)

同时,AISBench 会将:

HUMAN → user
BOT → assistant
SYSTEM → system

因此 prediction 文件中的 HUMAN/prompt 只是 AISBench 内部格式,并不是最终发送给 OpenAI-compatible API 的错误格式。

客户端构造请求时又会将参数直接并入请求体,因此可以把:

chat_template_kwargs

写入 generation_kwargs


10. 创建 CEval 专用 no-thinking 模型配置

为避免影响 BoolQ、GSM8K 等已有任务,没有直接修改通用配置,而是创建:

vllm_api_ceval_no_think.py

核心内容:

models = [
    dict(
        attr="service",
        type=VLLMCustomAPIChat,
        abbr="qwen36-35b-a3b-ceval-no-think",
        model="qwen3.6-35b-a3b",
        request_rate=0.2,
        retry=10,
        host_ip="127.0.0.1",
        host_port=8006,
        max_out_len=512,
        batch_size=1,
        generation_kwargs=dict(
            temperature=0.0,
            top_k=10,
            top_p=0.95,
            seed=None,
            repetition_penalty=1.03,
            chat_template_kwargs=dict(
                enable_thinking=False,
            ),
        ),
        pred_postprocessor=dict(
            type=extract_non_reasoning_content
        ),
    )
]

这里使用独立 abbr,避免 no-thinking 结果与旧结果混淆。该配置的实际创建过程和最终内容已有完整记录。


11. 不直接全量:采用四级验证流程

为了避免再次浪费全量运行时间,采用以下验证流程:

单条 curl
    ↓
20 条直连 API
    ↓
20 条 AISBench
    ↓
六科全量

20 条直连 API 结果

tested: 20
request errors: 0
empty content: 0
non-empty reasoning: 0
finish_reason=length: 0
strict format: 20
correct: 17
accuracy: 85.0%

20 条 AISBench 结果

total: 20
empty prediction count: 0
valid answer format: 20
correct: 17
manual accuracy: 85.0

两次结果完全一致,证明:

  • API 参数正确
  • AISBench 参数传递正确
  • prediction 保存正确
  • 后处理正确
  • summary 正确

12. 六科全量 no-thinking 结果

最终运行目录:

outputs/default/20260716_151051

结果如下:

科目 Accuracy
大学经济学 74.55%
工商管理 75.76%
注册会计师 83.67%
税务师 75.51%
法学 83.33%
法律职业资格 82.61%

总体:

total: 233
correct: 183
overall accuracy: 78.54
empty prediction count: 0
invalid format count: 0

初始结果与修复后结果对比:

阶段 结果
初始错误评测 0%~3.64%,大量空预测
修复后有效评测 总体 78.54%,空预测 0

13. Thinking 是否一定提高 Accuracy

为了验证 thinking 是否能够提高专业选择题成绩,又建立了:

vllm_api_ceval_thinking.py

参数:

max_out_len=2048
chat_template_kwargs=dict(
    enable_thinking=True,
)

大学经济学前 20 条结果:

模式 正确数 Accuracy
no-thinking 17/20 85%
thinking 17/20 85%

逐题比较:

same answer: 17
different answer: 3
thinking fixed: 1
thinking broke: 1
both wrong but different: 1

这说明 thinking 并不是单向提升:

  • 它可以将部分错误答案改对;
  • 也可能把原本正确的答案改错;
  • 还会明显增加推理耗时和 token 消耗。

20 条样本不足以判断总体收益,因此需要在同一批 233 条上做完整配对实验。


14. 后台运行问题:nohup 后找不到 ais_bench

最初使用:

nohup bash -c '
ais_bench ...
' > "$LOG" 2>&1 &

出现:

ais_bench: command not found
Exit 127

原因是新建的非交互 bash 没有正确继承当前 conda 环境的 PATH。

解决方法:

AIS_BENCH_BIN=$(command -v ais_bench)

nohup "$AIS_BENCH_BIN" \
  --models vllm_api_ceval_thinking \
  --datasets ceval_finance_compliance_thinking \
  --summarizer example \
  > "$LOG" 2>&1 &

使用绝对路径后,后台任务成功运行。


15. 日志监控问题:为什么一直显示 Post 20

启动全量任务后,监控窗口仍显示:

Post: 20
Received: 20
Failed: 0

最初误以为全量任务仍然只跑了 20 条。

实际原因是:

RUN=$(ls -td outputs/default/* | head -1)

是在旧任务期间赋值的。新任务启动后,已有 shell 变量不会自动更新,因此监控的仍是旧的 20 条目录。

解决方法是明确指定新目录:

RUN=/home/liluchi/benchmark/outputs/default/20260716_162709

或者从当前运行记录中读取 PID 和日志:

read PID LOG < ceval_thinking_current_run.txt
tail -f "$LOG"

同时通过 PID 区分:

旧 20 条任务 PID:826604
新全量任务 PID:834416

16. 经验总结

经验一:Failed=0 不代表 prediction 有效

必须同时检查:

Received
Failed
has no output
empty prediction
invalid format

经验二:summary 不能单独作为结果依据

正式结果至少要同时检查:

summary
prediction JSON
空预测数量
手动后处理准确率

经验三:文本提示不等于模型配置

/no_think

不一定可靠。

对于支持 thinking 的模型,应优先使用:

chat_template_kwargs=dict(
    enable_thinking=False
)

经验四:先小样本闭环,再跑全量

推荐流程:

1 条 → 20 条直连 → 20 条框架 → 全量

经验五:模型评测问题不一定是模型能力问题

本次从 0%~3.64% 修复到 78.54%,模型权重没有发生变化。

变化来自:

  • 数据集注册修复
  • API 返回字段分析
  • thinking 参数控制
  • 输出格式约束
  • 后处理和空预测复核

因此,模型评测首先是一项工程链路验证工作,其次才是模型能力比较。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐