当前位置: 首页 > news >正文

CANN/pypto常见问题

常见问题

【免费下载链接】pyptoPyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。项目地址: https://gitcode.com/cann/pypto

kernel函数出参未写回导致计算不生效

问题现象描述

当前PyPTO框架用pypto.frontend.jit装饰的kernel函数,不支持有返回值,输出需要通过参数的形式传入并使用[:]等进行写回操作,如果直接使用等号赋值,无法将数据写入输出Tensor中。

示例代码:

@pypto.frontend.jit def add_kernel(x, y): pypto.set_vec_tile_shapes(4, 4) y = x + 1 # 此处会创建新的Tensor y torch.npu.set_device(0) x = torch.ones(4, 4, dtype=torch.float32) y = torch.empty(4, 4, dtype=torch.float32) add_kernel(pypto.from_torch(x), pypto.from_torch(y)) print(y) # 输出torch.empty创建的未经初始化的随机值

输出数据:

tensor([[2.0703e-19, 7.1833e+22, 1.8502e+28, 6.8608e+22], [4.8011e+30, 1.2123e+25, 4.7418e+30, 1.8465e+25], [1.2122e+25, 4.6114e+24, 1.7836e+31, 1.7591e+22], [1.1306e+24, 4.2245e-39, 6.8664e-44, 0.0000e+00]])

原因分析

在add_kernel函数内部执行y = x + 1时,这里的y是函数的局部变量(相当于创建了一个新的变量y),它会覆盖传入参数y的引用。也就是说,这行代码只是让函数内的y指向了x + 1的新Tensor,并不会修改外部传入的Tensor y的内容。

解决措施

通过全切片操作符[:],将计算结果写入函数参数y的原有内存空间

示例代码:

@pypto.frontend.jit def add_kernel(x, y): pypto.set_vec_tile_shapes(4, 4) y[:] = x + 1 # 将x+1的结果写入函数参数y的原有内存空间 torch.npu.set_device(0) x = torch.ones(4, 4, dtype=torch.float32) y = torch.empty(4, 4, dtype=torch.float32) add_kernel(pypto.from_torch(x), pypto.from_torch(y)) print(y) # 输出x + 1的结果

输出数据:

tensor([[2., 2., 2., 2.], [2., 2., 2., 2.], [2., 2., 2., 2.], [2., 2., 2., 2.]])

其中y[:] = x + 1也可以替换为y.move(x + 1)或者y.assemble(x + 1, [0, 0])

未设置执行算子的设备id

问题现象描述

在昇腾AI处理器上执行算子时,出现失败,报错信息如下。

2025-12-17 14:31:32.491 E | fail get device id, check if set device id 2025-12-17 14:31:32.492 E | RuntimeAgent::AllocDevAddr failed for size 20448 2025-12-17 14:31:32.493 E | RuntimeAgent::AllocDevAddr failed for size 20448 2025-12-17 14:31:32.493 E | aclmdlRICaptureGetInfo failed, return[100000]

可能原因

用户定义的算子未使用@jit进行装饰,且未使用torch_npu接口显式设置当前算子执行的Device ID。

处理步骤

在算子执行前设置Device ID,例如:

def test_onboard(): device_id = int(os.environ.get('TILE_FWK_DEVICE_ID', 0)) #从环境变量获取期望执行的device id torch.npu.set_device(device_id) #显式设置device id ....

CANN包不兼容

问题现象描述

算子上板执行时出现如下报错字样:

ErrorTracking callback in, task_id = 0, stream_id = 3. [ERROR] Exception Type: exception invalid error taskid: 0, streamid: 3, tid: 6495, deviceid: 0, retcode: 507018 kernelName = (null) ErrorTracking callback in, task_id = 1, stream_id = 3. [ERROR] Exception Type: exception invalid error taskid: 1, streamid: 3, tid: 6495, deviceid: 0, retcode: 507018 kernelName = (null)

且device日志中出现类似如下接口为空报错:

~/ascend/log/debug/device-0/device-6495_20251222194004973.log [ERROR] CCECPU(5670,aicpu_scheduler):2025-12-22-19:40:01.899.541 [ae_kernel_lib_aicpu_kfc.cpp:105][CallKernelApi][tid:5680][AICPU_PROCESSER] Get KFC DynTileFwkKernelServerInit api success, but func is nullptr: (null) [ERROR] CCECPU(5670,aicpu_scheduler):2025-12-22-19:40:01.902.745 [ae_kernel_lib_aicpu_kfc.cpp:105][CallKernelApi][tid:5681][AICPU_PROCESSER] Get KFC DynTileFwkKernelServer api success, but func is nullptr: (null)

原因分析

PyPTO驱动包支持25.2.0以上版本,CANN包支持8.5.0以上版本。

