大家好,我最近在做一个开源项目 YERP( yolo-edge-runtime-profiler,地址:yolo-edge-runtime-profiler.git)。
做这个不是想替代 MindSpore Lite benchmark、日志系统、profiling 工具或底层性能分析器。而是想探索一层:Runtime Evidence Layer:运行时证据层。
简单说,就是当端侧 AI 推理出现慢帧、尾部延迟、输出异常膨胀、后处理压力、内存压力或难以复现的现场问题时,把当时的:
- 输入样本
- 推理阶段耗时
- 后处理耗时
- 输出元数据
- 硬件 / 系统状态
- 触发原因
“快照”下来,并绑一起成一条本地 EvidenceFlow 证据记录,供后续定位、分析和复核。
一句话:
benchmark 告诉我们模型平均跑多快;日志告诉我们哪里报错;YERP 记录:
到底是哪一个输入样本,让端侧推理进入了值得保存、追溯、分析的压力状态?
一、为什么想做“运行时证据层”?
在做端侧 AI 部署时,很多开发者可能都遇到过类似问题:
模型在本地 benchmark 里平均耗时很好,指标看起来很漂亮。但部署到真实设备、真实业务流、真实客户现场后,会出现偶发性卡顿、p95 / p99 延迟升高,或者某些输入样本明显更慢。
最麻烦的是,这类问题往往很难复现。常见情况是:
- 没有完整现场日志
- 没有保存触发问题的输入样本
- 没有当时的输出分布
- 没有完整硬件状态
- 只有一句反馈:现场偶尔卡一下
最后开发者只能自己在推理代码里到处打 timestamp,手动猜测:
- 是预处理慢了?
- 是 NPU / CPU 推理慢了?
- 是后处理慢了?
- 是数据拷贝慢了?
- 是输出候选数量突然变多?
- 是某些输入触发了特殊耗时路径?
现有工具链通常能解决两类问题:
- Benchmark / Profiler: 告诉你模型整体性能、平均耗时、算子级耗时分布。
- Error Logs: 告诉你哪里报错、哪里转换失败、哪里运行异常。
但在真实端侧部署中,还缺一层更贴近现场分析的问题:
到底是哪一个输入样本,把推理流水线压进了异常压力状态?
YERP 就是想做这一层,它不是底层 profiler,而是一个轻量的 运行时证据层 (Runtime Evidence Layer)。
当推理流水线出现异常压力时,YERP 会尝试把:
- 输入样本
- 各阶段耗时
- 输出张量 / 检测结果元数据
- 硬件或系统状态
- 触发原因
组织成一个本地 EvidenceFlow 证据包,用来后续分析、调试、profiling、重训、量化校准或工具链排查。
二、YERP 目前已经跑通的部分
目前 YERP Vision 已经在 YOLO 场景下跑通了一个最小闭环。它可以在推理过程中监控:
preprocess_ms
inference_ms
postprocess_ms
total_ms
p50 / p95 / p99 / max latency
tail latency coefficient
postprocess spike
stage imbalance
box count
confidence entropy
class entropy
dominant cause
当某一帧触发运行时压力时,YERP 会在本地保存:
image.jpg
metadata.json
runtime_report.json
runtime_frames.csv
例如在一个已经跑通的 YERP Vision 样例中,一帧普通 YOLO 检测画面被自动捕获。它不是因为人工提前标注为“问题帧”才被保存,而是因为 YERP 检测到这一帧触发了运行时压力:
(注:该图仅用于展示 YERP Vision 已跑通的 EvidenceFlow 捕获机制,不代表 MindSpore Lite / Ascend 后端测试结果,MindSpore Lite / Ascend adapter 仍处于共测设计阶段。)
下图是这个 JSON sidecar 对应的被捕获帧。重点不是这张图“看起来异常”,而是它在运行时触发了可记录的压力信号。
{
"state": "RED",
"dominant_cause": "POSTPROCESS_DOMINANT",
"selection_reason": "runtime_pressure",
"metrics": {
"box_count": 18,
"class_count": 4,
"confidence_entropy": 2.51,
"preprocess_ms": 1.20,
"inference_ms": 3.95,
"postprocess_ms": 2.02,
"postprocess_ratio": "28.15%"
}
}
这类记录的价值在于:
不需要提前知道这张图是不是“缺陷”或“坏样本”。
它先记录:这一个输入样本是否让端侧推理管线进入了值得复盘的压力状态。
这就是我说的 EvidenceFlow:
把一次运行时压力事件,转化成可保存、可复盘、可分享字段结构的证据记录。
我也已经在 Ultralytics GitHub Discussions 里介绍过这个思路,Ultralytics 正在持续收集团队和社区反馈:
https://github.com/orgs/ultralytics/discussions/25250#discussioncomment-17677787
三、为什么想和 MindSpore Lite / Ascend 社区共测?
我希望探索的是:能否为 MindSpore Lite / Ascend / 端侧 NPU 推理场景做一个 YERP EvidenceFlow Adapter。不是替代现有工具,而是和现有工具互补。形成:
MindSpore Lite benchmark:
关注模型整体性能、平均耗时、基础推理能力。
日志 / 报错信息:
关注模型转换失败、算子报错、运行异常。
底层 profiler:
关注算子、runtime、硬件调度、内存等底层瓶颈。
YERP:
关注哪一个输入样本触发了运行时压力,
并把输入样本、耗时、输出元数据、系统状态绑定成证据记录。
我觉得这层对于端侧推理、NPU 部署、机器人、无人机、AMR、工业视觉、信创边缘设备都可能有价值。因为这些场景里的问题往往不是简单的“能不能跑”,而是:
- 现场能不能稳定跑
- 出了问题能不能复现
- 能不能知道是哪一个输入样本触发了异常
- 能不能把这类样本沉淀下来,用于后续优化、重训、量化校准或工具链排查
四、我想共建的最小 Adapter
第一版不需要很复杂。只要 MindSpore Lite / Ascend 推理脚本能提供以下信息,就可以先生成 EvidenceFlow:
sample_id / input_path
preprocess_ms
inference_ms
postprocess_ms
output_metadata
可选硬件指标
例如伪代码大概是这样:
import time
from yerp import EvidenceRecorder
recorder = EvidenceRecorder(
backend="mindspore_lite",
output_dir="./yerp_evidence"
)
for sample in dataset:
t0 = time.perf_counter()
input_tensor = preprocess(sample)
t1 = time.perf_counter()
# 你的 MindSpore Lite / Ascend 推理
outputs = model.predict(input_tensor)
t2 = time.perf_counter()
result_meta = postprocess(outputs)
t3 = time.perf_counter()
recorder.update(
sample_id=sample.id,
input_ref=sample.path,
preprocess_ms=(t1 - t0) * 1000,
inference_ms=(t2 - t1) * 1000,
postprocess_ms=(t3 - t2) * 1000,
output_metadata=result_meta, # 例如 shape、candidate count、top score、检测框数量等
hardware_metadata={
"cpu_usage": optional_cpu_usage,
"memory_mb": optional_memory,
"npu_usage": optional_npu_usage,
"temperature": optional_temperature,
}
)
第一版甚至可以不强依赖硬件指标。只要能拿到:
- 输入样本引用
- 推理阶段耗时
- 后处理耗时
- 输出元数据
先做到:
滑动窗口基线计算
p50 / p95 / p99 延迟统计
尾部延迟检测
慢样本捕获
输出压力检测
本地 JSON / CSV / report 生成
后续再逐步接入 CPU、NPU、内存、温度、队列长度、多路 stream id 等指标。
五、希望寻找什么样的共测伙伴?
如果你正在使用 MindSpore Lite / Ascend / 端侧 NPU 推理,并且遇到过下面这些问题,欢迎一起测试:
模型转换后能跑,但某些样本推理特别慢;
benchmark 平均耗时正常,但实际业务流里偶发卡顿;
量化后模型体积变小,但端侧速度没有明显提升,甚至某些算子或某些样本耗时异常;
检测类模型在高密度目标场景下后处理突然变慢;
某些输入样本会明显拉高 p95 / p99 / max latency;
现场问题难复现,客户只反馈“偶尔卡一下”;
无法全量保存现场数据,但希望抓住最关键的异常样本。
不需要你上传商业模型、客户图片或敏感数据。
YERP 默认是 local-first:
图片留在本地
模型留在本地
业务数据不需要上传
EvidenceFlow 证据记录也可以只保存在本地
如果涉及隐私场景,也可以只分享:
脱敏后的 report
字段结构
耗时分布
报错日志
bucket 统计
你遇到的现象描述
我会根据这些反馈继续调整 YERP adapter 的字段设计和脚本逻辑。
六、共测主要想验证什么?
主要想先验证几个问题:
- MindSpore Lite / Ascend 推理脚本中,哪些运行时字段最容易采集?
- 对端侧推理用户来说,最需要看的 EvidenceFlow 字段是什么?是 inference_ms、postprocess_ms、p99、内存、NPU 利用率,还是输出 tensor 统计?
- 对检测、分类、OCR、语音、时序模型,不同任务的 output_metadata 应该如何抽象?
- YERP 生成的本地 JSON / CSV / report,是否能帮助开发者更快定位“哪一个输入样本触发了异常”?
- 是否有必要进一步做 MindSpore Lite / Ascend 专用 adapter?
七、当前边界说明
为了避免误解,再说明一下当前边界:
YERP 目前已经在 Vision / YOLO 场景跑通了运行时压力捕获。
MindSpore Lite / Ascend adapter 还在共测和设计阶段。
YERP 不替代 MindSpore Lite 官方 benchmark、日志或 profiler。
YERP 也不直接判断底层根因,而是先保存“哪一个输入样本 + 什么运行时证据”值得继续分析。
我更希望它成为一个辅助层:
先用 YERP 找到值得分析的输入样本;
再结合 MindSpore Lite 日志、benchmark、profiling 工具继续定位底层原因。
八、一句话总结
平均推理耗时只能告诉我们模型大体跑得快不快。但真实部署里,最关键的问题往往是:
到底是哪一个输入样本,让端侧推理进入了压力状态?
YERP 想做的,就是把这个瞬间保存成 EvidenceFlow。如果你对 MindSpore Lite / Ascend / 端侧推理 EvidenceFlow adapter 感兴趣,或者手里有真实部署中的慢样本、卡顿样本、量化后异常样本,欢迎留言或私信交流。
项目目前是开源方向,欢迎共测、反馈和一起定义 adapter 接口。
如果你对端侧推理 EvidenceFlow 感兴趣,或者手里有真实的现场压力样本,欢迎留言,或者来 GitHub 仓库 提 Issue 交流(觉得好的别忘了点星
)!
让我们一起把端侧排障从“玄学猜测”变成“有证可查”。
