1. 课程导入
在金融业务中,推理性能从来不是“跑得快一点”这么简单。行情推送、风控决策、量化回测、智能投顾、反欺诈评分等场景,对延迟、吞吐、抖动和成本都有明确约束。一次推理延迟从 8ms 上升到 35ms,可能意味着报价错过、风控窗口失效,或者单位算力成本翻倍。因此,本课程的第一件事,不是直接调参,而是建立一套可度量、可定位、可复盘的性能工程方法:用基准测试量化系统能力,用 Profiler 找到真实瓶颈,再把优化动作落到可验证的指标上。
学习目标:从“感觉慢”到“证据链完整”
完成本章后,你应当能够回答四个问题:第一,金融推理场景下应该看哪些指标,为什么不能只看平均延迟;第二,如何设计一个可复现的基准测试,而不是用一次随机请求下结论;第三,Profiler 能提供哪些层次的证据,如何从 kernel、算子、内存、通信和调度中找到主因;第四,如何把诊断结论转化为优化方案,并用回归基准验证收益。简言之,目标是形成“指标定义—基准采集—瓶颈定位—优化验证”的闭环能力。
核心判断:没有基准,优化就没有方向;没有 Profiler,基准只能告诉你“慢”,不能告诉你“为什么慢”。两者缺一不可。
核心概念:金融推理性能的五个关键词
- 延迟(Latency):单次请求从进入到返回的耗时,金融场景常关注 P50、P95、P99,甚至 P999。均值会掩盖尾部抖动。
- 吞吐(Throughput):单位时间内完成的请求数或 数,决定单位算力能承载多少业务量。
- 抖动(Jitter):延迟分布的离散程度。行情高峰时,抖动往往比均值更致命。
- 基准(Benchmark):在固定模型、固定输入分布、固定硬件和固定并发下重复测量的结果,强调可复现和可对比。
- Profiler:采集 CPU、GPU、内存、通信、算子等运行时数据的工具链,用于把“慢”拆解为可归因的耗时片段。
这五个概念之间不是并列关系,而是层层递进:延迟和吞吐描述结果,抖动描述稳定性,基准保证结果可信,Profiler 解释结果成因。金融业务还额外强调合规与可审计,因此基准配置、Profiler 原始数据和优化前后对比都应保留记录。
整体框架:四层诊断模型
为了避免一上来就陷入工具细节,本课程采用四层框架。第一层是业务指标层,定义 SLA,例如“风控评分 P99 小于 20ms”。第二层是系统基准层,采集端到端延迟、吞吐、错误率和资源利用率。第三层是运行时剖析层,用 Profiler 观察算子耗时、kernel 占用、内存拷贝、通信等待和调度空转。第四层是优化验证层,针对主因实施量化、融合、批处理、缓存、并行或硬件适配,并回归基准。四层之间形成证据链:业务指标提出约束,基准暴露现象,Profiler 定位根因,优化验证闭环。
方法流程:一次标准诊断怎么做
下面给出一个可落地的最小流程。它不依赖特定框架,CPU、GPU、NPU 均可套用。
- 明确目标:写清业务 SLA,例如“单条风控推理 P99 ≤ 20ms,QPS ≥ 2000”。
- 固定变量:锁定模型版本、权重精度、输入长度分布、批大小、并发数、硬件型号和驱动版本。
- 采集基准:先跑空载和单请求,再按并发梯度逐步加压,记录 P50/P95/P99、吞吐和资源曲线。
- 开启 Profiler:在代表性负载下采集 trace,避免只采空载或极端过载。
- 归因排序:按耗时占比排序,区分计算瓶颈、内存瓶颈、通信瓶颈和调度瓶颈。
- 实施优化:一次只改一个变量,保留对照。
- 回归验证:重跑同一基准,确认指标改善且无正确性回退。
一个典型的基准命令可能如下,重点在于参数可复现:
python benchmark.py \
--model risk_score_v3 \
--precision fp16 \
--batch-size 8 \
--concurrency 32 \
--input-len 128 \
--warmup 200 \
--repeat 2000 \
--report p50,p95,p99,throughput,gpu_mem
Profiler 采集时,建议同时保留时间线和汇总表:
nsys profile -o risk_v3_profile \
--trace cuda,nvtx,osrt \
python serve.py --config risk_v3_fp16.yaml
# 关注输出中的关键片段
# CUDA HW: kernel 执行、内存拷贝、流同步
# NVTX: 预处理、推理、后处理、风控规则
# OSRT: 线程调度、锁等待、GC 暂停
案例场景:风控评分 P99 超标
某风控评分服务在压测中 P50 为 9ms,但 P99 达到 48ms,远超 20ms 的 SLA。团队最初怀疑模型太大,准备直接换小模型。但基准数据显示 GPU 利用率仅 35%,显存拷贝时间占比却很高。进一步用 Profiler 观察发现,每次请求都在做一次同步的 host-to-device 拷贝,且后处理中的规则引擎持有全局锁,导致高并发下线程排队。真正的主因不是模型算力,而是数据搬运和锁竞争。优化动作包括:将输入预处理改为异步流水线、合并小拷贝、把规则引擎改为无锁读缓存。回归后 P99 降到 17ms,GPU 利用率升到 62%。这个案例说明:没有 Profiler,很容易把系统问题误判为模型问题。
| 诊断层次 | 典型指标 | 常见工具 | 输出物 |
|---|---|---|---|
| 业务指标层 | P99、QPS、错误率、成本 | 压测平台、监控看板 | SLA 定义与验收标准 |
| 系统基准层 | 延迟分布、吞吐、资源利用率 | benchmark 脚本、wrk、locust | 基准报告与对照表 |
| 运行时剖析层 | 算子耗时、kernel、拷贝、锁等待 | nsys、perf、py-spy、torch.profiler | trace 与热点排序 |
| 优化验证层 | 优化前后差值、正确性校验 | 回归基准、单元测试 | 优化记录与回滚方案 |
误区与复盘:新手最容易踩的五个坑
- 只看平均值:金融场景尾部延迟决定用户体验和风控时效,必须看 P95/P99。
- 基准不可复现:输入长度、并发、预热次数不一致,结果没有可比性。
- 在空载下做 Profiler:空载看不到排队、锁竞争和批处理收益,必须在代表性负载下采集。
- 一次改多个变量:无法判断收益来自哪里,也无法回滚。
- 忽略正确性:量化或融合后精度下降,可能让风控误判,性能优化必须伴随正确性验证。
提醒:Profiler 本身有开销,采集时可能改变系统行为。应先用低开销采样定位大致方向,再对可疑模块做细粒度采集,并对比开启与关闭 Profiler 时的基准差异。
实战建议:把每一次诊断都写成“现象—证据—根因—动作—结果”五段式记录。这不仅是技术复盘,也是金融合规审计中证明系统可控的重要材料。