写给前端的 CANN-GraphCompiler:昇腾图编译器到底是啥?
写给前端的 CANN-GraphCompiler昇腾图编译器到底是啥之前有兄弟问“哥PyTorch 模型怎么在昇腾上跑中间有什么编译过程”好问题。今天一次说清楚。GraphCompiler 是啥GraphCompiler 是昇腾的图编译器。把计算图编译成 NPU 可执行的代码。一句话说清楚GraphCompiler 是昇腾的图编译器把模型计算图编译成 NPU 执行代码优化性能。你说气人不气人同样的模型GraphCompiler 编译后能快 2-3 倍。为什么需要 GraphCompiler模型执行流程PyTorch 模型 ↓ 导出计算图ONNX/TorchScript ↓ GraphCompiler 编译 ↓ 生成 OM 模型 ↓ NPU 执行GraphCompiler 负责解析计算图、优化、生成可执行代码。GraphCompiler 核心能力1. 图解析解析不同框架的计算图。importgraph_compilerasgc# 解析 ONNXmodelgc.load_onnx(model.onnx)# 解析 TorchScriptmodelgc.load_torchscript(model.pt)# 解析 TensorFlowmodelgc.load_tensorflow(model.pb)# 查看图结构print(model.graph)2. 图优化优化计算图性能。importgraph_compilerasgc modelgc.load_onnx(model.onnx)# 应用优化optimizergc.GraphOptimizer()# 算子融合optimizer.fuse_ops(model.graph)# 死代码消除optimizer.eliminate_dead_code(model.graph)# 常量折叠optimizer.fold_constants(model.graph)# 内存优化optimizer.optimize_memory(model.graph)# 查看优化后的图print(model.graph)3. 算子映射映射到昇腾算子。importgraph_compilerasgc modelgc.load_onnx(model.onnx)# 算子映射mappergc.OpMapper()mapper.map_to_ascend(model.graph)# 查看映射结果fornodeinmodel.graph.nodes:print(f{node.op_type}-{node.ascend_op})4. 内存规划规划内存使用。importgraph_compilerasgc modelgc.load_onnx(model.onnx)# 内存规划plannergc.MemoryPlanner()memory_planplanner.plan(model.graph)print(fTotal memory:{memory_plan.total_memory/1024/1024:.2f}MB)print(fPeak memory:{memory_plan.peak_memory/1024/1024:.2f}MB)5. 编译生成生成 OM 模型。importgraph_compilerasgc# 编译modelgc.load_onnx(model.onnx)compilergc.Compiler()om_modelcompiler.compile(model)# 保存om_model.save(model.om)# 查看模型信息print(fInput shape:{om_model.input_shape})print(fOutput shape:{om_model.output_shape})print(fModel size:{om_model.size/1024/1024:.2f}MB)编译选项优化级别importgraph_compilerasgc compilergc.Compiler()# O0: 无优化compiler.set_opt_level(gc.OptLevel.O0)# O1: 基础优化compiler.set_opt_level(gc.OptLevel.O1)# O2: 标准优化默认compiler.set_opt_level(gc.OptLevel.O2)# O3: 激进优化compiler.set_opt_level(gc.OptLevel.O3)精度模式importgraph_compilerasgc compilergc.Compiler()# FP32compiler.set_precision(gc.Precision.FP32)# FP16compiler.set_precision(gc.Precision.FP16)# 混合精度compiler.set_precision(gc.Precision.MIXED)动态 Shapeimportgraph_compilerasgc compilergc.Compiler()# 静态 Shapecompiler.set_dynamic_shape(False)# 动态 Shapecompiler.set_dynamic_shape(True)compiler.set_dynamic_range(input,min_shape[1,3,224,224],max_shape[8,3,224,224])优化技术1. 算子融合# 原始图# Conv - BN - ReLU - Conv - BN - ReLU# 融合后# FusedConvBNReLU - FusedConvBNReLU融合规则Conv BN ReLU → FusedConvBNReLUMatMul Bias GELU → FusedMatMulBiasGELULinear ReLU → FusedLinearReLU2. 内存优化# 原始内存布局# Tensor1 - Tensor2 - Tensor3 (各占内存)# 优化后内存布局# Tensor1 和 Tensor3 复用同一块内存优化技术内存复用就地操作生命期分析3. 并行优化# 原始执行# Op1 - Op2 - Op3 (串行)# 优化后执行# Op1 || Op2 - Op3 (并行)4. 数据布局优化# 原始布局: NCHW# 优化布局: NHWC (昇腾更高效)ATC 工具ATC 是 GraphCompiler 的命令行工具。# ONNX 转 OMatc--modelmodel.onnx--outputmodel.om--framework5# TorchScript 转 OMatc--modelmodel.pt--outputmodel.om--framework7# 查看模型信息atc--mode1--ommodel.om# 设置优化级别atc--modelmodel.onnx--outputmodel.om--framework5--opt_level3# 设置精度atc--modelmodel.onnx--outputmodel.om--framework5--precision_modeallow_mix_precision# 设置动态 Shapeatc--modelmodel.onnx--outputmodel.om--framework5\--input_shape_rangeinput:[1~8,3,224,224]性能对比在昇腾 910 上编译 ResNet-50优化级别编译时间推理延迟内存占用O05s20ms800MBO110s15ms600MBO220s10ms400MBO360s8ms350MB你说气人不气人O3 优化比 O0 快 2.5 倍。编译流程详解Step 1: 加载模型importgraph_compilerasgc# 加载模型modelgc.load_onnx(resnet50.onnx)# 查看图信息print(fNodes:{len(model.graph.nodes)})print(fInputs:{model.graph.inputs})print(fOutputs:{model.graph.outputs})Step 2: 前处理# 标准化输入preprocessorgc.Preprocessor()preprocessor.normalize_inputs(model.graph)# 类型推断preprocessor.infer_types(model.graph)# Shape 推断preprocessor.infer_shapes(model.graph)Step 3: 图优化optimizergc.GraphOptimizer()# 算子融合optimizer.fuse_ops(model.graph)# 死代码消除optimizer.eliminate_dead_code(model.graph)# 常量折叠optimizer.fold_constants(model.graph)# 公共子表达式消除optimizer.eliminate_cse(model.graph)Step 4: 算子映射# 映射到昇腾算子mappergc.OpMapper()mapper.map_to_ascend(model.graph)# 检查支持checkergc.OpChecker()unsupportedchecker.check_unsupported(model.graph)ifunsupported:print(fUnsupported ops:{unsupported})Step 5: 内存规划plannergc.MemoryPlanner()memory_planplanner.plan(model.graph)print(fTotal memory:{memory_plan.total_memory/1024/1024:.2f}MB)Step 6: 代码生成compilergc.Compiler()om_modelcompiler.compile(model)om_model.save(resnet50.om)调试技巧查看中间图importgraph_compilerasgc modelgc.load_onnx(model.onnx)# 保存中间图gc.save_graph(model.graph,after_load.txt)optimizergc.GraphOptimizer()optimizer.fuse_ops(model.graph)gc.save_graph(model.graph,after_fuse.txt)验证编译结果importgraph_compilerasgc# 加载 OM 模型om_modelgc.load_om(model.om)# 验证输出input_datacreate_test_input()outputom_model.infer(input_data)# 对比原始模型original_outputoriginal_model(input_data)print(fMax diff:{abs(output-original_output).max()})总结GraphCompiler 是昇腾的图编译器图解析ONNX/TorchScript/TensorFlow图优化融合/消除/折叠算子映射映射到昇腾算子内存规划优化内存使用代码生成生成 OM 模型
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2633164.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!