Skip to content

Commit 87ceabb

Browse files
committed
feat(model): add Shensi model support
Shensi is a sparse-attention MoE family: every decoder layer picks one of three attention paths from a per-layer plan (compressed sparse / heavily compressed / sliding window), the residual stream is a pool of streams, layers group into attention-residual blocks that may span pipeline stages, the leading layers are token-embedding-gated dense MLPs, and routed experts use a low-rank bottleneck with an ERC auxiliary loss. The hybrid attention rides Megatron-Core's dsv4_hybrid path. - configuration_shensi: HF-side config plus the Megatron-Core transformer config (no mHC: the residual path is the attention-residual read, so the V4 stream fields/knobs are not carried) - modeling_shensi: attention residuals with pipeline-stage state transfer (the block history is kept as one tensor per block, without a full-buffer copy at every block boundary), MoE layout, selective fp32 keeping, decoder layer/stack and layer specs - shensi_bridge / shensi_provider: config and parameter mapping, model provider - shensi_builder: HybridModelConfig + HybridModelBuilder wiring so a training recipe can build the model through Megatron-Core's model-config / model-builder API - unit tests (attention-residual parity against the HF reference, per-slot block layout, hybrid stack, provider, ERC gather, pipeline state transfer) and functional tests with an L0 launcher - model registry, README and docs entries Follow-ups folded in while validating with a real 5-step smoke run: - defaults follow the 2.78B / 1.24B-active geometry (routed_expert_hidden_size 320, attn_res_block_size 2, o_groups 2, o_lora_rank 320, moe_intermediate_size 800, 1 MTP layer) - attention-residual block writes are functional: the in-place variant bumped the storage version of the buffer the read path holds in the autograd graph and failed in backward - csa_dense_mode and the loss coefficients (indexer KL / aux / ERC) remain training-side settings: they are no longer forced by hard defaults or by HF-side injection - the provider path (AutoBridge conversion / provider smoke) builds again after the HybridModel migration: it no longer reads the GPT-only `scatter_embedding_sequence_parallel`, and the MTP depths map their inner decoder layer under `mtp.layers.{d}.mtp_model_layer.layers.0.` instead of `mtp.layers.{d}.mtp_model_layer.` - the MTP attention-residual state is bound on the inner decoder layers as well as on the wrapper (the layers read it in forward, the wrapper is where the MTP layer and its test read it) - `gradient_accumulation_fusion` re-declares the upstream auto-detect default on the provider, so a host without apex fuses nothing instead of failing at model construction - `finalize()` rejects Megatron-Core's own stream machinery (`enable_mhc_connections`, `wide_residual`) the way Megatron-Core rejects an incompatible combination: shensi owns its residual path inside the decoder layers, so the stock knobs would add a second one - the functional tests no longer set `TE_FL_PREFER`; the model and test packages are env-free - the attention-residual state crosses a pipeline stage boundary inside the stage payload itself (`pack_attn_res_payload` / `unpack_attn_res_payload`, the Megatron-LM#6840 layout): the schedule ships whatever the model returns, so the side-channel handoff, its private process group and its header/serialization code are gone, and the state's gradients return through the same tensor; the provider turns on `variable_seq_lengths` when the layout actually crosses, since the payload shape then depends on the microbatch Signed-off-by: 313892219+zongzhilou <313892219+zongzhilou@users.noreply.github.com> The model carries no mHC: the attention-residual read is the residual path, so the V4 stream fields (`hc_mult` and friends), the mHC modules, their parameter mappings and the per-stream state layout are gone (state, payload rows and fp32-keeping now describe one residual stream). - the hash-MoE deep embedding lives in the routed-expert bottleneck (a per-token scale inside the low-rank space, RWKV-8 DeepEmbed's 4x form) and is applied between the activation and the down projection, TP-sharded like the FC1 output
1 parent 79edbdf commit 87ceabb

28 files changed

Lines changed: 5898 additions & 0 deletions

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ Megatron Bridge provides out-of-the-box bridges and training recipes for a wide
252252
| [**OLMoE**](docs/models/olmoe/index.md) | OLMoE |
253253
| [**Qwen**](docs/models/qwen/index.md) | Qwen2 / Qwen2.5, Qwen3, Qwen3-MoE, Qwen3 Next, Qwen3.5 (dense/MoE), Qwen2.5-VL, Qwen3-VL, Qwen3.5-VL, Qwen3.6-VL, Qwen2 Audio, Qwen2.5-Omni, Qwen3-Omni, Qwen3-ASR |
254254
| [**Sarvam**](docs/models/sarvam/index.md) | Sarvam |
255+
| [**Shensi**](docs/models/shensi/index.md) | Shensi |
255256
| [**StepFun**](docs/models/stepfun/index.md) | Step-3.5-Flash, Step-3.7-Flash |
256257

257258
### Launching Recipes

‎docs/fern/versions/nightly.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ navigation:
181181
- page: Sarvam
182182
path: ./nightly/pages/models/sarvam/sarvam.mdx
183183
section: Sarvam
184+
- contents:
185+
- page: Shensi
186+
path: ./nightly/pages/models/shensi/shensi.mdx
187+
section: Shensi
184188
- contents:
185189
- page: Step-3.5-Flash
186190
path: ./nightly/pages/models/stepfun/step35.mdx
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Shensi
2+
3+
Shensi model documentation is organized by model variant.
4+
5+
| Variant | Guide |
6+
|---------|-------|
7+
| Shensi | [shensi.md](shensi.md) |
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Shensi
2+
3+
Shensi is a sparse-attention Mixture-of-Experts language model. Every decoder layer picks one of
4+
three attention paths from a per-layer plan — compressed sparse attention (CSA, compression ratio
5+
4), heavily compressed attention (HCA, 128) or a sliding window — and the residual stream is not a
6+
single tensor but a pool of streams that the sublayers read from and write back into. Layers group
7+
into attention-residual blocks whose state may cross pipeline stages, the leading layers are
8+
token-embedding-gated dense MLPs, and routed experts use a low-rank bottleneck with an ERC
9+
auxiliary loss. The hybrid attention rides Megatron-Core's `dsv4_hybrid` path.
10+
11+
## Supported Variants
12+
13+
| Variant | Notes |
14+
|---------|-------|
15+
| Shensi | CSA/HCA/sliding-window attention plan, attention-residual blocks, hash-routed leading layers |
16+
17+
## Architecture Notes
18+
19+
- The per-layer attention plan is driven by compression ratios (0 = sliding window, 4 = CSA,
20+
128 = HCA); the DSA lightning indexer sits on the CSA layers.
21+
- Attention-residual blocks keep the block history that later layers of the block read; their
22+
state is handed across pipeline stages when a block spans stages.
23+
- Routed experts are low-rank (`routed_expert_hidden_size`). The leading layers use hash routing
24+
(token-id based), which takes no load-balancing loss; the remaining layers use the learned router.
25+
- The model rides `HybridModel` through two equivalent paths: `ShensiModelProvider` (provider) and
26+
`ShensiModelConfig` + `ShensiModelBuilder` (model-config / model-builder).
27+
28+
## Related Implementation
29+
30+
- Bridge implementation: [`src/megatron/bridge/models/shensi`](https://github.com/NVIDIA-NeMo/Megatron-Bridge/tree/main/src/megatron/bridge/models/shensi)
31+
- Implementation notes (layout, knobs, validation): [`src/megatron/bridge/models/shensi/README.md`](https://github.com/NVIDIA-NeMo/Megatron-Bridge/blob/main/src/megatron/bridge/models/shensi/README.md)

‎docs/models/shensi/index.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Shensi
2+
3+
Shensi model documentation is organized by model variant.
4+
5+
```{toctree}
6+
:hidden:
7+
8+
shensi.md
9+
```
10+
11+
| Variant | Guide |
12+
|---------|-------|
13+
| Shensi | [shensi.md](shensi.md) |

‎docs/models/shensi/shensi.md‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Shensi
2+
3+
Shensi is a sparse-attention Mixture-of-Experts language model. Every decoder layer picks one of
4+
three attention paths from a per-layer plan — compressed sparse attention (CSA, compression ratio
5+
4), heavily compressed attention (HCA, 128) or a sliding window — and the residual stream is not a
6+
single tensor but a pool of streams that the sublayers read from and write back into. Layers group
7+
into attention-residual blocks whose state may cross pipeline stages, the leading layers are
8+
token-embedding-gated dense MLPs, and routed experts use a low-rank bottleneck with an ERC
9+
auxiliary loss. The hybrid attention rides Megatron-Core's `dsv4_hybrid` path.
10+
11+
## Supported Variants
12+
13+
| Variant | Notes |
14+
|---------|-------|
15+
| Shensi | CSA/HCA/sliding-window attention plan, attention-residual blocks, hash-routed leading layers |
16+
17+
## Architecture Notes
18+
19+
- The per-layer attention plan is driven by compression ratios (0 = sliding window, 4 = CSA,
20+
128 = HCA); the DSA lightning indexer sits on the CSA layers.
21+
- Attention-residual blocks keep the block history that later layers of the block read; their
22+
state is handed across pipeline stages when a block spans stages.
23+
- Routed experts are low-rank (`routed_expert_hidden_size`). The leading layers use hash routing
24+
(token-id based), which takes no load-balancing loss; the remaining layers use the learned router.
25+
- The model rides `HybridModel` through two equivalent paths: `ShensiModelProvider` (provider) and
26+
`ShensiModelConfig` + `ShensiModelBuilder` (model-config / model-builder).
27+
28+
## Related Implementation
29+
30+
- Bridge implementation: [`src/megatron/bridge/models/shensi`](https://github.com/NVIDIA-NeMo/Megatron-Bridge/tree/main/src/megatron/bridge/models/shensi)
31+
- Implementation notes (layout, knobs, validation): [`src/megatron/bridge/models/shensi/README.md`](https://github.com/NVIDIA-NeMo/Megatron-Bridge/blob/main/src/megatron/bridge/models/shensi/README.md)

‎src/megatron/bridge/models/__init__.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@
213213
SarvamMLABridge,
214214
SarvamMoEBridge,
215215
)
216+
from megatron.bridge.models.shensi import (
217+
ShensiBridge,
218+
ShensiModel,
219+
ShensiModelProvider,
220+
)
216221
from megatron.bridge.models.stepfun import (
217222
Step35Bridge,
218223
Step37Bridge,
@@ -340,6 +345,10 @@
340345
"Qwen3OmniModelProvider",
341346
"SarvamMLABridge",
342347
"SarvamMoEBridge",
348+
# Shensi
349+
"ShensiBridge",
350+
"ShensiModel",
351+
"ShensiModelProvider",
343352
"Step35Bridge",
344353
"Step37Bridge",
345354
"Step37Model",
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Shensi
2+
3+
User-facing documentation lives under `docs/models/shensi/` (index page plus the variant page);
4+
this README covers the implementation.
5+
6+
## Layout
7+
8+
```
9+
shensi/
10+
├── configuration_shensi.py HF-side config: the per-layer plans, the RoPE split, validation
11+
├── modeling_shensi.py the components Shensi adds on top of Megatron-Core
12+
├── shensi_bridge.py HF <-> Megatron: config mapping and the parameter mappings
13+
├── shensi_hybrid.py HybridModel glue: pipeline layer pattern + hybrid stack spec
14+
├── shensi_builder.py model-config / model-builder path (HybridModelConfig + builder)
15+
├── shensi_provider.py provider: config fields -> ShensiModel, via build_shensi_model
16+
├── __init__.py
17+
└── README.md
18+
```
19+
20+
`configuration_shensi.py` holds both config surfaces: `ShensiConfig` mirrors the fields a
21+
checkpoint ships, `ShensiTransformerConfig` is the Megatron-Core transformer config that carries
22+
the Shensi-only fields next to the MLA ones.
23+
24+
## What Shensi adds
25+
26+
**Hybrid sparse attention** comes from Megatron-Core: the provider sets
27+
`experimental_attention_variant="dsv4_hybrid"` together with the per-layer `compress_ratios`, so
28+
CSA / HCA / sliding-window layers, their compressors and the Lightning-Indexer style router are the
29+
core implementations. This package adds what sits around them:
30+
31+
* **Attention residuals** (`ShensiAttentionResidual`) — layers are grouped into blocks by the
32+
hash-MoE prefix and `attn_res_block_size`. A block-writing layer publishes its residual context
33+
and the later layers of the block read it. The history is per stream and per block, matching the
34+
reference's `[s, b, hc, nb, H]` buffer; `ShensiAttnResState` stores one tensor per block
35+
(`state.blocks`) and re-assembles that layout only for the pipeline payload and tooling, so a
36+
block boundary costs no buffer copy. When a block spans a pipeline stage boundary, the state
37+
rides the stage payload itself (`pack_attn_res_payload` / `unpack_attn_res_payload`): the
38+
schedule ships whatever the model returns, so no side communicator and no extra process group are
39+
involved, and the state's gradients travel back through the same tensor. The payload then carries
40+
the state per token (`(1 + num_blocks) x hidden` on top of the activations), so the schedule has to exchange shapes per microbatch
41+
(`variable_seq_lengths: true`) for a crossing split to run, which the layout check enforces. For
42+
pipeline runs, align the stage split with the attention-residual block boundaries — then nothing
43+
has to cross; the model logs the crossing blocks whenever a split does not line up.
44+
* **MoE layout** (`ShensiMoELayer`, `ShensiHashMLP`) — the leading layers are dense SwiGLU MLPs
45+
gated by a token-embedding lookup rather than routed experts, and the routed experts of the
46+
remaining layers run through a low-rank bottleneck whose norm is applied before the up
47+
projection. The ERC auxiliary loss needs a global view of the expert weights, which
48+
`erc_gather_expert_weights` builds across the expert-parallel group.
49+
* **Selective fp32 keeping** — the attention-residual readers and the strict list
50+
of norms / sinks / position biases stay in fp32 while the rest of the model trains in bf16,
51+
matching the `_keep_in_fp32_modules_strict` list of the HF checkpoint.
52+
53+
## Field mapping
54+
55+
The provider derives the Megatron-Core fields from a `ShensiConfig` through
56+
`shensi_derived_field_values`: `sliding_window → csa_window_size`,
57+
`compress_rope_theta → csa_compress_rotary_base`, `index_* → dsa_indexer_*`,
58+
`moe_intermediate_size → moe_ffn_hidden_size`, `routed_expert_hidden_size → moe_latent_size`,
59+
`o_groups / o_lora_rank → output_projection_groups / output_projection_lora_rank`. The HF config's
60+
`num_key_value_heads = 1` is expressed through `kv_lora_rank`, so `num_query_groups` follows the
61+
attention head count. Fields without a Megatron-Core counterpart are listed in
62+
`SHENSI_ONLY_FIELDS`; `describe_mapping()` prints the result for a built config.
63+
64+
## Usage
65+
66+
```python
67+
from megatron.bridge import AutoBridge
68+
69+
bridge = AutoBridge.from_hf_pretrained("<hf checkpoint>")
70+
provider = bridge.to_megatron_provider(load_weights=False)
71+
model = provider.provide_distributed_model(wrap_with_ddp=False)
72+
bridge.load_hf_weights(model)
73+
```
74+
75+
## Inference
76+
77+
Megatron-Core's hybrid sparse attention has no inference path (`DSv4HybridAttention` rejects
78+
inference contexts), so `examples/conversion/hf_to_megatron_generate_text.py` can convert and load
79+
a Shensi checkpoint but cannot generate with it. Serving is done through vLLM, which ships the
80+
attention and compressor kernels for this family:
81+
82+
```sh
83+
vllm serve <exported hf directory> --served-model-name shensi --enforce-eager
84+
```
85+
86+
Exporting back to HuggingFace works (`bridge.save_hf_pretrained(model, path)`), which is what the
87+
functional round-trip test covers.
88+
89+
## Tests
90+
91+
```sh
92+
uv run python -m pytest -q tests/unit_tests/models/shensi --noconftest --import-mode=importlib
93+
uv run python -m pytest -q tests/functional_tests/test_groups/models/shensi
94+
```
95+
96+
The functional tests build a tiny Shensi checkpoint (`make_tiny_hf_model`) and cover the round trip
97+
(HF → Megatron → HF), the forward pass, right-padding behaviour and the provider/MTP configuration.
98+
The unit tests compare the attention-residual read bit-for-bit against the HF reference, pin the
99+
per-slot block layout to that reference (same draws, same rows, same gradients) and exercise the
100+
state carriage across pipeline stages (pack/unpack round trip, gradient path, per-stage conditions).
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
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+
# http://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+
"""Shensi: a hybrid sparse-attention MoE model with multi-stream hyper-connections."""
16+
17+
from megatron.bridge.models.shensi.configuration_shensi import ShensiConfig
18+
from megatron.bridge.models.shensi.modeling_shensi import ShensiModel
19+
from megatron.bridge.models.shensi.shensi_bridge import ShensiBridge
20+
from megatron.bridge.models.shensi.shensi_builder import ShensiModelBuilder, ShensiModelConfig
21+
from megatron.bridge.models.shensi.shensi_hybrid import (
22+
ShensiDecoderStack,
23+
get_shensi_hybrid_stack_spec,
24+
shensi_hybrid_layer_pattern,
25+
)
26+
from megatron.bridge.models.shensi.shensi_provider import ShensiModelProvider
27+
28+
29+
__all__ = [
30+
"ShensiBridge",
31+
"ShensiConfig",
32+
"ShensiDecoderStack",
33+
"ShensiModel",
34+
"ShensiModelBuilder",
35+
"ShensiModelConfig",
36+
"ShensiModelProvider",
37+
"get_shensi_hybrid_stack_spec",
38+
"shensi_hybrid_layer_pattern",
39+
]

0 commit comments

Comments
 (0)