主包准备的是文档推荐的数据集准备指南 — AISBench 评测工具 1.0 文档开源数据集。

小样本阶段: [0:8] accuracy = 87.50% [0:50] accuracy = 88.00%

分段评测阶段: [0:500]

原始 AISBench summary accuracy = 91.60% Post=500,Received=496,Failed=4,empty prediction=8。

对 8 条空预测样本进行手动补跑后,5 条补跑正确,修正 accuracy = 92.60%。

关键问题定位

1. max_out_len 太小会导致模型只返回 reasoning,content 为空,prediction 为空;

2. 全量一次性 request_rate=0 会导致大量请求失败;

3. 分段评测 + request_rate 限速 + retry 增加可以显著提升稳定性;

4. 空预测需要单独检查,必要时补跑或降低请求速率。

一、问题 1:accuracy = 0.00,prediction 全是空

现象

一开始 BoolQ 8 条样本跑通了流程,但是结果是:

BoolQ accuracy = 0.00

查看 prediction 文件发现:

"prediction": "",
"gold": "B"

同时 infer 日志里有:

Request xxx has no output. Please check the server response.
Post: 8 | Received: 8 | Failed: 0

说明:

API 请求发出去了;
服务端也返回了;
但 AISBench 没拿到有效 prediction。

根因

手动 curl 调 API 后发现返回是:

"content": null,
"reasoning": "Thinking Process: ...",
"finish_reason": "length"

这说明模型一直在生成 reasoning,但是 max_tokens 太小,还没来得及生成最终 content,就被截断了。

AISBench 默认读取的是:

message["content"]

所以 content=null 时,AISBench 的 prediction 就变成空字符串。


解决方法

把 AISBench 模型配置里的:

max_out_len

调大。它对应 API 里的:

max_tokens

执行:

cd ~/benchmark

python - <<'PY'
from pathlib import Path
import re

p = Path("ais_bench/benchmark/configs/models/vllm_api/vllm_api_general_chat.py")
s = p.read_text(encoding="utf-8")

s = re.sub(r"max_out_len\s*=\s*\d+", "max_out_len=2048", s)

p.write_text(s, encoding="utf-8")
print("updated max_out_len to 2048")
PY

grep -n "max_out_len" ais_bench/benchmark/configs/models/vllm_api/vllm_api_general_chat.py

验证方法

手动 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": "Ethanol fuel -- The energy balance for corn ethanol produced in the US is about 1.3 output units for one input unit. Question: does ethanol take more energy to make than it produces?\nA. Yes\nB. No\nPlease answer with only A or B. /no_think\nAnswer:"
      }
    ],
    "temperature": 0.2,
    "max_tokens": 2048
  }'

成功后返回里出现:

"content": "\n\nB",
"finish_reason": "stop"

说明模型已经生成了正式答案,AISBench 可以解析 prediction。


二、问题 2:原始 prediction 看起来和 gold 不相等,但 AISBench accuracy 是对的

现象

跑完 8 条后,summary 显示:

accuracy = 87.50

但自己直接比较:

prediction == gold

发现全是 False,比如:

prediction: '\n\nA. Yes'
gold: 'A'
correct: False

根因

AISBench 不是直接用原始 prediction 和 gold 比较,而是先经过后处理函数

first_capital_postprocess

BoolQ 配置里有:

pred_postprocessor=dict(type=first_capital_postprocess)

所以实际比较的是:

'\n\nA. Yes'  ->  'A'
'\n\nB. No'   ->  'B'

解决方法:用 AISBench 同样的后处理方式复现 accuracy

cd ~/benchmark

python - <<'PY'
import json
from pathlib import Path
from ais_bench.benchmark.utils.text_postprocessors import first_capital_postprocess

run = Path("outputs/default/20260713_132830")
p = run / "predictions/qwen36-35b-a3b-vllm-api/BoolQ.json"

data = json.load(open(p, "r", encoding="utf-8"))

correct = 0
total = 0

