Twinkle首发适配Deepseek-V4系列模型高效训练
2026年4月24日,DeepSeek V4发布。284B到1.6T参数的MoE 模型,混合注意力 CSA/HCA、流形约束超连接 mHC、Hash-MoE 静态路由——V4不是一个渐进式升级,而是一次架构重构。主流推理框架在数天内完成了适配,但训练支持的跟进要慢得多。原因很明晰,训练对精度要求更高,且流程更复杂,涉及到前向反向等多个环节,而训练涉及到的算力资源更多,资源调度与通信操作复杂性提升,让训练适配变得难上加难。
对于金融等行业的AI Infra团队来说,这个差异尤其关键。监管要求数据不出域,API调用的路走不通。要在自有集群上微调DeepSeek V4,就必须完整解决MoE分布式训练的一系列工程问题。
Twinkle在FSDP2后端上完成了DeepSeek V4的SFT/LoRA训练适配。核心工作是实现了一套与FSDP2深度集成的Expert Parallelism(EP)方案。
DeepSeek V4模型结构适配
DeepSeek-V4 使用了完全自研的 chat template,无法复用 HF 的 apply_chat_template。我们参考官方 encoding_dsv4.py,在 Twinkle 中实现了完整的编码模版。具体的,我们实现了如下的功能:
完整支持三种模式:
- chat、thinking(<think> 标签)、tools(DSML 格式);
- V4特有Tool Calling调用格式支持:解析 DSML 格式的 <|DSML|invoke> 标签;
- 不同Thinking Mode 支持:包括 reasoning_effort 控制、drop_thinking 策略;


在V4上做 agent训练的团队不需要自己处理tool call的编码解码,Twinkle框架通过适配好的模版直接提供。
FSDP2-4D并行引擎适配
V4-Flash的完整模型加载需要超过500GB 显存,单卡无法容纳。分布式训练是唯一的路径。FSDP2(Fully Sharded Data Parallel v2)是 PyTorch 原生的分布式训练方案,通过将模型参数、梯度、优化器状态分片到多张 GPU 上来降低单卡显存占用。
此前我们已经在Twinkle中实现了EP,专家并行(Expert Parallel, EP)的核心思路是:不让每张卡都持有全部专家,而是把专家参数按 EP rank 切分;前向时 router 仍然为每个 token 选择全局 expert id,然后通过 all-to-all 把 token 分发到对应专家所在 rank,本地专家计算完成后再 all-to-all 回收并按 routing weight 合并结果。
本次我们主要在之前FSDP2-4D并行引擎基础上兼容Deepseek V4 的HashRouter。在 DeepSeek V4 中,MoE router 有两种形式:普通 TopKRouter 和 HashRouter。当前 EP 适配没有为两者写两套 dispatch 逻辑,而是在 router 接入层做兼容:
- 对 TopKRouter:router 根据 hidden states 计算 logits,再选择 top-k experts,返回 router_logits / routing_weights / selected_experts 。
- 对 HashRouter:expert 选择不是动态 top-k,而是通过 tid2eid[input_ids] 查表得到固定 expert id;同时仍然用 gate logits 计算这些专家的 routing weights 。
- Twinkle 的 EP patch 会保留 DeepSeek V4 原生 router 的输出。如果 router 的 forward 支持 input_ids,就把上层传入的 input_ids 透传给 router,因此 HashRouter 可以正常执行 tid2eid[input_ids]。随后,无论 selected experts 来自普通 top-k 还是 hash table,都会被当作全局 expert id 构造 expert_mask,进入统一的 token dispatch 流程。

实测在开启ep_fsdp并行策略后,可进一步提升40%的训练效率。
显存、内存优化
284B模型的训练,显存是贯穿所有环节的硬约束。Twinkle在显存、内存等多方面展开了优化。
FSDP2 原本的模型初始化假设所有rank执行同样的`from_pretrained`加载。对于 284B 的模型,每张卡如果加载完整的模型权重,那么加载的权重会在占用284*2Gi*world_sized的内存,假设使用16路fsdp2,即8.875TB的内存。
为解决超大模型在 FSDP2 场景下的初始化内存问题,Twinkle 实现了 rank-aware 的模型初始化机制。具体流程如下:

训练启动时,Rank0 负责加载完整预训练权重,其他 Rank 仅基于 config 构建空模型,从而避免所有设备重复加载整份权重带来的巨大内存开销。随后,Twinkle 在 FSDP2 包裹和模型切分完成后,利用 rank0 广播机制将分片权重分发到各个 Rank,并进一步同步非 persistent buffer。最终,每个 Rank 仅持有自身所需的本地模型分片,在显著降低初始化内存占用的同时,完成训练前的模型恢复与对齐。
国产算力生态支持
DeepSeek V4的checkpoint使用混合FP4/FP8权重——MoE专家权重以FP4存储,注意力和其他稠密层以FP8存储。训练前需要将这些权重转换为BF16精度。Twinkle的cookbook 文档提供了权重转换的参考指引。
Twinkle还支持在昇腾上开展训练。通过Platform组件对昇腾的适配,结合在LoRA阶段的设备检测,将所有可训练参数强制对齐到 base model 的 dtype,消除混合精度训练过程中的隐式转换,避免了不必要的性能开销。
同时我们还在昇腾上验证了训练适配的正确性和精度。通过与GPU训练的Loss曲线对比,可以看到趋势完全吻合,逐Step Loss差异在千分之一以内,训练可正常收敛。

通过以上适配工作,用户只需要16卡910c,使用cookbook中的训练脚本,即可启动DeepSeek V4系列模型的微调。
快速开始
环境准备
pip install transformers>=5.8.0
转换 DeepSeek-V4-Flash FP4/FP8 权重为训练格式
单机训练
git clone https://github.com/modelscope/twinkle.git
cd twinkle
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
torchrun --nproc_per_node=8 \
cookbook/transformers/deepseek_v4_flash.py
训练过程截图:

更多推荐




所有评论(0)