路径指标与优化目标
用 FLOPs、逻辑读写量和内存相关指标比较收缩序,并设置优化目标与切片大小限制。
本页目录
PathStats 的六项指标
PathStats 根据网络结构和收缩序计算工作量与张量大小,不需要数值数组。其中三项累计整条路径的计算与数据访问量,另外三项描述与内存需求相关的张量大小。
字段名中的 log10 和 log2 表示保存的是对数。例如,log10_flops=6 表示 次标量乘法,log2_max_size=20 表示最大结果包含 个元素。比较同一项指标时,可以直接比较对数值:值越小,对应的工作量或张量大小越小。
设第 个二元步骤的输入和结果为 、、, 表示张量元素数, 表示该步的标量乘法次数。
| 字段 | 定义 | 回答的问题 |
|---|---|---|
log10_flops |
整条路径的标量乘法次数 | |
log2_total_size |
全部结果的写出元素数 | |
log2_read_write |
整条路径的逻辑读写量 |
读写量按每步读取两个输入、写出一个结果计数;原始输入按完整数组大小计入。因此,写出量与读写量不是同一项,也都不是硬件实测内存流量。
log2_total_size 将各步结果的大小累计相加。前一步的结果在用完后可以释放,所以这个累计量并不表示这些张量需要同时保存在内存中;同时保留的大小由下面的峰值指标描述。
单步指标计数
本步 FLOPs 按参与二元收缩的 index 维度之积计数;结果大小是保留 index 的维度之积。完整路径指标采用对数表示,避免大型网络的线性计数溢出。
本步结果保留属于 output 的 index,以及仍被这两个输入以外的张量使用的 index;其余参与本步的 index 求和消去。
设 为本步输入张量 的不同 index 集合, 为 index 的维度,则
这个计数包含本步将被求和消去的 index。若执行器先做一元求和,实际运算步骤可能不同;这里统计的是给定二元收缩序的结构代价。复数标量乘法仍计为一次标量乘法,不折算成实数指令数。
三个内存相关指标
三项分别描述最大的结果张量、单步输入与结果的总大小、执行过程中同时保留的张量总大小。都以元素数计量,报告中保存其以 2 为底的对数。
| 指标 | 字段 | 计数范围 |
|---|---|---|
| 最大结果张量 | log2_max_size |
,包括最后的输出 |
| 最大单步大小 | log2_max_contraction_size |
|
| 峰值存活张量大小 | log2_peak_size |
, 为时刻 尚未释放的张量元素数之和 |
、 是经过一元求和和对角处理后的逻辑输入。峰值统计则计入完整输入;每步先计入新结果,再释放本步输入。
以上一页的三矩阵乘法为例,输入大小为 、、:
| 指标(元素数,不取对数) | ||
|---|---|---|
| 最大结果张量 | 10 | 15 |
| 最大单步大小 | 38 | 47 |
| 峰值存活张量大小 | 46 | 53 |
两条收缩序的输入总计都是 38 个元素。第一步分别产生 8 或 15 个元素,因此峰值为 或 。对于 ,最终输出的 10 个元素比第一步的 8 个更大,所以最大结果张量为 10。
将元素数乘以每个元素的字节数,可估算相应张量的数据大小。例如 46 个 float64 元素占 字节。这仍不等于进程 RSS 或显存占用:转置临时数组、内存分配器和后端工作区没有计入。
target_size 限制每个 slice 的二元收缩结果元素数;单张量网络另检查最终输出。因此,它限制的是 log2_max_size 所描述的中间张量大小。它不涵盖所有一元临时数组,不直接约束 log2_peak_size,也不等于 RSS 或显存。
如果数值执行同时并行多个 slice,总驻留内存可能明显高于单个 slice 的路径指标。评估内存时还要记录 dtype、线程数、并发 slice 数和实测 RSS。
用指标定义优化目标
路径指标描述计算量和中间张量大小;优化目标决定如何比较不同路径。PlannerObjective 用完整路径的 FLOPs 与逻辑读写量 计算目标值:
默认权重为 flops_weight=1、read_write_weight=64。报告中的 planner_objective_score_log2 保存 。
例如,两个候选的 分别为 和 。只比较 FLOPs 时,第一个候选较好;使用默认权重时,二者目标值分别为 7400 和 4400,第二个候选较好,因为它减少了逻辑读写量。各项指标保留这些具体差别,目标值则给出本次搜索采用的排序依据。
| 权重 | 目标标签 | 比较内容 |
|---|---|---|
| (1, 64) | flops_read_write | FLOPs 与逻辑读写量的加权和 |
| (1, 0) | total_flops | 只比较总 FLOPs |
| (0, 1) | total_read_write | 只比较总逻辑读写量 |
权重必须有限、非负,并且不能同时为 0。权重 64 是目标函数中的相对系数,不是字节数、缓存行大小或实测带宽。
在 Python 中指定权重
from arctn import arctn_schedule
# 只按 FLOPs 优化;省略这两个权重参数时使用默认值 (1, 64)
report = arctn_schedule(
inputs, output, size_dict,
flops_weight=1.0, read_write_weight=0.0,
)
改变权重可能改变候选路径的排名、局部改进的接受结果和最终返回路径。
| 报告字段 | 含义 |
|---|---|
| planner_objective | 本次调用使用的目标标签;权重分别由 flops_weight 和 read_write_weight 字段报告 |
| planner_objective_score_log2 | 最终收缩序的加权目标值的 log2;启用切片时计入全部切片 |
| log10_flops / log2_read_write | 返回路径在未切片网络上的指标;启用切片后,全部切片的总量分别读取 sliced_log10_flops_total 和 planner_log2_read_write |
搜索中的目标函数
权重在寻路入口确定。各生成器可以采用不同的局部启发式,但完整候选、树改进和最终选择使用同一个 PlannerObjective。
局部启发式用于产生候选,不等于完整路径的目标值。例如,随机贪心的一步局部代价用于选择下一对张量,而多次搜索返回的完整路径仍按 比较。
优化目标与切片约束
优化目标用来比较方案的好坏,target_size 则规定单片结果的大小上限。一个方案即使 FLOPs 很低,只要不满足请求的大小限制,就不能作为满足约束的结果返回。搜索中使用的惩罚项不能替代最终的大小检查。
指定切片 index 后,切片数量等于这些 index 维度的乘积。ArcTN 按“单片工作量 × 切片数量”比较切片方案。使用以 2 为底的对数表示时,总目标值的对数等于单片目标值的对数加上 log2_n_slices。
是切片 index 集合。取对数后:
该结构模型计入各片的二元收缩,不包含跨片结果求和的额外加法。
log2_peak_size、log2_max_contraction_size 等指标仍会报告,但它们不是上述加权目标的组成项。切片限制的详细说明见切片与 target_size。
计算与比较路径指标
已有网络和 SSA path 时,用 simulate_path 校验路径并计算 PathStats,无需提供数值数组,也不重新搜索:
let stats = arctn::simulate_path(&net, &ssa_path)?;
println!("{:?}", stats);
跨方法或跨库比较时,应在相同网络和维度下,用同一套程序计算路径指标。各库对 FLOPs、读写量以及一元操作的统计方式可能不同;切片后的单片指标也不能直接与全部切片总量比较。测试数据的组成与用途见测试集。
空路径的报告值
单张量网络可以使用空路径,没有二元收缩步骤。此时,Rust 的 log10_flops、log2_total_size 和 log2_read_write 用负无穷表示对应工作量为零,log2_max_contraction_size 为 0;log2_max_size 取最终输出大小,log2_peak_size 仍计入完整输入。
Python 报告同样使用 -inf 表示空路径的零工作量,包括 log10_flops、log2_total_size、log2_read_write 和目标值;请求切片时,sliced_log10_flops_total 也为 -inf。这是零工作量取对数后的表示,不表示搜索或执行失败。