解决措施

可以查看驱动包安装目录下的version信息,如:

/usr/local/Ascend/driver/version.info Version=25.3.rc1 ascendhal_version=7.35.23 aicpu_version=1.0 tdt_version=1.0 log_version=1.0 prof_version=2.0 dvppkernels_version=1.1 tsfw_version=1.0 Innerversion=V100R001C23SPC002B212 compatible_version=[V100R001C19],[V100R001C20],[V100R001C21],[V100R001C22],[V100R001C23] compatible_version_fw=[7.0.0,8.9.9] package_version=25.3.rc1

同样可以查看CANN包安装目录下opp包内的version信息,如:

/usr/local/Ascend/ascend-toolkit/latest/opp/version.info Version=8.5.0.2.220 version_dir=8.5.0 timestamp=20251117_000024591 required_package_amct_acl_version="8.5"

按上述方法查看驱动包和CANN包是否满足版本要求,如不满足请升级对应版本。

TileShape与Tensor维度不匹配

问题现象描述

算子执行时出现如下报错:

2025-12-18 10:33:06.107 E | [ExpandFunction][Function][ERROR]: FUnction[TENSOR_b_loop_Unroll1_PATH0_hiddenfunc0] ExpandFunction failed: Tile shape size 1 is not matched the output shape size 2. 2025-12-18 10:33:06.107 E | Run pass [ExpandFunction] failed. 2025-12-18 10:33:06.107 E | Run pass <ExpandFunction> failed

可能原因

某个操作的TileShape设置的维度过小,小于该操作的输出Tensor的Shape维度,导致出现错误。

处理步骤

根据报错提示定位到相应的循环,如下所说,问题代码出现在b_loop循环中。

FUnction[TENSOR_b_loop_Unroll1_PATH0_hiddenfunc0]

找到对应的循环后,根据日志提示的错误维度以及代码逻辑,确定代码中TileShape的维度为1,而输出Shape的维度为2,将TileShape重新设置为2维即可。

view未传入valid_shape导致精度问题

问题现象描述

部分场景使用view时未传入valid_shape导致精度问题

问题原因

当view接口的输入tensor没有一个正确的validshape时,框架无法正确推导出输出的validshape。

处理步骤

当怀疑view部分的validshape推导有问题时,首先给view传入一个validshape,观察输出结果是否符合预期。

一个典型的需要传入validshape的场景:

当输入的validShape依赖别的tensor标识,必须传入dynValidShape。如下所示场景,q0的validshape curSeq来自于另外一个tensor,无法通过推导得到

# 输入 input [B, S, H] # 输入 act_seqs [B] # 输出 out [B, S, H] # 计算过程 AddS # 代码如下: for b_idx in pypto.loop(B, name="b_loop", idx_name="b"): cur_seq = act_seqs[b_idx] a0 = pypto.view(input, [1, S, H], [b_idx, 0, 0], valid_shape=[1, cur_seq, H]) a1 = a0 + 1.0 out[b_idx:, :, :] = a1

set_xxx_tile_shapes最后一维没有32字节对齐校验报错

问题现象描述

with pypto.function("TENSOR_SUM_FP32", [x], [res]): for _ in pypto.loop(1, name="LOOP_L0", idx_name="a_idx"): pypto.set_vec_tile_shapes(4, 8) res.move(x.sum())

通过pypto.set_xxx_tile_shapes设置TileShape大小最后一维需要32字节对齐,否则会校验报错。

C++ exception with description "ASSERTION FAILED: vecTile[lastDim] % alignNum == 0 Sum op: the tileShape of last axis need to 32Byte align!, func Sum, file reduction.cpp, line 374 libtile_fwk_interface.so(npu::tile_fwk::Sum(npu::tile_fwk::Tensor const&, int, bool)+0x620) [0xffff9ff2e090]

问题原因

硬件指令限制处理的数据需要32字节对齐。

处理步骤

通过pypto.set_xxx_tile_shapes设置TileShape大小需要将最后一维大小设置成32字节对齐的数,即TileShape[-1] * sizeof(dtype) % 32 == 0。

算子编译报堆栈溢出错误

问题现象描述

算子编译时出现类似如下报错字样:

error: stack frame size (*****) exceeds limit (32768) in function '*****'

在打屏日志中呈现样例如下:

error: stack frame size (47928) exceeds limit (32768) in function 'TENSOR_nLoop_Unroll1_PATH0_6_0_4503599627370496' error: stack frame size (47928) exceeds limit (32768) in function 'TENSOR_nLoop_Unroll1_PATH0_6_0_4503599627370496' 2 errors generated. terminate called after throwing an instance of 'npu::tile_fwk::Error' what(): ASSERTION FAILED: ret == 0 CompileCCE failed. errCode = 256, cce file: output/output_20251111_175724_806073/kernel_aicore/TENSOR_nLoop_Unroll1_PATH0_6_17699850674043372772_0_aic.cpp

