使用 Heavy 优化收缩序

调用 Heavy,读取收缩路径、目标值与耗时,并保存收缩序。

本页目录

请先完成快速开始中的张量网络输入,准备示例使用的网络结构、维度和数值数组。

运行 Heavy 并保留报告

安装包含 Light / Heavy 的完整 wheel 后,沿用快速开始中的网络,或提供自己的 inputs、output 和 size_dict。

将网络定义和下面的调用保存为 heavy_example.py,启动时设置线程数:

bash
RAYON_NUM_THREADS=24 python heavy_example.py

取得返回结果

arctn_schedule 优化收缩序,不执行数值数组。返回的 report 是 Python 字典,包含路径、指标和可选切片信息。

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。

读取返回结果

默认目标为 F+64RF+64R。比较相同网络、相同权重下的搜索结果时,读取 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 线程的对应关系见推荐线程配置。

读取搜索耗时:

python
print("搜索耗时(秒):", report["wall_s"])

内部候选列表、各阶段记录和独立起点报告不属于公开返回字段。若需要测量整次 Python 调用的耗时,可在调用前后使用 time.perf_counter();它与编译库记录的搜索耗时范围不同。

保存收缩序

已有 report 时,通过 ArcTNExecutionPlan.from_schedule 保存网络、SSA 收缩序与切片信息,不再次搜索:

python
from arctn import ArcTNExecutionPlan

plan = ArcTNExecutionPlan.from_schedule(
    report, inputs=inputs, output=output, size_dict=size_dict,
)
plan.save("plan.json")

后续执行与复用

加载文件、执行收缩及更新数组的例子见保存与复用收缩序。若要将路径交给其他工具,见路径与保存形式。