Skip to content

Add inner benchmark metrics component#7831

Open
Deleter-D wants to merge 3 commits into
PaddlePaddle:release/2.6from
Deleter-D:2.6_inner_benchmark
Open

Add inner benchmark metrics component#7831
Deleter-D wants to merge 3 commits into
PaddlePaddle:release/2.6from
Deleter-D:2.6_inner_benchmark

Conversation

@Deleter-D
Copy link
Copy Markdown
Collaborator

Motivation

💡 If this PR is a Cherry Pick, the PR title needs to follow the format by adding the [Cherry-Pick] label at the very beginning and appending the original PR ID at the end. For example, [Cherry-Pick][CI] Add check trigger and logic(#5191)

💡 如若此PR是Cherry Pick,PR标题需遵循格式,在最开始加上[Cherry-Pick]标签,以及最后面加上原PR ID,例如[Cherry-Pick][CI] Add check trigger and logic(#5191)

Modifications

Usage or Command

Accuracy Tests

Checklist

  • Add at least a tag in the PR title.
    • Tag list: [[FDConfig],[APIServer],[Engine], [Scheduler], [PD Disaggregation], [Executor], [Graph Optimization], [Speculative Decoding], [RL], [Models], [Quantization], [Loader], [OP], [KVCache], [DataProcessor], [BugFix], [Docs], [CI], [Optimization], [Feature], [Benchmark], [Others], [XPU], [HPU], [GCU], [DCU], [Iluvatar], [Metax]]
    • You can add new tags based on the PR content, but the semantics must be clear.
  • Format your code, run pre-commit before commit.
  • Add unit tests. Please write the reason in this PR if no unit tests.
  • Provide accuracy results.
  • If the current PR is submitting to the release branch, make sure the PR has been submitted to the develop branch, then cherry-pick it to the release branch with the [Cherry-Pick] PR tag.

PaddlePaddle-bot

This comment was marked as outdated.

@PaddlePaddle-bot
Copy link
Copy Markdown

PaddlePaddle-bot commented May 15, 2026

🤖 Paddle-CI-Agent | ci_status_monitor | 2026-05-19 12:13:53

CI报告基于以下代码生成(30分钟更新一次):


1 任务总览

当前有 2 个 required 任务失败,需优先处理后方可合并:

  • Approval:PR 未获得 FastDeploy RD 审批
  • run_tests_with_coverage:单元测试失败(新增属性未初始化)
总执行(rerun次数) 总任务 ✅ 通过 ❌ 失败 ⏳ 运行中 ⏸️ 等待中 跳过
37(0) 37 31 6 0 0 0

2 任务状态汇总

2.1 Required任务 : 8/10 通过

必选任务阻塞合并,失败需优先处理。

状态 任务 耗时 根因 修复建议 日志 重跑
Approval 10s 流程问题:PR 未获 FastDeploy RD 审批 请 qingqing01/jiangjiajun/dengkaipeng 审批 Job -
run_tests_with_coverage 1h14m PR问题:_benchmark_logger 属性未初始化 TokenProcessor.__init__ 中初始化属性 Job -
其余 8 个必选任务通过 - - - - -

2.2 可选任务 — 23/27 通过

可选任务不阻塞合并,失败仅供参考。

状态 任务 耗时 日志 重跑
Run iluvatar Tests / run_iluvatar_cases 16m14s Job -
Check PR Template 11s Job -
Trigger Jenkins for PR 10m9s Job -
CI_HPU 1h4m Job -
其余 23 个可选任务通过 - - -

3 失败详情(仅 required)

Approval — 流程检查失败(置信度: 高)

Approval

  • 状态: ❌ 失败
  • 错误类型: 流程检查
  • 置信度: 高
  • 根因摘要: PR 未获得 FastDeploy RD 审批,1 个审批要求未满足
  • 分析器: ci_analyze_infra

关键日志:

0. Cherry-Pick PR must come from develop and the title must contain [Cherry-Pick] and the original develop PR number (e.g., #5010).
Approval required from FastDeploy RD: qingqing01(dangqingqing), Jiang-Jia-Jun(jiangjiajun), heavengate(dengkaipeng).
There are 1 approved errors.

修复建议:

  1. 请指定的 FastDeploy RD 之一(qingqing01/dangqingqing、Jiang-Jia-Jun/jiangjiajun 或 heavengate/dengkaipeng)对此 PR 进行审批(Approve)

修复建议摘要: 请 FastDeploy RD(qingqing01 等)审批此 PR

链接: 查看日志

Run FastDeploy Unit Tests and Coverage / run_tests_with_coverage — 测试失败(置信度: 高)

Run FastDeploy Unit Tests and Coverage / run_tests_with_coverage

  • 状态: ❌ 失败
  • 错误类型: 测试失败
  • 置信度: 高
  • 根因摘要: 新增 _benchmark_logger 属性在 _record_completion_metrics 中使用但未初始化
  • 分析器: ci_analyze_unittest_fastdeploy

失败用例:

测试 错误 根因
tests/output/test_process_batch_output.py::...::test_process_batch_output_aborted_task_negative_token_speculative_decoding AttributeError: _benchmark_logger _record_completion_metrics 访问了未初始化的 _benchmark_logger 实例属性

根因详情:
本 PR 新增 benchmark metrics 组件,在 fastdeploy/output/token_processor.py_record_completion_metrics 方法(第 1153 行)中引入了 self._benchmark_logger 的访问。但 TokenProcessor.__init__ 中未初始化此属性(仅有 set_benchmark_logger 方法),导致在测试场景中未调用 set_benchmark_logger 时直接触发 AttributeError

关键日志:

fastdeploy/output/token_processor.py:1153: AttributeError
AttributeError: 'TokenProcessor' object has no attribute '_benchmark_logger'.
Did you mean: 'set_benchmark_logger'?

修复建议:

  1. fastdeploy/output/token_processor.pyTokenProcessor.__init__ 方法中添加 self._benchmark_logger = None 初始化
  2. 或在 _record_completion_metrics 第 1153 行改为 if getattr(self, '_benchmark_logger', None):

修复建议摘要: 在 TokenProcessor.__init__ 中添加 self._benchmark_logger = None

关联变更: fastdeploy/output/token_processor.py 第 1153 行新增 self._benchmark_logger 访问
链接: 查看日志

@paddle-bot
Copy link
Copy Markdown

paddle-bot Bot commented May 15, 2026

Thanks for your contribution!

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 15, 2026

Codecov Report

❌ Patch coverage is 51.26904% with 96 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (release/2.6@d71bdda). Learn more about missing BASE report.

Files with missing lines Patch % Lines
fastdeploy/metrics/benchmark_metrics_logger.py 45.89% 79 Missing ⚠️
fastdeploy/output/token_processor.py 18.18% 7 Missing and 2 partials ⚠️
fastdeploy/engine/common_engine.py 0.00% 3 Missing and 1 partial ⚠️
fastdeploy/engine/args_utils.py 66.66% 2 Missing and 1 partial ⚠️
fastdeploy/config.py 96.29% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@              Coverage Diff               @@
##             release/2.6    #7831   +/-   ##
==============================================
  Coverage               ?   72.36%           
==============================================
  Files                  ?      382           
  Lines                  ?    54352           
  Branches               ?     8500           
==============================================
  Hits                   ?    39333           
  Misses                 ?    12257           
  Partials               ?     2762           
Flag Coverage Δ
GPU 72.36% <51.26%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

PaddlePaddle-bot

This comment was marked as outdated.

Copy link
Copy Markdown

@PaddlePaddle-bot PaddlePaddle-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Paddle-CI-Agent | pr_review | 2026-05-18 16:56:53

📋 Review 摘要

PR 概述:新增进程内 Benchmark Metrics Logger,支持滑动/翻滚窗口统计推理性能并写入 JSONL 文件。
变更范围fastdeploy/metrics/(新模块)、fastdeploy/config.pyfastdeploy/engine/args_utils.pyfastdeploy/engine/common_engine.pyfastdeploy/output/token_processor.py、文档
影响面 Tag[Benchmark] [FDConfig] [Engine] [DataProcessor]

问题

级别 文件 概述
🔴 安全 fastdeploy/config.py:2459 assert 用于运行时用户输入校验,Python -O 下断言会被跳过,校验形同虚设
🔴 Bug fastdeploy/metrics/benchmark_metrics_logger.py:164 datetime.now() 使用本地时区,分布式多机环境时区不一致将导致时间戳错乱
🟡 建议 fastdeploy/metrics/benchmark_metrics_logger.py:68 多 DP rank 共享同一文件名 benchmark_metrics.jsonl,数据会互相覆盖/混合
🟡 建议 fastdeploy/engine/common_engine.py BenchmarkMetricsLogger.shutdown() 未集成到引擎停止流程,进程退出时可能丢失未落盘数据
📝 PR 规范 标题缺少 Tag;目标分支为 release/2.6 但未使用 Cherry-Pick 格式,且 PR 描述各段均为空

📝 PR 规范检查

当前 PR 存在两处规范问题:

  1. 标题缺少官方 Tag,且目标分支为 release/2.6,必须使用 Cherry-Pick 格式(需附原 PR 编号)。
  2. PR 描述所有段落均为空,未填写变更动机、修改内容、使用命令等。

标题建议(可直接复制):

  • [Cherry-Pick][Benchmark] Add inner benchmark metrics component (#<原PR编号>)

PR 描述建议(可直接复制):

## Motivation

新增进程内性能监控模块(BenchmarkMetricsLogger),在推理进程内部复用现有请求时间戳,每个请求完成时计算滚动统计并写入 JSONL 文件,与 `benchmark_serving.py` 指标体系对齐,支持实时监控与事后分析。

## Modifications

- `fastdeploy/config.py`:新增 `BenchmarkMetricsConfig` 配置类,包含 `enable``window_size``window_mode``percentiles``metrics` 字段;在 `FDConfig.__init__``FDConfig.check()` 中集成。
- `fastdeploy/engine/args_utils.py`:新增 `--benchmark-metrics-config` CLI 参数及 `create_benchmark_metrics_config()` 方法。
- `fastdeploy/metrics/benchmark_metrics_logger.py`:新增 `BenchmarkMetricsLogger`(后台线程写 JSONL)和 `CompletedRequestRecord`(请求级时序数据)。
- `fastdeploy/engine/common_engine.py`:在引擎初始化时按配置创建 `BenchmarkMetricsLogger` 并注入 `TokenProcessor`- `fastdeploy/output/token_processor.py`:在 `_record_metrics` 收集 ITL 样本,在 `_record_completion_metrics` 触发 `on_request_completed`- `docs/benchmark.md``docs/zh/benchmark.md`:补充进程内 Benchmark 使用文档,包含配置参数、可用指标、窗口模式说明和输出示例。
- `tests/metrics/test_benchmark_metrics_logger.py`:新增单测覆盖配置默认值、滑动/翻滚窗口、吞吐量计算、字段校验等场景。

## Usage or Command

```bash
python -m fastdeploy.entrypoints.openai.api_server \
       --model baidu/ERNIE-4.5-0.3B-Base-Paddle \
       --benchmark-metrics-config '{"enable": true, "window_size": 64, "window_mode": "sliding"}'
```

## Accuracy Tests

N/A(本 PR 为性能监控模块,不影响模型推理输出)

## Checklist

- [x] Add at least a tag in the PR title.
  - Tag list: [`[FDConfig]`,`[APIServer]`,`[Engine]`, `[Scheduler]`, `[PD Disaggregation]`, `[Executor]`, `[Graph Optimization]`, `[Speculative Decoding]`, `[RL]`, `[Models]`, `[Quantization]`, `[Loader]`, `[OP]`, `[KVCache]`, `[DataProcessor]`, `[BugFix]`, `[Docs]`, `[CI]`, `[Optimization]`, `[Feature]`, `[Benchmark]`, `[Others]`, `[XPU]`, `[HPU]`, `[GCU]`, `[DCU]`, `[Iluvatar]`, `[Metax]`]
  - You can add new tags based on the PR content, but the semantics must be clear.
- [x] Format your code, run `pre-commit` before commit.
- [x] Add unit tests. Please write the reason in this PR if no unit tests.
- [ ] Provide accuracy results.
- [x] If the current PR is submitting to the `release` branch, make sure the PR has been submitted to the `develop` branch, then cherry-pick it to the `release` branch with the `[Cherry-Pick]` PR tag.

总体评价

整体架构设计合理,滑动/翻滚窗口思路清晰,单测覆盖度较好。但存在两处 🔴 问题需修复后合入:assert 校验在生产环境优化模式下会被跳过(应改 raise ValueError),以及 datetime.now() 在多机分布式场景会引发时区不一致。此外建议修复 DP 多副本文件路径冲突和引擎停止时的 shutdown() 调用。

Comment thread fastdeploy/config.py
" CUDA 12.x → pip install cuda-python==12.*\n"
)

if self.benchmark_metrics_config is not None:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 安全 assert 用于运行时用户输入校验,Python -O 模式下所有 assert 语句会被跳过,导致非法配置无法被拦截。

这段校验逻辑共 12 个 assert,全部需要改为 raise ValueError。例如:

if not isinstance(cfg.enable, bool):
    raise ValueError(
        f"BenchmarkMetricsConfig: 'enable' must be a bool, got {type(cfg.enable).__name__}"
    )
if not (isinstance(cfg.window_size, int) and cfg.window_size >= 0):
    raise ValueError(
        f"BenchmarkMetricsConfig: 'window_size' must be a non-negative integer, got {cfg.window_size!r}"
    )
# 其余 assert 同理替换

duration = 0.0

result: dict[str, Any] = {
"timestamp": datetime.now().isoformat(),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Bug datetime.now() 使用系统本地时区,在分布式多机环境中各节点时区可能不一致,导致 JSONL 时间戳无法跨机对齐。

建议改为 UTC:

from datetime import timezone
# 替换所有 datetime.now().isoformat() 为:
datetime.now(tz=timezone.utc).isoformat()

文件中共两处(n==0 返回路径 和 正常路径),均需修改。

self._stop_event = threading.Event()

os.makedirs(log_dir, exist_ok=True)
self._file_path = os.path.join(log_dir, "benchmark_metrics.jsonl")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 建议 所有 DP rank 均写入同一路径 benchmark_metrics.jsonl,当 dp_rank > 0 时多个进程并发追加同一文件,会导致 JSONL 行序混乱,事后分析数据不可靠。

dp_rank 已作为构造参数传入,建议加入文件名区分:

fname = f"benchmark_metrics_dp{dp_rank}.jsonl" if dp_rank > 0 else "benchmark_metrics.jsonl"
self._file_path = os.path.join(log_dir, fname)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants