Profiling 正文
页面目标
这页把“怎么测”和“测出来之后怎么判断”分开讲,避免 profiling 只停留在采集数据。
适用人群
- 想先把性能问题定位清楚,再决定改代码的人。
- 正在看训练、推理或分布式 benchmark,但还不知道瓶颈在哪的人。
- 想把 profiling 结果和 benchmark、回归验证连起来的人。
不适用人群
- 只想找一个现成优化技巧,不关心问题归因的人。
- 还没有基本训练/推理流程概念的人。
- 只看单次结果,不打算做对照和验证的人。
你应该如何开始读
- 先读
17 -> 20 -> 13,把“测什么、怎么测、怎么看”立住。 - 如果你关心训练,接着看
2.5 -> 19 -> 32。 - 如果你关心多卡和通信,再接
2.8 -> 33 -> 34 -> 42。 - 最后回到
2.9,把 profiling 结论放进验证闭环。
故事线
一个最典型的 profiling 故事,是“任务没报错,但就是越来越慢”。最开始大家往往会盯着某个算子,觉得是实现问题;但把链路一拉开,往往会发现慢点分散在三个地方:训练步里有重算,显存峰值压住了 batch,多卡同步还在等通信。
第一步先跑 17 -> 20 -> 13,把时间热点和等待热点拆出来。 第二步再跑 2.5 -> 19 -> 32,确认是不是 activation 和 checkpointing 在拖慢训练。 第三步再跑 2.8 -> 33 -> 34 -> 42,确认并行收益是不是被通信吃掉。 最后把结果放回 2.9,比较优化前后是否真的更稳、更快。
这个故事的重点不是“图很多”,而是先定位,再归因,最后验证。
具体案例
案例 1:训练变慢,但看不出是哪一步慢
现象是:整体 step time 慢了,但单看训练日志看不出异常。
判断链路是:先看 17 -> 20 -> 13,把时间热点、单步热点和等待热点拆开;再看 2.5 -> 19 -> 32,确认是不是重算和 checkpointing 把训练拖慢。
常见结论是:
- 如果时间热点集中在少数 step,往往是局部算子或局部输入造成的。
- 如果重算比例升高,checkpointing 可能是在省显存,但在赔时间。
这个案例的重点是:先把“慢”拆成可解释的层,再决定是不是值得改。
案例 2:多卡 benchmark 不稳定
现象是:同一组多卡实验,结果波动大,有时看起来快,有时看起来不快。
判断链路是:先看 2.8 -> 33 -> 34 -> 42,把通信热点、同步等待和 benchmark 结果对上;再看 33 -> 34 -> 2.9,确认是不是验证口径不一致。
常见结论是:
- 如果同步等待占比高,波动通常会被放大。
- 如果 benchmark 口径不统一,优化前后对比就没有意义。
这个案例的重点是:profiling 不只是看热点,还要看实验设计是否足够稳。
案例 3:推理看起来慢,但根因不是 decode
现象是:大家第一反应是生成策略不够快,实际一查发现首 token 延迟更高。
判断链路是:先看 2.6 -> 20 -> 21 -> 22,把 attention 和 cache 先拆开;再看 22 -> 36 -> 41,确认是不是 cache 命中率和请求组织出了问题。
常见结论是:
- decode 慢不一定是采样慢,很多时候是 prefill 和缓存链路拖住了。
- 先把 request / cache / schedule 分开,再谈生成策略。
这个案例的重点是:profiling 的价值在于把“以为慢在 A”变成“实际上慢在 B”。
采集层
先把数据采对,再谈归因。采集层的目标不是“尽量多”,而是“足够解释问题”。
| 采集对象 | 你要回答什么 | 典型入口 |
|---|---|---|
| 时间 | 慢在哪一步、哪一层 | 17 -> 20 |
| 显存 | 哪类对象在占空间 | 18 -> 19 |
| 通信 | 同步和等待是否拖慢系统 | 42 -> 34 |
| 端到端 | 优化前后是否真的变化 | 33 -> 34 -> 2.9 |
归因层
采集完之后,不要马上改代码,先把问题归到能解释的层级上。
| 问题类型 | 先看什么 | 需要确认什么 |
|---|---|---|
compute | 17 -> 20 -> 13 | 是算子慢、层慢,还是流程慢 |
memory | 2.5 -> 19 -> 32 | 是 activation、重算,还是峰值误判 |
communication | 2.8 -> 33 -> 34 -> 42 | 是同步等待、气泡,还是 overlap 没生效 |
验证层
归因之后,必须回到实验验证。profiling 的价值最后要落到“能不能被重复证明”。
- 看
before / after是否有稳定差异。 - 看优化是否改变了
latency、throughput或peak memory。 - 看 benchmark 是否和线上请求分布一致。
- 看问题是否在后续回归里再次出现。
一页速记
| 层级 | 你主要关心什么 | 在本专题里怎么看 |
|---|---|---|
| 采集层 | 先把时间、显存和热点抓出来 | 先看 17 -> 20 -> 13 |
| 归因层 | 慢到底慢在 compute、memory 还是 communication | 再看 2.5 -> 19 -> 32 和 2.8 -> 33 -> 34 -> 42 |
| 验证层 | 改动后是不是确实变快了 | 最后回到 2.9 和 benchmark |
| 方法层 | 不是看图本身,而是定位到能动手的粒度 | 先测、再解释、最后验证 |
建议阅读顺序
- 先看
17 -> 20 -> 13,把时间、显存和瓶颈定位立住。 - 再看
2.5 -> 19 -> 32,观察训练侧显存和重算问题。 - 再看
2.8 -> 33 -> 34 -> 42,看分布式和通信瓶颈。 - 最后回到
2.9,把 profiling 结论收进项目验证闭环。
典型案例
系统慢了,但不知道慢在哪
最典型的 profiling 问题是“感觉慢,但说不清慢在哪里”。先看 17 -> 20 -> 13,把时间、显存和热点分出来;如果是训练场景,再看 2.5 -> 19 -> 32;如果是分布式场景,再看 2.8 -> 33 -> 34 -> 42。
结果看起来变好了,但不确定是不是真优化
有时候某次实验跑得更快了,但这不一定代表优化成立。要回到 33 -> 34 -> 2.9,确认是不是 benchmark 口径、请求分布或波动造成的假改善。
显存降了,但吞吐也掉了
这类问题不能只看峰值显存,要看 2.5 -> 19 -> 32 或 2.6 -> 22 -> 35 后,是否把 latency / throughput 也一起带坏了。profiling 的目标是把代价显式化,而不是把问题藏起来。
典型阅读链
- 如果你想先抓时间热点,先读
17 -> 20 -> 13。 - 如果你想先看显存和重算,先读
2.5 -> 19 -> 32。 - 如果你想先看通信和并行问题,先读
2.8 -> 33 -> 34 -> 42。 - 如果你想先确认优化是否成立,先读
33 -> 34 -> 2.9。
对照表
| 场景 | 先看什么 | 重点差异 |
|---|---|---|
| 训练慢 | 2.5 -> 19 -> 32 | 看 activation、重算和训练步耗时 |
| 推理慢 | 17 -> 20 -> 13 | 看 attention、cache 和单步热点 |
| 多卡慢 | 2.8 -> 33 -> 34 -> 42 | 看同步等待、通信和气泡 |
| 结果不稳 | 2.9 | 看单次波动、对照和验证口径 |
简单规则
- 先确认问题类型:compute、memory 还是 communication。
- 再看单步、单层还是全流程。
- 再决定要不要动代码。
常见错误
- 只采集数据,不做归因。
- 只看单次结果,不看波动和对照。
- 把 profiling 当成纯“找快慢”工具。
- 看到热点就改代码,没有先确认是不是系统级瓶颈。
FAQ
Profiling和Benchmark有什么区别?前者更偏诊断和归因,后者更偏结果验证;两者通常要一起用。- 这个专题是不是只管性能?不是,它也管显存、通信和调度的观测,只是最终都要回到性能判断。
- 为什么要先看
0E?因为它先把调试、显存和性能判断的基础观测习惯立起来。 - 如果只能做一次 profiling,优先看什么?优先看能解释主要瓶颈的指标,比如时间、显存或通信等待,而不是把所有日志都采一遍。
深入阅读
- 想看完整排障故事,去 Profiling 深入阅读。
- 想快速回顾摘要、清单和案例,继续留在本页即可。
相关专题
- 推理优化专题:当 profiling 指向 attention、decode 或 cache 时继续看这里。
- 通信与并行专题:当 profiling 指向同步、等待或 overlap 时继续看这里。
- 显存优化与性能调优专题:当 profiling 指向 activation、KV cache 或资源账本时继续看这里。
检查清单
- 先确认问题是
compute、memory还是communication。 - 再看瓶颈是集中在单步、单层,还是整个流程。
- 再看优化目标是降时延、提吞吐,还是省显存。
- 再回到
2.5 / 2.6 / 2.8 / 2.9,确认 profiling 结论能不能落到具体动作。 - 最后把方法和结果写成可复用的检查项,而不是一次性结论。
小结
Profiling 的核心不是“多看几张图”,而是“把问题定位到可以动手的粒度”。
