TorchTitan 训练 DeepSeek-V3 实践:模型注册表、融合内核优化与 HF 到 DCP 检查点转换
2026/9/17 6:05:41 网站建设 项目流程

TorchTitan 训练 DeepSeek-V3 实践:模型注册表、融合内核优化与 HF 到 DCP 检查点转换

【免费下载链接】torchtitanA PyTorch native platform for training generative AI models项目地址: https://gitcode.com/GitHub_Trending/to/torchtitan

本文基于 TorchTitan 仓库中 DeepSeek-V3 模型文档,完整覆盖该模型在 TorchTitan 中的落地流程:下载 tokenizer、通过run_train.sh启动 debugmodel/16B/671B 三档训练、启用融合 Triton 内核的性能优化选项,以及 HuggingFace safetensors 到 DCP 格式的检查点离线转换,并结合 模型注册表 与 训练配置 源码解读各配置的默认值与底层机制,帮助你在多机多卡环境下完成 DeepSeek-V3 架构的预训练调试与权重迁移。

一、DeepSeek-V3 模块在 TorchTitan 中的位置

DeepSeek-V3 的实现在 torchtitan/models/deepseek_v3/ 目录下,核心文件职责如下:

文件职责
__init__.py模型注册表model_registry,定义 debugmodel/16B/236B/671B 四档 flavor 及 MLA+MoE 层构建逻辑
model.pyDeepSeekV3Model、MLA 注意力AttentionDeepSeekV3TransformerBlock的定义
moe.py / mtp.pyDeepSeek-V3 路由器DeepSeekV3Router;MTP(多 token 预测)MTPDecoderMTPLoss
config_registry.py各 flavor 的Trainer.Config(数据、优化器、并行度、编译等)
sharding.py / parallelize.pyFSDP/TP/SP/EP 分片策略与并行化入口
state_dict_adapter.pyHF 命名与 TorchTitan 命名之间的 state dict 映射,支撑检查点互转
MTP.mdMTP 实现的完整设计文档(本文聚焦主 README 的训练流程)

二、下载 Tokenizer

2.1 两条下载命令

671B 参数模型使用 DeepSeek-V3.1-Base 的官方 tokenizer(自动下载tokenizer.jsontokenizer_config.json):

# DeepSeek 671B tokenizer python scripts/download_hf_assets.py --repo_id deepseek-ai/DeepSeek-V3.1-Base --assets tokenizer

16B 参数模型则复用 deepseek-moe-16b-base 的 tokenizer:

# DeepSeek 16B tokenizer python scripts/download_hf_assets.py --repo_id deepseek-moe-16b-base --assets tokenizer

2.2 为什么 16B 复用另一个仓库的 tokenizer

原 README 明确说明:TorchTitan 复用 deepseek-moe-16b-base 的 tokenizer 只是为了帮助用户测试和运行 16B 模型,它不是DeepSeek-V3-16B 模型的官方 tokenizer。根本原因在于架构差异:DeepSeek-V3 模型与 deepseek-moe 系列在注意力实现(MLA)、MoE router 实现等方面都不同,导致无法直接把 deepseek-moe-16b 的权重加载进 DeepSeek-V3-16B。这一判断也能从 模型注册表源码得到印证——TorchTitan 的 16B 配置(_16b)采用的是 DeepSeek-V3 家族参数(64 个专家、top_k=6、MLA 注意力),而非 deepseek-moe-16b 的结构。

2.3 下载脚本的行为细节

从 download_hf_assets.py 源码可以看到:--assets tokenizer会匹配下载tokenizer.jsontokenizer_config.jsontokenizer.modelvocab.txtvocab.jsonmerges.txtspecial_tokens_map.json等模式;脚本会根据repo_id中的模型名(/之后的部分)自动在local_dir下创建同名子目录存放文件。这解释了训练配置中hf_assets_path的取值——config_registry.py 中 671B 指向./assets/hf/DeepSeek-V3.1-Base,16B 指向./assets/hf/deepseek-moe-16b-base,即脚本按仓库名建目录后的产物位置。

三、三档训练命令与 run_train.sh 启动机制

3.1 启动脚本内部做了什么

三条训练命令统一通过仓库根目录的 run_train.sh 执行,该脚本的关键行为:

  • 通过环境变量MODULECONFIG指定模型模块和训练配置(默认llama3/llama3_debugmodel);
  • NGPU默认 8,最终调用torchrun --nproc_per_node=${NGPU} --rdzv_backend c10d -m torchtitan.train --module ${MODULE} --config ${CONFIG} "$@",因此训练参数可以直接以 tyro 风格追加在命令末尾;
  • LOG_RANK(默认 0)指定只 tee 输出哪个 rank 的日志;
  • 支持COMM_MODE="fake_backend"干跑模式:使用伪造的进程组、单 GPU、无需 NCCL 初始化,配合--training.steps 1可用来在纯 CPU/单机环境验证配置合法性。

