昇腾大模型训练全流程实战:从硬件底座到性能调优
2026/9/8 7:31:04 网站建设 项目流程

这几年大模型训练从拼显存、拼集群规模一路走过来,真正在昇腾这套软硬件栈上把一条全流程完整跑通的人,其实不算多。我自己的经历是从最早拿一张昇腾910B推理卡折腾小模型开始,到后来在8卡节点上跑通百亿级参数的训练、调优、断点续训,中间踩过的坑写出来能排好几页。这篇文章想把昇腾大模型训练的完整链路,从硬件底座、软件栈、数据处理、并行策略,到调试排查和性能调优,按我实际操作的顺序全部捋一遍。适合两类人看:一类是第一次接触昇腾,手里有训练任务但不知道从哪下手的;另一类是在别的框架上已经训练过大模型,想快速把模型迁移到昇腾上,又怕被各种细节卡住的。

1. 先看清底座:昇腾训练环境到底由什么构成

1.1 硬件产品线:从加速卡到整机形态

很多刚接触昇腾的人第一反应是问“昇腾系列有哪些GPU”,这里要纠正一个概念:昇腾不是GPU,是NPU,也就是神经网络处理器。它的产品线分成训练和推理两条,训练侧目前主流的是昇腾910系列,尤其是910B系列。910B有几个细分型号,B1、B2、B3,我记得B3和B4更多是整机形态的差异,比如910B3是双卡形态、910B4是八卡形态,本质是同一个芯片的模组化组合。单卡HBM容量普遍到64GB,这个显存规模在训练场景下够用,但跟H100的80GB比还是得精打细算。

实际部署时,你接触到的往往不是裸卡,而是整机,比如Atlas 800T A2训练服务器,一台机器就是8张910B卡,卡间通过HCCS高速互联,带宽大约392GB/s,这个数字跟NVLink同代产品在同一水平线上。跨机通信走的是HCCL,也就是华为的集合通信库,对标的是NCCL。组网方面,训练集群一般用RoCE或者infiniBand,现在昇腾整机默认支持RoCE组网,对绝大多数实验室和公司来说,RoCE的性价比更高,部署也简单,不过需要额外配置交换机和网卡,不能直接拿普通千兆交换机顶上。

我自己踩过的一个坑是机间通信带宽不足导致训练效率上不去。8卡单机内部互联很快,但是两个节点的网卡如果是25Gbps,百亿模型跑起来通信等待时间非常明显,跑分看着还行,一上真实训练就露馅。所以做集群规划的时候,建议节点间至少配100Gbps以上的RoCE网络,最好是200Gbps,否则分布式并行里的通信开销会直接吞掉算力增益。

1.2 软件栈与框架适配:CANN、torch_npu、MindSpore怎么选

昇腾的软件栈最底层是驱动和固件,上面是CANN(统一异构计算架构),再往上才是各种训练框架。CANN相当于昇腾的CUDA,负责算子调度、内存管理、图编译这些脏活累活。CANN里面有个很重要的工具叫Ascend Graph引擎,它会把训练脚本定义的算子构图编译成NPU能执行的整图或者子图,这个编译过程对性能影响极大,后面调优部分我会再展开。

框架层现在有三条路可选。第一条是MindSpore,这是昇腾的原生框架,也是华为主推的路线,优点是算子适配最全、性能优化最到位,用静态图模式训练效果最好,缺点是生态和PyTorch的差距还是存在,很多现成模型代码不能直接搬。第二条是PyTorch加torch_npu插件,这是目前社区里最常用的组合,torch_npu就是一个适配层,把PyTorch的算子调用桥接到CANN上,让PyTorch代码在昇腾NPU上跑起来。第三条是MindFormers这类大模型套件,它本身是基于MindSpore构建的,内置了GPT、LLaMA、ChatGLM这些主流模型结构的实现,同时支持数据并行、张量并行、流水线并行等策略的自动配置,适合做大规模训练的用户。

我个人的建议是:如果你不是非PyTorch不可,而且团队有精力学习新框架,MindSpore路线的长线收益高,尤其在图编译和融合算子这块,昇腾自己东西适配自己的硬件,性能上限更高。如果是急着把现有PyTorch代码迁移过来,那torch_npu是务实的选择,注意选对匹配版本就行,比如PyTorch 2.1对应torch_npu 2.1.0,CANN对应版本也有讲究,这些在官方文档都有明确的配套表,搬环境的时候一定要逐项核对,版本不匹配会出现各种奇怪的行为,后面调试章节会细讲。

