一. common issues

排查问题也可以写成一个 automated script.

  1. training become slow
    降宽,降速,或者降级(NVLink 变 Pcie,GDR没生效)+ cpu io 网络,这个是 data 和 checkpoint 之间的矛盾
1)gpu 温度高,一个慢拖慢所有
将这个 node cordon掉,然后看看散热有没有问题,让它凉快下来

2)ib 网卡出现丢包,重传在每个节点上使用 perfquery 命令查看ib 端口的错误计数是否增长,ibstat mlx5_0 进一步查看网卡有没有降
速,是否active
光模块,光纤,交换机端口等等是否有问题。换上新的试试

3)nccl 通信从 ib 退化成了以太网
kubectl 查看 master pod 的日志中 grep NCCL. 看看网络是不是从 NET/IB 变成了 NET/socket, 这样的话就是退到了 TCP Socket
(就是没用RDMA)
看看驱动是不是掉了。就是网卡驱动和nvidia驱动之间的媒人。重新加载驱动

4)存储 IO 变慢
存checkpoint用的共享存储cephfs,数据集用的fluid和Alluxio s3 拉到本地硬盘的方式。用的一张网卡,同时进行就会出现带宽竞争,
如果 fluid 缓存盘和 Cephfs 的日志/临时空间在一块盘上,磁盘IO 队列深度暴增(排队变多),响应变慢
Cephfs 消耗 CPU, Fluid/Alluxio 在移动数据的时候也会消耗 CPU, 两者同时进行,cpu忙不过来。
solution:将它们分开,Fluid 预先拉取数据,和 checkpoint分开。或者配置 Fluid prefetch策略,让其平稳拉取,不是像checkpoint
那样猛拉。checkpoint先写到本地存储,错开网络,再异步写到共享存储

5)数据预处理的pod 抢占了大量cpu, 让dataloader 的cpu 不够用
kubectl top node <node-name> 看看cpu占用,然后找到这个节点上所有运行的pod
给节点加 taint/teɪnt/ 污点(用中文,和interviewer 沟通顺畅),不让数据预处理调度到这上面

6)写入 checkpoint 的时候,如果是同步写,训练停止
  1. GPU Utilization low
1) 在训练代码里加计时器,看看dataloader 的时间是不是造成喂不上数据的原因,数据加载的时间比计算时间还长的话
让数据加载并行

2)用的 TCP socket,没用 RDMA。export NCCL_IB_HCA (指定用哪些网卡进行数据传输)没配,算的比传的快得多。
  1. Batchsize 上不去
1)频繁的不同大小的 tensor 分配释放导致显存碎片
代码里手动清理下, torch.cuda.empty_cache()。
  1. 带宽和速度
带宽:单位时间内处理的数据量  单位:GB/s (字节/秒) 或 Gbps (比特/秒)。
速度:就是延迟,数据包从 A 到 B的时间,单位:ms (毫秒) 或 $\mu$s (微秒)

传输路径,物理通道,典型单向带宽/速率
硬盘 → 内存, NVMe (Gen4 x4),约 7 GB/s
内存 → 显卡, PCIe Gen5 x16,约 63 GB/s
显卡 ↔ 显卡, NVLink (Gen4),约 450 GB/s - 900 GB/s

cpu开启多进程,第一个进程喂数据,在gpu 计算的时候,其他进程提前将数据放到内存,做好预处理等准备工作
cpu 读取数据做预处理的时间小于 GPU 跑一遍前向 + 反向传播的时间, Dataloader就不是瓶颈。
NVLink 那么大的带宽不是给 dataloader 设计的,是给gpu 之间的通信设计的。allReduce那些

大模型算的慢,小数据也要算半天,这时候需要 NVLink 和 RDMA
而小模型算的快,此时硬盘读图慢,所以gpu会停下来等数据。解决知道,不要读百万小文件,将它打包成 WebDataset (tar)、TFRecord 
或 LMDB. 顺序读大文件比随机读小文件快得多。
增加batchsize 也能让gpu 利用率提升

二. train

训练方式:SFT/LoRA / RLHF / 蒸馏

