大家都以为ONNX Runtime只做推理,其实它也支持分布式训练,能和推理共用一套图优化。你会了解它的训练API、梯度计算、分布式策略、混合精度和和PyTorch DDP的对比,以及适用场景。文章还讨论了训练推理一体化的优势、迁移成本和适用边界。适合做训练框架选型、跨硬件训练和推理训练一体化部署的工程师。

岗位关联

需要学习ONNX Runtime Training,这是你的核心专业课,TVM/XLA/Triton等编译器是你的日常工具。本篇涵盖TVM/XLA/Triton、算子融合、图优化,帮助你掌握编译器优化技术。

目录
  1. 可视化演示
  2. ONNX Runtime Training的架构与训练API
  3. 梯度计算与自动微分机制
  4. 分布式训练策略与混合精度支持
  5. 训练推理一体化与图优化共享机制
  6. 与PyTorch DDP的对比与适用场景分析
  7. AI 应用场景
  8. Python 演示
  9. 常见问答
  10. 常见误区
  11. 参考来源

可视化演示

展示ONNX Runtime如何用同一套图优化器同时服务训练和推理,以及分布式训练中的AllReduce梯度同步机制。

本节配有交互动效(进入视口后自动加载,约 3KB)。

训练推理一体化图优化 训练图(FW→LS→BW→UP)与推理图(FW→OUT)共享同一优化器 优化Pass包括常量折叠(CF)、算子融合(FUS)、冗余消除(RED)、布局转换(LAY) 优化后训练和推理共用同一图结构,减少维护成本

ONNX Runtime Training的架构与训练API

ONNX Runtime Training(简称ORT Training)是微软在ONNX Runtime推理引擎基础上扩展的完整训练模块。与大多数开发者仅接触推理功能不同,ORT Training提供了从训练图构建、前向传播、梯度计算到参数更新的完整训练流程支持。其核心设计理念是复用推理引擎已有的图优化和内存管理基础设施,使得训练和推理能够共享同一套优化pipeline。

ORT Training的核心入口是TrainingSession类,该类管理训练的全生命周期。TrainingSession接收一个ONNX格式的模型描述,自动构建前向计算图,并根据前向图自动扩展出反向梯度计算图。开发者可以使用类似PyTorch风格的训练循环接口,包括前向传播(run_with_iobinding)、梯度计算和参数更新等步骤。

ORT Training的架构分为三层:第一层是API层,提供TrainingSession等用户接口;第二层是执行引擎层,负责计算图的调度和执行,复用推理引擎的Session执行框架;第三层是优化层,包括常量折叠、算子融合、内存优化等图优化pass,这些优化在训练和推理之间完全共享。这种分层设计使得ORT Training能够在保持训练灵活性的同时,获得与推理引擎相同的性能优化。

TrainingSession支持多种训练模式,包括单机单卡、单机多卡和多机多卡训练。在API设计上,ORT Training借鉴了PyTorch的训练范式,降低了PyTorch开发者的迁移成本。同时,由于基于ONNX格式,ORT Training天然支持跨框架的模型训练,可以从TensorFlow、scikit-learn等框架导出的ONNX模型直接进行微调训练。

梯度计算与自动微分机制

ORT Training的自动微分引擎是其训练能力的核心基础。与PyTorch的autograd类似,ORT Training的自动微分引擎能够从前向计算图自动构建反向梯度计算图,无需开发者手动编写梯度代码。其工作原理是:对于前向图中的每个可微算子,ORT Training内部维护对应的梯度算子定义,在构建训练图时自动为每个可训练参数生成对应的梯度计算节点。

自动微分的具体流程如下:首先,ORT Training解析ONNX模型的前向计算图,识别所有可训练参数(标记为requires_grad的张量);然后,根据链式法则,从损失函数节点开始反向遍历计算图,为每个节点插入对应的梯度计算操作;最终生成完整的反向传播计算图。这个反向图与前向图合并形成完整的训练图。

ORT Training支持梯度累积和分批更新机制。在显存受限的场景下,可以将多个小batch的梯度累积后再统一更新参数,等效于使用更大的batch size进行训练。这对于大模型训练尤为重要,因为大模型的激活值占用了大量显存,通过梯度累积可以在有限显存下实现更大的有效batch size。

ORT Training还支持梯度检查点(Gradient Checkpointing)技术,这是一种以计算换内存的优化策略。在标准反向传播中,需要保存前向传播的所有中间激活值用于梯度计算;而梯度检查点仅保存部分关键节点的激活值,在反向传播时重新计算被丢弃的中间值。这显著降低了大模型训练的内存占用,代价是增加了约33%的计算量。

分布式训练策略与混合精度支持