2. 训练前必须做对的数据与模型准备工作

2.1 数据管线:语料清洗、Token化与持久化格式

很多人上手训练模型,第一件事就是找模型结构、配环境,反而把数据管线放到最后随便弄个DataLoader,结果一训练就发现GPU利用率忽高忽低,大量时间都花在等数据上。数据处理这件事在昇腾平台上尤其重要,因为NPU和CPU之间的数据拷贝跟GPU平台不太一样,不合理的数据管线会成为明确的性能瓶颈。

数据准备阶段,我一般按这个顺序走:先是语料清洗,把HTML标签、无关符号、重复段落、低质量文本过滤掉,这一步很多人会省略,但对训练质量影响非常大,尤其对垂直领域模型,数据和垃圾进垃圾出。清洗完之后是标准化,统一编码格式、处理繁体简体、规整标点,让文本进入Token化之前是一个干净、一致的状态。接着是Token化,这一步要决定用现成的Tokenizer还是自己训练,如果做中文场景,建议在通用词表基础上做扩充或者重新训练词表,考虑中文分词粒度,比如基于sentencepiece训练一个中文BPE词表,词表大小在32K到64K之间是比较合理的范围。词表太小会影响文本表示能力,太大又会增加embedding的内存开销和通信量。

Token化之后的数据需要落盘成便于高效读取的格式。昇腾平台上常用做法是转成MindRecord格式,这是MindSpore的原生数据格式,把样本打包成二进制文件,读取时用MindDataset加载,性能表现非常稳定。如果是PyTorch路线,也可以用WebDataset或者简单的内存映射文件格式。这里补充一个关键细节:不要用几百个小文件存数据,文件数量太大会导致I/O瓶颈,建议合并成10GB级别的大文件,哪怕是同一个数据集,也预先shuffle并切好分片,让每个训练进程都只读自己的分片文件,这是分布式训练数据管线的基本素养。

2.2 模型迁移:从CUDA代码到昇腾的常见改动

如果手上是现成的PyTorch模型,迁移到昇腾最理想的情况是只改设备指定,例如把torch.device('cuda')改成torch.device('npu')model.cuda()改成model.npu().to('cuda')改成.to('npu'),然后配上import torch_npu这个入口。但实际上很多模型会用到CUDA专属特性,比如torch.cuda.amp混合精度接口、torch.nn.DataParallel这类并行封装,这些在昇腾下往往有对应的替代方案,比如amp可以用torch_npu提供的混合精度接口,DataParallel可以用昇腾支持的DistributedDataParallel替代。

算子兼容性是最容易卡壳的地方。CUDA里有些算子在昇腾上没有对应实现,或性能极差,典型如某些自定义的cuda extension、特定的attention实现。这时有两个选择:一是改写模型结构,用Ascend上已有的算子组合去实现同样功能;二是走算子fallback路径,torch_npu会尝试把不支持算子切回CPU执行,这功能在调试期很省事,但训练期会巨慢,只能算应急,不能作为常态。跑大规模训练前,建议先花一天时间用小batch、少步数把整条链路过一遍,用profiling工具看有没有CPU fallback算子。如果发现大量fallback,趁早改代码,不要等到大规模训练才暴露。

另外一个容易忽略的是随机性对齐问题。如果迁移后要做精度对齐测试,需要在代码里固定各种随机种子,同时把CANN的确定性模式打开,也就是设置环境变量让算子计算结果可复现。昇腾上不同的算子在不同shape下计算顺序可能有差异,不定seed出来的loss曲线会对不上,这会让人误判成模型代码问题,实际上只是随机性问题。

3. 大模型并行策略拆解:从单卡到千卡集群

3.1 三种基础并行方式:DP、TP、PP到底在切什么

分布式训练里的并行方式,圈内简称“三种并行”:DP、TP、PP。很多新手看到这三个缩写就懵,其实用大白话解释特别简单。

