PyPTO 实验性运行时配置:set_runtime_options 精细化 Workspace 内存池调优指南
2026/9/19 19:03:51 网站建设 项目流程
  • 人工智能
  • 编译器
  • 模型编译
  • 高性能计算
  • 深度学习
  • CANN

【免费下载链接】pypto

PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。

项目地址:https://gitcode.com/cann/pypto
点击查看免费下载

导读

本文介绍 CANN PyPTO 提供的实验性运行时配置接口pypto.experimental.set_runtime_options,它把tile_fwk_config.json中运行时部分尚未稳定的参数(当前为stitch_function_num_per_pool)转化为可编程接口。通过该接口,开发者可以在算子编译前分别控制 Workspace 中三个子内存池(root_inner、assemble_outcast、exclusive_outcast)的容量,在“保证性能的前提下降低内存”与“优先内存的前提下提升并行度”两种典型场景下进行精细化调优。读完本文,你将掌握该接口的调用方式、参数校验规则、日志分析方法,以及一套可直接落地的两步调参流程。

产品支持情况

set_runtime_options及精细化 Workspace 模式在以下产品上受支持:

  • Ascend 950PR / Ascend 950DT:支持
  • Atlas A3 训练系列产品 / Atlas A3 推理系列产品:支持
  • Atlas A2 训练系列产品 / Atlas A2 推理系列产品:支持

功能说明:实验性运行时参数的编程化入口

PyPTO 的运行时参数集中维护在配置文件 tile_fwk_config.json 的"runtime"小节中,其中包含stitch_function_max_num(默认 128)、max_workspace_kb(默认 0)、stitch_function_num_per_pool(默认[0, 0, 0])等参数。这些参数中尚未稳定的一部分(例如精细化 Workspace 内存池控制)不会进入pypto.frontend.jit(runtime_options=...)的稳定参数表,而是通过实验性接口暴露给用户,后续新增的运行时实验特性也沿此通道扩展。

该接口的 Python 侧实现位于 python/pypto/experimental/runtime.py,并在 python/pypto/experimental/init.py 中导出:

from .runtime import get_runtime_options, set_runtime_options # noqa: F401

调用链上,set_runtime_options最终通过set_options(runtime_options=...)写入当前配置作用域(python/pypto/config.py 中set_options),其参数以runtime.前缀进入 C++ 侧配置。

函数原型

set_runtime_options( *, stitch_function_num_per_pool: Optional[list[int]] = None, )

该接口采用关键字参数(keyword-only),当前仅暴露一个参数。若不传入任何参数(或传入None),本次调用不产生任何配置变更;传入的合法参数会被打包进runtime_options字典后写入当前 scope。

参数说明

参数名输入/输出说明
stitch_function_num_per_pool输入用于分别控制 Workspace 中三个子内存池的容量大小,格式为[root_inner, assemble_outcast, exclusive_outcast]。配置的大小决定每个内存池可容纳的最大 stitch 构建 loop 迭代的数量。

各子内存池的含义如下:

池序号池名称典型承载对象
第 1 个元素root_inner算子执行过程中产生的 RootInner 中间结果(如循环内部的 matmul 结果)
第 2 个元素assemble_outcastAssemble outcast 型中间 Tensor
第 3 个元素exclusive_outcastExclusive outcast 型中间 Tensor

参数的详细规则:

  • 配置方法[0, 0, 0]表示关闭精细模式;任一元素非 0 即开启。开启后,某一维为 0 表示不为该子内存池预留容量。若算子存在该内存池对应类型的中间 Tensor,编译会因容量不足失败,此时该维至少需配为 1;仅当算子没有该类型 Tensor 时才可配 0。
  • 类型:list of int,固定 3 个元素。
  • 取值范围:每个元素 0~1024。
  • 默认值[0, 0, 0](关闭)。
  • 影响 Pass 范围:NA。

参数校验的源码实现

参数合法性在 python/pypto/experimental/runtime.py 的_validate_stitch_function_num_per_pool中强制校验:

def _validate_stitch_function_num_per_pool(value) -> List[int]: if not isinstance(value, (list, tuple)) or len(value) != 3: raise ValueError(...) if any(isinstance(x, bool) or not isinstance(x, int) or not 0 <= x <= 1024 for x in value): raise ValueError(...) return list(value)