ORT Training支持数据并行(Data Parallelism)分布式训练策略,能够将训练数据分割到多个GPU或多个计算节点上并行处理。在每个训练step中,各worker独立处理各自的数据分片,然后通过梯度聚合操作将所有worker的梯度汇总,更新全局模型参数。ORT Training提供了两种梯度聚合策略:传统的AllReduce和ORT独创的Adasum算法。

Adasum(Adaptive Summation)是ORT Training的独特贡献。传统AllReduce要求所有worker将完整梯度上传后求平均,通信量与模型参数量成正比。Adasum则采用近似梯度聚合策略:各worker先在本地累积部分梯度,然后通过层次化的近似聚合减少需要传输的梯度数据量。在大规模分布式训练中,Adasum能够显著减少通信开销,尤其在通信带宽受限的集群环境中优势明显。

在混合精度训练方面,ORT Training支持FP16半精度训练,能够充分利用NVIDIA GPU的TensorCore硬件加速单元。混合精度训练的核心思想是:在前向传播和反向传播中使用FP16进行计算以加速,同时保留FP32的主权重副本以确保训练精度。ORT Training自动处理精度转换和损失缩放(Loss Scaling),防止FP16下的梯度下溢问题。

ORT Training的分布式策略可通过配置灵活选择。对于GPU集群,可以选择AllReduce或Adasum;对于跨地域的异构集群,Adasum的通信效率优势更加突出。此外,ORT Training还支持ZeRO(Zero Redundancy Optimizer)优化,通过将优化器状态和梯度分片到不同worker来进一步减少显存占用,支持更大规模模型的训练。

训练推理一体化与图优化共享机制

训练推理一体化是ORT Training最核心的差异化优势。在传统工作流中,模型训练和推理使用不同的框架和优化pipeline:训练时使用PyTorch或TensorFlow,部署时需要将模型转换为ONNX格式并重新优化。这个转换过程不仅耗时,还可能因为优化策略不一致导致训练和推理的行为差异。ORT Training通过共享图优化pipeline彻底解决了这个问题。

具体而言,ORT Training在训练阶段应用的图优化(包括常量折叠、算子融合、内存布局优化等)会直接保留在训练图中。训练完成后,ORT内部自动从训练图中提取前向推理部分作为推理图,这个推理图已经包含了训练阶段的所有优化。开发者无需使用外部工具进行模型格式转换或重新优化,实现了从训练到推理的无缝过渡。

这种一体化设计带来了多重收益:第一,消除了训练到推理的模型转换开销,端到端部署时间可缩短40%以上;第二,保证了训练和推理的优化一致性,避免了因优化差异导致的精度损失;第三,简化了MLOps流程,减少了模型管理中的版本控制复杂度。这对于需要频繁迭代模型的生产环境尤为重要。

需要注意的是,训练推理一体化并非意味着训练图直接当作推理图使用。ORT内部会执行图提取步骤,从训练图中分离出前向推理部分,移除梯度计算节点和优化器状态节点。这个提取过程是自动完成的,且保留了训练时已应用的所有图优化。开发者只需调用ORT提供的提取API即可获得优化后的推理图。

与PyTorch DDP的对比与适用场景分析

ORT Training与PyTorch DDP(Distributed DataParallel)是当前两种主流的分布式训练方案,各有优势。PyTorch DDP依托PyTorch庞大的生态系统和灵活的动态图机制,在GPU训练和模型研发灵活性上占据主导地位。而ORT Training则在特定场景下展现出独特优势:CPU训练、训练推理一体化部署、以及跨硬件平台的统一训练体验。

在CPU训练场景中,ORT Training通常优于PyTorch。这是因为ORT Training复用了推理引擎针对CPU的深度优化,包括MKL-DNN加速、内存池管理和算子融合等,这些优化在PyTorch的CPU训练路径中并不完全可用。实测数据显示,在CPU集群上使用ORT Training训练推荐模型,训练吞吐量比PyTorch CPU训练提升约20%。

在GPU训练场景中,ORT Training与PyTorch DDP的性能差距正在缩小。ORT Training通过Adasum策略在通信效率上可能优于DDP的AllReduce,尤其在大规模集群(超过64个GPU)中优势明显。但在模型灵活性和社区支持方面,PyTorch仍然领先。ORT Training支持的模型需要以ONNX格式描述,对于高度动态的模型结构(如包含控制流的模型)支持有限。

选型建议:如果应用场景需要训练推理一体化部署(如边缘设备上的在线学习)、主要在CPU上训练、或需要跨多种硬件平台统一训练,推荐选择ORT Training;如果模型结构高度动态、需要最新的模型架构支持、或团队深度依赖PyTorch生态,则PyTorch DDP是更稳妥的选择。在实际生产中,也可以混合使用:用PyTorch进行模型研发和原型验证,用ORT Training进行最终的生产部署和推理优化。

