| name | external-cannbot-ops-pypto-op-perf-tune-tune-swimlane |
| description | PyPTO 算子深度性能调优技能。通过泳道图分析及调优性能,包括 Stitch 调优、TileShape 深度调优、合图调优、调度策略调优等。当用户需要进行深度性能调优、泳道图分析、Stitch 优化、合图优化时使用此技能。触发词:深度性能调优、泳道图分析、Stitch 调优、合图调优、调度优化。 |
| original-name | tune-swimlane |
| synced-from | https://gitcode.com/cann/cannbot-skills |
| synced-date | 2026-05-26 |
| synced-commit | ac5bbd2b4cf427d011874e11f8d1e8b1bef66eda |
| license | UNKNOWN |
PyPTO 算子深度性能调优
概述
深度性能调优通过泳道图分析及调优性能,采用 man-in-loop 的方式,通过获取并分析当前算子性能数据,针对性调整各性能配置参数,经过迭代调优逐步逼近最佳性能。
前置条件
- 完成开箱性能调优:先进行代码级优化
- 精度校验通过:确保算子计算正确
- 已采集性能数据:生成泳道图和气泡分析报告
泳道图分析
泳道图文件位置
泳道图数据文件位于 output/output_*/ 目录:
merged_swimlane.json - 泳道图数据文件
bubble_analysis.log - 气泡分析报告
查看泳道图
- 通过 PyPTO Toolkit 插件查看
- 或在 https://ui.perfetto.dev/ 上传泳道图文件
泳道图关键信息
- 任务的执行顺序和耗时信息
- 各核心的工作时间和等待时间
- 气泡(线程等待调度的时间)
- 任务依赖关系
调优方向
1. Stitch 调优
Stitch 配置决定了多少个 root function 被同时下发调度。
1.1 配置方法
@pypto.frontend.jit(
runtime_options={"stitch_function_max_num": 128}
)
1.2 参数影响
| 参数值 | 优点 | 缺点 |
|---|
| 过小(如 1) | - | 每个任务需同步,调度开销大 |
| 适中(如 128) | 泳道图紧凑,调度开销低 | - |
| 过大(如 512) | 泳道图更紧凑 | 调度耗时增加,workspace 增加 |
1.3 调优建议
在内存资源允许的前提下,逐步增大 Stitch 配置,结合泳道图和端到端总耗时数据调整参数。
2. TileShape 深度调优
2.1 Matmul TileShape 深度调优
主要关注减少重复载入和 K 轴分核两个调优手段。
pypto.set_cube_tile_shapes([128, 128], [64, 256], [256, 256],
enable_multi_data_load=True,
enable_split_k=True)
参数说明:
enable_multi_data_load:减少重复载入
enable_split_k:K 轴分核
2.2 Vector TileShape 深度调优
原则 1:下游 Vector Operation 的 TileShape 尽可能使用上游 Operation 的输出 TileShape
原则 2:根据泳道图上的子图大小和并行度调整
- 并行核数较少(<一半 Vector 核):减小 TileShape
- 子图耗时短、调度开销占比较高:增大 TileShape
原则 3:调整相邻 Cube 和 Vector Operation 的 TileShape,使依赖更简单
3. 合图调优
合图是指将计算图中多个逻辑上独立的 Operation 合并为一个逻辑子图。
3.1 深度方向合图
沿数据依赖路径将前后相邻的 Operation 进行融合。
手动指定合图方案:
pypto.set_pass_options(sg_set_scope=1)
pypto.set_pass_options(sg_set_scope=-1)
融合目标:
- 上下游 Operation 间传输数据量较大
- 多个 Operation 切分后变成并行的连通分支
注意:当前主要考虑在连续的 Vector 计算过程中使用,暂不支持将 Matmul Operation 与 Vector Operation 进行合图。
3.2 广度方向合图
针对计算图中处于同一层级、可并行执行的 Operation。
Matmul 广度方向合图:
- L1Reuse 策略(默认开启,用于合并具有冗余 L1 搬运的子图)
@pypto.frontend.jit(
pass_options={"cube_l1_reuse_setting": {-1: 2}}
)
@pypto.frontend.jit(
pass_options={"cube_l1_reuse_setting": {0: 8}}
)
@pypto.frontend.jit(
pass_options={"cube_l1_reuse_setting": {-1: 2, 0: 8}}
)
- CubeNBuffer 策略(用于合并同构的子图)
适用场景(不能使能 L1Reuse):
- Cube 子图间没有重复 L1 搬运
- K 轴很长且没有切 K
@pypto.frontend.jit(
pass_options={"cube_nbuffer_setting": {0: 8}}
)
Vector 广度方向合图:
@pypto.frontend.jit(
pass_options={"vec_nbuffer_setting": {0: 8}}
)
使用场景:泳道图内有同构子图组具有大量的小子图(耗时在 10u 以下)
4. 调度策略调优
当上下游子图之间依赖较为简单,或下游子图输入 Tensor 的 L2 命中率较为重要时,推荐使用 L2 亲和调度。
@pypto.jit(runtime_options={"device_sched_mode": 1})
注意事项:综合考虑 L2 复用与负载均衡的影响,不同场景的最佳配置策略不同。
性能优化建议库
建议 1:气泡率过高
症状:气泡率 > 10%
可能原因:
- 任务粒度过小
- 调度策略不当
- stitch 参数过小
优化建议:
-
Stitch 调优(优先级高)
@pypto.frontend.jit(
runtime_options={"stitch_function_max_num": 128}
)
-
Loop Unroll(优先级高)
for s2_idx in pypto.loop(s2_loop, unroll_list=[8, 4, 2, 1], name="LOOP_s2", idx_name="s2_idx"):
-
L1Reuse 优化
pypto.set_pass_options(cube_l1_reuse_setting={0: 8})
-
调整任务粒度
- 增大 loop 的 tile size
- 减少 loop 层级
建议 2:核心利用率低
症状:核心利用率 < 50%
可能原因:
优化建议:
-
L2 亲和调度
@pypto.jit(runtime_options={"device_sched_mode": 1})
-
调整 TileSize
pypto.set_cube_tile_shapes([128, 128], [128, 512], [128, 128])
-
启用 CubeNBuffer 合并同构子图
pypto.set_pass_options(cube_nbuffer_setting={0: 8})
建议 3:核心负载不均衡
症状:AicoreTime 差异 > 20%
可能原因:
优化建议:
-
调整任务分配策略
-
优化任务粒度
-
调整任务执行顺序
pypto.set_pass_options(sg_set_scope=1)
pypto.set_pass_options(sg_set_scope=-1)
调优流程
┌────────────────────────────────────────────────┐
│ 深度性能调优流程 │
├────────────────────────────────────────────────┤
│ │
│ 1. 采集泳道图数据 │
│ └─ debug_options={"runtime_debug_mode": 1} │
│ │
│ 2. 分析泳道图 │
│ ├─ 查看任务执行顺序 │
│ ├─ 识别气泡(等待调度时间) │
│ └─ 分析核心利用率 │
│ │
│ 3. 选择调优方向 │
│ ├─ 气泡率高 → Stitch/Loop Unroll │
│ ├─ 利用率低 → 调度策略/TileShape │
│ └─ 负载不均 → 合图优化 │
│ │
│ 4. 应用优化 │
│ └─ 每次只修改一个参数 │
│ │
│ 5. 验证 │
│ ├─ 重新编译运行 │
│ ├─ 检查精度 │
│ └─ 对比性能数据 │
│ │
│ 6. 迭代直到达到目标性能 │
│ │
└────────────────────────────────────────────────┘
常见问题
Q1: 泳道图文件在哪里?
A: 泳道图文件在 output/output_*/ 目录下,其中 * 是时间戳。
Q2: 如何查看性能统计?
A: 使用 PyPTO Toolkit 打开 merged_swimlane.json 文件,然后点击 "查看性能报告" 按钮。
Q3: 气泡是什么?
A: 气泡是指线程等待调度的时间,表示线程空闲的时间段。气泡率越低,说明调度效率越高。
Q4: 控制开销占比过高怎么办?
A: 对于小数据量,控制开销占比高是正常现象。可以通过增加数据规模来降低控制开销占比。
Q5: 如何选择合适的 Tilesize?
A:
- 对于 Cube 计算:推荐使用 [128, 128], [64, 256], [256, 256] 或 [256, 256], [64, 256], [128, 128]
- 对于 Vector 计算:推荐使用 [32, 512] 或 [64, 512]
- 需要根据具体场景(输入 shape、dtype、format 等)以及硬件平台进行综合考虑
参考资料