Skip to content

Commit 859abdf

Browse files
committed
update sharding to remove extra datacopy
update refactor update Add optional config Explicitly shard input tensors across mesh devices Run on 0.7.2 candidate image Fix typo in image tag Revert to use latest tag update test for new jax version Remove sharding rules for q_lora and kv_lora from base.yml update with configs clean up update
1 parent 2b25adf commit 859abdf

7 files changed

Lines changed: 53 additions & 14 deletions

File tree

.github/workflows/run_tests_internal.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,4 @@ jobs:
6767
FINAL_PYTEST_MARKER="${{ inputs.pytest_marker }} and not scheduled_only"
6868
fi
6969
python3 -m pip install -e . --no-dependencies &&
70-
python3 -m pytest -v -m "${FINAL_PYTEST_MARKER}" --durations=0
70+
LIBTPU_INIT_ARGS='--xla_tpu_scoped_vmem_limit_kib=65536' python3 -m pytest -v -m "${FINAL_PYTEST_MARKER}" --durations=0

src/MaxText/configs/base.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ expert_shard_attention_option: "fsdp"
182182

183183
# When MoE weight matrices are sharded on both FSDP and FSDP-transpose axes, use two separate All-Gather calls
184184
moe_fsdp_use_two_stage_all_gather: False
185+
# shard the moe weights on num_expert_dim. this can be performanct when num_expert % fdsp_parallisum
186+
fsdp_shard_on_exp: False
185187