1. SFT:输入一个标注好的问答对,输出一个学到了这部分知识的和原模型一样大小的新模型。
2. LoRA: 同样输入标注好的问答对,冻结原始模型权重,只训练新插入的一部分矩阵,得到adapter(适配器),合并到原模型。用于vllm的 
lora 对答特殊领域的问题。省显存,只需要切换adapter,底座是一个模型
3. RLHF: 输入一个已经做过 SFT的模型 + 人类偏好排序,输出这个模型回答的都是人类偏好的回答。
4. 蒸馏:拿 70B的模型根据 prompt 输出答案,将prompt + 回答作为 7B小模型的训练数据训练。
训练框架:Megatron-LM、DeepSpeed、FSDP
推理框架:TGI、SGLang(以及 vLLM)
它们的底层都是在调用 pytorch
FSDP是 pytorch 自家的,和Zero3 原理一样,但是生态啥的都不如 DeepSpeed
DeepSpeed 的优势在和 HuggingFace Transformers 无缝集成,加个 json 配置就能用。
Megatron-LM 的优势在于 TP,PP,是它首创,对于需要几百张卡的预训练团队需要它,不能直接用 HuggingFace 模型

Megatron-DeepSpeed

Megatron-LM 擅长:TP(张量并行)+ PP(流水线并行)
DeepSpeed 擅长:ZeRO(显存优化的数据并行)

Megatron-DeepSpeed = TP + PP + ZeRO-DP 三维并行

最后一步用 ZeRO-DP 的原因是优化器要精度高,存储一个参数就需要一个,而且比参数还占空间。并且在前向和反向传播中都不用。
只是在最后allgather,allreduce的时候用一下,不用存那么多副本,每个存一部分,最后算完参数再拼一起就行了。

 参数本身 bf16 = 2 bytes
  m 是 fp32 = 4 bytes
  v 是 fp32 = 4 bytes
  → 优化器状态是参数本身的 4
TGI 极致性能吞吐不如 vllm ,用于商业用途需要付费,Hugging Face 亲儿子,部署LLM 用的,快速上线 Hugging face有优势

===下面是详解部分

SFT(Supervised Fine-Tuning,全参数监督微调)

输入:基座模型(如 Qwen2.5-7B)+ 标注好的指令-回答对数据集

{"instruction": "帮我写一封请假邮件", "output": "尊敬的领导,我因身体不适..."}
{"instruction": "这段代码有什么bug", "input": "def add(a,b): return a-b", "output": "函数名是add但实际做了减法..."}

输出:一个完整的新模型权重(和原模型一样大,7B 模型产物约 14GB bf16)

实际项目价值

某金融公司拿 Qwen-14B 做 SFT,喂了 10 万条金融研报问答数据。训完后模型能准确回答"某公司 PE 是多少"“这份财报的风险点在哪"这类领域问题。基座模型本来对金融术语理解很泛,SFT 之后变成了一个"金融分析师助手”。

适用场景:你有充足的高质量标注数据,想让模型在特定领域有质的飞跃,且算力预算充足。全参微调效果上限最高,但成本也最高——7B 模型 SFT 至少需要 8 张 A100,70B 需要几十张。


LoRA(Low-Rank Adaptation,低秩适配微调)

输入:和 SFT 完全一样——基座模型 + 标注数据集。区别在于只训练插入的低秩矩阵,冻结原始权重。

输出:一个很小的 adapter 文件(通常几百 MB),不是完整模型。部署时可以合并回原模型,也可以动态加载。

实际项目价值

某电商平台需要同时服务 5 个业务线:客服对话、商品描述生成、评论情感分析、搜索 query 改写、营销文案。如果每个业务都做 SFT,就要维护 5 个 14GB 的完整模型,推理时要部署 5 套服务。

用 LoRA:基座模型只部署一份,5 个业务各训一个 adapter(每个几百 MB)。推理时用 vLLM 的多 LoRA 能力,一个服务实例动态切换 adapter,显存和机器成本直接降到原来的 1/5。

