Skip to content

Commit 2a72872

Browse files
authored
[train]: Add DeepSeek-V4 TFLOPs. (#1230)
### PR Category <!-- One of [ Train | Inference | Compress | Serve | RL | Core | Hardware | CICD | Tools | Others ] --> [Train] ### PR Types <!-- One of [ User Experience | New Features | Bug Fixes | Improvements | Performance | Breaking Change| Deprecations | Test Case | Docs | Others ] --> [Improvements] Add DeepSeek-V4 TFLOPs. Chane IdentityOp of Engram to None when not use_engram. ### PR Description <!-- Describe what you’ve done -->
1 parent 7bbea91 commit 2a72872

4 files changed

Lines changed: 73 additions & 37 deletions

File tree

flagscale/models/megatron/deepseek_v4/deepseek_builder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def get_deepseek_layer_spec(
108108
if build_engram:
109109
engram_module = EngramModule
110110
else:
111-
engram_module = IdentityOp
111+
engram_module = None
112112
submodules = DeepSeekTransformerLayerSubmodules(
113113
input_layernorm=input_layernorm,
114114
self_attention=hybrid_attn_spec,

flagscale/models/megatron/deepseek_v4/deepseek_transformer_layer.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,15 @@ def __init__(self, config, submodules, *args, **kwargs):
4141
"DeepSeekTransformerLayer now requires config.enable_hyper_connections=True."
4242
)
4343
super().__init__(config=config, submodules=submodules, *args, **kwargs)
44-
45-
self.engram = build_module(
46-
submodules.engram,
47-
engram_cfg=self.config,
48-
layer_id=self.layer_number - 1,
49-
)
44+
if self.config.use_engram:
45+
# If not use_engram, the submodules.engram is None
46+
self.engram = build_module(
47+
submodules.engram,
48+
engram_cfg=self.config,
49+
layer_id=self.layer_number - 1,
50+
)
51+
else:
52+
self.engram = None
5053
self._deepseek_engram_hash_input_ids = None
5154
self._mhc_recompute_manager = None
5255
if self.config.engram_layer_ids is not None and self.layer_number - 1 in self.config.engram_layer_ids:
@@ -104,7 +107,7 @@ def _forward_attention(
104107
inference_params: Optional[Any] = None,
105108
):
106109
"""Apply DeepSeek engram before the parent attention path."""
107-
if not isinstance(self.engram, IdentityOp):
110+
if self.engram is not None:
108111
nvtx_range_push(suffix="engram")
109112
hidden_states = self.engram(hidden_states, self._deepseek_engram_hash_input_ids)
110113
nvtx_range_pop(suffix="engram")

flagscale/train/megatron/training/arguments.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3271,6 +3271,13 @@ def _add_experimental_attention_variant_args(parser):
32713271
"([128]+[4]*23)": 1 HCA layer followed by 23 CSA layers
32723272
"([128]*3+[4]*2)*2": Three HCA layers followed by two CSA layers, repeated twice.
32733273
""")
3274+
group.add_argument(
3275+
'--no-dsa-kernel-fusion',
3276+
action='store_false',
3277+
help='Disable fused DSA sparse-attention kernels (FlashMLA + cuDNN DSA) '
3278+
'and fall back to unfused PyTorch implementations.',
3279+
dest='apply_dsa_kernel_fusion',
3280+
)
32743281
return parser
32753282

32763283
def _add_heterogeneous_args(parser):

flagscale/train/megatron/training/training.py

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -558,42 +558,68 @@ def transformer_flops():
558558
https://arxiv.org/abs/2305.10403
559559
https://arxiv.org/abs/2205.05198
560560
'''
561-
## MLA
562-
if args.q_lora_rank is None:
563-
q_term = (
564-
args.hidden_size
565-
* args.num_attention_heads
566-
* (args.qk_head_dim + args.qk_pos_emb_head_dim)
567-
)
568-
else:
561+
if args.experimental_attention_variant == "dsv4_hybrid":
562+
## DSv4 hybrid MLA projections (per layer, per token).
563+
## In dsv4_hybrid mode, qk_head_dim + qk_pos_emb_head_dim == v_head_dim
564+
## (qk_head_dim is derived as v_head_dim - qk_pos_emb_head_dim), and the
565+
## joint KV is produced by a single hidden -> v_head_dim projection.
566+
## Full core attention is replaced by sparse attention and is accounted
567+
## for in the dsv4_hybrid branch below.
569568
q_term = args.q_lora_rank * (
570569
args.hidden_size
571-
+ args.num_attention_heads * (args.qk_head_dim + args.qk_pos_emb_head_dim)
572-
+ 1
570+
+ args.num_attention_heads * args.v_head_dim
571+
+ 1 # q norm
573572
)
574-
standard_self_attn_term = (
575-
forward_backward_expansion_factor
576-
* fma_expansion_factor
577-
* (
578-
## q lora + rope + q norm
579-
q_term
580-
## kv lora + rope + kv norm
581-
+ args.kv_lora_rank
582-
* (
573+
kv_term = args.hidden_size * args.v_head_dim + args.v_head_dim # kv proj + kv norm
574+
## Grouped low-rank output projection:
575+
## wo_a: (n_head * v_head_dim) -> (o_groups * o_lora_rank)
576+
## linear_proj: (o_groups * o_lora_rank) -> hidden
577+
o_term = (
578+
args.num_attention_heads * args.v_head_dim * args.o_lora_rank
579+
+ args.o_groups * args.o_lora_rank * args.hidden_size
580+
)
581+
standard_self_attn_term = (
582+
forward_backward_expansion_factor
583+
* fma_expansion_factor
584+
* (q_term + kv_term + o_term)
585+
)
586+
else:
587+
## MLA
588+
if args.q_lora_rank is None:
589+
q_term = (
590+
args.hidden_size
591+
* args.num_attention_heads
592+
* (args.qk_head_dim + args.qk_pos_emb_head_dim)
593+
)
594+
else:
595+
q_term = args.q_lora_rank * (
583596
args.hidden_size
584-
+ args.num_attention_heads * (args.qk_head_dim + args.v_head_dim)
597+
+ args.num_attention_heads * (args.qk_head_dim + args.qk_pos_emb_head_dim)
585598
+ 1
586599
)
587-
+ args.hidden_size * args.qk_pos_emb_head_dim
588-
## o proj
589-
+ (args.num_attention_heads * args.v_head_dim) * args.hidden_size
590-
## core attn
591-
+ args.seq_length
592-
* (args.num_attention_heads * (args.qk_head_dim + args.qk_pos_emb_head_dim))
593-
/ 2 # causal mask (only half of the mask is non-zero)
594-
+ args.seq_length * args.num_attention_heads * args.v_head_dim / 2
600+
standard_self_attn_term = (
601+
forward_backward_expansion_factor
602+
* fma_expansion_factor
603+
* (
604+
## q lora + rope + q norm
605+
q_term
606+
## kv lora + rope + kv norm
607+
+ args.kv_lora_rank
608+
* (
609+
args.hidden_size
610+
+ args.num_attention_heads * (args.qk_head_dim + args.v_head_dim)
611+
+ 1
612+
)
613+
+ args.hidden_size * args.qk_pos_emb_head_dim
614+
## o proj
615+
+ (args.num_attention_heads * args.v_head_dim) * args.hidden_size
616+
## core attn
617+
+ args.seq_length
618+
* (args.num_attention_heads * (args.qk_head_dim + args.qk_pos_emb_head_dim))
619+
/ 2 # causal mask (only half of the mask is non-zero)
620+
+ args.seq_length * args.num_attention_heads * args.v_head_dim / 2
621+
)
595622
)
596-
)
597623

598624
else:
599625
## MHA or GQA

0 commit comments

Comments
 (0)