common problems+train+framework 2026-04-28
一. common issues
排查问题也可以写成一个 automated script.
- 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 的时候,如果是同步写,训练停止
- GPU Utilization low
1) 在训练代码里加计时器,看看dataloader 的时间是不是造成喂不上数据的原因,数据加载的时间比计算时间还长的话
让数据加载并行
2)用的 TCP socket,没用 RDMA。export NCCL_IB_HCA (指定用哪些网卡进行数据传输)没配,算的比传的快得多。
- Batchsize 上不去
1)频繁的不同大小的 tensor 分配释放导致显存碎片
代码里手动清理下, torch.cuda.empty_cache()。
- 带宽和速度
带宽:单位时间内处理的数据量 单位: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 倍
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)