模型训练与部署:一手资料核对
本文是截至 2026-09-14 的资料快照,只采用论文、项目官方文档、官方仓库和模型卡。它不是入门教程正文,而是给正文作者提供可追溯的 API、配置、兼容性和许可证依据。
先给结论
- DeepSpeed 和 DeepSeek 是两件事。 DeepSpeed 是分布式训练与推理优化库;DeepSeek 是模型家族。用户口中的“deepseeed 使用经验”更可能指 DeepSpeed,因此本文以 DeepSpeed 为主,DeepSeek 作为模型案例。
- 先用 ZeRO-2,再按显存需要升级到 ZeRO-3。 Hugging Face 当前文档明确建议:ZeRO-2 的通信开销低于 ZeRO-3,只有模型在 ZeRO-2 下仍放不进显存时,才优先考虑 ZeRO-3。CPU/NVMe offload 继续节省显存,但会把瓶颈转移到主存、PCIe 或存储。Transformers DeepSpeed ZeRO
- QLoRA 不是“把所有参数以 4 bit 训练”。 它冻结 4 bit 量化后的基础权重,梯度穿过量化层,只更新 LoRA 适配器。原始论文的三个关键点是 NF4、double quantization 和 paged optimizers。QLoRA 论文
- 当前 Hugging Face SFT API 已不同于许多旧教程。 当前
SFTConfig使用max_length,SFTTrainer的分词器/处理器参数叫processing_class;从 Transformers v5 起模型加载推荐写dtype=。旧代码常见的max_seq_length、tokenizer=、torch_dtype=不能不加判断地照抄。TRL SFTTrainer - DeepSeek-R1 Distill 更适合单机教学和微调。 Qwen 版实际是
Qwen2ForCausalLM,Llama 版沿用 Llama 架构;它们可以按各自基础模型使用 Transformers、PEFT、TRL 和 Unsloth。完整 R1/V3 是 671B MoE,虽然每 token 只激活约 37B 参数,仍需存放约 671B 主模型权重,不能用“激活参数量”估算单机显存。DeepSeek-R1 模型卡 DeepSeek-V3 仓库
一、DeepSpeed:它解决的不是同一个层次的问题
1. ZeRO 三阶段
ZeRO(Zero Redundancy Optimizer)逐级切分训练状态:DeepSpeed ZeRO API
ZeRO-3 前向计算某一层时需要临时 all-gather 该层参数,完成后再释放或重新切分。因此它能降低参数常驻显存,但通信更多;不能把“阶段越高”简单理解成“训练必然越快”。官方 Hugging Face 指南也明确建议在 ZeRO-2 无法容纳模型时才使用 ZeRO-3。Transformers DeepSpeed ZeRO
2. 安装与环境核对
官方最小安装是:
DeepSpeed 的 CUDA/C++ 算子默认可能在首次使用时 JIT 编译。ds_report(等价于 python -m deepspeed.env_report)用于检查哪些算子可用。系统 CUDA 工具链版本和 PyTorch 编译使用的 CUDA 主版本不一致时,算子编译会失败;官方建议主、次版本都尽量匹配,不应把 DS_SKIP_CUDA_CHECK=1 当作常规修复。DeepSpeed 安装说明
排查时至少记录:
DeepSpeed 官方已经提供原生 Windows 构建说明,但大模型训练生态中的 NCCL、多机启动器、vLLM、FlashAttention 等仍以 Linux 为主。Windows 工作站若要复现实验,WSL2 或 Linux 容器通常更容易与上游教程保持一致;如果坚持原生 Windows,应先以 ds_report 的实际结果为准,而不是只看 pip install 是否成功。DeepSpeed Windows 官方说明
3. Transformers Trainer + DeepSpeed 的当前写法
TrainingArguments.deepspeed 接收 JSON 文件路径或 Python 字典。与 Trainer 重复的批量、梯度累积、学习率和精度参数建议写成 "auto",由 Trainer 同步,避免两份配置悄悄不一致。Transformers DeepSpeed ZeRO
一个可作为起点的 ds-zero2.json:
训练参数只保留一份事实来源:
启动器可以三选一,不要叠加使用:
以上三种入口都受官方 Transformers 指南支持。Transformers DeepSpeed ZeRO
4. ZeRO-3 与 offload 配置
ZeRO-3 CPU offload 起点:
关键边界:
offload_optimizer可用于 ZeRO-2/3;offload_param只对 ZeRO-3 有意义。pin_memory: true可以加快 CPU/GPU 传输,但会锁定主存,不能只检查 GPU 显存。stage3_gather_16bit_weights_on_model_save: true会在保存时汇聚完整 16 bit 权重,速度慢且需要额外内存;但如果要得到能由from_pretrained()直接加载的完整权重,这是必要条件之一。- bucket 越大通常通信效率越高,同时占用更多显存。不要未经测量就照搬 5e8 等旧教程数值。
这些字段和行为均见当前 Transformers DeepSpeed ZeRO 指南 与 Accelerate DeepSpeed 指南。
5. Accelerate 的两种配置模式不能混写
Accelerate 有两条路径:
- 让
accelerate config生成简单的 DeepSpeed Plugin 配置; - 在 Accelerate YAML 中只写
deepspeed_config_file,详细设置放进 DeepSpeed JSON。
第二种模式的最小 YAML:
使用 deepspeed_config_file 后,不要同时在同一个 Accelerate YAML 中重复写 zero_stage、gradient_accumulation_steps、offload 和 zero3_save_16bit_model 等字段;当前 Accelerate 会提示这些字段将被忽略并抛出 ValueError。Accelerate DeepSpeed 配置冲突说明
如果 DeepSpeed JSON 自己声明了 optimizer 或 scheduler,原生 Accelerate 循环需要配套使用 DummyOptim / DummyScheduler;若 JSON 不声明它们,就继续使用代码里创建的 PyTorch optimizer/scheduler。四种组合及限制见 Accelerate DeepSpeed 指南。
6. 不经 Trainer 的原生 DeepSpeed API
以下示例体现当前最稳定的核心调用关系:initialize → engine(...) → engine.backward → engine.step。DeepSpeed Training Setup DeepSpeed Training API
默认由 DeepSpeed 管理梯度累积时,每个 micro-batch 都对称调用 backward() 和 step();只有达到累积边界时才真正更新参数。混合精度下优先调用 engine.backward(loss)。当前 DeepSpeed 虽支持部分场景直接 loss.backward(),但手工反向必须正确使用 engine.scale(loss),旧版又不一定支持,因此教学代码继续使用 engine API 更稳妥。DeepSpeed Training API
7. Checkpoint:训练恢复和部署导出不是同一种文件
保存和继续训练
DeepSpeed 每个进程保存自己的模型/优化器/调度器分片,因此 save_checkpoint() 必须由所有 rank 调用;只让 rank 0 调用会在同步点卡死。client_state 用于保存数据游标、epoch 等业务状态。DeepSpeed Getting Started
ZeRO-3 下,不要在同一个已分片的 engine 上紧接着 save_checkpoint() 后再 load_checkpoint()。官方说明 load_checkpoint() 需要干净、未分片的模型;若必须立即重新加载,应重新初始化 engine。DeepSpeed checkpoint API
导出给 Transformers 或推理引擎
DeepSpeed 的训练 checkpoint 是分片状态,不能直接当作普通 Hugging Face 模型目录使用。可在训练结束后离线合并 FP32 权重:
或用 Python:
合并需要大量 CPU RAM;Accelerate 文档估计约需最终 checkpoint 大小的两倍主存。调用 load_state_dict_from_zero_checkpoint 后,原 model 不再保持 DeepSpeed engine 语义;若还要继续分布式训练,需要重新初始化。DeepSpeed checkpoint API Accelerate DeepSpeed 保存说明
“换 GPU 数继续训练”也不能默认保证。DeepSpeed 的 Universal Checkpoint 正是为不同 DP/TP/PP 拓扑恢复设计的,但官方仍把它标为 under development,应先按目标并行拓扑做恢复演练。DeepSpeed Universal Checkpoint
8. DeepSpeed 常见坑清单
- 配置和 Trainer 双重定义。 批量、累积步数、精度、学习率优先用
"auto",或确保两边完全一致;当前文档指出不一致时可能继续运行但使用错误值。Transformers DeepSpeed ZeRO - 配置拼写错误。 当前 ZeRO 配置类使用 Pydantic 验证,但不同集成层和历史版本的校验强度不同;务必检查启动日志最终打印的 effective config,不把“成功启动”当成配置已生效。DeepSpeed ZeRO config
- ZeRO-3 初始化时机错误。 Transformers 文档要求使用 ZeRO 初始化时先创建
TrainingArguments,再实例化模型,否则from_pretrained()阶段不会进入 ZeRO-3 初始化。Trainer API - 只保存模型,不保存训练状态。
save_only_model=True省略优化器等状态,不能用于完整断点续训;它也不能与load_best_model_at_end=True组合。Transformers DeepSpeed ZeRO - rank 0 单独保存 DeepSpeed checkpoint。 会等待其他 rank,造成挂起。DeepSpeed Getting Started
- 把 ZeRO 分片目录交给
from_pretrained()。 应先汇聚 16 bit 权重,或离线执行zero_to_fp32.py。DeepSpeed checkpoint API - offload 后只看 GPU 利用率。 需要同时监测 CPU RAM、page fault、PCIe、NVMe 吞吐,否则“显存下降”可能换来数倍训练时长。
- 多机版本不一致。 所有节点的 Python、PyTorch、CUDA、DeepSpeed、模型代码和自定义算子构建必须一致;可以保存每个节点的
ds_report作为实验记录。DeepSpeed 安装说明
二、LoRA 与 QLoRA:原理和工程边界
1. LoRA 做了什么
对于冻结权重 ,LoRA 不直接训练完整增量,而是学习低秩分解:
其中 、,且 。训练参数量从 变成约 。LoRA 原论文冻结预训练权重并向 Transformer 层注入低秩矩阵,减少训练参数和每个任务的存储成本。LoRA 论文
LoRA 的直接收益是“少训练、少保存”,并不自动代表:
- 基础模型本体不占显存;
- 推理一定更快;
- 少量低质量数据能注入可靠事实;
- 对任意模型写同一组
target_modules都正确。
2. QLoRA 的准确含义
QLoRA 的路径是:
- 将基础模型权重量化为 4 bit 并冻结;
- 计算时按指定 dtype 反量化参与前向/反向;
- 只更新通常为 BF16/FP16 的 LoRA 参数;
- 优化器只保存适配器的状态。
原论文引入 NF4、double quantization 和 paged optimizers,并证明 65B 模型可在单张 48GB GPU 上完成其论文设置的微调;这是一项具体实验结果,不能外推成“任何 65B 模型、任意序列长度都只需 48GB”。QLoRA 论文
Hugging Face 当前建议对 4 bit 训练使用 NF4,并可使用 BF16 作为计算 dtype;nested/double quantization 进一步压缩量化常数。Transformers bitsandbytes
Turing 之前的卡可能支持 NF4/FP4,却不一定支持高效 BF16;运行时应根据 torch.cuda.is_bf16_supported() 选择 BF16 或 FP16。bitsandbytes 的 CUDA、ROCm、Intel 等后端支持状态持续变化,不能把一张旧博客的硬件表当成永久事实,发布前应回查 bitsandbytes 官方安装兼容表。
三、Hugging Face PEFT + TRL 的当前最小 QLoRA 示例
下面选择 deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B,因为它实际是 Qwen2 架构、规模适合教学。完整 DeepSeek-R1/V3 不适合拿同一份单卡脚本演示。DeepSeek-R1 模型卡
1. 安装
调研笔记不硬编码一组未来必然失效的精确版本。真实项目应先在目标 GPU 上跑 smoke test,再锁定一整套已验证版本;不要只锁 transformers,遗漏 trl、peft、accelerate、bitsandbytes 和 torch。
2. 可运行的最小训练脚本
依据和边界:
- 当前 TRL 支持把 conversational dataset 的
messages交给SFTTrainer;也可以不预先包装模型,改为向 Trainer 传入peft_config。上例选择显式执行prepare_model_for_kbit_training()和get_peft_model(),便于在训练前检查可训练参数,随后不要再重复传peft_config。PEFT 量化模型训练 TRL SFTTrainer processing_class是当前参数名。旧教程的tokenizer=tokenizer属于旧 API。- 当前
SFTConfig是max_length,不是不少旧版 Unsloth/TRL 示例使用的max_seq_length。TRL SFTConfig - 若设置
assistant_only_loss=True,聊天模板必须能产生 assistant token mask,即模板包含{% generation %}/{% endgeneration %};不能对任意 DeepSeek/Qwen 模板盲开。TRL assistant-only loss - PEFT 对常见架构有默认 target modules,但要追求 QLoRA 论文式 all-linear 适配时仍应检查实际层名。可用
model.named_modules()、model.print_trainable_parameters()和model.targeted_module_names核对。PEFT custom models
3. 加载 LoRA adapter 推理
只分发 adapter 时,使用者仍需取得许可证兼容的基础模型。合并权重会产生另一份完整模型,磁盘和发布合规要求都不同。PEFT 当前可用 AutoPeftModelForCausalLM 加载适配器,也可 merge_and_unload() 生成不再依赖 PEFT adapter 的普通模型,但合并前必须确认量化状态、dtype 和许可证。PEFT checkpoint format
四、Unsloth:使用经验与兼容边界
1. 安装原则
官方当前推荐普通环境直接:
Python、PyTorch 和 CUDA 组合特殊时,再使用官方安装选择器或对应 extra,而不是从旧 notebook 复制一条带固定 cu121-torch240 的命令。官方文档特别提醒 Python 3.13 仍可能遇到生态依赖问题,并提供按 PyTorch/CUDA 组合安装的方法。Unsloth Pip Install
2. 当前最小微调骨架
Unsloth 官方模型卡当前同时展示 FastModel,而大量已发布 notebook 仍使用 FastLanguageModel。文本自回归模型可以使用后者;新模型家族或官方模型卡明确要求时优先照模型卡使用 FastModel。以下骨架适用于 DeepSeek-R1-Distill-Qwen 这类 Qwen 文本模型:Unsloth DeepSeek 1.5B 模型卡 Unsloth 官方模型映射
这里同时存在两层 API:FastLanguageModel.from_pretrained() 仍使用 Unsloth 自己的 max_seq_length;当前 TRL 的 SFTConfig 使用 max_length。这两个名字不能机械地全局替换。Unsloth 官方 notebook TRL SFTConfig
3. 超参数起点,不是定律
Unsloth 当前官方建议把以下数值作为普通 LoRA/QLoRA 的起点:Unsloth LoRA 参数指南
不要把训练 loss 的某个固定阈值当作通用过拟合判断。更可靠的是独立验证集、领域任务集、生成样例盲评,以及对基础能力的回归测试。
4. 保存、GGUF 和跨引擎推理
Unsloth 可保存 adapter、合并后的 16 bit 模型和 GGUF。跨到 llama.cpp、Ollama、vLLM 后出现乱码、重复或无法结束,官方首先要求核对训练与推理是否使用同一聊天模板和特殊 token 约定。Unsloth 保存排错
因此每个训练产物至少保存:
- tokenizer 全部文件与
chat_template; - 基础模型精确 ID 和 revision;
- Unsloth、Transformers、TRL、PEFT、PyTorch 版本;
- 训练数据模板源码;
- 推理采样参数和停止 token;
- adapter-only、merged、GGUF 中具体是哪一种产物。
不要把 adapter_model.safetensors 当成完整模型,也不要只复制 GGUF 而遗漏模板和 generation config。
5. 许可证
Unsloth 当前仓库说明核心包采用 Apache-2.0,Unsloth Studio 等可选组件采用 AGPL-3.0;notebooks 也有自己的许可证。部署时还必须叠加检查基础模型、数据集和产出模型的许可证,不能用“训练框架是开源的”推导“模型可商用”。Unsloth 仓库许可证说明
五、DeepSeek 模型的训练与部署边界
1. 不同 DeepSeek 名称对应不同架构
模型谱系与许可证说明来自 DeepSeek-R1 官方模型卡;DeepSeek-V3 的权重结构见 README_WEIGHTS。
2. “DeepSeek-V3 不支持 Transformers”已经过时
DeepSeek-V3 仓库早期 README 曾写“Transformers 尚未直接支持”,并固定了 transformers==4.46.3 给官方 demo。此信息只描述当时状态。DeepSeek-V3 于 2025-03-28 合入 Transformers,当前已有 DeepseekV3Config、DeepseekV3Model 和 DeepseekV3ForCausalLM。Transformers DeepSeek-V3
但“能加载”不等于“适合高吞吐生产”。当前 Transformers 文档仍列出朴素 attention、逐专家循环、static cache 等实现限制。完整 R1/V3 服务应优先用官方模型仓库列出的 SGLang、vLLM 等专用引擎;Transformers 适合接口验证、研究和较小衍生模型。
3. Distill 模型的本地 Transformers 推理
DeepSeek 官方对 R1 Distill 推荐温度约 0.5~0.7,并提醒不合适的温度可能带来重复或不连贯输出。模型卡还给出 vLLM 示例,说明 Distill 模型可按 Qwen/Llama 模型使用。DeepSeek-R1 官方模型卡
4. 小模型 OpenAI 兼容服务
vLLM 的 OpenAI-compatible server 当前使用 vllm serve;模型仓库中的 generation_config.json 默认可能覆盖部分采样参数。--api-key 也并不保护 vLLM 的所有非 /v1 端点,生产环境必须放在反向代理和网络访问控制之后。vLLM OpenAI-Compatible Server
5. 完整 R1/V3 服务不是“小模型命令加一个模型名”
官方 vLLM recipe 给 DeepSeek-R1-0528 FP8 的起点是 8×H200 或同级多卡,启用 tensor/expert parallel;SGLang 的当前 DeepSeek 指南同样列出完整 FP8/BF16/量化权重的多卡乃至多节点配置。vLLM DeepSeek-R1 recipe SGLang DeepSeek 指南
SGLang 示例:
原始 DeepSeek-V3 权重本身就是 FP8,不要再盲加 --quantization fp8。A100 上需要先把官方 FP8 checkpoint 转成 BF16,或使用经过引擎验证的量化权重;具体卡型配置应以当时的 SGLang DeepSeek-V3/R1 文档 为准。
6. DeepSeek 许可证不能只看仓库右侧标签
- DeepSeek-V3 代码仓库为 MIT,但 V3 Base/Chat 权重受单独 Model License 约束;官方说明支持商业使用。DeepSeek-V3 仓库
- DeepSeek-R1 代码和权重使用 MIT,并允许修改、衍生和蒸馏;但 Distill-Qwen 的上游是 Apache-2.0,Distill-Llama 还需遵守相应 Llama 3.1/3.3 许可证。DeepSeek-R1 模型卡
- Unsloth 上传的量化文件不是新的基础模型授权来源。分发或商用时必须沿着 base model 链逐层检查。
六、LoRA/QLoRA 与 DeepSpeed 怎么组合
二者解决不同维度:
- LoRA/QLoRA 减少需要训练的参数和优化器状态;
- DeepSpeed 把仍需驻留的训练状态、梯度和参数分摊到多卡或 offload。
决策顺序可用:
- 单卡能放下:普通 LoRA;
- 基础模型放不下:QLoRA;
- 需要多卡提高吞吐:LoRA/QLoRA + DDP 或 ZeRO-2;
- 即使多卡每卡仍放不下模型:ZeRO-3;
- ZeRO-3 仍 OOM:再考虑 CPU/NVMe offload、缩短序列、减小 micro-batch、梯度检查点;
- 完整大 MoE 或多节点训练:还要评估 tensor parallel、pipeline parallel、expert parallel,而不是只继续提高 ZeRO stage。
PEFT 官方已有通过 Accelerate + DeepSpeed 训练 adapter 的指南,ZeRO-1/2 保存行为与普通模型接近,ZeRO-3 保存完整 16 bit 权重需要额外开关。PEFT + DeepSpeed
七、旧教程迁移检查表
API 依据:TRL SFTTrainer、Transformers DeepSeek-V3、DeepSpeed checkpoint、Accelerate DeepSpeed、PEFT custom models、Unsloth 保存排错。
八、最低限度的实验验收
任何声称“代码可运行”的训练笔记都至少应记录:
pip freeze、ds_report、GPU 型号和驱动;- 基础模型 ID、revision、权重 dtype 和量化方式;
- 数据条数、token 长度分位数、模板渲染后的真实文本;
- train/eval 划分是否存在近重复泄漏;
- 可训练参数数量与 target modules 列表;
- 峰值 GPU 显存、CPU RAM、吞吐和 wall-clock;
- 保存后从新进程重新加载 adapter/merged 模型;
- 用固定 prompt 比较 base 与 fine-tuned 输出;
- 至少一个领域指标和一个基础能力回归集;
- 从 checkpoint 恢复后核对 global step、学习率和数据游标。
一个最小参数核对片段:
PEFT 官方也建议使用 print_trainable_parameters() 和 targeted_module_names 检查适配是否施加在预期层上。PEFT custom models
参考资料
- LoRA: Low-Rank Adaptation of Large Language Models
- QLoRA: Efficient Finetuning of Quantized LLMs
- DeepSpeed 官方仓库
- DeepSpeed ZeRO 配置 API
- DeepSpeed Training API
- DeepSpeed Checkpointing API
- Transformers DeepSpeed ZeRO
- Accelerate DeepSpeed
- PEFT LoRA API
- PEFT 量化模型训练
- TRL SFTTrainer
- Transformers bitsandbytes
- Unsloth 官方文档
- Unsloth 官方 notebooks
- DeepSeek-R1 官方仓库
- DeepSeek-R1 官方模型卡
- DeepSeek-V3 官方仓库
- Transformers DeepSeek-V3
- vLLM OpenAI-Compatible Server
- SGLang DeepSeek V3/R1