数据并行(DP)是最直白的方式,相当于每个人拿一份完整模型的副本,各学各的数据,学完以后互相通报一下梯度,大家取个平均再一起更新参数。这种方案的问题在于模型必须能装进单卡显存,模型太大就放不下。

张量并行(TP)则是把一个矩阵运算切碎到多张卡上计算,好比把一个大型计算任务拆成小块分给多个计算员并行处理,每个计算员只负责一小块结果,最后拼起来。深度学习里最典型的是按头切分Attention层,或者把线性层的权重矩阵按列切分。TP的好处是能把超大模型塞进多卡,但坏处是每算一层都要跨卡通信,通信量大,通常只在单机内使用,因为机间通信延迟太高会严重拖慢速度。

流水线并行(PP)换个思路,按层切分。想象一条流水生产线,模型的第一层到第五层在卡A上算,第六层到第十层在卡B上算,数据像流水线上的产品一样,逐层往后流。这种并行方式通信开销相对小,但因为它是串行的,所以会出现流水线气泡,也就是某些卡处理完当前批次之后要等待前序卡的数据,空转等待。气泡时间可以通过micro-batch调优,把一个大batch拆成多个小batch依次灌进流水线,减少等待间隙。

3.2 昇腾场景下的3D混合并行与显存估算

真正训练几百亿甚至上千亿参数模型时,单一并行方式都不够,需要把DP、TP、PP结合起来,这就是常说的3D混合并行,也常被叫做混合并行策略。我的经验是,在昇腾平台上配置并行策略有个大原则:TP优先控制在单机8卡内部,因为它通信压力最大;PP用来横向扩规模,跨机的时候优先加PP;DP在最后补足规模,它的通信量最可控,通用性也最好。

举个例子,如果要在32张910B上训练一个130亿参数模型,单卡64GB显存,常见的配置是4路TP乘以2路PP乘以4路DP,也就是TP=4保证单机内部做张量并行,PP=2让模型按层切成两个流水段,DP=4让四组流水线各自处理不同批次数据,整个并行度计算下来是4×2×4=32,正好等于总卡数。这种配置下每张卡的显存压力、通信压力和流水线气泡基本能平衡在比较合理的区间。

显存估算方面有个经验公式可以先用起来。训练过程中显存主要被四个部分占用:模型参数、优化器状态、梯度、中间激活值。以FP16混合精度训练为例,参数是2字节每参数,梯度也是2字节,如果用AdamW优化器,每个参数还要额外存一份主权重(FP32,4字节)加上一阶动量(FP32,4字节)和二阶动量(FP32,4字节),仅优化器状态就12字节每参数。因此粗略计算单卡显存需求:参数总量乘以16字节,再除以并行度。假设130亿参数除以TP和PP的乘积,也就是130亿除以8,得到单卡约16亿参数,再乘以16字节约26GB,这只是静态容量的保守估计,还没算激活值。激活值这个变量很大,取决于序列长度、batch size和模型结构,通常再预留20GB到30GB比较安全。如果发现接近或超出64GB,优先调小微批次大小,减小序列长度,或者开激活重计算,这是释放显存最立竿见影的手段。

4. 调试实战:我踩过的高频报错与排查思路

4.1 设备层问题:卡不识别、驱动不匹配、HCCL通信失败

昇腾训练调试和CUDA平台有个非常大的差异:因为CUDA生态成熟,很多问题能在更上层暴露,但昇腾如果底层环境有偏差,会直接表现为各种诡异现象。最常见的设备层问题就是执行npu-smi info时看不到卡,或者卡的状态是异常。遇到这种情况我先查驱动和固件版本是不是和CANN配套,这是头号原因。昇腾官方有一张软硬件兼容性列表,驱动、固件、CANN版本必须严格对应,比如CANN 7.0配的是哪个版本的驱动、升级CANN之后驱动没跟上、设备就会异常。解决方式很简单,按官方配套表重装对应版本,然后把内核重启一下。

第二个高频问题是HCCL通信初始化失败。集群训练时,多机HCCL初始化报错,常见的现象是HCCL connect timeout,这种多半是网络问题,例如节点之间防火墙没放行通信端口,或者RoCE网络没有正确配置。排查可以直接用hccl_tools.py脚本生成rank表,然后跑一个简单的allreduce测试,如果单机allreduce通过而多机失败,问题基本就锁定在节点间网络上。另外,rank表配置也要检查,device_id和物理卡号是否一一对应,IP地址是否写成了管理网地址,这些都是我实际见过的坑。

