使用 Heavy 优化收缩序
调用 Heavy,读取收缩路径、目标值与耗时,并保存收缩序。
本页目录
请先完成快速开始中的张量网络输入,准备示例使用的网络结构、维度和数值数组。
运行 Heavy 并保留报告
安装包含 Light / Heavy 的完整 wheel 后,沿用快速开始中的网络,或提供自己的 inputs、output 和 size_dict。
将网络定义和下面的调用保存为 heavy_example.py,启动时设置线程数:
RAYON_NUM_THREADS=24 python heavy_example.py
取得返回结果
arctn_schedule 优化收缩序,不执行数值数组。返回的 report 是 Python 字典,包含路径、指标和可选切片信息。
from arctn import arctn_schedule
report = arctn_schedule(
inputs, output, size_dict,
preset="heavy", seed=17,
use_ssa=True,
)
path = report["path"]
print(report["log10_flops"])
print(report["log2_read_write"])
print(report["planner_objective_score_log2"])
Heavy 使用较大的搜索预算来寻找更好的路径。它仍是启发式搜索:返回的是本次运行已完成候选中的最佳结果,不保证局部最优、全局最优,也不保证每次都优于 Light。
读取返回结果
默认目标为 。比较相同网络、相同权重下的搜索结果时,读取 planner_objective_score_log2;只看 FLOPs 不能反映这一加权目标。
路径与目标字段
| 字段 | 含义 |
|---|---|
path、path_format |
最终路径与编码;默认 linear-v1,上例为 ssa-v1 |
planner_objective |
优化目标名称 |
flops_weight、read_write_weight |
本次调用的目标权重 |
planner_objective_score_log2 |
最终目标值以 2 为底的对数;有切片时计入全部切片 |
log10_flops、log2_read_write |
最终路径在未切片网络上的计算量与读写量,分别以 10 和 2 为底取对数 |
log2_max_size |
未切片路径的最大二元收缩结果元素数,以 2 为底的对数 |
log2_max_contraction_size |
未切片路径中,单步逻辑输入与结果元素数之和的最大值,以 2 为底的对数 |
log2_total_size、log2_peak_size |
未切片路径的总写出量与活跃元素峰值,以 2 为底的对数 |
wall_s |
Light / Heavy 编译库记录的搜索耗时,单位为秒;不包含随后执行数组的时间 |
path 中的整数表示张量编号,按 path_format 指定的格式读取;sliced_legs 中的整数则是 index 的内部编号。两种路径格式见收缩树与路径。
路径指标由网络结构和维度计算,不是实测的执行时间或进程内存。计算公式见路径指标与优化目标。
切片字段
上例未指定 target_size。需要限制单片中间张量大小时,按控制中间张量设置切片参数,再读取下列字段:
| 字段 | 含义 |
|---|---|
sliced_legs |
切片 index 的内部整数编号 |
log2_n_slices |
切片数量以 2 为底的对数 |
sliced_log10_flops_total |
全部切片的总 FLOPs,以 10 为底的对数 |
sliced_log2_max_size |
单片最大二元收缩结果元素数,以 2 为底的对数 |
planner_log2_read_write |
全部切片的总读写量,以 2 为底的对数 |
target_size |
请求的每片结果元素数上限 |
memory_constraint_metric |
大小约束的定义 |
max_intermediate_log2_elements_per_slice |
最终单片最大结果元素数,以 2 为底的对数 |
sliced_legs 列出切哪些 index,其长度不是切片数量。例如,一个维度为 4 的 index 对应 4 个 slice,此时 log2_n_slices 为 2。
未提供 target_size 时,sliced_legs 为空,log2_n_slices 为 0,部分 sliced_* 字段不返回,max_intermediate_log2_elements_per_slice 为 None。指定 target_size 也不一定需要切片;bool(report["sliced_legs"]) 表示是否实际选择了切片 index。
检查大小约束时使用单片大小,而不是未切片的 log2_max_size。比较总工作量时使用 sliced_log10_flops_total 和 planner_log2_read_write;planner_objective_score_log2 已按本次权重计算全部切片的目标值。
设置并行线程与读取耗时
上例只调用一次 Heavy。RAYON_NUM_THREADS=24 对应 3 个独立搜索起点,共享 24 个工作线程,不需要再写外层种子循环。seed=17 指定基础种子,其余种子由库派生。线程设置不表示预留了 24 个物理核;8、16、32 线程的对应关系见推荐线程配置。
读取搜索耗时:
print("搜索耗时(秒):", report["wall_s"])
内部候选列表、各阶段记录和独立起点报告不属于公开返回字段。若需要测量整次 Python 调用的耗时,可在调用前后使用 time.perf_counter();它与编译库记录的搜索耗时范围不同。
保存收缩序
已有 report 时,通过 ArcTNExecutionPlan.from_schedule 保存网络、SSA 收缩序与切片信息,不再次搜索:
from arctn import ArcTNExecutionPlan
plan = ArcTNExecutionPlan.from_schedule(
report, inputs=inputs, output=output, size_dict=size_dict,
)
plan.save("plan.json")