即:必须是长度为 3 的 list 或 tuple;每个元素必须是[0, 1024]内的整数;bool被显式拒绝(因为boolint的子类)。校验失败抛出ValueError,异常信息包含Invalid stitch_function_num_per_pool字样。对应单元测试见 python/tests/ut/interface/test_config_options.py 中的test_runtime_option_stitch_function_num_per_pooltest_runtime_option_stitch_function_num_per_pool_invalid,后者覆盖了长度不足、长度超限、非列表、负数、越界、浮点、混入 bool 等非法输入。

C++ 侧同样在workspace_budget_calculator.cpp中对三个元素逐项校验(framework/src/machine/utils/dynamic/workspace_budget_calculator.cpp 中ValidateDepth调用),并提示“若当前程序确实需要该内存池,该值不能为 0”。

返回值说明

void:Set 方法无返回值。设置成功即生效(写入当前配置作用域,随本次编译生效)。

约束说明

  • 类型安全:须为长度为 3 的 list 或 tuple,元素为[0, 1024]内的整数,不能使用 bool。
  • 作用范围:不要在pypto.loop内或 kernel 内设置,应在算子编译(pypto.frontend.jit或函数定义)之前设置。
  • 配置项相对关系
    • stitch_function_max_num:在不考虑内存占用、只考虑调优性能时使用;
    • max_workspace_kb:在有内存限制时按内存总量压缩内存使用,可能降低并行度;
    • 精细化配置(stitch_function_num_per_pool)在上述两项之后使用,按三个子内存池分别设置;开启后stitch_function_max_nummax_workspace_kb均失效

调用示例

最简单的启用方式:

pypto.experimental.set_runtime_options(stitch_function_num_per_pool=[64, 1, 1])

对应的读取接口(同文件提供,便于回读与自测):

pypto.get_runtime_options() # 返回 {'stitch_function_num_per_pool': [64, 1, 1], ...}

get_runtime_options从当前 scope 读取全部 runtime 选项(python/pypto/experimental/runtime.py),单元测试test_runtime_option_stitch_function_num_per_pool验证了默认值[0, 0, 0]、设置后回读一致、以及reset_options()后恢复默认的行为。

示例 1:精细 Workspace 模式

以下示例用来说明默认模式与精细控制的差异。示例包含三个 loop:Loop0 做 Exclusive write、Loop1 做 Assemble write、Loop2 做 Read:

B_STATIC, L_STATIC, H_STATIC, D_STATIC = 1, 64, 1, 16 pypto.experimental.set_runtime_options(stitch_function_num_per_pool=[64, 1, 1]) @pypto.frontend.jit def k_tmp_to_d_emb( dy: pypto.Tensor([B_STATIC, L_STATIC, H_STATIC, D_STATIC], pypto.DT_FP32), weight: pypto.Tensor([H_STATIC, D_STATIC, D_STATIC], pypto.DT_FP32), output1: pypto.Tensor([B_STATIC, L_STATIC, D_STATIC], pypto.DT_FP32), output2: pypto.Tensor([B_STATIC, L_STATIC, D_STATIC], pypto.DT_FP32), ): tmp_assemble = pypto.tensor([B_STATIC, L_STATIC, H_STATIC, D_STATIC], output1.dtype, "tmp_assemble") tmp_exclusive = pypto.tensor([B_STATIC, L_STATIC, H_STATIC, D_STATIC], output2.dtype, "tmp_exclusive") # Loop0:Exclusive write for i_idx, t in pypto.loop_unroll(0, 1, 1, name="l_loop_0"): pypto.set_vec_tile_shapes(1, 64, 1, 256) tmp_exclusive[:] = pypto.add(dy, dy) # Loop1:Assemble write for j_idx, t in pypto.loop_unroll(0, L_STATIC, 1, name="l_loop_1"): pypto.set_vec_tile_shapes(1, 64, 1, 256) dy_v = dy[0, j_idx : j_idx + t, 0] pypto.set_cube_tile_shapes([128, 128], [128, 128], [128, 128]) dx = pypto.matmul(dy_v, weight[0], pypto.DT_FP32, b_trans=True) pypto.set_vec_tile_shapes(1, 64, 1, 512) tmp_assemble[0, j_idx : j_idx + t, 0] = dx + 0.0 # Loop2:Read for k_idx, t in pypto.loop_unroll(0, L_STATIC, 1, name="l_loop_2"): pypto.set_vec_tile_shapes(1, 64, 1, 512) output1[0, k_idx : k_idx + t] = tmp_assemble[0, k_idx : k_idx + t, 0] output2[0, k_idx : k_idx + t] = tmp_exclusive[0, k_idx : k_idx + t, 0]