还有一个值得一说的是容器场景。昇腾NPU在容器里使用需要挂载设备,需要设置昇腾专属的设备插件,比如Ascend Docker Runtime。很多人本地跑通了,一进容器就找不到设备,原因就是容器运行时没配置好。Kubernetes集群里还要额外部署对应的NPU device plugin,这部分和GPU的nvidia-device-plugin用法类似,只是插件名和参数不同。

4.2 训练过程问题:loss不降、NaN、算子不支持和OOM

训练过程中遇到的bug,按我的经验可以分为四类:loss不降、loss出现NaN、算子不支持、显存溢出OOM。

loss完全不降,先别急着怀疑优化器或者学习率。我会先确认数据是不是对上了,比如tokenizer之后数据是否真的包含有效语义、标签是否和输入对齐。如果数据没问题,再看模型输出层是否挂了正确的损失函数,有些模型在迁移时会把损失函数漏掉或者写错。然后是学习率,大模型训练一般要用warmup加余弦衰减,如果用固定学习率且偏大,很容易导致初始阶段loss震荡不收敛。最后检查梯度。做一个梯度打印,看看回传的梯度数值是不是正常量级,梯度为0或者梯度爆炸都能快速定位到具体层。

loss出现NaN是另一个棘手问题。在混合精度训练下,NaN最常见的原因是fp16的数值溢出,表现为loss突然变NaN,并且梯度里出现极大值。对策也明确:一是使用动态loss scaling,torch_npu上调整对应混合精度缩放因子的策略;二是改成bf16,bf16的指数位和fp32一样,动态范围更大,但低精度尾数可能影响收敛精度,需要具体任务测试。还有一个经常被忽略的原因是某些算子在低精度下对极端shape敏感,比如LayerNorm在fp16下处理某些激活值会溢出,这时需要把特定算子强制用fp32计算,或者开启算子级别的精度补偿。

算子和显存问题,刚才讲模型迁移时已经提到了算子不支持,这里补充OOM。OOM分两种,一种是显存不足直接报错,另一种是显存碎片导致的OOM。前者优先调减微批次大小为2的幂次、降低序列长度、开激活重计算;后者在昇腾上可以通过设置内存管理环境变量,让CANN做显存碎片整理,开启block释放策略。每次调整batch size之后,建议重新跑一遍profiling,观察显存峰值,而不是只盯着有没有报错。

5. 性能调优关键手段:利用率、通信与精度三者平衡

5.1 监控先行:npu-smi和profiling怎么看瓶颈

性能调优第一步永远是量化分析。很多人一上来就调参数,不看数据,这跟盲人摸象差不多。昇腾上有一套完整的性能分析工具,既有命令行工具也有可视化profiling工具。最简单的是执行npu-smi info查看实时算力利用率、温度和显存占用,每几秒刷新一次。如果训练过程中NPU利用率长期低于80%,说明训练流程中存在严重等待,要么在等数据,要么在等通信。

数据加载瓶颈怎么看?一个简单方法是把数据加载时间单独打点,在训练循环里记录每个step的耗时,把数据加载和forward/backward分开计时。如果数据加载时间占比超过10%,就需要优化,常见手段包括增加num_workers、开启数据预取、把数据落成MindRecord这类更高效的格式,以及把数据文件分布到更快的NVMe磁盘上。训练中期我还会做一个实验,把模型固定住不更新参数,只跑forward和backward,如果这个基准耗时远低于实际训练耗时,通信或数据一定有问题。

通信瓶颈的判断方法更直接。测不同并行配置下同一个step耗时,比如同一模型分别用TP=4和TP=8各跑50步,对比单步耗时变化。如果TP从4增加到8,单步耗时反而显著上升,那说明通信开销已经大于并行收益。这种时候就要调整并行配置,把TP降下来,用PP或者DP替代。

profiling工具带出的信息还包括算子耗时排名。看单个算子耗时前20名,通常会发现瓶颈集中在attention计算、LayerNorm、激活函数或者embedding上。昇腾平台上有些算子的融合版本明确比逐个算子快很多,典型比如FusedRMSNorm融合归一化计算、FlashAttentionScore融合attention计算,这些融合算子在框架层提供接口,把对应模块替换掉,单步速度提升10%到30%都不罕见。

