尧图精选

PyPTO-Gym 中 movedim 算子的 PyPTO 实现:view 取片 + assemble 拼回的轴搬运 kernel 骨架解析

🕒 发布时间:2026/9/19 11:04:54 📁 来源:尧图网络
PyPTO-Gym 中 movedim 算子的 PyPTO 实现view 取片 assemble 拼回的轴搬运 kernel 骨架解析【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址: https://gitcode.com/cann/pypto-gymmovedim 是 PyTorch 中用于调整张量维度的常用算子可将指定源维度移动move到目标位置等效于对维度序列做一次重排permute。本篇文章基于 PyPTO-Gym 仓库中 movedim kernel 参考骨架讲解在 PyPTO 编程框架下如何用「batch 轴 loop 搬运」的策略实现 movedim整个算子被归类为 metadata/搬运语义——由pypto.view取片、pypto.assemble拼回不包含任何逐元素计算。读完本文你将掌握 movedim 在 PyPTO 中的 API 映射关系movedim→permute、view/assemble组合的轴切分写法、占位符含义以及如何结合仓库中的生产级实现如 mla_prolog.py、sum_lstm.py理解并复用这一模式。1. movedim 算子语义为什么要按「搬运」而非「计算」来设计PyTorch 的torch.movedim(input, source, destination)将source维度的轴移动到destination位置其余维度的相对顺序保持不变。例如对 shape 为[B, S, D]的张量执行movedim(input, 0, 1)结果是 shape[S, B, D]。本质上movedim 的结果等价于先根据source/destination推导出完整的维度重排序列再执行permute。在 NPU 算子开发视角下movedim 属于形状/索引变换类算子它不修改元素值只改变数据在内存中的逻辑排列方式因此既没有浮点运算也没有归约或激活逻辑。PyPTO-Gym 的 API 探索 skill 将这类算子归类为 metadata/搬运语义并在 torch-pypto-op-mapping.md 中给出了明确的映射结论movedim→permute需把 source/destination 换算为完整 dims 序列movedim.md也就是说PyPTO 侧并没有一个直接叫movedim的接口正确做法是先把source/destination换算成完整的 dims 排列序列再通过维度搬运骨架view取片 assemble拼回实现。2. kernel 参考骨架全文与逐行解读movedim.md提供的是一个 kernel 参考骨架reference skeleton全文如下pypto.frontend.jit(runtime_options{run_mode: pypto.RunMode.NPU}) def movedim_kernel(in_tensor: pypto.Tensor(sl, pypto_dtype), out_tensor: pypto.Tensor(ol, pypto_dtype)): for i in pypto.loop(batch, namebatch, unroll_list[1]): a_s pypto.view(in_tensor, [1] inner, [i] [0] * len(inner)) pypto.set_vec_tile_shapes(1, *inner) pypto.assemble(a_s, [i] [0] * (len(ol) - 1), out_tensor)骨架共 7 行核心动作可拆解为 4 步行代码作用1pypto.frontend.jit(runtime_options{run_mode: pypto.RunMode.NPU})声明在 NPU 上编译执行的 kernel 入口2movedim_kernel(in_tensor, out_tensor)输入/输出张量签名shape 与 dtype 由占位符sl/ol/pypto_dtype决定3for i in pypto.loop(batch, ...)沿 batch 轴循环每次迭代搬运一个 batch 切片4a_s pypto.view(in_tensor, [1] inner, [i] [0] * len(inner))从输入取出第i个 batch 切片切片 shape 为[1] inner偏移为[i, 0, 0, ...]5pypto.set_vec_tile_shapes(1, *inner)声明 Vector 侧 tile shape单次迭代处理[1] inner大小的块6pypto.assemble(a_s, [i] [0] * (len(ol) - 1), out_tensor)把切片写回输出的对应偏移位置关键点在于循环体内部只有 view取片和 assemble拼回两个动作没有数学运算。这正是 batch 轴 loop 搬运 策略——把张量按 batch 轴切成一片片逐片从输入搬运到输出从而绕开对整张大张量一次性做维度重排的存储布局难题。2.1 占位符约定按照 examples 目录的占位符约定本骨架使用以下占位符使用时需按实际 shape 替换占位符含义示例sl输入 shape 列表[B, S, D]ol输出 shape 列表[S, B, D]movedim 后pypto_dtype元素 dtypepypto.DT_FP32、pypto.DT_BF16等batch被 loop 的外层轴长度通常为sl[0]Binner单次迭代处理的内层 shapesl[1:]即[S, D]最小可运行 setup 可参考 README 中的示例B, D 8, 128; sl, ol [B, D], [B, 1]; pypto_dtype pypto.DT_FP32; batch, inner, inner_out B, [D], [1]。注意 README 同时强调这些骨架不是标准模板loop 轴、unroll_list、tile shape、动态轴处理都需按实际 shape/dtype 与平台约束确定并调优且骨架未经逐一 NPU 编译验证。3. 核心 API 语义view、assemble 与 set_vec_tile_shapes3.1pypto.view取片slicingpypto.view(in_tensor, new_shape, offset)从源张量中以给定偏移取出 shape 为new_shape的连续子张量。骨架中[1] inner表示batch 维取 1 片 完整内层[i] [0] * len(inner)表示第 i 个 batch、内层偏移全 0。view支持可选的valid_shape参数用于动态 shape 场景例如 lightning_indexer_prolog_quant_impl.py 中pypto.view(q_norm_in, [t_tile, q_lora_rank], [t_idx, 0], valid_shape[t_tile, q_lora_rank])即为带 valid_shape 的取片写法。3.2pypto.assemble拼回scatter 到输出pypto.assemble(tile, output_offset, out_tensor)把 loop 中产生的 tile 写入输出张量的指定偏移。骨架中[i] [0] * (len(ol) - 1)表示写入输出的第i个 batch 位置。在仓库中assemble 常用于分块计算 聚合写回的生产实现例如mla_prolog.py 中pypto.assemble(k_nope_tile, [tIdx, 0, 0], k_nope_out)、pypto.assemble(value_tile, [tIdx, 0, 0], value_out)、pypto.assemble(k_pe_2d_tile, [tIdx, 0], k_pe_embed_out)——按 token 块索引tIdx将分块结果拼回完整输出sum_lstm.py 中pypto.assemble(c_new_tile_out, output_offset, c_out)与pypto.assemble(h_new_tile_out, output_offset, h_out)——LSTM 状态按 batch 偏移写回。可见view/assemble是一对取片—拼回的搬运原语是 PyPTO 中处理大张量分块搬运的标准组合。3.3pypto.set_vec_tile_shapes声明 Vector 侧 tile shapepypto.set_vec_tile_shapes(*shape)声明后续 Vector 操作每次处理的数据块形状。骨架中pypto.set_vec_tile_shapes(1, *inner)与view的切片 shape[1] inner保持一致使每个 tile 恰好覆盖一个 batch 切片。该 API 的约束为每维 0最多 4 维见 SKILL 的硬约束速查。由于 movedim 只做搬运、不涉及 matmul/Cube因此只需设置 Vector tile shape无需set_cube_tile_shapes——这与 SKILL.md 中仅逐元素/归约 → Vector 类型 → set_vec_tile_shapes的算子类型判断规则一致。4. 与 t / unbind / squeeze 等搬运类骨架的共性movedim 骨架与仓库中其他纯搬运语义的 kernel 参考骨架高度同构。例如 t.md对应t()transpose(input, 0, 1)与 unbind.mdviewreshape组合采用了完全相同的 7 行骨架结构Note 也同为 batch 轴 loop 搬运本算子为 metadata/搬运语义view 取片 assemble 拼回无逐元素计算。这类骨架的统一特征可归纳为无计算循环体内只有viewassemblebatch 轴 loop外层轴切块内层整块搬运unroll_list[1]控制 unroll 行为tile shape 与切片 shape 对齐set_vec_tile_shapes(1, *inner)严格匹配 view 的[1] inner。因此当你需要实现 movedim或 transpose/t/unbind 等同类 shape 变换时可以直接以该骨架为起点仅调整sl/ol/batch/inner的取值即可。5. 组合方案与策略选择何时用搬运骨架何时用其它方案PyPTO-Gym 的映射文档 torch-pypto-op-mapping.md 将形状变换类算子分为差异映射与组合方案两类差异映射movedim→permute需换算 dims 序列、t→transpose、squeeze→reshape/view、split/chunk→view切片组合方案unbind→viewreshape、stack→unsqueezeconcat、repeat→unsqueezeexpand_clonereshape等。movedim 之所以走batch 轴 loop 搬运而非直接调用某个单一 API是因为 PyPTO 层面没有movedim命名映射需要把source/destination换算为完整 dims 序列后用 permute 语义表达。值得注意的是仓库生产代码中确实存在pypto.transpose的用法例如 mla_prolog_quant_impl.py 中的x_trans pypto.transpose(x_view, 1, 2)说明当重排仅涉及两轴时直接用pypto.transpose也是可行的生产选择而骨架形式viewassemble 逐片搬运更适合需要显式控制分块粒度、避免整张张量一次性重排的场景。6. 实战把骨架落成一个可运行的 movedim kernel结合 examples/README.md 的最小可运行 setup一个具体的落地方案如下以[B, S, D]→ 移动 batch 轴到中间为例import pypto B, S, D 8, 64, 128 sl [B, S, D] # 输入 [B, S, D] ol [S, B, D] # movedim(0 - 1) 后的输出 [S, B, D] pypto_dtype pypto.DT_FP32 batch, inner B, [S, D] pypto.frontend.jit(runtime_options{run_mode: pypto.RunMode.NPU}) def movedim_kernel(in_tensor: pypto.Tensor(sl, pypto_dtype), out_tensor: pypto.Tensor(ol, pypto_dtype)): for i in pypto.loop(batch, namebatch, unroll_list[1]): a_s pypto.view(in_tensor, [1] inner, [i] [0] * len(inner)) pypto.set_vec_tile_shapes(1, *inner) pypto.assemble(a_s, [i] [0] * (len(ol) - 1), out_tensor)注意事项入口约束根据 SKILL 的硬约束速查from_torch入口要求非空 Tensor、contiguous内存连续dtype 支持 FP16/BF16/FP32/FP64/INT8/INT16/INT32/INT64/UINT8/UINT16/UINT32/UINT64/BOOLshape 上限张量总元素数须 ≤ INT32_MAX动态 shapeview/assemble这类搬运 API 支持动态轴可配合valid_shape若后续引入 matmul/归约类计算则需编译期 concrete shape动态轴须走 loop 切 tile 策略见 SKILL 中引用的 execution-constraints.md §5tile shape 维度set_vec_tile_shapes每维 0 且最多 4 维[1] inner展开后不得超过 4 维否则需进一步拆分 loop 层次。7. 在 pypto-api-explore 工作流中的定位movedim.md是 pypto-api-explore skill 中examples/目录下的 kernel 参考骨架之一。该 skill 的核心工作流是解析输入 → 公式分解 →本地映射优先先查 torch-pypto-op-mapping.md 与examples/op.md→ 并行 Explore 探索 → 生成 API_REPORT。当开发者需要为某个算子做 API 探索时若在映射表中命中movedim条目即可直接阅读本文讲解的骨架作为 kernel 参考再通过 Explore subagent 核实具体约束与生产实现。需要强调的是examples/下的骨架仅作API 用法参考不是 production 实现标准SKILL 明确要求当写法与 lint / 门禁冲突时以 lint 为准。同时按 examples/README.md 的 Note 约定每个骨架应以一句话说明切分方式loop 的轴、整块的轴及原因movedim 骨架的切分方式即为loop batch 轴内层整体搬运因为 movedim 属纯搬运语义、无计算逐 batch 搬运即可在保持逻辑重排的同时控制单次搬运的 tile 规模。8. 小结movedim 在 PyPTO 中的实现要点可归纳为三点一是语义定位为 metadata/搬运view 取片 assemble 拼回不含逐元素计算二是映射关系为movedim→permute需将source/destination换算为完整 dims 序列三是切分策略为 batch 轴 loop 搬运unroll_list[1]set_vec_tile_shapes(1, *inner)与切片 shape 严格对齐。该骨架与 t、unbind 等搬运类参考骨架同构可直接套用并替换占位符生产级实现中view/assemble的分块取片—偏移写回组合也在 mla_prolog.pyMLA prolog 按 token 块拼回 k/value 输出与 sum_lstm.pyLSTM 按 batch 偏移拼回状态等真实算子中得到验证可作为深入研读的对照实现。【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址: https://gitcode.com/cann/pypto-gym创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →