|
40 | 40 | from maxtext.layers.quantizations import AqtQuantization as Quant |
41 | 41 | from maxtext.models import ( |
42 | 42 | deepseek, |
| 43 | + deepseek4, |
43 | 44 | deepseek_batchsplit, |
44 | 45 | deepseek_batchsplit_fp8, |
45 | 46 | gemma, |
@@ -457,6 +458,10 @@ def get_decoder_layers(self): |
457 | 458 | deepseek.DeepSeekDenseLayerToLinen, |
458 | 459 | deepseek.DeepSeekMoELayerToLinen, |
459 | 460 | ] |
| 461 | + case DecoderBlockType.DEEPSEEK4: |
| 462 | + return ( |
| 463 | + [deepseek4.DeepSeek4ScannableBlockToLinen] if self.config.scan_layers else [deepseek4.DeepSeek4LayerToLinen] |
| 464 | + ) |
460 | 465 | case DecoderBlockType.GEMMA: |
461 | 466 | return [gemma.GemmaDecoderLayerToLinen] |
462 | 467 | case DecoderBlockType.GEMMA2: |
@@ -534,6 +539,7 @@ def get_norm_layer(self, num_features: int): |
534 | 539 | DecoderBlockType.MISTRAL, |
535 | 540 | DecoderBlockType.MIXTRAL, |
536 | 541 | DecoderBlockType.DEEPSEEK, |
| 542 | + DecoderBlockType.DEEPSEEK4, |
537 | 543 | DecoderBlockType.GEMMA, |
538 | 544 | DecoderBlockType.GEMMA2, |
539 | 545 | DecoderBlockType.GEMMA3, |
@@ -999,6 +1005,17 @@ def __call__( |
999 | 1005 | previous_chunk, |
1000 | 1006 | slot, |
1001 | 1007 | ) |
| 1008 | + elif cfg.decoder_block == DecoderBlockType.DEEPSEEK4: |
| 1009 | + y = self._apply_deepseek4_scanned_blocks( |
| 1010 | + y, |
| 1011 | + decoder_segment_ids, |
| 1012 | + decoder_positions, |
| 1013 | + deterministic, |
| 1014 | + model_mode, |
| 1015 | + previous_chunk, |
| 1016 | + slot, |
| 1017 | + decoder_input_tokens, |
| 1018 | + ) |
1002 | 1019 | else: |
1003 | 1020 | RemattedBlockLayer = RemattedBlockLayers[0] |
1004 | 1021 | scan_length = int(cfg.num_decoder_layers / cfg.inhomogeneous_layer_cycle_interval) |
@@ -1133,7 +1150,7 @@ def __call__( |
1133 | 1150 | "is_nope_layer": llama4.determine_is_nope_layer(lyr, self.config.nope_layer_interval), |
1134 | 1151 | "is_moe_layer": llama4.determine_is_moe_layer(lyr, self.config.interleave_moe_layer_step), |
1135 | 1152 | } |
1136 | | - if cfg.decoder_block in (DecoderBlockType.QWEN3_NEXT, DecoderBlockType.QWEN3_5): |
| 1153 | + if cfg.decoder_block in (DecoderBlockType.QWEN3_NEXT, DecoderBlockType.QWEN3_5, DecoderBlockType.DEEPSEEK4): |
1137 | 1154 | layer_kwargs = {"layer_idx": lyr} |
1138 | 1155 | kv_cache = None |
1139 | 1156 | if kv_caches is not None: |
@@ -1351,6 +1368,111 @@ def _apply_gemma4_scanned_blocks( |
1351 | 1368 |
|
1352 | 1369 | return y |
1353 | 1370 |
|
| 1371 | + def _apply_deepseek4_scanned_blocks( |
| 1372 | + self, |
| 1373 | + y, |
| 1374 | + decoder_segment_ids, |
| 1375 | + decoder_positions, |
| 1376 | + deterministic, |
| 1377 | + model_mode, |
| 1378 | + previous_chunk, |
| 1379 | + slot, |
| 1380 | + decoder_input_tokens, |
| 1381 | + ): |
| 1382 | + """Applies DeepSeek V4 scanned decoder blocks. |
| 1383 | +
|
| 1384 | + DeepSeek V4 has 44 layers. The first 2 (0,1) and the last 2 (42,43) break the perfectly |
| 1385 | + repeating `[4, 128]` sequence of compression ratios. Therefore, we manually unroll the |
| 1386 | + prefix and suffix layers, and scan the perfectly repeating 40 layers in the middle |
| 1387 | + (20 chunks of 2). |
| 1388 | + """ |
| 1389 | + |
| 1390 | + cfg = self.config |
| 1391 | + mesh = self.mesh |
| 1392 | + |
| 1393 | + broadcast_args = ( |
| 1394 | + decoder_segment_ids, |
| 1395 | + decoder_positions, |
| 1396 | + deterministic, |
| 1397 | + model_mode, |
| 1398 | + slot, |
| 1399 | + previous_chunk, |
| 1400 | + ) |
| 1401 | + |
| 1402 | + layer_call_kwargs = { |
| 1403 | + "previous_chunk": previous_chunk, |
| 1404 | + "slot": slot, |
| 1405 | + "decoder_input_tokens": decoder_input_tokens, |
| 1406 | + } |
| 1407 | + |
| 1408 | + # 1. Prefix Unrolling (Layers 0, 1) |
| 1409 | + # These layers use Hash Routing and compress_ratio=0. |
| 1410 | + for layer_idx in range(2): |
| 1411 | + prefix_layer = deepseek4.DeepSeek4LayerToLinen( |
| 1412 | + config=cfg, |
| 1413 | + mesh=mesh, |
| 1414 | + name=f"layers_{layer_idx}", |
| 1415 | + quant=self.quant, |
| 1416 | + model_mode=self.model_mode, |
| 1417 | + layer_idx=layer_idx, |
| 1418 | + ) |
| 1419 | + y, _ = prefix_layer( |
| 1420 | + y, |
| 1421 | + decoder_segment_ids, |
| 1422 | + decoder_positions, |
| 1423 | + deterministic, |
| 1424 | + model_mode, |
| 1425 | + **layer_call_kwargs, |
| 1426 | + ) |
| 1427 | + |
| 1428 | + # 2. Chunked Scanning (Layers 2 to 41) |
| 1429 | + # These 40 layers perfectly alternate CSA (4) and HCA (128). |
| 1430 | + num_full_blocks = 20 |
| 1431 | + if num_full_blocks > 0: |
| 1432 | + ScannableBlockToLinen = deepseek4.DeepSeek4ScannableBlockToLinen |
| 1433 | + policy = self.get_remat_policy() |
| 1434 | + RemattedDeepSeek4Block = self.set_remat_policy([ScannableBlockToLinen], policy)[0] |
| 1435 | + |
| 1436 | + y, _ = nn.scan( |
| 1437 | + RemattedDeepSeek4Block, |
| 1438 | + variable_axes={ |
| 1439 | + "params": cfg.param_scan_axis, |
| 1440 | + "cache": 0, |
| 1441 | + "intermediates": 0, |
| 1442 | + "aqt": 0, |
| 1443 | + "_overwrite_with_gradient": 0, |
| 1444 | + }, |
| 1445 | + split_rngs={"params": True, "dropout": cfg.enable_dropout}, |
| 1446 | + in_axes=(nn.broadcast,) * len(broadcast_args), |
| 1447 | + length=num_full_blocks, |
| 1448 | + metadata_params={ |
| 1449 | + nn.PARTITION_NAME: "layers", |
| 1450 | + "abstract_init": False, |
| 1451 | + }, |
| 1452 | + )(config=cfg, mesh=mesh, quant=self.quant, model_mode=model_mode, name="scanned_blocks",)(y, *broadcast_args) |
| 1453 | + |
| 1454 | + # 3. Suffix Unrolling (Layers 42, 43) |
| 1455 | + # Layer 42 is CSA (4), Layer 43 is full MoE (0). Both use Top-K routing. |
| 1456 | + for layer_idx in range(42, 44): |
| 1457 | + suffix_layer = deepseek4.DeepSeek4LayerToLinen( |
| 1458 | + config=cfg, |
| 1459 | + mesh=mesh, |
| 1460 | + name=f"layers_{layer_idx}", |
| 1461 | + quant=self.quant, |
| 1462 | + model_mode=self.model_mode, |
| 1463 | + layer_idx=layer_idx, |
| 1464 | + ) |
| 1465 | + y, _ = suffix_layer( |
| 1466 | + y, |
| 1467 | + decoder_segment_ids, |
| 1468 | + decoder_positions, |
| 1469 | + deterministic, |
| 1470 | + model_mode, |
| 1471 | + **layer_call_kwargs, |
| 1472 | + ) |
| 1473 | + |
| 1474 | + return y |
| 1475 | + |
1354 | 1476 | def _apply_gemma4_small_layers( |
1355 | 1477 | self, |
1356 | 1478 | y, |
|
0 commit comments