该示例中 tensor 的内存分布如下:

Tensor数据归属
dy、weight、output1、output2输入参数,不进 Workspace 内存池
dy_vdy 的切片视图,复用同一块内存
dxRootInner
tmp_assembleAssemble outcast
tmp_exclusiveExclusive outcast

stitch_function_num_per_pool配置为非全零后,三个子内存池可容纳的 stitch 构建的 loop 数量相互独立,可分别按实际需求设置。对本示例,运行时根据实际占用得到的推荐配置为[64, 1, 1],说明如下:

  • root_inner:由默认的 128 下调为 64。dx只存在于 loop1 的单次循环内,无需为 loop0、loop2 预留容量。
  • assemble_outcast:由默认的 128 下调为 1。tmp_assemble在循环外创建,多次循环共享同一块内存。
  • exclusive_outcast:由默认的 128 下调为 1。tmp_exclusive仅在 loop0 的一次循环中产生。

经过上述设置,在并行度基本不变的前提下降低 workspace 占用。

调优方法

精细模式的价值在于“有的放矢”,因此调优的第一步是采集运行时日志,观察每个内存池的真实占用,再针对性地修改配置。

采集日志

开启 INFO 级日志并将日志输出到指定目录:

export ASCEND_PROCESS_LOG_PATH=./wk export ASCEND_GLOBAL_LOG_LEVEL=1 python your_test.py

运行结束后,用 grep 过滤 Workspace 相关日志:

grep -rE "\[Workspace Runtime (Pool|Tuning|Summary|Recommendation)\]" ./wk

日志标识及重点字段说明:

日志标识说明重点字段
[Workspace Runtime Pool]单次任务提交时各池实际使用currentpeakcapacity
[Workspace Runtime Tuning]单次任务提交的配置与推荐taskIdstitchCountconfiguredDepthsrecommendedDepths
[Workspace Runtime Summary]整次执行各池的最大实际占用与容量上限各池peakcapacity
[Workspace Runtime Recommendation]整次执行结束后的配置建议,以及某个内存池配置值加 1 时增加的内存recommendedDepthsrawPerParallelBytesnextDepthTotalBytes

其中recommendedDepths={rootInner, assembleOutcast, exclusive}按顺序对应stitch_function_num_per_pool的三个元素;actualDepths为当前各个内存池生效大小。

从源码看,这些日志由 Workspace 分配器在运行时产出:[Workspace Runtime Pool]记录每个并行单元各池的current/peak/capacity[Workspace Runtime Tuning]记录taskIdstitchCountconfiguredDepths/recommendedDepths(见 framework/src/machine/utils/dynamic/dev_workspace.cpp 中LogTuningUsage),其中recommendedDepths由实际峰值占用除以对应内存池的单位字节数向上取整得到。若内存不足,会出现[Workspace Runtime Alloc Failure]日志,表示并行度已被内存截断。

场景 1:并行度已满足预期,精细化控制以降低内存

目标:并行度已达到预期时,去掉已申请但并未使用的内存,降低 workspace,同时保持性能。

操作步骤:

  1. 仅使用stitch_function_max_num(或不设置,默认 128)将端到端性能调至目标,不要同时开启本配置或max_workspace_kb
  2. 按上文开启 INFO 日志并执行算子。若出现[Workspace Runtime Alloc Failure],说明并行度已被内存截断,须先增大stitch_function_max_num或改走场景 2。
  3. 读取[Workspace Runtime Recommendation]recommendedDepths,写入本配置。例如recommendedDepths={rootInner=64, assembleOutcast=1, exclusive=1}对应[64, 1, 1]
  4. 去掉配置stitch_function_max_num后复测:workspace 应下降,端到端耗时相对步骤 1 应基本持平。若性能下降,查看[Workspace Runtime Summary]中实际占用已接近容量上限的内存池,将该元素加 1 后重试。
  5. 覆盖算子实际使用的 shape 与执行路径,对各样本的recommendedDepths逐项取最大值后固化,再关闭 INFO 日志验收。

场景 2:优先内存,精细化控制以提升并行度

目标:在总内存存在使用限制时,精细控制子内存池大小,把内存用到真正限制 stitch 构建的 loop 数量的池上。