for k, v in data.items():
    raw_pred = v.get("prediction", "")
    gold = v.get("gold", "")
    pred = first_capital_postprocess(raw_pred)

    ok = pred == gold
    correct += int(ok)
    total += 1

    print("=" * 80)
    print("id:", k)
    print("raw prediction:", repr(raw_pred[:120]))
    print("processed prediction:", repr(pred))
    print("gold:", repr(gold))
    print("correct:", ok)

print("=" * 80)
print("accuracy:", correct / total * 100)
PY

得到:

accuracy: 87.5

说明 AISBench 的结果是对的。


三、问题 3:8 条样本太少,需要扩大验证

已完成结果

先跑 8 条:

BoolQ [0:8]
accuracy = 87.50

然后扩大到 50 条:

BoolQ [0:50]
accuracy = 88.00

说明 AISBench 调用 vLLM API 的评测链路已经稳定跑通。


小样本配置代码

新建 demo 配置:

cd ~/benchmark

cp ais_bench/benchmark/configs/datasets/SuperGLUE_BoolQ/SuperGLUE_BoolQ_gen_0_shot_str.py \
   ais_bench/benchmark/configs/datasets/SuperGLUE_BoolQ/SuperGLUE_BoolQ_gen_0_shot_str_demo.py

然后加入:

test_range='[0:8]'

对应修改代码:

cd ~/benchmark

python - <<'PY'
from pathlib import Path

p = Path("ais_bench/benchmark/configs/datasets/SuperGLUE_BoolQ/SuperGLUE_BoolQ_gen_0_shot_str_demo.py")
s = p.read_text(encoding="utf-8")

old = """BoolQ_reader_cfg = dict(
    input_columns=['question', 'passage'],
    output_column='label',
)"""

new = """BoolQ_reader_cfg = dict(
    input_columns=['question', 'passage'],
    output_column='label',
    test_range='[0:8]',
)"""

s = s.replace(old, new)
p.write_text(s, encoding="utf-8")

print("created demo config:", p)
PY

改成 50 条

cd ~/benchmark

python - <<'PY'
from pathlib import Path
import re

p = Path("ais_bench/benchmark/configs/datasets/SuperGLUE_BoolQ/SuperGLUE_BoolQ_gen_0_shot_str_demo.py")
s = p.read_text(encoding="utf-8")

s = re.sub(r"test_range=['\"]\[0:\d+\]['\"]", "test_range='[0:50]'", s)

p.write_text(s, encoding="utf-8")
print("updated test_range to [0:50]")
PY

运行:

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

结果:

BoolQ accuracy = 88.00

四、问题 4:直接跑全量时大量请求失败

现象

你直接跑全量 BoolQ:

nohup ais_bench --models vllm_api_general_chat \
  --datasets SuperGLUE_BoolQ_gen_0_shot_str \
  --summarizer example \
  > boolq_full_$(date +%Y%m%d_%H%M%S).log 2>&1 &

跑到后面出现大量错误:

Request failed: Exceeded maximum retry attempts (2)

最终日志显示:

Post: 3270
Received: 333
Failed: 2937

根因

模型配置里原来是:

request_rate = 0
retry = 2

AISBench 日志也提示:

Request rate (0), sending all requests simultaneously

意思是它会尽可能同时发送所有请求。
全量 3270 条一起压到 127.0.0.1:8006,vLLM 服务承受不了,于是大量请求超时或失败。


解决方法:限速 + 分段跑

把模型配置改成:

request_rate=0.1
retry=5

代码:

cd ~/benchmark

python - <<'PY'
from pathlib import Path
import re

p = Path("ais_bench/benchmark/configs/models/vllm_api/vllm_api_general_chat.py")
s = p.read_text(encoding="utf-8")

s = re.sub(r"request_rate\s*=\s*[\d.]+", "request_rate=0.1", s)
s = re.sub(r"retry\s*=\s*\d+", "retry=5", s)

p.write_text(s, encoding="utf-8")
print("updated request_rate=0.1, retry=5")
PY

grep -n "request_rate\|retry\|max_out_len" ais_bench/benchmark/configs/models/vllm_api/vllm_api_general_chat.py

最终目标配置:

request_rate=0.1
retry=5
max_out_len=2048

五、问题 5:全量太大,改成 [0:500] 分段评测