3.2 三条核心命令(原 README 完整继承)

# 小型模型快速调试(Quick debug run with small model) MODULE=deepseek_v3 CONFIG=deepseek_v3_debugmodel ./run_train.sh
# 16B 参数模型:适配自较早的 16B 参数模型(deepseek-moe-16b-base 同系列参数规模) MODULE=deepseek_v3 CONFIG=deepseek_v3_16b ./run_train.sh
# 671B 参数模型 MODULE=deepseek_v3 CONFIG=deepseek_v3_671b ./run_train.sh

3.3 各配置对应的 Trainer.Config 参数

对照 config_registry.py 源码,三个默认配置的实际参数如下:

配置项deepseek_v3_debugmodeldeepseek_v3_16bdeepseek_v3_671b
模型 flavordebugmodel(dim 256,6 层,8 专家)16B(dim 2048,27 层,64 专家)671B(dim 7168,61 层,256 专家)
tokenizer 资产路径./tests/assets/tokenizer(仓库自带测试 tokenizer,无需下载)./assets/hf/deepseek-moe-16b-base./assets/hf/DeepSeek-V3.1-Base
数据集c4_test(仓库内小样本)c4c4
优化器/学习率AdamW,lr=8e-4AdamW,lr=2.2e-4AdamW,lr=2.2e-4
LR 调度线性衰减,warmup 2 步,min_lr_factor=0余弦衰减,decay_ratio=0.8,min_lr_factor=0.1余弦衰减,warmup 2000 步,decay_ratio=0.8,min_lr_factor=0.1
总步数10100010000
微批 token 数/DP rank8 × max_context_length4 × max_context_length4 × max_context_length
并行度EP=1EP=8,PP 调度 Interleaved1F1BEP=2,PP 调度 Interleaved1F1B
检查点每 10 步每 10 步每 500 步
激活检查点SelectiveACSelectiveACSelectiveAC
编译默认开启 loss 编译开启 loss 编译
CUDA Graphs默认禁用禁用

三档配置均使用ChunkedLossWrapper包裹CrossEntropyLoss,并把词表大小传给 loss 以支持 loss-parallel 交叉熵路径。16B/671B 的注意力后端通过model_registry(..., attn_backend="flex")指定为 flex attention。四档 flavor 的上下文长度上限均为 16384,见 deepseekv3_configs 表:

deepseekv3_configs = { "debugmodel": (_debugmodel, 16384), "16B": (_16b, 16384), "236B": (_236b, 16384), "671B": (_671b, 16384), }

需要说明的是,注册表中实际还存在236Bflavor(dim 5120、60 层、160 专家、top_k=6、Softmax 路由分数并带 8 组/限 3 组的 group-limited 路由),但 README 默认推荐的是上面三档命令,236B 可通过CONFIG指向对应注册配置使用。

3.4 注册表中的架构要点

init.py 的 flavor 定义可以读出 DeepSeek-V3 的关键架构选择:

  • MLA(多头潜在注意力):所有 flavor 都有kv_lora_rank=512qk_nope_head_dim=128qk_rope_head_dim=64v_head_dim=128;debugmodel/16B 设q_lora_rank=0(Q 走单一线性wq),236B/671B 设q_lora_rank=1536(Q 走低秩分解wq_aq_normwq_b)。model.py 中的 Attention 实现了 KV 压缩(wkv_a压缩到 512 维 latent,kv_norm归一化后wkv_b展开),K 的 RoPE 分量通过对所有头 expand 复用来共享;
  • 前密后稀的 FFN 布局n_dense_layers之前的层用稠密 FeedForward(debugmodel/16B/236B 为 1 层,671B 为 3 层),之后全部为 MoE 层(256 专家 × 671B,top_k=8,8 组限 4 组的辅助损失路由,aux_loss_coeff=1e-3);
  • YaRN 长上下文 RoPE:统一使用ComplexRoPE+scaling="yarn"rope_factor=40.0original_seq_len=4096,与 MLA 的mscale共同作用于 softmax 缩放(见 model.py L92-L94);
  • 可选变体config_registry.py还定义了deepseek_v3_debugmodel_mxfp8(对 MoE grouped GEMM 及稠密线性做 MXFP8 量化,pad_multiple=128为 sm_100/B200 上 CuTeDSL 量化内核的硬要求)、deepseek_v3_671b_float8(float8 路径,注释标明需要 torchao 且仅支持 NVIDIA SM89+ 或 AMD MI300+,其他后端构建时会报错,应回退到普通 671B 配置)、deepseek_v3_16b_hybridep/deepseek_v3_debugmodel_hybridepmoe_comm_backend="hybridep",并把non_blocking_capacity_factor=1.0),以及deepseek_v3_debugmodel_mtpnum_mtp_layers=1、内部 loss 换为MTPLoss.Config,其mtp_scale默认 0.3,见 mtp.py)。MTP 的输入构造、并行分片与损失计算细节可进一步阅读 MTP.md。