适用场景:算力有限、需要快速迭代、需要多任务/多租户共享基座模型。效果比 SFT 略差 5-10%,但性价比极高。你的 4090 节点单机 4 卡就能跑 7B LoRA。


RLHF(Reinforcement Learning from Human Feedback,人类反馈强化学习)

输入:一个已经做过 SFT 的模型 + 人类偏好排序数据

偏好数据长这样:

{
  "prompt": "写一首关于春天的诗",
  "chosen": "春风拂面柳丝长,燕子归来筑新房...",
  "rejected": "春天来了,花开了,草绿了,天暖了..."
}

人类标注员对同一个 prompt 的多个回答做排序,标出哪个好哪个差。

整个 RLHF 流程实际上分三步

第 1 步:SFT → 得到 SFT 模型(上面讲的)
第 2 步:训练 Reward Model → 输入偏好数据,输出一个打分模型
第 3 步:PPO/DPO 强化学习 → 用 Reward Model 的打分信号优化 SFT 模型

PPO 阶段需要同时加载 4 个模型:Actor(正在训练的)、Critic(价值网络)、Reference(SFT 原始模型,防止偏离太远)、Reward Model。7B 模型做 PPO,4 个模型同时在显存里,至少需要 32 张 A100。

DPO(Direct Preference Optimization)是简化版,不需要单独的 Reward Model,只需要 2 个模型(Actor + Reference),资源需求降一半。

输出:一个对齐后的完整模型权重

实际项目价值

ChatGPT 之所以比 GPT-3 好用,核心就是 RLHF。SFT 让模型"会回答问题",RLHF 让模型"回答得像人话"。

某公司做了一个法律咨询 AI,SFT 之后模型能回答法律问题,但经常输出冗长、重复、格式混乱的内容,偶尔还会编造法条。做了 RLHF 之后:回答变得简洁准确,不确定的会说"建议咨询专业律师",不再胡编法条。

适用场景:你的模型已经有能力了(SFT 过),但需要提升回答质量、安全性、用户体验。成本最高,数据标注也最贵(需要人类标注员做偏好排序)。


蒸馏(Knowledge Distillation)

输入:一个大的教师模型(如 70B)+ 训练数据(可以是无标注数据,让教师模型生成标注)

蒸馏数据的生成过程:

拿一批 prompt → 用 70B 教师模型生成高质量回答 → 把 (prompt, 回答) 作为训练数据
用这些数据去训练一个小的学生模型(如 7B)

训练时不只看 hard label(正确答案),还看教师模型输出的 soft label(概率分布),让学生模型学习教师的"思考方式":

# 蒸馏 loss = α × 标准交叉熵 + (1-α) × KL散度(学生分布, 教师分布)
loss = alpha * ce_loss + (1 - alpha) * kl_loss(student_logits / T, teacher_logits / T)

输出:一个小模型的完整权重,能力接近大模型但推理成本低得多

实际项目价值

某搜索公司有一个 70B 的排序模型,效果很好但推理太慢,单次请求要 2 秒,线上 QPS 扛不住。把 70B 蒸馏到 7B:效果保留了 70B 的 90-95%,但推理速度快了 8 倍,单卡就能部署,QPS 从 50 提到 400。

DeepSeek-R1 的蒸馏版本(DeepSeek-R1-Distill-Qwen-7B/14B/32B)就是典型案例——用 R1 671B 的输出数据去训练小模型,让 7B 模型也具备一定的推理链能力。

适用场景:你有一个效果好但太大的模型,需要压缩到能实际部署的大小。或者你没有高质量人工标注数据,但有一个强大的教师模型可以"造数据"。

Soft Label 是什么意思

Hard label:老师告诉你答案是"猫",对就是对,错就是错。

Soft label:老师告诉你"我觉得 80% 是猫,15% 是老虎,5% 是豹子"。

教师模型对下一个 token 的预测:
  "的"  → 0.60
  "了"  → 0.25
  "着"  → 0.10
  其他  → 0.05

学生模型不只学"正确答案是'的'",还要学这个概率分布的形状
——"了"也有一定合理性,"着"也沾点边