解决方法

新建 chunk 配置:

cd ~/benchmark

cp ais_bench/benchmark/configs/datasets/SuperGLUE_BoolQ/SuperGLUE_BoolQ_gen_0_shot_str.py \
   ais_bench/benchmark/configs/datasets/SuperGLUE_BoolQ/SuperGLUE_BoolQ_gen_0_shot_str_chunk.py

加入:

test_range='[0:500]'

代码:

cd ~/benchmark

python - <<'PY'
from pathlib import Path

p = Path("ais_bench/benchmark/configs/datasets/SuperGLUE_BoolQ/SuperGLUE_BoolQ_gen_0_shot_str_chunk.py")
s = p.read_text(encoding="utf-8")

old = """BoolQ_reader_cfg = dict(
    input_columns=['question', 'passage'],
    output_column='label',
)"""

new = """BoolQ_reader_cfg = dict(
    input_columns=['question', 'passage'],
    output_column='label',
    test_range='[0:500]',
)"""

s = s.replace(old, new)
p.write_text(s, encoding="utf-8")

print("created chunk config [0:500]")
PY

grep -n "test_range" ais_bench/benchmark/configs/datasets/SuperGLUE_BoolQ/SuperGLUE_BoolQ_gen_0_shot_str_chunk.py

后台运行 [0:500]

cd ~/benchmark

nohup ais_bench --models vllm_api_general_chat \
  --datasets SuperGLUE_BoolQ_gen_0_shot_str_chunk \
  --summarizer example \
  > boolq_chunk_0_500_$(date +%Y%m%d_%H%M%S).log 2>&1 &

查看进程:

ps -ef | grep ais_bench | grep -v grep

查看最新输出目录:

cd ~/benchmark