四、性能优化选项:融合 Triton 内核

原 README 指出,DeepSeek-V3 可以可选地启用三类融合 Triton 内核:MLA Q/KV 组装ComplexRoPESwiGLU。这些 override 通过 tyro 的--override.imports机制注入,且保持现有模型参数名与检查点布局不变(即转换后的模型可直接加载/保存原有格式的检查点):

MODULE=deepseek_v3 CONFIG=deepseek_v3_671b ./run_train.sh \ --override.imports torchtitan.overrides.fused_mla.fused_mla,torchtitan.overrides.fused_swiglu.fused_swiglu

对应的实现位于 torchtitan/overrides/fused_mla.py 与 torchtitan/overrides/fused_swiglu.py,模块内通过 override 注册替换默认的逐算子实现;由于只替换计算、不改变参数布局,这一优化对 checkpoint 兼容性零成本。run_train.sh会原样透传"$@",因此该参数无需修改脚本即可生效。

五、HuggingFace 到 DCP 检查点转换

5.1 转换命令与适用范围

TorchTitan 为 DeepSeek-V3 实现了StateDictAdapter,用于 HuggingFace safetensors 到 DCP(PyTorch Distributed Checkpoint)格式的转换。原 README 明确了当前限制:只支持从 HF 检查点到 DCP 检查点的离线转换(使用 CPU plain tensor),即单向、离线、非分布式。命令如下:

python scripts/checkpoint_conversion/convert_from_hf.py <hf_checkpoints_dir> <dcp_output_dir> --model_name deepseek_v3 --model_flavor 671B

其中<hf_checkpoints_dir>为包含*.safetensors与 index 文件的 HF 权重目录,<dcp_output_dir>为 DCP 输出目录;--model_flavor需与注册表 flavor 名一致(16B/671B 等)。完整用法说明见 scripts/checkpoint_conversion/README.md。

5.2 脚本执行流程(源码走读)

convert_from_hf.py 的核心逻辑在convert_from_hf()函数中,整个流程在torch.inference_mode()下运行:

  1. importlib.import_module(f"torchtitan.models.{model_name}")动态加载模型模块,调用model_registry(model_flavor)拿到ModelSpec
  2. torch.device("cpu")build()模型——这就是 README 所说 "using CPU plain tensor" 的来源,整个转换不依赖 GPU;
  3. ModelWrapper包装后,取 TorchTitan 命名的空 state dict(model._get_state_dict());
  4. 调用sd_adapter.to_hf(state_dict)把 TT 命名映射回 HF 命名(反向重命名 + 必要的 reshape/拼接),得到 HF 命名的空 state dict;
  5. dcp.load(hf_state_dict, storage_reader=HuggingFaceStorageReader(path=input_dir))从 HF safetensors 目录读取权重填入;
  6. sd_adapter.from_hf(hf_state_dict)映射回 TorchTitan 命名,最后dcp.save(...)写出标准 DCP 目录。

映射规则由 DeepSeekV3StateDictAdapter 定义,负责处理 MLA 的wq_a/wq_b/wkv_a/wkv_b/wo、路由门、专家权重等在 HF 命名与 TorchTitan 命名间的差异。转换完成后,得到的 DCP 目录即可被 TorchTitan 训练器通过--checkpoint.enable等参数直接恢复训练(见 checkpoint.md)。

六、快速上手清单

  1. 按 flavor 执行 tokenizer 下载命令(debugmodel 可用仓库自带./tests/assets/tokenizer,无需下载);
  2. MODULE=deepseek_v3 CONFIG=<config> ./run_train.sh启动,追加NGPU=...LOG_RANK=...或 tyro 参数覆盖默认值;无 GPU 时可用NGPU=8 COMM_MODE="fake_backend" ./run_train.sh干跑验证配置;
  3. 大模型追求性能时,为 671B 追加--override.imports启用 fused MLA 与 fused SwiGLU 内核;
  4. 已有 HF 权重时,先用convert_from_hf.py离线转换为 DCP 格式再断点续训;
  5. 需要 MTP 训练、MXFP8/Float8 量化或 HybridEP 通信后端时,参考 config_registry.py 中的对应变体配置与 MTP 设计文档。

【免费下载链接】torchtitanA PyTorch native platform for training generative AI models项目地址: https://gitcode.com/GitHub_Trending/to/torchtitan

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询