状态:草稿 (2026-10-16),部分实测。 阶段耗时是在一台配备单张 8GB 级笔记本 GPU 的服务器上,通过临时 Pod(限制 4 个 CPU 核心)测量的(预热 30 次后的 300 次运行中位数)。手机端的捕获与编码耗时以及网络区间属于 未测量。队列模拟使用的是笔记本 CPU 示例(
code/01_latency_queue.py,大约 1 秒左右)。 系列《阅读视觉模型 3:实时运行》第 1 篇。本系列探讨了如何在 阅读视觉模型 1·2中看到的模型在 规定时间内 运行的方法。
目录
- 1. “实时”的两个数字
- 2. 重叠阶段:吞吐量增加,延迟保持不变
- 3. 拥堵时:排队等待还是直接丢弃
- 4. 迟到的正确答案等于错误答案:Streaming Perception
- 5. 我们的实测:寻找球的一帧的生命周期
- 6. 阅读数字的习惯
- 7. 局限性
- 8. 与我们项目的联系
- 参考文献
1. “实时”的两个数字
乒乓球记分牌应用要做到“实时”,必须同时满足两个条件:
- 吞吐量(throughput):每秒处理多少帧。如果相机以 30fps 的速度提供数据,则处理能力必须达到 30 以上才不会出现卡顿。
- 端到端延迟(end-to-end latency):从拍摄一帧的瞬间到该结果显示在屏幕上的时间。它决定了记分牌何时在球弹跳后更新。
这两者经常被混为一谈,但它们是不同的数字。吞吐量由“最慢的一个阶段”决定,而延迟则是“所有阶段的总和 + 在队列中等待的时间”。30fps 的帧间隔 1000 ÷ 30 = 33.3ms 是吞吐量的预算,而不是延迟的上限。如果重叠执行各个阶段,即使延迟超过 33ms 也能达到 30fps;相反,即使延迟只有 10ms,如果队列堆积,用户看到的也是 1 秒前的结果。
2. 重叠阶段:吞吐量增加,延迟保持不变
如果按顺序执行 8ms 的预处理和 25ms 的推理,一帧需要 33ms,每秒可处理 30.3 张。如果在另一个线程中提前做好预处理(流水线化),GPU 就可以不间断地只进行推理,从而使每秒处理量达到 40 张。然而,单帧所经历的时间仍然是 8 + 25 = 33ms。
처리량 = 1 ÷ (가장 느린 단계의 시간)
지연 = 단계 시간의 합 + 줄에서 기다린 시간
리틀의 법칙: 처리 중인 프레임 수 = 처리량 × 지연 (40장/초 × 0.033초 = 1.32장)
利特尔法则(排队论的基本公式)也可以反过来使用。如果吞吐量是固定的,但“当前正在处理或等待的帧数”增加,则意味着延迟也相应增加。
3. 拥堵时:排队等待还是直接丢弃
推理时间每次都会略有不同。如果平均为 25ms,通常在预算范围内,但如果平均值超过预算达到 36ms 会发生什么呢?我们模拟了 60 秒的 30fps 相机场景(code/01_latency_queue.out.txt,推理时间呈对数正态分布,数字为说明性质的假设)。
| 推理平均值 | 规则 | 处理 fps | 丢弃的帧数 | 延迟中位数 · p99 | 60秒后的最后一帧延迟 |
|---|---|---|---|---|---|
| 25ms | 排队等待 | 30.0 | 0% | 24.6 · 44.1ms | 21.3ms |
| 25ms | 仅最新 | 30.0 | 0% | 24.6 · 44.1ms | 21.3ms |
| 36ms | 排队等待 | 27.9 | 0% | 2,068.7 · 4,465.7ms | 4,500.7ms |
| 36ms | 仅最新 | 27.4 | 8.6% | 48.0 · 82.3ms | 75.9ms |
在预算范围内,这两种规则表现相同。一旦超出预算, 排队等待几乎能维持吞吐量,但延迟会无限累积(1 分钟后屏幕画面会延迟 4.5 秒)。“仅最新”策略则会在处理器空闲的瞬间只抓取最新的一帧,并丢弃积压的旧帧。虽然会丢弃 8.6% 的帧,但延迟得到了控制。在实时视频中,几秒钟前的帧结果毫无用处,因此选择丢弃是正确的。TT Score 的实时工作线程和浏览器也是这样做的(第 8 篇)。
4. 迟到的正确答案等于错误答案:Streaming Perception
Li、Wang 和 Ramanan 的论文《Towards Streaming Perception》(ECCV 2020)将这一理念转化为了一种评估方法。通常的检测准确率(AP)假设世界会等待模型。这篇论文中的 streaming AP 会将时间 t 的标准答案与“在 t 之前 完成计算 的最近一次输出”进行比较。由于延迟产生的输出与已经运动的世界进行对比,分数自然会下降。
| 检测器(自动驾驶视频 30fps,1920×1200) | 单帧 | AP |
|---|---|---|
| HTC(准确但缓慢),常规评估 | 700.5ms | 38.0 |
| 同款模型,streaming 评估 | 700.5ms | 6.2 |
| RetinaNet(最快),0.2倍输入 | 31–36ms | 5.5–6.0 |
| Mask R-CNN,0.5倍输入,GPU 预处理 | 56.7ms | 12.0 |
| + 调度调整(偶尔休息) | 56.7ms | 13.0 |
| + 卡尔曼预测,以 0.75 倍输入重新选择 | 92.7ms | 17.8 |
(论文表 1·2,2017 年消费级高端 GPU 一张。)这里可以看出三点:
- 准确但缓慢的模型在实时场景下会崩溃(38.0 → 6.2)。
- 但这并不意味着速度最快的模型就能获胜。介于两者之间的某个平衡点才是最优的。
- 如果加入预测(在延迟期间将物体按移动距离向前推进),更慢但更准确的模型就会重新获胜。如果无法“缩短”延迟,就可以通过“补偿”来弥补。
“调度调整”很有意思。如果预计下一帧很快就会到来,它就不会开始处理当前帧并选择等待。因为这总比为了抓着旧帧不放而错过新帧要好。这与第 3 节的“仅最新”理念如出一辙。
5. 我们的实测:寻找球的一帧的生命周期
我们在服务器端按阶段测量了 TT Score 的实时处理路径。我们将实际比赛画面的单帧(将 1920×1080 缩小为相机尺寸 1280×720)循环运行了 300 次。手机端所做的工作(缩放、编码)也在同一服务器 CPU 上进行了模拟。
| 阶段 | 运行位置 | 中位数 | p90 |
|---|---|---|---|
| 1280×720 → 512×288 缩放 | 手机(用服务器 CPU 模拟) | 0.27ms | 0.30ms |
| JPEG 编码(质量 70) | 手机(用服务器 CPU 模拟) | 0.30ms | 0.31ms |
| (传输:JPEG 中位数 12,252 字节) | 互联网 | 未测量 | 未测量 |
| JPEG 解码 | 服务器 CPU | 0.31ms | 0.32ms |
| BGR → RGB,0–1 归一化,减去均值与标准差 | 服务器 CPU | 1.35ms | 1.38ms |
| 3 帧窗口堆叠 + 传输至 GPU | CPU → GPU | 1.76ms | 1.86ms |
| 球模型推理(FP32,生产模式) | GPU | 15.17ms | 15.19ms |
| (同款推理使用 FP16) | GPU | 9.98ms | 10.03ms |
| sigmoid + 将热力图传回 CPU | GPU → CPU | 0.18ms | 0.20ms |
| 寻找球的轮廓 | 服务器 CPU | 0.07ms | 0.07ms |
在服务器端,处理一帧花费的时间约为 19ms(FP32),其中推理占了 80%。在剩下的部分中,耗时较长的不是解码,而是 归一化(1.35ms)和传输至 GPU(1.76ms) 。如果将 512×288×3 转换为 float32,单张图片大小为 1.77MB,如果是三张窗口帧则每次需要创建并传输 5.3MB。如果直接以 uint8 发送到 GPU并在 GPU 上进行归一化,传输量将减少到四分之一,且归一化也由 GPU 完成。目前尚未进行此项修改,其实际效果尚未测量。
该表格中未包含手机端的相机捕获与实际编码、互联网往返、Web 服务器转发以及屏幕渲染。这部分内容将在第 8 篇中结合实际浏览器的测试端到端数值一并总结。
6. 阅读数字的习惯
- 同时观察中位数和长尾数据。 用户感受到的“卡顿”通常是由 p99 这一端引起的。在第 3 节中,即使在预算范围内,p99 达到了 44ms,也超出了预算。
- 将运行条件一并考虑。 “推理 10ms”会根据运行的 GPU、批处理大小以及是否有其他任务同时运行而产生最多达 3 倍的差异(第 6 篇)。
- 以预热后的数据为准。 GPU 的首次运行由于需要选择内核和分配内存,长达数秒。本系列的所有测量均采用预热后的重复运行中位数。
7. 局限性
- 第 3 节的模拟仅针对单个推理阶段,且时间分布属于假设。实际系统包含多个阶段,且每个阶段都有队列。
- 第 5 节仅测量了服务器端。手机 CPU 进行相同的缩放和编码需要多长时间尚未测量。
- 关于人类从多大程度的延迟开始觉得“迟缓”的第一手资料,由于这次未能查阅原文而未被引用。
8. 与我们项目的联系
- 在乒乓球运动中,“迟到的正确答案”意味着记分牌在下一个回合开始后才发生变化。TT Score 的目标是将判定时间控制在回合结束后的 1.5 秒内,并正在对此进行测量(第 8 篇)。
- 如果浏览器有 3 张帧没有收到回答,就会暂停发送,而工作线程会用新窗口覆盖积压的窗口。这相当于在两端都应用了第 3 节的“仅最新”策略。
- 本系列的后续文章将介绍如何缩减表格中占用空间最大的部分(推理)。包括精度(第 2 篇)、编译器(第 3 篇)、小型模型(第 4 篇)、降低运行频率(第 5 篇)、多任务共享(第 6 篇)以及在手机上运行(第 7 篇)。
Tt 的小贴士。 如果在球弹跳 4 秒后才大喊“界内!”,那无论多么准确,我都已经开始打下一个球了。迟到的正确答案就是错误答案!
参考文献
- Li, M., Wang, Y.-X., Ramanan, D. (2020). Towards Streaming Perception. ECCV 2020. https://arxiv.org/abs/2005.10420
- 我们的测量:本系列的实测(原始数据为仓库外部的研究记录),仓库
docs/tt/PERFORMANCE.md第 4 节 - 示例代码与输出:此文件夹的
code/01_latency_queue.py,code/01_latency_queue.out.txt