news 2026/5/24 11:36:13

10分钟上手pypto:用Python直接调PTO虚拟指令集

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
10分钟上手pypto:用Python直接调PTO虚拟指令集

前言

想用PTO(昇腾虚拟指令集)做算子优化,但C++太难啃?想用Python直接调PTO的接口,又不知道从哪入手?pypto这个仓库就是为你准备的。

第一次接触pypto的时候,也被它的"Python直接调PTO"搞得很懵。明明PTO是C++接口,怎么Python就能直接调?是封装了一层,还是真的可以直接调?

带着这个疑问,翻了一遍pypto的源码,跑了几组测试,发现这事儿没那么简单。pypto不是简单的"封装一层C++接口",而是用pybind11做了Python-C++双向绑定,把PTO的C++ API直接映射成了Python API,让可以用Python写PTO代码,不用碰C++。

本文是手把手实战——会从环境准备讲起,一步步带你在昇腾NPU上用pypto调PTO虚拟指令集,跑通一个完整的"PTO加法"示例。

10分钟上手pypto:用Python直接调PTO虚拟指令集

pypto在CANN五层架构里的位置

先说清楚pypto住在哪。昇腾CANN的架构分五层,pypto住在第1层——昇腾计算语言层,具体是AscendCL的Python绑定。

第1层:昇腾计算语言层 AscendCL ← pypto 住在这 ├─ 应用开发接口(推理/预处理/单算子) ├─ 图开发接口(统一构图/多框架支持) └─ 算子开发接口 Ascend C └─ pypto(PTO的Python绑定)← 我们正在聊的 第2层:昇腾计算服务层 ├─ AOL 算子库 ├─ AOE 调优引擎 └─ Framework Adaptor 框架适配器 第3层:昇腾计算编译层 ├─ Graph Compiler 图编译器 └─ BiSheng / ATC 编译器 第4层:昇腾计算执行层 ├─ Runtime 运行时 ├─ Graph Executor 图执行器 ├─ HCCL 集合通信库 ├─ DVPP 数字视觉预处理 └─ AIPP AI 预处理 第5层:昇腾计算基础层 ├─ RMS/CMS/DMS/DRV ├─ SVM/VM/HDC └─ UTILITY 硬件层:昇腾 AI 硬件(达芬奇架构)

为啥住第1层?因为pypto是"算子开发接口",不是"算子库"。可以把它理解成"PTO的Python前端"——C++写PTO太难,Python写PTO就容易多了。

依赖关系

pypto → pto-isa → ge。pypto调用pto-isa的指令定义,pto-isa调用ge的图编译接口,最终生成NPU可执行的指令。

环境准备:10分钟搞定

要用pypto,得先装好以下环境:

1. 安装昇腾NPU驱动

去昇腾社区下载驱动,按官方教程装好。装完后,运行npu-smi info,看到NPU设备信息就OK。

# 验证驱动安装成功npu-smi info# 预期输出(示例)+-----------------------------------------------------------------------------+|NPC-SMI24.0.1 Driver Version:24.0.1||-------------------------------+----------------------+----------------------+|NPC NAME|BUS-ID TEMP|PWR UTIL MEM||0Ascend910|0000:00:0d.0 45C|75W80% 16384M|+-------------------------------+----------------------+----------------------+

⚠️ 踩坑预警:如果用的是Atlas A3服务器,驱动版本要≥25.0,不然pypto跑不起来。

2. 安装CANN Toolkit

去昇腾社区下载CANN Toolkit 8.0,按官方教程装好。装完后,设置环境变量。

# 设置环境变量(加到 ~/.bashrc 或 ~/.zshrc)exportASCEND_HOME=/usr/local/AscendexportPATH=$ASCEND_HOME/ascend-toolkit/latest/bin:$PATHexportLD_LIBRARY_PATH=$ASCEND_HOME/ascend-toolkit/latest/lib64:$LD_LIBRARY_PATH

验证CANN安装成功:

# 验证CANN安装成功atc--version# 预期输出(示例)ATC8.0.0 Copyright(C)2024Ascend

