Skip to content

Commit d2e6db4

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 - modeling_shensi: mHC hyper-connections, attention residuals with pipeline-stage state transfer (the block history is kept as one tensor per block -- the same per-stream values as the HF reference's stacked `[s, b, hc, nb, H]` buffer, without its 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 Signed-off-by: 313892219+zongzhilou <313892219+zongzhilou@users.noreply.github.com>
1 parent 79edbdf commit d2e6db4

28 files changed

Lines changed: 6683 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, mHC streams, 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+
- Residual streams are multi-stream hyper-connections (mHC); attention-residual blocks read and
22+
write them, and block 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, mHC streams, 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+
- Residual streams are multi-stream hyper-connections (mHC); attention-residual blocks read and
22+
write them, and block 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: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
* **mHC hyper-connections** (`ShensiHyperConnection`) — the residual stream is a pool of
32+
`hc_mult` streams. A sublayer collapses the pool into its input and writes its output back into
33+
a fixed plus a top-k routed subset of streams; the MLP side augments the write with causal depth
34+
convolutions and their Gram-Schmidt orthogonalizations. `ShensiHyperHead` collapses the pool at
35+
the end of the stack.
36+
* **Attention residuals** (`ShensiAttentionResidual`) — layers are grouped into blocks by the
37+
hash-MoE prefix and `attn_res_block_size`. A block-writing layer publishes its stream context and
38+
the later layers of the block read it. The history is per stream and per block, matching the
39+
reference's `[s, b, hc, nb, H]` buffer; `ShensiAttnResState` stores one tensor per block
40+
(`state.blocks`) and re-assembles that layout only for the pipeline payload and tooling, so a
41+
block boundary costs no buffer copy. The state also travels across pipeline stages on a
42+
dedicated communicator (the pipeline group's ranks, with its own tag space so the handoff's
43+
point-to-point ops cannot interleave with the schedule's), so a block may span stage boundaries.
44+
The state is per token and per stream (`hc_mult x num_blocks x hidden`), orders of magnitude
45+
larger than one activation, so for pipeline runs align the stage split with the
46+
attention-residual block boundaries — then nothing has to cross. The model logs the crossing
47+
blocks and that cost whenever a split does not line up.
48+
* **MoE layout** (`ShensiMoELayer`, `ShensiHashMLP`) — the leading layers are dense SwiGLU MLPs
49+
gated by a token-embedding lookup rather than routed experts, and the routed experts of the
50+
remaining layers run through a low-rank bottleneck whose norm is applied before the up
51+
projection. The ERC auxiliary loss needs a global view of the expert weights, which
52+
`erc_gather_expert_weights` builds across the expert-parallel group.
53+
* **Selective fp32 keeping** — the mHC mixers, the attention-residual readers and the strict list
54+
of norms / sinks / position biases stay in fp32 while the rest of the model trains in bf16,
55+
matching the `_keep_in_fp32_modules_strict` list of the HF checkpoint.
56+
57+
## Field mapping
58+
59+
The provider derives the Megatron-Core fields from a `ShensiConfig` through
60+
`shensi_derived_field_values`: `hc_mult → num_residual_streams`, `sliding_window → csa_window_size`,
61+
`compress_rope_theta → csa_compress_rotary_base`, `index_* → dsa_indexer_*`,
62+
`moe_intermediate_size → moe_ffn_hidden_size`, `routed_expert_hidden_size → moe_latent_size`,
63+
`o_groups / o_lora_rank → output_projection_groups / output_projection_lora_rank`. The HF config's
64+
`num_key_value_heads = 1` is expressed through `kv_lora_rank`, so `num_query_groups` follows the
65+
attention head count. Fields without a Megatron-Core counterpart are listed in
66+
`SHENSI_ONLY_FIELDS`; `describe_mapping()` prints the result for a built config.
67+
68+
## Usage
69+
70+
```python
71+
from megatron.bridge import AutoBridge
72+
73+
bridge = AutoBridge.from_hf_pretrained("<hf checkpoint>")
74+
provider = bridge.to_megatron_provider(load_weights=False)
75+
model = provider.provide_distributed_model(wrap_with_ddp=False)
76+
bridge.load_hf_weights(model)
77+
```
78+
79+
## Inference
80+
81+
Megatron-Core's hybrid sparse attention has no inference path (`DSv4HybridAttention` rejects
82+
inference contexts), so `examples/conversion/hf_to_megatron_generate_text.py` can convert and load
83+
a Shensi checkpoint but cannot generate with it. Serving is done through vLLM, which ships the
84+
attention and compressor kernels for this family:
85+
86+
```sh
87+
vllm serve <exported hf directory> --served-model-name shensi --enforce-eager
88+
```
89+
90+
Exporting back to HuggingFace works (`bridge.save_hf_pretrained(model, path)`), which is what the
91+
functional round-trip test covers.
92+
93+
## Tests
94+
95+
```sh
96+
uv run python -m pytest -q tests/unit_tests/models/shensi --noconftest --import-mode=importlib
97+
uv run python -m pytest -q tests/functional_tests/test_groups/models/shensi
98+
```
99+
100+
The functional tests build a tiny Shensi checkpoint (`make_tiny_hf_model`) and cover the round trip
101+
(HF → Megatron → HF), the forward pass, right-padding behaviour and the provider/MTP configuration.
102+
The unit tests compare the attention-residual read bit-for-bit against the HF reference, pin the
103+
per-slot block layout to that reference (same draws, same rows, same gradients) and exercise the
104+
pipeline-stage handoff across two processes.
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)