Skip to content

Commit 9c5c564

Browse files
committed
feat: implement DeepSeek-V4 model integration, decoders, and configuration stack
1 parent b7afa2d commit 9c5c564

17 files changed

Lines changed: 5169 additions & 79 deletions

src/maxtext/common/common_types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class DecoderBlockType(enum.Enum):
9393
MISTRAL = "mistral"
9494
MIXTRAL = "mixtral"
9595
DEEPSEEK = "deepseek"
96+
DEEPSEEK_V4 = "deepseek_v4"
9697
GEMMA = "gemma"
9798
GEMMA2 = "gemma2"
9899
GEMMA3 = "gemma3"

src/maxtext/configs/base.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ topk_routing_group: -1 # number of top groups to route inputs. For EP,
268268
# all-to-all communication with compute. Currently only implemented with DeepSeek sparse layers.
269269
use_batch_split_schedule: False # a flag if splitting batch into micro-batches to hide communications that yields performance benefits.
270270
batch_split_factor: 1 # the factor by which to split the batch. Only used if use_batch_split_schedule is True.
271+
num_hash_layers: 3 # Number of initial MoE layers to apply static Hash Routing.
271272

272273
# For complex architectures like llama4 there are repeated sets of
273274
# inhomogeneous layers. E.g. maverick uses [dense+rope, moe+rope, dense+rope, moe+nope]
@@ -405,6 +406,16 @@ qk_clip_threshold: 100.0 # Threshold for clipping (tau in the paper)
405406
fused_qkv: False
406407
fused_mlp: False
407408

409+
# DeepSeek-V4 Compressed Attention parameters
410+
compress_rope_theta: 160000.0
411+
compress_ratios: []
412+
index_head_dim: 128
413+
index_n_heads: 64
414+
index_topk: 512
415+
o_groups: 8
416+
o_lora_rank: 1024
417+
sliding_window: 128
418+
408419
record_internal_nn_metrics: 0
409420

410421
# Output directory
@@ -1217,6 +1228,7 @@ force_q_layout: false
12171228
mhc_expansion_rate: 1
12181229
# The number of iterations for the Sinkhorn-Knopp algorithm.
12191230
sinkhorn_iterations: 20
1231+
hc_eps: 1.0e-6
12201232

12211233
################################## DeepSeek Engram ##################################
12221234
# Indices of transformer layers where Engram are integrated; leave empty [] to disable.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Default model configs for DeepSeek-V4-Flash (43 Layers)
16+
17+
base_config: base.yml
18+
model_name: deepseek_v4-flash
19+
20+
base_emb_dim: 4096
21+
base_num_query_heads: 64
22+
base_num_kv_heads: 1
23+
head_dim: 512
24+
base_mlp_dim: 2048
25+
base_moe_mlp_dim: 2048
26+
base_num_decoder_layers: 43
27+
first_num_dense_layers: 0
28+
mlp_activations: ["silu"]
29+
vocab_size: 129280
30+
tokenizer_type: "huggingface"
31+
tokenizer_path: "deepseek-ai/DeepSeek-V3"
32+
enable_dropout: False
33+
logits_via_embedding: False
34+
normalization_layer_epsilon: 1.0e-6
35+
num_experts: 256
36+
num_experts_per_tok: 6
37+
shared_experts: 1
38+
routed_scaling_factor: 1.5
39+
routed_score_func: "sqrtsoftplus"
40+
routed_bias: True
41+
norm_topk_prob: True
42+
decoder_block: "deepseek_v4"
43+
pure_nnx_decoder: True
44+
enable_nnx: True
45+
use_tokamax_splash: True
46+
# TODO: Dynamic Flash Attention masking requires use_indexer: True to route the custom compressor mask indexer_mask into Tokamax's make_dynamic_splash_mha dynamic Pallas kernel path. Refactor this MLA configuration parameter out of deep coordinator layers in subsequent milestones.
47+
use_indexer: True
48+
remat_policy: minimal_offloaded
49+
50+
# Manifold-Constrained Hyper-Connection configurations
51+
mhc_expansion_rate: 4
52+
sinkhorn_iterations: 20
53+
compress_rope_theta: 160000.0
54+
index_head_dim: 128
55+
index_n_heads: 64
56+
index_topk: 512
57+
o_groups: 8
58+
o_lora_rank: 1024
59+
sliding_window: 128
60+
num_hash_layers: 3
61+
mlp_activations_limit: 10.0
62+
compress_ratios: [0, 0, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4, 128, 4]
63+
64+
# Compressed Sparse Attention
65+
q_lora_rank: 1024
66+
kv_lora_rank: 512
67+
qk_nope_head_dim: 128
68+
qk_rope_head_dim: 64
69+
v_head_dim: 128
70+
mscale: 1.0
71+
72+
# RoPE
73+
rope_type: "default"
74+
rope_max_timescale: 10_000
75+
max_position_embeddings: 1048576
76+
original_max_position_embeddings: 65536
77+
rope_factor: 16
78+
beta_fast: 32
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Tiny version of DeepSeek-V4 (4 Layers) for local sharding and compilation checks.
16+
17+
base_config: base.yml
18+
model_name: deepseek_v4-tiny
19+
20+
base_emb_dim: 128
21+
base_num_query_heads: 16
22+
base_num_kv_heads: 1
23+
head_dim: 32
24+
base_mlp_dim: 128
25+
base_moe_mlp_dim: 128
26+
base_num_decoder_layers: 6
27+
first_num_dense_layers: 0
28+
mlp_activations: ["silu"]
29+
vocab_size: 129280
30+
tokenizer_type: "huggingface"
31+
tokenizer_path: "deepseek-ai/DeepSeek-V3"
32+
enable_dropout: False
33+
logits_via_embedding: False
34+
normalization_layer_epsilon: 1.0e-6
35+
num_experts: 8
36+
num_experts_per_tok: 4
37+
shared_experts: 1
38+
routed_scaling_factor: 1.5
39+
routed_score_func: "sqrtsoftplus"
40+
routed_bias: True
41+
norm_topk_prob: True
42+
decoder_block: "deepseek_v4"
43+
pure_nnx_decoder: True
44+
enable_nnx: True
45+
46+
# Manifold-Constrained Hyper-Connection configurations
47+
mhc_expansion_rate: 4
48+
sinkhorn_iterations: 20
49+
compress_rope_theta: 160000.0
50+
index_head_dim: 32
51+
index_n_heads: 16
52+
index_topk: 64
53+
o_groups: 2
54+
o_lora_rank: 64
55+
sliding_window: 32
56+
num_hash_layers: 3
57+
mlp_activations_limit: 10.0
58+
compress_ratios: [0, 4, 128, 4, 128, 0]
59+
60+
# Compressed Attention
61+
q_lora_rank: 64
62+
kv_lora_rank: 32
63+
qk_nope_head_dim: 32
64+
qk_rope_head_dim: 16
65+
v_head_dim: 128
66+
mscale: 1.0
67+
68+
# RoPE
69+
rope_type: "default"
70+
rope_max_timescale: 10_000
71+
max_position_embeddings: 163840
72+
original_max_position_embeddings: 4096
73+
rope_factor: 40
74+
beta_fast: 32

