> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/automodel/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/automodel/_mcp/server.

# nemo_automodel.components.models.hy_mt2.model

HyMT2ForCausalLM — Tencent Hy-MT2-30B-A3B (translation MoE) SFT support.

Architecture (from tencent/Hy-MT2-30B-A3B config.json):

* 48 transformer layers; layer 0 is dense, layers 1-47 are MoE
* MoE: 128 routed experts + 1 shared expert, top-8 activated
* Sigmoid routing with expert-bias correction, router\_scaling\_factor=2.826
* route\_norm = True (normalize top-k weights to sum to 1)
* GQA: 32 Q heads, 4 KV heads, head\_dim=128, hidden\_size=2048
* Per-head Q/K RMSNorm (qk\_norm=True) before RoPE
* 256K context, rope\_theta=11158840
* dense intermediate\_size=6912, moe\_intermediate\_size=expert\_hidden\_dim=768
* vocab\_size=120832
* enable\_lm\_head\_fp32 = True (HF reference upcasts lm\_head to fp32)

Notes vs. `components/models/hy_v3` (Hy3-preview 295B):

* Smaller everywhere (48L / 128 experts / 32+4 heads / hidden=2048).
* Adds an in-model `enable_lm_head_fp32` fallback (applies when the
  YAML's `lm_head_precision` is not set). The preferred path is to set
  `distributed.moe.lm_head_precision: float32` in the YAML, which the
  MoE parallelizer handles via `MixedPrecisionPolicy`.
* `score_func` is driven by `config.moe_router_use_sigmoid` instead
  of being hard-coded.

## Module Contents

### Classes

| Name                                                                                  | Description                                                                       |
| ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| [`Block`](#nemo_automodel-components-models-hy_mt2-model-Block)                       | Single Hy-MT2 transformer block: attention + (dense MLP \| MoE) + residual norms. |
| [`HyMT2ForCausalLM`](#nemo_automodel-components-models-hy_mt2-model-HyMT2ForCausalLM) | Hy-MT2-30B-A3B causal-LM wrapper.                                                 |
| [`HyMT2Model`](#nemo_automodel-components-models-hy_mt2-model-HyMT2Model)             | Hy-MT2 backbone: token embeddings + transformer blocks + final RMSNorm.           |

### Functions

| Name                                                                                        | Description                                                      |
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| [`_resolve_score_func`](#nemo_automodel-components-models-hy_mt2-model-_resolve_score_func) | Map `config.moe_router_use_sigmoid` to a gate `score_func` name. |

### Data

[`ModelClass`](#nemo_automodel-components-models-hy_mt2-model-ModelClass)

### API

```python
class nemo_automodel.components.models.hy_mt2.model.Block(
    layer_idx: int,
    config: typing.Any,
    moe_config: nemo_automodel.components.moe.config.MoEConfig,
    backend: nemo_automodel.components.models.common.BackendConfig
)
```

**Bases:** `Module`

Single Hy-MT2 transformer block: attention + (dense MLP | MoE) + residual norms.

```python
nemo_automodel.components.models.hy_mt2.model.Block._mlp(
    x: torch.Tensor,
    padding_mask: torch.Tensor | None
) -> torch.Tensor
```

```python
nemo_automodel.components.models.hy_mt2.model.Block.forward(
    x: torch.Tensor,
    freqs_cis: torch.Tensor,
    attention_mask: torch.Tensor | None = None,
    padding_mask: torch.Tensor | None = None,
    attn_kwargs: typing.Any = {}
) -> torch.Tensor
```

```python
nemo_automodel.components.models.hy_mt2.model.Block.init_weights(
    buffer_device: torch.device
)
```

```python
class nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM(
    config: typing.Any,
    moe_config: nemo_automodel.components.moe.config.MoEConfig | None = None,
    backend: nemo_automodel.components.models.common.BackendConfig | None = None,
    kwargs = {}
)
```

**Bases:** [HFCheckpointingMixin](/nemo-automodel/nemo_automodel/components/models/common/hf_checkpointing_mixin#nemo_automodel-components-models-common-hf_checkpointing_mixin-HFCheckpointingMixin), `Module`, [MoEFSDPSyncMixin](/nemo-automodel/nemo_automodel/components/moe/fsdp_mixin#nemo_automodel-components-moe-fsdp_mixin-MoEFSDPSyncMixin)

Hy-MT2-30B-A3B causal-LM wrapper.

Mixes in `MoEFSDPSyncMixin` so EP / FSDP2 expert-gradient sync works
out of the box (set `distributed.ep_size` in the YAML; must divide
`num_experts`=128). The `HFCheckpointingMixin` provides
`from_pretrained` / `save_pretrained` over the HF safetensors layout.

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM.forward(
    input_ids: torch.Tensor,
    position_ids: torch.Tensor | None = None,
    attention_mask: torch.Tensor | None = None,
    padding_mask: torch.Tensor | None = None,
    logits_to_keep: typing.Union[int, torch.Tensor] = 0,
    output_hidden_states: typing.Optional[bool] = None,
    attn_kwargs: typing.Any = {}
) -> transformers.modeling_outputs.CausalLMOutputWithPast
```

Forward pass returning :class:`CausalLMOutputWithPast`.

**Parameters:**

Token IDs. BSHD: `[B, S]`; THD: `[1, T]` (squeezed internally).

Optional position indices.

Optional 2D padding mask.

Optional padding mask used by the THD squeeze helper.

If 0 (default) compute logits for all positions; if > 0
only compute logits for the last `logits_to_keep` positions
(avoids materialising the full logit matrix during generation /
enables fused-linear cross-entropy in training).

Whether to return the final hidden states (the
input to `lm_head`) on the output. Defaults to the config flag.

Additional attention kwargs forwarded to the base model
(e.g. qkv\_format, cu\_seqlens, CP kwargs).

**Returns:** `CausalLMOutputWithPast`

class:`~transformers.modeling_outputs.CausalLMOutputWithPast` with

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM.from_config(
    config: typing.Any,
    moe_config: nemo_automodel.components.moe.config.MoEConfig | None = None,
    backend: nemo_automodel.components.models.common.BackendConfig | None = None,
    kwargs = {}
)
```

classmethod

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM.from_pretrained(
    pretrained_model_name_or_path: str,
    model_args = (),
    kwargs = {}
)
```

classmethod

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM.get_input_embeddings()
```

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM.get_output_embeddings()
```

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM.initialize_weights(
    buffer_device: torch.device | None = None,
    dtype: torch.dtype = torch.bfloat16
) -> None
```

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM.set_input_embeddings(
    value
)
```

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM.set_output_embeddings(
    new_embeddings
)
```

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2ForCausalLM.update_moe_gate_bias() -> None
```

```python
class nemo_automodel.components.models.hy_mt2.model.HyMT2Model(
    config: typing.Any,
    backend: nemo_automodel.components.models.common.BackendConfig,
    moe_config: nemo_automodel.components.moe.config.MoEConfig | None = None,
    moe_overrides: dict | None = None
)
```

**Bases:** `Module`

Hy-MT2 backbone: token embeddings + transformer blocks + final RMSNorm.

The MoE / dense split is governed by `config.first_k_dense_replace`
(layer 0 dense, the rest MoE for the published Hy-MT2-30B-A3B). The
MoE configuration is assembled from the HF config fields and forwarded
to every MoE-bearing `Block`.

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2Model.forward(
    input_ids: torch.Tensor,
    position_ids: torch.Tensor | None = None,
    attention_mask: torch.Tensor | None = None,
    padding_mask: torch.Tensor | None = None,
    attn_kwargs: typing.Any = {}
) -> torch.Tensor
```

```python
nemo_automodel.components.models.hy_mt2.model.HyMT2Model.init_weights(
    buffer_device: torch.device | None = None
) -> None
```

```python
nemo_automodel.components.models.hy_mt2.model._resolve_score_func(
    config: typing.Any
) -> str
```

Map `config.moe_router_use_sigmoid` to a gate `score_func` name.

Returns "sigmoid" when the flag is True (Hy-MT2 default) and "softmax"
otherwise. The bias-aware variants ("sigmoid\_with\_bias" /
"softmax\_with\_bias") are selected at the gate level by the presence of
`e_score_correction_bias` plus expert-group routing, which Hy-MT2 does
not use (n\_expert\_groups=0).

```python
nemo_automodel.components.models.hy_mt2.model.ModelClass = HyMT2ForCausalLM
```