5.2 混合精度、梯度累积与静态图编译的调优实践

精度策略是训练性能的关键变量。大模型训练在昇腾平台上,我推荐的组合是FP16/BF16混合精度加动态loss scaling。FP16能大幅减少显存占用和计算量,但前面提到的数值溢出问题需要靠loss scaling兜底。这里建议初始缩放因子设成65536,之后让框架自动动态调整,如果梯度超过阈值就降低缩放因子,如果连续多步没有溢出就增加缩放因子。BF16不需要loss scaling,因为它的动态范围和FP32接近,但低精度尾数会让有些模型收敛变慢。实操中我会准备两套配置,先跑小规模实验对比两者收敛曲线,选效果更好的再上全量训练。

梯度累积是解决显存不足的常用手段,原理就是攒够多个小batch的梯度之后再更新一次参数,效果等价于增大batch size。昇腾上做梯度累积有几个细节要特别注意:梯度累积步数设成多少,要看总的等效batch size是否符合模型训练的预期,比如目标batch size是512,单卡每次只能跑4条样本,32卡数据并行下每步能跑128条样本,那梯度累积步数是4。另外,累计梯度期间BatchNorm这类依赖batch内统计信息的层会受影响,大模型通常用LayerNorm不受此问题影响,但如果是CNN类模型要谨慎。

静态图编译是我强烈推荐的大模型训练加速手段。PyTorch默认是动态图模式,边执行边构图,灵活但开销大。昇腾的CANN本质上更适合静态图,当训练脚本以静态图方式运行,整个计算图会被完整编译优化,算子融合、内存复用都能充分发挥。如果走torch_npu路线,可以考虑把关键训练循环用图模式编译,也可以用torch.compile配套昇腾后端。MindSpore默认调优就建议跑静态图模式,性能提升立竿见影,代价是动态shape处理要提前设计好,比如输入序列长度不要频繁变化,尽量padding成统一长度。这个约束在NLP训练场景下很自然。

通信优化方面还有一个实用技巧:调整HCCL的buffer大小。HCCL默认通信缓冲区可能不够,在大模型场景下会造成频繁等待甚至通信超时,把HCCL_BUFFSIZE设为256或更大,往往能明显降低通信等待时间。另外,开启梯度压缩或者使用梯度分桶通信机制,让梯度数据分成小桶并行传输,也能降低通信峰值压力。这些参数都藏在环境变量里,不踩过坑的人很难主动去设置。

6. 另一类全流程实践:从3D重建到垂直行业微调

6.1 昇腾跑3DGS三维重建的要点

最近很火的三维重建方向,3DGS,也就是3D高斯泼溅,很多人在昇腾上尝试跑通训练流程。3DGS的核心是CUDA实现的栅格化器和一系列自定义算子,迁移到昇腾的主要工作就是把自定义CUDA算子替换成昇腾原生算子或者用torch_npu支持的算子重写。这一步绕不开,也是最费时间的地方。

我的建议是先梳理3DGS的算子清单,找出哪些能用原生算子组合替代,哪些必须自己开发。常见的高斯投影、alpha混合这些操作,在昇腾上可以用组合算子和自定义算子的方式实现,工程量大,但对理解昇腾的算子开发框架有巨大帮助。如果只是想快速验证效果,也可以考虑用纯PyTorch实现的高斯栅格化版本跑小场景实验,性能差一些,但能先把流程跑通。

昇腾上做3DGS训练还有一个优势,就是它的高显存容量对三维重建这种吃显存的任务比较友好。之前在单个游戏场景上做训练,点云数量几十万级别,单卡64GB完全够用。关键是OpenGL和pyrender这类依赖光栅化的库在NPU环境里不可用,遇到渲染相关的预处理步骤要改用numpy和PyTorch纯张量操作来实现。整体来看,3DGS迁移到昇腾是一个典型的算子迁移项目,工程量集中在前端算子映射,一旦算子打通,训练流程和常规视觉模型训练没有本质差别。

6.2 垂直行业大模型微调的数据来源与流程组织