src/maxtext/configs/types.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ class ProfilerType(str, Enum):
226226
"deepseek3-test",
227227
"deepseek3-tiny",
228228
"deepseek3.2-671b",
229+
"deepseek_v4-tiny",
230+
"deepseek_v4-flash",
229231
"deepseek-custom",
230232
"kimi-k2-1t",
231233
"gemma-7b",
@@ -618,6 +620,22 @@ class AttentionIndexer(BaseModel):
618620
indexer_loss_scaling_factor: float = Field(0.0, description="Multiplier for the indexer KL divergence loss.")
619621

620622

623+
class DeepSeekV4AttentionConfig(BaseModel):
624+
"""Configuration specific to DeepSeek-V4 stateless compressed attention layers."""
625+
626+
compress_rope_theta: float = Field(160000.0, description="Theta base frequency for long-range compressor layers.")
627+
compress_ratios: list[int] = Field(
628+
default_factory=list,
629+
description="Layer-by-layer compressor rates (0: standard, 4: CSA, 128: HCA).",
630+
)
631+
index_head_dim: int = Field(128, description="Head dim for indexer query and key.")
632+
index_n_heads: int = Field(64, description="Number of query heads in indexer.")
633+
index_topk: int = Field(512, description="Number of tokens selected by indexer.")
634+
o_groups: int = Field(8, description="Number of group partitions for grouped linear output projection.")
635+
o_lora_rank: int = Field(1024, description="Low-rank output dimension prior to grouped mix projection.")
636+
sliding_window: int = Field(128, description="Sliding window size for attention.")
637+
638+
621639
class Llama4Attention(BaseModel):
622640
"""Configuration specific to Llama4-style models."""
623641

@@ -815,6 +833,10 @@ class DeepSeekMoE(BaseModel):
815833
1,
816834
description="Factor by which to split the batch into micro-batches. Only used if use_batch_split_schedule is True.",
817835
)
836+
num_hash_layers: int = Field(
837+
3,
838+
description="Number of initial MoE layers to apply static Hash Routing.",
839+
)
818840

819841

820842
class Qwen3Next(BaseModel):
@@ -1365,6 +1387,7 @@ class ManifoldConstrainedHyperConnections(BaseModel):
13651387

13661388
mhc_expansion_rate: PositiveInt = Field(1, description="The number of parallel streams in Hyper Connection.")
13671389
sinkhorn_iterations: PositiveInt = Field(20, description="The number of iterations for the Sinkhorn-Knopp algorithm.")
1390+
hc_eps: float = Field(1e-6, description="The epsilon fallback value for numerical stability in mHC.")
13681391

13691392

13701393
class DilocoParams(BaseModel):
@@ -2224,6 +2247,7 @@ class MaxTextConfig(
22242247
MlaAttention,
22252248
MoBa,
22262249
AttentionIndexer,
2250+
DeepSeekV4AttentionConfig,
22272251
Llama4Attention,
22282252
SplashAttention,
22292253
PagedAttention,

0 commit comments

Comments
 (0)