大模型并行训练全解析:从显存墙到混合并行实战

单机显存耗尽,训练脚本崩溃退场的那晚,我盯着屏幕上的OOM日志,第一次意识到并行训练不是加分项,而是AI应用架构师的硬门槛。后来陆陆续续在多个大模型项目里折腾分布式训练,从单机多卡到多机多卡,从数据并行一路改到流水线、张量并行混合编排,踩过的坑大概够写一本小册子。这篇笔记,就把我对AI模型并行训练的完整理解拆开讲,从为什么要并行、四种并行范式怎么选、框架怎么落地,到显存怎么算、通信怎么优化、故障怎么查,一次性把这条链路讲透。


1. 单卡装不下、单卡跑不动:并行训练到底解决了什么问题

很多人第一次接触并行训练,都是被同一个现实问题逼的:模型太大,一张卡放不下。但等到真上手之后你会发现,“放不下”只是表面现象,背后其实是两个完全不同的瓶颈——显存墙和算力墙。这两个瓶颈决定了你要用哪种并行策略,也决定了你的训练效率和成本上限。

1.1 显存墙:模型参数只是冰山一角

先说显存。很多人有个误区,觉得模型显存占用就是权重参数大小。一个70亿参数的模型,按FP16算差不多14GB,现在一张80GB的加速卡看起来绰绰有余。但真训练起来,显存账单远比这复杂。

训练过程中显存至少要被四个东西分走:

  • 模型参数本身:权重矩阵,也就是那14GB的FP16数据。
  • 梯度:反向传播时要算出来的梯度,规模和模型参数一样大,又是14GB。
  • 优化器状态:以Adam优化器为例,它要为每个参数额外保存一阶动量、二阶动量,而且为了数值稳定,这两个状态通常用FP32保存。算下来一个参数要额外占8字节,70亿参数就是56GB。
  • 中间激活值:前向传播过程中每一层的输出都要暂存,供反向传播计算梯度使用。这个量极其惊人,尤其在高分辨率输入、长序列场景下,激活值甚至比参数本身还占显存,随序列长度和批大小线性增长。

把上面几项加一加,70亿参数的模型用Adam训练,光参数、梯度、优化器状态就要80多GB,一张80GB的卡直接吃满,激活值还没地方放。这就是“放不下”的真相。更别提千亿参数的模型,那显存需求直接奔着几百GB甚至上TB去了。

所以并行训练的第一个核心目标,就是把显存需求拆开,让一堆小房间拼成一个大仓库。拆法不同,就有了后面要讲的各种并行范式。

1.2 算力墙:训练周期长到不可接受

就算显存能放下,还有一个更隐蔽的问题:算力。单张加速卡的计算能力再强,也有物理上限。训一个百亿参数的模型,单卡可能要跑几个月甚至一年。业务等不了,研究也等不了。

举个直观的例子。假设单卡每秒能处理100万token,一次训练要跑5000亿token,单卡就需要跑50万秒,大约是5.8天。但如果只用单卡,数据读取、通信、同步损耗全算上,实际吞吐还要打个对折,训练周期直奔两周。模型再大一点,单卡跑上几个月都不稀奇。

并行训练第二个核心目标,是通过多卡协同把训练总时长压缩到业务可接受的范围。同样是5000亿token,如果用128张卡做数据并行,理想情况下能把5.8天压缩到1小时左右。当然,实际情况因为通信开销不可能做到完美线性扩展,但即使只有70%的扩展效率,也已经是从“不可用”到“可用”的跨越。

1.3 什么人需要吃透并行训练的底层逻辑

说了这么多,到底谁需要学这个?我的经验是,三类人最需要:

  • 算法工程师转全栈:你设计了一个新模型,想在更大规模数据上验证效果,但只会单卡脚本。你说模型效果不行,实际可能是训练规模和策略不对。
  • AI平台/基础设施工程师:要服务多个算法团队跑各种规模的训练任务,不懂并行训练的底层逻辑,排障会非常吃力。
  • AI应用架构师:要设计从数据到模型到服务的完整方案,对训练成本、周期、扩展性必须有清晰判断,否则技术选型就是拍脑袋。