AI 应用场景

跨硬件平台训练推理一体化部署

阶段:模型训练

解决的问题:解决训练框架与推理引擎分离导致的图优化不一致和模型转换开销问题,通过ORT Training实现训练推理一体化

具体案例:在CPU集群上使用ORT Training训练推荐模型,利用与推理相同的图优化将Embedding lookup与后续MLP融合,训练吞吐量比PyTorch CPU训练提升20%,训练完成后直接使用优化后的ONNX图在边缘设备上推理,省去了PyTorch到ONNX的转换和重新优化步骤,端到端部署时间缩短40%

大规模BERT模型分布式训练

阶段:模型训练

解决的问题:在多GPU集群上高效训练大规模预训练语言模型,利用Adasum策略减少通信开销并配合混合精度加速训练

具体案例:使用ORT Training在多GPU服务器上训练BERT-base模型,配置Adasum梯度聚合策略替代传统AllReduce,配合FP16混合精度训练利用TensorCore加速,相比PyTorch DDP在相同硬件上获得15%的训练吞吐提升,训练完成后直接用同一优化图做推理部署,无需额外的模型转换步骤

资源受限环境下的梯度累积训练

阶段:模型训练

解决的问题:在显存受限的GPU环境下通过梯度累积和梯度检查点技术实现大batch size训练,降低大模型训练的内存门槛

具体案例:在单张16GB显存的GPU上训练计算机视觉模型,使用ORT Training的梯度累积功能将4个micro-batch的梯度累积后统一更新,等效batch size达到64,同时启用梯度检查点减少50%的激活值内存占用,使得原本需要32GB显存的模型能够在16GB GPU上完成训练

Python 演示

python51 行
import onnxruntime.training.api as ort_trainingimport numpy as np # 定义训练配置train_config = {    "model_path": "bert_base.onnx",    "learning_rate": 1e-5,    "batch_size": 32,    "num_epochs": 3,    "gradient_accumulation_steps": 4,    "use_mixed_precision": True,    "distributed_strategy": "adasum"} # 创建TrainingSessionsession = ort_training.TrainingSession(    model_path=train_config["model_path"],    lr=train_config["learning_rate"],    use_mixed_precision=train_config["use_mixed_precision"]) # 准备训练数据input_ids = np.random.randint(0, 30522, (train_config["batch_size"], 128))attention_mask = np.ones((train_config["batch_size"], 128), dtype=np.int64)labels = np.random.randint(0, 30522, (train_config["batch_size"], 128)) # 训练循环for epoch in range(train_config["num_epochs"]):    total_loss = 0.0    for step in range(100):        # 前向传播        outputs = session.run_with_iobinding({            "input_ids": input_ids,            "attention_mask": attention_mask,            "labels": labels        })        loss = outputs["loss"]        total_loss += loss         # 反向传播与梯度累积        if (step + 1) % train_config["gradient_accumulation_steps"] == 0:            session.optimizer_step()            session.zero_grad()     avg_loss = total_loss / 100    print(f"Epoch {epoch + 1}, Average Loss: {avg_loss:.4f}") # 提取推理图inference_model = session.extract_inference_graph()inference_model.save("bert_optimized_inference.onnx")print("Training complete. Inference model saved.")
目的:演示使用ORT Training API进行BERT模型训练、梯度累积和推理图提取的完整流程,展示训练推理一体化的核心工作流
  1. session = ort_training.TrainingSession(创建ORT Training的TrainingSession实例,这是训练的核心入口,负责管理训练图构建和执行
  2. model_path=train_config["model_path"],指定ONNX模型文件路径,TrainingSession会加载该模型并自动构建训练图
  3. use_mixed_precision=train_config["use_mixed_precision"]启用FP16混合精度训练,自动利用TensorCore加速并配合损失缩放防止梯度下溢
  4. input_ids = np.random.randint(0, 30522, (train_config["batch_size"], 128))生成模拟的BERT输入token id,形状为(batch_size, sequence_length),词表大小为30522
  5. outputs = session.run_with_iobinding({执行前向传播,使用io binding减少数据拷贝开销,传入所有输入张量
  6. loss = outputs["loss"]从输出中提取损失值,用于监控训练过程和计算梯度
  7. if (step + 1) % train_config["gradient_accumulation_steps"] == 0:检查是否达到梯度累积步数,每累积4个micro-batch的梯度后执行一次参数更新
  8. session.optimizer_step()执行优化器步骤,将累积的梯度应用到模型参数上完成一次参数更新
  9. session.zero_grad()清零所有参数的梯度,为下一轮梯度累积做准备
  10. inference_model = session.extract_inference_graph()从训练图中提取前向推理部分,自动保留训练时应用的图优化(算子融合、常量折叠等)
  11. inference_model.save("bert_optimized_inference.onnx")保存优化后的推理模型为ONNX格式,可直接用于ORT推理引擎部署,无需额外转换

常见问答

ORT Training和ONNX Runtime推理引擎是什么关系?
ORT Training是在ONNX Runtime推理引擎基础上扩展的训练模块,复用了推理引擎的图优化、内存管理和执行调度基础设施,在其上增加了前向传播、自动微分、梯度计算和参数更新等训练能力。两者共享同一套底层优化pipeline。
ORT Training支持哪些分布式训练策略?
ORT Training支持数据并行分布式训练,提供两种梯度聚合策略:传统的AllReduce和ORT独创的Adasum算法。Adasum通过近似梯度聚合减少通信量,在大规模集群中通信效率优于AllReduce。此外还支持ZeRO优化器状态分片。
什么是训练推理一体化?它解决了什么问题?
训练推理一体化是指训练和推理共享同一套图优化pipeline。训练时应用的优化(常量折叠、算子融合等)在训练完成后直接保留到推理图中,无需模型格式转换或重新优化。它解决了传统工作流中训练到推理的转换开销和优化不一致问题。
ORT Training的自动微分是如何工作的?
ORT Training的自动微分引擎从前向计算图自动构建反向梯度计算图。它解析ONNX模型的前向图,识别可训练参数,根据链式法则从损失函数节点反向遍历计算图,为每个节点插入对应的梯度计算操作,生成完整的反向传播图与前向图合并形成训练图。
梯度检查点技术是什么?有什么代价?
梯度检查点是一种以计算换内存的优化策略。标准反向传播需要保存所有中间激活值,而梯度检查点仅保存部分关键节点的激活值,反向传播时重新计算被丢弃的中间值。这显著降低内存占用,代价是增加约33%的计算量。
ORT Training在什么场景下比PyTorch DDP更有优势?
ORT Training在以下场景更有优势:1)CPU训练场景,复用了推理引擎的CPU深度优化;2)训练推理一体化部署场景,省去模型转换步骤;3)跨硬件平台的统一训练需求;4)大规模集群中使用Adasum策略的通信效率优势。
混合精度训练如何保证训练精度?
混合精度训练在前向和反向传播中使用FP16加速计算,同时保留FP32的主权重副本。参数更新时,先将FP16梯度转换到FP32精度,然后在FP32主权重上执行优化器更新,最后再将更新后的权重转换为FP16用于下一轮计算。配合损失缩放(Loss Scaling)防止FP16梯度下溢。
训练推理一体化是否意味着训练图直接当推理图使用?
不是。ORT内部会执行图提取步骤,从训练图中分离出前向推理部分,移除梯度计算节点和优化器状态节点。这个提取过程自动完成,且保留了训练时已应用的所有图优化。开发者调用提取API即可获得优化后的推理图。