原因分析

由于硬件限制,昇腾AI处理器核内的标量处理单元栈空间最大为32K。因此,在算子编译时,底层的毕昇编译器会对算子核内函数的栈使用情况进行分析和校验。如果函数实现较为复杂,例如变量较多或变量生命周期较长等因素,均可能影响分析结果。如果最终分析结果超出32K限制,毕昇编译器将拦截并报告该错误。

在PTO编程模型下,算子核内函数实现复杂的主要原因主要如下:

  • 子图规模较大,导致变量过多。
  • 子图计算逻辑复杂,导致变量的生命周期较长。

解决措施

针对上述可能的原因,可以采取以下措施进行处理:

  • 调整Tensor的Tiling切分策略,采用更大的Tile块进行切分。通过增加单个Tile块的计算数据量,在总数据量保持不变的情况下,可以减少子图所需的计算步骤,从而有效减小子图的规模。相关设置接口为:pypto.set_vec_tile_shapes和pypto.set_cube_tile_shapes。
  • 对于矩阵乘(MATMUL)计算场景,建议用户对K轴进行多核切分。
  • 修改控制子图大小的选项"cycle_upper_bound",将单个子图的最大规模限制在指定范围内。相关设置接口为:pypto.set_pass_options

循环中使用Python print函数打印

问题现象描述

@pypto.frontend.jit def add_kernel_0(a, b, c): for i in pypto.loop(20): print("i = ", i) c[:] = a + b >>> i = 0 @pypto.frontend.jit def add_kernel_1(a, b, c): for i in pypto.loop(20): print("i = ", i) if pypto.cond(i == 0): c[:] = a + b else: c[:] = a - b >>> i = 0 i = 1

可能原因

用户算子描述的是构图过程,而非实际的执行逻辑。在构图阶段,Loop执行仅用于遍历所有执行路径。示例代码add_kernel_0中仅有一条执行路径,因此Loop仅执行一次。add_kernel_1中存在if/else两条路径,因此Loop执行两次。

处理步骤

N/A

local Tensor 无 producer 时被读取触发device侧断言

问题现象描述

在算子编写过程中,如果 local Tensor 仅创建但未写入,就在 loop 内被读取,编译/执行到设备路径时可能触发设备侧断言或异常。典型报错如下:

ASSERTION FAILED: WORKSPACE_ITER_INVALID Root[...] incast ... slotIndex ... read from empty address.

该现象通常对应读取到的 slot 没有 producer,即 Tensor 对应 slot 未被任何 operation 写入。

最小示例(语义示意):

def kernel(x): t = pypto.tensor((1,), pypto.DT_FP32, "t") for i in range(n): _ = t[0]

可能原因

local Tensor(如t)仅被创建,但在被读取前没有任何写操作(如切片赋值、moveassemble或其他能建立 producer 的写入),导致读取路径访问到空地址并触发断言。

处理步骤

可采用以下任一方式规避:

  1. 在读取前先对 local Tensor 执行有效写入(例如切片赋值、moveassemble等),确保其存在 producer。
  2. 将该 local Tensor 写在 loop 内,作为 loop 内 Tensor 使用,使其在当前 loop 作用域内,pypto内存管理策略会为其申请内存地址

Loop 原理及其描述

在编译阶段会将loop编译为控制流,将loop body转换为计算流,分别对应kernel_aicpu/kernel_aicore. kernel_aicpu 负责控制流的执行,创建kernel_aicore任务,包括使用到的内存分配以及执行参数准备, 同时分析输入输出的依赖将kernel_aicore任务合并成一个更大的调度单元,然后提交给调度单元进行调度

原型介绍

def loop(start, end, step=1, name=None, idx_name=None, unroll_list = [1], submit_before_loop=False): def loop_roll(start, end, step=1, name=None, idx_name=None, unroll_list = [1], submit_before_loop=False):