尤其现在大模型相关应用遍地都是,动不动就要微调、继续预训练、领域适配。如果只会搬一张卡去硬练,成本和周期都会失控。并行训练不是研究员的专属技能,已经逐渐变成AI应用落地的通用基本功。


2. 四种并行范式逐个拆解:数据并行、流水线并行、张量并行、混合并行

并行训练这些年沉淀出了几种经典范式,它们解决的是不同层面的问题。很多初学者一上来就懵,是因为不知道这些名词对应什么场景。我用一个模型训练的过程来打个比方。

训练一个模型,本质上就是反复做三件事:前向传播算预测、反向传播算梯度、优化器更新参数。并行化的核心思路就两条:要么让多张卡各算各的,最后把结果汇总;要么把一个模型切成好几块,每张卡管一块。所有范式都是这两条思路的变体。

2.1 数据并行:最简单也最常用的一条路

数据并行,英文叫Data Parallelism,这个思路非常朴素:每张卡上都放一份完整的模型副本,把训练数据切成多份分给各张卡,每张卡独立算梯度,然后通过聚合梯度的方式把模型同步起来。

它的优势是容易理解、实现成熟、扩展性好。PyTorch里封装的DDP(DistributedDataParallel)就是数据并行的典型实现,市面上大部分训练任务也都从数据并行起步。

它的局限也很明显:每张卡都要能放下一整个模型。模型小的时候,数据并行几乎是最优解;模型大到单卡放不下,数据并行就彻底失灵了。用我们前面说的70亿参数模型来看,单卡光参数加优化器状态就80多GB,数据并行根本跑不起来。

所以在实际项目里,我通常把数据并行作为基础底座,再往上叠加其他并行策略。

2.2 流水线并行:按层切分,用气泡换显存

流水线并行,Pipeline Parallelism,思路是把模型按层切成多段,每张卡负责其中一段。比如一个12层的Transformer,切成3段,每张卡管4层。数据按顺序流过第一张卡、第二张卡、第三张卡,每一段算完再把中间结果传给下一段。

这个方案解决了“模型太大放不下”的问题,因为每张卡只存一部分模型参数。但它有个著名的副作用叫“气泡”(Bubble):在某张卡等待前面卡片计算结果的时候,它其实是空闲的,这个空闲时间就是流水线上的气泡,会拉低整体利用率。

为了减少气泡,后来又发展出微批次流水线策略,把一个大的batch拆成很多个micro-batch,让流水线尽量保持忙碌。即便如此,纯流水线并行的硬件利用率通常也到不了90%,设计不好很可能只有60%左右。

流水线并行适合那种“模型特别深、每层又特别重”的场景,比如超深Transformer。实际项目中,它更多是和数据并行组合出现,比如每张卡管一段模型,同时每组卡都处理不同的数据批次。

2.3 张量并行:算子内部的切分艺术

张量并行,Tensor Parallelism,和流水线并行的思路完全不同。它不是按层切,而是在某一层内部把一个矩阵乘法切到多张卡上算。

举个例子,一个全连接层的计算是Y = XW。张量并行可以把权重矩阵W按行切成两块、按列切成几块,分给多张卡各自算一部分,最后再做一次汇总。这样单卡上每层的显存占用就变小了,而且计算本身也被并行加速了。

听起来很美好,但张量并行有个要命的问题:通信量极大。因为每一层前向、反向都要做多次AllReduce或AllGather操作,卡间通信几乎成了瓶颈。业界做千亿参数模型时,把张量并行维度卡在2、4、8这种规模,很少敢开到很大,就是因为通信扛不住。

