【AI编译器入门⑥】端到端编译流程实战ONNX → TVM → TensorRT全链路本文是「AI编译器」系列的第六篇。前面我们分别讲了前端、中端、后端今天把它们串起来——从ONNX模型开始经过TVM中端优化再选择不同的后端CUDA/CUTLASS/TensorRT最终生成可部署产物。本文带你完整走一遍端到端编译链路。一、写在前面为什么要串起来看学了前端、中端、后端你可能会问它们是怎么配合的实际项目中完整的编译流程是什么样的单独看每一块都很清楚但串起来才知道onnx-simplifier为什么要先跑一遍中端Pass的顺序为什么要这样排TensorRT partition和CUTLASS partition有什么不同动态batch怎么支持今天我们就把整个链路打通从一个ONNX模型开始一直到生成可部署的.so文件。先上一张端到端流程图二、完整链路总览ONNX model ↓ Step 1onnx-simplifier化简 ONNX简化模型 ↓ Step 2TVM前端解析 Relay/Relax IR ↓ Step 3中端Pass优化 DynamicToStatic → FoldConstant → SimplifyInference → FuseOps → DeadCodeElimination → InferType 优化后的IR ↓ Step 4后端选择 ├── TVM CUDA Codegen ├── TVM CUTLASS partition └── TVM TensorRT partition ↓ Step 5编译 打包 runtime artifacts.so / .trt ↓ Step 6部署运行 推理服务我们一步步来看。三、Step 1ONNX化简onnx-simplifier3.1 为什么要先化简ONNX模型从PyTorch/TensorFlow导出时常常带了很多冗余节点无意义的Identity常量shape的Reshape/Squeeze成对的Cast死代码分支这些冗余节点不仅影响性能还可能导致TVM前端解析失败或中端优化效果打折扣。所以在喂给TVM之前先在ONNX层做一轮大扫除——onnx-simplifier就是干这个的。3.2 怎么用python-monnxsim model.onnx model_sim.onnxonnx-simplifier做了什么常量折叠Constant Folding形状推导Shape Inference死代码消除冗余节点清理经验之谈编译ONNX模型前先跑一遍onnx-simplifier几乎是标配操作。花不了多少时间但能避免很多奇怪的问题。四、Step 2TVM前端解析4.1 ONNX导入importonnxfromtvmimportrelay onnx_modelonnx.load(model_sim.onnx)mod,paramsrelay.frontend.from_onnx(onnx_model,shape{input:[1,3,224,224]},dtype{input:float32},)modrelay.transform.InferType()(mod)4.2 这一步可能遇到的坑算子不支持ONNX模型里有TVM不认识的算子 → 需要注册自定义算子opset版本不兼容opset太高或太低 → 升级TVM或转换opset动态shape处理batch/sequence length是动态的 → 用Relax或bucket编译数值精度问题某些算子语义有细微差异 → 需要对齐验证五、Step 3中端Pass优化5.1 标准Pass Pipelinefromtvm.relayimporttransformasT modT.DynamicToStatic()(mod)# 动态算子静态化如果可能modT.FoldConstant()(mod)# 常量折叠modT.SimplifyInference()(mod)# 推理化简BN/Dropout等modT.FuseOps(fuse_opt_level2)(mod)# 算子融合modT.DeadCodeElimination()(mod)# 死代码消除modT.InferType()(mod)# 重新推导类型5.2 为什么是这个顺序Pass的顺序很重要——顺序不对效果会大打折扣先FoldConstant常量折叠后图变小了后续Pass处理更快再SimplifyInference把BN等训练算子化简为融合创造条件再FuseOps图干净了融合效果更好最后DCE前面的Pass可能产生死代码最后清理一遍Pass顺序不是随便排的——每一步都在为下一步创造条件。顺序错了可能需要多跑好几轮才能收敛。5.3 布局适配如果后端是TensorRT或CUTLASS还需要根据后端偏好调整布局modT.ConvertLayout({nn.conv2d:[NCHW,OIHW]})(mod)注意布局转换要和后端对齐不然可能引入额外的transpose开销。六、Step 4后端选择TVM支持多种后端我们来看看怎么选、怎么用。6.1 后端一纯CUDA Codegen最简单的方式——全部走TVM自己的CUDA Codegentargettvm.target.cuda(modela100)withtvm.transform.PassContext(opt_level3):librelay.build(mod,targettarget,paramsparams)lib.export_library(model_cuda.so)适合场景自定义算子多、需要深度定制、调试阶段。6.2 后端二TVM CUTLASS核心算子走CUTLASS其余走TVM Codegenfromtvm.contrib.cutlassimportpartition_for_cutlass modpartition_for_cutlass(mod,params)withtvm.target.cuda(modela100):librelay.build(mod,targetcuda,paramsparams)lib.export_library(model_cutlass.so)原理遍历图识别MatMul/Conv/BMM等可offload的算子标记为CUTLASS子图PartitionGraph切分CUTLASS子图生成CUTLASS kernel其余走TVM Codegen适合场景核心GEMM/Conv多想用CUTLASS的高性能又要保留TVM的灵活性。6.3 后端三TVM TensorRT大子图走TensorRT不支持的fallback到TVMfromtvm.contrib.tensorrtimportpartition_for_tensorrt modpartition_for_tensorrt(mod,params)withtvm.transform.PassContext(opt_level3):librelay.build(mod,targetcuda,paramsparams)lib.export_library(model_tensorrt.so)原理遍历图检查每个算子是否被TensorRT支持连续支持的子图标记为TensorRT子图PartitionGraph切分TensorRT子图调用TensorRT builder生成engine适合场景标准模型CNN/Transformer追求极致性能能接受黑盒。6.4 直接TensorRT vs TVMTensorRT维度直接TensorRTTVM TensorRT性能最高全图TensorRT略低子图切换有overhead灵活性低黑盒高不支持的算子fallback到TVM跨平台只支持NVIDIATVM部分可跨平台可调试性差好TVM部分可以看IR、看生成代码怎么选标准模型、只用NVIDIA、追求性能 → 直接TensorRT有自定义算子、要跨平台、需要可调试 → TVMTensorRT七、Step 5动态Batch推理支持大模型推理中batch size总是动态变化的。怎么支持动态batch7.1 方案一Relax原生动态shape编译期生成动态调度代码运行期根据输入shape直接执行fromtvmimportrelaxfromtvm.relax.frontendimportnnclassModel(nn.Module):defforward(self,x:nn.Tensor):returnnn.matmul(x,self.w)modelModel()mod,paramsmodel.export_tvm(spec{forward:{x:nn.spec.Tensor([batch,768],float32)}})优点灵活一个产物支持所有batch缺点性能比全静态编译差一些因为没法做完全的常量折叠和布局优化7.2 方案二Relay bucket编译预编译多个bucket尺寸运行期根据实际batch选最近的buckets[1,4,8,16]libs{}forbinbuckets:mod_brelay.frontend.from_onnx(onnx_model,shape{input:[b,3,224,224]})libs[b]relay.build(mod_b,targetcuda)优点每个bucket都是全静态优化性能高缺点产物多占空间非bucket大小有padding浪费7.3 方案三TensorRT动态batchTensorRT支持explicit batch optimization profiletrt_config{use_explicit_batch:True,max_batch_size:16,}modpartition_for_tensorrt(mod,params,**trt_config)设置min/opt/max三个profile点TensorRT会在范围内动态调整。7.4 实际部署中怎么选通常是组合方案主要形状用bucket编译保证性能特殊形状走Relax动态shape保证灵活性TensorRT子图用profile支持动态范围没有银弹要根据业务场景权衡。八、完整代码示例伪代码最后给大家一个完整的端到端编译流程的代码框架importonnxfromtvmimportrelayfromtvm.contribimporttensorrt# Step 1: ONNX化简命令行做# python -m onnxsim model.onnx model_sim.onnx# Step 2: 前端解析onnx_modelonnx.load(model_sim.onnx)mod,paramsrelay.frontend.from_onnx(onnx_model,shape{input:[1,3,224,224]})# Step 3: 中端Pass优化fromtvm.relayimporttransformasT modT.FoldConstant()(mod)modT.SimplifyInference()(mod)modT.FuseOps(fuse_opt_level2)(mod)modT.DeadCodeElimination()(mod)modT.InferType()(mod)# Step 4: TensorRT partition可选modtensorrt.partition_for_tensorrt(mod,params)# Step 5: 编译withtvm.transform.PassContext(opt_level3):librelay.build(mod,targetcuda,paramsparams)# Step 6: 导出lib.export_library(model.so)九、常见误区误区一“ONNX是万能的中间格式”ONNX只能表达静态图的算子连接关系动态控制流、自定义算子、某些PyTorch特性转换时会丢失信息。复杂模型需要额外处理。误区二“TensorRT子图越多越好”TensorRT子图和TVM子图之间切换有数据搬运overhead。如果子图太小或切分太碎整体性能可能反而下降。误区三“动态batch只需要Relax”Relax原生动态shape编译灵活但某些后端如TensorRT对动态shape支持有限。实际部署中可能需要Relax bucket profile组合方案。十、总结一下今天这篇文章我们走了一遍端到端编译流程ONNX化简onnx-simplifier先做一轮大扫除减轻后续压力前端解析ONNX → Relay/Relax注意算子支持和动态shape中端Pass常量折叠 → 推理化简 → 算子融合 → DCE顺序很重要后端选择纯CUDA灵活、CUTLASS核心算子快、TensorRT整体性能高——各取所长动态batchRelax原生动态、Relay bucket、TensorRT profile——通常组合使用下一篇预告我们来认识一个面向多平台自动化部署的编译框架——Laser。它是怎么实现一份模型多平台同出的HPC Plugin机制又是什么本系列导航第1篇AI编译器基础三段式Pipeline与全链路协同第2篇TVM架构拆解Relay、Relax、TIR与Runtime第3篇编译前端ONNX、TorchScript与动态shape处理第4篇编译中端图优化Pass全解析第5篇编译后端CUDA Codegen、CUTLASS与TensorRT第6篇端到端编译流程ONNX → TVM → TensorRT全链路实战本文第7篇Laser编译框架多平台自动化部署与HPC Plugin更多内容持续更新中……
企业数字化 ERP 产品动态
相关推荐
FireRedASR2S Python API教程:如何用10行代码接入工业级ASR系统(附完整示例) 【免费下载链接】FireRedASR2S A SOTA Industrial-Grade All-in-One ASR system with ASR, VAD, LID, and Punc modules. FireRedASR2 supports Chinese (Mandarin, 20 dialects/accents), English, code-switching, and both speech and singing ASR. FireRedVAD supports spe… · 2026/11/15 0:59:41
丹阳电工证报名地点在哪?全国通用证书复审全攻略 丹阳电工证报名地点在哪?全国通用证书复审全攻略 证书过期了不知道怎么复审延期?这是很多电工从业者在遇到证书有效期快到时最头疼的问题。特别是像你这样已经在一线操作岗位上工作多年的朋友, 全国通用… · 2026/11/15 16:10:18
电工证要多久才拿得到 通过率揭秘这些坑千万别踩 电工证要多久才拿得到 通过率揭秘这些坑千万别踩 怕考不过白交培训费?别慌,电工证考下来真的不容易,但也不是想象中那么难。很多人被培训机构忽悠,以为只要交钱就能拿证,结果培训费花了,考试没过,白忙一场。今天咱们就从信阳浉河区公路工程从业者的视… · 2026/11/15 16:10:18
汕尾市办理电工证官方回应:避开中介坑,从这一步开始 汕尾市办理电工证官方回应:避开中介坑,从这一步开始 不知道去哪报名怕被中介坑?汕尾市办理电工证的流程看似复杂,其实只要走对路,完全可以自己搞定。很多人因为不了解流程,反而被各种“包过”“代报名”等套路忽悠,花冤枉钱还拿不到证。这篇文章从… · 2026/11/15 16:10:18
在博白哪里考电工证良心建议:证书过期了不知道怎么复审延期 在博白哪里考电工证良心建议:证书过期了不知道怎么复审延期 证书过期了不知道怎么复审延期,这个问题我见过太多人犯。我自己也曾经因为一时疏忽,差点因为电工证过期而被停工,损失了一笔不小的收入。这年头,特种作业证就像咱们的“身份证”一样重要,尤其… · 2026/11/15 16:10:18
内蒙古煤气作业证复审别被坑了!2026河南最新政策你知道吗 内蒙古煤气作业证复审别被坑了!2026河南最新政策你知道吗 你是不是也遇到过这种情况?拿着内蒙古煤气作业证,想复审却不知道去哪儿,结果被各种中介忽悠,钱花了证没办下来?别急,2026河南最新政策出台后,流程更透明了,但很多人还是摸不着门道。… · 2026/11/15 16:10:18
特种工白龙马上岗必须要这个证吗?2026河南最新政策怎么说 特种工白龙马上岗必须要这个证吗?2026河南最新政策怎么说 怕考不过白交培训费?2026河南最新政策明确,特种作业操作证是从事相关工作的“通行证”,尤其是特种工白龙马这类高风险岗位,证件就是“生命线”。如果你是南阳卧龙区劳务班组的负责人,正… · 2026/11/15 16:09:18
长春初级电工证怎么考?通过率揭秘全在这里 长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50
国内电工证报考条件与考试时间 低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50
电工作业时如何断电?电子证书到底能不能全国通用? 电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50
长春初级电工证怎么考?通过率揭秘全在这里 长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50
国内电工证报考条件与考试时间 低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50
电工作业时如何断电?电子证书到底能不能全国通用? 电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 1:51:20
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 4:02:19
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 3:02:05