这个分布里包含了教师模型对语言的"理解":哪些词在这个位置合理、合理程度如何、词与词之间的相似关系。这些信息比单纯的正确答案丰富得多,所以蒸馏出来的学生模型比直接用 hard label 训练效果更好。


就是把两个框架的优势拼在一起用,NVIDIA 和微软合作的产物。

Megatron-LM 擅长:TP(张量并行)+ PP(流水线并行)
DeepSpeed 擅长:ZeRO(显存优化的数据并行)

Megatron-DeepSpeed = TP + PP + ZeRO-DP 三维并行

用一个具体例子说明。假设你要用 256 张 A100 训一个 70B 模型:

TP = 8(一台机器 8 张卡做张量并行,切矩阵)
PP = 4(4 台机器串成流水线,切层)
DP = 8(8 组数据并行副本,ZeRO-1 分片优化器状态)

8 × 4 × 8 = 256 张卡

每个维度干的事:

TP:一个 transformer 层太大,切成 8 块分到同一台机器的 8 张卡上
    → 走 NVSwitch,带宽高延迟低,适合频繁通信

PP:70B 模型有 80 层,每 20 层放一组机器上
    → 走 IB 网络,通信量相对小(只传激活值)

ZeRO-DP:8 组副本各算不同的数据,梯度同步 + 优化器状态分片
    → 走 IB 网络,AllReduce 同步

代码层面,就是在 Megatron-LM 的训练脚本里启用 DeepSpeed 作为后端:

deepspeed --num_gpus 8 --num_nodes 32 \
  pretrain_gpt.py \
  --tensor-model-parallel-size 8 \
  --pipeline-model-parallel-size 4 \
  --deepspeed \
  --deepspeed_config ds_config.json

Megatron 管模型怎么切(TP/PP),DeepSpeed 管显存怎么省(ZeRO)和训练怎么加速(通信优化、混合精度)。目前业界大模型预训练基本都是这个组合,包括 BigScience BLOOM 176B、各家的百亿级以上模型训练。


可以只算不同数据,那就是普通 DDP。但问题出在显存上。

不用 ZeRO 会怎样

70B 模型,每组 DP 副本需要存:

参数(bf16):     140 GB
梯度(bf16):     140 GB
Adam 优化器状态:  560 GB(m 和 v 各一份 fp32,每个参数 8 bytes)
─────────────────────────
总计:             840 GB

这 840GB 是每组 DP 副本都要完整存一份的。8 组 DP 就是 8 份 840GB,每组的 32 张卡(8 TP × 4 PP)要分摊这 840GB。

其中优化器状态 560GB 占了 67%,而它只在参数更新那一步用一下,前向反向计算时完全用不到,白白占着显存。

ZeRO 做了什么

把优化器状态切成 N 份,每组 DP 副本只存 1/N:

8 组 DP,ZeRO-1:
  每组只存 560/8 = 70GB 优化器状态(而不是 560GB)
  省了 490GB

更新参数时:
  每组算自己那 1/8 参数的更新(因为只有这部分的优化器状态)
  然后 AllGather 把更新后的参数广播给其他组

就这么简单。本质是用一次通信(AllGather)换回大量显存。

省下来的显存干什么

方案 A:加大 batch size → 提高 GPU 利用率 → 训练更快
方案 B:不加 batch size,但模型能放得下了(本来 OOM 的现在不 OOM 了)
方案 C:用更少的卡训同样的模型(省钱)

所以 ZeRO-DP 不是"为了并行",而是"在数据并行的基础上,把每张卡上冗余存储的东西切掉,省显存"。没有 ZeRO,普通 DDP 也能跑,但要么放不下,要么 batch size 上不去。

Adam 优化器为什么这么占显存:
  每个参数要额外存两个 fp32 状态:
    m(一阶动量,梯度的移动平均)
    v(二阶动量,梯度平方的移动平均)
  
  参数本身 bf16 = 2 bytes
  m 是 fp32 = 4 bytes
  v 是 fp32 = 4 bytes
  → 优化器状态是参数本身的 4
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