张量并行一般用在“单机多卡”场景,因为机内通信带宽高(比如NVLink),机间通信延迟太大就会拖垮性能。如果是多机训练,通常要把张量并行维度限制在单机内部。

2.4 混合并行:大模型训练的标准答案

写到这里,你一定猜到了:真正训练超大规模模型,用的绝不是单一并行策略,而是把三种策略组合起来,形成混合并行的三维空间。

怎么理解这个三维空间?我习惯用一个坐标轴来想:

  • 张量并行维度:在一台机器内,把模型某层切成多份,用高速卡间通信解决。
  • 流水线并行维度:跨机器切模型层,每台机器管其中一段。
  • 数据并行维度:把训练数据复制到多组并行的模型副本上,同步更新参数。

举个例子。假设你有64张加速卡,可以先把张量并行设为4,让4张卡组成一组,共同负责一个模型层的计算;再把流水线并行设为4,让4组串联起来覆盖模型的不同层;最后把数据并行设为4,让这么一条模型管道复制4份,分别处理不同数据批次。整体算下来就是64 = 4 × 4 × 4。

这种“TP × PP × DP”的三维混合并行,就是现在主流千亿模型训练的标配。各大分布式训练框架也都默认支持这个组合,你只需要提供配置文件,框架自动帮你生成并行矩阵。


3. 从单卡脚本到分布式训练:框架选型与架构设计的实操落地

理解了四种范式,接下来就是动手。我见过太多同行卡在这一步:理论都懂,一跑就错。这一节我会从框架选型、最小改造方案、关键参数三个层面讲实际操作。

3.1 最短路径:用现成分布式框架跑起第一个多卡任务

现在的深度学习生态,已经不需要你从零手写分布式训练逻辑了。主流框架都内置了分布式训练能力,你需要做的是“选一个、用起来”。

我自己的习惯是分场景选择:

  • PyTorch DDP:如果你用的是PyTorch,模型还没大到单卡放不下,DDP是优先级最高的方案。改造成本极低,只需把模型用DDP包一层,再配合启动工具,单卡脚本几乎不用大改。
  • DeepSpeed:如果你想在数据并行基础上做显存优化,比如用ZeRO系列把优化器状态、梯度、参数拆到多卡上,DeepSpeed是首选。它可以作为PyTorch的插件使用,配置灵活。
  • Megatron-LM风格引擎:如果你要训练百亿、千亿规模的模型,需要完整的TP+PP+DP混合并行支持,这类框架会把模型层切分细节都处理好。
  • Horovod:老牌分布式训练框架,跨框架兼容性好,但现在新项目我很少再用它,生态活跃度不如PyTorch原生的方案。

先看一个最基础的DDP改造,单卡训练代码只需要改三行:

# 原来的写法: model = MyModel() train_loader = DataLoader(dataset, batch_size=32) # DDP改造后: import torch.distributed as dist from torch.nn.parallel import DistributedDataParallel as DDP # 1. 初始化进程组 dist.init_process_group(backend="nccl") # 2. 把模型放在对应的GPU上并包一层DDP model = DDP(MyModel().to(rank), device_ids=[rank]) # 3. 数据加载器里要设置分布式采样器 train_loader = DataLoader(dataset, batch_size=32, sampler=DistributedSampler(dataset))

启动训练也很简单,PyTorch已经封装好了多卡启动命令:

# 单机8卡训练,pytorch 2.x以上推荐用torchrun torchrun --nproc_per_node=8 train.py

看起来很简单对吧?但实际项目里,还有几个细节非常容易踩坑。比如DistributedSampler必须要搭配shuffle=True时在每个epoch开始时调用set_epoch(epoch),否则每个epoch的数据打乱顺序都一样。又比如batch_size这个参数的含义,在DDP里通常指的是“每张卡上的batch大小”,而不是“总batch大小”,配置学习率的时候很容易搞混。

3.2 关键参数怎么定:批大小、学习率与通信后端