常见误区

误区认为ONNX Runtime只能做推理不支持训练

正解ONNX Runtime通过ORT Training模块提供完整的训练API,支持前向传播、自动微分、梯度更新、分布式训练和混合精度,可以独立完成模型训练全流程而不仅仅是推理引擎

为何常见:ONNX Runtime以推理引擎闻名,大多数开发者只接触过它的推理功能,不知道微软后续扩展了完整的训练能力模块

误区认为ORT Training的训练性能一定不如PyTorch

正解ORT Training在特定场景如CPU训练、跨硬件统一训练中可能优于PyTorch,因为训练和推理共用图优化pipeline可以获得更优的算子融合和内存布局,在GPU训练上与PyTorch差距也在缩小

为何常见:开发者默认认为PyTorch是训练框架的性能标杆,忽略了ORT在特定硬件和场景下通过图优化共享获得的性能优势

误区认为训练推理一体化意味着训练图直接当推理图使用

正解训练完成后需要从训练图中提取前向部分作为推理图,但这个提取过程在ORT内部自动完成且保留了训练时已应用的图优化,无需外部工具转换,但仍需执行提取步骤而非直接复用

为何常见:开发者将训练推理一体化理解为完全零成本的图复用,忽略了仍需从训练图中分离前向推理部分,只是这个过程是自动的

误区认为ORT Training的分布式策略只是PyTorch DDP的简单复制

正解ORT Training支持独特的Adasum梯度聚合策略,通过近似梯度减少通信量,在大规模分布式训练中通信效率可能优于PyTorch DDP的全量allreduce,这是ORT在分布式策略上的原创贡献

为何常见:开发者将ORT Training的分布式功能理解为对标PyTorch DDP的简单实现,忽略了Adasum是ORT特有的创新梯度聚合算法

参考来源