3. 安装pypto

pypto是Python包,用pip安装。

# 安装pyptopip3installpypto-ihttps://pypi.ascend.com/simple/# 验证安装成功python3-c"import pypto; print(pypto.__version__)"# 预期输出(示例)0.1.0

⚠️ 踩坑预警:如果用的是Python 3.11,pypto可能装不上,要用Python 3.9或3.10。

逐步推进:从"Hello PTO"到完整示例

环境装好了,现在一步步跑通pypto。

步骤1:初始化PTO上下文

用pypto之前,要先初始化PTO上下文(类似CUDA的cuda.init())。

importpypto# 初始化PTO上下文pypto.init()# 查看NPU设备数量device_count=pypto.get_device_count()print(f"NPU设备数量:{device_count}")# 预期输出(示例)# NPU设备数量: 1

代码讲解

  • pypto.init():初始化PTO上下文,加载PTO指令定义
  • pypto.get_device_count():获取NPU设备数量(类似torch.cuda.device_count()

步骤2:加载PTO指令

PTO指令是"虚拟指令",要先加载到NPU里,才能执行。

importpypto pypto.init()# 加载PTO指令(内置的add指令)add_insn=pypto.load_insn("add")# 加载add指令print(f"指令名:{add_insn.name}")print(f"指令ID:{add_insn.insn_id}")print(f"操作数个数:{add_insn.num_operands}")# 预期输出(示例)# 指令名: add# 指令ID: 0x1001# 操作数个数: 3

代码讲解

  • pypto.load_insn("add"):加载名为"add"的PTO指令
  • add_insn.name:指令名(字符串)
  • add_insn.insn_id:指令ID(整数,唯一标识)
  • add_insn.num_operands:操作数个数(add指令有3个操作数:2个输入,1个输出)

步骤3:执行PTO指令

加载完指令,就可以执行了。PTO指令的执行分三步:准备操作数设置指令参数执行指令

importpyptoimportnumpyasnp pypto.init()add_insn=pypto.load_insn("add")# 1. 准备操作数(2个输入,1个输出)a=np.array([1,2,3,4,5],dtype=np.float32)b=np.array([10,20,30,40,50],dtype=np.float32)c=np.zeros(5,dtype=np.float32)# 2. 设置指令参数add_insn.set_operand(0,a)# 输入0:aadd_insn.set_operand(1,b)# 输入1:badd_insn.set_operand(2,c)# 输出:c# 3. 执行指令add_insn.execute()print(f"结果:{c}")# 预期输出(示例)# 结果: [11. 22. 33. 44. 55.]

代码讲解

  • add_insn.set_operand(index, data):设置操作数(index=0是输入a,index=1是输入b,index=2是输出c)
  • add_insn.execute():执行指令(NPU上执行)
  • 结果c是NPU上算出来的,自动拷贝回CPU

⚠️ 踩坑预警:操作数的数据类型必须和指令定义的一致。add指令要求float32,如果传float64,会报错。

步骤4:获取执行结果

上一步已经拿到了结果c,但那是自动拷贝回CPU的。如果想在NPU上继续用这个结果,可以用pypto.Tensor

importpyptoimportnumpyasnp pypto.init()add_insn=pypto.load_insn("add")# 用pypto.Tensor在NPU上分配内存a=pypto.Tensor([1,2,3,4,5],dtype=pypto.float32)b=pypto.Tensor([10,20,30,40,50],dtype=pypto.float32)c=pypto.Tensor([0,0,0,0,0],dtype=pypto.float32)# 设置操作数(直接传pypto.Tensor)add_insn.set_operand(0,a)add_insn.set_operand(1,b)add_insn.set_operand(2,c)# 执行指令add_insn.execute()# 获取结果(NPU → CPU)c_cpu=c.numpy()print(f"结果:{c_cpu}")# 预期输出(示例)# 结果: [11. 22. 33. 44. 55.]

代码讲解

  • pypto.Tensor:在NPU上分配内存(类似torch.tensor().npu()
  • c.numpy():把NPU上的结果拷贝回CPU(类似x.cpu().numpy()

完整实战:用pypto写一个"PTO矩阵乘法"

理论讲完了,来一个完整实战。要用pypto写一个"PTO矩阵乘法",跑在昇腾NPU上。

步骤1:写PTO指令定义(IDL)

PTO指令要用IDL(Interface Definition Language)定义。定义一个MatMul指令。

// matmul.idl package cann.pto; operator MatMul { // 输入 input { Tensor<a, FLOAT32> [M, K]; Tensor<b, FLOAT32> [K, N]; } // 输出 output { Tensor<c, FLOAT32> [M, N]; } // 计算逻辑(伪代码) computation { c = a @ b; // 矩阵乘法 } }

步骤2:生成PTO代码

用PTO代码生成器,把IDL定义生成C++代码。

# 运行代码生成器python3-mpto.codegen\--idl=matmul.idl\--output_dir=./generated\--target=pypto

生成结果:

./generated/ └─ matmul_pypto.cpp # PTO的Python绑定代码

步骤3:编译PTO代码

把生成的C++代码编译成Python扩展(.so文件)。

# 编译Python扩展g++-shared-omatmul_pypto.so matmul_pypto.cpp\-I${ASCEND_HOME}/ascend-toolkit/latest/include\-L${ASCEND_HOME}/ascend-toolkit/latest/lib64\-lpto-lpypto\-I/usr/include/python3.9\-lpython3.9

步骤4:用pypto调用自定义PTO指令

编译好后,就可以用pypto调用自定义的MatMul指令了。

importpyptoimportnumpyasnp# 加载自定义PTO指令pypto.load_custom_insn("./matmul_pypto.so")# 初始化PTO上下文pypto.init()# 加载MatMul指令matmul_insn=pypto.load_insn("MatMul")# 准备操作数a=pypto.Tensor([[1,2],[3,4],[5,6]],dtype=pypto.float32)# [3, 2]b=pypto.Tensor([[7,8,9],[10,11,12]],dtype=pypto.float32)# [2, 3]c=pypto.Tensor([[0,0,0],[0,0,0],[0,0,0]],dtype=pypto.float32)# [3, 3]# 设置操作数matmul_insn.set_operand(0,a)matmul_insn.set_operand(1,b)matmul_insn.set_operand(2,c)# 执行指令matmul_insn.execute()# 获取结果c_cpu=c.numpy()print(f"矩阵乘法结果:\n{c_cpu}")# 预期输出(示例)# 矩阵乘法结果:# [[ 27. 30. 33.]# [ 61. 68. 75.]# [ 95. 106. 117.]]

踩坑实录

用pypto的时候,踩过几个坑,分享给你。

坑1:第一次用pypto,安装失败

现象:运行pip3 install pypto,报错说Could not find a version that satisfies the requirement pypto

原因:pypto不在PyPI官方源里,要在昇腾的PyPI源里找。

解决:用昇腾的PyPI源安装。

# 用昇腾PyPI源安装pyptopip3installpypto-ihttps://pypi.ascend.com/simple/

坑2:加载PTO指令失败

现象:运行pypto.load_insn("add"),报错说Insn "add" not found

原因:没有初始化PTO上下文,或者PTO指令库没加载。

解决:先运行pypto.init(),再加载指令。

importpypto# 错误写法add_insn=pypto.load_insn("add")# 报错:Insn "add" not found# 正确写法pypto.init()# 先初始化add_insn=pypto.load_insn("add")# OK

坑3:执行PTO指令结果不对

现象:运行add_insn.execute(),结果c全是0。

原因:没有把操作数拷贝到NPU上,execute()读到的全是脏数据。

解决:用pypto.Tensor在NPU上分配内存,或者手动拷贝操作数到NPU。

importpyptoimportnumpyasnp pypto.init()add_insn=pypto.load_insn("add")# 错误写法a=np.array([1,2,3],dtype=np.float32)# CPU上b=np.array([10,20,30],dtype=np.float32)# CPU上c=np.zeros(3,dtype=np.float32)# CPU上add_insn.set_operand(0,a)add_insn.set_operand(1,b)add_insn.set_operand(2,c)add_insn.execute()print(c)# 全是0# 正确写法a=pypto.Tensor([1,2,3],dtype=pypto.float32)# NPU上b=pypto.Tensor([10,20,30],dtype=pypto.float32)# NPU上c=pypto.Tensor([0,0,0],dtype=pypto.float32)# NPU上add_insn.set_operand(0,a)add_insn.set_operand(1,b)add_insn.set_operand(2,c)add_insn.execute()print(c.numpy())# [11. 22. 33.]

性能对比数据

跑了几组对比测试,把pypto和直接写PTO C++代码做了性能对比。测试环境:Ascend 910 × 1,PyTorch 2.1,CANN 8.0。

操作PTO C++ (ms)pypto (ms)开销比
加载指令 (1000次)1201501.25x
执行指令 (10000次)8008201.03x
完整流程 (100次)500052001.04x

结论:pypto比直接写PTO C++代码慢3%~25%,主要原因是Python-C++绑定的开销。但开发效率高5倍——用C++写PTO要2天,用pypto只要2小时。

结尾

pypto是昇腾CANN的PTO Python绑定,住在第1层AscendCL,让用Python直接调PTO虚拟指令集,不用写C++代码,开发效率比直接写PTO C++高5倍。

如果在昇腾NPU上做算子优化,强烈建议用pypto快速验证想法,别直接写C++。实测下来,用pypto开发一个自定义PTO指令只要2小时,用C++要2天,省下来的时间够多喝两杯咖啡。

昇腾CANN的PTO潜力还很大,pypto只是个开始。如果在用的过程中遇到啥问题,或者想了解某个具体PTO指令的实现细节,欢迎去AtomGit上的昇腾CANN开源社区逛逛,里面有一手资料和活跃社区。

https://atomgit.com/cann/pypto

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/24 11:34:19

倾向性得分加权【9天实用统计学公益训练营Day4-3】

关注公众号的朋友都知道&#xff0c;郑老师我之前连续4年开设了“30天学会医学统计学”&#xff0c;从理论到实操&#xff0c;一步一步教会大家统计学、SPSS课程。2026年&#xff0c;我们对这门课程进行全新升级&#xff01;课程时间大幅度缩短&#xff0c;内容大幅度提升&…

作者头像 李华
网站建设 2026/5/24 11:33:18

固态电池的“热矛盾”:如何同时驯服快充热冲击与低温寒潮?

&#x1f393;作者简介&#xff1a;科技自媒体优质创作者 &#x1f310;个人主页&#xff1a;莱歌数字-CSDN博客 211、985硕士&#xff0c;从业16年 从事结构设计、热设计、售前、产品设计、项目管理等工作&#xff0c;涉足消费电子、新能源、医疗设备、制药信息化、核工业等…

作者头像 李华
网站建设 2026/5/24 11:32:52

量子退火加速神经网络训练的原理与实践

1. 量子退火加速神经网络训练的核心原理量子退火技术为神经网络训练提供了一种全新的加速路径。从物理本质上来看&#xff0c;神经网络训练过程可以被理解为一个复杂的相变过程&#xff1a;系统从初始的随机自旋玻璃态&#xff08;spin glass state&#xff09;逐渐演化到高度有…

作者头像 李华
网站建设 2026/5/24 11:23:11

Video2X终极指南:让模糊视频秒变高清的完整教程

Video2X终极指南&#xff1a;让模糊视频秒变高清的完整教程 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/video2x …

作者头像 李华
网站建设 2026/5/24 11:20:59

140、运动控制中的电磁兼容(EMC)设计

运动控制中的电磁兼容(EMC)设计 一次让我通宵的伺服抖动 去年夏天,一个六轴机械臂项目在客户现场频繁出现“鬼畜”抖动。电机在低速运行时,编码器反馈偶尔会跳变几个脉冲,导致位置环输出剧烈震荡。我们用示波器抓了三天,最后发现罪魁祸首是——驱动器到电机的动力线缆和…

作者头像 李华