跑分布式训练,最核心的三个参数分别是批大小、学习率、通信后端。

先说批大小。数据并行时,总批大小 = 单卡批大小 × 卡数。举个例子,单卡批大小是32,使用8卡并行,那总批大小就是256。注意,这个总批大小会直接影响模型的收敛行为。经验法则是,批大小翻倍时,学习率也要适当放大,但放大倍数不能照搬,通常用线性缩放法则或者平方根缩放法则做参考。

线性缩放法则意思是,总批大小从B变成kB,学习率就从lr变成k*lr。但这个法则在批大小很大时就会失效,实际中我经常用平方根缩放更稳妥,也就是lr变成sqrt(k)*lr。具体还是需要做小规模试跑对比。

再说通信后端。PyTorch的DDP默认用NCCL(NVIDIA集合通信库),这是最稳妥的选项。NCCL后端有几个环境变量值得关注:NCCL_DEBUG=INFO可以输出详细的通信日志,排障的时候很有用;NCCL_SOCKET_IFNAME在多机互联时要显式指定网卡名称,比如NCCL_SOCKET_IFNAME=eth0,否则可能因为选错网卡导致通信极慢。

我还发现一个很迷的坑:在DDP里设置find_unused_parameters=True的场景。如果你的模型里有参数没有参与梯度计算(比如冻结部分层、或者有多分支结构中某些分支没走),你必须把这个参数打开,否则会报错。但打开之后性能会略有下降,所以能用默认值还是用默认值,冻结层可以用requires_grad控制而不是启动这个参数开关。

3.3 部署形态的取舍:单机多卡、多机多卡与弹性训练

我接触过的项目,分布式训练的部署形态无非三种:单机多卡、多机多卡、弹性训练。

单机多卡最简单,所有卡都在一台物理机上,通过PCIe或NVLink互联,通信延迟低,故障域小。大多数团队刚开始做分布式训练,都是从这个级别起步。需要注意的只有散热和供电,8卡满负荷跑起来,机房空调要是扛不住,会看到奇怪的计算降频,表现为训练变慢但日志无报错。

多机多卡就要复杂一个量级。第一是网络,节点间通信至少需要万兆网,RoCE或者InfiniBand更好。第二是存储,训练数据最好放在所有节点都能访问的共享存储上,避免每个节点拷一份数据导致版本不一致。第三是容错,任何一个节点挂了,整个训练任务就前功尽弃。

弹性训练是最近几年越来越常见的形态,它允许训练任务在运行过程中动态调整节点数量。节点加入或退出不用重启任务。云上场景特别适合弹性训练,因为抢占式实例便宜,被回收了再重新拉起新节点加入训练池即可。各大云厂商的AI训练平台基本都支持这个能力。我的建议是,如果你的训练任务超过N天,弹性训练的价值会非常明显,值得一开始就设计进去,而不是把节点看成不可变资产。


4. 显存估算与通信开销:并行训练的数学账本

很多人跑并行训练失败,不是代码写错,而是方案一开始就算错了。这里我公开一套我自己一直在用的估算方法,它帮助我把很多训练任务的资源需求预测得很准。

4.1 参数、梯度、优化器状态各占多少显存

假设某个模型参数量为Ψ,这个数字可以很容易从模型定义里数出来。以Transformer解码器为例,每一层的参数主要是注意力机制的Q、K、V、O矩阵和MLP层的两个全连接层,加总的权重大致可以由隐藏层维度H和层数L算出来。

训练时显存底线的计算公式如下:

  • 模型参数(FP16):2Ψ字节
  • 梯度(FP16):2Ψ字节
  • Adam优化器状态:4Ψ(FP32参数副本) + 4Ψ(一阶动量) + 4Ψ(二阶动量) = 12Ψ字节

参数 + 梯度 + 优化器状态 = 16Ψ字节。这个“16字节/参数”是我后台做资源评估时最常拍脑袋用的基准数。

