Repository navigation
[RFC]AISBench 推理响应异常检测模块设计 #473
Description
AISBench 推理响应异常检测模块设计
修订记录
| 日期 | 修订版本 | 修改描述 | 作者 | RFC文档 |
|---|---|---|---|---|
| 2026-08-15 | 1.0 | 初稿完成:设计 msProbe 推理响应异常检测能力 | ||
背景描述
大模型服务推理过程中,即使 HTTP 请求成功且返回内容可被正常消费,也可能出现影响结果质量和稳定性的输出异常,例如:
- 生僻字符或异常字符;
- 输出乱码;
- 连续重复生成;
- token 概率出现
NaN等数值异常。
现有 AISBench 推理与评测链路主要关注请求成功率、模型输出及评测指标,缺少针对生成过程质量的独立审计能力。特别是在服务模型场景中,异常往往只能通过最终文本人工排查,定位成本较高。
本模块接入 msProbe 的 Response Anomaly 能力,在服务模型推理阶段采集生成 token id 与 top-k logprobs,并在推理结束后异步执行异常检测。检测结果独立落盘,不改变原有 prediction、Eval、Judge 和汇总逻辑。
核心价值如下:
- 自动化检测:对每个推理 Case 自动识别常见响应异常。
- 低侵入集成:异常检测与原始评测结果解耦,不影响已有指标计算。
- 异步执行:推理完成后后台执行检测,可与 Eval、JudgeInfer 等后续阶段并行。
- 可恢复性:支持复用工作目录时继承已完成检测结果,避免重复检测。
- 可审计性:独立保存检测结果、状态、日志及可选 payload 归档。
- 多模型适配:支持模型级 msProbe 配置,并可基于本地模型自动生成检测所需配置文件。
本模块当前目标是覆盖 AISBench 普通服务模型生成链路,不对 msProbe 检测算法本身进行复制、改写或维护。
方案设计
1. 总体架构
模块以 ResponseAnomalyCoordinator 为核心协调组件,贯穿配置初始化、推理响应采集、payload 分流存储、后台检测、结果归档和状态展示等阶段。
flowchart LR
A[CLI / 配置文件] --> B[ConfigManager]
B --> C[服务模型 generation_kwargs]
C --> D[BaseAPIModel]
D --> E[解析 token ids / top-k logprobs]
E --> F[Inferencer OutputHandler]
F --> G[Prediction JSONL]
F --> H[Payload Staging JSONL.ZST]
G --> I[ResponseAnomalyCoordinator]
H --> I
I --> J[msProbe ILLDetector]
J --> K[Response Anomaly Result JSONL]
I --> L[状态文件 tmp_ResponseAnomaly.json]
L --> M[TasksMonitor 状态面板]
G --> N[Judge / Eval / Summary]
整体流程说明:
- 用户通过配置文件或 CLI 开启响应异常检测。
ConfigManager校验运行模式和模型类型,并向服务模型请求参数注入:logprobs=Truetop_logprobs=20
- API 模型从流式或非流式响应中提取 token id 与 top-k logprobs。
- 推理输出处理器将 payload 写入独立的 ZSTD 压缩 JSONL staging 文件,避免完整 payload 长期混入 prediction 文件。
- Infer 阶段结束后,
ResponseAnomalyCoordinator启动后台线程:- 读取 prediction 文件和 payload staging;
- 初始化或复用按模型缓存的 msProbe 检测器;
- 调用
ILLDetector.run(...)检测每个 Case; - 写入独立异常检测结果;
- 根据保留策略归档或清理 payload。
- 检测线程与 Eval / JudgeInfer / 汇总阶段并行执行。
- 工作流结束前通过
ResponseAnomalyWait等待检测线程完成,保证结果完整落盘。
2. 模块划分
| 模块 | 主要文件 | 职责 |
|---|---|---|
| CLI 参数 | ais_bench/benchmark/cli/argument_parser.py |
提供响应异常检测开关及 payload 保留策略参数。 |
| 配置管理 | ais_bench/benchmark/cli/config_manager.py |
归一化全局和模型级配置,校验约束并注入请求参数。 |
| 工作流编排 | ais_bench/benchmark/cli/workers.py |
Infer 完成后启动检测线程;流程结束前等待检测完成。 |
| API 响应采集 | ais_bench/benchmark/models/api_models/base_api.py |
从服务响应提取 token id 和 top-k logprobs。 |
| vLLM 请求适配 | ais_bench/benchmark/models/api_models/vllm_custom_api_chat.py |
开启检测时请求 vLLM 返回 token id。 |
| 推理输出分流 | ais_bench/benchmark/openicl/icl_inferencer/output_handler/base_handler.py |
将 payload 写入 staging 压缩文件,并从常规 prediction 中移除。 |
| Payload 存储 | ais_bench/benchmark/utils/response_anomaly_jsonl.py |
提供 JSONL.ZST 分片写入、读取、manifest 生成和校验信息。 |
| 检测协调器 | ais_bench/benchmark/utils/response_anomaly.py |
管理检测线程、msProbe 初始化、检测执行、断点恢复、结果写入及状态上报。 |
| 状态面板 | ais_bench/benchmark/runners/base.py |
动态识别并展示 ResponseAnomaly 辅助任务状态。 |
| 配置生成工具 | ais_bench/tools/response_anomaly/gen_model_config.py |
调用 msProbe 官方工具生成模型配置,并合并已有模型信息。 |
3. 核心流程设计
3.1 配置初始化流程
ConfigManager 在加载总配置后执行响应异常检测配置初始化。
flowchart TD
A[读取 response_anomaly 配置] --> B{是否由 CLI 覆盖 enabled?}
B --> C[设置 enabled]
C --> D{是否启用?}
D -- 否 --> E[结束]
D -- 是 --> F[校验运行模式]
F --> G[校验 service 模型存在]
G --> H[校验 payload_retention 和存储参数]
H --> I[合并全局和模型级配置]
I --> J[强制注入 logprobs=True]
J --> K[强制注入 top_logprobs=20]
K --> L[注入内部标识 response_anomaly_enabled]
启用后,系统会进行以下约束校验:
- 仅支持
all、infer、infer_judge模式; - 不支持
perf模式; - 不支持 Agent、工具调用、函数调用等自定义推理链路;
- 至少需要存在一个
attr='service'的服务模型; top_logprobs固定为20,不允许用户自定义;payload_storage.format固定为jsonl;payload_storage.compression固定为zstd;- ZSTD 压缩级别范围为
1至22; - 每个分片的最大行数必须为正整数。
3.2 推理响应 payload 采集
服务模型通过 BaseAPIModel 解析服务端返回内容。
支持以下响应字段位置:
- 响应根节点:
token_ids或tokenstopk_logprobs
choices[0]节点:token_ids或tokenstopk_logprobs
- vLLM OpenAI 风格响应:
choices[0].logprobs.content- 每个 token 的
top_logprobs
非流式响应直接提取并保存完整 payload。
流式响应需要兼容不同服务端行为:
- 每个 chunk 只返回一个新 token;
- 每个 chunk 返回当前全部 token 快照;
- 返回完整 token 列表,但只返回当前 token 的 top-k logprobs;
- 连续出现相同 token;
- token 数和 logprob 数不一致。
对于 token 与 top-k logprobs 数量不一致的 chunk,系统会丢弃该 chunk 并记录 debug 日志,避免错误 payload 污染后续检测。
payload 的标准结构如下:
{
"tokens": [151643, 123, 456],
"topk_logprobs": [
{"151643": -0.01, "12": -5.20},
{"123": -0.12, "88": -3.50},
{"456": -0.23, "42": -4.10}
]
}3.3 Payload 分流与存储
完整 token/logprob 数据量较大,不适合长期保存在普通 prediction 文件中。因此,输出处理器将其分流到独立 staging 文件。
目录结构如下:
<work_dir>/
├── predictions/
│ └── <model_abbr>/
│ └── <dataset_abbr>.jsonl
└── response_anomaly/
└── <model_abbr>/
└── payload_staging/
└── <dataset_abbr>/
├── part-<process>-<session>-00000.jsonl.zst
└── part-<process>-<session>-00001.jsonl.zst
每条 staging 记录包含:
{
"data_abbr": "dataset_name",
"id": 12,
"uuid": "case-uuid",
"response_anomaly_payload": {
"tokens": [151643, 123],
"topk_logprobs": [
{"151643": -0.01},
{"123": -0.12}
]
}
}存储设计要点:
- 使用 JSONL 便于流式读写;
- 使用 ZSTD 压缩降低 token/logprob 数据的磁盘占用;
- 使用分片机制控制单文件大小;
- 分片写入完成后使用原子替换发布,避免读取到半写入文件;
- 生成 manifest,记录分片文件、行数、大小与 SHA-256;
- 常规 prediction 文件会移除
response_anomaly_payload字段,避免影响后续 Eval 和减少文件体积。
3.4 异常检测流程
Infer 阶段结束后,ResponseAnomalyCoordinator 在后台线程中执行检测。
sequenceDiagram
participant W as Infer Worker
participant C as Coordinator
participant S as Payload Staging
participant M as msProbe ILLDetector
participant R as Result JSONL
participant B as TasksMonitor
W->>C: Infer 完成后 start(cfg)
C->>B: 写入 preparing 状态
C->>C: 合并模型级检测配置
C->>C: 自动生成或加载 msProbe 配置
C->>M: 初始化 ILLDetector
C->>B: 写入 loading 状态
loop 每个 model / dataset / case
C->>S: 流式读取 JSONL.ZST payload
C->>M: run(topk_logprobs, tokens, model_name)
M-->>C: is_anomaly, anomaly_type
C->>R: 批量写入检测结果
C->>B: 更新检测进度和统计
end
C->>C: 根据 retention 策略归档或清理 payload
C->>B: 写入 finish 状态
msProbe 调用方式如下:
from msprobe.response_anomaly.detector import ILLDetector
detector = ILLDetector(
config_path,
mtype_path,
token2category_path,
)
result = detector.run(
[topk_logprobs],
[tokens],
[model_name],
)为减少初始化开销,检测器按模型缓存:
- 同一模型对应多个数据集时,复用同一个
ILLDetector; - token 分类映射按模型配置和 EOS token 缓存;
- 避免逐 Case 反复解析大规模 token 分类文件。
3.5 检测结果设计
检测结果写入以下路径:
<work_dir>/response_anomaly/<model_abbr>/<dataset_abbr>.jsonl
每个 Case 一行,例如:
{
"id": 12,
"uuid": "case-uuid",
"is_anomaly": true,
"anomaly_type": 3,
"anomaly_type_name": "repetition",
"detection_status": "completed"
}字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
id |
int / str | 原始推理 Case 标识。 |
uuid |
str | Case 唯一标识,用于恢复场景精确匹配。 |
is_anomaly |
bool | 是否检测到异常。 |
anomaly_type |
int | msProbe 返回的异常类型编号。 |
anomaly_type_name |
str | 异常类型名称。 |
detection_status |
str | 检测执行状态。 |
reason |
str | 当检测失败、依赖不可用或 payload 无效时的原因摘要。 |
异常类型映射如下:
| anomaly_type | anomaly_type_name | 说明 |
|---|---|---|
0 |
normal |
正常输出。 |
1 |
rare_character |
生僻字符异常。 |
2 |
garbled |
乱码异常。 |
3 |
repetition |
重复输出异常。 |
4 |
nan_value |
概率数值异常。 |
检测状态如下:
| detection_status | 含义 |
|---|---|
completed |
已成功调用 msProbe 并得到检测结果。 |
skipped |
服务响应未返回有效 token id 或 top-k logprobs。 |
unavailable |
未安装或无法导入 msProbe 依赖。 |
failed |
检测器调用、配置初始化或输入转换失败。 |
3.6 Payload 保留策略
检测完成后,payload 是否长期保留由 payload_retention 决定。
| 策略 | 行为 |
|---|---|
all |
保留所有 Case 的 payload。 |
anomalies |
仅保留异常 Case,以及检测失败或依赖不可用的 Case。 |
none |
不保留 payload,仅保留检测结果。 |
归档目录:
<work_dir>/response_anomaly/<model_abbr>/payload/<dataset_abbr>/
├── payload_manifest.json
└── part-*.jsonl.zst
payload_manifest.json 示例:
{
"format": "jsonl",
"compression": "zstd",
"compression_level": 3,
"payload_retention": "anomalies",
"total_rows": 10,
"shards": [
{
"file": "part-p12345-abcd1234-00000.jsonl.zst",
"rows": 10,
"size_bytes": 2048,
"sha256": "sha256:<digest>"
}
]
}3.7 状态面板与日志
检测任务通过状态文件向 TasksMonitor 上报进度:
<work_dir>/status_tmp/tmp_ResponseAnomaly.json
状态项按模型和数据集粒度生成:
ResponseAnomaly/<model_abbr>/<dataset_abbr>
状态内容包含:
finish_count:已处理 Case 数;total_count:当前模型和数据集下的 Case 总数;progress_description:当前阶段描述;status:任务状态;other_kwargs:按异常类型聚合的统计数据;task_log_path:当前检测任务日志路径。
典型状态阶段包括:
waiting for response anomaly detectionpreparing response anomaly configloading response anomaly detectorstreaming response anomaly payloadsresponse anomaly detectingfinalizing response anomaly payloadsresponse anomaly finished
每个模型和数据集组合生成独立日志:
<work_dir>/logs/response_anomaly/<model_abbr>/<dataset_abbr>.out
状态文件使用原子替换写入,避免状态面板读取到不完整 JSON。
3.8 断点恢复设计
使用 --reuse 复用工作目录时,模块需要避免对已完成 Case 重复检测。
恢复策略如下:
- 读取现有异常检测结果文件;
- 使用
id + uuid作为 Case 唯一匹配键; - 仅继承
detection_status='completed'的结果; skipped、failed、unavailable状态不作为最终完成结果,可在后续运行中重新尝试;- 对 prediction 中不存在或 uuid 不一致的旧结果不继承;
- 已完成 Case 不再调用 msProbe;
- 已完成结果参与状态统计和最终汇总;
- 若需要保留 payload,则补齐已继承 Case 但尚未归档的 payload。
使用 id + uuid 而非仅使用 id,可避免同一 Case 被重新推理后误用旧检测结果。
3.9 msProbe 模型配置自动生成
msProbe 检测依赖以下文件:
| 文件 | 用途 |
|---|---|
config.yaml |
检测阈值与算法参数。 |
mtype_config.json |
模型名称及特殊 token 配置。 |
token2category/ |
token id 与类别映射文件。 |
当模型配置提供 model_path,但未提供完整的 msprobe_mtype_path 和 msprobe_token2category_dir 时,AISBench 自动调用配置生成工具:
ais_bench-gen-response-anomaly-config \
--model-path /path/to/local/model \
--model-name Qwen3-30B-A3B \
--output-dir /data/msprobe_configs/qwen3-30b-a3b
生成目录:
<work_dir>/response_anomaly_config/<model_abbr>/
├── configs/
│ ├── config.yaml
│ └── mtype_config.json
└── token2category/
└── <model_name>_<vocab_size>.json
生成工具设计原则:
- 调用 msProbe 官方
gen_model_config.py; - 在隔离临时目录中执行,避免部分失败覆盖已有配置;
- 自动合并已有
mtype_config.json中的模型条目; - 已存在的
config.yaml不覆盖,允许用户维护自定义阈值; - 生成成功后才将结果发布到目标目录。
约束
- 不支持性能测试场景和Agent场景下的异常检测;
- 只支持vllm框架下的流式和非流式chat,其他不支持。
使用说明
1. 安装依赖
响应异常检测依赖 msProbe 和 Zstandard,为可选依赖:
pip install 'ais-bench-benchmark[response_anomaly]'该依赖不影响未开启异常检测功能的普通 AISBench 使用。
2. 通过配置文件开启
在总配置文件中增加:
response_anomaly = dict(
enabled=True,
payload_retention='anomalies',
payload_storage=dict(
format='jsonl',
compression='zstd',
compression_level=3,
rows_per_shard=2000,
),
)服务模型配置示例:
models = [
dict(
abbr='qwen3-30b',
attr='service',
generation_kwargs=dict(
temperature=0.01,
),
response_anomaly=dict(
model_name='Qwen3-30B-A3B',
model_path='/path/to/Qwen3-30B-A3B',
# 以下三项可选;未配置时优先使用自动生成或 msProbe 默认资源
msprobe_config_path='/path/to/config.yaml',
msprobe_mtype_path='/path/to/mtype_config.json',
msprobe_token2category_dir='/path/to/token2category',
),
),
]配置优先级:
- 模型级
models[].response_anomaly - 全局
response_anomaly - 模块默认值
模型级配置主要用于多模型场景,为每个服务模型指定独立的 msProbe 模型名称和资源路径。
3. 通过命令行开启或关闭
开启:
ais_bench --config <config.py> --response-anomaly关闭:
ais_bench --config <config.py> --no-response-anomaly指定 payload 保留策略:
ais_bench \
--config <config.py> \
--response-anomaly \
--response-anomaly-payload-retention anomaliesCLI 参数优先级高于配置文件:
| 参数 | 说明 |
|---|---|
--response-anomaly |
强制开启响应异常检测。 |
--no-response-anomaly |
强制关闭响应异常检测。 |
--response-anomaly-payload-retention |
设置 all、anomalies 或 none。 |
4. 手工生成 msProbe 模型配置
对于 msProbe 未内置支持的模型,可手工执行:
ais_bench-gen-response-anomaly-config \
--model-path /path/to/local-model \
--model-name Qwen3-30B-A3B \
--output-dir ./msprobe_configs生成后,在模型配置中引用:
response_anomaly=dict(
model_name='Qwen3-30B-A3B',
msprobe_config_path='./msprobe_configs/configs/config.yaml',
msprobe_mtype_path='./msprobe_configs/configs/mtype_config.json',
msprobe_token2category_dir='./msprobe_configs/token2category',
)5. 输出文件说明
启用后主要输出如下:
<work_dir>/
├── predictions/
│ └── <model_abbr>/<dataset_abbr>.jsonl
├── response_anomaly/
│ └── <model_abbr>/
│ ├── <dataset_abbr>.jsonl
│ ├── payload_staging/
│ │ └── <dataset_abbr>/
│ └── payload/
│ └── <dataset_abbr>/
├── logs/
│ └── response_anomaly/
│ └── <model_abbr>/<dataset_abbr>.out
└── status_tmp/
└── tmp_ResponseAnomaly.json
其中:
predictions/:原始轻量推理结果;response_anomaly/<model>/<dataset>.jsonl:每个 Case 的异常检测结果;payload_staging/:检测过程临时使用的压缩 payload;payload/:依据保留策略生成的正式 payload 归档;logs/response_anomaly/:检测任务日志;status_tmp/:状态面板临时状态文件。
6. 使用限制
- 仅支持
attr='service'的服务模型。 - 仅支持
all、infer和infer_judge模式。 - 不支持
perf模式。 - 不支持 Agent、工具调用、函数调用及相关自定义评测链路。
- 服务端必须返回 token id 与 top-k logprobs,否则对应 Case 状态为
skipped。 top_logprobs固定为20,不允许修改。- 同一个
work_dir不应由多个 AISBench 进程同时读写。 - 使用
--reuse时,不应改变已有 payload 归档的保留策略;如需变更,应使用新的工作目录。 model_name应与 msProbe 的mtype_config.json和 token 分类映射中的名称匹配。
测试设计
1. 单元测试
1.1 配置与 CLI 测试
覆盖内容:
- 默认未开启响应异常检测;
--response-anomaly/--no-response-anomaly生效;- CLI payload 保留策略覆盖配置文件;
payload_retention非法值校验;- ZSTD 压缩级别、分片大小等参数校验;
- 仅允许支持的运行模式;
- 拒绝 Agent 和性能评测场景;
- 启用后自动注入:
logprobs=Truetop_logprobs=20response_anomaly_enabled=True
相关测试文件:
tests/UT/cli/test_argument_parser.py
tests/UT/cli/test_config_manager.py
1.2 API 响应 payload 测试
覆盖内容:
- 非流式响应提取 token id 和 top-k logprobs;
- vLLM OpenAI 风格 logprobs 响应转换;
- 流式单 token chunk 累积;
- 全量快照 chunk 替换;
- 完整 token + 单个 logprob 的混合响应;
- 连续相同 token 不丢失;
- token 和 logprob 不对齐时丢弃 chunk;
- 开关关闭时不采集 payload;
- vLLM 请求自动追加 token id 返回参数。
相关测试文件:
tests/UT/models/api_models/test_response_anomaly_payload.py
tests/UT/models/api_models/test_vllm_custom_api_chat.py
1.3 Payload 存储测试
覆盖内容:
- JSONL.ZST 写入与读取一致性;
- 分片阈值触发;
- 分片原子发布;
- manifest 内容正确;
- 多数据集路由到不同目录;
- staging writer 正确关闭;
- prediction 文件中 payload 被剥离。
相关测试文件:
tests/UT/utils/test_response_anomaly_jsonl.py
tests/UT/openicl/icl_inferencer/output_handler/test_base_handler.py
1.4 检测协调器测试
覆盖内容:
ILLDetector初始化和调用参数正确;- 正常、异常、失败、跳过和依赖不可用状态映射正确;
- 异常类型编号映射正确;
- 单模型多数据集场景复用检测器;
- token 分类映射缓存;
- 状态文件原子写入;
- 每个模型和数据集生成独立状态与日志;
id + uuid精确恢复;- 已完成 Case 不重复检测;
- 旧 payload、staging payload 与归档 payload 的恢复和去重;
all、anomalies、none三种保留策略;- 中断后残留构建目录清理;
- 空 prediction 文件产生告警但不阻塞流程。
相关测试文件:
tests/UT/utils/test_response_anomaly.py
2. 集成测试
集成测试环境要求:
- 安装
ais-bench-benchmark[response_anomaly]; - 准备 msProbe 支持或已生成配置的本地模型;
- 服务端兼容 token id 和 top-k logprobs 返回;
- 至少包含一个普通服务模型和一个数据集。
测试步骤:
ais_bench \
--config <config.py> \
--mode all \
--response-anomaly \
--response-anomaly-payload-retention anomalies验证项:
- 服务请求中包含
logprobs=True和top_logprobs=20; - 推理可正常完成;
- prediction 文件不包含完整
response_anomaly_payload; - staging 文件生成有效
.jsonl.zst分片; - 检测结果文件存在且包含每个 Case;
- 状态面板显示
ResponseAnomaly任务; - Eval 和汇总流程不受影响;
- payload 归档符合指定保留策略;
- 检测日志按模型和数据集落盘。
3. 端到端和回归测试
| 场景 | 预期结果 |
|---|---|
| 未开启功能 | 推理、评测行为与现有版本一致。 |
| 开启功能且服务返回完整 payload | 所有 Case 生成异常检测结果。 |
| 服务不返回 token/logprobs | 推理正常完成,对应检测结果为 skipped。 |
| 未安装 msProbe | 推理和评测正常完成,对应结果为 unavailable。 |
| msProbe 初始化失败 | 对应 Case 标记为 failed,流程不因单 Case 失败中断。 |
| 已知重复输出样本 | 结果中 anomaly_type_name 为 repetition。 |
| 已知乱码样本 | 结果中 anomaly_type_name 为 garbled。 |
payload_retention=all |
所有 payload 被归档。 |
payload_retention=anomalies |
仅异常、失败和不可用 Case 被归档。 |
payload_retention=none |
不生成正式 payload 归档。 |
使用 --reuse 重跑 |
已完成 Case 不重复调用 msProbe。 |
| 同 id、不同 uuid 重跑 | 不继承旧检测结果,重新执行检测。 |
| 多模型、多数据集 | 每个组合生成独立状态、日志与结果文件。 |
Activity
github-actions commentedon Aug 17, 2026
🌟欢迎给AISBench benchmark测评工具提issue,我们会尽快处理您的诉求~
github-actions commentedon Aug 17, 2026
🤖 基于AI机器人的issue内容完整性检查结果:
问题内容检查结果
检查状态
[FAIL]
详细检查
改进建议
此GitHub Issue的内容是一份关于“AISBench 推理响应异常检测模块设计”的RFC(Request For Comments)文档,而非一个问题报告。因此,所要求的“操作系统及版本”、“安装工具的python环境”、“python版本”、“AISBench工具版本”、“AISBench执行命令”、“模型配置文件或自定义配置文件内容”以及“实际行为”等信息,通常用于描述一个具体的问题或bug,与RFC文档的性质不符,故未包含在内。
如果此Issue旨在报告一个问题,则需要补充以下信息:
👉 如果想重新检查,在评论区@issue_checker即可。
【强烈推荐❤️🔥】确保issue描述完整后,可以试着将issue交给
回答,deepwiki包含了和工具相关的所有知识库