描述

  1. start, end, step 分别可以表示循环的起始值、结束值和步长,类型可以为 SymbolicScalar 或者 int, 和Python中的range语法基本保持一致

  2. name 表示循环的名称,默认值为loop_{id}, 对实际使用运行效果无影响,仅用于调试和生成代码中注释信息

  3. idx_name 表示循环索引的名称,默认值为loop_idx_{id}, 对于嵌套累的Loop使用相同的idx会产生覆盖行为, 目前会在前端进行检查报错

  4. unroll_list 主要用于循环展开,产生更大的loop body, 降低调度开销。对于unroll_list=2, loop大概会产生如下代码

    new_start = start for k in unroll_list: left = (stop - start) % k for idx in loop(new_start, stop - left, k): for i in range(k): body(idx) # 需要用户一次处理step=1的步长 new_start = stop - left

    loop_unroll 大概会产生如下代码

    new_start = start for k in unroll_list: left = (stop - start) % k for idx in loop(new_start, stop - left, k): body(idx, k) # 需要用户一次处理k的步长 new_start = stop - left

    原则上如果可以一次处理多个i, 使用loop_unroll会更高效; 如果一次只能处理1个i, 则需要使用loop

  5. submit_before_loop 表示是否在循环开始前提交任务,默认值为False。如果设置为True,则循环前的任务会先提交到调度队列中,等待后续任务完成后再开始执行,过多的设置submit_before_loop会增加调度开销, 建议仅在必要时设置为True

  6. unroll_list 对pypto.cond影响, 通常一个循环中有一个pypto.cond, 会产生两个分支,当unroll次数为4次时,会产生 2 ** 4 16个路径分支,通常上每个分支都需要单独编译, 因此会大量增加编译时间和编译出的代码量. 为了支持关键算子FA的编译优化,提供了两个特殊的函数pypto.is_loop_begin()pypto.is_loop_end()用于优化条件分支

  7. 考虑到对外层loop进行loop_unroll不能提升loop body的大小, 当前仅支持最内侧循环进行unroll

  8. 为了写代码方便,可能有时看到前端算子并没有直接表达loop,是如何产生loop和loop body的呢. 实际是在构图阶段前端会隐式的在function开始的位置插入一个loop, 循环次数为1. 循环直到下一个循环开始前结束,举例如下

    @pypto.frontend.jit def foo(a, b, c): c[:] = a + b # 等价于 @pypto.frontend.jit def foo(a, b, c): for i in pypto.loop(1): c[:] = a + b @pypto.frontend.jit def foo(a, b, c): t = a + 1 for i in pypto.loop(1): c[:] = t + b # 等价于 @pypto.frontend.jit def foo(a, b, c): for i in pypto.loop(1): t = a + 1 for i in pypto.loop(1): c[:] = t + b

    框架当前不会自动进行loop(1)合并,因此在实际使用中,建议用户手动合并loop(1),以提高效率

【免费下载链接】pyptoPyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。项目地址: https://gitcode.com/cann/pypto

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

http://www.jsqmd.com/news/862108/

相关文章:

  • Win11 右键菜单缺少“新建文本文档“win11 某些软件中文乱码
  • 如何用SciencePlots快速制作专业科研图表:终极美化方案指南
  • 软件测试的职业规划与发展
  • linuxcnc开发环境搭建
  • DeepEval终极指南:如何用开源框架轻松评估AI模型质量
  • MVVMFramework网络请求自动缓存:提升iOS应用性能的3个秘诀
  • CANN/asc-devkit数据搬运API样例
  • 2026最权威一键生成论文工具榜单:这些被高校和导师偷偷推荐的软件你用了吗
  • gdb调试ros2程序
  • LangChain 是什么?从零开始学会 LangChain 的工程实践指南
  • 设计师私藏的11个纹理Prompt原子模块(仅限本周开放下载:含PBR贴图映射表+光照反射系数速查卡)
  • 2026年无添加微辣萝卜干深度厂家推荐 - 行业平台推荐
  • swift-doc与Swift Package Manager的完美结合实践:快速生成专业Swift文档
  • mlir 编译器学习笔记之六 -- 经典实现
  • ubuntu24 主题经验
  • 抖音内容本地化保存解决方案:批量下载与去水印工具实践
  • 谷歌关键词优化seo需要怎么做?避开这4个最掏钱的布词误区
  • 2026年最新一键生成论文工具全攻略(含免费额度说明)
  • 【Midjourney拟物化风格实战指南】:20年视觉设计专家亲授3大材质渲染公式与5步出图工作流
  • 新人结婚开封汴绣婚庆礼品推荐
  • C语言中的sizeof和strlen
  • 2026年评价高的榨菜芯/去皮榨菜优质厂家推荐榜 - 品牌宣传支持者
  • 【docker镜像加速器配置】
  • Spring AI Alibaba 1.x 系列【55】Interrupts 中断机制:静态中断源码分析
  • 升学赠礼推荐开封汴绣绣品
  • 2026年局域网考试系统选型对比:优考试助力政企信创与内网安全
  • 【RK3588-AI-004】RK3588 AI专属依赖环境预装(Python、OpenCV、基础编译工具)
  • 3分钟掌握gmpublisher:Garry‘s Mod工坊发布的终极解决方案
  • 数分-MySQL基础01
  • Allen-Bradley 280D-F12Z-10B-CR启动控制模块