186188
# deepseek moe
187189
base_moe_mlp_dim: 7168 # intermediate dimension at MoE layer. For a fully MoE model, base_mlp_dim must be equal to base_moe_mlp_dim.
@@ -385,10 +387,12 @@ logical_axis_rules: [
385387
['q_lora', ['fsdp', 'sequence', 'context', 'tensor_transpose', 'expert']],
386388
['q_lora', ['fsdp', 'fsdp_transpose', 'sequence', 'context', 'expert']],
387389
['q_lora', ['fsdp', 'sequence', 'context', 'expert']],
390+
["q_lora_up_proj",[]],
388391
['kv_lora', ['fsdp', 'fsdp_transpose', 'sequence', 'context', 'tensor_transpose', 'expert']],
389392
['kv_lora', ['fsdp', 'sequence', 'context', 'tensor_transpose', 'expert']],
390393
['kv_lora', ['fsdp', 'fsdp_transpose', 'sequence', 'context', 'expert']],
391394
['kv_lora', ['fsdp', 'sequence', 'context', 'expert']],
395+
["kv_lora_up_proj",[]],
392396
['norm', ['tensor', 'tensor_transpose']],
393397
['layers', 'stage'],
394398
['kv', []],
@@ -405,6 +409,8 @@ logical_axis_rules: [
405409
['num_pages', []],
406410
['tokens_per_page', []],
407411
['paged_kv_head_dim_size', []],
412+
['dense_layers', []],
413+
['moe_layers', []],
408414
]
409415
# Axes used for DCN must be earlier in this list than ICI, see (b/339009148) for details
410416
data_sharding: [['data', 'stage', 'fsdp', 'fsdp_transpose', 'sequence', 'context', 'context_autoregressive', 'tensor', 'tensor_transpose', 'tensor_sequence', 'expert', 'autoregressive']]

src/MaxText/layers/attention_mla.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ def _init_projections(self, inputs_q_shape: Tuple, inputs_kv_shape: Tuple) -> No
398398
out_features_shape=self.q_lora_rank,
399399
axis=-1,
400400
kernel_init=self.kernel_init,
401-
kernel_axes=("embed", "q_lora"),
401+
kernel_axes=("embed", "q_lora_up_proj"),
402402
dtype=self.dtype,
403403
weight_dtype=self.weight_dtype,
404404
quant=self.quant,
@@ -432,7 +432,7 @@ def _init_projections(self, inputs_q_shape: Tuple, inputs_kv_shape: Tuple) -> No
432432
out_features_shape=self.kv_lora_rank + self.qk_rope_head_dim,
433433
axis=-1,
434434
kernel_init=self.kernel_init,
435-
kernel_axes=("embed", "kv_lora"),
435+
kernel_axes=("embed", "kv_lora_up_proj"),
436436
dtype=self.dtype,
437437
weight_dtype=self.weight_dtype,
438438
quant=self.quant,

src/MaxText/layers/moe.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,13 @@ def __init__(
300300
self.quant = quant
301301
self.rngs = rngs
302302

303-
self.wi_kernel_axes = ("exp", "embed_no_exp", "mlp")
304-
self.wo_kernel_axes = ("exp", "mlp", "embed_no_exp")
303+
if self.config.fsdp_shard_on_exp:
304+
# special sharding for dsv3
305+
self.wi_kernel_axes = ("embed_no_exp", None, "mlp")
306+
self.wo_kernel_axes = ("embed_no_exp", "mlp", None)
307+
else:
308+
self.wi_kernel_axes = ("exp", "embed_no_exp", "mlp")
309+
self.wo_kernel_axes = ("exp", "mlp", "embed_no_exp")
305310

306311
self.gate = GateLogit(
307312
in_features_shape=self.config.emb_dim,
@@ -427,6 +432,7 @@ def get_topk(self, gate_logits, pre_bias_logits, rngs=None):
427432

428433
return top_k_weights, top_k_indices
429434

435+
430436
def deepseek_scale_weights(self, weights):
431437
"""Scales weights according to DeepSeek's v3 reference implementation."""
432438
# https://github.com/deepseek-ai/DeepSeek-V3/blob/2f7b80eecebf3d1c84da5a0d465f6639ea175012/inference/model.py#L592-L594.
@@ -900,9 +906,15 @@ def gmm(inputs, kernel, group_sizes, expert_assignments):
900906

901907
# w0, w1, wo needs to be un sharded on fsdp / fsdp_transpose axis, so use
902908
# mlp_no_fsdp axis
903-
w0_pspec = nn.logical_to_mesh_axes(("exp", "embed_tensor_transpose", "mlp_no_fsdp"))
904-
w1_pspec = nn.logical_to_mesh_axes(("exp", "embed_tensor_transpose", "mlp_no_fsdp"))
905-
wo_pspec = nn.logical_to_mesh_axes(("exp", "mlp_no_fsdp", "embed_tensor_transpose"))
909+
if self.config.fsdp_shard_on_exp:
910+
# special sharding for dsv3 to remove overhead between gmm/AG
911+
w0_pspec = nn.logical_to_mesh_axes(("embed_tensor_transpose", None, "mlp_no_fsdp"))
912+
w1_pspec = nn.logical_to_mesh_axes(("embed_tensor_transpose", None, "mlp_no_fsdp"))
913+
wo_pspec = nn.logical_to_mesh_axes(("embed_tensor_transpose", "mlp_no_fsdp", None))
914+
else:
915+
w0_pspec = nn.logical_to_mesh_axes(("exp", "embed_tensor_transpose", "mlp_no_fsdp"))
916+
w1_pspec = nn.logical_to_mesh_axes(("exp", "embed_tensor_transpose", "mlp_no_fsdp"))
917+
wo_pspec = nn.logical_to_mesh_axes(("exp", "mlp_no_fsdp", "embed_tensor_transpose"))
906918
if isinstance(w0_kernel, aqt.QTensor):
907919
w0_pspec = aqt.partition_spec(w0_pspec, (1,), w0_kernel.dtype, use_bias=False)
908920
if isinstance(w1_kernel, aqt.QTensor):

src/MaxText/pyconfig.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ def validate_keys(keys):
219219
validate_mlp_dim(keys)
220220
validate_sparse_matmul_parallelism(keys)
221221
validate_ring_of_experts_parallelism(keys)
222+
validate_shard_fsdp_on_expert_parallelism(keys)
222223
validate_ragged_dot(keys)
223224
validate_deepseek_moe(keys)
224225
validate_expert_shard_attention_option(keys["expert_shard_attention_option"])
@@ -1049,6 +1050,11 @@ def validate_ring_of_experts_parallelism(raw_keys):
10491050
if raw_keys["use_ring_of_experts"] and not using_expert_parallelism(raw_keys):
10501051
raise ValueError("Ring-of-experts requires expert-parallelism to be enabled.")
10511052

1053+
def validate_shard_fsdp_on_expert_parallelism(raw_keys):
1054+
if raw_keys["fsdp_shard_on_exp"] and raw_keys["num_experts"] % raw_keys["ici_fsdp_parallelism"]!=0:
1055+
raise ValueError("fsdp_shard_on_exp requires num_experts is divisiable by ici_fsdp_parallelism.")
1056+
if raw_keys["fsdp_shard_on_exp"] and (using_tensor_parallelism(raw_keys) or useing_expert_parallelism(raw_keys)):
1057+
raise ValueError("fsdp_shard_on_exp requires ici_expert_parallelism = 1 and ici_tensor_parallelism/ici_tensor_transpose_parallelism = 1.")
10521058

10531059
def validate_ragged_dot(raw_keys):
10541060
if raw_keys["sparse_matmul"] and not raw_keys["megablox"]:

tests/attention_test.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
import numpy as np
2828

29-
from jax.sharding import Mesh
29+
from jax.sharding import Mesh, NamedSharding, PartitionSpec
3030
import jax
3131
import jax.numpy as jnp
3232

@@ -1383,6 +1383,21 @@ def _forward_with_context_expert_parallelism(cfg_cp, mesh_cp, attention_cp, lnx,
13831383
decoder_positions = reordered_batch["inputs_position"]
13841384
# apply attention with sharding
13851385
with mesh_cp, nn_partitioning.axis_rules(cfg_cp.logical_axis_rules):
1386+
lnx_spec = nn_partitioning.logical_to_mesh_axes(
1387+
('activation_batch_no_exp', 'activation_length_no_exp', 'activation_embed'),
1388+
nn_partitioning.get_axis_rules()
1389+
)
1390+
pos_spec = nn_partitioning.logical_to_mesh_axes(
1391+
('activation_batch_no_exp', 'activation_length_no_exp'),
1392+
nn_partitioning.get_axis_rules()
1393+
)
1394+
lnx_sharding = NamedSharding(mesh_cp, lnx_spec)
1395+
pos_sharding = NamedSharding(mesh_cp, pos_spec)
1396+
1397+
lnx = jax.device_put(lnx, lnx_sharding)
1398+
decoder_segment_ids = jax.device_put(decoder_segment_ids, pos_sharding)
1399+
decoder_positions = jax.device_put(decoder_positions, pos_sharding)
1400+
13861401
attention_cp_output = attention_cp(
13871402
lnx,
13881403
lnx,

tests/train_compile_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ def test_moe_deepseek_scanned_bf16(self):
493493
"megablox=False",
494494
"per_device_batch_size=2",
495495
"max_target_length=1024",
496-
"attention=dot_product", # Change to flash attention once it works for MLA
496+
"attention=flash",
497497
"dtype=bfloat16",
498498
"weight_dtype=bfloat16",
499499
"scan_layers=True",
@@ -518,7 +518,7 @@ def test_moe_deepseek_unscanned_bf16(self):
518518
"megablox=False",
519519
"per_device_batch_size=1",
520520
"max_target_length=1024",
521-
"attention=dot_product", # Change to flash attention once it works for MLA
521+
"attention=flash",
522522
"dtype=bfloat16",
523523
"weight_dtype=bfloat16",
524524
"scan_layers=False",
@@ -541,7 +541,7 @@ def test_moe_deepseek_with_device_limit(self):
541541
"megablox=False",
542542
"per_device_batch_size=1",
543543
"max_target_length=1024",
544-
"attention=dot_product", # Change to flash attention once it works for MLA
544+
"attention=flash",
545545
"dtype=bfloat16",
546546
"weight_dtype=bfloat16",
547547
"n_routing_groups=8",
@@ -565,7 +565,7 @@ def test_moe_deepseek_without_device_limit(self):
565565
"megablox=False",
566566
"per_device_batch_size=1",
567567
"max_target_length=1024",
568-
"attention=dot_product", # Change to flash attention once it works for MLA
568+
"attention=flash",
569569
"dtype=bfloat16",
570570
"weight_dtype=bfloat16",
571571
"n_routing_groups=-1",
@@ -585,7 +585,7 @@ def test_moe_deepseek_pipeline_subset(self):
585585
"compile_topology_num_slices=8",
586586
"use_iota_embed=true",
587587
"model_name=deepseek3-671b",
588-
"megablox=False", # dropless not yet supported (b/418313093)
588+
"megablox=True",
589589
"sparse_matmul=False",
590590
"capacity_factor=1",
591591
"per_device_batch_size=1",

0 commit comments

Comments
 (0)