Instructions to use nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16
- SGLang
How to use nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16 with Docker Model Runner:
docker model run hf.co/nvidia/Nemotron-Labs-TwoTower-30B-A3B-Base-BF16
Update model card (README) and tidy inference scaffolding
Browse files- README: rewrite as a Nemotron-TwoTower model card following the
Nemotron-3-Nano format (architecture diagram, generation modes,
training methodology, usage). Benchmark per-task numbers are
placeholders pending the released-checkpoint evaluation.
- inference.py: remove unused --trace-context-layers/--trace-denoiser-layers
flags (set but never read).
- modeling_nemotron_twotower.py: tidy the fp32-scan comment.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- README.md +127 -61
- inference.py +0 -4
- modeling_nemotron_twotower.py +2 -2
|
@@ -44,11 +44,15 @@ track_downloads: true
|
|
| 44 |
# Nemotron-TwoTower-30B-A3B-Base-BF16
|
| 45 |
|
| 46 |
<div align="center" style="line-height: 1;">
|
| 47 |
-
<
|
| 48 |
-
|
|
|
|
| 49 |
</a>
|
| 50 |
<a href="https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16" target="_blank" style="margin: 2px;">
|
| 51 |
-
<img alt="
|
|
|
|
|
|
|
|
|
|
| 52 |
</a>
|
| 53 |
</div>
|
| 54 |
|
|
@@ -66,44 +70,72 @@ track_downloads: true
|
|
| 66 |
|
| 67 |
**Data Freshness:** The pre-training data has a cutoff date of June 25, 2025.
|
| 68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
## Description
|
| 70 |
|
| 71 |
-
Nemotron-TwoTower
|
| 72 |
|
| 73 |
-
- **Context
|
| 74 |
-
- **Denoiser
|
| 75 |
|
| 76 |
-
Both towers
|
| 77 |
|
| 78 |
-
###
|
| 79 |
|
| 80 |
-
|
| 81 |
-
|------|-------------|-------------|-----|
|
| 82 |
-
| **Mask Diffusion** | Block-wise iterative denoising with confidence-based unmasking (flagship two-tower mode). | up to `block_size` | `generate_mask_diffusion()` |
|
| 83 |
-
| **Mock-AR** | Two-tower autoregressive. Context tower builds cache, denoiser predicts next token. | 1 | `generate_mock_ar()` |
|
| 84 |
-
| **AR** | Standard autoregressive via `generate()`. Uses context tower only (single GPU). | 1 | `generate()` |
|
| 85 |
|
| 86 |
-
##
|
| 87 |
|
| 88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
-
|
| 91 |
-
- **Denoiser Tower** generates a *block* of tokens at once. Within a block it is **bidirectional** (every position attends to the whole noisy block + the full causal context); across blocks it is causal via the context cache.
|
| 92 |
|
| 93 |
-
|
| 94 |
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
-
|
|
|
|
|
|
|
| 98 |
|
| 99 |
1. Initialize the block as all `[MASK]` tokens (`mask_token_id`).
|
| 100 |
-
2. For `steps_per_block` iterations:
|
| 101 |
-
- Compute the diffusion timestep `t` = current masked fraction of the block, and feed it to the **time-conditioned denoiser** (
|
| 102 |
-
- Run the denoiser over the whole block (bidirectional self-attention + cross-attention to the context cache; Mamba chunk-scan seeded from the context state).
|
| 103 |
-
- Constrain to `p(xβ | xβ)` (mask token forbidden; already-decoded positions fixed), then **commit** the
|
| 104 |
-
3.
|
| 105 |
|
| 106 |
-
|
| 107 |
|
| 108 |
## License/Terms of Use
|
| 109 |
|
|
@@ -111,27 +143,54 @@ GOVERNING TERMS: Use of this model is governed by the [NVIDIA Nemotron Open Mode
|
|
| 111 |
|
| 112 |
## Benchmark Evaluations
|
| 113 |
|
| 114 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
## Model Architecture
|
| 117 |
|
| 118 |
-
- **Architecture Type:** Two-Tower Mamba2-Transformer Hybrid Mixture of Experts (MoE)
|
| 119 |
- **Network Architecture:** Nemotron Hybrid MoE (Two-Tower)
|
| 120 |
-
- **
|
| 121 |
-
- **
|
| 122 |
-
- **Number of
|
| 123 |
-
- **
|
| 124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
## Training Methodology
|
| 127 |
|
| 128 |
-
|
| 129 |
|
| 130 |
-
|
|
|
|
| 131 |
|
| 132 |
-
|
| 133 |
|
| 134 |
-
|
|
|
|
| 135 |
|
| 136 |
## Input
|
| 137 |
|
|
@@ -147,14 +206,17 @@ Software used for training: [Megatron-LM](https://github.com/NVIDIA/Megatron-LM)
|
|
| 147 |
- **Output Parameters:** One-Dimensional (1D): Sequences
|
| 148 |
- **Maximum output size:** 128K tokens
|
| 149 |
|
|
|
|
|
|
|
| 150 |
## Software Integration
|
| 151 |
|
| 152 |
-
-
|
| 153 |
-
-
|
|
|
|
| 154 |
|
| 155 |
### Use it with Transformers
|
| 156 |
|
| 157 |
-
|
| 158 |
|
| 159 |
```python
|
| 160 |
import torch
|
|
@@ -168,20 +230,20 @@ model = AutoModelForCausalLM.from_pretrained(
|
|
| 168 |
trust_remote_code=True,
|
| 169 |
)
|
| 170 |
|
| 171 |
-
#
|
| 172 |
model.place_towers_on_devices("cuda:0", "cuda:1")
|
| 173 |
model.eval()
|
| 174 |
|
| 175 |
prompt = "France is a country "
|
| 176 |
inputs = tokenizer(prompt, return_tensors="pt").to("cuda:0")
|
| 177 |
|
| 178 |
-
#
|
| 179 |
outputs = model.generate_mask_diffusion(
|
| 180 |
inputs["input_ids"],
|
| 181 |
max_new_tokens=128,
|
| 182 |
block_size=16, # tokens generated per block
|
| 183 |
steps_per_block=16, # denoising iterations per block
|
| 184 |
-
mask_token_id=3, #
|
| 185 |
temperature=0.1,
|
| 186 |
confidence_threshold=0.8, # commit positions above this confidence each step
|
| 187 |
eos_token_id=tokenizer.eos_token_id,
|
|
@@ -189,7 +251,7 @@ outputs = model.generate_mask_diffusion(
|
|
| 189 |
print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
|
| 190 |
```
|
| 191 |
|
| 192 |
-
**Mock-AR** (two-tower, one token per step):
|
| 193 |
|
| 194 |
```python
|
| 195 |
outputs = model.generate_mock_ar(
|
|
@@ -199,48 +261,52 @@ outputs = model.generate_mock_ar(
|
|
| 199 |
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
|
| 200 |
```
|
| 201 |
|
| 202 |
-
**AR-only** (single GPU, context tower only β load with `.cuda()` instead of `place_towers_on_devices`):
|
| 203 |
|
| 204 |
```python
|
| 205 |
-
outputs = model.
|
|
|
|
|
|
|
|
|
|
| 206 |
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
|
| 207 |
```
|
| 208 |
|
| 209 |
## Model Version(s)
|
| 210 |
|
| 211 |
-
- v1.1 β Block-wise **mask-diffusion** generation enabled (time-conditioned denoiser, bidirectional in-block attention, chunk-scan Mamba); AR and mock-AR also supported.
|
| 212 |
-
- v1.0 β Two-tower AR (mock-AR) checkpoint
|
| 213 |
|
| 214 |
# Training, Testing, and Evaluation Datasets
|
| 215 |
|
| 216 |
-
|
| 217 |
|
| 218 |
-
**Data Modality:** Text
|
| 219 |
-
**
|
| 220 |
-
**
|
| 221 |
-
**Data Collection Method by dataset:** Hybrid: Automated, Human, Synthetic
|
| 222 |
|
| 223 |
## Inference
|
| 224 |
|
| 225 |
-
-
|
| 226 |
-
- Test Hardware:
|
| 227 |
|
| 228 |
## Ethical Considerations
|
| 229 |
|
| 230 |
-
NVIDIA believes Trustworthy AI is a shared responsibility and we have established policies and practices to enable development for a wide array of AI applications. When downloaded or used in accordance with our terms of service, developers should work with their internal model team to ensure this model meets requirements for the relevant industry and use case and addresses unforeseen product misuse.
|
| 231 |
|
| 232 |
-
For more detailed information on ethical considerations for this model, please see the Model Card++ [Bias](bias.md), [Explainability](explainability.md),
|
| 233 |
|
| 234 |
Please report security vulnerabilities or NVIDIA AI Concerns [here](https://www.nvidia.com/en-us/support/submit-security-vulnerability/).
|
| 235 |
|
| 236 |
## Citation
|
| 237 |
|
|
|
|
|
|
|
| 238 |
```
|
| 239 |
-
@misc{
|
| 240 |
-
title = {{Nemotron
|
| 241 |
author = {{NVIDIA}},
|
| 242 |
-
year = {
|
| 243 |
-
url = {https://
|
| 244 |
note = {Technical report}
|
| 245 |
}
|
| 246 |
```
|
|
|
|
| 44 |
# Nemotron-TwoTower-30B-A3B-Base-BF16
|
| 45 |
|
| 46 |
<div align="center" style="line-height: 1;">
|
| 47 |
+
<!-- TODO: update paper link/badge once the Nemotron-TwoTower technical report is public -->
|
| 48 |
+
<a href="https://huggingface.co/collections/nvidia/nemotron-twotower" target="_blank" style="margin: 2px;">
|
| 49 |
+
<img alt="Paper" src="https://img.shields.io/badge/πPaper-Coming Soon-536af5?color=76B900&logoColor=white" style="display: inline-block; vertical-align: middle;"/>
|
| 50 |
</a>
|
| 51 |
<a href="https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16" target="_blank" style="margin: 2px;">
|
| 52 |
+
<img alt="Backbone" src="https://img.shields.io/badge/ποΈBackbone-Nemotron_3_Nano_30B--A3B-76B900?logoColor=white" style="display: inline-block; vertical-align: middle;"/>
|
| 53 |
+
</a>
|
| 54 |
+
<a href="https://huggingface.co/collections/nvidia/nemotron-twotower" target="_blank" style="margin: 2px;">
|
| 55 |
+
<img alt="Collection" src="https://img.shields.io/badge/π€Collection-Nemotron--TwoTower-76B900?logoColor=white" style="display: inline-block; vertical-align: middle;"/>
|
| 56 |
</a>
|
| 57 |
</div>
|
| 58 |
|
|
|
|
| 70 |
|
| 71 |
**Data Freshness:** The pre-training data has a cutoff date of June 25, 2025.
|
| 72 |
|
| 73 |
+
Nemotron-TwoTower-30B-A3B-Base-BF16 is a **block-wise autoregressive diffusion** language model built on the [NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16) backbone. It generates text by iteratively denoising blocks of tokens in parallel rather than one token at a time.
|
| 74 |
+
|
| 75 |
+
This model is ready for commercial use.
|
| 76 |
+
|
| 77 |
## Description
|
| 78 |
|
| 79 |
+
Nemotron-TwoTower uses two towers:
|
| 80 |
|
| 81 |
+
- **Context tower (AR / context)** β a frozen causal, autoregressive tower that processes the clean prompt and all previously committed tokens once, producing the per-layer KV cache (attention) and final Mamba-2 states.
|
| 82 |
+
- **Denoiser tower (diffusion / denoiser)** β a trainable tower that generates a block of tokens at a time via mask diffusion, refining noisy blocks with bidirectional in-block attention, layer-aligned cross-attention to the context tower, and context-seeded Mamba states.
|
| 83 |
|
| 84 |
+
Both towers are copies of the same 52-layer hybrid Mamba-2 / attention / MoE backbone; only the diffusion/denoiser tower is trained, and the AR/context tower stays frozen. The denoiser is trained on **~2.1T tokens** (the backbone was pretrained on 25T tokens). At the default operating point, Nemotron-TwoTower retains **98.7%** of the autoregressive baseline's aggregate benchmark quality and provides **2.42Γ** the AR baseline's wall-clock generation throughput.
|
| 85 |
|
| 86 |
+
### What is Nemotron?
|
| 87 |
|
| 88 |
+
NVIDIA Nemotronβ’ is a family of open models with open weights, training data, and recipes, delivering leading efficiency and accuracy for building specialized AI agents.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
+
## Architecture
|
| 91 |
|
| 92 |
+
```
|
| 93 |
+
AR / Context Tower Diffusion / Denoiser Tower
|
| 94 |
+
|
| 95 |
+
clean token blocks noisy token blocks
|
| 96 |
+
β β
|
| 97 |
+
βββββββββΌββββββββ βββββββββΌββββββββ
|
| 98 |
+
β Embedding β β Embedding β
|
| 99 |
+
βββββββββ¬ββββββββ βββββββββ¬ββββββββ
|
| 100 |
+
β β
|
| 101 |
+
βββββββββΌββββββββ KV + Mamba βββββββββΌββββββββ
|
| 102 |
+
β Mamba-2/Attn ββββββstatesββββββΆβ Mamba-2/Attn β
|
| 103 |
+
βββββββββ¬ββββββββ βββββββββ¬ββββββββ
|
| 104 |
+
β β
|
| 105 |
+
βββββββββΌββββββββ βββββββββΌββββββββ
|
| 106 |
+
β MoE β β MoE β
|
| 107 |
+
βββββββββ¬ββββββββ βββββββββ¬ββββββββ
|
| 108 |
+
β β
|
| 109 |
+
βββββββββΌββββββββ βββββββββΌββββββββ
|
| 110 |
+
β Output Head β β Output Head β
|
| 111 |
+
βββββββββ¬ββββββββ βββββββββ¬ββββββββ
|
| 112 |
+
β β
|
| 113 |
+
logits / loss logits / loss
|
| 114 |
+
(optional)
|
| 115 |
+
```
|
| 116 |
|
| 117 |
+
The AR/context tower (left) runs causally over clean token blocks and exposes, at every layer, the attention KV cache and the Mamba-2 conv/SSM boundary states. The diffusion/denoiser tower (right) consumes a noisy block; at each layer it cross-attends to the corresponding layer of the context tower (KV) and seeds its Mamba-2 layer from the corresponding context Mamba state.
|
|
|
|
| 118 |
|
| 119 |
+
### Two-Tower Generation Modes
|
| 120 |
|
| 121 |
+
| Mode | Description | Tokens / step | API |
|
| 122 |
+
|------|-------------|---------------|-----|
|
| 123 |
+
| **Mask Diffusion** | Diffusion/denoiser mode: block-wise iterative denoising with confidence-based unmasking. | up to `block_size` | `generate_mask_diffusion()` |
|
| 124 |
+
| **Mock-AR** | Two-tower **autoregressive**: AR/context tower builds the cache, diffusion/denoiser predicts the next token. | 1 | `generate_mock_ar()` |
|
| 125 |
+
| **AR** | Standard **autoregressive** generation using the AR/context tower only (single GPU). | 1 | `generate_ar()` |
|
| 126 |
|
| 127 |
+
### How mask diffusion works
|
| 128 |
+
|
| 129 |
+
Generation is **block-wise autoregressive**: the AR/context tower encodes the prompt once, then the diffusion/denoiser fills one block of `block_size` positions at a time. For each new block:
|
| 130 |
|
| 131 |
1. Initialize the block as all `[MASK]` tokens (`mask_token_id`).
|
| 132 |
+
2. For `steps_per_block` denoising iterations:
|
| 133 |
+
- Compute the diffusion timestep `t` = current masked fraction of the block, and feed it to the **time-conditioned denoiser** (adaLN-single modulation β a global MLP maps `t` to per-layer scale/shift/gate, PixArt-Ξ± style).
|
| 134 |
+
- Run the diffusion/denoiser over the whole block (bidirectional in-block self-attention + layer-aligned causal cross-attention to the AR/context cache; Mamba-2 chunk-scan seeded from the context state).
|
| 135 |
+
- Constrain to `p(xβ | xβ)` (mask token forbidden; already-decoded positions fixed), then **commit** the high-confidence positions (all above `confidence_threshold`, with a floor that guarantees completion within `steps_per_block`) and re-mask the rest (**confidence unmasking**).
|
| 136 |
+
3. Commit the resolved block, advance the AR/context tower over it to update the KV + Mamba caches, and continue with the next block.
|
| 137 |
|
| 138 |
+
Each step predicts all masked positions in parallel and commits the confident subset, so multiple tokens may be committed per step.
|
| 139 |
|
| 140 |
## License/Terms of Use
|
| 141 |
|
|
|
|
| 143 |
|
| 144 |
## Benchmark Evaluations
|
| 145 |
|
| 146 |
+
Default operating point: **confidence unmasking**, threshold `Ξ³ = 0.8`, block size `S = 16`, BF16 on 2ΓH100 GPUs. At this point Nemotron-TwoTower retains **98.7%** of the AR baseline's aggregate benchmark quality and reaches **2.42Γ** the AR baseline's wall-clock generation throughput. Lowering the confidence threshold increases the tokens committed per step and the throughput, with reduced quality.
|
| 147 |
+
|
| 148 |
+
Per-task results below compare the autoregressive backbone (AR/context baseline) against Nemotron-TwoTower (diffusion/denoiser decoding). <!-- TODO: fill in final released-checkpoint numbers -->
|
| 149 |
+
|
| 150 |
+
| Task | NVIDIA-Nemotron-3-Nano-30B-A3B-Base (AR baseline) | Nemotron-TwoTower-30B-A3B-Base (diffusion) |
|
| 151 |
+
| :---- | :---- | :---- |
|
| 152 |
+
| **General Knowledge** | | |
|
| 153 |
+
| MMLU (5-shot, acc) | 78.56 | _To be filled_ |
|
| 154 |
+
| MMLU-Pro (5-shot, CoT EM) | 65.05 | _To be filled_ |
|
| 155 |
+
| **Code** | | |
|
| 156 |
+
| HumanEval (0-shot) | 78.05 | _To be filled_ |
|
| 157 |
+
| MBPP-Sanitized (3-shot) | 75.49 | _To be filled_ |
|
| 158 |
+
| **Math** | | |
|
| 159 |
+
| GSM8K (8-shot, acc) | 92.34 | _To be filled_ |
|
| 160 |
+
| MATH-500 (4-shot) | 78.63 | _To be filled_ |
|
| 161 |
+
| **Multilingual** | | |
|
| 162 |
+
| MGSM (8-shot, avg acc) | 83.00 | _To be filled_ |
|
| 163 |
+
| **Aggregate** | | |
|
| 164 |
+
| Quality retained (% of AR baseline) | 100% | **98.7%** |
|
| 165 |
+
| Generation throughput (Γ AR baseline) | 1.0Γ | **2.42Γ** |
|
| 166 |
+
|
| 167 |
+
<!-- TODO: confirm AR-baseline column values and the evaluation harness/configs for the diffusion column before release. -->
|
| 168 |
|
| 169 |
## Model Architecture
|
| 170 |
|
| 171 |
+
- **Architecture Type:** Two-Tower Block-Diffusion over a Mamba2-Transformer Hybrid Mixture of Experts (MoE) backbone
|
| 172 |
- **Network Architecture:** Nemotron Hybrid MoE (Two-Tower)
|
| 173 |
+
- **Backbone:** [NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16)
|
| 174 |
+
- **Layers per tower:** 52 β **23 Mamba-2**, **6 self-attention**, **23 MoE**
|
| 175 |
+
- **Number of model parameters:** ~60B total (30B AR/context tower + 30B diffusion/denoiser tower); the released checkpoint ships both towers
|
| 176 |
+
- **Active parameters per token:** ~3B per tower (β6B total when both towers run during two-tower diffusion generation)
|
| 177 |
+
- **Denoiser-only modifications vs. the backbone:**
|
| 178 |
+
- **Bidirectional in-block attention** β noisy tokens attend bidirectionally within the current block, causally to past clean blocks (no added parameters).
|
| 179 |
+
- **Layer-aligned cross-attention** β denoiser layer *i* attends to context-tower layer *i*'s KV.
|
| 180 |
+
- **Context-seeded Mamba-2** β denoiser Mamba layers seed their initial conv/SSM state from the corresponding context Mamba state (causal; the bidirectional-Mamba variant is not used).
|
| 181 |
+
- **adaLN-single time conditioning** β the diffusion timestep `t` modulates every denoiser layer (β1.5M added parameters; replicated per tensor-parallel rank).
|
| 182 |
|
| 183 |
## Training Methodology
|
| 184 |
|
| 185 |
+
Nemotron-TwoTower is produced by adapting a pretrained autoregressive backbone into a block-wise diffusion generator β **only the diffusion/denoiser tower is trained; the AR/context tower is frozen.**
|
| 186 |
|
| 187 |
+
- **Stage 1 β Backbone pre-training (AR).** The single-tower [NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16) is pre-trained from scratch with next-token prediction (~25T tokens).
|
| 188 |
+
- **Stage 2 β Two-tower denoiser training (diffusion).** Both towers are initialized from the same backbone checkpoint. The AR/context tower is frozen; the diffusion/denoiser tower is trained under a **masked-diffusion** objective (mean negative log-likelihood over masked positions), conditioned on the context tower's per-layer KV cache and Mamba boundary states. Training follows the backbone's two-stage data curriculum (broad phase-1 blend β higher-quality phase-2 blend), over **~2.1T tokens** total.
|
| 189 |
|
| 190 |
+
The released checkpoint is trained in three stages: phase-1 adaptation at block size `S=32`, phase-2 continuation at `S=32`, and a final phase-2 continuation at `S=16` (the default sampling block size).
|
| 191 |
|
| 192 |
+
- **Precision:** BF16. **Optimizer:** AdamW with a Warmup-Stable-Decay schedule (peak LR `1e-4`, final LR `1e-6`), reset at phase boundaries.
|
| 193 |
+
- **Software used for training:** [Megatron-LM](https://github.com/NVIDIA/Megatron-LM)
|
| 194 |
|
| 195 |
## Input
|
| 196 |
|
|
|
|
| 206 |
- **Output Parameters:** One-Dimensional (1D): Sequences
|
| 207 |
- **Maximum output size:** 128K tokens
|
| 208 |
|
| 209 |
+
Our AI models are designed and optimized to run on NVIDIA GPU-accelerated systems. By leveraging NVIDIA's hardware (e.g. GPU cores) and software frameworks (e.g., CUDA libraries), the model achieves faster training and inference times compared to CPU-only solutions.
|
| 210 |
+
|
| 211 |
## Software Integration
|
| 212 |
|
| 213 |
+
- **Runtime Engine(s):** HuggingFace Transformers (with `trust_remote_code=True`)
|
| 214 |
+
- **Supported Hardware Microarchitecture Compatibility:** NVIDIA H100-80GB, NVIDIA A100 (full two-tower diffusion inference uses **2 GPUs**, ~59GB per GPU for BF16 weights)
|
| 215 |
+
- **Operating System(s):** Linux
|
| 216 |
|
| 217 |
### Use it with Transformers
|
| 218 |
|
| 219 |
+
Full **two-tower diffusion** inference places the AR/context tower and the diffusion/denoiser tower on separate GPUs.
|
| 220 |
|
| 221 |
```python
|
| 222 |
import torch
|
|
|
|
| 230 |
trust_remote_code=True,
|
| 231 |
)
|
| 232 |
|
| 233 |
+
# AR/context tower -> GPU 0, diffusion/denoiser tower -> GPU 1
|
| 234 |
model.place_towers_on_devices("cuda:0", "cuda:1")
|
| 235 |
model.eval()
|
| 236 |
|
| 237 |
prompt = "France is a country "
|
| 238 |
inputs = tokenizer(prompt, return_tensors="pt").to("cuda:0")
|
| 239 |
|
| 240 |
+
# Mask-diffusion generation (two-tower)
|
| 241 |
outputs = model.generate_mask_diffusion(
|
| 242 |
inputs["input_ids"],
|
| 243 |
max_new_tokens=128,
|
| 244 |
block_size=16, # tokens generated per block
|
| 245 |
steps_per_block=16, # denoising iterations per block
|
| 246 |
+
mask_token_id=3, # [MASK]
|
| 247 |
temperature=0.1,
|
| 248 |
confidence_threshold=0.8, # commit positions above this confidence each step
|
| 249 |
eos_token_id=tokenizer.eos_token_id,
|
|
|
|
| 251 |
print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
|
| 252 |
```
|
| 253 |
|
| 254 |
+
**Mock-AR** (two-tower autoregressive, one token per step):
|
| 255 |
|
| 256 |
```python
|
| 257 |
outputs = model.generate_mock_ar(
|
|
|
|
| 261 |
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
|
| 262 |
```
|
| 263 |
|
| 264 |
+
**AR-only** (single GPU, AR/context tower only β load with `.cuda()` instead of `place_towers_on_devices`):
|
| 265 |
|
| 266 |
```python
|
| 267 |
+
outputs = model.generate_ar(
|
| 268 |
+
inputs["input_ids"], max_new_tokens=128, temperature=0.0,
|
| 269 |
+
eos_token_id=tokenizer.eos_token_id,
|
| 270 |
+
)
|
| 271 |
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
|
| 272 |
```
|
| 273 |
|
| 274 |
## Model Version(s)
|
| 275 |
|
| 276 |
+
- **v1.1** β Block-wise **mask-diffusion** generation enabled (time-conditioned diffusion/denoiser, bidirectional in-block attention, context-seeded chunk-scan Mamba-2); AR and mock-AR also supported.
|
| 277 |
+
- **v1.0** β Two-tower AR (mock-AR) checkpoint.
|
| 278 |
|
| 279 |
# Training, Testing, and Evaluation Datasets
|
| 280 |
|
| 281 |
+
The diffusion/denoiser tower is trained on the same data sources as the [NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16) backbone (a ~2.1T-token subset of the backbone's two-phase blend). See the [base model card](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-Base-BF16#training-testing-and-evaluation-datasets) for the full dataset listing.
|
| 282 |
|
| 283 |
+
- **Data Modality:** Text
|
| 284 |
+
- **Data Collection Method by dataset:** Hybrid: Automated, Human, Synthetic
|
| 285 |
+
- **Labeling Method by dataset:** Not applicable (self-supervised mask-diffusion objective)
|
|
|
|
| 286 |
|
| 287 |
## Inference
|
| 288 |
|
| 289 |
+
- **Engine(s):** HuggingFace Transformers (with `trust_remote_code=True`)
|
| 290 |
+
- **Test Hardware:** 2Γ NVIDIA A100 80GB or 2Γ NVIDIA H100 80GB (two-tower diffusion); 1Γ 80GB GPU sufficient for AR-only mode
|
| 291 |
|
| 292 |
## Ethical Considerations
|
| 293 |
|
| 294 |
+
NVIDIA believes Trustworthy AI is a shared responsibility and we have established policies and practices to enable development for a wide array of AI applications. When downloaded or used in accordance with our [Trustworthy AI terms of service](https://www.nvidia.com/en-us/agreements/trustworthy-ai/terms/), developers should work with their internal model team to ensure this model meets requirements for the relevant industry and use case and addresses unforeseen product misuse.
|
| 295 |
|
| 296 |
+
For more detailed information on ethical considerations for this model, please see the Model Card++ [Bias](bias.md), [Explainability](explainability.md), and [Privacy](privacy.md) Subcards.
|
| 297 |
|
| 298 |
Please report security vulnerabilities or NVIDIA AI Concerns [here](https://www.nvidia.com/en-us/support/submit-security-vulnerability/).
|
| 299 |
|
| 300 |
## Citation
|
| 301 |
|
| 302 |
+
<!-- TODO: authors omitted for now; fill in arXiv id / venue / year when the report is public. -->
|
| 303 |
+
|
| 304 |
```
|
| 305 |
+
@misc{nvidia_nemotron_twotower_2026,
|
| 306 |
+
title = {{Nemotron-TwoTower}: Diffusion Language Modeling with Pretrained Autoregressive Context},
|
| 307 |
author = {{NVIDIA}},
|
| 308 |
+
year = {2026},
|
| 309 |
+
url = {https://huggingface.co/collections/nvidia/nemotron-twotower},
|
| 310 |
note = {Technical report}
|
| 311 |
}
|
| 312 |
```
|
|
@@ -43,8 +43,6 @@ parser.add_argument("--confidence-threshold", type=float, default=0.9)
|
|
| 43 |
parser.add_argument("--deterministic", action="store_true")
|
| 44 |
parser.add_argument("--seed", type=int, default=42)
|
| 45 |
parser.add_argument("--print-diffusion-steps", action="store_true")
|
| 46 |
-
parser.add_argument("--trace-context-layers", action="store_true")
|
| 47 |
-
parser.add_argument("--trace-denoiser-layers", action="store_true")
|
| 48 |
args = parser.parse_args()
|
| 49 |
prompt = args.prompt if args.prompt is not None else (args.prompt_arg or "France is a country ")
|
| 50 |
|
|
@@ -75,8 +73,6 @@ else:
|
|
| 75 |
model.cuda()
|
| 76 |
|
| 77 |
model.eval()
|
| 78 |
-
model.trace_context_layers = args.trace_context_layers
|
| 79 |
-
model.trace_denoiser_layers = args.trace_denoiser_layers
|
| 80 |
# Build the request list. A --prompt-file (jsonl, one {"text": ...} per line,
|
| 81 |
# same format mcore consumes) runs as multiple Requests i/N; otherwise the
|
| 82 |
# single positional/--prompt is the lone request.
|
|
|
|
| 43 |
parser.add_argument("--deterministic", action="store_true")
|
| 44 |
parser.add_argument("--seed", type=int, default=42)
|
| 45 |
parser.add_argument("--print-diffusion-steps", action="store_true")
|
|
|
|
|
|
|
| 46 |
args = parser.parse_args()
|
| 47 |
prompt = args.prompt if args.prompt is not None else (args.prompt_arg or "France is a country ")
|
| 48 |
|
|
|
|
| 73 |
model.cuda()
|
| 74 |
|
| 75 |
model.eval()
|
|
|
|
|
|
|
| 76 |
# Build the request list. A --prompt-file (jsonl, one {"text": ...} per line,
|
| 77 |
# same format mcore consumes) runs as multiple Requests i/N; otherwise the
|
| 78 |
# single positional/--prompt is the lone request.
|
|
@@ -557,8 +557,8 @@ class NemotronHTwoTowerForCausalLM(NemotronHPreTrainedModel, GenerationMixin):
|
|
| 557 |
# Run the SSM scan in fp32. With a long context the seeded SSM state gets
|
| 558 |
# large (O(1e3)+); the bf16 chunk-scan then overflows to NaN, and because
|
| 559 |
# the Triton kernel's reductions are not bit-deterministic this strikes
|
| 560 |
-
# nondeterministically (a NaN on a block's first/all-masked step
|
| 561 |
-
#
|
| 562 |
# The scan spans only one block (<=16 tokens) so fp32 is essentially free,
|
| 563 |
# and it is strictly more accurate. Cast back before the gated norm.
|
| 564 |
_y_dtype = z.dtype
|
|
|
|
| 557 |
# Run the SSM scan in fp32. With a long context the seeded SSM state gets
|
| 558 |
# large (O(1e3)+); the bf16 chunk-scan then overflows to NaN, and because
|
| 559 |
# the Triton kernel's reductions are not bit-deterministic this strikes
|
| 560 |
+
# nondeterministically (a NaN on a block's first/all-masked step makes
|
| 561 |
+
# every confidence NaN and force-commits an arbitrary token).
|
| 562 |
# The scan spans only one block (<=16 tokens) so fp32 is essentially free,
|
| 563 |
# and it is strictly more accurate. Cast back before the gated norm.
|
| 564 |
_y_dtype = z.dtype
|