Skip to content

Commit 3255e67

Browse files
authored
docs(misc): list EXAONE, Kimi K3, MiniMax-M3 and Nemotron-3 Ultra as supported (#5743)
Signed-off-by: Pruthviraj Prakash <pruprakash@nvidia.com>
1 parent 8a6a128 commit 3255e67

2 files changed

Lines changed: 82 additions & 3 deletions

File tree

‎README.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,18 +234,19 @@ Megatron Bridge provides out-of-the-box bridges and training recipes for a wide
234234
| [**DeepSeek**](docs/models/deepseek/index.md) | DeepSeek V2 / V2 Lite (deprecated), DeepSeek V3, DeepSeek V4 / V4 Flash |
235235
| [**Diffusion**](https://github.com/NVIDIA-NeMo/Megatron-Bridge/tree/main/src/megatron/bridge/diffusion/models) | FLUX, LLaDA 1.5, Nemotron-Labs Diffusion, WAN |
236236
| **Ernie** | [Ernie 4.5 MoE](https://github.com/NVIDIA-NeMo/Megatron-Bridge/tree/main/src/megatron/bridge/models/ernie), [Ernie 4.5 VL MoE](https://github.com/NVIDIA-NeMo/Megatron-Bridge/tree/main/src/megatron/bridge/models/ernie_vl) |
237+
| [**EXAONE**](docs/models/exaone/exaone.md) | EXAONE 4.0, EXAONE 4.5 VL, K-EXAONE MoE |
237238
| [**Falcon**](docs/models/falcon/index.md) | Falcon H1 |
238239
| [**Gemma**](docs/models/gemma/index.md) | Gemma / Gemma 2 (deprecated), Gemma 3, Gemma 3-VL, Gemma 4 (26B-A4B MoE / 31B dense), Gemma 4-VL (26B-A4B MoE) |
239240
| [**GLM**](docs/models/glm/index.md) | GLM-4.5 / GLM-4.7 / GLM-4.7-Flash, GLM-4.5V, GLM-5 / GLM-5.1 / GLM-5.2 / [GLM-5.3](docs/models/glm/glm5-2.md) |
240241
| [**GPT-OSS**](docs/models/gpt_oss/index.md) | GPT-oss |
241242
| [**HY V3**](https://huggingface.co/tencent/Hy3-preview-Base) | Hy3 preview-Base (HF → Megatron checkpoint conversion) |
242-
| [**Kimi**](docs/models/kimi/index.md) | Kimi K2, Kimi-K2.5-VL |
243+
| [**Kimi**](docs/models/kimi/index.md) | Kimi K2, Kimi-K2.5-VL, Kimi K3 |
243244
| [**Llama**](docs/models/llama/index.md) | Llama 2 (deprecated), Llama 3 / 3.1 / 3.2 / 3.3 |
244-
| [**MiniMax**](docs/models/minimax/index.md) | MiniMax-M2 / M2.5 / M2.7 |
245+
| [**MiniMax**](docs/models/minimax/index.md) | MiniMax-M2 / M2.5 / M2.7, MiniMax-M3 |
245246
| [**Mistral**](docs/models/mistral/index.md) | Mistral 7B / Small 3 24B (deprecated), Ministral 3 (3B/8B/14B) |
246247
| [**Xiaomi-MiMo**](docs/models/mimo/index.md) | Xiaomi-MiMo, MiMo-V2-Flash |
247248
| [**Moonlight**](docs/models/moonlight/index.md) | Moonlight |
248-
| [**Nemotron**](docs/models/nemotron/index.md) | Nemotron H v1 (deprecated), Nemotron Nano v2 (deprecated), Nemotron-3 Nano, Nemotron-3 Super, Llama Nemotron (deprecated), Nemotron Nano v2 VL (deprecated), Nemotron-3 Nano Omni |
249+
| [**Nemotron**](docs/models/nemotron/index.md) | Nemotron H v1 (deprecated), Nemotron Nano v2 (deprecated), Nemotron-3 Nano, Nemotron-3 Super, Nemotron-3 Ultra, Llama Nemotron (deprecated), Nemotron Nano v2 VL (deprecated), Nemotron-3 Nano Omni |
249250
| [**OLMoE**](docs/models/olmoe/index.md) | OLMoE |
250251
| [**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 |
251252
| [**Sarvam**](docs/models/sarvam/index.md) | Sarvam |

‎tests/unit_tests/doc_consistency/test_readme_consistency.py‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828

2929

3030
REPO_ROOT = Path(__file__).resolve().parents[3]
31+
README = REPO_ROOT / "README.md"
32+
DOCS_MODELS = REPO_ROOT / "docs" / "models"
33+
SUPPORTED_MODELS_HEADING = "## Supported Models"
3134
RECIPES_DIR = REPO_ROOT / "src" / "megatron" / "bridge" / "recipes"
3235
PERF_RECIPES_DIR = REPO_ROOT / "src" / "megatron" / "bridge" / "perf_recipes"
3336
TRAINING_README = REPO_ROOT / "scripts" / "training" / "README.md"
@@ -605,6 +608,81 @@ def test_qwen3_model_guides_match_fern_and_reference_exported_recipes():
605608
assert not missing, f"{sphinx_path.relative_to(REPO_ROOT)} references unknown recipes: {missing}"
606609

607610

611+
def _normalize(text: str) -> str:
612+
"""Lowercase and drop every non-alphanumeric character, so separators and case do not matter."""
613+
return re.sub(r"[^a-z0-9]", "", text.lower())
614+
615+
616+
def _supported_models_rows() -> list[tuple[str, str]]:
617+
"""`(family_cell, variants_cell)` for every data row of the README Supported Models table."""
618+
text = _read(README)
619+
assert SUPPORTED_MODELS_HEADING in text, f"README.md has no {SUPPORTED_MODELS_HEADING!r} section"
620+
body = text.split(SUPPORTED_MODELS_HEADING, 1)[1]
621+
following = re.search(r"^## ", body, flags=re.MULTILINE)
622+
table = body[: following.start()] if following else body
623+
624+
rows: list[tuple[str, str]] = []
625+
for line in table.splitlines():
626+
line = line.strip()
627+
if not line.startswith("|") or "---" in line or line.count("|") < 3:
628+
continue
629+
cells = [cell.strip() for cell in line.strip("|").split("|")]
630+
if not cells[0].lower().startswith("family"):
631+
rows.append((cells[0], cells[1] if len(cells) > 1 else ""))
632+
return rows
633+
634+
635+
def _row_for_family(rows: list[tuple[str, str]], family: str) -> tuple[str, str] | None:
636+
"""The row claiming `family`, matched by its docs link or by name, or None."""
637+
for cell, variants in rows:
638+
if f"docs/models/{family}/" in cell:
639+
return cell, variants
640+
for cell, variants in rows:
641+
if _normalize(family) in _normalize(cell):
642+
return cell, variants
643+
return None
644+
645+
646+
def test_readme_supported_models_table_lists_every_shipped_model_family():
647+
"""Every documented model family with code in the tree has a Supported Models row."""
648+
rows = _supported_models_rows()
649+
assert len(rows) >= 15, f"only {len(rows)} Supported Models rows parsed — the table layout has changed"
650+
651+
missing = []
652+
for family_dir in sorted(path for path in DOCS_MODELS.iterdir() if path.is_dir()):
653+
name = family_dir.name
654+
shipped = (REPO_ROOT / "examples" / "models" / name).is_dir() or (
655+
REPO_ROOT / "src" / "megatron" / "bridge" / "models" / name
656+
).is_dir()
657+
if shipped and _row_for_family(rows, name) is None:
658+
missing.append(f"docs/models/{name}/")
659+
assert not missing, f"documented, shipped model families have no Supported Models row: {missing}"
660+
661+
662+
def test_readme_supported_models_rows_name_every_shipped_model_variant():
663+
"""Every documented variant page with runnable examples is named in its family's row."""
664+
rows = _supported_models_rows()
665+
checked, missing = [], []
666+
for page in sorted(DOCS_MODELS.glob("*/*.md")):
667+
if page.name == "index.md":
668+
continue
669+
examples = re.findall(r"(examples/[A-Za-z0-9_./-]+)", _read(page))
670+
if not any((REPO_ROOT / path.rstrip("/.")).exists() for path in examples):
671+
continue # nothing runnable behind this page yet, so the table cannot be expected to name it
672+
row = _row_for_family(rows, page.parent.name)
673+
if row is None:
674+
continue # already reported at family granularity
675+
checked.append(page.name)
676+
named = _normalize(" ".join(row))
677+
tokens = [token for token in re.split(r"[-_]", page.stem) if token]
678+
if _normalize(page.stem) in named or all(_normalize(token) in named for token in tokens):
679+
continue
680+
missing.append(f"docs/models/{page.parent.name}/{page.name}")
681+
682+
assert checked, "no documented variant page cleared the shipped gate — the docs layout has changed"
683+
assert not missing, f"documented, shipped model variants are not named in their README row: {missing}"
684+
685+
608686
def test_sphinx_docs_link_out_of_tree_tutorials_as_urls():
609687
"""Sphinx must not treat repository-root tutorials as source documents."""
610688
for path in SPHINX_TUTORIAL_LINK_DOCS:

0 commit comments

Comments
 (0)