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 定位根因,优化验证闭环。

金融推理性能四层诊断模型 从业务约束到优化验证的完整证据链 ① 业务指标层 SLA 定义:P99 延迟、吞吐、错误率、成本上限、合规审计要求 约束 ② 系统基准层 端到端延迟、吞吐、抖动、资源利用率、并发梯度、输入分布 现象 ③ 运行时剖析层 算子耗时、kernel 占用、内存拷贝、通信等待、调度空转、GC 根因 ④ 优化验证层 量化、融合、批处理、缓存、并行、硬件适配、回归基准 闭环 回归反馈

方法流程:一次标准诊断怎么做

下面给出一个可落地的最小流程。它不依赖特定框架,CPU、GPU、NPU 均可套用。

  1. 明确目标:写清业务 SLA,例如“单条风控推理 P99 ≤ 20ms,QPS ≥ 2000”。
  2. 固定变量:锁定模型版本、权重精度、输入长度分布、批大小、并发数、硬件型号和驱动版本。
  3. 采集基准:先跑空载和单请求,再按并发梯度逐步加压,记录 P50/P95/P99、吞吐和资源曲线。
  4. 开启 Profiler:在代表性负载下采集 trace,避免只采空载或极端过载。
  5. 归因排序:按耗时占比排序,区分计算瓶颈、内存瓶颈、通信瓶颈和调度瓶颈。
  6. 实施优化:一次只改一个变量,保留对照。
  7. 回归验证:重跑同一基准,确认指标改善且无正确性回退。

一个典型的基准命令可能如下,重点在于参数可复现:

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.profilertrace 与热点排序
优化验证层优化前后差值、正确性校验回归基准、单元测试优化记录与回滚方案

误区与复盘:新手最容易踩的五个坑

  • 只看平均值:金融场景尾部延迟决定用户体验和风控时效,必须看 P95/P99。
  • 基准不可复现:输入长度、并发、预热次数不一致,结果没有可比性。
  • 在空载下做 Profiler:空载看不到排队、锁竞争和批处理收益,必须在代表性负载下采集。
  • 一次改多个变量:无法判断收益来自哪里,也无法回滚。
  • 忽略正确性:量化或融合后精度下降,可能让风控误判,性能优化必须伴随正确性验证。

提醒:Profiler 本身有开销,采集时可能改变系统行为。应先用低开销采样定位大致方向,再对可疑模块做细粒度采集,并对比开启与关闭 Profiler 时的基准差异。

实战建议:把每一次诊断都写成“现象—证据—根因—动作—结果”五段式记录。这不仅是技术复盘,也是金融合规审计中证明系统可控的重要材料。