看个实例。70亿参数的模型(7B),底线性显存需求 = 7 × 10⁹ × 16 = 112GB。一张80GB的卡绝对扛不住,至少要2张80GB卡,这还没算激活值。如果你用DeepSpeed的ZeRO-2/ZeRO-3把优化器状态、梯度、参数再做切分,这部分开销才能分散到更多卡上。

激活值的估算更复杂,它取决于序列长度、批大小、隐藏维度、层数。粗略经验是,对于7B模型、序列长度2048、批大小1的情况,激活值可能需要几十GB。所以激活值重计算技术(Activation Checkpointing)才会这么流行,它用一部分计算换显存,能让峰值显存下降到原来的三分之一左右。

4.2 通信量决定加速上限,别忽略拓扑结构

并行训练除了显存,另一个必须算清楚的是通信量。这里我最常说的一句话是:并行策略的收益是显存,代价是通信,而通信是决定扩展效率的隐形天花板。

数据并行的通信量主要来自每步训练结尾的梯度AllReduce。梯度大小和模型参数一样大,所以每训练一步,各卡就要把和模型一样大小的数据聚合一遍。模型越大,这一步通信耗时越明显——这恰恰是很多人把数据并行扩展到256卡之后,发现加速曲线变平甚至下降的原因。

张量并行的通信量更大。每次前向或反向传播都需要AllReduce多次,且是在每层计算过程中高频发生。所以TP维度一加大,GPU利用率立刻下滑。这也是为什么很多框架默认TP≤8,就是为了把通信控制在一台机器内部的NVLink带宽范围内。

流水线并行的通信量相对最小,因为它只需要在流水线段的边界传输激活值和梯度,通信频率远低于TP和DP。但因为流水线会导致气泡,它的代价更多体现在计算利用率上。这也是为什么业界常说“TP管单卡显存、PP管节点间显存、DP管吞吐”。

实操层面,我一般会用下面这个办法快速估算扩展效率:先测单卡吞吐,再测多卡吞吐,算出实际加速比,然后用“加速比/卡数”得到扩展效率。70%以上说明并行策略合理,低于50%就要重新审视通信瓶颈了。

# 观测每张卡的吞吐,这里以某个框架为例 # metrics: samples_per_sec / tokens_per_sec / gpu_util watch -n 1 nvidia-smi

4.3 经典配置思路:不同参数量下该怎么切

下面这张表是根据我的实操经验整理的并行策略参考,它不适用于所有场景,但作为起点非常保险:

模型规模推荐并行策略显存方案典型卡数
1B ~ 7BDP或ZeRO单卡或ZeRO-1/24 ~ 32
13B ~ 30BPP + DP 或 ZeRO-3配合激活重计算32 ~ 128
70B+TP × PP × DP 混合并行ZeRO + 激活重计算128 ~ 1024+

这里要强调一件事:没有绝对最优的并行配置,只有当前资源下的局部最优。比如你有64张卡,想把7B模型训得更快,你可以选择纯DP的64卡方案。但如果你发现通信已经成为瓶颈,那考虑把PP维度设为2,把同一份模型分成两段,每段再放到32卡上做DP,往往能改善整体效率。

我自己调参时有个习惯:先用8卡做一次小规模试跑,用训练框架自带的性能分析工具看一下“计算时间、通信时间、空闲时间”三者的占比,再去调并行维度。比盲目堆卡有效得多。


5. 踩坑实录:并行训练常见问题与排查方案

这部分内容全是我自己的血泪经验。说实话,并行训练相关的报错信息千奇百怪,但绝大多数都离不开几个根因。这里我把典型问题和排查路径整理成了一份速查表。

症状常见根因排查方向
训练启动后卡住,日志不动进程组初始化失败、卡间握手超时检查网络连通性、网卡环境变量
显存溢出OOM单卡显存超限、激活值爆炸计算显存账本,开启激活重计算
loss NaN或剧烈抖动学习率过大、批大小变化带来收敛问题回退学习率、检查混合精度配置
训练速度远低于预期通信拓扑瓶颈、数据加载缓慢用性能分析工具定位通信和IO占比
某节点报错导致任务终止单点故障、存储权限不一致启用检查点续训、统一环境配置