LATEST=$(ls -td ~/benchmark/outputs/default/* | head -1)
echo "$LATEST"

查看实时 infer 日志:

tail -f "$LATEST/logs/infer/qwen36-35b-a3b-vllm-api/BoolQ.out"

退出日志查看:

Ctrl+C

不会停止后台任务。


六、问题 6:后台运行没反应 / 提交了两次

现象

运行 nohup ... & 后只显示:

[2] 3501773

以为没反应。


解释

这是正常的。
nohup ... & 会把任务放到后台运行,终端不会继续刷 AISBench 日志。

其中:

[2]      后台任务编号
3501773  进程 PID

查看后台任务

jobs -l

查看 AISBench 进程:

ps -ef | grep ais_bench | grep -v grep

如果提交了两次,就保留一个,杀掉另一个:

kill PID

如果还在:

kill -9 PID

七、问题 7:[0:500] 跑到 50 条时有 4 条 failed

现象

日志显示:

Post: 50
Received: 45
Failed: 4

一开始担心是不是又炸了。


判断

这次不是全量那种大规模失败。后面继续观察,到 180 条时:

Failed 还是 4

说明失败没有继续增加,服务进入稳定状态。


最终 [0:500] 推理结果

Post: 500
Received: 496
Failed: 4
time elapsed: 6833.68s

含义:

500 条请求
496 条成功返回
4 条请求失败
总耗时约 6833 秒 ≈ 1小时53分54秒
成功率 99.2%
失败率 0.8%

八、问题 8:[0:500] summary accuracy = 91.60,但有 failed 样本

原始 summary

BoolQ accuracy = 91.60

对应:

458 / 500 = 91.60%

查看 prediction 空样本

执行后发现:

total: 500
correct by postprocess: 458
accuracy: 91.60
empty prediction count: 8
empty ids: ['0', '1', '2', '3', '20', '49', '88', '297']

这里说明:

日志里 Failed = 4
但 prediction 为空 = 8

原因是空预测有两类:

1. 请求真正失败,超过最大重试次数;
2. 请求成功但 content 为空,例如 finish_reason=length,只生成 reasoning 没生成 content。

查空预测代码

cd ~/benchmark

RUN=outputs/default/20260713_160953

python - <<'PY'
import json
from pathlib import Path
from ais_bench.benchmark.utils.text_postprocessors import first_capital_postprocess

run = Path("outputs/default/20260713_160953")
p = run / "predictions/qwen36-35b-a3b-vllm-api/BoolQ.json"

data = json.load(open(p, "r", encoding="utf-8"))

empty = []
correct = 0

for k, v in data.items():
    raw = v.get("prediction", "")
    gold = v.get("gold", "")
    pred = first_capital_postprocess(raw) if raw else ""
    ok = pred == gold
    correct += int(ok)

    if raw is None or raw.strip() == "":
        empty.append((k, gold, v.get("origin_prompt", "")[:500]))

print("total:", len(data))
print("correct by postprocess:", correct)
print("accuracy:", correct / len(data) * 100)
print("empty prediction count:", len(empty))
print("empty ids:", [x[0] for x in empty])

print("\n===== empty cases =====")
for k, gold, prompt in empty:
    print("=" * 80)
    print("id:", k)
    print("gold:", gold)
    print("prompt head:", prompt.replace("\n", " "))
PY

九、问题 9:空预测样本需要补跑

手动补跑 8 条空预测

补跑样本:

0, 1, 2, 3, 20, 49, 88, 297

代码:

cd ~/benchmark

python - <<'PY'
import json
import time
import urllib.request
from pathlib import Path
from ais_bench.benchmark.utils.text_postprocessors import first_capital_postprocess

BASE_URL = "http://127.0.0.1:8006/v1/chat/completions"
MODEL_ID = "qwen3.6-35b-a3b"

run = Path("outputs/default/20260713_160953")
pred_path = run / "predictions/qwen36-35b-a3b-vllm-api/BoolQ.json"
out_path = run / "empty_retry_manual.json"

data = json.load(open(pred_path, "r", encoding="utf-8"))

empty_ids = ["0", "1", "2", "3", "20", "49", "88", "297"]

results = {}
correct = 0

for k in empty_ids:
    v = data[k]
    prompt = v["origin_prompt"]
    gold = v["gold"]

    payload = {
        "model": MODEL_ID,
        "messages": [
            {
                "role": "user",
                "content": prompt + "\nPlease answer with exactly one letter: A or B. Do not explain. /no_think"
            }
        ],
        "temperature": 0.2,
        "max_tokens": 2048
    }

    req = urllib.request.Request(
        BASE_URL,
        data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST"
    )

    print("=" * 80)
    print("retry id:", k, "gold:", gold)

    try:
        with urllib.request.urlopen(req, timeout=300) as resp:
            res = json.loads(resp.read().decode("utf-8"))

        msg = res["choices"][0]["message"]
        content = msg.get("content") or ""
        reasoning = msg.get("reasoning") or ""
        finish_reason = res["choices"][0].get("finish_reason")

        pred = first_capital_postprocess(content)
        ok = pred == gold
        correct += int(ok)

        print("finish_reason:", finish_reason)
        print("content:", repr(content[:300]))
        print("processed pred:", pred)
        print("gold:", gold)
        print("correct:", ok)

        results[k] = {
            "gold": gold,
            "content": content,
            "processed_prediction": pred,
            "correct": ok,
            "finish_reason": finish_reason,
            "reasoning_head": reasoning[:500],
        }

    except Exception as e:
        print("retry failed:", repr(e))
        results[k] = {
            "gold": gold,
            "error": repr(e),
        }

    time.sleep(3)

json.dump(results, open(out_path, "w", encoding="utf-8"), ensure_ascii=False, indent=2)

print("\nmanual retry correct:", correct, "/", len(empty_ids))
print("saved to:", out_path)

original_correct = 458
new_correct = original_correct + correct
print("corrected accuracy if using retry:", new_correct / 500 * 100)
PY

补跑结果

manual retry correct: 5 / 8
corrected accuracy if using retry: 92.60

具体:

id 0   B / B  对
id 1   A / A  对
id 2   A / A  对
id 3   A / A  对
id 20  B / B  对
id 49  B / A  错
id 88  空 / A  仍然 length 截断
id 297 B / A  错

所以:

原始正确数 = 458
补跑新增正确 = 5
修正正确数 = 463
修正 accuracy = 463 / 500 = 92.60%

Logo

免费领 200 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