除了通用大模型,垂直行业大模型的微调也是现在需求量非常大的方向,比如之前讨论很多的数控机床维修垂直大模型。这类行业模型和通用大模型不一样的点在于数据来源高度分散,训练流程很多时间其实花在数据工程上。

以数控机床维修为例,训练数据的来源至少可以列出六类:一是在线数据,包括维修论坛、行业社区、技术博客上的问题讨论和解决方案;二是离线技术文档,包括设备手册、维修手册、电路图纸说明、PLC程序注释,这些需要OCR转成文本;三是设备日志数据,数控系统会记录大量报警代码、故障代码、主轴负载曲线和伺服驱动器参数,这些时序数据和代码文本组合在一起能形成非常有价值的维修样本;四是维修工单数据,售后系统和报修记录里有大量历史故障描述、维修过程和结果,这是真实的问答对;五是专家经验,通过访谈资深维修工程师,把隐性经验转写成结构化的问答对;六是标准规范,包括国家标准、行业规范中的安全要求和操作规程。

数据收集回来之后,整理流程比通用语料更重。要做去敏感信息处理,比如客户名称、地点、设备编号这类信息脱敏。要做问答案例清洗和重写,把短答案扩写成完整的维修指导文本,或者把长文本压缩成精准的问答对。垂直领域微调我更推荐用LoRA这类参数高效微调方式,只需要在推理阶段前加载LoRA权重,不用改动基座模型本身,训练的算力和显存要求都低很多,一张910B就能跑通中等规模数据的微调。

6.3 开源训练平台与自己的落地选型建议

聊到开源的大模型训练平台,昇腾生态圈其实已经有不少可选项目。官方维护的MindFormers是一站式大模型训练套件,支持从数据准备到分布式训练、评测、部署的完整流程,内置多种主流模型结构,也支持自定义模型迁移进来。基于MindSpore社区的ModelZoo里面也沉淀了大量模型案例,可以直接参考训练配置。另外还有面向科学计算和行业应用的MindScience套件,以及针对三维重建和其他图形任务的MindX系列工具,覆盖的面越来越广。

选平台的时候我的建议是,不要盲目追求大而全,而是看自己的团队现状。如果团队熟悉PyTorch,又想尽量少改代码,那么基于PyTorch的torch_npu加一套分布式训练框架就够用了,先把代码跑通,再逐步替换掉性能差的算子。如果是从零开始做训练平台建设,MindFormers这类一站式套件的价值就体现出来了,它把数据格式、并行配置、checkpoint管理这些细节都做了统一封装,团队不需要自己重复造轮子。如果做的是科学计算或者三维重建这种算子自定义比例高的场景,那么可能需要同时掌握MindSpore静态图开发和自定义算子开发两条路线。

平台选型还有一个现实问题是调试工具链的成熟度。昇腾的调试工具在快速迭代,但和CUDA生态的成熟度相比还有差距,所以建议选平台时优先看它的profiling、算子分析和性能日志工具是否完整。真实训练时,这些工具决定你排查问题效率的上限。

最后再分享两个小经验

第一,训练脚本里从第一行开始就加上详细的日志,每打印一次loss就记录当前学习率、全局步数、吞吐量、显存余量、数据加载耗时这些关键指标。我养成的习惯是每50步打一次摘要日志,每500步触发一次profiling采样。很多难缠的性能问题,事后复盘时靠这些日志就能直接定位,省去大量重新排查的时间。

第二,昇腾环境做版本升级一定要先小规模验证再生产。每次升级CANN、torch_npu或者驱动,先把之前跑通的训练任务在小数据集上重跑一遍,观察loss曲线和单步耗时是否有变化,确认指标不回退后再启动正式训练。我踩过一次大版本升级之后融合算子行为变化导致loss波动的情况,排查了两天,最后发现是版本升级后算子融合策略变化,回退版本就恢复正常。版本升级后第一时间做回归测试,这个习惯值得养起来。

如果你正在从别的平台迁移大模型训练任务到昇腾,不用一开始就追求全套性能指标达标,先把全流程跑通,再逐步做算子替换和性能优化,这条路走起来最稳。昇腾这套生态还在高速发展期,很多今天觉得麻烦的问题,过几个月可能就已经被新版工具链解决掉了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询