5.1 一上来就显存溢出,先分清是哪种OOM

显存溢出是我被问得最多的问题。很多新手一看到CUDA OOM就慌了,其实先要分清是哪种OOM:

第一种是显存本身不够。这种最简单,报错会明确告诉你要多少,还差多少。你按我前面说的显存账本估算一下,就能判断是不是模型太大、batch太大、或者序列太长。

第二种是显存碎片化。明明单卡显存容量足够,但跑着跑着就OOM。这种报错往往出现在训练一段时间之后,而不是启动第一步。排查方法很简单,把batch调小一点试试,如果调小后能稳定运行,大概率就是碎片化问题。可以从调整内存分配策略入手,比如设置PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:32,把显存按小块分配,降低碎片。

第三种是峰值显存瞬涨。比如开启了梯度累积、或者某个特殊sample特别长,导致某一轮的中间激活值飙升。这种我一般用梯度累积配合动态batch策略解决,或者把激活重计算打开,牺牲一点速度换稳定性。

5.2 NCCL超时与死锁,多半是通信拓扑的问题

NCCL报错通常非常抽象,最常见的几类我都遇到过。

“NCCL Timeout”是最让人崩溃的。多机训练中,节点间网络抖动或防火墙策略会直接导致超时。排查思路就是先确认节点间能连通,然后用NCCL自带的nccl-tests跑一遍带宽测试。如果带宽正常,再检查是否因为NCCL_SOCKET_IFNAME选错网卡,导致走了数据网络而不是高速计算网络。

“Deadlock / stuck”场景则是通信集合不匹配。典型的场景是,你在代码里写了一个if条件,某个rank执行了AllReduce,另一个rank因为条件不满足跳过了AllReduce,那么所有rank都会卡死等待。这个问题的排查方法是看日志里最后一条通信操作在所有rank上是否一致。我的习惯是,分布式代码里尽量避免有条件的通信操作,如果有条件分支,也要保证所有rank的执行路径一致。

5.3 loss不收敛或剧烈抖动,可能是并行策略带偏了学习率

很多现象看似是算法问题,实际是并行策略带来的数值问题。

最典型的是loss曲线突然抖动,NaN频出。原因之一就是有效批大小变化导致梯度噪声分布变了,而学习率没跟着调。另一个常见原因是混合精度训练时的loss scaling配置不合理,梯度出现overflow,导致NaN。

排查这类问题,我有一套固定的三板斧:

  1. 先关掉并行,用单卡小batch跑几个step,看loss是否正常。
  2. 确认并行配置下,每张卡上的数据顺序和单卡运行一致(可以打印对比前几个batch)。
  3. 如果单卡正常、多卡异常,优先怀疑学习率和loss scaling,把学习率先降一个数量级再跑。

5.4 排障三板斧:日志、监控、最小重现

最后分享一套通用排障方法论。遇到任何并行训练问题,我会按下面三步走:

  • 第一步,看日志。启动时会打印进程组信息、rank编号、卡号、通信库版本,这些信息能快速帮我判断环境配置是否有问题。
  • 第二步,看监控。显卡温度、功耗、显存、PCIe/NVLink带宽、网络吞吐,这些指标能定位是算力瓶颈还是通信瓶颈。我见过不少“训练卡死”,一看图发现网卡流量为0,直接就定位到网络配置问题了。
  • 第三步,最小重现。把训练脚本缩到最小规模,2张卡、1个batch、模型砍到几层,看能不能复现。能复现,问题就在代码逻辑;不能复现,大概率是资源或规模的边界条件问题。

这套方法论帮我解决过很多看起来很吓人的故障,核心思路就是“解规模、拆条件、找最小可疑点”。