背景:max_workspace_kb按同一规模压缩三个子内存池,其推荐值反映的是当前内存限制下根据实际使用内存反推的并行度,不是内存充足时的最优并行度,不能保证内存被充分利用。内存未用满时,可按下面步骤提高并行度。

操作步骤:

  1. 使用max_workspace_kb(须大于提示的最小可运行值)。例如限额 200MB 时配置max_workspace_kb=200*1024
  2. 按上文采集日志。从[Workspace Runtime Summary]对比各池实际占用与容量上限,从[Workspace Runtime Recommendation]读取recommendedDepthsnextDepthTotalBytes
  3. recommendedDepths写入本配置作为起点,并取消max_workspace_kb
  4. 计算剩余内存:限额减去当前 workspace 占用。某个内存池的配置值再加 1,整次执行增加的字节数为nextDepthTotalBytes中对应项。
  5. 优先增加实际占用更接近容量上限、且nextDepthTotalBytes能被剩余内存覆盖的池(常见为第 1 个元素root_inner)。每次只将该元素加 1,复测端到端耗时与 workspace。
  6. 当再加 1 将超过限额,或耗时不再下降时停止。多 shape 时对各元素取最大值后固化。

示例:限额 200MB,实际峰值约 100MB,recommendedDepths={rootInner=32, assembleOutcast=1, exclusive=1}。剩余约 100MB 可用于提高root_inner,可增加的次数不超过剩余字节除以nextDepthTotalBytes.rootInner。提高后 workspace 上升、并行度变大;若出现[Workspace Runtime Alloc Failure]或性能回退,将该元素减回。

与配置文件的对应关系

stitch_function_num_per_pool的默认值与相邻运行时参数一同维护在 tile_fwk_config.json 的"runtime"小节:

"runtime": { "device_sched_mode": 0, "run_mode": 0, "stitch_function_max_num": 128, "max_workspace_kb": 0, "stitch_function_num_per_pool": [0, 0, 0], ... }

可以看到默认模式下 Workspace 各子内存池由stitch_function_max_num=128统一决定深度,而max_workspace_kb=0表示不限制总内存。调用set_runtime_options(stitch_function_num_per_pool=...)后,运行时配置覆盖该默认值:三个池深度彼此独立,且stitch_function_max_nummax_workspace_kb不再生效。这一“默认配置 → 编程覆盖”的关系也被单元测试所印证:reset_options()get_runtime_options()["stitch_function_num_per_pool"]恢复为[0, 0, 0](见 python/tests/ut/interface/test_config_options.py)。

使用建议与注意事项

  • 先采集、后配置:精细模式的价值依赖对真实占用分布的判断,务必先按“调优方法”一节采集[Workspace Runtime Recommendation]日志,再写入配置,避免凭经验盲目设置。
  • 区分三种配置的适用时机:性能优先用stitch_function_max_num,内存受限用max_workspace_kb,两者之后的精细化收尾用stitch_function_num_per_pool;三者不可同时作为生效手段,精细模式开启后前两者失效。
  • 为 0 的元素需要谨慎:只有当算子确定不产生该内存池对应类型的中间 Tensor 时,才可将该维配为 0,否则编译期会因容量不足失败,日志会给出明确提示。
  • 多 shape 取并集:算子覆盖多个 shape/执行路径时,按各样本recommendedDepths逐项取最大值后固化,确保所有路径可运行。
  • 实验性接口的稳定性:该接口面向尚未稳定的运行时特性,接口形态与语义可能在后续版本调整或移除,生产固化前建议关注版本发布说明。

相关文档

  • 接口文档原文:docs/zh/api/tensor_api/config/pypto-experimental-set_runtime_options.md
  • 接口实现:python/pypto/experimental/runtime.py
  • 配置管理:python/pypto/config.py
  • 运行时默认配置:framework/src/interface/configs/tile_fwk_config.json
  • 运行时 Workspace 分配与日志:framework/src/machine/utils/dynamic/dev_workspace.cpp
  • 内存池深度校验与预算计算:framework/src/machine/utils/dynamic/workspace_budget_calculator.cpp
  • 单元测试:python/tests/ut/interface/test_config_options.py
  • 人工智能
  • 编译器
  • 模型编译
  • 高性能计算
  • 深度学习
  • CANN

【免费下载链接】pypto

PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。

项目地址:https://gitcode.com/cann/pypto
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询