6. 从“能跑”到“跑得好”:架构师层面的平台化思考

当你把并行训练跑通,并且能在几十张卡上稳定训练之后,下一个阶段的问题是:如何让整个组织都能经济、高效、稳定地使用并行训练能力。这部分属于架构师的更高阶职责,我简单分享三个方向。

6.1 算力资源调度与多任务编排

训练任务往往不是孤立存在的。一个团队可能同时跑多个实验,数据并行任务、混合并行任务、微调任务并存。如果没有统一的资源调度,很容易出现资源争抢或者闲置。

我见过比较靠谱的方案是引入任务队列和配额机制。每个训练任务提交到队列后,由调度器根据优先级和资源池剩余容量决定是否启动。这样做的另一个好处是,当某个高优先级任务需要更多显卡时,可以抢占低优先级任务的资源,而低优先级任务的检查点机制能保证它后续可以原地续跑。

如果你所在团队体量不大,一开始就用Kubernetes加专业AI调度器可能太重了。我更建议先从脚本层面做简单的“排队–启动–回收”流程,等实验规模真的上来了再引入重方案。工具永远是服务业务的,别为了架构而架构。

6.2 训练可观测性:看板、日志和告警

分布式训练最大的幻觉是“看着在跑,其实在浪费”。没有可观测性的时候,一个卡的GPU利用率只有20%你可能根本不知道。等到训练结束,才发现本该一天跑完的任务跑了三天。

我自己的经验是,训练看板至少要包含三类指标:

  • 资源类:GPU利用率、显存占用、显存温度/功耗、网络吞吐、PCIe带宽。
  • 训练进度类:当前epoch、全局step、吞吐量(tokens_per_sec)、剩余时间预估。
  • 训练质量类:loss曲线、梯度范数、学习率变化、loss scaling值。

这些指标不仅用于事后复盘,更要配置告警规则。比如GPU利用率低于某个阈值持续N分钟就告警,loss出现NaN立即告警,显存峰值逼近上限就告警。有了这套机制,训练集群才能从“放养”变成“可管”。

6.3 容错与续训:检查点不只是存个权重

大模型训练动不动要跑几周,任何一次硬件故障、网络抖动、训练抖动都可能导致任务失败。在大规模训练里,失败几乎是常态,成功才是侥幸。所以“检查点”机制就是最后的保命符。

我的建议是:

  • 训练脚本里定期保存完整检查点,不仅存模型权重,还要存优化器状态、学习率调度器状态、随机数种子、当前step数。否则续训时优化器状态丢失,模型可能需要很多步才能重新稳定。
  • 保存频率不能盲目缩短。7B模型一个检查点可能数十GB,保存太频繁,磁盘IO和存储成本都受不了。一般每训练10~30分钟存一次比较合理,同时保留最近N份,避免磁盘写满。
  • 续训前最好做一次校验,确认检查点的字段完整,并且记录对应的数据和配置版本。数据版本和代码版本不一致时就续训,是最容易造成隐性训练事故的做法。

最后再分享一个我个人的体会。并行训练这件事,表面上是技术难点,本质上是工程管理问题。你需要的不是会背并行策略的名字,而是能在有限资源下把“显存、通信、吞吐、稳定性”这四件事做出平衡。从7B模型起步,多跑几个任务,多踩几次坑,慢慢地这张图就会在你脑子里变成一套直觉。如果你正准备上手并行训练,希望这份笔记能帮你少走点弯路。

相关新闻

5G核心技术全景梳理:从演进逻辑到网络架构的入门指南

5G核心技术全景梳理:从演进逻辑到网络架构的入门指南

整理5G学习笔记时,我给自己定了一个规矩:每一个技术点都必须回答“它到底为哪个场景解决什么问题”。这套笔记从1G读到5G,从物理层一路看到核心网,中间推翻过好几版结构,最后沉淀下来的主线非常清晰:演进逻…

2026/10/20 20:48:53 阅读更多 →
Coding Agent与Personal Agent架构差异:从收敛到延续的设计逻辑

Coding Agent与Personal Agent架构差异:从收敛到延续的设计逻辑

1. 两类智能体的本质差异:先从"服务对象"说起Coding Agent 和 Personal Agent,这两个词最近在开发者圈子里高频出现。很多人以为它们只是"写代码的Agent"和"处理个人事务的Agent"的区别,但真正做过底层架构设计…

2026/10/20 20:47:50 阅读更多 →
ChatGPT论文AI率100%?从原理到实操的降AI率完整指南

ChatGPT论文AI率100%?从原理到实操的降AI率完整指南

ChatGPT生成的论文AI率100%?用这几款工具轻松降下来说实话,我第一次看到自己写的文章被某检测系统标红成一片、AI率直接飙到100%的时候,整个人是懵的。那一整段明明是我让ChatGPT帮我做了大纲、搭了框架、润色了段落,怎么就成了“…

2026/10/20 20:47:50 阅读更多 →

最新新闻

图数据建模必知:从转导式到归纳式学习的范式切换实践

图数据建模必知:从转导式到归纳式学习的范式切换实践

前阵子接手一个图数据的用户行为预测项目,最初跑得挺顺,后来每来一批新用户,模型效果就肉眼可见地掉。一开始我以为只是特征没做好,调了一周才意识到,问题出在我用的学习范式上——我一直在一张静态图上做转导式&#…

2026/10/20 21:30:50 阅读更多 →
Docker镜像加载原理:分层、内容寻址与联合文件系统

Docker镜像加载原理:分层、内容寻址与联合文件系统

1. 从一次镜像拉取卡顿说起:为什么需要搞懂加载原理很多人用 Docker 的第一课就是docker pull,然后docker run,容器跑起来了,任务就算完成。直到某天你发现:同一个镜像,在测试机上拉取只要十几秒&#xff0…

2026/10/20 21:30:50 阅读更多 →
扩展HTTP协议实现文件夹多线程分片秒传:信创环境下的完整方案

扩展HTTP协议实现文件夹多线程分片秒传:信创环境下的完整方案

前段时间做信创改造,好几个同行都在问同一个问题:配置再高、网络再好的环境里,为什么文件夹上传还是动不动报错?仔细一看,多数系统还在用最原始的multipart/form-data一次性上传。大文件传一半断了就从头再来&#xff…

2026/10/20 21:30:50 阅读更多 →
开源AI助手OpenClaw本地部署实战:从零到跑通全流程

开源AI助手OpenClaw本地部署实战:从零到跑通全流程

先讲一个特别有画面感的场景:上周我在某个技术讨论区闲逛,有人发了一条动态,晒了一张终端截图——一个叫 OpenClaw 的项目跑起来了,正在自动整理他电脑里的文档。底下评论区有人问:"这跟网页版 AI 有啥区别&#…

2026/10/20 21:30:50 阅读更多 →
H3C策略路由PBR双出口实验:配置、验证与排错全指南

H3C策略路由PBR双出口实验:配置、验证与排错全指南

做网络的人早晚会撞上这样一个需求:内网有两条出口链路,领导指定“财务部门的流量必须走专线,其他上网流量走普通宽带”,然后你觉得这很简单,在出口设备上多写几条静态路由不就完事了吗?真正敲完命令你会发…

2026/10/20 21:30:50 阅读更多 →
大语言模型反常识推理能力:培养路径与工程实践

大语言模型反常识推理能力:培养路径与工程实践

大规模语言模型的反常识推理能力培养这两年做大模型应用,有个问题一直在困扰我和身边的同行:模型在常规问答、内容生成上已经强得离谱,但只要碰到那种"违背直觉但其实是正确答案"的问题,立马就露怯。比如你问"一个…

2026/10/20 21:29:46 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →