From 3e5ff74b932d0d86788ac65a934d21f8fcab32f7 Mon Sep 17 00:00:00 2001 From: Lawrence Lane Date: Thu, 21 May 2026 16:52:21 -0400 Subject: [PATCH 1/7] docs(fern): mirror qwen3-omni ASR + embedding/reranker into nightly Backfills two post-scaffold docs/ changes into the nightly Fern tree that the scaffold had not yet captured: * commit cf1d4559 (qwen3-omni ASR recipe): adds guides/audio/qwen3-omni-asr.mdx + image, wires it into the Recipes & E2E Examples nav, and adds the matching rows to the Latest Model Support and Recipes & Guides tables plus the Audio Models section in guides/overview.mdx. * commit 76e74074 (embedding + reranker coverage): adds the new model-coverage/embedding/ and model-coverage/reranker/ sections with their NVIDIA and Mistral pages, registers two new sidebar sections in versions/nightly.yml, and adds the two Auto-class rows to the model-coverage overview table. Content and intent preserved verbatim; only sphinx-isms are rewritten to fern-native MDX (cards, accordions, version-agnostic internal links, GitHub blob/main/ URLs in place of {download} roles). The v0.4 frozen tree and latest/v0.4 alias YAMLs are intentionally not touched - this is nightly drift, not a back-port. Signed-off-by: Lawrence Lane --- fern/versions/nightly.yml | 24 ++ .../pages/guides/audio/qwen3-omni-asr.mdx | 256 ++++++++++++++++++ .../pages/guides/audio/qwen_omni_asr.png | Bin 0 -> 74676 bytes .../nightly/pages/guides/overview.mdx | 12 + fern/versions/nightly/pages/index.mdx | 6 +- .../pages/model-coverage/embedding/index.mdx | 49 ++++ .../mistralai/ministral3-bidirectional.mdx | 83 ++++++ .../embedding/nvidia/llama-bidirectional.mdx | 114 ++++++++ .../nightly/pages/model-coverage/overview.mdx | 5 +- .../pages/model-coverage/reranker/index.mdx | 36 +++ .../reranker/nvidia/llama-bidirectional.mdx | 101 +++++++ 11 files changed, 682 insertions(+), 4 deletions(-) create mode 100644 fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx create mode 100644 fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png create mode 100644 fern/versions/nightly/pages/model-coverage/embedding/index.mdx create mode 100644 fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx create mode 100644 fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx create mode 100644 fern/versions/nightly/pages/model-coverage/reranker/index.mdx create mode 100644 fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx diff --git a/fern/versions/nightly.yml b/fern/versions/nightly.yml index dd2f6f15e4..247e9c6ddd 100644 --- a/fern/versions/nightly.yml +++ b/fern/versions/nightly.yml @@ -220,6 +220,27 @@ navigation: path: ./nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx - page: "Qwen-Image" path: ./nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx + - section: "Embedding Models" + slug: embedding-models + contents: + - page: "Overview" + path: ./nightly/pages/model-coverage/embedding/index.mdx + slug: overview + - page: "Llama (Bidirectional)" + path: ./nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx + slug: llama-bidirectional + - page: "Ministral3 (Bidirectional)" + path: ./nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx + slug: ministral3-bidirectional + - section: "Reranking Models" + slug: reranking-models + contents: + - page: "Overview" + path: ./nightly/pages/model-coverage/reranker/index.mdx + slug: overview + - page: "Llama (Bidirectional)" + path: ./nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx + slug: llama-bidirectional - section: "Recipes & E2E Examples" contents: - page: "Recipes and End-to-End Examples" @@ -267,6 +288,9 @@ navigation: - page: "Mistral Medium 3.5 VL" path: ./nightly/pages/guides/vlm/mistral-medium-3-5.mdx slug: mistral-medium-3-5 + - page: "Fine-Tune Qwen3-Omni for ASR" + path: ./nightly/pages/guides/audio/qwen3-omni-asr.mdx + slug: qwen3-omni-asr - page: "Diffusion Model Fine-Tuning with NeMo AutoModel" path: ./nightly/pages/guides/diffusion/finetune.mdx slug: diffusion-fine-tuning diff --git a/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx b/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx new file mode 100644 index 0000000000..0191e7f662 --- /dev/null +++ b/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx @@ -0,0 +1,256 @@ +--- +title: "Fine-Tune Qwen3-Omni for ASR" +description: "End-to-end ASR fine-tuning of Qwen3-Omni-30B on Hugging Face audio datasets with NeMo AutoModel." +--- + +End-to-end ASR fine-tuning of `Qwen/Qwen3-Omni-30B-A3B-Instruct` on a +Hugging Face audio dataset, using the NeMo AutoModel VLM training stack. The +running example is the public +[`edinburghcstr/ami`](https://huggingface.co/datasets/edinburghcstr/ami) +meeting corpus (English IHM), but the same recipe works for any HF dataset +that exposes `{audio, text}` columns (AMI, LibriSpeech, GigaSpeech, +WenetSpeech, CommonVoice, …). + +The workflow has two stages: + +1. **Train** the thinker sub-model with the `FinetuneRecipeForVLM` recipe. +2. **Convert** the NeMo-saved thinker checkpoint into a Hugging Face-compatible + Qwen3-Omni export so `transformers.AutoModel*` and vLLM can load it. + +--- + +## Data Preparation + +### Built-In Builder: `make_hf_audio_asr_dataset` + +`nemo_automodel.components.datasets.vlm.datasets.make_hf_audio_asr_dataset` +returns a Hugging Face `Dataset` whose `__getitem__` lazily produces a single +`{"conversation": [...]}` dict suitable for `qwen3_omni_asr_collate_fn`. Key +design points: + +* **`with_transform` for lazy decoding.** Building the dataset object is a + constant-time metadata read; audio decode and chat-template assembly only + run inside dataloader workers when a batch is fetched. Startup time is + independent of split size. +* **Configurable prompt shape.** Defaults are `system_prompt=None` and + `user_prompt=None`, yielding the minimal `user(audio) → assistant(text)` + conversation. Setting either or both expands the conversation: + `system_prompt="..."` adds a `system` turn, `user_prompt="..."` prepends a + text item before the audio inside the user turn. Whitespace-only prompts + are treated as absent. +* **Dataset-agnostic.** Accepts any HF audio dataset that exposes an audio + column and a transcript column. Defaults (`audio_column="audio"`, + `text_column="text"`, `name=None`) cover AMI, LibriSpeech, GigaSpeech, and + WenetSpeech out of the box; per-dataset overrides go in the recipe YAML. + +```python +from nemo_automodel.components.datasets.vlm.datasets import ( + make_hf_audio_asr_dataset, +) + +dataset = make_hf_audio_asr_dataset( + path_or_dataset="edinburghcstr/ami", + name="ihm", + split="train", + sampling_rate=16000, + user_prompt="Transcribe the English audio into text.", +) +# dataset[0]["conversation"] yields: +# [ +# {"role": "user", "content": [{"type": "text", "text": "Transcribe…"}, +# {"type": "audio", "audio": np.ndarray}]}, +# {"role": "assistant", "content": [{"type": "text", "text": "..."}]}, +# ] +``` + +### Built-In Collate: `qwen3_omni_asr_collate_fn` + +`nemo_automodel.components.datasets.vlm.collate_fns.qwen3_omni_asr_collate_fn` +batches the lazy samples into model inputs without depending on +`qwen_omni_utils`: + +* Walks each conversation for `{"type": "audio", "audio": }` items + and feeds the raw waveforms straight to `Qwen3OmniMoeProcessor`'s + `WhisperFeatureExtractor` (skipping the `process_mm_info` helper). +* Validates and coerces every audio payload through + `_validate_and_coerce_audio_payload` (1-D `float32`; otherwise raises + `ValueError` naming the sample index and offending shape/dtype). +* Pins `padding_side="right"` so the recipe's `count_tail_padding` token + accounting works correctly. +* Reuses `build_labels_from_template` (marker-based; `Qwen3OmniMoeProcessor` + is in `_IMSTART_TEMPLATE_PROCESSORS`) and emits pre-shifted labels. + +The collate is selected through the YAML's `dataloader.collate_fn._target_`; it +is intentionally **not** registered in the global `COLLATE_FNS` map so the +existing `Qwen3OmniMoeProcessor → qwen3_omni_collate_fn` mapping keeps +serving non-ASR VLM users that *do* have `qwen_omni_utils` installed. + +### Use a Different HF Audio Dataset + +To target your own dataset, set `dataset.path_or_dataset` and override the +defaults below only when the dataset diverges: + +| Dataset | `path_or_dataset` | `name` | `text_column` | +|-----------------------------------------|----------------------------------------|------------------------------|-------------------| +| `edinburghcstr/ami` | `edinburghcstr/ami` | `ihm` or `sdm` | `text` (default) | +| `openslr/librispeech_asr` | `openslr/librispeech_asr` | optional config | `text` (default) | +| `speechcolab/gigaspeech` | `speechcolab/gigaspeech` | optional config | `text` (default) | +| `mozilla-foundation/common_voice_*` | `mozilla-foundation/common_voice_18_0` | language code (e.g., `en`) | **`sentence`** | + +YAML override snippet for CommonVoice (note `text_column: sentence`): + +```yaml +dataset: + _target_: nemo_automodel.components.datasets.vlm.datasets.make_hf_audio_asr_dataset + path_or_dataset: mozilla-foundation/common_voice_18_0 + name: en + text_column: sentence + split: train + sampling_rate: 16000 +``` + +Audio columns are universally named `audio` across these datasets, so the +default `audio_column="audio"` rarely needs an override. + +--- + +## Train + +### Example Config + +`examples/audio_finetune/qwen3_omni_asr/ami_sft.yaml` is a ready-to-run full +fine-tune for the 30B-A3B Omni model on a single 8-GPU node, targeting the +public AMI IHM corpus. Defaults: + +| Section | Setting | +|--------------------|----------------------------------------------------------------------------------------| +| `recipe` | `FinetuneRecipeForVLM` | +| `distributed` | `fsdp2`, `ep_size=8`, `tp=cp=pp=1` | +| `freeze_config` | `freeze_vision_tower=true`, `freeze_audio_tower=false`, `freeze_language_model=false` | +| `step_scheduler` | `global_batch_size=64`, `local_batch_size=8`, `ckpt_every_steps=200`, `num_epochs=1` | +| `optimizer` | `AdamW(lr=2.0e-5, betas=[0.9, 0.95], weight_decay=0.0)` | +| `checkpoint` | `result/checkpoints/...`, `model_save_format=safetensors`, `save_consolidated=true` | +| `dataset` | `make_hf_audio_asr_dataset(path_or_dataset="edinburghcstr/ami", name="ihm")` | + +`peft:` is intentionally omitted — both the language model and the audio +tower are trainable; the vision tower stays frozen. With `ep_size=8`, the MoE +experts are sharded across all 8 GPUs. + +Measured on 8x H100 80 GB: ~1.4 step/s steady-state, ~36–40 GB peak/GPU. +One epoch over the ~69k post-1.0s-filter AMI IHM train clips finishes in +~22 min (compared to ~2 h at `local_batch_size=1`). Peak memory on this MoE is +dominated by FSDP/expert all-gather (~36 GB), not by activations, so the batch +size can be pushed this high without OOM. + + +### Launch + +Use the standard NeMo AutoModel CLI: + +```bash +torchrun --nproc_per_node=8 --nnodes=1 -m nemo_automodel.cli.app \ + examples/audio_finetune/qwen3_omni_asr/ami_sft.yaml +``` + +Any per-field CLI override (e.g., `--dataset.split 'train[:5000]'`) is +forwarded to the YAML. Optional WandB logging streams online as long as +`WANDB_API_KEY` is set in the environment; set `WANDB_MODE=offline` for a +dry run. + +### What Gets Saved + +Every `ckpt_every_steps` steps the recipe writes a consolidated checkpoint: + +``` +epoch_E_step_S/ +├── config.yaml # snapshot of the recipe config +├── losses.json +├── dataloader/ # StatefulDataLoader state for restart +├── optim/ # AdamW state (~30 GB / shard for 30B FT) +├── rng/ # PyTorch + numpy + python RNG state +├── step_scheduler.pt +└── model/ + ├── shard-XXXXX-model-00001-of-00001.safetensors # DCP sharded + ├── consolidated/ # HF-format export + │ ├── config.json # thinker subtree only + │ ├── model.safetensors.index.json + │ ├── model-00001-of-00013.safetensors + │ └── ... + └── chat_template.jinja, tokenizer*.json, processor_config.json +``` + +The `consolidated/` directory is the artifact to use for inference. It already +holds the trained weights and the right tokenizer + processor — but its +`config.json` describes the *thinker sub-model only* +(`model_type=qwen3_omni_moe_thinker`), which neither `transformers.AutoConfig` +nor vLLM recognizes as a top-level architecture. See the Convert section for the +conversion step. + +### Resume + +`--checkpoint.restore_from ` reloads the model state, optimizer, +RNG, and dataloader position. Full-FT checkpoints are loaded directly into +the sharded model parts. The recipe does not require the conversion step +below for restart — only for *external* inference tooling. + +--- + +## Convert: Thinker → HF-Compatible Omni + +NeMo maps `Qwen3OmniMoeForConditionalGeneration` to a custom *thinker-only* +class (the parent Omni model in HF has `thinker / code2wav / talker` +sub-modules; this recipe only needs the thinker for ASR). The saved +`consolidated/config.json` therefore carries +`model_type=qwen3_omni_moe_thinker`, which is **not registered as a top-level +architecture** in `transformers.CONFIG_MAPPING`. Loading it directly will +fail with: + +```text +ValueError: The checkpoint you are trying to load has model type +`qwen3_omni_moe_thinker` but Transformers does not recognize this architecture. +``` + +### Tool: `tools/wrap_thinker_ckpt_as_omni.py` + +`tools/wrap_thinker_ckpt_as_omni.py` rewraps the thinker checkpoint as a +full Qwen3-Omni export by: + +1. Renaming + copying the trained `thinker.*` shards into the output dir. +2. Copying the untrained `code2wav.*` and `talker.*` shards verbatim from + the cached HF base model (these were never modified during ASR training). +3. Writing a merged `model.safetensors.index.json` across all three buckets. +4. Replacing the bogus `config.json` with the base model's + (`model_type=qwen3_omni_moe`, + `architectures=["Qwen3OmniMoeForConditionalGeneration"]`). +5. Copying the rest of the HF metadata (tokenizer, processor, generation + config, chat template) from the base; the recipe-saved `chat_template.jinja` + wins if present. + +Memory footprint stays at roughly one shard (~5 GB) at a time — no full-model +materialisation. + +```bash +python tools/wrap_thinker_ckpt_as_omni.py \ + --ckpt-dir result/checkpoints//epoch_0_step_199/model/consolidated \ + --base-dir ~/.cache/huggingface/hub/models--Qwen--Qwen3-Omni-30B-A3B-Instruct/snapshots/ \ + --out-dir /tmp/qwen3_omni_asr_step_199_wrapped +``` + +The output directory is a drop-in replacement for the public Qwen3-Omni +snapshot — only the `thinker.*` weights differ. + +--- + +## Results: AMI IHM + +End-of-epoch evaluation on the AMI IHM `test` split, comparing the +zero-shot base Qwen3-Omni against the same model after one epoch of full +fine-tuning with the recipe above (audio tower trainable). WER drops by +roughly half: + +![AMI IHM WER: base vs. fine-tuned Qwen3-Omni](./qwen_omni_asr.png) + +| Stage | Model | WER (AMI IHM test) | +|-----------------|-------------------------------------------------------|--------------------| +| Before training | Base `Qwen/Qwen3-Omni-30B-A3B-Instruct` (zero-shot) | 15.81% | +| After training | 1 epoch full FT (audio tower trainable) | **8.31%** | diff --git a/fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png b/fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png new file mode 100644 index 0000000000000000000000000000000000000000..1b6043c4ce7ea9341bd2ef3a02ee488e3e2335eb GIT binary patch literal 74676 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

CcLbj5DpU4QaMSOR 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 literal 0 HcmV?d00001 diff --git a/fern/versions/nightly/pages/guides/overview.mdx b/fern/versions/nightly/pages/guides/overview.mdx index 63becad471..8f44d8b9aa 100644 --- a/fern/versions/nightly/pages/guides/overview.mdx +++ b/fern/versions/nightly/pages/guides/overview.mdx @@ -69,6 +69,18 @@ Simple generation script and configurations for VLMs. - Folder: [examples/vlm_generate](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/vlm_generate) +## Audio Models (ASR) + +This section provides recipes for fine-tuning omni / audio-capable models on automatic speech recognition (ASR) tasks. The recipes reuse the VLM training stack but operate on `{audio, text}` HuggingFace datasets (AMI, LibriSpeech, GigaSpeech, CommonVoice, etc.). + +### Fine-Tuning + +End-to-end ASR fine-tuning of `Qwen3-Omni-30B-A3B-Instruct` on any HuggingFace audio dataset, including a thinker-only checkpoint export step for downstream `transformers` / vLLM loading. + +- Folder: [examples/audio_finetune/qwen3_omni_asr](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/audio_finetune/qwen3_omni_asr) +- Representative model: Qwen3-Omni-30B-A3B-Instruct +- How-to guide: [Fine-tune Qwen3-Omni for ASR](/recipes-e2e-examples/qwen3-omni-asr) + ## Diffusion Models (Text-to-Image & Text-to-Video) Text-to-image and text-to-video diffusion models can generate visual content from natural language descriptions. Fine-tuning lets you adapt these models to a specific style, domain, or dataset — for example, generating product videos in your brand's aesthetic. Pretraining gives you full control when no existing model fits your needs. diff --git a/fern/versions/nightly/pages/index.mdx b/fern/versions/nightly/pages/index.mdx index 6383d35c16..55dc2708eb 100644 --- a/fern/versions/nightly/pages/index.mdx +++ b/fern/versions/nightly/pages/index.mdx @@ -4,7 +4,7 @@ description: "NeMo AutoModel is a PyTorch DTensor-native SPMD open-source traini --- import { Tag } from "@/components/Tag"; -PyTorch-native training that scales from 1 GPU to thousands with a single config change. Load any Hugging Face model, point at your data, and start training -- no checkpoint conversion, no boilerplate. +PyTorch-native training that scales from 1 GPU to thousands with a single config change. Load any Hugging Face model, point at your data, and start training; no checkpoint conversion and no boilerplate. **Quick links:** [🤗 HF Compatible](/get-started/hf-compatibility) | [🚀 Performance](/performance/performance-summary) | [📐 Scalability](/get-started/key-features) | [🎯 SFT & PEFT](/recipes-e2e-examples/sft-peft) | [🎨 Diffusion](/recipes-e2e-examples/diffusion-fine-tuning) | [👁️ VLM](/recipes-e2e-examples/gemma-4) @@ -44,6 +44,7 @@ New models are added regularly. Pick a model below to start fine-tuning, or see | Date | Modality | Model | |------|----------|-------| +| 2026-05-18 | Audio | Qwen3-Omni ASR ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/audio_finetune/qwen3_omni_asr/ami_sft.yaml)) | | 2026-04-07 | LLM | [GLM-5.1](https://github.com/NVIDIA-NeMo/Automodel/discussions/1719) ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_5.1_hellaswag_pp.yaml)) | | 2026-04-02 | VLM | Gemma 4 ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_4b.yaml)) | | 2026-03-16 | VLM | [Mistral Small 4](https://github.com/NVIDIA-NeMo/Automodel/discussions/1558) ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral4/mistral4_medpix.yaml)) | @@ -52,7 +53,7 @@ New models are added regularly. Pick a model below to start fine-tuning, or see ## Recipes & Guides -Find the right guide for your task -- fine-tuning, pretraining, distillation, diffusion, and more. +Find the right guide for your task: fine-tuning, pretraining, distillation, diffusion, and more. | I want to... | Choose this when... | Input Data | Model | Guide | | --------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------- | --------- | --------------------------------------------------------- | @@ -64,6 +65,7 @@ Find the right guide for your task -- fine-tuning, pretraining, distillation, di | **Fine-tune dLLM** | You want to fine-tune a diffusion language model (e.g., LLaDA) using masked denoising | Instruction / chat dataset | dLLM | [Fine-tune dLLM](/recipes-e2e-examples/dllm-fine-tuning) | | **Fine-tune Diffusion** | You want to fine-tune a diffusion model for image or video generation | Video / Image dataset | Diffusion | [Fine-tune Diffusion](/recipes-e2e-examples/diffusion-fine-tuning) | | **Fine-tune VLM-MoE** | You need large-scale vision-language training with sparse MoE efficiency | Image + text dataset | VLM (MoE) | [Fine-tune VLM-MoE](/recipes-e2e-examples/qwen3-5-vl) | +| **Fine-tune Audio ASR** | Adapt Qwen3-Omni for speech recognition on HF audio datasets | Audio + transcript dataset | Qwen3-Omni | [Fine-tune Qwen3-Omni ASR](/recipes-e2e-examples/qwen3-omni-asr) | | **Embedding fine-tune** | You want to improve text similarity for search, retrieval, or RAG | Text pairs / retrieval corpus | LLM | Coming Soon | | **Fine-tune a large MoE** | You are adapting a large sparse MoE model (DeepSeek-V3, GLM-5, etc.) to your domain | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune MoE](/recipes-e2e-examples/large-moe-fine-tuning) | | **Fine-tune DeepSeek V4 Flash** | You want to fine-tune the DeepSeek V4 Flash hybrid-attention MoE (SWA / CSA / HCA + hash-routing) | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune DeepSeek V4 Flash](/recipes-e2e-examples/deepseek-v4-flash) | diff --git a/fern/versions/nightly/pages/model-coverage/embedding/index.mdx b/fern/versions/nightly/pages/model-coverage/embedding/index.mdx new file mode 100644 index 0000000000..8c860cec33 --- /dev/null +++ b/fern/versions/nightly/pages/model-coverage/embedding/index.mdx @@ -0,0 +1,49 @@ +--- +title: "Embedding Models" +description: "" +position: 1 +--- + +## Introduction + +Text embedding models transform text into dense vector representations that power semantic search, dense retrieval, retrieval-augmented generation (RAG), and classification tasks. NeMo AutoModel includes a training recipe for converting Llama decoder-only models into encoder architectures with bidirectional attention, and falls back to Hugging Face AutoModel for other encoder backbones. + +For cross-encoder pairwise scoring, see [Reranking Models](/model-coverage/reranking-models/overview). + +Embedding models use bi-encoders to produce dense representations for queries and documents independently. They are the standard path for embedding generation and first-stage dense retrieval. + +### Optimized Backbones (Bidirectional Attention) + +| Owner | Model | Architecture | Auto Class | Tasks | +|---|---|---|---|---| +| NVIDIA | [Llama (Bidirectional)](/model-coverage/embedding-models/llama-bidirectional) | `LlamaBidirectionalModel` | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Embedding, Dense Retrieval | +| Mistral AI | [Ministral3 (Bidirectional)](/model-coverage/embedding-models/ministral3-bidirectional) | `Ministral3BidirectionalModel` | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Embedding, Dense Retrieval | + +### Hugging Face Auto Backbones + +Any Hugging Face model that can be loaded with `AutoModel` can be used as an embedding backbone. This fallback path uses the model's native attention; no bidirectional conversion is applied. + +## Example Recipes + +| Recipe | Description | +|---|---| +| [llama3_2_1b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama3_2_1b.yaml) | Bi-encoder — Llama 3.2 1B embedding model | +| [llama_embed_nemotron_8b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama_embed_nemotron_8b/llama_embed_nemotron_8b.yaml) | Bi-encoder — Llama-Embed-Nemotron-8B reproduction recipe | +| [ministral3_3b_instruct.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/ministral3_3b_instruct.yaml) | Bi-encoder — Ministral3-3B recipe | + +## Supported Workflows + +- **Fine-tuning (Bi-Encoder):** Contrastive learning on query-document pairs to produce embedding models +- **LoRA/PEFT:** Parameter-efficient fine-tuning for embedding backbones +- **ONNX Export:** Export trained embedding models for deployment (case by case, model dependent) + +## Dataset + +Retrieval fine-tuning requires query-document pairs: each example is a query paired with one positive document and one or more negative documents. Both inline JSONL and corpus ID-based JSON formats are supported. See the [Retrieval Dataset](/datasets/retrieval-dataset) guide. + +{/* +@akoumpa: uncomment this when finetune guide is published. +## Train Embedding Models + +For a complete walkthrough of training configuration, model-specific settings, and launch commands, see the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune). +*/} diff --git a/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx b/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx new file mode 100644 index 0000000000..255d59bb3d --- /dev/null +++ b/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx @@ -0,0 +1,83 @@ +--- +title: "Ministral3 (Bidirectional) for Embedding" +description: "" +--- + +NeMo AutoModel provides a bidirectional variant of [Mistral AI's Ministral3](https://mistral.ai/news/ministraux/) for embedding and dense retrieval tasks. Unlike the standard causal (left-to-right) Ministral3 used for text generation, this variant uses **bidirectional attention**, so each token can attend to both past and future tokens in the sequence, producing richer representations for semantic similarity and dense retrieval. + +The bidirectional encoder can be loaded directly from text-only checkpoints (e.g. `mistralai/Ministral-3B-Instruct`) and also automatically extracts the language model from Ministral3 VLM checkpoints (e.g. `mistralai/Ministral-3-3B-Base-2512` or `mistralai/Ministral-3-3B-Instruct-2512`). + +| | | +|---|---| +| **Tasks** | Embedding, Dense Retrieval | +| **Architecture** | `Ministral3BidirectionalModel` | +| **Parameters** | 3B | +| **HF Org** | [mistralai](https://huggingface.co/mistralai) | + +## Available Models + +Any Ministral3 checkpoint can be loaded as a bidirectional backbone. The following configurations are tested: + +- **Ministral-3-3B-Base-2512** — VLM checkpoint, language model is extracted automatically +- **Ministral-3-3B-Instruct-2512** — VLM checkpoint, language model is extracted automatically + +## Embedding Models + +The bidirectional bi-encoder path is used for embedding generation and dense retrieval. + +| Architecture | Task | Auto Class | Description | +|---|---|---|---| +| `Ministral3BidirectionalModel` | Embedding | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Bidirectional Ministral3 with mean pooling for dense embeddings | + +## Pooling Strategies + +The bi-encoder supports multiple pooling strategies to aggregate token representations into a single embedding vector: + +| Strategy | Description | +|---|---| +| `avg` | Average of all token hidden states (default) | +| `cls` | First token hidden state | +| `last` | Last non-padding token hidden state | +| `weighted_avg` | Weighted average of token hidden states | + +## Example HF Models + +| Model | HF ID | +|---|---| +| Ministral-3 3B Base | [`mistralai/Ministral-3-3B-Base-2512`](https://huggingface.co/mistralai/Ministral-3-3B-Base-2512) | +| Ministral-3 3B Instruct | [`mistralai/Ministral-3-3B-Instruct-2512`](https://huggingface.co/mistralai/Ministral-3-3B-Instruct-2512) | + +## Try with NeMo AutoModel + +**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](/get-started/installation)) for information: + +```bash +uv pip install nemo-automodel +``` + +**2. Clone the repo** to get the example recipes: + +```bash +git clone https://github.com/NVIDIA-NeMo/Automodel.git +cd Automodel +``` + +**3. Run the recipe** from inside the repo (point any Llama bi-encoder recipe at a Ministral3 checkpoint, or write a recipe targeting `mistralai/Ministral-3-3B-Base-2512`): + +```bash +torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/llama3_2_1b.yaml +torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/ministral3_3b_instruct.yaml +``` + +See the [Installation Guide](/get-started/installation). + +{/* TODO: uncomment when finetune guide is published. +## Fine-Tuning + +See the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune) for bi-encoder training instructions, including LoRA and PEFT configuration. +*/} + +## Hugging Face Model Cards + +- [mistralai/Ministral-3-3B-Base-2512](https://huggingface.co/mistralai/Ministral-3-3B-Base-2512) +- [mistralai/Ministral-3-3B-Instruct-2512](https://huggingface.co/mistralai/Ministral-3-3B-Instruct-2512) diff --git a/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx b/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx new file mode 100644 index 0000000000..dd4851039a --- /dev/null +++ b/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx @@ -0,0 +1,114 @@ +--- +title: "Llama (Bidirectional) for Embedding" +description: "" +--- + +NeMo AutoModel provides a bidirectional variant of [Meta's Llama](https://www.llama.com/) for embedding and dense retrieval tasks. Unlike the standard causal (left-to-right) Llama used for text generation, this variant uses **bidirectional attention**, so each token can attend to both past and future tokens in the sequence, producing richer representations for semantic similarity and dense retrieval. + +For the cross-encoder variant, see [Llama (Bidirectional) for Reranking](/model-coverage/reranking-models/llama-bidirectional). + +| | | +|---|---| +| **Tasks** | Embedding, Dense Retrieval | +| **Architecture** | `LlamaBidirectionalModel` | +| **Parameters** | 1B – 8B | +| **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | + +## Available Models + +Any Llama checkpoint can be loaded as a bidirectional backbone. The following configurations are tested: + +- **Llama 3.2 1B** — fast iteration, fits on a single GPU +- **Llama 3.1 8B** — higher-quality embeddings for production use + +## Embedding Models + +The bidirectional bi-encoder path is used for embedding generation and dense retrieval. + +| Architecture | Task | Auto Class | Description | +|---|---|---|---| +| `LlamaBidirectionalModel` | Embedding | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Bidirectional Llama with mean pooling for dense embeddings | + +## Pooling Strategies + +The bi-encoder supports multiple pooling strategies to aggregate token representations into a single embedding vector: + +| Strategy | Description | +|---|---| +| `avg` | Average of all token hidden states (default) | +| `cls` | First token hidden state | +| `last` | Last non-padding token hidden state | +| `weighted_avg` | Weighted average of token hidden states | + +## Example HF Models + +| Model | HF ID | +|---|---| +| Llama 3.2 1B | [`meta-llama/Llama-3.2-1B`](https://huggingface.co/meta-llama/Llama-3.2-1B) | +| Llama 3.1 8B | [`meta-llama/Llama-3.1-8B`](https://huggingface.co/meta-llama/Llama-3.1-8B) | + +## Example Recipes + +| Recipe | Description | +|---|---| +| [llama3_2_1b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama3_2_1b.yaml) | Bi-encoder — Llama 3.2 1B embedding model | +| [llama_embed_nemotron_8b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama_embed_nemotron_8b/llama_embed_nemotron_8b.yaml) | Bi-encoder — reproduction recipe for [`nvidia/llama-embed-nemotron-8b`](https://huggingface.co/nvidia/llama-embed-nemotron-8b) (uses [`nvidia/embed-nemotron-dataset-v1`](https://huggingface.co/datasets/nvidia/embed-nemotron-dataset-v1)) | + +## Try with NeMo AutoModel + +**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](/get-started/installation)) for information: + +```bash +uv pip install nemo-automodel +``` + +**2. Clone the repo** to get the example recipes: + +```bash +git clone https://github.com/NVIDIA-NeMo/Automodel.git +cd Automodel +``` + +**3. Run the recipe** from inside the repo: + +```bash +torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/llama3_2_1b.yaml +``` + + +**1. Pull the container** and mount a checkpoint directory: + +```bash +docker run --gpus all -it --rm \ + --shm-size=8g \ + -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ + nvcr.io/nvidia/nemo-automodel:26.04.00 +``` + +**2. Navigate** to the AutoModel directory (where the recipes are): + +```bash +cd /opt/Automodel +``` + +**3. Run the recipe**: + +```bash +torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/llama3_2_1b.yaml +``` + + +See the [Installation Guide](/get-started/installation). + +{/* TODO: uncomment when finetune guide is published. +## Fine-Tuning + +See the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune) for bi-encoder training instructions, including LoRA and PEFT configuration. +*/} + +## Hugging Face Model Card + +NVIDIA trained and released the `Llama Nemotron Embedding 1B` model, which leverages a bidirectional attention mechanism for multilingual and cross-lingual question–answer retrieval. The model supports long documents (up to 8,192 tokens) and dynamic embedding sizes via Matryoshka embeddings. For more details, see the model card on Hugging Face. + +- [nvidia/llama-nemotron-embed-1b-v2](https://huggingface.co/nvidia/llama-nemotron-embed-1b-v2) +- [nvidia/llama-embed-nemotron-8b](https://huggingface.co/nvidia/llama-embed-nemotron-8b) diff --git a/fern/versions/nightly/pages/model-coverage/overview.mdx b/fern/versions/nightly/pages/model-coverage/overview.mdx index 5d8e72f282..fa7f939008 100644 --- a/fern/versions/nightly/pages/model-coverage/overview.mdx +++ b/fern/versions/nightly/pages/model-coverage/overview.mdx @@ -3,7 +3,7 @@ title: "Model Coverage Overview" description: "" position: 1 --- -NeMo AutoModel integrates with Hugging Face `transformers`. Any LLM or VLM that can be instantiated through `transformers` can also be used via NeMo AutoModel, subject to runtime, third-party software dependencies, and feature compatibility. +NeMo AutoModel integrates with Hugging Face `transformers`. Any LLM or VLM that can be instantiated through `transformers` can also be used using NeMo AutoModel, subject to runtime, third-party software dependencies, and feature compatibility. ## Supported Hugging Face Auto Classes @@ -13,6 +13,8 @@ NeMo AutoModel integrates with Hugging Face `transformers`. Any LLM or VLM that | `AutoModelForImageTextToText` | Image-Text-to-Text (VLM) | Supported | See [VLM model list](/model-coverage/vision-language-models/overview). | | `AutoModelForSequenceClassification` | Sequence Classification | WIP | Early support; interfaces may change. | | Diffusers Pipelines | Diffusion Generation (T2I, T2V) | Supported | See [Diffusion model list](/model-coverage/diffusion/overview). | +| `NeMoAutoModelBiEncoder` | Embedding Models | Supported | See [Embedding model list](/model-coverage/embedding-models/overview). | +| `NeMoAutoModelCrossEncoder` | Reranking Models | Supported | See [Reranking model list](/model-coverage/reranking-models/overview). | ## Release Log @@ -31,7 +33,6 @@ The table below tracks when model support and key features were added across NeM - New models released on the Hugging Face Hub may require the latest `transformers` version, necessitating a package upgrade. - We are working on a CI pipeline that automatically bumps the supported `transformers` version when a new release is detected, enabling even faster day-0 support. -**Note:** To use newly released models, you may need to upgrade your NeMo AutoModel installation — just as you would upgrade `transformers` to access the latest models. AutoModel mirrors the familiar `transformers` `Auto*` APIs while adding optional performance accelerations and distributed training features. ## Custom Model Registry diff --git a/fern/versions/nightly/pages/model-coverage/reranker/index.mdx b/fern/versions/nightly/pages/model-coverage/reranker/index.mdx new file mode 100644 index 0000000000..fc22d03f88 --- /dev/null +++ b/fern/versions/nightly/pages/model-coverage/reranker/index.mdx @@ -0,0 +1,36 @@ +--- +title: "Reranking Models" +description: "" +position: 1 +--- + +## Introduction + +Reranking models use cross-encoders to score a query-document pair jointly. They are typically used after an embedding model has produced an initial candidate set. NeMo AutoModel supports optimized bidirectional Llama rerankers and falls back to Hugging Face `AutoModelForSequenceClassification` for other architectures. + +For first-stage dense retrieval, see [Embedding Models](/model-coverage/embedding-models/overview). + +## Optimized Backbones (Bidirectional Attention) + +| Owner | Model | Architecture | Wrapper Class | Tasks | +|---|---|---|---|---| +| NVIDIA | [llama-nemotron-rerank-1b-v2](/model-coverage/reranking-models/llama-bidirectional) | `LlamaBidirectionalForSequenceClassification` | `NeMoAutoModelCrossEncoder` | Reranking | + +## Hugging Face Auto Backbones + +Any Hugging Face model loadable using `AutoModelForSequenceClassification` can be used as a reranking backbone. This fallback path uses the model's native attention; no bidirectional conversion is applied. + +## Supported Workflows + +- **Fine-tuning (Cross-Encoder):** Cross-entropy training on query-document pairs to produce rerankers +- **LoRA/PEFT:** Parameter-efficient fine-tuning for reranking backbones + +## Dataset + +Retrieval fine-tuning requires query-document pairs: each example is a query paired with one positive document and one or more negative documents. Both inline JSONL and corpus ID-based JSON formats are supported. See the [Retrieval Dataset](/datasets/retrieval-dataset) guide. + +{/* TODO: uncomment when finetune guide is published. +## Train Reranking Models + +For a complete walkthrough of training configuration, model-specific settings, and launch commands, see the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune). +*/} diff --git a/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx b/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx new file mode 100644 index 0000000000..110b811236 --- /dev/null +++ b/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx @@ -0,0 +1,101 @@ +--- +title: "Llama (Bidirectional) for Reranking" +description: "" +--- + +NeMo AutoModel provides a bidirectional variant of [Meta's Llama](https://www.llama.com/) for reranking tasks. Unlike the standard causal (left-to-right) Llama used for text generation, this variant uses **bidirectional attention**, allowing the query and document to interact across the full sequence before a classification head produces a relevance score. + +For the bi-encoder variant, see [Llama (Bidirectional) for Embedding](/model-coverage/embedding-models/llama-bidirectional). + +| | | +|---|---| +| **Tasks** | Reranking | +| **Architecture** | `LlamaBidirectionalForSequenceClassification` | +| **Parameters** | 1B – 8B | +| **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | + +## Available Models + +Any Llama checkpoint can be loaded as a bidirectional reranking backbone. The following configurations have been tested: + +- **Llama 3.2 1B** — fast iteration, fits on a single GPU +- **Llama 3.1 8B** — higher-quality reranking for production use + +## Reranking Models + +The cross-encoder path is used for pairwise relevance scoring and reranking. + +| Architecture | Task | Wrapper Class | Description | +|---|---|---|---| +| `LlamaBidirectionalForSequenceClassification` | Reranking | `NeMoAutoModelCrossEncoder` | Bidirectional Llama with classification head for relevance scoring | + +## Example HF Models + +| Model | HF ID | +|---|---| +| Llama 3.2 1B | [`meta-llama/Llama-3.2-1B`](https://huggingface.co/meta-llama/Llama-3.2-1B) | +| Llama 3.1 8B | [`meta-llama/Llama-3.1-8B`](https://huggingface.co/meta-llama/Llama-3.1-8B) | + +## Example Recipes + +| Recipe | Description | +|---|---| +| [llama3_2_1b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/cross_encoder/llama3_2_1b.yaml) | Cross-encoder — Llama 3.2 1B reranker | + +## Try with NeMo AutoModel + +**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](/get-started/installation)) for information: + +```bash +uv pip install nemo-automodel +``` + +**2. Clone the repo** to get the example recipes: + +```bash +git clone https://github.com/NVIDIA-NeMo/Automodel.git +cd Automodel +``` + +**3. Run the recipe** from inside the repo: + +```bash +torchrun --nproc-per-node=8 examples/retrieval/cross_encoder/finetune.py --config examples/retrieval/cross_encoder/llama3_2_1b.yaml +``` + + +**1. Pull the container** and mount a checkpoint directory: + +```bash +docker run --gpus all -it --rm \ + --shm-size=8g \ + -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ + nvcr.io/nvidia/nemo-automodel:26.04.00 +``` + +**2. Navigate to the AutoModel directory** (where the recipes are): + +```bash +cd /opt/Automodel +``` + +**3. Run the recipe**: + +```bash +torchrun --nproc-per-node=8 examples/retrieval/cross_encoder/finetune.py --config examples/retrieval/cross_encoder/llama3_2_1b.yaml +``` + + +See the [Installation Guide](/get-started/installation). + +{/* TODO: uncomment when finetune guide is published. +## Fine-Tuning + +See the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune) for cross-encoder training instructions, including LoRA/PEFT configuration. +*/} + +## Hugging Face Model Cards + +NVIDIA trained and released the `Llama Nemotron Reranking 1B` model, optimized to produce a relevance logit score indicating how well a document matches a given query. The model was fine-tuned with a bidirectional attention mechanism for multilingual and cross-lingual question–answer retrieval, with support for long documents (up to 8,192 tokens). + +- [nvidia/llama-nemotron-rerank-1b-v2](https://huggingface.co/nvidia/llama-nemotron-rerank-1b-v2) From 3da7cc4cccb3f46a7d54fc7c61b6afbf3a44feba Mon Sep 17 00:00:00 2001 From: Lawrence Lane Date: Thu, 21 May 2026 16:57:42 -0400 Subject: [PATCH 2/7] docs(fern): relocate fern/ infrastructure under docs/fern/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pure tree move + CI path filter and working-directory updates. No content edits, no docs rewrites — every MDX, YAML, and asset is rename-tracked by git so blame and `git log --follow` continue to work unchanged at the new path. Workflows now trigger on `docs/fern/**` (CI / preview) and `docs/**` (publish), and the `working-directory:` keys are repointed at `./docs/fern`. The .gitignore entry for the generated library reference also moves to `docs/fern/product-docs/`. This is the first commit in a multi-step migration toward the "docs/ holds nightly MDX as top-level siblings of docs/fern/" layout. Subsequent commits will (a) replay-then-convert the sphinx MD ↔ converted MDX pairs so each conversion shows up as a single same-directory `.md` → `.mdx` rename diff for review, then (b) re-wire `docs/fern/versions/nightly.yml` to point at the new top-level paths and retire the now-empty `docs/fern/versions/nightly/` tree. Signed-off-by: Lawrence Lane --- .github/workflows/fern-docs-ci.yml | 4 ++-- .github/workflows/fern-docs-preview-build.yml | 6 +++--- .github/workflows/fern-docs-preview-comment.yml | 4 ++-- .github/workflows/publish-fern-docs.yml | 3 +-- .gitignore | 2 +- {fern => docs/fern}/Makefile | 0 {fern => docs/fern}/README.md | 0 {fern => docs/fern}/assets/NVIDIA_dark.svg | 0 {fern => docs/fern}/assets/NVIDIA_light.svg | 0 {fern => docs/fern}/assets/NVIDIA_symbol.svg | 0 {fern => docs/fern}/components/BadgeLinks.tsx | 0 {fern => docs/fern}/components/CustomFooter.tsx | 0 {fern => docs/fern}/components/Tag.tsx | 0 {fern => docs/fern}/docs.yml | 0 {fern => docs/fern}/fern.config.json | 0 {fern => docs/fern}/main.css | 0 {fern => docs/fern}/versions/latest.yml | 0 {fern => docs/fern}/versions/nightly.yml | 0 .../fern}/versions/nightly/pages/about/index.mdx | 0 .../versions/nightly/pages/about/key-features.mdx | 0 .../fern}/versions/nightly/pages/announcements.mdx | 0 .../versions/nightly/pages/api-reference/index.mdx | 0 .../versions/nightly/pages/automodel_diagram.png | Bin .../versions/nightly/pages/breaking-changes.mdx | 0 .../fern}/versions/nightly/pages/documentation.mdx | 0 .../nightly/pages/guides/audio/qwen3-omni-asr.mdx | 0 .../nightly/pages/guides/audio/qwen_omni_asr.png | Bin .../versions/nightly/pages/guides/checkpointing.mdx | 0 .../versions/nightly/pages/guides/configuration.mdx | 0 .../nightly/pages/guides/dataset-overview.mdx | 0 .../nightly/pages/guides/diffusion/dataset.mdx | 0 .../nightly/pages/guides/diffusion/finetune.mdx | 0 .../versions/nightly/pages/guides/dllm/finetune.mdx | 0 .../versions/nightly/pages/guides/fp8-training.mdx | 0 .../nightly/pages/guides/fp8_convergence.jpg | Bin .../nightly/pages/guides/gradient-checkpointing.mdx | 0 .../pages/guides/huggingface-api-compatibility.mdx | 0 .../versions/nightly/pages/guides/installation.mdx | 0 .../llm/column-mapped-text-instruction-dataset.mdx | 0 ...umn-mapped-text-instruction-iterable-dataset.mdx | 0 .../guides/llm/databricks-gpu-metrics-multi.png | Bin .../guides/llm/databricks-gpu-metrics-single.png | Bin .../nightly/pages/guides/llm/databricks.mdx | 0 .../versions/nightly/pages/guides/llm/dataset.mdx | 0 .../nightly/pages/guides/llm/dsv4-flash.mdx | 0 .../versions/nightly/pages/guides/llm/finetune.mdx | 0 .../pages/guides/llm/functiongemma-peft-loss.png | Bin .../pages/guides/llm/functiongemma-sft-loss.png | Bin .../versions/nightly/pages/guides/llm/gpt2_loss.png | Bin .../fern}/versions/nightly/pages/guides/llm/hy3.mdx | 0 .../pages/guides/llm/knowledge-distillation.mdx | 0 .../nightly/pages/guides/llm/large-moe-finetune.mdx | 0 .../pages/guides/llm/nanogpt-pretraining.mdx | 0 .../nightly/pages/guides/llm/pretraining.mdx | 0 .../nightly/pages/guides/llm/retrieval-dataset.mdx | 0 .../pages/guides/llm/sequence-classification.mdx | 0 .../nightly/pages/guides/llm/toolcalling.mdx | 0 .../nightly/pages/guides/mlflow-logging.mdx | 0 .../nightly/pages/guides/omni/gemma3-3n.mdx | 0 .../versions/nightly/pages/guides/omni/medpix.jpg | Bin .../nightly/pages/guides/omni/medpix_peft.jpg | Bin .../versions/nightly/pages/guides/overview.mdx | 0 .../versions/nightly/pages/guides/pipelining.mdx | 0 .../pages/guides/quantization-aware-training.mdx | 0 .../versions/nightly/pages/guides/vlm/dataset.mdx | 0 .../versions/nightly/pages/guides/vlm/gemma4.mdx | 0 .../nightly/pages/guides/vlm/mistral-medium-3-5.mdx | 0 .../nightly/pages/guides/vlm/mistralm35.png | Bin .../nightly/pages/guides/vlm/nemotron-omni.mdx | 0 .../versions/nightly/pages/guides/vlm/qwen3-5.mdx | 0 .../versions/nightly/pages/guides/vlm/qwen3_5.png | Bin .../nightly/pages/guides/vlm/qwen3_5scores.png | Bin .../fern}/versions/nightly/pages/index.mdx | 0 .../nightly/pages/launcher/local-workstation.mdx | 0 .../versions/nightly/pages/launcher/nemo-run.mdx | 0 .../versions/nightly/pages/launcher/overview.mdx | 0 .../nightly/pages/launcher/skypilot-kubernetes.mdx | 0 .../versions/nightly/pages/launcher/skypilot.mdx | 0 .../fern}/versions/nightly/pages/launcher/slurm.mdx | 0 .../diffusion/black-forest-labs/flux.mdx | 0 .../hunyuanvideo-community/hunyuanvideo.mdx | 0 .../pages/model-coverage/diffusion/index.mdx | 0 .../model-coverage/diffusion/qwen/qwen-image.mdx | 0 .../model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx | 0 .../pages/model-coverage/embedding/index.mdx | 0 .../mistralai/ministral3-bidirectional.mdx | 0 .../embedding/nvidia/llama-bidirectional.mdx | 0 .../nightly/pages/model-coverage/latest-models.mdx | 0 .../pages/model-coverage/llm/allenai/olmo.mdx | 0 .../pages/model-coverage/llm/allenai/olmo2.mdx | 0 .../pages/model-coverage/llm/allenai/olmoe.mdx | 0 .../pages/model-coverage/llm/baai/aquila.mdx | 0 .../model-coverage/llm/baichuan-inc/baichuan.mdx | 0 .../pages/model-coverage/llm/baidu/ernie4-5.mdx | 0 .../pages/model-coverage/llm/bigcode/starcoder.mdx | 0 .../pages/model-coverage/llm/bigcode/starcoder2.mdx | 0 .../model-coverage/llm/bytedance-seed/seed.mdx | 0 .../pages/model-coverage/llm/cohere/command-r.mdx | 0 .../model-coverage/llm/deepseek-ai/deepseek-v3.mdx | 0 .../model-coverage/llm/deepseek-ai/deepseek.mdx | 0 .../model-coverage/llm/deepseek-ai/dsv4-flash.mdx | 0 .../pages/model-coverage/llm/eleutherai/gpt-j.mdx | 0 .../model-coverage/llm/eleutherai/gpt-neox.mdx | 0 .../pages/model-coverage/llm/google/gemma.mdx | 0 .../nightly/pages/model-coverage/llm/ibm/bamba.mdx | 0 .../pages/model-coverage/llm/ibm/granite-moe.mdx | 0 .../pages/model-coverage/llm/ibm/granite.mdx | 0 .../pages/model-coverage/llm/inceptionai/jais.mdx | 0 .../pages/model-coverage/llm/inclusionai/ling-2.mdx | 0 .../nightly/pages/model-coverage/llm/index.mdx | 0 .../pages/model-coverage/llm/internlm/internlm.mdx | 0 .../pages/model-coverage/llm/lgai-exaone/exaone.mdx | 0 .../nightly/pages/model-coverage/llm/meta/llama.mdx | 0 .../pages/model-coverage/llm/microsoft/phi.mdx | 0 .../model-coverage/llm/microsoft/phi3-small.mdx | 0 .../pages/model-coverage/llm/microsoft/phi3.mdx | 0 .../pages/model-coverage/llm/minimax/minimax-m2.mdx | 0 .../model-coverage/llm/mistralai/ministral3.mdx | 0 .../pages/model-coverage/llm/mistralai/mistral.mdx | 0 .../pages/model-coverage/llm/mistralai/mixtral.mdx | 0 .../model-coverage/llm/moonshotai/moonlight.mdx | 0 .../model-coverage/llm/nvidia/nemotron-flash.mdx | 0 .../pages/model-coverage/llm/nvidia/nemotron-h.mdx | 0 .../model-coverage/llm/nvidia/nemotron-super.mdx | 0 .../pages/model-coverage/llm/nvidia/nemotron.mdx | 0 .../pages/model-coverage/llm/openai/gpt-oss.mdx | 0 .../pages/model-coverage/llm/openai/gpt2.mdx | 0 .../pages/model-coverage/llm/openbmb/minicpm.mdx | 0 .../pages/model-coverage/llm/orionstar/orion.mdx | 0 .../pages/model-coverage/llm/parasail-ai/gritlm.mdx | 0 .../pages/model-coverage/llm/qwen/qwen2-moe.mdx | 0 .../nightly/pages/model-coverage/llm/qwen/qwen2.mdx | 0 .../pages/model-coverage/llm/qwen/qwen3-moe.mdx | 0 .../pages/model-coverage/llm/qwen/qwen3-next.mdx | 0 .../nightly/pages/model-coverage/llm/qwen/qwen3.mdx | 0 .../model-coverage/llm/stabilityai/stablelm.mdx | 0 .../model-coverage/llm/stepfun-ai/step-3-5.mdx | 0 .../pages/model-coverage/llm/tencent/hy3.mdx | 0 .../pages/model-coverage/llm/thudm/chatglm.mdx | 0 .../pages/model-coverage/llm/thudm/glm4-moe.mdx | 0 .../nightly/pages/model-coverage/llm/thudm/glm4.mdx | 0 .../pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx | 0 .../pages/model-coverage/llm/tiiuae/falcon.mdx | 0 .../pages/model-coverage/llm/upstage/solar.mdx | 0 .../model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx | 0 .../nightly/pages/model-coverage/omni/index.mdx | 0 .../omni/microsoft/phi4-multimodal.mdx | 0 .../model-coverage/omni/nvidia/nemotron-omni.mdx | 0 .../pages/model-coverage/omni/qwen/qwen3-omni.mdx | 0 .../nightly/pages/model-coverage/overview.mdx | 0 .../nightly/pages/model-coverage/reranker/index.mdx | 0 .../reranker/nvidia/llama-bidirectional.mdx | 0 .../pages/model-coverage/troubleshooting.mdx | 0 .../pages/model-coverage/vlm/google/gemma3-vl.mdx | 0 .../pages/model-coverage/vlm/google/gemma4.mdx | 0 .../model-coverage/vlm/huggingface/smolvlm.mdx | 0 .../nightly/pages/model-coverage/vlm/index.mdx | 0 .../pages/model-coverage/vlm/internlm/internvl.mdx | 0 .../pages/model-coverage/vlm/llava-hf/llava.mdx | 0 .../model-coverage/vlm/lmms-lab/llava-onevision.mdx | 0 .../pages/model-coverage/vlm/meta/llama4.mdx | 0 .../model-coverage/vlm/mistralai/ministral3-vl.mdx | 0 .../vlm/mistralai/mistral-medium-3-5.mdx | 0 .../vlm/mistralai/mistral-small-4.mdx | 0 .../pages/model-coverage/vlm/moonshotai/kimi-vl.mdx | 0 .../model-coverage/vlm/nvidia/nemotron-parse.mdx | 0 .../pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx | 0 .../pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx | 0 .../pages/model-coverage/vlm/qwen/qwen3-vl.mdx | 0 .../versions/nightly/pages/performance-summary.mdx | 0 .../fern}/versions/nightly/pages/release-notes.mdx | 0 .../versions/nightly/pages/repository-structure.mdx | 0 {fern => docs/fern}/versions/v0.4.yml | 0 .../fern}/versions/v0.4/pages/about/index.mdx | 0 .../versions/v0.4/pages/about/key-features.mdx | 0 .../fern}/versions/v0.4/pages/announcements.mdx | 0 .../versions/v0.4/pages/api-reference/index.mdx | 0 .../fern}/versions/v0.4/pages/automodel_diagram.png | Bin .../fern}/versions/v0.4/pages/breaking-changes.mdx | 0 .../fern}/versions/v0.4/pages/documentation.mdx | 0 .../versions/v0.4/pages/guides/checkpointing.mdx | 0 .../versions/v0.4/pages/guides/configuration.mdx | 0 .../versions/v0.4/pages/guides/dataset-overview.mdx | 0 .../v0.4/pages/guides/diffusion/dataset.mdx | 0 .../v0.4/pages/guides/diffusion/finetune.mdx | 0 .../versions/v0.4/pages/guides/dllm/finetune.mdx | 0 .../versions/v0.4/pages/guides/fp8-training.mdx | 0 .../versions/v0.4/pages/guides/fp8_convergence.jpg | Bin .../v0.4/pages/guides/gradient-checkpointing.mdx | 0 .../pages/guides/huggingface-api-compatibility.mdx | 0 .../versions/v0.4/pages/guides/installation.mdx | 0 .../llm/column-mapped-text-instruction-dataset.mdx | 0 ...umn-mapped-text-instruction-iterable-dataset.mdx | 0 .../guides/llm/databricks-gpu-metrics-multi.png | Bin .../guides/llm/databricks-gpu-metrics-single.png | Bin .../versions/v0.4/pages/guides/llm/databricks.mdx | 0 .../versions/v0.4/pages/guides/llm/dataset.mdx | 0 .../versions/v0.4/pages/guides/llm/dsv4-flash.mdx | 0 .../versions/v0.4/pages/guides/llm/finetune.mdx | 0 .../pages/guides/llm/functiongemma-peft-loss.png | Bin .../pages/guides/llm/functiongemma-sft-loss.png | Bin .../versions/v0.4/pages/guides/llm/gpt2_loss.png | Bin .../fern}/versions/v0.4/pages/guides/llm/hy3.mdx | 0 .../pages/guides/llm/knowledge-distillation.mdx | 0 .../v0.4/pages/guides/llm/large-moe-finetune.mdx | 0 .../v0.4/pages/guides/llm/nanogpt-pretraining.mdx | 0 .../versions/v0.4/pages/guides/llm/pretraining.mdx | 0 .../v0.4/pages/guides/llm/retrieval-dataset.mdx | 0 .../pages/guides/llm/sequence-classification.mdx | 0 .../versions/v0.4/pages/guides/llm/toolcalling.mdx | 0 .../versions/v0.4/pages/guides/mlflow-logging.mdx | 0 .../versions/v0.4/pages/guides/omni/gemma3-3n.mdx | 0 .../versions/v0.4/pages/guides/omni/medpix.jpg | Bin .../versions/v0.4/pages/guides/omni/medpix_peft.jpg | Bin .../fern}/versions/v0.4/pages/guides/overview.mdx | 0 .../fern}/versions/v0.4/pages/guides/pipelining.mdx | 0 .../pages/guides/quantization-aware-training.mdx | 0 .../versions/v0.4/pages/guides/vlm/dataset.mdx | 0 .../fern}/versions/v0.4/pages/guides/vlm/gemma4.mdx | 0 .../v0.4/pages/guides/vlm/mistral-medium-3-5.mdx | 0 .../versions/v0.4/pages/guides/vlm/mistralm35.png | Bin .../v0.4/pages/guides/vlm/nemotron-omni.mdx | 0 .../versions/v0.4/pages/guides/vlm/qwen3-5.mdx | 0 .../versions/v0.4/pages/guides/vlm/qwen3_5.png | Bin .../v0.4/pages/guides/vlm/qwen3_5scores.png | Bin {fern => docs/fern}/versions/v0.4/pages/index.mdx | 0 .../v0.4/pages/launcher/local-workstation.mdx | 0 .../fern}/versions/v0.4/pages/launcher/nemo-run.mdx | 0 .../fern}/versions/v0.4/pages/launcher/overview.mdx | 0 .../v0.4/pages/launcher/skypilot-kubernetes.mdx | 0 .../fern}/versions/v0.4/pages/launcher/skypilot.mdx | 0 .../fern}/versions/v0.4/pages/launcher/slurm.mdx | 0 .../diffusion/black-forest-labs/flux.mdx | 0 .../hunyuanvideo-community/hunyuanvideo.mdx | 0 .../v0.4/pages/model-coverage/diffusion/index.mdx | 0 .../model-coverage/diffusion/qwen/qwen-image.mdx | 0 .../model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx | 0 .../v0.4/pages/model-coverage/latest-models.mdx | 0 .../v0.4/pages/model-coverage/llm/allenai/olmo.mdx | 0 .../v0.4/pages/model-coverage/llm/allenai/olmo2.mdx | 0 .../v0.4/pages/model-coverage/llm/allenai/olmoe.mdx | 0 .../v0.4/pages/model-coverage/llm/baai/aquila.mdx | 0 .../model-coverage/llm/baichuan-inc/baichuan.mdx | 0 .../pages/model-coverage/llm/bigcode/starcoder.mdx | 0 .../pages/model-coverage/llm/bigcode/starcoder2.mdx | 0 .../model-coverage/llm/bytedance-seed/seed.mdx | 0 .../pages/model-coverage/llm/cohere/command-r.mdx | 0 .../model-coverage/llm/deepseek-ai/deepseek-v3.mdx | 0 .../model-coverage/llm/deepseek-ai/deepseek.mdx | 0 .../model-coverage/llm/deepseek-ai/dsv4-flash.mdx | 0 .../pages/model-coverage/llm/eleutherai/gpt-j.mdx | 0 .../model-coverage/llm/eleutherai/gpt-neox.mdx | 0 .../v0.4/pages/model-coverage/llm/google/gemma.mdx | 0 .../v0.4/pages/model-coverage/llm/ibm/bamba.mdx | 0 .../pages/model-coverage/llm/ibm/granite-moe.mdx | 0 .../v0.4/pages/model-coverage/llm/ibm/granite.mdx | 0 .../pages/model-coverage/llm/inceptionai/jais.mdx | 0 .../v0.4/pages/model-coverage/llm/index.mdx | 0 .../pages/model-coverage/llm/internlm/internlm.mdx | 0 .../pages/model-coverage/llm/lgai-exaone/exaone.mdx | 0 .../v0.4/pages/model-coverage/llm/meta/llama.mdx | 0 .../v0.4/pages/model-coverage/llm/microsoft/phi.mdx | 0 .../model-coverage/llm/microsoft/phi3-small.mdx | 0 .../pages/model-coverage/llm/microsoft/phi3.mdx | 0 .../pages/model-coverage/llm/minimax/minimax-m2.mdx | 0 .../model-coverage/llm/mistralai/ministral3.mdx | 0 .../pages/model-coverage/llm/mistralai/mistral.mdx | 0 .../pages/model-coverage/llm/mistralai/mixtral.mdx | 0 .../model-coverage/llm/moonshotai/moonlight.mdx | 0 .../model-coverage/llm/nvidia/nemotron-flash.mdx | 0 .../pages/model-coverage/llm/nvidia/nemotron-h.mdx | 0 .../model-coverage/llm/nvidia/nemotron-super.mdx | 0 .../pages/model-coverage/llm/nvidia/nemotron.mdx | 0 .../pages/model-coverage/llm/openai/gpt-oss.mdx | 0 .../v0.4/pages/model-coverage/llm/openai/gpt2.mdx | 0 .../pages/model-coverage/llm/openbmb/minicpm.mdx | 0 .../pages/model-coverage/llm/orionstar/orion.mdx | 0 .../pages/model-coverage/llm/parasail-ai/gritlm.mdx | 0 .../pages/model-coverage/llm/qwen/qwen2-moe.mdx | 0 .../v0.4/pages/model-coverage/llm/qwen/qwen2.mdx | 0 .../pages/model-coverage/llm/qwen/qwen3-moe.mdx | 0 .../pages/model-coverage/llm/qwen/qwen3-next.mdx | 0 .../v0.4/pages/model-coverage/llm/qwen/qwen3.mdx | 0 .../model-coverage/llm/stabilityai/stablelm.mdx | 0 .../model-coverage/llm/stepfun-ai/step-3-5.mdx | 0 .../v0.4/pages/model-coverage/llm/tencent/hy3.mdx | 0 .../v0.4/pages/model-coverage/llm/thudm/chatglm.mdx | 0 .../pages/model-coverage/llm/thudm/glm4-moe.mdx | 0 .../v0.4/pages/model-coverage/llm/thudm/glm4.mdx | 0 .../pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx | 0 .../v0.4/pages/model-coverage/llm/tiiuae/falcon.mdx | 0 .../v0.4/pages/model-coverage/llm/upstage/solar.mdx | 0 .../v0.4/pages/model-coverage/omni/index.mdx | 0 .../omni/microsoft/phi4-multimodal.mdx | 0 .../model-coverage/omni/nvidia/nemotron-omni.mdx | 0 .../pages/model-coverage/omni/qwen/qwen3-omni.mdx | 0 .../versions/v0.4/pages/model-coverage/overview.mdx | 0 .../v0.4/pages/model-coverage/troubleshooting.mdx | 0 .../pages/model-coverage/vlm/google/gemma3-vl.mdx | 0 .../v0.4/pages/model-coverage/vlm/google/gemma4.mdx | 0 .../model-coverage/vlm/huggingface/smolvlm.mdx | 0 .../v0.4/pages/model-coverage/vlm/index.mdx | 0 .../pages/model-coverage/vlm/internlm/internvl.mdx | 0 .../pages/model-coverage/vlm/llava-hf/llava.mdx | 0 .../model-coverage/vlm/lmms-lab/llava-onevision.mdx | 0 .../v0.4/pages/model-coverage/vlm/meta/llama4.mdx | 0 .../model-coverage/vlm/mistralai/ministral3-vl.mdx | 0 .../vlm/mistralai/mistral-medium-3-5.mdx | 0 .../vlm/mistralai/mistral-small-4.mdx | 0 .../pages/model-coverage/vlm/moonshotai/kimi-vl.mdx | 0 .../model-coverage/vlm/nvidia/nemotron-parse.mdx | 0 .../pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx | 0 .../pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx | 0 .../v0.4/pages/model-coverage/vlm/qwen/qwen3-vl.mdx | 0 .../versions/v0.4/pages/performance-summary.mdx | 0 .../versions/v0.4/pages/repository-structure.mdx | 0 316 files changed, 9 insertions(+), 10 deletions(-) rename {fern => docs/fern}/Makefile (100%) rename {fern => docs/fern}/README.md (100%) rename {fern => docs/fern}/assets/NVIDIA_dark.svg (100%) rename {fern => docs/fern}/assets/NVIDIA_light.svg (100%) rename {fern => docs/fern}/assets/NVIDIA_symbol.svg (100%) rename {fern => docs/fern}/components/BadgeLinks.tsx (100%) rename {fern => docs/fern}/components/CustomFooter.tsx (100%) rename {fern => docs/fern}/components/Tag.tsx (100%) rename {fern => docs/fern}/docs.yml (100%) rename {fern => docs/fern}/fern.config.json (100%) rename {fern => docs/fern}/main.css (100%) rename {fern => docs/fern}/versions/latest.yml (100%) rename {fern => docs/fern}/versions/nightly.yml (100%) rename {fern => docs/fern}/versions/nightly/pages/about/index.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/about/key-features.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/announcements.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/api-reference/index.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/automodel_diagram.png (100%) rename {fern => docs/fern}/versions/nightly/pages/breaking-changes.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/documentation.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/audio/qwen_omni_asr.png (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/checkpointing.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/configuration.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/dataset-overview.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/diffusion/dataset.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/diffusion/finetune.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/dllm/finetune.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/fp8-training.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/fp8_convergence.jpg (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/gradient-checkpointing.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/huggingface-api-compatibility.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/installation.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/databricks-gpu-metrics-multi.png (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/databricks-gpu-metrics-single.png (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/databricks.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/dataset.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/dsv4-flash.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/finetune.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/functiongemma-peft-loss.png (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/functiongemma-sft-loss.png (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/gpt2_loss.png (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/hy3.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/knowledge-distillation.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/large-moe-finetune.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/nanogpt-pretraining.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/pretraining.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/retrieval-dataset.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/sequence-classification.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/llm/toolcalling.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/mlflow-logging.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/omni/gemma3-3n.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/omni/medpix.jpg (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/omni/medpix_peft.jpg (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/overview.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/pipelining.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/quantization-aware-training.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/vlm/dataset.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/vlm/gemma4.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/vlm/mistral-medium-3-5.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/vlm/mistralm35.png (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/vlm/nemotron-omni.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/vlm/qwen3-5.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/vlm/qwen3_5.png (100%) rename {fern => docs/fern}/versions/nightly/pages/guides/vlm/qwen3_5scores.png (100%) rename {fern => docs/fern}/versions/nightly/pages/index.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/launcher/local-workstation.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/launcher/nemo-run.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/launcher/overview.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/launcher/skypilot-kubernetes.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/launcher/skypilot.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/launcher/slurm.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/diffusion/index.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/embedding/index.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/latest-models.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/allenai/olmo.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/allenai/olmo2.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/allenai/olmoe.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/baai/aquila.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/bigcode/starcoder.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/cohere/command-r.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/google/gemma.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/ibm/bamba.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/ibm/granite-moe.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/ibm/granite.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/inceptionai/jais.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/index.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/internlm/internlm.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/meta/llama.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/microsoft/phi.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/microsoft/phi3.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/mistralai/ministral3.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/mistralai/mistral.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/mistralai/mixtral.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/nvidia/nemotron.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/openai/gpt-oss.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/openai/gpt2.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/openbmb/minicpm.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/orionstar/orion.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/qwen/qwen2.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/qwen/qwen3.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/tencent/hy3.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/thudm/chatglm.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/thudm/glm4.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/tiiuae/falcon.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/upstage/solar.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/omni/index.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/overview.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/reranker/index.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/troubleshooting.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/google/gemma4.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/index.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/internlm/internvl.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/llava-hf/llava.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/meta/llama4.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/performance-summary.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/release-notes.mdx (100%) rename {fern => docs/fern}/versions/nightly/pages/repository-structure.mdx (100%) rename {fern => docs/fern}/versions/v0.4.yml (100%) rename {fern => docs/fern}/versions/v0.4/pages/about/index.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/about/key-features.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/announcements.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/api-reference/index.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/automodel_diagram.png (100%) rename {fern => docs/fern}/versions/v0.4/pages/breaking-changes.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/documentation.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/checkpointing.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/configuration.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/dataset-overview.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/diffusion/dataset.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/diffusion/finetune.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/dllm/finetune.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/fp8-training.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/fp8_convergence.jpg (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/gradient-checkpointing.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/huggingface-api-compatibility.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/installation.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-dataset.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-multi.png (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-single.png (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/databricks.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/dataset.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/dsv4-flash.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/finetune.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/functiongemma-peft-loss.png (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/functiongemma-sft-loss.png (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/gpt2_loss.png (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/hy3.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/knowledge-distillation.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/large-moe-finetune.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/nanogpt-pretraining.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/pretraining.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/retrieval-dataset.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/sequence-classification.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/llm/toolcalling.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/mlflow-logging.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/omni/gemma3-3n.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/omni/medpix.jpg (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/omni/medpix_peft.jpg (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/overview.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/pipelining.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/quantization-aware-training.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/vlm/dataset.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/vlm/gemma4.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/vlm/mistral-medium-3-5.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/vlm/mistralm35.png (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/vlm/nemotron-omni.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/vlm/qwen3-5.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/vlm/qwen3_5.png (100%) rename {fern => docs/fern}/versions/v0.4/pages/guides/vlm/qwen3_5scores.png (100%) rename {fern => docs/fern}/versions/v0.4/pages/index.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/launcher/local-workstation.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/launcher/nemo-run.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/launcher/overview.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/launcher/skypilot-kubernetes.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/launcher/skypilot.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/launcher/slurm.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/diffusion/black-forest-labs/flux.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/diffusion/index.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/diffusion/qwen/qwen-image.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/latest-models.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/allenai/olmo.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/allenai/olmo2.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/allenai/olmoe.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/baai/aquila.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/baichuan-inc/baichuan.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder2.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/bytedance-seed/seed.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/cohere/command-r.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-j.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-neox.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/google/gemma.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/ibm/bamba.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/ibm/granite-moe.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/ibm/granite.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/inceptionai/jais.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/index.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/internlm/internlm.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/lgai-exaone/exaone.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/meta/llama.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/microsoft/phi.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/microsoft/phi3-small.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/microsoft/phi3.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/minimax/minimax-m2.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/mistralai/ministral3.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/mistralai/mistral.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/mistralai/mixtral.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/moonshotai/moonlight.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-flash.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-h.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-super.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/openai/gpt-oss.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/openai/gpt2.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/openbmb/minicpm.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/orionstar/orion.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/parasail-ai/gritlm.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/qwen/qwen2-moe.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/qwen/qwen2.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-moe.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-next.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/qwen/qwen3.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/stabilityai/stablelm.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/tencent/hy3.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/thudm/chatglm.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/thudm/glm4-moe.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/thudm/glm4.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/tiiuae/falcon.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/llm/upstage/solar.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/omni/index.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/omni/nvidia/nemotron-omni.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/omni/qwen/qwen3-omni.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/overview.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/troubleshooting.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/google/gemma3-vl.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/google/gemma4.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/huggingface/smolvlm.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/index.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/internlm/internvl.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/llava-hf/llava.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/meta/llama4.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-vl.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/performance-summary.mdx (100%) rename {fern => docs/fern}/versions/v0.4/pages/repository-structure.mdx (100%) diff --git a/.github/workflows/fern-docs-ci.yml b/.github/workflows/fern-docs-ci.yml index ecc67c1187..89bb98d0c9 100644 --- a/.github/workflows/fern-docs-ci.yml +++ b/.github/workflows/fern-docs-ci.yml @@ -25,7 +25,7 @@ on: branches: - "pull-request/[0-9]+" paths: - - 'fern/**' + - 'docs/fern/**' - '.github/workflows/fern-docs-ci.yml' permissions: @@ -47,5 +47,5 @@ jobs: run: npm install -g fern-api - name: Validate Fern configuration - working-directory: ./fern + working-directory: ./docs/fern run: fern check diff --git a/.github/workflows/fern-docs-preview-build.yml b/.github/workflows/fern-docs-preview-build.yml index 5423f7cccc..e7ee714f9f 100644 --- a/.github/workflows/fern-docs-preview-build.yml +++ b/.github/workflows/fern-docs-preview-build.yml @@ -15,7 +15,7 @@ # Workflow 1 of 2 for Fern doc previews. # -# Collects the fern/ sources and PR metadata from the (possibly untrusted) PR +# Collects the docs/fern/ sources and PR metadata from the (possibly untrusted) PR # branch and uploads them as an artifact. No secrets are used here, so this is # safe to run on fork PRs via the regular pull_request trigger. # @@ -27,7 +27,7 @@ name: "Preview Fern Docs: Build" on: pull_request: paths: - - 'fern/**' + - 'docs/fern/**' - '.github/workflows/fern-docs-preview-build.yml' permissions: @@ -58,6 +58,6 @@ jobs: with: name: fern-preview path: | - fern/ + docs/fern/ preview-metadata/ retention-days: 1 diff --git a/.github/workflows/fern-docs-preview-comment.yml b/.github/workflows/fern-docs-preview-comment.yml index 411bb53940..1bc40f6cf4 100644 --- a/.github/workflows/fern-docs-preview-comment.yml +++ b/.github/workflows/fern-docs-preview-comment.yml @@ -16,7 +16,7 @@ # Workflow 2 of 2 for Fern doc previews. # # Triggered by workflow_run after "Preview Fern Docs: Build" completes. -# Downloads the fern/ artifact, builds a preview with DOCS_FERN_TOKEN, and +# Downloads the docs/fern/ artifact, builds a preview with DOCS_FERN_TOKEN, and # posts a stable :herb: comment on the PR. This workflow never checks out the # PR branch directly, keeping secrets isolated from untrusted code. # @@ -65,7 +65,7 @@ jobs: env: FERN_TOKEN: ${{ secrets.DOCS_FERN_TOKEN }} HEAD_REF: ${{ steps.metadata.outputs.head_ref }} - working-directory: ./fern + working-directory: ./docs/fern run: | OUTPUT=$(fern generate --docs --preview --id "$HEAD_REF" 2>&1) echo "$OUTPUT" diff --git a/.github/workflows/publish-fern-docs.yml b/.github/workflows/publish-fern-docs.yml index 4204e55e55..cfec75784e 100644 --- a/.github/workflows/publish-fern-docs.yml +++ b/.github/workflows/publish-fern-docs.yml @@ -29,7 +29,6 @@ on: - main paths: - 'docs/**' - - 'fern/**' tags: - 'docs/v*' workflow_dispatch: {} @@ -59,5 +58,5 @@ jobs: - name: Publish Docs env: FERN_TOKEN: ${{ secrets.DOCS_FERN_TOKEN }} - working-directory: ./fern + working-directory: ./docs/fern run: fern generate --docs diff --git a/.gitignore b/.gitignore index 298ad67da4..7cdf3b9db2 100644 --- a/.gitignore +++ b/.gitignore @@ -186,6 +186,6 @@ skypilot_jobs/ # Fern: generated library reference (regenerated by `fern docs md generate` # during preview / publish — not committed) -fern/product-docs/ +docs/fern/product-docs/ training_logs/ diff --git a/fern/Makefile b/docs/fern/Makefile similarity index 100% rename from fern/Makefile rename to docs/fern/Makefile diff --git a/fern/README.md b/docs/fern/README.md similarity index 100% rename from fern/README.md rename to docs/fern/README.md diff --git a/fern/assets/NVIDIA_dark.svg b/docs/fern/assets/NVIDIA_dark.svg similarity index 100% rename from fern/assets/NVIDIA_dark.svg rename to docs/fern/assets/NVIDIA_dark.svg diff --git a/fern/assets/NVIDIA_light.svg b/docs/fern/assets/NVIDIA_light.svg similarity index 100% rename from fern/assets/NVIDIA_light.svg rename to docs/fern/assets/NVIDIA_light.svg diff --git a/fern/assets/NVIDIA_symbol.svg b/docs/fern/assets/NVIDIA_symbol.svg similarity index 100% rename from fern/assets/NVIDIA_symbol.svg rename to docs/fern/assets/NVIDIA_symbol.svg diff --git a/fern/components/BadgeLinks.tsx b/docs/fern/components/BadgeLinks.tsx similarity index 100% rename from fern/components/BadgeLinks.tsx rename to docs/fern/components/BadgeLinks.tsx diff --git a/fern/components/CustomFooter.tsx b/docs/fern/components/CustomFooter.tsx similarity index 100% rename from fern/components/CustomFooter.tsx rename to docs/fern/components/CustomFooter.tsx diff --git a/fern/components/Tag.tsx b/docs/fern/components/Tag.tsx similarity index 100% rename from fern/components/Tag.tsx rename to docs/fern/components/Tag.tsx diff --git a/fern/docs.yml b/docs/fern/docs.yml similarity index 100% rename from fern/docs.yml rename to docs/fern/docs.yml diff --git a/fern/fern.config.json b/docs/fern/fern.config.json similarity index 100% rename from fern/fern.config.json rename to docs/fern/fern.config.json diff --git a/fern/main.css b/docs/fern/main.css similarity index 100% rename from fern/main.css rename to docs/fern/main.css diff --git a/fern/versions/latest.yml b/docs/fern/versions/latest.yml similarity index 100% rename from fern/versions/latest.yml rename to docs/fern/versions/latest.yml diff --git a/fern/versions/nightly.yml b/docs/fern/versions/nightly.yml similarity index 100% rename from fern/versions/nightly.yml rename to docs/fern/versions/nightly.yml diff --git a/fern/versions/nightly/pages/about/index.mdx b/docs/fern/versions/nightly/pages/about/index.mdx similarity index 100% rename from fern/versions/nightly/pages/about/index.mdx rename to docs/fern/versions/nightly/pages/about/index.mdx diff --git a/fern/versions/nightly/pages/about/key-features.mdx b/docs/fern/versions/nightly/pages/about/key-features.mdx similarity index 100% rename from fern/versions/nightly/pages/about/key-features.mdx rename to docs/fern/versions/nightly/pages/about/key-features.mdx diff --git a/fern/versions/nightly/pages/announcements.mdx b/docs/fern/versions/nightly/pages/announcements.mdx similarity index 100% rename from fern/versions/nightly/pages/announcements.mdx rename to docs/fern/versions/nightly/pages/announcements.mdx diff --git a/fern/versions/nightly/pages/api-reference/index.mdx b/docs/fern/versions/nightly/pages/api-reference/index.mdx similarity index 100% rename from fern/versions/nightly/pages/api-reference/index.mdx rename to docs/fern/versions/nightly/pages/api-reference/index.mdx diff --git a/fern/versions/nightly/pages/automodel_diagram.png b/docs/fern/versions/nightly/pages/automodel_diagram.png similarity index 100% rename from fern/versions/nightly/pages/automodel_diagram.png rename to docs/fern/versions/nightly/pages/automodel_diagram.png diff --git a/fern/versions/nightly/pages/breaking-changes.mdx b/docs/fern/versions/nightly/pages/breaking-changes.mdx similarity index 100% rename from fern/versions/nightly/pages/breaking-changes.mdx rename to docs/fern/versions/nightly/pages/breaking-changes.mdx diff --git a/fern/versions/nightly/pages/documentation.mdx b/docs/fern/versions/nightly/pages/documentation.mdx similarity index 100% rename from fern/versions/nightly/pages/documentation.mdx rename to docs/fern/versions/nightly/pages/documentation.mdx diff --git a/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx b/docs/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx rename to docs/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx diff --git a/fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png b/docs/fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png similarity index 100% rename from fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png rename to docs/fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png diff --git a/fern/versions/nightly/pages/guides/checkpointing.mdx b/docs/fern/versions/nightly/pages/guides/checkpointing.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/checkpointing.mdx rename to docs/fern/versions/nightly/pages/guides/checkpointing.mdx diff --git a/fern/versions/nightly/pages/guides/configuration.mdx b/docs/fern/versions/nightly/pages/guides/configuration.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/configuration.mdx rename to docs/fern/versions/nightly/pages/guides/configuration.mdx diff --git a/fern/versions/nightly/pages/guides/dataset-overview.mdx b/docs/fern/versions/nightly/pages/guides/dataset-overview.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/dataset-overview.mdx rename to docs/fern/versions/nightly/pages/guides/dataset-overview.mdx diff --git a/fern/versions/nightly/pages/guides/diffusion/dataset.mdx b/docs/fern/versions/nightly/pages/guides/diffusion/dataset.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/diffusion/dataset.mdx rename to docs/fern/versions/nightly/pages/guides/diffusion/dataset.mdx diff --git a/fern/versions/nightly/pages/guides/diffusion/finetune.mdx b/docs/fern/versions/nightly/pages/guides/diffusion/finetune.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/diffusion/finetune.mdx rename to docs/fern/versions/nightly/pages/guides/diffusion/finetune.mdx diff --git a/fern/versions/nightly/pages/guides/dllm/finetune.mdx b/docs/fern/versions/nightly/pages/guides/dllm/finetune.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/dllm/finetune.mdx rename to docs/fern/versions/nightly/pages/guides/dllm/finetune.mdx diff --git a/fern/versions/nightly/pages/guides/fp8-training.mdx b/docs/fern/versions/nightly/pages/guides/fp8-training.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/fp8-training.mdx rename to docs/fern/versions/nightly/pages/guides/fp8-training.mdx diff --git a/fern/versions/nightly/pages/guides/fp8_convergence.jpg b/docs/fern/versions/nightly/pages/guides/fp8_convergence.jpg similarity index 100% rename from fern/versions/nightly/pages/guides/fp8_convergence.jpg rename to docs/fern/versions/nightly/pages/guides/fp8_convergence.jpg diff --git a/fern/versions/nightly/pages/guides/gradient-checkpointing.mdx b/docs/fern/versions/nightly/pages/guides/gradient-checkpointing.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/gradient-checkpointing.mdx rename to docs/fern/versions/nightly/pages/guides/gradient-checkpointing.mdx diff --git a/fern/versions/nightly/pages/guides/huggingface-api-compatibility.mdx b/docs/fern/versions/nightly/pages/guides/huggingface-api-compatibility.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/huggingface-api-compatibility.mdx rename to docs/fern/versions/nightly/pages/guides/huggingface-api-compatibility.mdx diff --git a/fern/versions/nightly/pages/guides/installation.mdx b/docs/fern/versions/nightly/pages/guides/installation.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/installation.mdx rename to docs/fern/versions/nightly/pages/guides/installation.mdx diff --git a/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx b/docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx rename to docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx diff --git a/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx b/docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx rename to docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx diff --git a/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-multi.png b/docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-multi.png similarity index 100% rename from fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-multi.png rename to docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-multi.png diff --git a/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-single.png b/docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-single.png similarity index 100% rename from fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-single.png rename to docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-single.png diff --git a/fern/versions/nightly/pages/guides/llm/databricks.mdx b/docs/fern/versions/nightly/pages/guides/llm/databricks.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/databricks.mdx rename to docs/fern/versions/nightly/pages/guides/llm/databricks.mdx diff --git a/fern/versions/nightly/pages/guides/llm/dataset.mdx b/docs/fern/versions/nightly/pages/guides/llm/dataset.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/dataset.mdx rename to docs/fern/versions/nightly/pages/guides/llm/dataset.mdx diff --git a/fern/versions/nightly/pages/guides/llm/dsv4-flash.mdx b/docs/fern/versions/nightly/pages/guides/llm/dsv4-flash.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/dsv4-flash.mdx rename to docs/fern/versions/nightly/pages/guides/llm/dsv4-flash.mdx diff --git a/fern/versions/nightly/pages/guides/llm/finetune.mdx b/docs/fern/versions/nightly/pages/guides/llm/finetune.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/finetune.mdx rename to docs/fern/versions/nightly/pages/guides/llm/finetune.mdx diff --git a/fern/versions/nightly/pages/guides/llm/functiongemma-peft-loss.png b/docs/fern/versions/nightly/pages/guides/llm/functiongemma-peft-loss.png similarity index 100% rename from fern/versions/nightly/pages/guides/llm/functiongemma-peft-loss.png rename to docs/fern/versions/nightly/pages/guides/llm/functiongemma-peft-loss.png diff --git a/fern/versions/nightly/pages/guides/llm/functiongemma-sft-loss.png b/docs/fern/versions/nightly/pages/guides/llm/functiongemma-sft-loss.png similarity index 100% rename from fern/versions/nightly/pages/guides/llm/functiongemma-sft-loss.png rename to docs/fern/versions/nightly/pages/guides/llm/functiongemma-sft-loss.png diff --git a/fern/versions/nightly/pages/guides/llm/gpt2_loss.png b/docs/fern/versions/nightly/pages/guides/llm/gpt2_loss.png similarity index 100% rename from fern/versions/nightly/pages/guides/llm/gpt2_loss.png rename to docs/fern/versions/nightly/pages/guides/llm/gpt2_loss.png diff --git a/fern/versions/nightly/pages/guides/llm/hy3.mdx b/docs/fern/versions/nightly/pages/guides/llm/hy3.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/hy3.mdx rename to docs/fern/versions/nightly/pages/guides/llm/hy3.mdx diff --git a/fern/versions/nightly/pages/guides/llm/knowledge-distillation.mdx b/docs/fern/versions/nightly/pages/guides/llm/knowledge-distillation.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/knowledge-distillation.mdx rename to docs/fern/versions/nightly/pages/guides/llm/knowledge-distillation.mdx diff --git a/fern/versions/nightly/pages/guides/llm/large-moe-finetune.mdx b/docs/fern/versions/nightly/pages/guides/llm/large-moe-finetune.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/large-moe-finetune.mdx rename to docs/fern/versions/nightly/pages/guides/llm/large-moe-finetune.mdx diff --git a/fern/versions/nightly/pages/guides/llm/nanogpt-pretraining.mdx b/docs/fern/versions/nightly/pages/guides/llm/nanogpt-pretraining.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/nanogpt-pretraining.mdx rename to docs/fern/versions/nightly/pages/guides/llm/nanogpt-pretraining.mdx diff --git a/fern/versions/nightly/pages/guides/llm/pretraining.mdx b/docs/fern/versions/nightly/pages/guides/llm/pretraining.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/pretraining.mdx rename to docs/fern/versions/nightly/pages/guides/llm/pretraining.mdx diff --git a/fern/versions/nightly/pages/guides/llm/retrieval-dataset.mdx b/docs/fern/versions/nightly/pages/guides/llm/retrieval-dataset.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/retrieval-dataset.mdx rename to docs/fern/versions/nightly/pages/guides/llm/retrieval-dataset.mdx diff --git a/fern/versions/nightly/pages/guides/llm/sequence-classification.mdx b/docs/fern/versions/nightly/pages/guides/llm/sequence-classification.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/sequence-classification.mdx rename to docs/fern/versions/nightly/pages/guides/llm/sequence-classification.mdx diff --git a/fern/versions/nightly/pages/guides/llm/toolcalling.mdx b/docs/fern/versions/nightly/pages/guides/llm/toolcalling.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/llm/toolcalling.mdx rename to docs/fern/versions/nightly/pages/guides/llm/toolcalling.mdx diff --git a/fern/versions/nightly/pages/guides/mlflow-logging.mdx b/docs/fern/versions/nightly/pages/guides/mlflow-logging.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/mlflow-logging.mdx rename to docs/fern/versions/nightly/pages/guides/mlflow-logging.mdx diff --git a/fern/versions/nightly/pages/guides/omni/gemma3-3n.mdx b/docs/fern/versions/nightly/pages/guides/omni/gemma3-3n.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/omni/gemma3-3n.mdx rename to docs/fern/versions/nightly/pages/guides/omni/gemma3-3n.mdx diff --git a/fern/versions/nightly/pages/guides/omni/medpix.jpg b/docs/fern/versions/nightly/pages/guides/omni/medpix.jpg similarity index 100% rename from fern/versions/nightly/pages/guides/omni/medpix.jpg rename to docs/fern/versions/nightly/pages/guides/omni/medpix.jpg diff --git a/fern/versions/nightly/pages/guides/omni/medpix_peft.jpg b/docs/fern/versions/nightly/pages/guides/omni/medpix_peft.jpg similarity index 100% rename from fern/versions/nightly/pages/guides/omni/medpix_peft.jpg rename to docs/fern/versions/nightly/pages/guides/omni/medpix_peft.jpg diff --git a/fern/versions/nightly/pages/guides/overview.mdx b/docs/fern/versions/nightly/pages/guides/overview.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/overview.mdx rename to docs/fern/versions/nightly/pages/guides/overview.mdx diff --git a/fern/versions/nightly/pages/guides/pipelining.mdx b/docs/fern/versions/nightly/pages/guides/pipelining.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/pipelining.mdx rename to docs/fern/versions/nightly/pages/guides/pipelining.mdx diff --git a/fern/versions/nightly/pages/guides/quantization-aware-training.mdx b/docs/fern/versions/nightly/pages/guides/quantization-aware-training.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/quantization-aware-training.mdx rename to docs/fern/versions/nightly/pages/guides/quantization-aware-training.mdx diff --git a/fern/versions/nightly/pages/guides/vlm/dataset.mdx b/docs/fern/versions/nightly/pages/guides/vlm/dataset.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/vlm/dataset.mdx rename to docs/fern/versions/nightly/pages/guides/vlm/dataset.mdx diff --git a/fern/versions/nightly/pages/guides/vlm/gemma4.mdx b/docs/fern/versions/nightly/pages/guides/vlm/gemma4.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/vlm/gemma4.mdx rename to docs/fern/versions/nightly/pages/guides/vlm/gemma4.mdx diff --git a/fern/versions/nightly/pages/guides/vlm/mistral-medium-3-5.mdx b/docs/fern/versions/nightly/pages/guides/vlm/mistral-medium-3-5.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/vlm/mistral-medium-3-5.mdx rename to docs/fern/versions/nightly/pages/guides/vlm/mistral-medium-3-5.mdx diff --git a/fern/versions/nightly/pages/guides/vlm/mistralm35.png b/docs/fern/versions/nightly/pages/guides/vlm/mistralm35.png similarity index 100% rename from fern/versions/nightly/pages/guides/vlm/mistralm35.png rename to docs/fern/versions/nightly/pages/guides/vlm/mistralm35.png diff --git a/fern/versions/nightly/pages/guides/vlm/nemotron-omni.mdx b/docs/fern/versions/nightly/pages/guides/vlm/nemotron-omni.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/vlm/nemotron-omni.mdx rename to docs/fern/versions/nightly/pages/guides/vlm/nemotron-omni.mdx diff --git a/fern/versions/nightly/pages/guides/vlm/qwen3-5.mdx b/docs/fern/versions/nightly/pages/guides/vlm/qwen3-5.mdx similarity index 100% rename from fern/versions/nightly/pages/guides/vlm/qwen3-5.mdx rename to docs/fern/versions/nightly/pages/guides/vlm/qwen3-5.mdx diff --git a/fern/versions/nightly/pages/guides/vlm/qwen3_5.png b/docs/fern/versions/nightly/pages/guides/vlm/qwen3_5.png similarity index 100% rename from fern/versions/nightly/pages/guides/vlm/qwen3_5.png rename to docs/fern/versions/nightly/pages/guides/vlm/qwen3_5.png diff --git a/fern/versions/nightly/pages/guides/vlm/qwen3_5scores.png b/docs/fern/versions/nightly/pages/guides/vlm/qwen3_5scores.png similarity index 100% rename from fern/versions/nightly/pages/guides/vlm/qwen3_5scores.png rename to docs/fern/versions/nightly/pages/guides/vlm/qwen3_5scores.png diff --git a/fern/versions/nightly/pages/index.mdx b/docs/fern/versions/nightly/pages/index.mdx similarity index 100% rename from fern/versions/nightly/pages/index.mdx rename to docs/fern/versions/nightly/pages/index.mdx diff --git a/fern/versions/nightly/pages/launcher/local-workstation.mdx b/docs/fern/versions/nightly/pages/launcher/local-workstation.mdx similarity index 100% rename from fern/versions/nightly/pages/launcher/local-workstation.mdx rename to docs/fern/versions/nightly/pages/launcher/local-workstation.mdx diff --git a/fern/versions/nightly/pages/launcher/nemo-run.mdx b/docs/fern/versions/nightly/pages/launcher/nemo-run.mdx similarity index 100% rename from fern/versions/nightly/pages/launcher/nemo-run.mdx rename to docs/fern/versions/nightly/pages/launcher/nemo-run.mdx diff --git a/fern/versions/nightly/pages/launcher/overview.mdx b/docs/fern/versions/nightly/pages/launcher/overview.mdx similarity index 100% rename from fern/versions/nightly/pages/launcher/overview.mdx rename to docs/fern/versions/nightly/pages/launcher/overview.mdx diff --git a/fern/versions/nightly/pages/launcher/skypilot-kubernetes.mdx b/docs/fern/versions/nightly/pages/launcher/skypilot-kubernetes.mdx similarity index 100% rename from fern/versions/nightly/pages/launcher/skypilot-kubernetes.mdx rename to docs/fern/versions/nightly/pages/launcher/skypilot-kubernetes.mdx diff --git a/fern/versions/nightly/pages/launcher/skypilot.mdx b/docs/fern/versions/nightly/pages/launcher/skypilot.mdx similarity index 100% rename from fern/versions/nightly/pages/launcher/skypilot.mdx rename to docs/fern/versions/nightly/pages/launcher/skypilot.mdx diff --git a/fern/versions/nightly/pages/launcher/slurm.mdx b/docs/fern/versions/nightly/pages/launcher/slurm.mdx similarity index 100% rename from fern/versions/nightly/pages/launcher/slurm.mdx rename to docs/fern/versions/nightly/pages/launcher/slurm.mdx diff --git a/fern/versions/nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx rename to docs/fern/versions/nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx diff --git a/fern/versions/nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx rename to docs/fern/versions/nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx diff --git a/fern/versions/nightly/pages/model-coverage/diffusion/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/index.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/diffusion/index.mdx rename to docs/fern/versions/nightly/pages/model-coverage/diffusion/index.mdx diff --git a/fern/versions/nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx rename to docs/fern/versions/nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx diff --git a/fern/versions/nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx rename to docs/fern/versions/nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx diff --git a/fern/versions/nightly/pages/model-coverage/embedding/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/embedding/index.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/embedding/index.mdx rename to docs/fern/versions/nightly/pages/model-coverage/embedding/index.mdx diff --git a/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx b/docs/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx rename to docs/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx diff --git a/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx b/docs/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx rename to docs/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx diff --git a/fern/versions/nightly/pages/model-coverage/latest-models.mdx b/docs/fern/versions/nightly/pages/model-coverage/latest-models.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/latest-models.mdx rename to docs/fern/versions/nightly/pages/model-coverage/latest-models.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/allenai/olmo.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo2.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/allenai/olmo2.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo2.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/allenai/olmoe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmoe.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/allenai/olmoe.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmoe.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/baai/aquila.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/baai/aquila.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/baai/aquila.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/baai/aquila.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/cohere/command-r.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/cohere/command-r.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/cohere/command-r.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/cohere/command-r.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/google/gemma.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/google/gemma.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/google/gemma.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/google/gemma.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/ibm/bamba.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/bamba.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/ibm/bamba.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/ibm/bamba.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/ibm/granite-moe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite-moe.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/ibm/granite-moe.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite-moe.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/ibm/granite.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/ibm/granite.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/inceptionai/jais.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/inceptionai/jais.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/inceptionai/jais.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/inceptionai/jais.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/index.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/index.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/index.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/internlm/internlm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/internlm/internlm.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/internlm/internlm.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/internlm/internlm.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/meta/llama.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/meta/llama.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/meta/llama.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/meta/llama.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/microsoft/phi.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/mistralai/ministral3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/ministral3.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/mistralai/ministral3.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/ministral3.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/mistralai/mistral.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mistral.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/mistralai/mistral.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mistral.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/mistralai/mixtral.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mixtral.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/mistralai/mixtral.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mixtral.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/openai/gpt-oss.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt-oss.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/openai/gpt-oss.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt-oss.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/openai/gpt2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt2.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/openai/gpt2.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt2.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/openbmb/minicpm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/openbmb/minicpm.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/openbmb/minicpm.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/openbmb/minicpm.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/orionstar/orion.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/orionstar/orion.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/orionstar/orion.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/orionstar/orion.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/tencent/hy3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/tencent/hy3.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/tencent/hy3.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/tencent/hy3.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/thudm/chatglm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/chatglm.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/thudm/chatglm.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/thudm/chatglm.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/thudm/glm4.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/tiiuae/falcon.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/tiiuae/falcon.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/tiiuae/falcon.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/tiiuae/falcon.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/upstage/solar.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/upstage/solar.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/upstage/solar.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/upstage/solar.mdx diff --git a/fern/versions/nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx rename to docs/fern/versions/nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx diff --git a/fern/versions/nightly/pages/model-coverage/omni/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/omni/index.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/omni/index.mdx rename to docs/fern/versions/nightly/pages/model-coverage/omni/index.mdx diff --git a/fern/versions/nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx b/docs/fern/versions/nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx rename to docs/fern/versions/nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx diff --git a/fern/versions/nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx b/docs/fern/versions/nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx rename to docs/fern/versions/nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx diff --git a/fern/versions/nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx b/docs/fern/versions/nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx rename to docs/fern/versions/nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx diff --git a/fern/versions/nightly/pages/model-coverage/overview.mdx b/docs/fern/versions/nightly/pages/model-coverage/overview.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/overview.mdx rename to docs/fern/versions/nightly/pages/model-coverage/overview.mdx diff --git a/fern/versions/nightly/pages/model-coverage/reranker/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/reranker/index.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/reranker/index.mdx rename to docs/fern/versions/nightly/pages/model-coverage/reranker/index.mdx diff --git a/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx b/docs/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx rename to docs/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx diff --git a/fern/versions/nightly/pages/model-coverage/troubleshooting.mdx b/docs/fern/versions/nightly/pages/model-coverage/troubleshooting.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/troubleshooting.mdx rename to docs/fern/versions/nightly/pages/model-coverage/troubleshooting.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/google/gemma4.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma4.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/google/gemma4.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma4.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/index.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/index.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/index.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/internlm/internvl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/internlm/internvl.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/internlm/internvl.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/internlm/internvl.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/llava-hf/llava.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/llava-hf/llava.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/llava-hf/llava.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/llava-hf/llava.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/meta/llama4.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/meta/llama4.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/meta/llama4.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/meta/llama4.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx diff --git a/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx similarity index 100% rename from fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx rename to docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx diff --git a/fern/versions/nightly/pages/performance-summary.mdx b/docs/fern/versions/nightly/pages/performance-summary.mdx similarity index 100% rename from fern/versions/nightly/pages/performance-summary.mdx rename to docs/fern/versions/nightly/pages/performance-summary.mdx diff --git a/fern/versions/nightly/pages/release-notes.mdx b/docs/fern/versions/nightly/pages/release-notes.mdx similarity index 100% rename from fern/versions/nightly/pages/release-notes.mdx rename to docs/fern/versions/nightly/pages/release-notes.mdx diff --git a/fern/versions/nightly/pages/repository-structure.mdx b/docs/fern/versions/nightly/pages/repository-structure.mdx similarity index 100% rename from fern/versions/nightly/pages/repository-structure.mdx rename to docs/fern/versions/nightly/pages/repository-structure.mdx diff --git a/fern/versions/v0.4.yml b/docs/fern/versions/v0.4.yml similarity index 100% rename from fern/versions/v0.4.yml rename to docs/fern/versions/v0.4.yml diff --git a/fern/versions/v0.4/pages/about/index.mdx b/docs/fern/versions/v0.4/pages/about/index.mdx similarity index 100% rename from fern/versions/v0.4/pages/about/index.mdx rename to docs/fern/versions/v0.4/pages/about/index.mdx diff --git a/fern/versions/v0.4/pages/about/key-features.mdx b/docs/fern/versions/v0.4/pages/about/key-features.mdx similarity index 100% rename from fern/versions/v0.4/pages/about/key-features.mdx rename to docs/fern/versions/v0.4/pages/about/key-features.mdx diff --git a/fern/versions/v0.4/pages/announcements.mdx b/docs/fern/versions/v0.4/pages/announcements.mdx similarity index 100% rename from fern/versions/v0.4/pages/announcements.mdx rename to docs/fern/versions/v0.4/pages/announcements.mdx diff --git a/fern/versions/v0.4/pages/api-reference/index.mdx b/docs/fern/versions/v0.4/pages/api-reference/index.mdx similarity index 100% rename from fern/versions/v0.4/pages/api-reference/index.mdx rename to docs/fern/versions/v0.4/pages/api-reference/index.mdx diff --git a/fern/versions/v0.4/pages/automodel_diagram.png b/docs/fern/versions/v0.4/pages/automodel_diagram.png similarity index 100% rename from fern/versions/v0.4/pages/automodel_diagram.png rename to docs/fern/versions/v0.4/pages/automodel_diagram.png diff --git a/fern/versions/v0.4/pages/breaking-changes.mdx b/docs/fern/versions/v0.4/pages/breaking-changes.mdx similarity index 100% rename from fern/versions/v0.4/pages/breaking-changes.mdx rename to docs/fern/versions/v0.4/pages/breaking-changes.mdx diff --git a/fern/versions/v0.4/pages/documentation.mdx b/docs/fern/versions/v0.4/pages/documentation.mdx similarity index 100% rename from fern/versions/v0.4/pages/documentation.mdx rename to docs/fern/versions/v0.4/pages/documentation.mdx diff --git a/fern/versions/v0.4/pages/guides/checkpointing.mdx b/docs/fern/versions/v0.4/pages/guides/checkpointing.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/checkpointing.mdx rename to docs/fern/versions/v0.4/pages/guides/checkpointing.mdx diff --git a/fern/versions/v0.4/pages/guides/configuration.mdx b/docs/fern/versions/v0.4/pages/guides/configuration.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/configuration.mdx rename to docs/fern/versions/v0.4/pages/guides/configuration.mdx diff --git a/fern/versions/v0.4/pages/guides/dataset-overview.mdx b/docs/fern/versions/v0.4/pages/guides/dataset-overview.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/dataset-overview.mdx rename to docs/fern/versions/v0.4/pages/guides/dataset-overview.mdx diff --git a/fern/versions/v0.4/pages/guides/diffusion/dataset.mdx b/docs/fern/versions/v0.4/pages/guides/diffusion/dataset.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/diffusion/dataset.mdx rename to docs/fern/versions/v0.4/pages/guides/diffusion/dataset.mdx diff --git a/fern/versions/v0.4/pages/guides/diffusion/finetune.mdx b/docs/fern/versions/v0.4/pages/guides/diffusion/finetune.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/diffusion/finetune.mdx rename to docs/fern/versions/v0.4/pages/guides/diffusion/finetune.mdx diff --git a/fern/versions/v0.4/pages/guides/dllm/finetune.mdx b/docs/fern/versions/v0.4/pages/guides/dllm/finetune.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/dllm/finetune.mdx rename to docs/fern/versions/v0.4/pages/guides/dllm/finetune.mdx diff --git a/fern/versions/v0.4/pages/guides/fp8-training.mdx b/docs/fern/versions/v0.4/pages/guides/fp8-training.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/fp8-training.mdx rename to docs/fern/versions/v0.4/pages/guides/fp8-training.mdx diff --git a/fern/versions/v0.4/pages/guides/fp8_convergence.jpg b/docs/fern/versions/v0.4/pages/guides/fp8_convergence.jpg similarity index 100% rename from fern/versions/v0.4/pages/guides/fp8_convergence.jpg rename to docs/fern/versions/v0.4/pages/guides/fp8_convergence.jpg diff --git a/fern/versions/v0.4/pages/guides/gradient-checkpointing.mdx b/docs/fern/versions/v0.4/pages/guides/gradient-checkpointing.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/gradient-checkpointing.mdx rename to docs/fern/versions/v0.4/pages/guides/gradient-checkpointing.mdx diff --git a/fern/versions/v0.4/pages/guides/huggingface-api-compatibility.mdx b/docs/fern/versions/v0.4/pages/guides/huggingface-api-compatibility.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/huggingface-api-compatibility.mdx rename to docs/fern/versions/v0.4/pages/guides/huggingface-api-compatibility.mdx diff --git a/fern/versions/v0.4/pages/guides/installation.mdx b/docs/fern/versions/v0.4/pages/guides/installation.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/installation.mdx rename to docs/fern/versions/v0.4/pages/guides/installation.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-dataset.mdx b/docs/fern/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-dataset.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-dataset.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-dataset.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx b/docs/fern/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-multi.png b/docs/fern/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-multi.png similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-multi.png rename to docs/fern/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-multi.png diff --git a/fern/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-single.png b/docs/fern/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-single.png similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-single.png rename to docs/fern/versions/v0.4/pages/guides/llm/databricks-gpu-metrics-single.png diff --git a/fern/versions/v0.4/pages/guides/llm/databricks.mdx b/docs/fern/versions/v0.4/pages/guides/llm/databricks.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/databricks.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/databricks.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/dataset.mdx b/docs/fern/versions/v0.4/pages/guides/llm/dataset.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/dataset.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/dataset.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/dsv4-flash.mdx b/docs/fern/versions/v0.4/pages/guides/llm/dsv4-flash.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/dsv4-flash.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/dsv4-flash.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/finetune.mdx b/docs/fern/versions/v0.4/pages/guides/llm/finetune.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/finetune.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/finetune.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/functiongemma-peft-loss.png b/docs/fern/versions/v0.4/pages/guides/llm/functiongemma-peft-loss.png similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/functiongemma-peft-loss.png rename to docs/fern/versions/v0.4/pages/guides/llm/functiongemma-peft-loss.png diff --git a/fern/versions/v0.4/pages/guides/llm/functiongemma-sft-loss.png b/docs/fern/versions/v0.4/pages/guides/llm/functiongemma-sft-loss.png similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/functiongemma-sft-loss.png rename to docs/fern/versions/v0.4/pages/guides/llm/functiongemma-sft-loss.png diff --git a/fern/versions/v0.4/pages/guides/llm/gpt2_loss.png b/docs/fern/versions/v0.4/pages/guides/llm/gpt2_loss.png similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/gpt2_loss.png rename to docs/fern/versions/v0.4/pages/guides/llm/gpt2_loss.png diff --git a/fern/versions/v0.4/pages/guides/llm/hy3.mdx b/docs/fern/versions/v0.4/pages/guides/llm/hy3.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/hy3.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/hy3.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/knowledge-distillation.mdx b/docs/fern/versions/v0.4/pages/guides/llm/knowledge-distillation.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/knowledge-distillation.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/knowledge-distillation.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/large-moe-finetune.mdx b/docs/fern/versions/v0.4/pages/guides/llm/large-moe-finetune.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/large-moe-finetune.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/large-moe-finetune.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/nanogpt-pretraining.mdx b/docs/fern/versions/v0.4/pages/guides/llm/nanogpt-pretraining.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/nanogpt-pretraining.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/nanogpt-pretraining.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/pretraining.mdx b/docs/fern/versions/v0.4/pages/guides/llm/pretraining.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/pretraining.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/pretraining.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/retrieval-dataset.mdx b/docs/fern/versions/v0.4/pages/guides/llm/retrieval-dataset.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/retrieval-dataset.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/retrieval-dataset.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/sequence-classification.mdx b/docs/fern/versions/v0.4/pages/guides/llm/sequence-classification.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/sequence-classification.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/sequence-classification.mdx diff --git a/fern/versions/v0.4/pages/guides/llm/toolcalling.mdx b/docs/fern/versions/v0.4/pages/guides/llm/toolcalling.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/llm/toolcalling.mdx rename to docs/fern/versions/v0.4/pages/guides/llm/toolcalling.mdx diff --git a/fern/versions/v0.4/pages/guides/mlflow-logging.mdx b/docs/fern/versions/v0.4/pages/guides/mlflow-logging.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/mlflow-logging.mdx rename to docs/fern/versions/v0.4/pages/guides/mlflow-logging.mdx diff --git a/fern/versions/v0.4/pages/guides/omni/gemma3-3n.mdx b/docs/fern/versions/v0.4/pages/guides/omni/gemma3-3n.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/omni/gemma3-3n.mdx rename to docs/fern/versions/v0.4/pages/guides/omni/gemma3-3n.mdx diff --git a/fern/versions/v0.4/pages/guides/omni/medpix.jpg b/docs/fern/versions/v0.4/pages/guides/omni/medpix.jpg similarity index 100% rename from fern/versions/v0.4/pages/guides/omni/medpix.jpg rename to docs/fern/versions/v0.4/pages/guides/omni/medpix.jpg diff --git a/fern/versions/v0.4/pages/guides/omni/medpix_peft.jpg b/docs/fern/versions/v0.4/pages/guides/omni/medpix_peft.jpg similarity index 100% rename from fern/versions/v0.4/pages/guides/omni/medpix_peft.jpg rename to docs/fern/versions/v0.4/pages/guides/omni/medpix_peft.jpg diff --git a/fern/versions/v0.4/pages/guides/overview.mdx b/docs/fern/versions/v0.4/pages/guides/overview.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/overview.mdx rename to docs/fern/versions/v0.4/pages/guides/overview.mdx diff --git a/fern/versions/v0.4/pages/guides/pipelining.mdx b/docs/fern/versions/v0.4/pages/guides/pipelining.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/pipelining.mdx rename to docs/fern/versions/v0.4/pages/guides/pipelining.mdx diff --git a/fern/versions/v0.4/pages/guides/quantization-aware-training.mdx b/docs/fern/versions/v0.4/pages/guides/quantization-aware-training.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/quantization-aware-training.mdx rename to docs/fern/versions/v0.4/pages/guides/quantization-aware-training.mdx diff --git a/fern/versions/v0.4/pages/guides/vlm/dataset.mdx b/docs/fern/versions/v0.4/pages/guides/vlm/dataset.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/vlm/dataset.mdx rename to docs/fern/versions/v0.4/pages/guides/vlm/dataset.mdx diff --git a/fern/versions/v0.4/pages/guides/vlm/gemma4.mdx b/docs/fern/versions/v0.4/pages/guides/vlm/gemma4.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/vlm/gemma4.mdx rename to docs/fern/versions/v0.4/pages/guides/vlm/gemma4.mdx diff --git a/fern/versions/v0.4/pages/guides/vlm/mistral-medium-3-5.mdx b/docs/fern/versions/v0.4/pages/guides/vlm/mistral-medium-3-5.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/vlm/mistral-medium-3-5.mdx rename to docs/fern/versions/v0.4/pages/guides/vlm/mistral-medium-3-5.mdx diff --git a/fern/versions/v0.4/pages/guides/vlm/mistralm35.png b/docs/fern/versions/v0.4/pages/guides/vlm/mistralm35.png similarity index 100% rename from fern/versions/v0.4/pages/guides/vlm/mistralm35.png rename to docs/fern/versions/v0.4/pages/guides/vlm/mistralm35.png diff --git a/fern/versions/v0.4/pages/guides/vlm/nemotron-omni.mdx b/docs/fern/versions/v0.4/pages/guides/vlm/nemotron-omni.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/vlm/nemotron-omni.mdx rename to docs/fern/versions/v0.4/pages/guides/vlm/nemotron-omni.mdx diff --git a/fern/versions/v0.4/pages/guides/vlm/qwen3-5.mdx b/docs/fern/versions/v0.4/pages/guides/vlm/qwen3-5.mdx similarity index 100% rename from fern/versions/v0.4/pages/guides/vlm/qwen3-5.mdx rename to docs/fern/versions/v0.4/pages/guides/vlm/qwen3-5.mdx diff --git a/fern/versions/v0.4/pages/guides/vlm/qwen3_5.png b/docs/fern/versions/v0.4/pages/guides/vlm/qwen3_5.png similarity index 100% rename from fern/versions/v0.4/pages/guides/vlm/qwen3_5.png rename to docs/fern/versions/v0.4/pages/guides/vlm/qwen3_5.png diff --git a/fern/versions/v0.4/pages/guides/vlm/qwen3_5scores.png b/docs/fern/versions/v0.4/pages/guides/vlm/qwen3_5scores.png similarity index 100% rename from fern/versions/v0.4/pages/guides/vlm/qwen3_5scores.png rename to docs/fern/versions/v0.4/pages/guides/vlm/qwen3_5scores.png diff --git a/fern/versions/v0.4/pages/index.mdx b/docs/fern/versions/v0.4/pages/index.mdx similarity index 100% rename from fern/versions/v0.4/pages/index.mdx rename to docs/fern/versions/v0.4/pages/index.mdx diff --git a/fern/versions/v0.4/pages/launcher/local-workstation.mdx b/docs/fern/versions/v0.4/pages/launcher/local-workstation.mdx similarity index 100% rename from fern/versions/v0.4/pages/launcher/local-workstation.mdx rename to docs/fern/versions/v0.4/pages/launcher/local-workstation.mdx diff --git a/fern/versions/v0.4/pages/launcher/nemo-run.mdx b/docs/fern/versions/v0.4/pages/launcher/nemo-run.mdx similarity index 100% rename from fern/versions/v0.4/pages/launcher/nemo-run.mdx rename to docs/fern/versions/v0.4/pages/launcher/nemo-run.mdx diff --git a/fern/versions/v0.4/pages/launcher/overview.mdx b/docs/fern/versions/v0.4/pages/launcher/overview.mdx similarity index 100% rename from fern/versions/v0.4/pages/launcher/overview.mdx rename to docs/fern/versions/v0.4/pages/launcher/overview.mdx diff --git a/fern/versions/v0.4/pages/launcher/skypilot-kubernetes.mdx b/docs/fern/versions/v0.4/pages/launcher/skypilot-kubernetes.mdx similarity index 100% rename from fern/versions/v0.4/pages/launcher/skypilot-kubernetes.mdx rename to docs/fern/versions/v0.4/pages/launcher/skypilot-kubernetes.mdx diff --git a/fern/versions/v0.4/pages/launcher/skypilot.mdx b/docs/fern/versions/v0.4/pages/launcher/skypilot.mdx similarity index 100% rename from fern/versions/v0.4/pages/launcher/skypilot.mdx rename to docs/fern/versions/v0.4/pages/launcher/skypilot.mdx diff --git a/fern/versions/v0.4/pages/launcher/slurm.mdx b/docs/fern/versions/v0.4/pages/launcher/slurm.mdx similarity index 100% rename from fern/versions/v0.4/pages/launcher/slurm.mdx rename to docs/fern/versions/v0.4/pages/launcher/slurm.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/diffusion/black-forest-labs/flux.mdx b/docs/fern/versions/v0.4/pages/model-coverage/diffusion/black-forest-labs/flux.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/diffusion/black-forest-labs/flux.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/diffusion/black-forest-labs/flux.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx b/docs/fern/versions/v0.4/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/diffusion/index.mdx b/docs/fern/versions/v0.4/pages/model-coverage/diffusion/index.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/diffusion/index.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/diffusion/index.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/diffusion/qwen/qwen-image.mdx b/docs/fern/versions/v0.4/pages/model-coverage/diffusion/qwen/qwen-image.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/diffusion/qwen/qwen-image.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/diffusion/qwen/qwen-image.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx b/docs/fern/versions/v0.4/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/latest-models.mdx b/docs/fern/versions/v0.4/pages/model-coverage/latest-models.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/latest-models.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/latest-models.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/allenai/olmo.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/allenai/olmo.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/allenai/olmo.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/allenai/olmo.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/allenai/olmo2.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/allenai/olmo2.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/allenai/olmo2.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/allenai/olmo2.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/allenai/olmoe.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/allenai/olmoe.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/allenai/olmoe.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/allenai/olmoe.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/baai/aquila.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/baai/aquila.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/baai/aquila.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/baai/aquila.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/baichuan-inc/baichuan.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/baichuan-inc/baichuan.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/baichuan-inc/baichuan.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/baichuan-inc/baichuan.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder2.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder2.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder2.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/bigcode/starcoder2.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/bytedance-seed/seed.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/bytedance-seed/seed.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/bytedance-seed/seed.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/bytedance-seed/seed.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/cohere/command-r.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/cohere/command-r.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/cohere/command-r.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/cohere/command-r.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/deepseek.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-j.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-j.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-j.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-j.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-neox.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-neox.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-neox.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/eleutherai/gpt-neox.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/google/gemma.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/google/gemma.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/google/gemma.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/google/gemma.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/ibm/bamba.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/ibm/bamba.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/ibm/bamba.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/ibm/bamba.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/ibm/granite-moe.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/ibm/granite-moe.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/ibm/granite-moe.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/ibm/granite-moe.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/ibm/granite.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/ibm/granite.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/ibm/granite.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/ibm/granite.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/inceptionai/jais.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/inceptionai/jais.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/inceptionai/jais.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/inceptionai/jais.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/index.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/index.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/index.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/index.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/internlm/internlm.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/internlm/internlm.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/internlm/internlm.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/internlm/internlm.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/lgai-exaone/exaone.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/lgai-exaone/exaone.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/lgai-exaone/exaone.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/lgai-exaone/exaone.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/meta/llama.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/meta/llama.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/meta/llama.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/meta/llama.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi3-small.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi3-small.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi3-small.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi3-small.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi3.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi3.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi3.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/microsoft/phi3.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/minimax/minimax-m2.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/minimax/minimax-m2.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/minimax/minimax-m2.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/minimax/minimax-m2.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/mistralai/ministral3.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/mistralai/ministral3.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/mistralai/ministral3.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/mistralai/ministral3.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/mistralai/mistral.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/mistralai/mistral.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/mistralai/mistral.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/mistralai/mistral.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/mistralai/mixtral.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/mistralai/mixtral.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/mistralai/mixtral.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/mistralai/mixtral.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/moonshotai/moonlight.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/moonshotai/moonlight.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/moonshotai/moonlight.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/moonshotai/moonlight.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-flash.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-flash.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-flash.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-flash.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-h.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-h.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-h.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-h.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-super.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-super.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-super.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron-super.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/nvidia/nemotron.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/openai/gpt-oss.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/openai/gpt-oss.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/openai/gpt-oss.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/openai/gpt-oss.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/openai/gpt2.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/openai/gpt2.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/openai/gpt2.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/openai/gpt2.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/openbmb/minicpm.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/openbmb/minicpm.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/openbmb/minicpm.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/openbmb/minicpm.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/orionstar/orion.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/orionstar/orion.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/orionstar/orion.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/orionstar/orion.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/parasail-ai/gritlm.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/parasail-ai/gritlm.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/parasail-ai/gritlm.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/parasail-ai/gritlm.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen2-moe.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen2-moe.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen2-moe.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen2-moe.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen2.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen2.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen2.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen2.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-moe.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-moe.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-moe.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-moe.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-next.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-next.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-next.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3-next.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/qwen/qwen3.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/stabilityai/stablelm.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/stabilityai/stablelm.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/stabilityai/stablelm.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/stabilityai/stablelm.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/tencent/hy3.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/tencent/hy3.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/tencent/hy3.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/tencent/hy3.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/thudm/chatglm.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/thudm/chatglm.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/thudm/chatglm.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/thudm/chatglm.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/thudm/glm4-moe.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/thudm/glm4-moe.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/thudm/glm4-moe.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/thudm/glm4-moe.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/thudm/glm4.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/thudm/glm4.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/thudm/glm4.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/thudm/glm4.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/tiiuae/falcon.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/tiiuae/falcon.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/tiiuae/falcon.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/tiiuae/falcon.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/llm/upstage/solar.mdx b/docs/fern/versions/v0.4/pages/model-coverage/llm/upstage/solar.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/llm/upstage/solar.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/llm/upstage/solar.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/omni/index.mdx b/docs/fern/versions/v0.4/pages/model-coverage/omni/index.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/omni/index.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/omni/index.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx b/docs/fern/versions/v0.4/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/omni/nvidia/nemotron-omni.mdx b/docs/fern/versions/v0.4/pages/model-coverage/omni/nvidia/nemotron-omni.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/omni/nvidia/nemotron-omni.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/omni/nvidia/nemotron-omni.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/omni/qwen/qwen3-omni.mdx b/docs/fern/versions/v0.4/pages/model-coverage/omni/qwen/qwen3-omni.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/omni/qwen/qwen3-omni.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/omni/qwen/qwen3-omni.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/overview.mdx b/docs/fern/versions/v0.4/pages/model-coverage/overview.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/overview.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/overview.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/troubleshooting.mdx b/docs/fern/versions/v0.4/pages/model-coverage/troubleshooting.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/troubleshooting.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/troubleshooting.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/google/gemma3-vl.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/google/gemma3-vl.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/google/gemma3-vl.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/google/gemma3-vl.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/google/gemma4.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/google/gemma4.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/google/gemma4.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/google/gemma4.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/huggingface/smolvlm.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/huggingface/smolvlm.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/huggingface/smolvlm.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/huggingface/smolvlm.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/index.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/index.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/index.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/index.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/internlm/internvl.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/internlm/internvl.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/internlm/internvl.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/internlm/internvl.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/llava-hf/llava.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/llava-hf/llava.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/llava-hf/llava.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/llava-hf/llava.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/meta/llama4.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/meta/llama4.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/meta/llama4.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/meta/llama4.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx diff --git a/fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-vl.mdx b/docs/fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-vl.mdx similarity index 100% rename from fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-vl.mdx rename to docs/fern/versions/v0.4/pages/model-coverage/vlm/qwen/qwen3-vl.mdx diff --git a/fern/versions/v0.4/pages/performance-summary.mdx b/docs/fern/versions/v0.4/pages/performance-summary.mdx similarity index 100% rename from fern/versions/v0.4/pages/performance-summary.mdx rename to docs/fern/versions/v0.4/pages/performance-summary.mdx diff --git a/fern/versions/v0.4/pages/repository-structure.mdx b/docs/fern/versions/v0.4/pages/repository-structure.mdx similarity index 100% rename from fern/versions/v0.4/pages/repository-structure.mdx rename to docs/fern/versions/v0.4/pages/repository-structure.mdx From f50ec23ba333402b4184dbc4a45e81896cf103af Mon Sep 17 00:00:00 2001 From: Lawrence Lane Date: Thu, 21 May 2026 17:22:17 -0400 Subject: [PATCH 3/7] =?UTF-8?q?docs(fern-migrate):=20rename=20docs/*.md=20?= =?UTF-8?q?=E2=86=92=20docs/*.mdx=20(sphinx=20=E2=86=92=20fern=20tree)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bulk same-directory extension rename of all 140 Sphinx Markdown source files into the Fern MDX tree. Three operations bundled: 1. R100 docs/<...>.md → docs/<...>.mdx (140 files; .md extension replaced with .mdx, byte-identical content). `git log --follow` on each new path walks straight back through the legacy Sphinx history. 2. D docs/fern/versions/nightly/pages/<...>.mdx (140 files; the pre-converted MDX placeholders are deleted — their bodies are restored at the same docs/<...>.mdx paths in the next commit). 3. R docs/fern/versions/nightly/pages/api-reference/index.mdx → docs/api-reference/index.mdx (fern-native page; no MD source). 4. D docs/fern/versions/nightly/{automodel_diagram.png, guides/...} — drop the page-scoped image copies that lived under the old nightly/pages tree. The originals already exist at docs/

/ from the legacy Sphinx tree. 5. M docs/fern/versions/nightly.yml — rewrite every `path: ./nightly/pages/.mdx` to `path: ../../.mdx` so the nav references the new top-level location. The MDX files at this commit contain the original Sphinx-MD body (unchanged content, just the extension flipped). The next commit applies the actual Sphinx → Fern MDX conversion as a per-file content diff. Splitting the rename from the conversion means `git show HEAD~ -- docs/.mdx` shows the 100% rename, and `git show HEAD -- docs/.mdx` (in the next commit) shows exactly what the conversion rewrote — that's the before-vs-after diff requested for review. fern check passes. Signed-off-by: Lawrence Lane --- docs/about/{index.md => index.mdx} | 0 .../{key-features.md => key-features.mdx} | 0 docs/{announcements.md => announcements.mdx} | 0 .../pages => }/api-reference/index.mdx | 0 ...eaking-changes.md => breaking-changes.mdx} | 0 docs/{documentation.md => documentation.mdx} | 0 docs/fern/versions/nightly.yml | 276 ++--- .../versions/nightly/pages/about/index.mdx | 87 -- .../nightly/pages/about/key-features.mdx | 164 --- .../versions/nightly/pages/announcements.mdx | 11 - .../nightly/pages/automodel_diagram.png | Bin 50597 -> 0 bytes .../nightly/pages/breaking-changes.mdx | 109 -- .../versions/nightly/pages/documentation.mdx | 43 - .../pages/guides/audio/qwen3-omni-asr.mdx | 256 ----- .../pages/guides/audio/qwen_omni_asr.png | Bin 74676 -> 0 bytes .../nightly/pages/guides/checkpointing.mdx | 348 ------- .../nightly/pages/guides/configuration.mdx | 121 --- .../nightly/pages/guides/dataset-overview.mdx | 618 ------------ .../pages/guides/diffusion/dataset.mdx | 209 ---- .../pages/guides/diffusion/finetune.mdx | 392 -------- .../nightly/pages/guides/dllm/finetune.mdx | 124 --- .../nightly/pages/guides/fp8-training.mdx | 142 --- .../nightly/pages/guides/fp8_convergence.jpg | Bin 44260 -> 0 bytes .../pages/guides/gradient-checkpointing.mdx | 89 -- .../guides/huggingface-api-compatibility.mdx | 225 ----- .../nightly/pages/guides/installation.mdx | 335 ------- ...column-mapped-text-instruction-dataset.mdx | 252 ----- ...pped-text-instruction-iterable-dataset.mdx | 225 ----- .../llm/databricks-gpu-metrics-multi.png | Bin 59318 -> 0 bytes .../llm/databricks-gpu-metrics-single.png | Bin 54011 -> 0 bytes .../nightly/pages/guides/llm/databricks.mdx | 290 ------ .../nightly/pages/guides/llm/dataset.mdx | 184 ---- .../nightly/pages/guides/llm/dsv4-flash.mdx | 97 -- .../nightly/pages/guides/llm/finetune.mdx | 942 ------------------ .../guides/llm/functiongemma-peft-loss.png | Bin 40019 -> 0 bytes .../guides/llm/functiongemma-sft-loss.png | Bin 38421 -> 0 bytes .../nightly/pages/guides/llm/gpt2_loss.png | Bin 32804 -> 0 bytes .../versions/nightly/pages/guides/llm/hy3.mdx | 103 -- .../guides/llm/knowledge-distillation.mdx | 183 ---- .../pages/guides/llm/large-moe-finetune.mdx | 133 --- .../pages/guides/llm/nanogpt-pretraining.mdx | 463 --------- .../nightly/pages/guides/llm/pretraining.mdx | 749 -------------- .../pages/guides/llm/retrieval-dataset.mdx | 111 --- .../guides/llm/sequence-classification.mdx | 120 --- .../nightly/pages/guides/llm/toolcalling.mdx | 119 --- .../nightly/pages/guides/mlflow-logging.mdx | 260 ----- .../nightly/pages/guides/omni/gemma3-3n.mdx | 327 ------ .../nightly/pages/guides/omni/medpix.jpg | Bin 19958 -> 0 bytes .../nightly/pages/guides/omni/medpix_peft.jpg | Bin 34742 -> 0 bytes .../nightly/pages/guides/overview.mdx | 122 --- .../nightly/pages/guides/pipelining.mdx | 745 -------------- .../guides/quantization-aware-training.mdx | 314 ------ .../nightly/pages/guides/vlm/dataset.mdx | 160 --- .../nightly/pages/guides/vlm/gemma4.mdx | 515 ---------- .../pages/guides/vlm/mistral-medium-3-5.mdx | 98 -- .../nightly/pages/guides/vlm/mistralm35.png | Bin 162658 -> 0 bytes .../pages/guides/vlm/nemotron-omni.mdx | 483 --------- .../nightly/pages/guides/vlm/qwen3-5.mdx | 65 -- .../nightly/pages/guides/vlm/qwen3_5.png | Bin 152665 -> 0 bytes .../pages/guides/vlm/qwen3_5scores.png | Bin 598134 -> 0 bytes docs/fern/versions/nightly/pages/index.mdx | 161 --- .../pages/launcher/local-workstation.mdx | 153 --- .../nightly/pages/launcher/nemo-run.mdx | 240 ----- .../nightly/pages/launcher/overview.mdx | 69 -- .../pages/launcher/skypilot-kubernetes.mdx | 238 ----- .../nightly/pages/launcher/skypilot.mdx | 198 ---- .../versions/nightly/pages/launcher/slurm.mdx | 192 ---- .../diffusion/black-forest-labs/flux.mdx | 95 -- .../hunyuanvideo-community/hunyuanvideo.mdx | 94 -- .../pages/model-coverage/diffusion/index.mdx | 33 - .../diffusion/qwen/qwen-image.mdx | 94 -- .../diffusion/wan-ai/wan2-1-t2v.mdx | 95 -- .../pages/model-coverage/embedding/index.mdx | 49 - .../mistralai/ministral3-bidirectional.mdx | 83 -- .../embedding/nvidia/llama-bidirectional.mdx | 114 --- .../pages/model-coverage/latest-models.mdx | 69 -- .../pages/model-coverage/llm/allenai/olmo.mdx | 93 -- .../model-coverage/llm/allenai/olmo2.mdx | 94 -- .../model-coverage/llm/allenai/olmoe.mdx | 92 -- .../pages/model-coverage/llm/baai/aquila.mdx | 93 -- .../llm/baichuan-inc/baichuan.mdx | 94 -- .../model-coverage/llm/baidu/ernie4-5.mdx | 98 -- .../model-coverage/llm/bigcode/starcoder.mdx | 94 -- .../model-coverage/llm/bigcode/starcoder2.mdx | 95 -- .../llm/bytedance-seed/seed.mdx | 96 -- .../model-coverage/llm/cohere/command-r.mdx | 96 -- .../llm/deepseek-ai/deepseek-v3.mdx | 107 -- .../llm/deepseek-ai/deepseek.mdx | 94 -- .../llm/deepseek-ai/dsv4-flash.mdx | 95 -- .../model-coverage/llm/eleutherai/gpt-j.mdx | 92 -- .../llm/eleutherai/gpt-neox.mdx | 99 -- .../pages/model-coverage/llm/google/gemma.mdx | 105 -- .../pages/model-coverage/llm/ibm/bamba.mdx | 90 -- .../model-coverage/llm/ibm/granite-moe.mdx | 97 -- .../pages/model-coverage/llm/ibm/granite.mdx | 97 -- .../model-coverage/llm/inceptionai/jais.mdx | 96 -- .../model-coverage/llm/inclusionai/ling-2.mdx | 66 -- .../pages/model-coverage/llm/index.mdx | 94 -- .../model-coverage/llm/internlm/internlm.mdx | 97 -- .../model-coverage/llm/lgai-exaone/exaone.mdx | 91 -- .../pages/model-coverage/llm/meta/llama.mdx | 106 -- .../model-coverage/llm/microsoft/phi.mdx | 94 -- .../llm/microsoft/phi3-small.mdx | 93 -- .../model-coverage/llm/microsoft/phi3.mdx | 104 -- .../model-coverage/llm/minimax/minimax-m2.mdx | 102 -- .../llm/mistralai/ministral3.mdx | 96 -- .../model-coverage/llm/mistralai/mistral.mdx | 98 -- .../model-coverage/llm/mistralai/mixtral.mdx | 95 -- .../llm/moonshotai/moonlight.mdx | 91 -- .../llm/nvidia/nemotron-flash.mdx | 96 -- .../model-coverage/llm/nvidia/nemotron-h.mdx | 99 -- .../llm/nvidia/nemotron-super.mdx | 90 -- .../model-coverage/llm/nvidia/nemotron.mdx | 90 -- .../model-coverage/llm/openai/gpt-oss.mdx | 94 -- .../pages/model-coverage/llm/openai/gpt2.mdx | 66 -- .../model-coverage/llm/openbmb/minicpm.mdx | 95 -- .../model-coverage/llm/orionstar/orion.mdx | 92 -- .../model-coverage/llm/parasail-ai/gritlm.mdx | 90 -- .../model-coverage/llm/qwen/qwen2-moe.mdx | 91 -- .../pages/model-coverage/llm/qwen/qwen2.mdx | 98 -- .../model-coverage/llm/qwen/qwen3-moe.mdx | 94 -- .../model-coverage/llm/qwen/qwen3-next.mdx | 95 -- .../pages/model-coverage/llm/qwen/qwen3.mdx | 94 -- .../llm/stabilityai/stablelm.mdx | 92 -- .../llm/stepfun-ai/step-3-5.mdx | 95 -- .../pages/model-coverage/llm/tencent/hy3.mdx | 67 -- .../model-coverage/llm/thudm/chatglm.mdx | 93 -- .../model-coverage/llm/thudm/glm4-moe.mdx | 105 -- .../pages/model-coverage/llm/thudm/glm4.mdx | 95 -- .../model-coverage/llm/thudm/glm5-moe-dsa.mdx | 128 --- .../model-coverage/llm/tiiuae/falcon.mdx | 97 -- .../model-coverage/llm/upstage/solar.mdx | 90 -- .../llm/xiaomimimo/mimo-v2-flash.mdx | 93 -- .../pages/model-coverage/omni/index.mdx | 28 - .../omni/microsoft/phi4-multimodal.mdx | 90 -- .../omni/nvidia/nemotron-omni.mdx | 59 -- .../model-coverage/omni/qwen/qwen3-omni.mdx | 90 -- .../nightly/pages/model-coverage/overview.mdx | 46 - .../pages/model-coverage/reranker/index.mdx | 36 - .../reranker/nvidia/llama-bidirectional.mdx | 101 -- .../pages/model-coverage/troubleshooting.mdx | 23 - .../model-coverage/vlm/google/gemma3-vl.mdx | 99 -- .../model-coverage/vlm/google/gemma4.mdx | 109 -- .../vlm/huggingface/smolvlm.mdx | 92 -- .../pages/model-coverage/vlm/index.mdx | 51 - .../model-coverage/vlm/internlm/internvl.mdx | 91 -- .../model-coverage/vlm/llava-hf/llava.mdx | 103 -- .../vlm/lmms-lab/llava-onevision.mdx | 96 -- .../pages/model-coverage/vlm/meta/llama4.mdx | 93 -- .../vlm/mistralai/ministral3-vl.mdx | 96 -- .../vlm/mistralai/mistral-medium-3-5.mdx | 162 --- .../vlm/mistralai/mistral-small-4.mdx | 95 -- .../model-coverage/vlm/moonshotai/kimi-vl.mdx | 92 -- .../vlm/nvidia/nemotron-parse.mdx | 94 -- .../model-coverage/vlm/qwen/qwen2-5-vl.mdx | 98 -- .../model-coverage/vlm/qwen/qwen3-5-vl.mdx | 94 -- .../model-coverage/vlm/qwen/qwen3-vl.mdx | 98 -- .../nightly/pages/performance-summary.mdx | 85 -- .../versions/nightly/pages/release-notes.mdx | 258 ----- .../nightly/pages/repository-structure.mdx | 120 --- .../{qwen3-omni-asr.md => qwen3-omni-asr.mdx} | 0 .../{checkpointing.md => checkpointing.mdx} | 0 .../{configuration.md => configuration.mdx} | 0 ...taset-overview.md => dataset-overview.mdx} | 0 .../diffusion/{dataset.md => dataset.mdx} | 0 .../diffusion/{finetune.md => finetune.mdx} | 0 .../guides/dllm/{finetune.md => finetune.mdx} | 0 .../{fp8-training.md => fp8-training.mdx} | 0 ...pointing.md => gradient-checkpointing.mdx} | 0 ...y.md => huggingface-api-compatibility.mdx} | 0 .../{installation.md => installation.mdx} | 0 ...olumn-mapped-text-instruction-dataset.mdx} | 0 ...ped-text-instruction-iterable-dataset.mdx} | 0 .../llm/{databricks.md => databricks.mdx} | 0 docs/guides/llm/{dataset.md => dataset.mdx} | 0 .../llm/{dsv4-flash.md => dsv4-flash.mdx} | 0 docs/guides/llm/{finetune.md => finetune.mdx} | 0 docs/guides/llm/{hy3.md => hy3.mdx} | 0 ...illation.md => knowledge-distillation.mdx} | 0 ...moe-finetune.md => large-moe-finetune.mdx} | 0 ...pretraining.md => nanogpt-pretraining.mdx} | 0 .../llm/{pretraining.md => pretraining.mdx} | 0 ...ieval-dataset.md => retrieval-dataset.mdx} | 0 ...ication.md => sequence-classification.mdx} | 0 .../llm/{toolcalling.md => toolcalling.mdx} | 0 .../{mlflow-logging.md => mlflow-logging.mdx} | 0 .../omni/{gemma3-3n.md => gemma3-3n.mdx} | 0 docs/guides/{overview.md => overview.mdx} | 0 docs/guides/{pipelining.md => pipelining.mdx} | 0 ...ing.md => quantization-aware-training.mdx} | 0 docs/guides/vlm/{dataset.md => dataset.mdx} | 0 docs/guides/vlm/{gemma4.md => gemma4.mdx} | 0 ...l-medium-3-5.md => mistral-medium-3-5.mdx} | 0 .../{nemotron-omni.md => nemotron-omni.mdx} | 0 docs/guides/vlm/{qwen3-5.md => qwen3-5.mdx} | 0 docs/{index.md => index.mdx} | 0 ...l-workstation.md => local-workstation.mdx} | 0 docs/launcher/{nemo-run.md => nemo-run.mdx} | 0 docs/launcher/{overview.md => overview.mdx} | 0 ...-kubernetes.md => skypilot-kubernetes.mdx} | 0 docs/launcher/{skypilot.md => skypilot.mdx} | 0 docs/launcher/{slurm.md => slurm.mdx} | 0 .../black-forest-labs/{flux.md => flux.mdx} | 0 .../{hunyuanvideo.md => hunyuanvideo.mdx} | 0 .../diffusion/{index.md => index.mdx} | 0 .../qwen/{qwen-image.md => qwen-image.mdx} | 0 .../wan-ai/{wan2-1-t2v.md => wan2-1-t2v.mdx} | 0 .../embedding/{index.md => index.mdx} | 0 ...tional.md => ministral3-bidirectional.mdx} | 0 ...directional.md => llama-bidirectional.mdx} | 0 .../{latest-models.md => latest-models.mdx} | 0 .../llm/allenai/{olmo.md => olmo.mdx} | 0 .../llm/allenai/{olmo2.md => olmo2.mdx} | 0 .../llm/allenai/{olmoe.md => olmoe.mdx} | 0 .../llm/baai/{aquila.md => aquila.mdx} | 0 .../{baichuan.md => baichuan.mdx} | 0 .../llm/baidu/{ernie4-5.md => ernie4-5.mdx} | 0 .../bigcode/{starcoder.md => starcoder.mdx} | 0 .../bigcode/{starcoder2.md => starcoder2.mdx} | 0 .../llm/bytedance-seed/{seed.md => seed.mdx} | 0 .../cohere/{command-r.md => command-r.mdx} | 0 .../{deepseek-v3.md => deepseek-v3.mdx} | 0 .../deepseek-ai/{deepseek.md => deepseek.mdx} | 0 .../{dsv4-flash.md => dsv4-flash.mdx} | 0 .../llm/eleutherai/{gpt-j.md => gpt-j.mdx} | 0 .../eleutherai/{gpt-neox.md => gpt-neox.mdx} | 0 .../llm/google/{gemma.md => gemma.mdx} | 0 .../llm/ibm/{bamba.md => bamba.mdx} | 0 .../ibm/{granite-moe.md => granite-moe.mdx} | 0 .../llm/ibm/{granite.md => granite.mdx} | 0 .../llm/inceptionai/{jais.md => jais.mdx} | 0 .../llm/inclusionai/{ling-2.md => ling-2.mdx} | 0 .../llm/{index.md => index.mdx} | 0 .../internlm/{internlm.md => internlm.mdx} | 0 .../llm/lgai-exaone/{exaone.md => exaone.mdx} | 0 .../llm/meta/{llama.md => llama.mdx} | 0 .../llm/microsoft/{phi.md => phi.mdx} | 0 .../{phi3-small.md => phi3-small.mdx} | 0 .../llm/microsoft/{phi3.md => phi3.mdx} | 0 .../minimax/{minimax-m2.md => minimax-m2.mdx} | 0 .../{ministral3.md => ministral3.mdx} | 0 .../llm/mistralai/{mistral.md => mistral.mdx} | 0 .../llm/mistralai/{mixtral.md => mixtral.mdx} | 0 .../{moonlight.md => moonlight.mdx} | 0 .../{nemotron-flash.md => nemotron-flash.mdx} | 0 .../nvidia/{nemotron-h.md => nemotron-h.mdx} | 0 .../{nemotron-super.md => nemotron-super.mdx} | 0 .../llm/nvidia/{nemotron.md => nemotron.mdx} | 0 .../llm/openai/{gpt-oss.md => gpt-oss.mdx} | 0 .../llm/openai/{gpt2.md => gpt2.mdx} | 0 .../llm/openbmb/{minicpm.md => minicpm.mdx} | 0 .../llm/orionstar/{orion.md => orion.mdx} | 0 .../llm/parasail-ai/{gritlm.md => gritlm.mdx} | 0 .../llm/qwen/{qwen2-moe.md => qwen2-moe.mdx} | 0 .../llm/qwen/{qwen2.md => qwen2.mdx} | 0 .../llm/qwen/{qwen3-moe.md => qwen3-moe.mdx} | 0 .../qwen/{qwen3-next.md => qwen3-next.mdx} | 0 .../llm/qwen/{qwen3.md => qwen3.mdx} | 0 .../stabilityai/{stablelm.md => stablelm.mdx} | 0 .../stepfun-ai/{step-3-5.md => step-3-5.mdx} | 0 .../llm/tencent/{hy3.md => hy3.mdx} | 0 .../llm/thudm/{chatglm.md => chatglm.mdx} | 0 .../llm/thudm/{glm4-moe.md => glm4-moe.mdx} | 0 .../llm/thudm/{glm4.md => glm4.mdx} | 0 .../{glm5-moe-dsa.md => glm5-moe-dsa.mdx} | 0 .../llm/tiiuae/{falcon.md => falcon.mdx} | 0 .../llm/upstage/{solar.md => solar.mdx} | 0 .../{mimo-v2-flash.md => mimo-v2-flash.mdx} | 0 .../omni/{index.md => index.mdx} | 0 ...phi4-multimodal.md => phi4-multimodal.mdx} | 0 .../{nemotron-omni.md => nemotron-omni.mdx} | 0 .../qwen/{qwen3-omni.md => qwen3-omni.mdx} | 0 .../{overview.md => overview.mdx} | 0 .../reranker/{index.md => index.mdx} | 0 ...directional.md => llama-bidirectional.mdx} | 0 ...troubleshooting.md => troubleshooting.mdx} | 0 .../google/{gemma3-vl.md => gemma3-vl.mdx} | 0 .../vlm/google/{gemma4.md => gemma4.mdx} | 0 .../huggingface/{smolvlm.md => smolvlm.mdx} | 0 .../vlm/{index.md => index.mdx} | 0 .../internlm/{internvl.md => internvl.mdx} | 0 .../vlm/llava-hf/{llava.md => llava.mdx} | 0 ...llava-onevision.md => llava-onevision.mdx} | 0 .../vlm/meta/{llama4.md => llama4.mdx} | 0 .../{ministral3-vl.md => ministral3-vl.mdx} | 0 ...l-medium-3-5.md => mistral-medium-3-5.mdx} | 0 ...mistral-small-4.md => mistral-small-4.mdx} | 0 .../moonshotai/{kimi-vl.md => kimi-vl.mdx} | 0 .../{nemotron-parse.md => nemotron-parse.mdx} | 0 .../qwen/{qwen2-5-vl.md => qwen2-5-vl.mdx} | 0 .../qwen/{qwen3-5-vl.md => qwen3-5-vl.mdx} | 0 .../vlm/qwen/{qwen3-vl.md => qwen3-vl.mdx} | 0 ...nce-summary.md => performance-summary.mdx} | 0 docs/{release-notes.md => release-notes.mdx} | 0 ...-structure.md => repository-structure.mdx} | 0 295 files changed, 138 insertions(+), 20330 deletions(-) rename docs/about/{index.md => index.mdx} (100%) rename docs/about/{key-features.md => key-features.mdx} (100%) rename docs/{announcements.md => announcements.mdx} (100%) rename docs/{fern/versions/nightly/pages => }/api-reference/index.mdx (100%) rename docs/{breaking-changes.md => breaking-changes.mdx} (100%) rename docs/{documentation.md => documentation.mdx} (100%) delete mode 100644 docs/fern/versions/nightly/pages/about/index.mdx delete mode 100644 docs/fern/versions/nightly/pages/about/key-features.mdx delete mode 100644 docs/fern/versions/nightly/pages/announcements.mdx delete mode 100644 docs/fern/versions/nightly/pages/automodel_diagram.png delete mode 100644 docs/fern/versions/nightly/pages/breaking-changes.mdx delete mode 100644 docs/fern/versions/nightly/pages/documentation.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png delete mode 100644 docs/fern/versions/nightly/pages/guides/checkpointing.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/configuration.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/dataset-overview.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/diffusion/dataset.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/diffusion/finetune.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/dllm/finetune.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/fp8-training.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/fp8_convergence.jpg delete mode 100644 docs/fern/versions/nightly/pages/guides/gradient-checkpointing.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/huggingface-api-compatibility.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/installation.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-multi.png delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-single.png delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/databricks.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/dataset.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/dsv4-flash.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/finetune.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/functiongemma-peft-loss.png delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/functiongemma-sft-loss.png delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/gpt2_loss.png delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/hy3.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/knowledge-distillation.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/large-moe-finetune.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/nanogpt-pretraining.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/pretraining.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/retrieval-dataset.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/sequence-classification.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/llm/toolcalling.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/mlflow-logging.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/omni/gemma3-3n.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/omni/medpix.jpg delete mode 100644 docs/fern/versions/nightly/pages/guides/omni/medpix_peft.jpg delete mode 100644 docs/fern/versions/nightly/pages/guides/overview.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/pipelining.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/quantization-aware-training.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/vlm/dataset.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/vlm/gemma4.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/vlm/mistral-medium-3-5.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/vlm/mistralm35.png delete mode 100644 docs/fern/versions/nightly/pages/guides/vlm/nemotron-omni.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/vlm/qwen3-5.mdx delete mode 100644 docs/fern/versions/nightly/pages/guides/vlm/qwen3_5.png delete mode 100644 docs/fern/versions/nightly/pages/guides/vlm/qwen3_5scores.png delete mode 100644 docs/fern/versions/nightly/pages/index.mdx delete mode 100644 docs/fern/versions/nightly/pages/launcher/local-workstation.mdx delete mode 100644 docs/fern/versions/nightly/pages/launcher/nemo-run.mdx delete mode 100644 docs/fern/versions/nightly/pages/launcher/overview.mdx delete mode 100644 docs/fern/versions/nightly/pages/launcher/skypilot-kubernetes.mdx delete mode 100644 docs/fern/versions/nightly/pages/launcher/skypilot.mdx delete mode 100644 docs/fern/versions/nightly/pages/launcher/slurm.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/diffusion/index.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/embedding/index.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/latest-models.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo2.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmoe.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/baai/aquila.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/cohere/command-r.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/google/gemma.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/ibm/bamba.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite-moe.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/inceptionai/jais.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/index.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/internlm/internlm.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/meta/llama.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/ministral3.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mistral.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mixtral.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt-oss.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt2.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/openbmb/minicpm.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/orionstar/orion.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/tencent/hy3.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/thudm/chatglm.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/tiiuae/falcon.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/upstage/solar.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/omni/index.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/overview.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/reranker/index.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/troubleshooting.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma4.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/index.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/internlm/internvl.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/llava-hf/llava.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/meta/llama4.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx delete mode 100644 docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx delete mode 100644 docs/fern/versions/nightly/pages/performance-summary.mdx delete mode 100644 docs/fern/versions/nightly/pages/release-notes.mdx delete mode 100644 docs/fern/versions/nightly/pages/repository-structure.mdx rename docs/guides/audio/{qwen3-omni-asr.md => qwen3-omni-asr.mdx} (100%) rename docs/guides/{checkpointing.md => checkpointing.mdx} (100%) rename docs/guides/{configuration.md => configuration.mdx} (100%) rename docs/guides/{dataset-overview.md => dataset-overview.mdx} (100%) rename docs/guides/diffusion/{dataset.md => dataset.mdx} (100%) rename docs/guides/diffusion/{finetune.md => finetune.mdx} (100%) rename docs/guides/dllm/{finetune.md => finetune.mdx} (100%) rename docs/guides/{fp8-training.md => fp8-training.mdx} (100%) rename docs/guides/{gradient-checkpointing.md => gradient-checkpointing.mdx} (100%) rename docs/guides/{huggingface-api-compatibility.md => huggingface-api-compatibility.mdx} (100%) rename docs/guides/{installation.md => installation.mdx} (100%) rename docs/guides/llm/{column-mapped-text-instruction-dataset.md => column-mapped-text-instruction-dataset.mdx} (100%) rename docs/guides/llm/{column-mapped-text-instruction-iterable-dataset.md => column-mapped-text-instruction-iterable-dataset.mdx} (100%) rename docs/guides/llm/{databricks.md => databricks.mdx} (100%) rename docs/guides/llm/{dataset.md => dataset.mdx} (100%) rename docs/guides/llm/{dsv4-flash.md => dsv4-flash.mdx} (100%) rename docs/guides/llm/{finetune.md => finetune.mdx} (100%) rename docs/guides/llm/{hy3.md => hy3.mdx} (100%) rename docs/guides/llm/{knowledge-distillation.md => knowledge-distillation.mdx} (100%) rename docs/guides/llm/{large-moe-finetune.md => large-moe-finetune.mdx} (100%) rename docs/guides/llm/{nanogpt-pretraining.md => nanogpt-pretraining.mdx} (100%) rename docs/guides/llm/{pretraining.md => pretraining.mdx} (100%) rename docs/guides/llm/{retrieval-dataset.md => retrieval-dataset.mdx} (100%) rename docs/guides/llm/{sequence-classification.md => sequence-classification.mdx} (100%) rename docs/guides/llm/{toolcalling.md => toolcalling.mdx} (100%) rename docs/guides/{mlflow-logging.md => mlflow-logging.mdx} (100%) rename docs/guides/omni/{gemma3-3n.md => gemma3-3n.mdx} (100%) rename docs/guides/{overview.md => overview.mdx} (100%) rename docs/guides/{pipelining.md => pipelining.mdx} (100%) rename docs/guides/{quantization-aware-training.md => quantization-aware-training.mdx} (100%) rename docs/guides/vlm/{dataset.md => dataset.mdx} (100%) rename docs/guides/vlm/{gemma4.md => gemma4.mdx} (100%) rename docs/guides/vlm/{mistral-medium-3-5.md => mistral-medium-3-5.mdx} (100%) rename docs/guides/vlm/{nemotron-omni.md => nemotron-omni.mdx} (100%) rename docs/guides/vlm/{qwen3-5.md => qwen3-5.mdx} (100%) rename docs/{index.md => index.mdx} (100%) rename docs/launcher/{local-workstation.md => local-workstation.mdx} (100%) rename docs/launcher/{nemo-run.md => nemo-run.mdx} (100%) rename docs/launcher/{overview.md => overview.mdx} (100%) rename docs/launcher/{skypilot-kubernetes.md => skypilot-kubernetes.mdx} (100%) rename docs/launcher/{skypilot.md => skypilot.mdx} (100%) rename docs/launcher/{slurm.md => slurm.mdx} (100%) rename docs/model-coverage/diffusion/black-forest-labs/{flux.md => flux.mdx} (100%) rename docs/model-coverage/diffusion/hunyuanvideo-community/{hunyuanvideo.md => hunyuanvideo.mdx} (100%) rename docs/model-coverage/diffusion/{index.md => index.mdx} (100%) rename docs/model-coverage/diffusion/qwen/{qwen-image.md => qwen-image.mdx} (100%) rename docs/model-coverage/diffusion/wan-ai/{wan2-1-t2v.md => wan2-1-t2v.mdx} (100%) rename docs/model-coverage/embedding/{index.md => index.mdx} (100%) rename docs/model-coverage/embedding/mistralai/{ministral3-bidirectional.md => ministral3-bidirectional.mdx} (100%) rename docs/model-coverage/embedding/nvidia/{llama-bidirectional.md => llama-bidirectional.mdx} (100%) rename docs/model-coverage/{latest-models.md => latest-models.mdx} (100%) rename docs/model-coverage/llm/allenai/{olmo.md => olmo.mdx} (100%) rename docs/model-coverage/llm/allenai/{olmo2.md => olmo2.mdx} (100%) rename docs/model-coverage/llm/allenai/{olmoe.md => olmoe.mdx} (100%) rename docs/model-coverage/llm/baai/{aquila.md => aquila.mdx} (100%) rename docs/model-coverage/llm/baichuan-inc/{baichuan.md => baichuan.mdx} (100%) rename docs/model-coverage/llm/baidu/{ernie4-5.md => ernie4-5.mdx} (100%) rename docs/model-coverage/llm/bigcode/{starcoder.md => starcoder.mdx} (100%) rename docs/model-coverage/llm/bigcode/{starcoder2.md => starcoder2.mdx} (100%) rename docs/model-coverage/llm/bytedance-seed/{seed.md => seed.mdx} (100%) rename docs/model-coverage/llm/cohere/{command-r.md => command-r.mdx} (100%) rename docs/model-coverage/llm/deepseek-ai/{deepseek-v3.md => deepseek-v3.mdx} (100%) rename docs/model-coverage/llm/deepseek-ai/{deepseek.md => deepseek.mdx} (100%) rename docs/model-coverage/llm/deepseek-ai/{dsv4-flash.md => dsv4-flash.mdx} (100%) rename docs/model-coverage/llm/eleutherai/{gpt-j.md => gpt-j.mdx} (100%) rename docs/model-coverage/llm/eleutherai/{gpt-neox.md => gpt-neox.mdx} (100%) rename docs/model-coverage/llm/google/{gemma.md => gemma.mdx} (100%) rename docs/model-coverage/llm/ibm/{bamba.md => bamba.mdx} (100%) rename docs/model-coverage/llm/ibm/{granite-moe.md => granite-moe.mdx} (100%) rename docs/model-coverage/llm/ibm/{granite.md => granite.mdx} (100%) rename docs/model-coverage/llm/inceptionai/{jais.md => jais.mdx} (100%) rename docs/model-coverage/llm/inclusionai/{ling-2.md => ling-2.mdx} (100%) rename docs/model-coverage/llm/{index.md => index.mdx} (100%) rename docs/model-coverage/llm/internlm/{internlm.md => internlm.mdx} (100%) rename docs/model-coverage/llm/lgai-exaone/{exaone.md => exaone.mdx} (100%) rename docs/model-coverage/llm/meta/{llama.md => llama.mdx} (100%) rename docs/model-coverage/llm/microsoft/{phi.md => phi.mdx} (100%) rename docs/model-coverage/llm/microsoft/{phi3-small.md => phi3-small.mdx} (100%) rename docs/model-coverage/llm/microsoft/{phi3.md => phi3.mdx} (100%) rename docs/model-coverage/llm/minimax/{minimax-m2.md => minimax-m2.mdx} (100%) rename docs/model-coverage/llm/mistralai/{ministral3.md => ministral3.mdx} (100%) rename docs/model-coverage/llm/mistralai/{mistral.md => mistral.mdx} (100%) rename docs/model-coverage/llm/mistralai/{mixtral.md => mixtral.mdx} (100%) rename docs/model-coverage/llm/moonshotai/{moonlight.md => moonlight.mdx} (100%) rename docs/model-coverage/llm/nvidia/{nemotron-flash.md => nemotron-flash.mdx} (100%) rename docs/model-coverage/llm/nvidia/{nemotron-h.md => nemotron-h.mdx} (100%) rename docs/model-coverage/llm/nvidia/{nemotron-super.md => nemotron-super.mdx} (100%) rename docs/model-coverage/llm/nvidia/{nemotron.md => nemotron.mdx} (100%) rename docs/model-coverage/llm/openai/{gpt-oss.md => gpt-oss.mdx} (100%) rename docs/model-coverage/llm/openai/{gpt2.md => gpt2.mdx} (100%) rename docs/model-coverage/llm/openbmb/{minicpm.md => minicpm.mdx} (100%) rename docs/model-coverage/llm/orionstar/{orion.md => orion.mdx} (100%) rename docs/model-coverage/llm/parasail-ai/{gritlm.md => gritlm.mdx} (100%) rename docs/model-coverage/llm/qwen/{qwen2-moe.md => qwen2-moe.mdx} (100%) rename docs/model-coverage/llm/qwen/{qwen2.md => qwen2.mdx} (100%) rename docs/model-coverage/llm/qwen/{qwen3-moe.md => qwen3-moe.mdx} (100%) rename docs/model-coverage/llm/qwen/{qwen3-next.md => qwen3-next.mdx} (100%) rename docs/model-coverage/llm/qwen/{qwen3.md => qwen3.mdx} (100%) rename docs/model-coverage/llm/stabilityai/{stablelm.md => stablelm.mdx} (100%) rename docs/model-coverage/llm/stepfun-ai/{step-3-5.md => step-3-5.mdx} (100%) rename docs/model-coverage/llm/tencent/{hy3.md => hy3.mdx} (100%) rename docs/model-coverage/llm/thudm/{chatglm.md => chatglm.mdx} (100%) rename docs/model-coverage/llm/thudm/{glm4-moe.md => glm4-moe.mdx} (100%) rename docs/model-coverage/llm/thudm/{glm4.md => glm4.mdx} (100%) rename docs/model-coverage/llm/thudm/{glm5-moe-dsa.md => glm5-moe-dsa.mdx} (100%) rename docs/model-coverage/llm/tiiuae/{falcon.md => falcon.mdx} (100%) rename docs/model-coverage/llm/upstage/{solar.md => solar.mdx} (100%) rename docs/model-coverage/llm/xiaomimimo/{mimo-v2-flash.md => mimo-v2-flash.mdx} (100%) rename docs/model-coverage/omni/{index.md => index.mdx} (100%) rename docs/model-coverage/omni/microsoft/{phi4-multimodal.md => phi4-multimodal.mdx} (100%) rename docs/model-coverage/omni/nvidia/{nemotron-omni.md => nemotron-omni.mdx} (100%) rename docs/model-coverage/omni/qwen/{qwen3-omni.md => qwen3-omni.mdx} (100%) rename docs/model-coverage/{overview.md => overview.mdx} (100%) rename docs/model-coverage/reranker/{index.md => index.mdx} (100%) rename docs/model-coverage/reranker/nvidia/{llama-bidirectional.md => llama-bidirectional.mdx} (100%) rename docs/model-coverage/{troubleshooting.md => troubleshooting.mdx} (100%) rename docs/model-coverage/vlm/google/{gemma3-vl.md => gemma3-vl.mdx} (100%) rename docs/model-coverage/vlm/google/{gemma4.md => gemma4.mdx} (100%) rename docs/model-coverage/vlm/huggingface/{smolvlm.md => smolvlm.mdx} (100%) rename docs/model-coverage/vlm/{index.md => index.mdx} (100%) rename docs/model-coverage/vlm/internlm/{internvl.md => internvl.mdx} (100%) rename docs/model-coverage/vlm/llava-hf/{llava.md => llava.mdx} (100%) rename docs/model-coverage/vlm/lmms-lab/{llava-onevision.md => llava-onevision.mdx} (100%) rename docs/model-coverage/vlm/meta/{llama4.md => llama4.mdx} (100%) rename docs/model-coverage/vlm/mistralai/{ministral3-vl.md => ministral3-vl.mdx} (100%) rename docs/model-coverage/vlm/mistralai/{mistral-medium-3-5.md => mistral-medium-3-5.mdx} (100%) rename docs/model-coverage/vlm/mistralai/{mistral-small-4.md => mistral-small-4.mdx} (100%) rename docs/model-coverage/vlm/moonshotai/{kimi-vl.md => kimi-vl.mdx} (100%) rename docs/model-coverage/vlm/nvidia/{nemotron-parse.md => nemotron-parse.mdx} (100%) rename docs/model-coverage/vlm/qwen/{qwen2-5-vl.md => qwen2-5-vl.mdx} (100%) rename docs/model-coverage/vlm/qwen/{qwen3-5-vl.md => qwen3-5-vl.mdx} (100%) rename docs/model-coverage/vlm/qwen/{qwen3-vl.md => qwen3-vl.mdx} (100%) rename docs/{performance-summary.md => performance-summary.mdx} (100%) rename docs/{release-notes.md => release-notes.mdx} (100%) rename docs/{repository-structure.md => repository-structure.mdx} (100%) diff --git a/docs/about/index.md b/docs/about/index.mdx similarity index 100% rename from docs/about/index.md rename to docs/about/index.mdx diff --git a/docs/about/key-features.md b/docs/about/key-features.mdx similarity index 100% rename from docs/about/key-features.md rename to docs/about/key-features.mdx diff --git a/docs/announcements.md b/docs/announcements.mdx similarity index 100% rename from docs/announcements.md rename to docs/announcements.mdx diff --git a/docs/fern/versions/nightly/pages/api-reference/index.mdx b/docs/api-reference/index.mdx similarity index 100% rename from docs/fern/versions/nightly/pages/api-reference/index.mdx rename to docs/api-reference/index.mdx diff --git a/docs/breaking-changes.md b/docs/breaking-changes.mdx similarity index 100% rename from docs/breaking-changes.md rename to docs/breaking-changes.mdx diff --git a/docs/documentation.md b/docs/documentation.mdx similarity index 100% rename from docs/documentation.md rename to docs/documentation.mdx diff --git a/docs/fern/versions/nightly.yml b/docs/fern/versions/nightly.yml index 247e9c6ddd..5849938bb7 100644 --- a/docs/fern/versions/nightly.yml +++ b/docs/fern/versions/nightly.yml @@ -2,374 +2,374 @@ navigation: - section: "Get Started" contents: - page: "About NeMo AutoModel" - path: ./nightly/pages/about/index.mdx + path: ../../about/index.mdx slug: about - page: "Key Features and Concepts" - path: ./nightly/pages/about/key-features.mdx + path: ../../about/key-features.mdx slug: key-features - page: "Install NeMo AutoModel" - path: ./nightly/pages/guides/installation.mdx + path: ../../guides/installation.mdx slug: installation - page: "YAML Configuration" - path: ./nightly/pages/guides/configuration.mdx + path: ../../guides/configuration.mdx slug: configuration - page: "🤗 Transformers API Compatibility" - path: ./nightly/pages/guides/huggingface-api-compatibility.mdx + path: ../../guides/huggingface-api-compatibility.mdx slug: hf-compatibility - page: "Repository Structure" - path: ./nightly/pages/repository-structure.mdx + path: ../../repository-structure.mdx slug: repo-structure - page: "Release Notes" - path: ./nightly/pages/release-notes.mdx + path: ../../release-notes.mdx slug: release-notes - section: "Announcements" contents: - page: "Announcements" - path: ./nightly/pages/announcements.mdx + path: ../../announcements.mdx - section: "NeMo AutoModel Performance" slug: performance contents: - page: "Performance Summary" - path: ./nightly/pages/performance-summary.mdx + path: ../../performance-summary.mdx slug: performance-summary - section: "Model Coverage" contents: - page: "Model Coverage Overview" - path: ./nightly/pages/model-coverage/overview.mdx + path: ../../model-coverage/overview.mdx slug: overview - page: "Model Release Log" - path: ./nightly/pages/model-coverage/latest-models.mdx + path: ../../model-coverage/latest-models.mdx slug: release-log - section: "Large Language Models (LLMs)" slug: large-language-models contents: - page: "Overview" - path: ./nightly/pages/model-coverage/llm/index.mdx + path: ../../model-coverage/llm/index.mdx slug: overview - page: "Llama" - path: ./nightly/pages/model-coverage/llm/meta/llama.mdx + path: ../../model-coverage/llm/meta/llama.mdx - page: "Gemma" - path: ./nightly/pages/model-coverage/llm/google/gemma.mdx + path: ../../model-coverage/llm/google/gemma.mdx - page: "Qwen2" - path: ./nightly/pages/model-coverage/llm/qwen/qwen2.mdx + path: ../../model-coverage/llm/qwen/qwen2.mdx - page: "Qwen2 MoE" - path: ./nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx + path: ../../model-coverage/llm/qwen/qwen2-moe.mdx - page: "Qwen3" - path: ./nightly/pages/model-coverage/llm/qwen/qwen3.mdx + path: ../../model-coverage/llm/qwen/qwen3.mdx - page: "Qwen3 MoE" - path: ./nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx + path: ../../model-coverage/llm/qwen/qwen3-moe.mdx - page: "Qwen3-Next" - path: ./nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx + path: ../../model-coverage/llm/qwen/qwen3-next.mdx - page: "ERNIE 4.5" - path: ./nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx + path: ../../model-coverage/llm/baidu/ernie4-5.mdx - page: "DeepSeek" - path: ./nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx + path: ../../model-coverage/llm/deepseek-ai/deepseek.mdx - page: "DeepSeek-V3" - path: ./nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx + path: ../../model-coverage/llm/deepseek-ai/deepseek-v3.mdx - page: "DeepSeek-V4 Flash" - path: ./nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx + path: ../../model-coverage/llm/deepseek-ai/dsv4-flash.mdx - page: "Mistral" - path: ./nightly/pages/model-coverage/llm/mistralai/mistral.mdx + path: ../../model-coverage/llm/mistralai/mistral.mdx - page: "Mixtral" - path: ./nightly/pages/model-coverage/llm/mistralai/mixtral.mdx + path: ../../model-coverage/llm/mistralai/mixtral.mdx - page: "Ministral3 / Devstral" - path: ./nightly/pages/model-coverage/llm/mistralai/ministral3.mdx + path: ../../model-coverage/llm/mistralai/ministral3.mdx - page: "Phi" - path: ./nightly/pages/model-coverage/llm/microsoft/phi.mdx + path: ../../model-coverage/llm/microsoft/phi.mdx - page: "Phi-3 / Phi-4" - path: ./nightly/pages/model-coverage/llm/microsoft/phi3.mdx + path: ../../model-coverage/llm/microsoft/phi3.mdx - page: "Phi-3-Small" - path: ./nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx + path: ../../model-coverage/llm/microsoft/phi3-small.mdx - page: "Nemotron / Minitron" - path: ./nightly/pages/model-coverage/llm/nvidia/nemotron.mdx + path: ../../model-coverage/llm/nvidia/nemotron.mdx - page: "Nemotron-H" - path: ./nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx + path: ../../model-coverage/llm/nvidia/nemotron-h.mdx - page: "Nemotron-Flash" - path: ./nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx + path: ../../model-coverage/llm/nvidia/nemotron-flash.mdx - page: "Nemotron-Super (Llama-3.3-Nemotron-Super-49B)" - path: ./nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx + path: ../../model-coverage/llm/nvidia/nemotron-super.mdx - page: "ChatGLM" - path: ./nightly/pages/model-coverage/llm/thudm/chatglm.mdx + path: ../../model-coverage/llm/thudm/chatglm.mdx - page: "GLM-4" - path: ./nightly/pages/model-coverage/llm/thudm/glm4.mdx + path: ../../model-coverage/llm/thudm/glm4.mdx - page: "GLM-4 MoE (GLM-4.5 / GLM-4.7)" - path: ./nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx + path: ../../model-coverage/llm/thudm/glm4-moe.mdx - page: "GLM-5 MoE (DSA)" - path: ./nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx + path: ../../model-coverage/llm/thudm/glm5-moe-dsa.mdx - page: "Granite" - path: ./nightly/pages/model-coverage/llm/ibm/granite.mdx + path: ../../model-coverage/llm/ibm/granite.mdx - page: "Granite MoE" - path: ./nightly/pages/model-coverage/llm/ibm/granite-moe.mdx + path: ../../model-coverage/llm/ibm/granite-moe.mdx - page: "Bamba" - path: ./nightly/pages/model-coverage/llm/ibm/bamba.mdx + path: ../../model-coverage/llm/ibm/bamba.mdx - page: "OLMo" - path: ./nightly/pages/model-coverage/llm/allenai/olmo.mdx + path: ../../model-coverage/llm/allenai/olmo.mdx - page: "OLMo2" - path: ./nightly/pages/model-coverage/llm/allenai/olmo2.mdx + path: ../../model-coverage/llm/allenai/olmo2.mdx - page: "OLMoE" - path: ./nightly/pages/model-coverage/llm/allenai/olmoe.mdx + path: ../../model-coverage/llm/allenai/olmoe.mdx - page: "GPT-OSS" - path: ./nightly/pages/model-coverage/llm/openai/gpt-oss.mdx + path: ../../model-coverage/llm/openai/gpt-oss.mdx - page: "GPT-2" - path: ./nightly/pages/model-coverage/llm/openai/gpt2.mdx + path: ../../model-coverage/llm/openai/gpt2.mdx - page: "GPT-J" - path: ./nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx + path: ../../model-coverage/llm/eleutherai/gpt-j.mdx - page: "GPT-NeoX / Pythia" - path: ./nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx + path: ../../model-coverage/llm/eleutherai/gpt-neox.mdx - page: "StarCoder" - path: ./nightly/pages/model-coverage/llm/bigcode/starcoder.mdx + path: ../../model-coverage/llm/bigcode/starcoder.mdx - page: "StarCoder2" - path: ./nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx + path: ../../model-coverage/llm/bigcode/starcoder2.mdx - page: "Aquila / Aquila2" - path: ./nightly/pages/model-coverage/llm/baai/aquila.mdx + path: ../../model-coverage/llm/baai/aquila.mdx - page: "Baichuan / Baichuan2" - path: ./nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx + path: ../../model-coverage/llm/baichuan-inc/baichuan.mdx - page: "Command-R" - path: ./nightly/pages/model-coverage/llm/cohere/command-r.mdx + path: ../../model-coverage/llm/cohere/command-r.mdx - page: "Falcon" - path: ./nightly/pages/model-coverage/llm/tiiuae/falcon.mdx + path: ../../model-coverage/llm/tiiuae/falcon.mdx - page: "EXAONE" - path: ./nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx + path: ../../model-coverage/llm/lgai-exaone/exaone.mdx - page: "InternLM" - path: ./nightly/pages/model-coverage/llm/internlm/internlm.mdx + path: ../../model-coverage/llm/internlm/internlm.mdx - page: "Jais" - path: ./nightly/pages/model-coverage/llm/inceptionai/jais.mdx + path: ../../model-coverage/llm/inceptionai/jais.mdx - page: "MiniMax-M2" - path: ./nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx + path: ../../model-coverage/llm/minimax/minimax-m2.mdx - page: "MiniCPM" - path: ./nightly/pages/model-coverage/llm/openbmb/minicpm.mdx + path: ../../model-coverage/llm/openbmb/minicpm.mdx - page: "Moonlight" - path: ./nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx + path: ../../model-coverage/llm/moonshotai/moonlight.mdx - page: "Seed (ByteDance)" - path: ./nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx + path: ../../model-coverage/llm/bytedance-seed/seed.mdx - page: "Solar Pro" - path: ./nightly/pages/model-coverage/llm/upstage/solar.mdx + path: ../../model-coverage/llm/upstage/solar.mdx - page: "Orion" - path: ./nightly/pages/model-coverage/llm/orionstar/orion.mdx + path: ../../model-coverage/llm/orionstar/orion.mdx - page: "StableLM" - path: ./nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx + path: ../../model-coverage/llm/stabilityai/stablelm.mdx - page: "Step-3.5" - path: ./nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx + path: ../../model-coverage/llm/stepfun-ai/step-3-5.mdx - page: "GritLM" - path: ./nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx + path: ../../model-coverage/llm/parasail-ai/gritlm.mdx - page: "Hy3-preview" - path: ./nightly/pages/model-coverage/llm/tencent/hy3.mdx + path: ../../model-coverage/llm/tencent/hy3.mdx - page: "MiMo-V2-Flash" - path: ./nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx + path: ../../model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx - page: "Ling 2.0" - path: ./nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx + path: ../../model-coverage/llm/inclusionai/ling-2.mdx - section: "Vision Language Models (VLMs)" slug: vision-language-models contents: - page: "Overview" - path: ./nightly/pages/model-coverage/vlm/index.mdx + path: ../../model-coverage/vlm/index.mdx slug: overview - page: "Kimi-VL" - path: ./nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx + path: ../../model-coverage/vlm/moonshotai/kimi-vl.mdx - page: "Gemma 3 VL / Gemma 3n" - path: ./nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx + path: ../../model-coverage/vlm/google/gemma3-vl.mdx - page: "Gemma 4" - path: ./nightly/pages/model-coverage/vlm/google/gemma4.mdx + path: ../../model-coverage/vlm/google/gemma4.mdx - page: "Qwen2.5-VL" - path: ./nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx + path: ../../model-coverage/vlm/qwen/qwen2-5-vl.mdx - page: "Qwen3-VL / Qwen3-VL-MoE" - path: ./nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx + path: ../../model-coverage/vlm/qwen/qwen3-vl.mdx - page: "Qwen3.5-VL" - path: ./nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx + path: ../../model-coverage/vlm/qwen/qwen3-5-vl.mdx - page: "Nemotron-Parse" - path: ./nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx + path: ../../model-coverage/vlm/nvidia/nemotron-parse.mdx - page: "Ministral3 VL" - path: ./nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx + path: ../../model-coverage/vlm/mistralai/ministral3-vl.mdx - page: "Mistral Medium 3.5" - path: ./nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx + path: ../../model-coverage/vlm/mistralai/mistral-medium-3-5.mdx - page: "Mistral-Small-4" - path: ./nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx + path: ../../model-coverage/vlm/mistralai/mistral-small-4.mdx - page: "InternVL" - path: ./nightly/pages/model-coverage/vlm/internlm/internvl.mdx + path: ../../model-coverage/vlm/internlm/internvl.mdx - page: "Llama 4" - path: ./nightly/pages/model-coverage/vlm/meta/llama4.mdx + path: ../../model-coverage/vlm/meta/llama4.mdx - page: "LLaVA-OneVision" - path: ./nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx + path: ../../model-coverage/vlm/lmms-lab/llava-onevision.mdx - page: "SmolVLM" - path: ./nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx + path: ../../model-coverage/vlm/huggingface/smolvlm.mdx - page: "LLaVA" - path: ./nightly/pages/model-coverage/vlm/llava-hf/llava.mdx + path: ../../model-coverage/vlm/llava-hf/llava.mdx - section: "Omni Models" slug: omni contents: - page: "Overview" - path: ./nightly/pages/model-coverage/omni/index.mdx + path: ../../model-coverage/omni/index.mdx slug: overview - page: "Qwen3-Omni" - path: ./nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx + path: ../../model-coverage/omni/qwen/qwen3-omni.mdx - page: "Phi-4-multimodal" - path: ./nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx + path: ../../model-coverage/omni/microsoft/phi4-multimodal.mdx - page: "Nemotron-Omni" - path: ./nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx + path: ../../model-coverage/omni/nvidia/nemotron-omni.mdx - section: "Diffusion Models" slug: diffusion contents: - page: "Overview" - path: ./nightly/pages/model-coverage/diffusion/index.mdx + path: ../../model-coverage/diffusion/index.mdx slug: overview - page: "Wan 2.1 T2V" - path: ./nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx + path: ../../model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx - page: "FLUX.1-dev" - path: ./nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx + path: ../../model-coverage/diffusion/black-forest-labs/flux.mdx - page: "HunyuanVideo 1.5" - path: ./nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx + path: ../../model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx - page: "Qwen-Image" - path: ./nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx + path: ../../model-coverage/diffusion/qwen/qwen-image.mdx - section: "Embedding Models" slug: embedding-models contents: - page: "Overview" - path: ./nightly/pages/model-coverage/embedding/index.mdx + path: ../../model-coverage/embedding/index.mdx slug: overview - page: "Llama (Bidirectional)" - path: ./nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx + path: ../../model-coverage/embedding/nvidia/llama-bidirectional.mdx slug: llama-bidirectional - page: "Ministral3 (Bidirectional)" - path: ./nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx + path: ../../model-coverage/embedding/mistralai/ministral3-bidirectional.mdx slug: ministral3-bidirectional - section: "Reranking Models" slug: reranking-models contents: - page: "Overview" - path: ./nightly/pages/model-coverage/reranker/index.mdx + path: ../../model-coverage/reranker/index.mdx slug: overview - page: "Llama (Bidirectional)" - path: ./nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx + path: ../../model-coverage/reranker/nvidia/llama-bidirectional.mdx slug: llama-bidirectional - section: "Recipes & E2E Examples" contents: - page: "Recipes and End-to-End Examples" - path: ./nightly/pages/guides/overview.mdx + path: ../../guides/overview.mdx slug: overview - page: "Supervised Fine-Tuning (SFT) and Parameter-Efficient Fine-Tuning (PEFT) with NeMo AutoModel" - path: ./nightly/pages/guides/llm/finetune.mdx + path: ../../guides/llm/finetune.mdx slug: sft-peft - page: "Function Calling with NeMo AutoModel using FunctionGemma" - path: ./nightly/pages/guides/llm/toolcalling.mdx + path: ../../guides/llm/toolcalling.mdx slug: function-calling - page: "Knowledge Distillation with NeMo AutoModel" - path: ./nightly/pages/guides/llm/knowledge-distillation.mdx + path: ../../guides/llm/knowledge-distillation.mdx slug: knowledge-distillation - page: "Fine-Tune Large MoE LLMs" - path: ./nightly/pages/guides/llm/large-moe-finetune.mdx + path: ../../guides/llm/large-moe-finetune.mdx slug: large-moe-fine-tuning - page: "DeepSeek V4 Flash" - path: ./nightly/pages/guides/llm/dsv4-flash.mdx + path: ../../guides/llm/dsv4-flash.mdx slug: deepseek-v4-flash - page: "Hy3-preview" - path: ./nightly/pages/guides/llm/hy3.mdx + path: ../../guides/llm/hy3.mdx slug: hy3-preview - page: "Pretraining Megatron Core Datasets with NeMo AutoModel" - path: ./nightly/pages/guides/llm/pretraining.mdx + path: ../../guides/llm/pretraining.mdx slug: pretraining - page: "LLM Pre-Training with NeMo AutoModel" - path: ./nightly/pages/guides/llm/nanogpt-pretraining.mdx + path: ../../guides/llm/nanogpt-pretraining.mdx slug: nanogpt-pretraining - page: "Sequence Classification (SFT/PEFT) with NeMo AutoModel" - path: ./nightly/pages/guides/llm/sequence-classification.mdx + path: ../../guides/llm/sequence-classification.mdx slug: sequence-classification - page: "Fine-Tune Gemma 3 and Gemma 3n" - path: ./nightly/pages/guides/omni/gemma3-3n.mdx + path: ../../guides/omni/gemma3-3n.mdx slug: gemma-3-3n - page: "Fine-Tuning Gemma 4 31B on CORD-v2 Receipts — End-to-End Guide" - path: ./nightly/pages/guides/vlm/gemma4.mdx + path: ../../guides/vlm/gemma4.mdx slug: gemma-4 - page: "Fine-Tune Qwen3.5-VL" - path: ./nightly/pages/guides/vlm/qwen3-5.mdx + path: ../../guides/vlm/qwen3-5.mdx slug: qwen3-5-vl - page: "Nemotron-Omni" - path: ./nightly/pages/guides/vlm/nemotron-omni.mdx + path: ../../guides/vlm/nemotron-omni.mdx slug: nemotron-omni - page: "Mistral Medium 3.5 VL" - path: ./nightly/pages/guides/vlm/mistral-medium-3-5.mdx + path: ../../guides/vlm/mistral-medium-3-5.mdx slug: mistral-medium-3-5 - page: "Fine-Tune Qwen3-Omni for ASR" - path: ./nightly/pages/guides/audio/qwen3-omni-asr.mdx + path: ../../guides/audio/qwen3-omni-asr.mdx slug: qwen3-omni-asr - page: "Diffusion Model Fine-Tuning with NeMo AutoModel" - path: ./nightly/pages/guides/diffusion/finetune.mdx + path: ../../guides/diffusion/finetune.mdx slug: diffusion-fine-tuning - page: "dLLM Fine-Tuning" - path: ./nightly/pages/guides/dllm/finetune.mdx + path: ../../guides/dllm/finetune.mdx slug: dllm-fine-tuning - page: "Quantization-Aware Training (QAT) in NeMo Automodel" - path: ./nightly/pages/guides/quantization-aware-training.mdx + path: ../../guides/quantization-aware-training.mdx slug: qat - page: "Model Training on Databricks" - path: ./nightly/pages/guides/llm/databricks.mdx + path: ../../guides/llm/databricks.mdx slug: databricks - section: "Datasets" contents: - page: "Dataset Overview: LLM, VLM, and Retrieval Datasets in NeMo AutoModel" - path: ./nightly/pages/guides/dataset-overview.mdx + path: ../../guides/dataset-overview.mdx slug: overview - page: "Integrate Your Own Text Dataset" - path: ./nightly/pages/guides/llm/dataset.mdx + path: ../../guides/llm/dataset.mdx slug: text-dataset - page: "Retrieval Dataset (Embedding Fine-tuning)" - path: ./nightly/pages/guides/llm/retrieval-dataset.mdx + path: ../../guides/llm/retrieval-dataset.mdx slug: retrieval-dataset - page: "Use the ColumnMappedTextInstructionDataset" - path: ./nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx + path: ../../guides/llm/column-mapped-text-instruction-dataset.mdx slug: columnmapped-dataset - page: "Use the ColumnMappedTextInstructionIterableDataset (Streaming)" - path: ./nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx + path: ../../guides/llm/column-mapped-text-instruction-iterable-dataset.mdx slug: columnmapped-iterable - page: "Integrate Your Own Multi-Modal Dataset" - path: ./nightly/pages/guides/vlm/dataset.mdx + path: ../../guides/vlm/dataset.mdx slug: multi-modal-dataset - page: "Diffusion Dataset Preparation" - path: ./nightly/pages/guides/diffusion/dataset.mdx + path: ../../guides/diffusion/dataset.mdx slug: diffusion-dataset - section: "Job Launchers" contents: - page: "Job Launchers" - path: ./nightly/pages/launcher/overview.mdx + path: ../../launcher/overview.mdx slug: overview - page: "Run on Your Local Workstation" - path: ./nightly/pages/launcher/local-workstation.mdx + path: ../../launcher/local-workstation.mdx slug: local-workstation - page: "Run on a Cluster" - path: ./nightly/pages/launcher/slurm.mdx + path: ../../launcher/slurm.mdx slug: slurm-cluster - page: "Run with NeMo Run" - path: ./nightly/pages/launcher/nemo-run.mdx + path: ../../launcher/nemo-run.mdx slug: nemo-run - page: "Run on Any Cloud with SkyPilot" - path: ./nightly/pages/launcher/skypilot.mdx + path: ../../launcher/skypilot.mdx slug: skypilot - page: "SkyPilot k8s" - path: ./nightly/pages/launcher/skypilot-kubernetes.mdx + path: ../../launcher/skypilot-kubernetes.mdx slug: skypilot-k8s - section: "Development" contents: - page: "Checkpointing in NeMo Automodel" - path: ./nightly/pages/guides/checkpointing.mdx + path: ../../guides/checkpointing.mdx slug: checkpointing - page: "Gradient (Activation) Checkpointing in NeMo AutoModel" - path: ./nightly/pages/guides/gradient-checkpointing.mdx + path: ../../guides/gradient-checkpointing.mdx slug: gradient-checkpointing - page: "Pipeline Parallelism with AutoPipeline" - path: ./nightly/pages/guides/pipelining.mdx + path: ../../guides/pipelining.mdx slug: pipeline-parallelism - page: "FP8 Training in NeMo AutoModel" - path: ./nightly/pages/guides/fp8-training.mdx + path: ../../guides/fp8-training.mdx slug: fp8-training - page: "MLflow Logging in NeMo AutoModel" - path: ./nightly/pages/guides/mlflow-logging.mdx + path: ../../guides/mlflow-logging.mdx slug: mlflow-logging - page: "Breaking Changes" - path: ./nightly/pages/breaking-changes.mdx + path: ../../breaking-changes.mdx slug: breaking-changes - section: "API Reference" slug: api-reference contents: - page: "Overview" - path: ./nightly/pages/api-reference/index.mdx + path: ../../api-reference/index.mdx slug: overview - folder: ../product-docs/nemo-automodel/Full-Library-Reference diff --git a/docs/fern/versions/nightly/pages/about/index.mdx b/docs/fern/versions/nightly/pages/about/index.mdx deleted file mode 100644 index d35e674693..0000000000 --- a/docs/fern/versions/nightly/pages/about/index.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "About NeMo AutoModel" -description: "Overview of NeMo AutoModel, a PyTorch DTensor-native SPMD library with optimized model implementations and a Hugging Face-compatible API for training, fine-tuning, and as an accelerated backend for other frameworks" -position: 1 ---- -NeMo AutoModel is a PyTorch DTensor-native SPMD (Single Program, Multiple Data) open-source library under [NVIDIA NeMo Framework](https://github.com/NVIDIA-NeMo). It provides **optimized model implementations** with a **Hugging Face-compatible API**, so any model on the Hub works out of the box with no checkpoint conversion. On top of that, it ships ready-made **recipes** for training and fine-tuning LLMs and VLMs at scale. - -Because AutoModel exposes the same Autoclass interface as `transformers`, it can also be used as a **drop-in accelerated backend for other libraries** -- reinforcement learning frameworks, evaluation harnesses, or any codebase that loads Hugging Face models. - -## Target Users - -- **Machine learning engineers**: Fine-tune and pre-train LLMs and VLMs at scale with minimal boilerplate. -- **Researchers**: Rapidly prototype with hackable, linear training scripts and YAML-driven configuration. -- **Library and framework authors**: Use AutoModel's optimized model implementations as a drop-in replacement for `transformers` to accelerate RL, alignment, evaluation, or any downstream workflow. - -## How It Works - -NeMo AutoModel is built around two core ideas: **recipes** and **components**. - -- **Recipes** are executable Python scripts paired with YAML configs. Each recipe defines an end-to-end workflow -- model loading, data preparation, training loop, and checkpointing -- and can be launched with a single command. -- **Components** are modular, self-contained building blocks (datasets, optimizers, loss functions, distribution strategies) that recipes compose together. Swap any component by changing a `_target_` field in your YAML. - -This design means the training loop is always visible and hackable -- no hidden abstractions. You configure parallelism, precision, and scaling through config, not code changes. - -### SPMD and DTensor - -NeMo AutoModel uses PyTorch's native SPMD (Single Program, Multiple Data) model with DTensor and DeviceMesh: - -- **One program, any scale**: The same training script runs on 1 GPU or 1000+ by changing the mesh configuration. -- **Parallelism is configuration**: Mix tensor, sequence, pipeline, and data parallelism by editing placements -- no model rewrites. -- **Decoupled concerns**: Model code stays pure PyTorch; the parallel strategy lives in config. - -### Key Technologies - -- **FSDP2 and MegatronFSDP**: Memory-efficient sharded data parallelism for large-scale training, including Hybrid Sharding (HSDP). -- **Pipeline Parallelism**: Torch-native pipelining composable with FSDP2 and DTensor for 3D parallelism. -- **Custom CUDA Kernels**: Fused attention, TransformerEngine, DeepEP, and FlexAttn for optimized throughput. -- **FP8 Mixed Precision**: FP8 training via torchao for supported models. -- **Distributed Checkpointing (DCP)**: Sharded SafeTensors checkpoints with merge and reshard utilities, interoperable with Hugging Face. - -## Hugging Face Integration - -NeMo AutoModel builds on top of `transformers` rather than replacing it: - -- Load any `AutoModelForCausalLM` or `AutoModelForImageTextToText` model directly from the Hub. -- Use Hugging Face tokenizers, datasets, and chat templates as-is. -- Checkpoints stay in the native Hugging Face format -- no conversion step before or after training. -- New models released on the Hub get day-0 support because AutoModel tracks the latest `transformers` version. - -See the [Hugging Face API Compatibility](/get-started/hf-compatibility) guide and [Model Coverage](/model-coverage/overview) for details. - -## Optimized Model Implementations - -AutoModel ships optimized implementations for supported architectures (fused attention, TransformerEngine layers, DeepEP for MoE routing, FlexAttn) while keeping the standard `transformers` API surface. This means: - -- **Faster training and inference** with no code changes -- load a model the same way you would with `transformers` and get accelerated kernels automatically. -- **No checkpoint conversion** -- weights are loaded from and saved to the native Hugging Face format. -- **Day-0 model support** -- because AutoModel builds on `transformers`, newly released models on the Hub work immediately. Optimized kernels are added incrementally for popular architectures. - -## Use as a Library - -NeMo AutoModel is not limited to its built-in training recipes. Because it implements the Hugging Face `AutoModel` API, any library or framework that loads models through `transformers` can swap in AutoModel to get optimized performance: - -- **Reinforcement learning** (e.g., TRL, OpenRLHF) -- replace the policy or reference model with an AutoModel instance for faster rollouts and gradient steps. -- **Evaluation and benchmarking** -- plug into lm-evaluation-harness or custom eval loops with no API changes. -- **Custom training loops** -- import individual components (optimizers, loss functions, distributed strategies) without using recipes at all. - -```python -from nemo_automodel import NeMoAutoModelForCausalLM - -model = NeMoAutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B") -``` - -The returned model is a standard `nn.Module` with the same forward signature as the `transformers` equivalent, so it works anywhere a Hugging Face model is expected. - -## What's Next - - - -Explore the main features, supported workflows, and core concepts. - - - -Jump to the quickstart table to find the right guide for your task. - - - diff --git a/docs/fern/versions/nightly/pages/about/key-features.mdx b/docs/fern/versions/nightly/pages/about/key-features.mdx deleted file mode 100644 index 288cbff071..0000000000 --- a/docs/fern/versions/nightly/pages/about/key-features.mdx +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: "Key Features and Concepts" -description: "Key features and core concepts of NeMo AutoModel for scalable LLM and VLM training with Hugging Face integration" -position: 2 ---- -NeMo AutoModel provides GPU-accelerated, `transformers`-compatible training for LLMs and VLMs. It combines Hugging Face's model ecosystem with NVIDIA's optimized training stack, delivering high throughput without sacrificing ease of use. - -## Why NeMo AutoModel? - -- **Hugging Face native**: Train any model from the Hub with no checkpoint conversion -- day-0 support for new releases. -- **High performance**: Custom CUDA kernels (TransformerEngine, DeepEP, FlexAttn) deliver up to 279 TFLOPs/sec/GPU. -- **Any scale**: The same recipe runs on 1 GPU or across hundreds of nodes -- parallelism is configuration, not code. -- **Hackable**: Linear training scripts with YAML config. No hidden trainer abstractions. -- **Open source**: Apache 2.0 licensed, NVIDIA-supported, and actively maintained. - -### Performance Highlights - -| Model | GPUs | TFLOPs/sec/GPU | Tokens/sec/GPU | Optimizations | -|-------|-----:|---------------:|---------------:|---------------| -| DeepSeek V3 671B | 256 | 250 | 1,002 | TE + DeepEP | -| GPT-OSS 20B | 8 | 279 | 13,058 | TE + DeepEP + FlexAttn | -| Qwen3 MoE 30B | 8 | 212 | 11,842 | TE + DeepEP | - -See the [full benchmark results](/performance/performance-summary) for configuration details and more models. - ---- - -## Training Workflows - -NeMo AutoModel supports a range of training tasks across LLM and VLM modalities. - - - -Full-parameter fine-tuning for task-specific adaptation. - - - -Memory-efficient fine-tuning by updating only low-rank adapter weights. - - - -Train models from scratch on large-scale datasets. - - - -Transfer knowledge from a large teacher to a smaller student model. - - - -Fine-tune models for structured function calling with tool schemas. - - - -Train with quantization for deployment-ready models. - - - - ---- - -## Parallelism and Scaling - -NeMo AutoModel leverages PyTorch-native parallelism strategies to scale training from a single GPU to multi-node clusters. - - - -Fully Sharded Data Parallelism with DTensor for memory-efficient distributed training. Supports Hybrid Sharding (HSDP) for multi-node. - - - -Torch-native pipelining composable with FSDP2 and DTensor for 3D parallelism. - - - -FP8 training via torchao for reduced memory and higher throughput on supported models. - - - -Add a `slurm:` section to any YAML config and launch with the `automodel` CLI. See the [Cluster guide](/job-launchers/slurm-cluster). - - - - ---- - -## Core Concepts - -### Recipes - -Recipes are executable Python scripts paired with YAML configuration files. Each recipe defines a complete training workflow: - -1. **Load** a model and tokenizer from Hugging Face (via `_target_` in YAML) -2. **Prepare** a dataset with the appropriate collator and chat template -3. **Train** with a configurable loop (gradient accumulation, validation, logging) -4. **Checkpoint** using Distributed Checkpoint (DCP) with SafeTensors output - -```yaml -recipe: - _target_: nemo_automodel.recipes.llm.train_ft.TrainFinetuneRecipeForNextTokenPrediction - -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad - split: train -``` - -Override any field from the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --step_scheduler.local_batch_size 16 -``` - -### Components - -Components are modular, self-contained building blocks that recipes assemble: - -| Component | Purpose | -|-----------|---------| -| `datasets/` | LLM and VLM datasets with collators, tokenization, and chat templates | -| `distributed/` | FSDP2, MegatronFSDP, tensor/sequence/pipeline parallelism | -| `_peft/` | LoRA and QLoRA implementations | -| `attention/` | Fused attention, rotary embeddings, FlexAttn | -| `checkpoint/` | DCP save/load with SafeTensors output | -| `moe/` | Mixture of Experts routing and DeepEP integration | -| `optim/` | Optimizers and LR schedulers | -| `loss/` | Cross-entropy, linear cross-entropy, KD loss | -| `launcher/` | SLURM and interactive job launch | - -Each component can be used independently and has no cross-module imports. - -### The `automodel` CLI - -The CLI simplifies job launch across environments: - -```bash -# Single-node interactive -automodel config.yaml - -# Multi-node SLURM batch -sbatch my_cluster.sub # copy slurm.sub, edit CONFIG & SBATCH directives, then submit -``` - -See the [Run on Your Local Workstation](/job-launchers/local-workstation) and [Cluster](/job-launchers/slurm-cluster) guides. - ---- - -## Checkpointing - -NeMo AutoModel writes Distributed Checkpoints (DCP) with SafeTensors shards. Checkpoints carry partition metadata to: - -- **Merge** into a single Hugging Face-compatible checkpoint for inference or sharing. -- **Reshard** when loading onto a different mesh or topology. -- **Resume** training from any checkpoint without manual intervention. - -See the [Checkpointing guide](/development/checkpointing) for details. - -## Experiment Tracking - -NeMo AutoModel integrates with MLflow and Weights & Biases for experiment tracking, metric logging, and artifact management. See the [Experiment Tracking guide](/development/mlflow-logging). diff --git a/docs/fern/versions/nightly/pages/announcements.mdx b/docs/fern/versions/nightly/pages/announcements.mdx deleted file mode 100644 index 2df7a45855..0000000000 --- a/docs/fern/versions/nightly/pages/announcements.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: "Announcements" -description: "" -position: 1 ---- -See also the [Model Coverage Release Log](/model-coverage/overview#release-log) for newly supported models across releases. - -- [Accelerating Large-Scale Mixture-of-Experts Training in PyTorch with NeMo Automodel](https://github.com/NVIDIA-NeMo/Automodel/discussions/777) -- [Challenges in Enabling PyTorch Native Pipeline Parallelism for Hugging Face Transformer Models](https://github.com/NVIDIA-NeMo/Automodel/discussions/589) -- [Google Gemma 3n: Efficient Multimodal Fine-tuning Made Simple](https://github.com/NVIDIA-NeMo/Automodel/discussions/494) -- [Fine-tune Hugging Face Models Instantly with Day-0 Support with NVIDIA NeMo AutoModel](https://github.com/NVIDIA-NeMo/Automodel/discussions/477) diff --git a/docs/fern/versions/nightly/pages/automodel_diagram.png b/docs/fern/versions/nightly/pages/automodel_diagram.png deleted file mode 100644 index bb56ea575aface85535f2909e50498875f04e244..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50597 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

%IYnP>v#pL-Q(F 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 -c -``` - -**After:** - -``` -automodel [--nproc-per-node N] [--overrides ...] -``` - -A short alias `am` is also available: - -``` -am [--nproc-per-node N] [--overrides ...] -``` - -The positional `` and `` arguments have been removed. The recipe -class is now specified inside the YAML config via the `recipe._target_` key. - -### YAML Config: New Required `recipe` Section - -All YAML configs now require a top-level `recipe:` key: - -```yaml -recipe: - _target_: nemo_automodel.recipes.llm.train_ft.TrainFinetuneRecipeForNextTokenPrediction -``` - -Configs without this key will produce an error with guidance on which target to add. - -#### Available Recipe Targets - -| Use Case | `_target_` | -|---|---| -| LLM fine-tuning / pre-training | `nemo_automodel.recipes.llm.train_ft.TrainFinetuneRecipeForNextTokenPrediction` | -| VLM fine-tuning | `nemo_automodel.recipes.vlm.finetune.FinetuneRecipeForVLM` | -| Knowledge distillation | `nemo_automodel.recipes.llm.kd.KnowledgeDistillationRecipeForNextTokenPrediction` | -| Benchmarking | `nemo_automodel.recipes.llm.benchmark.BenchmarkingRecipeForNextTokenPrediction` | -| Sequence classification | `nemo_automodel.recipes.llm.train_seq_cls.TrainFinetuneRecipeForSequenceClassification` | -| Biencoder training | `nemo_automodel.recipes.biencoder.train_biencoder.TrainBiencoderRecipe` | - -### Launcher Configuration Moved to YAML - -Multi-node launch settings (Kubernetes, NeMo-Run) are now configured -entirely within the YAML config file rather than through CLI arguments. - -| Launcher | YAML section | -|---|---| -| Kubernetes | `k8s:` | -| NeMo-Run | `nemo_run:` | - -If none of these sections are present the job runs locally (interactive mode). - -### SLURM: Script-Based Submission - -The `slurm:` YAML section and all related fields have been removed. SLURM -jobs are now submitted with `sbatch` directly, using a self-contained sbatch -script. Copy the reference template and adapt it to your cluster: - -```bash -cp slurm.sub my_cluster.sub -# Edit CONFIG, #SBATCH directives, container, mounts, etc. -sbatch my_cluster.sub -``` - -The script runs `torchrun -m nemo_automodel.cli.app` on each node, which -detects the distributed environment and executes the recipe in-process. -All cluster-specific configuration lives in the sbatch script where you can -see and edit it directly. - -### Lightweight CLI-Only Install - -A new `automodel[cli]` install extra is available for login nodes or environments -where you only need to submit jobs (SLURM, k8s, NeMo-Run) without running -training locally: - -``` -pip install nemo-automodel[cli] -``` - -This installs only `pyyaml` -- no PyTorch, no CUDA dependencies. It is enough -to submit jobs via SLURM or Kubernetes. If you also need NeMo-Run, install it -separately (`pip install nemo-run`). If you try to run a local/interactive job -with the CLI-only install, you will get a clear error message with instructions -to install the full package. - -### CLI Module Lives Inside the Package - -The CLI entry-point lives at `nemo_automodel/cli/app.py` and is registered as -the `automodel` / `am` console entry-points. A thin convenience wrapper -(`app.py`) at the repository root is available for running from a source -checkout but is **not** installed as part of the package. - -### Example Wrapper Scripts Deprecated - -The Python wrapper scripts in `examples/` (for example, `examples/llm_finetune/finetune.py`) -are deprecated. They now print a deprecation warning and delegate to the recipe -directly. Use `automodel ` instead. diff --git a/docs/fern/versions/nightly/pages/documentation.mdx b/docs/fern/versions/nightly/pages/documentation.mdx deleted file mode 100644 index b6865466b5..0000000000 --- a/docs/fern/versions/nightly/pages/documentation.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "Documentation Development" -description: "" ---- -- [Documentation Development](#documentation-development) - - [Build the Documentation](#build-the-documentation) - - [Live Building](#live-building) - - [Documentation Version](#documentation-version) - -## Build the Documentation - -The following sections describe how to set up and build the NeMo Automodel documentation. - -Switch to the documentation source folder and generate HTML output. - -```sh -cd docs/ -uv run sphinx-build . _build/html -``` - -* The resulting HTML files are generated in a `_build/html` folder that is created under the project `docs/` folder. -* The generated python API docs are placed in `apidocs` under the `docs/` folder. - -## Live Building - -When writing documentation, it can be helpful to serve the documentation and have it update live while you edit. - -To do so, run: - -```sh -cd docs/ -uv run sphinx-autobuild . _build/html --port 12345 --host 0.0.0.0 -``` - -Open a web browser and go to `http://0.0.0.0:12345` to view the output. - -## Documentation Version - -The three files below control the version switcher. Before you attempt to publish a new version of the documentation, update these files to match the latest version numbers. - -* docs/versions1.json -* docs/project.json -* docs/conf.py diff --git a/docs/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx b/docs/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx deleted file mode 100644 index 0191e7f662..0000000000 --- a/docs/fern/versions/nightly/pages/guides/audio/qwen3-omni-asr.mdx +++ /dev/null @@ -1,256 +0,0 @@ ---- -title: "Fine-Tune Qwen3-Omni for ASR" -description: "End-to-end ASR fine-tuning of Qwen3-Omni-30B on Hugging Face audio datasets with NeMo AutoModel." ---- - -End-to-end ASR fine-tuning of `Qwen/Qwen3-Omni-30B-A3B-Instruct` on a -Hugging Face audio dataset, using the NeMo AutoModel VLM training stack. The -running example is the public -[`edinburghcstr/ami`](https://huggingface.co/datasets/edinburghcstr/ami) -meeting corpus (English IHM), but the same recipe works for any HF dataset -that exposes `{audio, text}` columns (AMI, LibriSpeech, GigaSpeech, -WenetSpeech, CommonVoice, …). - -The workflow has two stages: - -1. **Train** the thinker sub-model with the `FinetuneRecipeForVLM` recipe. -2. **Convert** the NeMo-saved thinker checkpoint into a Hugging Face-compatible - Qwen3-Omni export so `transformers.AutoModel*` and vLLM can load it. - ---- - -## Data Preparation - -### Built-In Builder: `make_hf_audio_asr_dataset` - -`nemo_automodel.components.datasets.vlm.datasets.make_hf_audio_asr_dataset` -returns a Hugging Face `Dataset` whose `__getitem__` lazily produces a single -`{"conversation": [...]}` dict suitable for `qwen3_omni_asr_collate_fn`. Key -design points: - -* **`with_transform` for lazy decoding.** Building the dataset object is a - constant-time metadata read; audio decode and chat-template assembly only - run inside dataloader workers when a batch is fetched. Startup time is - independent of split size. -* **Configurable prompt shape.** Defaults are `system_prompt=None` and - `user_prompt=None`, yielding the minimal `user(audio) → assistant(text)` - conversation. Setting either or both expands the conversation: - `system_prompt="..."` adds a `system` turn, `user_prompt="..."` prepends a - text item before the audio inside the user turn. Whitespace-only prompts - are treated as absent. -* **Dataset-agnostic.** Accepts any HF audio dataset that exposes an audio - column and a transcript column. Defaults (`audio_column="audio"`, - `text_column="text"`, `name=None`) cover AMI, LibriSpeech, GigaSpeech, and - WenetSpeech out of the box; per-dataset overrides go in the recipe YAML. - -```python -from nemo_automodel.components.datasets.vlm.datasets import ( - make_hf_audio_asr_dataset, -) - -dataset = make_hf_audio_asr_dataset( - path_or_dataset="edinburghcstr/ami", - name="ihm", - split="train", - sampling_rate=16000, - user_prompt="Transcribe the English audio into text.", -) -# dataset[0]["conversation"] yields: -# [ -# {"role": "user", "content": [{"type": "text", "text": "Transcribe…"}, -# {"type": "audio", "audio": np.ndarray}]}, -# {"role": "assistant", "content": [{"type": "text", "text": "..."}]}, -# ] -``` - -### Built-In Collate: `qwen3_omni_asr_collate_fn` - -`nemo_automodel.components.datasets.vlm.collate_fns.qwen3_omni_asr_collate_fn` -batches the lazy samples into model inputs without depending on -`qwen_omni_utils`: - -* Walks each conversation for `{"type": "audio", "audio": }` items - and feeds the raw waveforms straight to `Qwen3OmniMoeProcessor`'s - `WhisperFeatureExtractor` (skipping the `process_mm_info` helper). -* Validates and coerces every audio payload through - `_validate_and_coerce_audio_payload` (1-D `float32`; otherwise raises - `ValueError` naming the sample index and offending shape/dtype). -* Pins `padding_side="right"` so the recipe's `count_tail_padding` token - accounting works correctly. -* Reuses `build_labels_from_template` (marker-based; `Qwen3OmniMoeProcessor` - is in `_IMSTART_TEMPLATE_PROCESSORS`) and emits pre-shifted labels. - -The collate is selected through the YAML's `dataloader.collate_fn._target_`; it -is intentionally **not** registered in the global `COLLATE_FNS` map so the -existing `Qwen3OmniMoeProcessor → qwen3_omni_collate_fn` mapping keeps -serving non-ASR VLM users that *do* have `qwen_omni_utils` installed. - -### Use a Different HF Audio Dataset - -To target your own dataset, set `dataset.path_or_dataset` and override the -defaults below only when the dataset diverges: - -| Dataset | `path_or_dataset` | `name` | `text_column` | -|-----------------------------------------|----------------------------------------|------------------------------|-------------------| -| `edinburghcstr/ami` | `edinburghcstr/ami` | `ihm` or `sdm` | `text` (default) | -| `openslr/librispeech_asr` | `openslr/librispeech_asr` | optional config | `text` (default) | -| `speechcolab/gigaspeech` | `speechcolab/gigaspeech` | optional config | `text` (default) | -| `mozilla-foundation/common_voice_*` | `mozilla-foundation/common_voice_18_0` | language code (e.g., `en`) | **`sentence`** | - -YAML override snippet for CommonVoice (note `text_column: sentence`): - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.vlm.datasets.make_hf_audio_asr_dataset - path_or_dataset: mozilla-foundation/common_voice_18_0 - name: en - text_column: sentence - split: train - sampling_rate: 16000 -``` - -Audio columns are universally named `audio` across these datasets, so the -default `audio_column="audio"` rarely needs an override. - ---- - -## Train - -### Example Config - -`examples/audio_finetune/qwen3_omni_asr/ami_sft.yaml` is a ready-to-run full -fine-tune for the 30B-A3B Omni model on a single 8-GPU node, targeting the -public AMI IHM corpus. Defaults: - -| Section | Setting | -|--------------------|----------------------------------------------------------------------------------------| -| `recipe` | `FinetuneRecipeForVLM` | -| `distributed` | `fsdp2`, `ep_size=8`, `tp=cp=pp=1` | -| `freeze_config` | `freeze_vision_tower=true`, `freeze_audio_tower=false`, `freeze_language_model=false` | -| `step_scheduler` | `global_batch_size=64`, `local_batch_size=8`, `ckpt_every_steps=200`, `num_epochs=1` | -| `optimizer` | `AdamW(lr=2.0e-5, betas=[0.9, 0.95], weight_decay=0.0)` | -| `checkpoint` | `result/checkpoints/...`, `model_save_format=safetensors`, `save_consolidated=true` | -| `dataset` | `make_hf_audio_asr_dataset(path_or_dataset="edinburghcstr/ami", name="ihm")` | - -`peft:` is intentionally omitted — both the language model and the audio -tower are trainable; the vision tower stays frozen. With `ep_size=8`, the MoE -experts are sharded across all 8 GPUs. - -Measured on 8x H100 80 GB: ~1.4 step/s steady-state, ~36–40 GB peak/GPU. -One epoch over the ~69k post-1.0s-filter AMI IHM train clips finishes in -~22 min (compared to ~2 h at `local_batch_size=1`). Peak memory on this MoE is -dominated by FSDP/expert all-gather (~36 GB), not by activations, so the batch -size can be pushed this high without OOM. - - -### Launch - -Use the standard NeMo AutoModel CLI: - -```bash -torchrun --nproc_per_node=8 --nnodes=1 -m nemo_automodel.cli.app \ - examples/audio_finetune/qwen3_omni_asr/ami_sft.yaml -``` - -Any per-field CLI override (e.g., `--dataset.split 'train[:5000]'`) is -forwarded to the YAML. Optional WandB logging streams online as long as -`WANDB_API_KEY` is set in the environment; set `WANDB_MODE=offline` for a -dry run. - -### What Gets Saved - -Every `ckpt_every_steps` steps the recipe writes a consolidated checkpoint: - -``` -epoch_E_step_S/ -├── config.yaml # snapshot of the recipe config -├── losses.json -├── dataloader/ # StatefulDataLoader state for restart -├── optim/ # AdamW state (~30 GB / shard for 30B FT) -├── rng/ # PyTorch + numpy + python RNG state -├── step_scheduler.pt -└── model/ - ├── shard-XXXXX-model-00001-of-00001.safetensors # DCP sharded - ├── consolidated/ # HF-format export - │ ├── config.json # thinker subtree only - │ ├── model.safetensors.index.json - │ ├── model-00001-of-00013.safetensors - │ └── ... - └── chat_template.jinja, tokenizer*.json, processor_config.json -``` - -The `consolidated/` directory is the artifact to use for inference. It already -holds the trained weights and the right tokenizer + processor — but its -`config.json` describes the *thinker sub-model only* -(`model_type=qwen3_omni_moe_thinker`), which neither `transformers.AutoConfig` -nor vLLM recognizes as a top-level architecture. See the Convert section for the -conversion step. - -### Resume - -`--checkpoint.restore_from ` reloads the model state, optimizer, -RNG, and dataloader position. Full-FT checkpoints are loaded directly into -the sharded model parts. The recipe does not require the conversion step -below for restart — only for *external* inference tooling. - ---- - -## Convert: Thinker → HF-Compatible Omni - -NeMo maps `Qwen3OmniMoeForConditionalGeneration` to a custom *thinker-only* -class (the parent Omni model in HF has `thinker / code2wav / talker` -sub-modules; this recipe only needs the thinker for ASR). The saved -`consolidated/config.json` therefore carries -`model_type=qwen3_omni_moe_thinker`, which is **not registered as a top-level -architecture** in `transformers.CONFIG_MAPPING`. Loading it directly will -fail with: - -```text -ValueError: The checkpoint you are trying to load has model type -`qwen3_omni_moe_thinker` but Transformers does not recognize this architecture. -``` - -### Tool: `tools/wrap_thinker_ckpt_as_omni.py` - -`tools/wrap_thinker_ckpt_as_omni.py` rewraps the thinker checkpoint as a -full Qwen3-Omni export by: - -1. Renaming + copying the trained `thinker.*` shards into the output dir. -2. Copying the untrained `code2wav.*` and `talker.*` shards verbatim from - the cached HF base model (these were never modified during ASR training). -3. Writing a merged `model.safetensors.index.json` across all three buckets. -4. Replacing the bogus `config.json` with the base model's - (`model_type=qwen3_omni_moe`, - `architectures=["Qwen3OmniMoeForConditionalGeneration"]`). -5. Copying the rest of the HF metadata (tokenizer, processor, generation - config, chat template) from the base; the recipe-saved `chat_template.jinja` - wins if present. - -Memory footprint stays at roughly one shard (~5 GB) at a time — no full-model -materialisation. - -```bash -python tools/wrap_thinker_ckpt_as_omni.py \ - --ckpt-dir result/checkpoints//epoch_0_step_199/model/consolidated \ - --base-dir ~/.cache/huggingface/hub/models--Qwen--Qwen3-Omni-30B-A3B-Instruct/snapshots/ \ - --out-dir /tmp/qwen3_omni_asr_step_199_wrapped -``` - -The output directory is a drop-in replacement for the public Qwen3-Omni -snapshot — only the `thinker.*` weights differ. - ---- - -## Results: AMI IHM - -End-of-epoch evaluation on the AMI IHM `test` split, comparing the -zero-shot base Qwen3-Omni against the same model after one epoch of full -fine-tuning with the recipe above (audio tower trainable). WER drops by -roughly half: - -![AMI IHM WER: base vs. fine-tuned Qwen3-Omni](./qwen_omni_asr.png) - -| Stage | Model | WER (AMI IHM test) | -|-----------------|-------------------------------------------------------|--------------------| -| Before training | Base `Qwen/Qwen3-Omni-30B-A3B-Instruct` (zero-shot) | 15.81% | -| After training | 1 epoch full FT (audio tower trainable) | **8.31%** | diff --git a/docs/fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png b/docs/fern/versions/nightly/pages/guides/audio/qwen_omni_asr.png deleted file mode 100644 index 1b6043c4ce7ea9341bd2ef3a02ee488e3e2335eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74676 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

CcLbj5DpU4QaMSOR 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 diff --git a/docs/fern/versions/nightly/pages/guides/checkpointing.mdx b/docs/fern/versions/nightly/pages/guides/checkpointing.mdx deleted file mode 100644 index 68bdb1da8f..0000000000 --- a/docs/fern/versions/nightly/pages/guides/checkpointing.mdx +++ /dev/null @@ -1,348 +0,0 @@ ---- -title: "Checkpointing in NeMo Automodel" -description: "" -position: 1 ---- -## Introduction - -During machine-learning experiments, the model-training routine regularly saves checkpoints. A checkpoint is a complete snapshot of a run that includes model weights, optimizer states, and other metadata required to resume training exactly where it left off. Writing these snapshots at regular intervals lets you recover quickly from crashes or pauses without losing progress. - -NeMo Automodel checkpoints capture the complete state of a distributed training run across multiple GPUs or nodes. This reduces memory overhead, improves GPU utilization, and allows training to be resumed with a different parallelism strategy. - -NeMo Automodel writes checkpoints in two formats: [Hugging Face Safetensors](https://github.com/safetensors/safetensors) and [PyTorch Distributed Checkpointing (DCP)](https://docs.pytorch.org/docs/stable/distributed.checkpoint.html). It also supports two layouts: - -- **Consolidated Checkpoints**: The complete model state is saved as a Hugging Face-compatible bundle, typically in a single file or a compact set of files with an index. Because tensors are not split across GPUs (unsharded), tools like Hugging Face, vLLM, and SGLang can load these checkpoints directly. - -- **Sharded Checkpoints**: During distributed training with parameter sharing, each GPU holds a subset (or "shard") of the full state, such as model weights and optimizer states. When checkpointing, each GPU writes its own shard independently without reconstructing the full model state. - -We provide an overview of the different types of available checkpoint formats in the table below. - -Task | Model domain | DCP (sharded) | Safetensors (sharded) | Safetensors (consolidated) | ------|----------------------|:-----------:|:-------------------:|:------------------------:| -SFT | LLM | ✅ | ✅ | ✅ | -SFT | VLM | ✅ | ✅ | ✅ | -PEFT | LLM / VLM | 🚧 | 🚧 | ✅ | - -Changing between output formats can be done seamlessly through the recipe's `yaml` configuration file: -```yaml -checkpoint: - ... - model_save_format: safetensors # Format for saving (torch_save or safetensors) - save_consolidated: true # Change to false if you want to save sharded checkpoints. - ... -``` -> **Note:** For optimal compatibility with the Hugging Face ecosystem, including downstream tools such as vLLM and SGLang, we recommend using the checkpoint configuration provided above. - - -The optimizer states are _always_ saved in DCP (`.distcp` extension) format. - - - -## Checkpoint Symbolic Links - -NeMo Automodel automatically creates symbolic links in the checkpoint directory to provide convenient access to important checkpoints: - -- **LATEST**: Points to the most recently saved checkpoint. This is useful for resuming training from the last saved state. -- **LOWEST_VAL**: Points to the checkpoint with the lowest validation score/loss. This provides easy access to the best-performing checkpoint based on validation metrics, making it ideal for model evaluation or deployment. - -These symbolic links eliminate the need to manually track checkpoint names or search through directories to find the best model. When validation is enabled in your training run, both links are automatically maintained and updated as training progresses. - -## Safetensors -To ensure seamless integration with the Hugging Face ecosystem, NeMo Automodel saves checkpoints in the [Safetensors](https://github.com/safetensors/safetensors) format. Safetensors is a memory-safe, zero-copy alternative to Python's pickle (PyTorch .bin), natively supported by Hugging Face Transformers, offering both safety and performance advantages over Python pickle-based approaches. - -### Key Benefits: -- **Native Hugging Face Compatibility**: Checkpoints can be loaded directly into Hugging Face-compatible tools, including vLLM, SGLang, and others. -- **Memory Safety and Speed**: The Safetensors format prohibits saving serialized Python code, ensuring memory safety, and supports zero-copy loading for improved performance. -- **Optional Consolidation**: Sharded checkpoints can be merged into a standard Hugging Face model format for easier downstream use. - -**Most importantly**, this format offers the added advantage of optionally consolidating multiple shards into a complete Hugging Face format model. - -### Example - -The following command runs the LLM fine-tuning recipe on two GPUs and saves the resulting checkpoint in the Safetensors format: -```bash -automodel --nproc-per-node=2 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --step_scheduler.ckpt_every_steps 20 \ - --checkpoint.model_save_format safetensors \ - --checkpoint.save_consolidated True -``` - - -In the above command we used the [`llama3_2_1b_squad.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/492add84a2b9d495946fe211c28973cd00051f3e/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml) config as a running example, adjust as necessary to your case. -More config examples can be found in our [`examples/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples) directory. - - - -If you're running on a single GPU, you can run: -```bash -automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --step_scheduler.ckpt_every_steps 20 \ - --checkpoint.model_save_format safetensors \ - --checkpoint.save_consolidated True -``` - -After running for a few seconds, the standard output should be: -``` -... -> Saving checkpoint to checkpoints/epoch_0_step_20 -... -``` - -The `checkpoints/` should have the following contents: -``` -checkpoints/ -├── LATEST -> epoch_0_step_20 -├── LOWEST_VAL -> epoch_0_step_20 -└── epoch_0_step_20 - ├── model - │ ├── consolidated - │ │ ├── config.json - │ │ ├── generation_config.json - │ │ ├── model-00001-of-00001.safetensors - │ │ ├── model.safetensors.index.json - │ │ ├── special_tokens_map.json - │ │ ├── tokenizer.json - │ │ └── tokenizer_config.json - │ ├── shard-00001-model-00001-of-00001.safetensors - │ └── shard-00002-model-00001-of-00001.safetensors - └── optim - ├── __0_0.distcp - └── __1_0.distcp -... -``` - -The `epoch_0_step_20/` directory stores the full training state from step `20` of the first epoch, including both the model and optimizer states. - -We can load and run the consolidated checkpoint using the Hugging Face Transformers API directly: -```python -import torch -from transformers import pipeline - -model_id = "checkpoints/epoch_0_step_20/model/consolidated/" -pipe = pipeline( - "text-generation", - model=model_id, - torch_dtype=torch.bfloat16, - device_map="auto", -) - -print(pipe("The key to life is")) - ->>> [{'generated_text': 'The key to life is to be happy. The key to happiness is to be kind. The key to kindness is to be'}] -``` - -Although this example uses the Hugging Face Transformers API, the `consolidated/` checkpoint is compatible with any Hugging Face-compatible tool, such as vLLM, SGLang, and others. - -## PEFT -When training with Parameter-Efficient Fine-Tuning (PEFT) techniques, only a small subset of model weights are updated — the rest of the model remains frozen. This dramatically reduces the size of the checkpoint, often to just a few megabytes. - -### Why Consolidated Checkpoints? -Because the PEFT state is so lightweight, sharded checkpointing adds unnecessary overhead. Instead, NeMo Automodel automatically saves a single, consolidated Hugging Face–compatible checkpoint when using PEFT. This makes it: - -- easier to manage and share (just the adapters), -- compatible with Hugging Face Transformers out of the box, -- ideal for deployment and downstream evaluation. - -### Example: PEFT Fine-Tuning on Two GPUs - -To fine-tune a model using PEFT and save a Hugging Face–ready checkpoint: -```bash -automodel --nproc-per-node=2 examples/llm_finetune/llama3_2/llama3_2_1b_hellaswag_peft.yaml --step_scheduler.ckpt_every_steps 20 --checkpoint.model_save_format safetensors -``` - -After training, you'll get a compact, consolidated Safetensors checkpoint that can be loaded directly with Hugging Face tools: - -``` -checkpoints/ -├── LATEST -> epoch_0_step_20 -├── LOWEST_VAL -> epoch_0_step_20 -├── epoch_0_step_20 -│ ├── config.yaml -│ ├── dataloader -│ │ ├── dataloader_dp_rank_0.pt -│ │ └── dataloader_dp_rank_1.pt -│ ├── losses.json -│ ├── model -│ │ ├── adapter_config.json -│ │ ├── adapter_model.safetensors -│ │ ├── automodel_peft_config.json -│ │ ├── special_tokens_map.json -│ │ ├── tokenizer.json -│ │ └── tokenizer_config.json -│ ├── optim -│ │ ├── __0_0.distcp -│ │ └── __1_0.distcp -│ ├── rng -│ │ ├── rng_dp_rank_0.pt -│ │ └── rng_dp_rank_1.pt -│ └── step_scheduler.pt -├── training.jsonl -└── validation.jsonl -``` - -The example below showcases the direct compatibility of NeMo Automodel with Hugging Face and PEFT: -```python -from peft import AutoPeftModelForCausalLM -from transformers import AutoTokenizer - -checkpoint_path = "checkpoints/epoch_0_step_20/model/" -model = AutoPeftModelForCausalLM.from_pretrained(checkpoint_path) -tokenizer = AutoTokenizer.from_pretrained(checkpoint_path) - -model = model.to("cuda") -model.eval() -inputs = tokenizer("Preheat the oven to 350 degrees and place the cookie dough", return_tensors="pt") - -outputs = model.generate(input_ids=inputs["input_ids"].to("cuda"), max_new_tokens=50) -print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0]) - ->>> Preheat the oven to 350 degrees and place the cookie dough in a large bowl. Roll the dough into 1-inch balls and place them on a cookie sheet. Bake the cookies for 10 minutes. While the cookies are baking, melt the chocolate chips in the microwave for 30 seconds. -``` - -## PyTorch DCP -NeMo Automodel also offers native PyTorch DCP checkpointing support (`.distcp` extension). Similar to Safetensors, it also provides the same features of load-time resharding and parallel saving. - -As a simple example, we can run the following command to launch the training recipe on two GPUs. -```bash -automodel --nproc-per-node=2 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --step_scheduler.ckpt_every_steps 20 \ - --checkpoint.model_save_format torch_save - -... -> Saving checkpoint to checkpoints/epoch_0_step_20 -... -``` -After 20 steps, the following checkpoint will be saved: - -``` -checkpoints/ -├── LATEST -> epoch_0_step_20 -├── LOWEST_VAL -> epoch_0_step_20 -└── epoch_0_step_20 - ├── config.yaml - ├── dataloader - │ ├── dataloader_dp_rank_0.pt - │ └── dataloader_dp_rank_1.pt - ├── losses.json - ├── model - │ ├── __0_0.distcp - │ └── __1_0.distcp - └── optim - ├── __0_0.distcp - └── __1_0.distcp -... -``` - -If you rerun the script, NeMo Automodel automatically detects and restores the most recent checkpoint. -```bash -automodel --nproc-per-node=2 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --step_scheduler.ckpt_every_steps 20 \ - --checkpoint.model_save_format torch_save - -... -> Loading checkpoint from checkpoints/epoch_0_step_20 -... -``` - -## Saving Checkpoints When Using Docker - -When training inside a Docker container (see [Installation Guide](/get-started/installation)), any files written to the container's filesystem are lost when the container exits (especially with `--rm`). To keep your checkpoints, you must **bind-mount a host directory** to the checkpoint path before starting the container: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v "$(pwd)"/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:25.11.00 -``` - -You can also set a custom checkpoint directory via the YAML config or CLI override: -```yaml -checkpoint: - checkpoint_dir: /mnt/shared/my_checkpoints -``` -```bash -# Or via CLI override: -automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --checkpoint.checkpoint_dir /mnt/shared/my_checkpoints -``` - -When using a custom path, make sure the corresponding host directory is mounted into the container with `-v`. - - -Mount additional host directories for datasets and the Hugging Face model cache to avoid re-downloading large models across container restarts. See the [Installation Guide](/get-started/installation) for a complete `docker run` example with all recommended mounts. - - - -## Asynchronous Checkpointing - -NeMo Automodel can write checkpoints asynchronously to reduce training stalls caused by I/O. When enabled, checkpoint writes are scheduled in the background using PyTorch Distributed Checkpointing's async API while training continues. - -- **Enable** (YAML): - ```yaml - checkpoint: - is_async: true - ``` -- **Enable** (CLI): add `--checkpoint.is_async True` to your run command. -- **Requirements**: PyTorch ≥ 2.9.0. If an older version is detected, async mode is automatically disabled. -- **Behavior**: At most one checkpoint uploads at a time; the next save waits for the previous upload to finish. The `LATEST` symlink is updated after the async save completes (may be deferred until the next save call). During PEFT, adapter model files are written synchronously on rank 0; optimizer states can still use async. - -## Advanced Usage: Save Additional States -You can also save additional states in NeMo Automodel. By default, we also automatically checkpoint the `dataloader`, `rng`, and `step_scheduler` states which are necessary to resume training accurately. In full, a Safetensors consolidated checkpoint will look like this: - -``` -checkpoints/ -├── LATEST -> epoch_0_step_20 -├── LOWEST_VAL -> epoch_0_step_20 -├── epoch_0_step_20 -│ ├── config.yaml -│ ├── dataloader -│ │ ├── dataloader_dp_rank_0.pt -│ │ └── dataloader_dp_rank_1.pt -│ ├── losses.json -│ ├── model -│ │ ├── consolidated -│ │ │ ├── config.json -│ │ │ ├── generation_config.json -│ │ │ ├── model-00001-of-00001.safetensors -│ │ │ ├── model.safetensors.index.json -│ │ │ ├── special_tokens_map.json -│ │ │ ├── tokenizer.json -│ │ │ └── tokenizer_config.json -│ │ ├── shard-00001-model-00001-of-00001.safetensors -│ │ └── shard-00002-model-00001-of-00001.safetensors -│ ├── optim -│ │ ├── __0_0.distcp -│ │ └── __1_0.distcp -│ ├── rng -│ │ ├── rng_dp_rank_0.pt -│ │ └── rng_dp_rank_1.pt -│ └── step_scheduler.pt -├── training.jsonl -└── validation.jsonl -``` - -If you want to define a new state to be checkpointed in the recipe, the easiest way is to create a new attribute in the recipe class (defined using `self.` inside the recipe). Just make sure that the new attribute uses both the `load_state_dict` and `state_dict` methods. - -Here is an example of what it might look like: - -```python - -class NewState: - - def __init__(self, ...): - self.state_value = ... - self.another_value = ... - ... - - def state_dict(self) -> dict[str, Any]: - return { - "": self.state_value, - "": self.another_value, - } - - def load_state_dict(self, state_dict: dict[str, Any]) -> None: - self.state_value = state_dict[""] - self.another_value = state_dict[""] -``` - -Inside your recipe class, define the new state as an instance attribute using `self.new_state = NewState(...)`. diff --git a/docs/fern/versions/nightly/pages/guides/configuration.mdx b/docs/fern/versions/nightly/pages/guides/configuration.mdx deleted file mode 100644 index 173de807c1..0000000000 --- a/docs/fern/versions/nightly/pages/guides/configuration.mdx +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: "YAML Configuration" -description: "" -position: 4 ---- -NeMo AutoModel recipes are configured with YAML. Under the hood, YAML is parsed into a `ConfigNode` which: - -- Translates common scalar strings into typed Python values (e.g., `"10"` → `10`). -- Resolves `_target_` (and `*_fn`) into Python callables/classes. -- Supports environment variable interpolation inside YAML strings. -- Tries to make config printing safe by preserving original placeholders (to avoid leaking secrets). - -## Load Model and Dataset Configs - -Most recipes load the YAML using `nemo_automodel.components.config.loader.load_yaml_config()`, which returns a `ConfigNode`. - -Within a `ConfigNode`: - -- Nested dicts become nested `ConfigNode` objects. -- Lists are recursively wrapped. -- Scalars are translated with `translate_value()` when they are YAML strings. - -### Typed Scalar Translation (`translate_value`) - -Only **strings** are translated. Examples: - -- `"123"` → `123` -- `"3.14"` → `3.14` -- `"true"` / `"false"` → `True` / `False` -- `"None"` / `"none"` → `None` - -YAML-native types (like `step_size: 10` without quotes) are already typed by the YAML parser and remain unchanged. - -## Use `_target_` for Instantiation - -Any mapping containing a `_target_` key can be instantiated using `ConfigNode.instantiate()`: - -```yaml -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B -``` - -There is also support for resolving callables from: - -- **Dotted paths**: `pkg.module.symbol` -- **Local file paths**: `/abs/path/to/file.py:symbol` - -### Safety and Policy - -By default, resolving targets is restricted: - -- Imports are allowed from common safe prefixes (e.g. `nemo_automodel`, `torch`, `transformers`, …). -- Accessing private or dunder attributes is blocked by default. -- Loading out-of-tree user code can be enabled with `NEMO_ENABLE_USER_MODULES=1` or by calling `set_enable_user_modules(True)`. - -## Distributed Section (Strategy-Based) - -The `distributed:` section is **not** instantiated using `_target_`. Recipes parse it with a fixed schema: use `strategy: fsdp2`, `strategy: ddp`, or `strategy: megatron_fsdp`, plus optional parallelism sizes (`dp_size`, `tp_size`, `pp_size`, etc.) and strategy-specific options. When pipeline parallelism is enabled (`pp_size > 1`), add a `pipeline:` subsection with options such as `pp_schedule`, `pp_microbatch_size`, and `layers_per_stage`. See the [Pipeline Parallelism with AutoPipeline](/development/pipeline-parallelism) guide and recipe example configs for full examples. - -## Interpolate Environment Variables in YAML - -NeMo AutoModel supports env var interpolation inside YAML **string values**. - -### Supported Forms - -- **Braced**: - - `${VAR}` - - `${VAR,default}` - - `${var.dot.var}` (dots are treated as part of the env var name) -- **Dollar**: - - `$VAR` - - `$var.dot.var` -- **Back-compat**: - - `${oc.env:VAR}` - - `${oc.env:VAR,default}` - -### Interpolation Behavior - -- Interpolation happens when values are wrapped into a `ConfigNode`. -- If a referenced env var is **missing** and **no default** is provided, config loading raises a `KeyError`. -- Defaults are supported only for braced forms using the first comma: `${VAR,default_value}`. - -### Example (Databricks Delta) - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.column_mapped_text_instruction_iterable_dataset.ColumnMappedTextInstructionIterableDataset - path_or_dataset_id: delta://catalog.schema.training_data - delta_storage_options: - DATABRICKS_HOST: ${DATABRICKS_HOST} - DATABRICKS_TOKEN: ${DATABRICKS_TOKEN} - DATABRICKS_HTTP_PATH: ${DATABRICKS_HTTP_PATH} -``` - -## Prevent Secret Leakage in Logs - -When an env var placeholder is resolved, the config keeps the original placeholder in an internal `._orig_value` field for **safe printing**: - -- `str(cfg)` / `repr(cfg)` prints placeholders (e.g. `${DATABRICKS_TOKEN}`), not resolved secrets. -- `cfg.to_yaml_dict(use_orig_values=True, redact_sensitive=True)` is the recommended way to produce a loggable YAML dict. - - -Printing a **leaf value** (for example, `print(cfg.dataset.delta_storage_options.DATABRICKS_TOKEN)`) outputs the resolved secret. Instead, print the full config or use a redacted YAML dict. - - - -## Configure Slurm - -SLURM jobs are submitted with `sbatch` directly — no YAML section needed. -Copy the reference script, edit `CONFIG` and cluster settings, then submit: - -```bash -cp slurm.sub my_cluster.sub -vim my_cluster.sub -sbatch my_cluster.sub -``` - -All cluster-specific configuration (SBATCH directives, container image, mounts, -secrets, environment variables) lives in your sbatch script. See -[Run on a Cluster](/job-launchers/slurm-cluster) for full examples. diff --git a/docs/fern/versions/nightly/pages/guides/dataset-overview.mdx b/docs/fern/versions/nightly/pages/guides/dataset-overview.mdx deleted file mode 100644 index 1fec91bee5..0000000000 --- a/docs/fern/versions/nightly/pages/guides/dataset-overview.mdx +++ /dev/null @@ -1,618 +0,0 @@ ---- -title: "Dataset Overview: LLM, VLM, and Retrieval Datasets in NeMo AutoModel" -description: "" -position: 1 ---- -This page summarizes the datasets supported in NeMo AutoModel for LLM, VLM, and retrieval training and shows how to plug in your own datasets using Python functions or the YAML `_target_` mechanism. - -- See also: [LLM datasets](/datasets/text-dataset), [VLM datasets](/datasets/multi-modal-dataset), and [Retrieval dataset](/datasets/retrieval-dataset) for deeper, task-specific guides. - -- If a dataset you need is missing, please open a [GitHub issue](https://github.com/NVIDIA-NeMo/Automodel/issues) with a short description and example schema so we can prioritize support. ---- - -## LLM Datasets - -NeMo AutoModel supports several common patterns for language modeling and instruction tuning. -### HellaSwag (Completion SFT) -- Wrapper: `nemo_automodel.components.datasets.llm.hellaswag.HellaSwag` -- Use case: single-turn completion-style SFT where a prompt (ctx) is followed by a gold continuation (ending) -- Key args: `path_or_dataset`, `split`, `num_samples_limit` -- Example YAML: -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.hellaswag.HellaSwag - path_or_dataset: rowan/hellaswag - split: train -``` - -### SQuAD-Style Question Answering (QA) (Instruction SFT) -- Factory: `nemo_automodel.components.datasets.llm.squad.make_squad_dataset` -- Use case: instruction/QA tuning with either prompt-and-answer formatting or chat-template formatting - -- If the tokenizer has a chat template and you want answer-only loss, you must provide `start_of_turn_token`. -- Optional `seq_length` can be used for padding/truncation. - - -- Example YAML: -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - split: train - dataset_name: rajpurkar/squad - start_of_turn_token: "<|assistant|>" -``` - -- **ColumnMappedTextInstructionDataset (generic instruction SFT)** - - Class: `nemo_automodel.components.datasets.llm.column_mapped_text_instruction_dataset.ColumnMappedTextInstructionDataset` - - Use case: quickly adapt instruction datasets by mapping your schema's columns to `context`, `question`, `answer` - - Sources: local JSON/JSONL or Hugging Face Hub dataset ID - - Notes: - - For tokenizers with chat templates and answer-only loss, you may set `answer_only_loss_mask: true` and provide `start_of_turn_token`. - - Supports streaming mode for large datasets (see [Streaming Datasets](#streaming-datasets) section below). - - Map-style, non-streaming dataset (supports `len(ds)` and `ds[i]`) - - For streaming (including Delta Lake / Databricks), use `ColumnMappedTextInstructionIterableDataset` - - Example YAML: -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.column_mapped_text_instruction_dataset.ColumnMappedTextInstructionDataset - path_or_dataset_id: Muennighoff/natural-instructions - split: train - column_mapping: - context: definition - question: inputs - answer: targets - answer_only_loss_mask: true - start_of_turn_token: "<|assistant|>" -``` -See the detailed guide, [Column-Mapped Text Instruction Dataset](/datasets/columnmapped-dataset), for more information. - -- **ChatDataset (multi-turn conversations and tool calling)** - - Class: `nemo_automodel.components.datasets.llm.ChatDataset` - - Use case: multi-turn conversations and tool calling in OpenAI chat format - - Sources: local JSON/JSONL or Hugging Face Hub dataset ID - - Key args: - - `path_or_dataset_id`: path to local file(s) or HuggingFace dataset ID - - `tokenizer`: tokenizer instance (required. Must have chat template support) - - `split`: dataset split (e.g., "train", "validation") - - `name`: dataset configuration/subset name - - `seq_length`: maximum sequence length for padding/truncation - - `padding`: padding strategy ("do_not_pad", "max_length", etc.) - - `truncation`: truncation strategy ("do_not_truncate", "longest_first", etc.) - - `start_of_turn_token`: token marking assistant response start (for answer-only loss) - - `chat_template`: optional override for tokenizer's chat template - - `skip_invalid_samples`: if `true`, skip malformed JSONL lines when reading local files (warnings log skip counts); default `false` fails fast on a bad line - - Notes: - - Requires a tokenizer with chat template support - - Supports both single-turn and multi-turn tool calling - - Tool definitions are provided in a `tools` field at the conversation level - - Tool calls appear in assistant messages via `tool_calls` field - - Tool responses use the `tool` role -### ChatDataset (Multi-Turn Conversations and Tool Calling) -- Class: `nemo_automodel.components.datasets.llm.ChatDataset` -- Use case: multi-turn conversations and tool calling in OpenAI chat format -- Sources: local JSON/JSONL or Hugging Face Hub dataset ID -- Key args: - - `path_or_dataset_id`: path to local file(s) or Hugging Face dataset ID - - `tokenizer`: tokenizer instance (required; must have chat template support) - - `split`: dataset split (e.g., "train", "validation") - - `name`: dataset configuration/subset name - - `seq_length`: maximum sequence length for padding/truncation - - `padding`: padding strategy ("do_not_pad", "max_length", etc.) - - `truncation`: truncation strategy ("do_not_truncate", "longest_first", etc.) - - `start_of_turn_token`: token marking assistant response start (for answer-only loss) - - `chat_template`: optional override for tokenizer's chat template - - `mask_reasoning_content`: optionally exclude rendered `reasoning_content` tokens from loss - - `skip_invalid_samples`: if `true`, skip malformed JSONL lines when reading local files (warnings log skip counts); default `false` fails fast on a bad line - -- Requires a tokenizer with chat template support -- Supports both single-turn and multi-turn tool calling -- Assistant messages may also include `reasoning_content` for structured reasoning traces -- Tool definitions are provided in a `tools` field at the conversation level -- Tool calls appear in assistant messages through the `tool_calls` field -- Tool responses use the `tool` role and must include `tool_call_id` -- If your dataset contains `reasoning_content`, your chat template must render it explicitly or it will be dropped -- For multi-turn tool-calling datasets, prefer chat templates that use `{% generation %}` blocks so assistant-turn loss masking is exact -- Set `mask_reasoning_content: true` if you want to train on the final assistant answer while excluding rendered reasoning traces from loss -- Set `skip_invalid_samples: true` for noisy local JSONL so lines that are not valid JSON are skipped instead of failing the load - - -- Example YAML: -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.ChatDataset - path_or_dataset_id: Salesforce/xlam-function-calling-60k - split: train - tokenizer: - _target_: transformers.AutoTokenizer.from_pretrained - pretrained_model_name_or_path: google/functiongemma-270m-it - seq_length: 2048 - start_of_turn_token: "" - mask_reasoning_content: false - skip_invalid_samples: false -``` - - Expected data format (OpenAI messages format): -```json -{ - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and should I bring an umbrella?" - }, - { - "role": "assistant", - "reasoning_content": "The user wants weather info and advice. I should call get_weather first, then decide whether an umbrella is needed.", - "content": "", - "tool_calls": [ - { - "id": "call_1", - "type": "function", - "function": { - "name": "get_weather", - "arguments": "{\"city\": \"Seattle\"}" - } - } - ] - }, - { - "role": "tool", - "tool_call_id": "call_1", - "content": "{\"temperature\": 55, \"condition\": \"rain\", \"precipitation_chance\": 0.85}" - }, - { - "role": "assistant", - "reasoning_content": "It is raining with a high precipitation chance, so I should recommend bringing an umbrella.", - "content": "It's currently 55 degrees F and raining in Seattle with an 85% chance of continued precipitation. Yes, definitely bring an umbrella." - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "get_weather", - "description": "Get current weather for a city", - "parameters": { - "type": "object", - "properties": { - "city": {"type": "string"} - }, - "required": ["city"] - } - } - } - ] -} -``` - - Template requirement example for `reasoning_content`: -```jinja -{%- if message.reasoning_content %} -{% generation %} -{{ "\n" + message.reasoning_content + "\n\n" }} -{% endgeneration %} -{%- endif %} -{% generation %} -{{ message.content }} -{% endgeneration %} -``` - - For single-turn tool calling (one tool call per conversation), omit the tool response and final assistant message: -```json -{ - "messages": [ - { - "role": "user", - "content": "Book a table for two at 7pm in Seattle." - }, - { - "role": "assistant", - "content": "", - "tool_calls": [ - { - "id": "call_1", - "type": "function", - "function": { - "name": "book_table", - "arguments": "{\"party_size\": 2, \"time\": \"19:00\", \"city\": \"Seattle\"}" - } - } - ] - } - ], - "tools": [ - { - "type": "function", - "function": { - "name": "book_table", - "description": "Book a restaurant table", - "parameters": { - "type": "object", - "properties": { - "party_size": {"type": "integer"}, - "time": {"type": "string"}, - "city": {"type": "string"} - } - } - } - } - ] -} -``` -See the [Function Calling guide](/recipes-e2e-examples/function-calling) for an end-to-end example with FunctionGemma. -For a small reasoning-style chat SFT starting point, see [qwen2_5_0p5b_instruct_fineproofs_chat.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen2_5_0p5b_instruct_fineproofs_chat.yaml). - -### Retrieval (Embedding Fine-Tuning) -- Factory: `nemo_automodel.components.datasets.llm.make_retrieval_dataset` -- Collator: `nemo_automodel.components.datasets.llm.BiEncoderCollator` -- Use case: embedding model fine-tuning with (query, positive doc, negative docs) contrastive learning -- Supported schemas: - - Corpus-ID JSON (Merlin/NeMo-retriever style) - - Inline-text JSONL (e.g., `{"query": "...", "pos_doc": "...", "neg_doc": ["...", "..."]}`) -- Example YAML: -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.make_retrieval_dataset - data_dir_list: /abs/path/to/train.jsonl - data_type: train - n_passages: 5 -collate_fn: - _target_: nemo_automodel.components.datasets.llm.BiEncoderCollator - q_max_len: 512 - p_max_len: 512 -``` -See the detailed guide, [Retrieval dataset](/datasets/retrieval-dataset), for more information. - -### NanoGPT Binary Shards (Pretraining) -- Class: `nemo_automodel.components.datasets.llm.nanogpt_dataset.NanogptDataset` -- Use case: token-level LM pretraining over `.bin` shards produced by NanoGPT-style preprocessors (supports legacy and current formats) - -- Streams contiguous `seq_len` slices, supports optional BOS alignment and `.bos.idx` sidecar files -- Related tool: `tools/nanogpt_data_processor.py` - - - -### Megatron (Pretraining; Interoperable With Pre-Tokenized Megatron Data) -- Class: `nemo_automodel.components.datasets.llm.megatron_dataset.MegatronPretraining` -- Use case: large-scale LM pretraining over Megatron-LM formatted tokenized corpora -- Interoperability: If your corpus has already been tokenized/indexed for Megatron (i.e., `.bin`/`.idx` pairs), you can point AutoModel to those assets directly. No re-tokenization required. -- Key args: `paths` (single path, glob, weighted list, or per-split dict), `seq_length`, `tokenizer`, `split`, `index_mapping_dir`, `splits_to_build` -- Example YAML: -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.megatron_dataset.MegatronPretraining - paths: /abs/path/to/processed_data_*_text_document* # glob or explicit list - index_mapping_dir: /abs/path/to/mapping_dir - tokenizer: - _target_: transformers.AutoTokenizer.from_pretrained - pretrained_model_name_or_path: openai-community/gpt2 - seq_length: 1024 - split: "0.99, 0.01, 0.00" # train, validation, test - splits_to_build: "train" -``` -See the detailed [pretraining guide](/recipes-e2e-examples/pretraining), which uses MegatronPretraining data. - -## Streaming Datasets - -Streaming datasets enable processing very large datasets without loading them entirely into memory. This is particularly useful when working with datasets that exceed available RAM or when you want to start training immediately without waiting for the full dataset to download. - -### What Are Streaming Datasets? - -Streaming datasets load and process data incrementally, one batch at a time, rather than loading the entire dataset into memory upfront. This approach: - -- **Reduces memory footprint**: Only the current batch resides in memory -- **Enables training on massive datasets**: Process terabyte-scale datasets on machines with limited RAM -- **Faster startup**: Begin training immediately without waiting for full dataset download -- **Efficient for remote datasets**: Stream directly from Hugging Face Hub without local storage - -### When to Use Streaming - -Use streaming mode when: - -- Your dataset is very large (hundreds of GB or TB) -- Available memory is limited compared to dataset size -- You want to start training quickly without downloading the full dataset -- You're experimenting with a subset of a large dataset - -Avoid streaming when: - -- Your dataset is small enough to fit comfortably in memory -- You need random access to samples (e.g., for certain sampling strategies) -- You need to know the exact dataset length upfront -- Training requires multiple passes with different orderings - -### How to Enable Streaming - -For `ColumnMappedTextInstructionDataset`, use the streaming variant by changing the class to `ColumnMappedTextInstructionIterableDataset`: - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.column_mapped_text_instruction_iterable_dataset.ColumnMappedTextInstructionIterableDataset - path_or_dataset_id: Muennighoff/natural-instructions - split: train - column_mapping: - context: definition - question: inputs - answer: targets - answer_only_loss_mask: true - start_of_turn_token: "<|assistant|>" -``` - -For Hugging Face datasets loaded directly, set `streaming=True`: - -```python -from datasets import load_dataset - -# Non-streaming (loads entire dataset into memory) -dataset = load_dataset("large-dataset/corpus", split="train", streaming=False) - -# Streaming (loads data incrementally) -dataset = load_dataset("large-dataset/corpus", split="train", streaming=True) -``` - -### Streaming Limitations - -When using streaming datasets, be aware of these limitations: - -1. **No random access**: You cannot use `dataset[index]` to access specific samples. Streaming datasets only support iteration. - -2. **No length information**: The `len(dataset)` operation is not available. You cannot determine the total number of samples upfront. - -3. **Single-pass iteration**: Each iteration consumes the stream. To iterate multiple times, you need to recreate the dataset or use the `repeat_on_exhaustion` parameter. - -4. **Limited shuffling**: Shuffling is done with a buffer (not the entire dataset), which may not provide perfect randomization. - -### Distributed Training with Streaming - -Streaming datasets support distributed training through sharding: - -```python -from nemo_automodel.components.datasets.llm.column_mapped_text_instruction_iterable_dataset import ( - ColumnMappedTextInstructionIterableDataset -) - -dataset = ColumnMappedTextInstructionIterableDataset( - path_or_dataset_id="large-dataset/corpus", - column_mapping={"question": "input", "answer": "output"}, - tokenizer=tokenizer, -) - -# Shard the dataset across workers -dataset = dataset.shard(num_shards=8, index=worker_id) - -# Enable shuffling with a buffer -dataset = dataset.shuffle(buffer_size=10000, seed=42) - -# Set epoch for deterministic shuffling across epochs -dataset.set_epoch(epoch_num) -``` - -### Performance Considerations - -**Memory vs. Speed Trade-offs**: -- Streaming reduces memory usage but may be slower than in-memory datasets -- Network latency can impact streaming performance for remote datasets -- Use local caching when repeatedly accessing the same remote dataset - -**Buffer Size for Shuffling**: -- Larger buffers provide better randomization but use more memory -- A buffer size of 10,000-100,000 samples is typically a good balance -- For perfect shuffling, you need a buffer size equal to the dataset size (defeating the purpose of streaming) - -**Prefetching**: -- Most streaming implementations prefetch data in the background -- This helps hide network latency and keeps GPUs busy -- Adjust prefetch settings based on your network speed and batch size - -### Example: Streaming a Large Dataset - -Here's a complete example of using streaming for a large instruction-tuning dataset: - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.column_mapped_text_instruction_iterable_dataset.ColumnMappedTextInstructionIterableDataset - path_or_dataset_id: HuggingFaceH4/ultrachat_200k - split: train_sft - column_mapping: - question: prompt - answer: completion - answer_only_loss_mask: true - start_of_turn_token: "<|assistant|>" - repeat_on_exhaustion: true # Automatically restart when stream ends - -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - batch_size: 4 - num_workers: 4 -``` - -This configuration: -- Streams the dataset without loading it fully into memory -- Automatically repeats when the stream is exhausted -- Uses multiple workers for efficient data loading -- Applies answer-only loss masking during tokenization - -## Packed Sequence Support -To reduce padding and improve throughput with variable-length sequences: -```yaml -packed_sequence: - packed_sequence_size: 8192 # > 0 enables packing - split_across_pack: false -``` -Use a collator that pads to an FP8-friendly multiple when training with FP8: -```yaml -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: - _target_: nemo_automodel.components.datasets.utils.default_collater - pad_seq_len_divisible: 16 -``` - ---- - -## VLM Datasets (Vision/Audio + Language) -VLM datasets are represented as conversations (message lists) that combine text with images or audio and are processed with the model's `AutoProcessor.apply_chat_template` and a suitable collate function. - -Built-in dataset makers (return lists of `conversation` dicts): -- **RDR items**: `nemo_automodel.components.datasets.vlm.datasets.make_rdr_dataset` (HF: `quintend/rdr-items`) -- **CORD-V2 receipts (Consolidated Receipt Dataset for Post-OCR Parsing)**: `nemo_automodel.components.datasets.vlm.datasets.make_cord_v2_dataset` (HF: `naver-clova-ix/cord-v2`) -- **MedPix-VQA (Medical Pixel Question Answering)**: `nemo_automodel.components.datasets.vlm.datasets.make_medpix_dataset` -- **CommonVoice 17 (CV17) (audio)**: `nemo_automodel.components.datasets.vlm.datasets.make_cv17_dataset` - -Each example follows the conversation schema expected by `apply_chat_template`, e.g.: -```python -{ - "conversation": [ - { - "role": "user", - "content": [ - {"type": "image", "image": example_image}, - {"type": "text", "text": "Describe this image."} - ] - }, - { - "role": "assistant", - "content": [{"type": "text", "text": ground_truth_text}] - } - ] -} -``` - -### Custom Chat Template -By default, VLM fine-tuning uses the chat template built into the model's `AutoProcessor`. To override it, add `chat_template` under `dataset:` in your YAML config: - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.vlm.datasets.make_medpix_dataset - split: train - chat_template: "{% for msg in messages %}{{ msg.role }}: {{ msg.content }}\n{% endfor %}" -``` - -`chat_template` accepts a Jinja template string, a path to a `.jinja` file, or a path to a JSON file containing a `chat_template` key. The override is applied to both the processor and its tokenizer before dataset instantiation. - -### Collate Functions -- `nemo_automodel.components.datasets.vlm.collate_fns.default_collate_fn` -- `nemo_automodel.components.datasets.vlm.collate_fns.qwen2_5_collate_fn` (Qwen2.5 VL) -- `nemo_automodel.components.datasets.vlm.collate_fns.phi4_mm_collate_fn` (audio) - -Select in your YAML: -```yaml -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - batch_size: 1 - collate_fn: - _target_: nemo_automodel.components.datasets.vlm.collate_fns.qwen2_5_collate_fn -``` -If you want answer-only loss masking, provide a model-appropriate `start_of_response_token` to the collate function. - -See [Gemma-3n](/recipes-e2e-examples/gemma-3-3n) and [VLM dataset](/datasets/multi-modal-dataset) for end-to-end examples. - ---- - -## Diffusion Datasets - -Diffusion models don't train directly on raw images or videos. Instead, the data is first encoded into a compact numerical representation called a latent — this is what the model actually learns from. Text captions are similarly converted into text embeddings that the model uses as conditioning. - -This encoding is done once during preprocessing, and the results are saved as cache files (.meta). Training then reads these cache files directly, which is significantly faster than re-encoding on every step. - -The built-in preprocessing tool ([`tools/diffusion/preprocessing_multiprocess.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/tools/diffusion/preprocessing_multiprocess.py)) handles this conversion. It uses a VAE (Variational Autoencoder) to encode visual data and a text encoder for captions, grouping outputs into resolution-bucketed directories compatible with the multiresolution dataloader. - -### Dataloader Builders - -- **Video (T2V)**: `nemo_automodel.components.datasets.diffusion.build_video_multiresolution_dataloader` — for Wan 2.1 and HunyuanVideo -- **Image (T2I)**: `nemo_automodel.components.datasets.diffusion.build_text_to_image_multiresolution_dataloader` — for FLUX.1-dev - -### Example YAML (Video Dataloader) - -```yaml -data: - dataloader: - _target_: nemo_automodel.components.datasets.diffusion.build_video_multiresolution_dataloader - cache_dir: /path/to/processed_meta - model_type: wan - base_resolution: [512, 512] - dynamic_batch_size: false - shuffle: true - drop_last: false - num_workers: 0 -``` - -See the [Diffusion Dataset Preparation](/datasets/diffusion-dataset) guide for full preprocessing instructions and configuration details. - ---- - -## Bring Your Own Dataset -You can integrate custom datasets with zero code changes to NeMo AutoModel by using `_target_` in YAML. There are three approaches: - -### Point to an Existing Class or Function (Dotted Path) -- LLM example (class): -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.hellaswag.HellaSwag - path_or_dataset: rowan/hellaswag - split: train -``` -- LLM example (factory function): -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - split: train - dataset_name: rajpurkar/squad -``` -- VLM example (factory function): -```yaml -dataset: - _target_: nemo_automodel.components.datasets.vlm.datasets.make_cord_v2_dataset - split: train -``` - -### Point to a Local Python File and Function -```yaml -dataset: - _target_: /abs/path/to/my_custom_dataset.py:build_my_dataset - some_arg: 123 - split: train -``` -Where `build_my_dataset` returns either a `datasets.Dataset` or a list/iterator of conversation dicts (for VLM). - -### Use ColumnMappedTextInstructionDataset for Most Instruction Datasets (LLM) -- Ideal when your data has columns like `instruction`, `input`, or `output` but with arbitrary names -- Supports local JSON/JSONL and HF Hub -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.column_mapped_text_instruction_dataset.ColumnMappedTextInstructionDataset - path_or_dataset_id: /abs/path/to/*.jsonl # or org/repo on HF - column_mapping: - context: definition - question: inputs - answer: targets - answer_only_loss_mask: true - start_of_turn_token: "<|assistant|>" -``` - -### Implement a Minimal Custom Class Pattern (LLM Completion) -If you prefer Python, implement `get_context` and `get_target` and reuse the built-in preprocessor: -```python -from datasets import load_dataset -from nemo_automodel.components.datasets.utils import SFTSingleTurnPreprocessor - -class MyCompletionDataset: - def __init__(self, path_or_dataset, tokenizer, split="train"): - raw_ds = load_dataset(path_or_dataset, split=split) - self.dataset = SFTSingleTurnPreprocessor(tokenizer).process(raw_ds, self) - - def get_context(self, examples): - return examples["my_context_field"] - - def get_target(self, examples): - return examples["my_target_field"] -``` -Then reference your class with `_target_` in YAML. - -### Important Considerations -- **Chat templates**: If your tokenizer has a chat template and you want answer-only loss, provide the correct `start_of_turn_token` (LLM) or `start_of_response_token` (VLM collate functions). -- **Padding for FP8**: If training with FP8, set `pad_seq_len_divisible: 16` in your collate function to align sequence lengths. -- **Packed sequences**: Prefer packed sequences for throughput when fine-tuning LLMs on variable-length corpora. -- **Validation**: You can define a separate `validation_dataset` and `validation_dataloader` block mirroring your training config. - -For detailed, end-to-end recipes, browse the example configs under [examples/llm_finetune/](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_finetune), [examples/llm_pretrain/](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_pretrain), and [examples/vlm_finetune/](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/vlm_finetune). diff --git a/docs/fern/versions/nightly/pages/guides/diffusion/dataset.mdx b/docs/fern/versions/nightly/pages/guides/diffusion/dataset.mdx deleted file mode 100644 index a9f911bb71..0000000000 --- a/docs/fern/versions/nightly/pages/guides/diffusion/dataset.mdx +++ /dev/null @@ -1,209 +0,0 @@ ---- -title: "Diffusion Dataset Preparation" -description: "" -position: 7 ---- -## Introduction - -Diffusion model training in NeMo AutoModel requires pre-encoded `.meta` files rather than raw images or videos. During preprocessing, a VAE encodes visual data into latent representations and a text encoder produces text embeddings. These are saved as `.meta` files so that training operates entirely in latent space, avoiding the need to load heavy encoder models during training. - -## Input Data Format - -### Images - -Place your images in a directory. Supported formats: `jpg`, `jpeg`, `png`, `webp`, `bmp`. - -Captions can be provided in several formats: -- **Sidecar JSON** (default for images): A `.json` file alongside each image with a caption field -- **JSONL**: A `.jsonl` file with `internvl` or `usr` caption fields - -### Videos - -Place your videos in a directory. Supported formats: `mp4`, `avi`, `mov`, `mkv`, `webm`. - -Captions can be provided in several formats: -- **Sidecar JSON** (`--caption_format sidecar`): A `.json` file alongside each video -- **meta.json** (`--caption_format meta_json`): A single `meta.json` manifest in the video directory -- **JSONL** (`--caption_format jsonl`): A `.jsonl` file with captions - -If no caption is found for a sample, the filename (with underscores replaced by spaces) is used as a fallback. - -## Preprocessing - -NeMo AutoModel includes a unified preprocessing tool at [`tools/diffusion/preprocessing_multiprocess.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/tools/diffusion/preprocessing_multiprocess.py) that encodes raw images and videos into cache files compatible with the multiresolution dataloader. It uses model-specific processors from `tools/diffusion/processors/` to handle VAE encoding, text embedding, and cache data formatting for each supported model. - -The tool automatically distributes work across all available GPUs using multiprocessing, with one worker per GPU. - -### Available Processors - -| Processor | Media Type | Model | -|-----------|-----------|-------| -| `flux` | Image | FLUX.1-dev | -| `wan` | Video | Wan 2.1 | -| `hunyuan` | Video | HunyuanVideo 1.5 | - -You can list all registered processors with: - -```bash -python -m tools.diffusion.preprocessing_multiprocess --list_processors -``` - -### Image Preprocessing (FLUX) - -```bash -python -m tools.diffusion.preprocessing_multiprocess image \ - --image_dir /path/to/images \ - --output_dir /path/to/cache \ - --processor flux \ - --resolution_preset 512p -``` - -### Video Preprocessing (Wan 2.1) - -**Video mode** (encodes the full video as a single sample, recommended for training): - -```bash -python -m tools.diffusion.preprocessing_multiprocess video \ - --video_dir /path/to/videos \ - --output_dir /path/to/cache \ - --processor wan \ - --resolution_preset 512p \ - --caption_format sidecar -``` - -**Frames mode** (extracts evenly-spaced frames, each becomes a separate sample): - -```bash -python -m tools.diffusion.preprocessing_multiprocess video \ - --video_dir /path/to/videos \ - --output_dir /path/to/cache \ - --processor wan \ - --mode frames \ - --num_frames 40 \ - --resolution_preset 512p -``` - -### Video Preprocessing (HunyuanVideo) - -```bash -python -m tools.diffusion.preprocessing_multiprocess video \ - --video_dir /path/to/videos \ - --output_dir /path/to/cache \ - --processor hunyuan \ - --target_frames 121 \ - --caption_format meta_json -``` - -### Key Arguments - -**Common arguments:** - -| Argument | Description | -|----------|-------------| -| `--processor` | Processor name (`flux`, `wan`, `hunyuan`) | -| `--model_name` | HuggingFace model name (uses processor default if omitted) | -| `--output_dir` | Output directory for cached data | -| `--shard_size` | Number of samples per metadata shard (default: 10000) | - -**Image-specific arguments:** - -| Argument | Description | -|----------|-------------| -| `--image_dir` | Input image directory | -| `--resolution_preset` | Resolution preset: `256p`, `512p`, `768p`, `1024p`, `1536p` | -| `--max_pixels` | Custom pixel budget (alternative to preset) | -| `--caption_field` | Caption field in JSONL files (`internvl` or `usr`) | -| `--verify` | Verify latents can be decoded back | - -**Video-specific arguments:** - -| Argument | Description | -|----------|-------------| -| `--video_dir` | Input video directory | -| `--mode` | `video` (full video) or `frames` (extract evenly-spaced frames) | -| `--num_frames` | Number of frames to extract in `frames` mode | -| `--target_frames` | Target frame count (for example, 121 for HunyuanVideo 4n+1 constraint) | -| `--resolution_preset` | Resolution preset for bucketing | -| `--height` / `--width` | Explicit target size (disables bucketing) | -| `--resize_mode` | Interpolation: `bilinear`, `bicubic`, `nearest`, `area`, `lanczos` | -| `--center_crop` / `--no_center_crop` | Enable/disable center cropping (default: enabled) | -| `--caption_format` | Caption source: `sidecar`, `meta_json`, `jsonl` | -| `--caption_field` | Field name for captions (default: `caption`) | -| `--output_format` | Output format: `meta` (pickle) or `pt` (torch.save) | - -## Output Format - -The preprocessing tool produces a cache directory organized by resolution bucket: - -``` -/path/to/cache/ -├── 512x512/ -│ ├── .meta -│ ├── .meta -│ └── ... -├── 832x480/ -│ └── ... -├── metadata.json # Global config (processor, model, total items) -└── metadata_shard_0000.json # Per-sample metadata (paths, resolutions, captions) -``` - -Each cache file (`.meta` or `.pt`) contains: - -- **Encoded latents** — VAE latent representations of the image or video -- **Text embeddings** — Pre-computed from the model's text encoder -- **First frame** — Reference image for image-to-video conditioning (video mode only) -- **Image embeddings** — For models that support i2v conditioning (video mode only) -- **Metadata** — Original and bucket resolutions, caption, source path - -## Multiresolution Bucketing - -NeMo AutoModel supports multiresolution training through bucketed sampling. This groups samples by their spatial resolution so that each batch contains samples of the same size, avoiding padding waste. - -During preprocessing, the `--resolution_preset` argument controls the pixel budget used for bucketing. Available presets: `256p`, `512p`, `768p`, `1024p`, `1536p`. Alternatively, use `--max_pixels` for a custom pixel budget, or `--height`/`--width` to disable bucketing and use a fixed resolution. - -During training, the dataloader uses these key configuration parameters: - -- `base_resolution`: The target resolution used for bucketing (for example, `[512, 512]`) -- The `SequentialBucketSampler` groups samples by resolution bucket -- `dynamic_batch_size`: When `true`, adjusts batch size per resolution bucket to maintain constant memory usage - -## YAML Configuration - -### Video Dataloader (Wan 2.1 / HunyuanVideo) - -Used for text-to-video models. Set `model_type` to match your model (`wan` or `hunyuan`): - -```yaml -data: - dataloader: - _target_: nemo_automodel.components.datasets.diffusion.build_video_multiresolution_dataloader - cache_dir: /path/to/processed_meta - model_type: wan # or "hunyuan" - base_resolution: [512, 512] - dynamic_batch_size: false - shuffle: true - drop_last: false - num_workers: 0 -``` - -### Image Dataloader (FLUX) - -Used for text-to-image models: - -```yaml -data: - dataloader: - _target_: nemo_automodel.components.datasets.diffusion.build_text_to_image_multiresolution_dataloader - cache_dir: /path/to/processed_meta - train_text_encoder: false - num_workers: 0 - base_resolution: [512, 512] - dynamic_batch_size: false - shuffle: true - drop_last: false -``` - - -Supported image resolutions for FLUX include `[256, 256]`, `[512, 512]`, and `[1024, 1024]`. While a 1:1 aspect ratio is currently used as a proxy for the closest image size, the implementation is designed to support multiple aspect ratios. - - diff --git a/docs/fern/versions/nightly/pages/guides/diffusion/finetune.mdx b/docs/fern/versions/nightly/pages/guides/diffusion/finetune.mdx deleted file mode 100644 index 27a8b86ab5..0000000000 --- a/docs/fern/versions/nightly/pages/guides/diffusion/finetune.mdx +++ /dev/null @@ -1,392 +0,0 @@ ---- -title: "Diffusion Model Fine-Tuning with NeMo AutoModel" -description: "" -position: 16 ---- -## Introduction - -Diffusion models generate images and videos by learning to reverse a noise process — starting from random noise and iteratively refining it into coherent visual output guided by a text prompt. Pretrained diffusion models (like [FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev) for images or [Wan 2.1](https://huggingface.co/Wan-AI/Wan2.1-T2V-1.3B-Diffusers) for video) produce impressive general-purpose results, but they know nothing about your particular visual domain, style, or subject matter. Fine-tuning bridges that gap — you adapt the model on your own data so it produces outputs that match your requirements, without the cost of training from scratch. - -Under the hood, NeMo AutoModel uses [flow matching](https://arxiv.org/abs/2210.02747), a modern generative framework that learns to transform noise into data by regressing a velocity field along straight interpolation paths. It integrates with [Hugging Face Diffusers](https://huggingface.co/docs/diffusers) to provide distributed fine-tuning for text-to-image and text-to-video models. This guide walks you through the process end-to-end — from installation through training and inference — using [Wan 2.1 T2V 1.3B](https://huggingface.co/Wan-AI/Wan2.1-T2V-1.3B-Diffusers) as a running example. - -### Workflow Overview - -```text -┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ -│ 1. Install │--->│ 2. Prepare │--->│ 3. Configure │--->│ 4. Train │--->│ 5. Generate │ -│ │ │ Data │ │ │ │ │ │ │ -│ pip install │ │ Encode to │ │ YAML recipe │ │ torchrun │ │ Run inference│ -│ or Docker │ │ .meta files │ │ │ │ │ │ with ckpt │ -└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ -``` - -| Step | Section | What You Do | -|------|---------|-------------| -| **1. Install** | [Install NeMo AutoModel](#install-nemo-automodel) | Install the package via pip or Docker | -| **2. Prepare Data** | [Prepare Your Dataset](#prepare-your-dataset) | Encode raw images/videos into `.meta` latent files | -| **3. Configure** | [Configure Your Training Recipe](#configure-your-training-recipe) | Write a YAML config specifying model, data, and training settings | -| **4. Train** | [Fine-Tune the Model](#fine-tune-the-model) | Launch training with `torchrun` on a single node | -| **4b. Multi-Node** | [Multi-Node Training](#multi-node-training) | Scale training across multiple nodes | -| **5. Generate** | [Generation / Inference](#generation--inference) | Run inference using the fine-tuned checkpoint | - -For model-specific configuration (FLUX.1-dev, HunyuanVideo), see [Model-Specific Notes](#model-specific-notes). - -### Supported Models - -| Model | HF Model ID | Task | Parameters | Example Config | -|-------|-------------|------|------------|----------------| -| Wan 2.1 T2V 1.3B | `Wan-AI/Wan2.1-T2V-1.3B-Diffusers` | Text-to-Video | 1.3B | [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow.yaml) | -| FLUX.1-dev | `black-forest-labs/FLUX.1-dev` | Text-to-Image | 12B | [flux_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/flux_t2i_flow.yaml) | -| HunyuanVideo 1.5 | `hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v` | Text-to-Video | — | [hunyuan_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/hunyuan_t2v_flow.yaml) | - -All models use FSDP2 for distributed training and flow matching for loss computation. - -## Install NeMo AutoModel - -```bash -pip3 install nemo-automodel -``` - -Alternatively, if you run into dependency or driver issues, use the pre-built Docker container: - -```bash -docker pull nvcr.io/nvidia/nemo-automodel:26.02.00 -docker run --gpus all -it --rm --shm-size=8g nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - - -**Docker users:** Checkpoints are lost when the container exits unless you bind-mount the checkpoint directory to the host. See [Install with NeMo Docker Container](/get-started/installation#install-with-nemo-docker-container) and [Saving Checkpoints When Using Docker](/development/checkpointing#saving-checkpoints-when-using-docker). - - - -For the full set of installation methods, see the [installation guide](/get-started/installation). - -## Prepare Your Dataset - -Diffusion models operate in latent space — a compressed representation of visual data — rather than directly on raw images or videos. To avoid re-encoding data on every training step, the preprocessing - pipeline encodes all inputs ahead of time and saves them as .meta files. - - Each .meta file contains: - - Latent representations produced by a VAE (Variational Autoencoder) from the raw visual data - - Text embeddings produced by a text encoder from the associated captions/prompts - -Fine-tuning then operates entirely on these pre-encoded .meta files, which is significantly faster than encoding on the fly. - -Preprocess your data using the built-in tool at [`tools/diffusion/preprocessing_multiprocess.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/tools/diffusion/preprocessing_multiprocess.py). The script provides `image` and `video` subcommands: - -**Video preprocessing (using Wan 2.1 as a running example):** -```bash -python -m tools.diffusion.preprocessing_multiprocess video \ - --video_dir /data/videos \ - --output_dir /cache \ - --processor wan \ - --resolution_preset 512p \ - --caption_format sidecar -``` - -**Image preprocessing (FLUX):** -```bash -python -m tools.diffusion.preprocessing_multiprocess image \ - --image_dir /data/images \ - --output_dir /cache \ - --processor flux -``` - -**Video preprocessing (HunyuanVideo):** -```bash -python -m tools.diffusion.preprocessing_multiprocess video \ - --video_dir /data/videos \ - --output_dir /cache \ - --processor hunyuan \ - --target_frames 121 \ - --caption_format meta_json -``` - -For the full set of arguments and input format details, see the [Diffusion Dataset Preparation](/datasets/diffusion-dataset) guide. - -## Configure Your Training Recipe - -Fine-tuning is driven by two components: - -1. A recipe script (e.g., [`train.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/recipes/diffusion/train.py)) — the Python entry point that orchestrates the training loop: loading the model, building the dataloader, running forward/backward passes, computing the flow matching loss, checkpointing, and logging. -2. A YAML configuration file — a text file in YAML format that specifies all settings the recipe uses: which model to fine-tune, where the data lives, optimizer hyperparameters, parallelism strategy, etc. - You customize training by editing this file rather than modifying code, allowing you to scale from 1 to 100s of GPUs seamlessly. - -Below is the annotated [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow.yaml), with each section explained: - -```yaml -seed: 42 - -# Weights & Biases experiment tracking -wandb: - project: wan-t2v-flow-matching - mode: online - name: wan2_1_t2v_fm_v2 - -dist_env: - backend: nccl - timeout_minutes: 30 - -# Model configuration -# pretrained_model_name_or_path: Hugging Face model ID -# mode: "finetune" loads pretrained weights and adapts them to your dataset -model: - pretrained_model_name_or_path: Wan-AI/Wan2.1-T2V-1.3B-Diffusers - mode: finetune - -# Training schedule -step_scheduler: - global_batch_size: 8 # Effective batch size across all GPUs - local_batch_size: 1 # Per-GPU batch size (gradient accumulation = global/local/num_gpus) - ckpt_every_steps: 1000 # Checkpoint frequency - num_epochs: 100 - log_every: 2 # Log metrics every N steps - -# Data: uses pre-encoded .meta files -data: - dataloader: - _target_: nemo_automodel.components.datasets.diffusion.build_video_multiresolution_dataloader - cache_dir: PATH_TO_YOUR_DATA - model_type: wan # "wan" for Wan 2.1, "hunyuan" for HunyuanVideo - base_resolution: [512, 512] - dynamic_batch_size: false - shuffle: true - drop_last: false - num_workers: 0 - -# Optimizer -optim: - learning_rate: 5e-6 - optimizer: - weight_decay: 0.01 - betas: [0.9, 0.999] - -# Learning rate scheduler -lr_scheduler: - lr_decay_style: cosine - lr_warmup_steps: 0 - min_lr: 1e-6 - -# Flow matching configuration -flow_matching: - adapter_type: "simple" # Model-specific adapter (simple, flux, hunyuan) - adapter_kwargs: {} - timestep_sampling: "uniform" # How timesteps are sampled during training - logit_mean: 0.0 - logit_std: 1.0 - flow_shift: 3.0 # Shifts the flow schedule - mix_uniform_ratio: 0.1 - sigma_min: 0.0 - sigma_max: 1.0 - num_train_timesteps: 1000 - i2v_prob: 0.3 # Probability of image-to-video conditioning - use_loss_weighting: true - log_interval: 100 - summary_log_interval: 10 - -# FSDP2 distributed training -fsdp: - tp_size: 1 # Tensor parallelism - cp_size: 1 # Context parallelism - pp_size: 1 # Pipeline parallelism - dp_replicate_size: 1 - dp_size: 8 # Data parallelism (number of GPUs) - -# Checkpointing -checkpoint: - enabled: true - checkpoint_dir: PATH_TO_YOUR_CKPT_DIR - model_save_format: torch_save - save_consolidated: false - restore_from: null -``` - -### Config Field Reference - -| Section | Required? | What to Change | -|---------|-----------|----------------| -| `model` | Yes | Set `pretrained_model_name_or_path` to the Hugging Face model ID. Set `mode: finetune`. | -| `step_scheduler` | Yes | `global_batch_size` is the effective batch size across all GPUs. `ckpt_every_steps` controls checkpoint frequency. | -| `data` | Yes | Set `cache_dir` to the path containing your preprocessed `.meta` files. Change `model_type` and `_target_` for different models (see [Model-Specific Notes](#model-specific-notes)). | -| `optim` | Yes | `learning_rate: 5e-6` is a good default for fine-tuning. | -| `flow_matching` | Yes | `adapter_type` must match the model (`simple` for Wan, `flux` for FLUX, `hunyuan` for HunyuanVideo). | -| `fsdp` | Yes | Set `dp_size` to the number of GPUs on your node. | -| `checkpoint` | Recommended | Set `checkpoint_dir` to a persistent path, especially in Docker. | -| `wandb` | Optional | Configure to enable Weights & Biases logging. | - -## Fine-Tune the Model - -Launch fine-tuning with `torchrun`: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/wan2_1_t2v_flow.yaml -``` - -Adjust `--nproc-per-node` to match the number of GPUs on your node, and ensure `fsdp.dp_size` in the YAML matches. - -## Multi-Node Training - -When a single node doesn't provide enough GPUs or memory for your workload, you can scale training across multiple nodes. NeMo AutoModel handles multi-node distributed training through `torchrun` rendezvous and FSDP2 — the same recipe script works on one node or many. - -### YAML Configuration Changes - -The main change is in the `fsdp` section. Set `dp_size` to the **total number of GPUs across all nodes**, and optionally increase `dp_replicate_size` for gradient replication across nodes. - -For example, to train on 2 nodes with 8 GPUs each (16 GPUs total): - -```yaml -fsdp: - tp_size: 1 - cp_size: 1 - pp_size: 1 - dp_replicate_size: 2 # Replicate across 2 nodes for robustness - dp_size: 16 # Total GPUs: 2 nodes × 8 GPUs -``` - -A complete multi-node config is provided at [wan2_1_t2v_flow_multinode.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow_multinode.yaml). - -### Launch with torchrun - -Run the following command on **each node**, setting `NODE_RANK` to `0` on the first node, `1` on the second, and so on: - -```bash -export MASTER_ADDR=node0.hostname # hostname or IP of the first node -export MASTER_PORT=29500 -export NODE_RANK=0 # 0 on master, 1 on second node, etc. - -torchrun \ - --nnodes=2 \ - --nproc-per-node=8 \ - --node_rank=${NODE_RANK} \ - --rdzv_backend=c10d \ - --rdzv_endpoint=${MASTER_ADDR}:${MASTER_PORT} \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/wan2_1_t2v_flow_multinode.yaml -``` - -## Model-Specific Notes - -Use the table below to pick the right model for your use case: - -| Use Case | Model | Why Choose It | -|----------|-------|---------------| -| **Video generation on limited hardware** | [Wan 2.1 T2V 1.3B](#wan-21-t2v-13b) | Smallest model (1.3B params) — fast iteration, fits on a single A100 40GB | -| **High-quality image generation** | [FLUX.1-dev](#flux1-dev-text-to-image) | State-of-the-art text-to-image with 12B params and guidance-based control | -| **High-quality video generation** | [HunyuanVideo 1.5](#hunyuanvideo-15) | Larger video model with condition-latent support for richer motion and detail | - -### Wan 2.1 T2V 1.3B - -- **Adapter type**: `simple` -- **Dataloader**: `build_video_multiresolution_dataloader` with `model_type: wan` -- **Config**: [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow.yaml) - -### FLUX.1-dev (Text-to-Image) - -- **Adapter type**: `flux` -- **Dataloader**: `build_text_to_image_multiresolution_dataloader` -- **Key differences**: - - Uses `pipeline_spec` to specify the transformer architecture: - ```yaml - model: - pipeline_spec: - transformer_cls: "FluxTransformer2DModel" - subfolder: "transformer" - load_full_pipeline: false - ``` - - Requires `guidance_scale` in adapter kwargs: - ```yaml - flow_matching: - adapter_type: "flux" - adapter_kwargs: - guidance_scale: 3.5 - use_guidance_embeds: true - ``` - - Uses `logit_normal` timestep sampling instead of `uniform` -- **Config**: [flux_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/flux_t2i_flow.yaml) - -### HunyuanVideo 1.5 - -- **Adapter type**: `hunyuan` -- **Dataloader**: `build_video_multiresolution_dataloader` with `model_type: hunyuan` -- **Key differences**: - - Requires `activation_checkpointing: true` in FSDP config due to model size - - Uses condition latents in adapter kwargs: - ```yaml - flow_matching: - adapter_type: "hunyuan" - adapter_kwargs: - use_condition_latents: true - default_image_embed_shape: [729, 1152] - ``` - - Uses `logit_normal` timestep sampling -- **Config**: [hunyuan_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/hunyuan_t2v_flow.yaml) - -## Generation / Inference - -Once training is complete, you can use the model to generate images or videos from text prompts. This step is called inference — as opposed to training, where the model learns from data, inference is where it produces new outputs. - -In diffusion models, generation works by starting from random noise and iteratively denoising it, guided by your text prompt, until a clean image or video emerges. - -The generation script ([`generate.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/generate/generate.py)) handles this: it loads your model weights (pretrained or fine-tuned), configures the diffusion sampler, and produces outputs for one or more prompts. - -**Single-GPU (Wan 2.1 1.3B):** -```bash -python examples/diffusion/generate/generate.py \ - -c examples/diffusion/generate/configs/generate_wan.yaml -``` - -**Multi-GPU (Wan 2.1 1.3B):** - -Wan 2.1 supports tensor parallelism for inference, which shards the transformer across GPUs to reduce per-GPU memory. Pass the `distributed` config via CLI overrides: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/generate/generate.py \ - -c examples/diffusion/generate/configs/generate_wan.yaml \ - --distributed.backend nccl \ - --distributed.parallel_scheme.transformer.tp_size 8 -``` - -**With a fine-tuned checkpoint:** -```bash -python examples/diffusion/generate/generate.py \ - -c examples/diffusion/generate/configs/generate_wan.yaml \ - --model.checkpoint ./checkpoints/step_1000 \ - --inference.prompts '["A dog running on a beach"]' -``` - -**FLUX image generation:** -```bash -python examples/diffusion/generate/generate.py \ - -c examples/diffusion/generate/configs/generate_flux.yaml -``` - -**HunyuanVideo:** -```bash -python examples/diffusion/generate/generate.py \ - -c examples/diffusion/generate/configs/generate_hunyuan.yaml -``` - -### Available Generation Configs - -| Config | Model | Output | GPUs | -|--------|-------|--------|------| -| [`generate_wan.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/generate/configs/generate_wan.yaml) | Wan 2.1 1.3B | Video | 1 | -| [`generate_flux.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/generate/configs/generate_flux.yaml) | FLUX.1-dev | Image | 1 | -| [`generate_hunyuan.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/generate/configs/generate_hunyuan.yaml) | HunyuanVideo | Video | 1 | - - -You can use `--model.checkpoint ./checkpoints/LATEST` to automatically load the most recent checkpoint. - - - -## Hardware Requirements - -| Component | Minimum | Recommended | -|-----------|---------|-------------| -| GPU | A100 40GB | A100 80GB / H100 | -| GPUs | 4 | 8 | -| RAM | 128 GB | 256 GB+ | -| Storage | 500 GB SSD | 2 TB NVMe | diff --git a/docs/fern/versions/nightly/pages/guides/dllm/finetune.mdx b/docs/fern/versions/nightly/pages/guides/dllm/finetune.mdx deleted file mode 100644 index bf0d96c7da..0000000000 --- a/docs/fern/versions/nightly/pages/guides/dllm/finetune.mdx +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: "dLLM Fine-Tuning" -description: "" -position: 17 ---- -## Introduction - -Diffusion language models (dLLMs) generate text by iteratively denoising masked tokens, rather than generating one token at a time left-to-right like autoregressive (AR) models. Starting from a sequence of `[MASK]` tokens, the model progressively unmasks the most confident positions over multiple denoising steps until the full response is revealed. - -This approach enables **parallel token generation** and **bidirectional attention**, which gives the model more context for each prediction compared to AR models. - -NeMo AutoModel currently supports the following dLLM model family: - -- **LLaDA (MDLM)** — Bidirectional masked diffusion. The model receives corrupted tokens and predicts the clean token at each masked position. - -### Workflow Overview - -```text -┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ -│ 1. Install │--->│ 2. Configure │--->│ 3. Train │--->│ 4. Generate │ -│ │ │ YAML │ │ │ │ │ -│ pip install │ │ Recipe + │ │ torchrun │ │ Run dLLM │ -│ or Docker │ │ dLLM config │ │ │ │ inference │ -└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ -``` - -| Step | Section | What You Do | -|------|---------|-------------| -| **1. Install** | [Install NeMo AutoModel](#install-nemo-automodel) | Install the package via pip or Docker | -| **2. Configure** | [Configure Your Training Recipe](#configure-your-training-recipe) | Write a YAML config specifying model, data, dLLM mode, and training settings | -| **3. Train** | [Fine-Tune the Model](#fine-tune-the-model) | Launch training with `torchrun` | -| **4. Generate** | [Generation / Inference](#generation--inference) | Generate text from a fine-tuned checkpoint | - -### Supported Models - -| Model Family | dLLM Mode | Loss | Inference | Example Config | -|---|---|---|---|---| -| LLaDA | `mdlm` | MDLM cross-entropy | Block-by-block, full-forward (no KV cache) | [llada_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/dllm_sft/llada_sft.yaml) | - -## Install NeMo AutoModel - -```bash -pip3 install nemo-automodel -``` - -Alternatively, use the pre-built Docker container: - -```bash -docker pull nvcr.io/nvidia/nemo-automodel:26.02.00 -docker run --gpus all -it --rm --shm-size=8g nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -For the full set of installation methods, see the [installation guide](/get-started/installation). - -## Configure Your Training Recipe - -dLLM fine-tuning is driven by: - -1. A **recipe script** ([`train_ft.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/recipes/dllm/train_ft.py)) — orchestrates the training loop with dLLM-specific corruption, loss, and batch handling. -2. A **YAML configuration file** — specifies the model, data, optimizer, dLLM-specific settings, and distributed training strategy. - -The recipe uses a **strategy pattern** to handle differences between model families. The `dllm.mode` field in the YAML selects the strategy: - -| Mode | Strategy | Description | -|------|----------|-------------| -| `mdlm` | `MDLMStrategy` | LLaDA-style: model receives corrupted tokens, MDLM cross-entropy loss | - -### LLaDA Configuration - -See [llada_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/dllm_sft/llada_sft.yaml) for the full working config. The key dLLM-specific sections are: - -```yaml -model: - pretrained_model_name_or_path: GSAI-ML/LLaDA-8B-Base - torch_dtype: float32 - trust_remote_code: true - -dllm: - mode: mdlm - mask_token_id: 126336 # LLaDA mask token - eps: 0.001 # Minimum corruption ratio - -dataset: - unshifted: true # Required for dLLM training -``` - -### Key dLLM Config Fields - -| Field | Description | -|-------|-------------| -| `dllm.mode` | Training strategy (`mdlm`) | -| `dllm.mask_token_id` | Token ID used for masking (`126336` for LLaDA) | -| `dllm.eps` | Minimum corruption ratio to avoid zero-corruption samples | -| `dataset.unshifted` | Must be `true` for dLLM — disables the autoregressive input/target shift | - -## Fine-Tune the Model - -```bash -torchrun --nproc-per-node=8 \ - nemo_automodel/recipes/dllm/train_ft.py \ - -c examples/dllm_sft/llada_sft.yaml -``` - -## Generation / Inference - -The generation script ([`generate.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/dllm_generate/generate.py)) supports chat, raw, and infilling modes for LLaDA checkpoints. - -### LLaDA Generation - -```bash -python examples/dllm_generate/generate.py \ - --checkpoint \ - --prompt "Explain what a neural network is." -``` - -### Generation Parameters - -| Parameter | Description | Default | -|-----------|-------------|---------| -| `--steps` | Number of denoising steps | 128 | -| `--max_new_tokens` | Maximum tokens to generate | 128 | -| `--block_size` | Tokens per denoising block | 32 | -| `--temperature` | Gumbel noise temperature (0 = greedy) | 0.0 | -| `--remasking` | Confidence scoring strategy for selecting which positions to unmask | `low_confidence` | diff --git a/docs/fern/versions/nightly/pages/guides/fp8-training.mdx b/docs/fern/versions/nightly/pages/guides/fp8-training.mdx deleted file mode 100644 index 8dedb024ea..0000000000 --- a/docs/fern/versions/nightly/pages/guides/fp8-training.mdx +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: "FP8 Training in NeMo AutoModel" -description: "" -position: 4 ---- -NeMo AutoModel supports FP8 quantization using [TorchAO](https://github.com/pytorch/ao) and `torch.compile` to accelerate training on compatible hardware. - -FP8 (8-bit floating point) quantization can provide substantial speedups for models where the majority of GEMMs are sufficiently large. The speedup from using FP8 tensor cores must outweigh the overhead of dynamic quantization. - -### Requirements for FP8 Training in NeMo AutoModel - -To enable FP8 training in NeMo AutoModel, the following hardware and software requirements must be met: - -- **Hardware**: - An NVIDIA H100 GPU or newer is required. These GPUs feature FP8 tensor cores that accelerate training. - -- **Software**: - The TorchAO library must be installed. - -- **Configuration**: - Both `torch.compile` and `fp8` must be enabled in your training configuration. - **Important**: `torch.compile` is essential for achieving meaningful speedup with TorchAO FP8 training. - -## Install TorchAO - -Make sure you have TorchAO installed. Follow the [installation guide](https://github.com/pytorch/ao?tab=readme-ov-file#-installation) for TorchAO. - -## Usage - -### Configure FP8 - -To enable FP8 quantization with `torch.compile`, you need both FP8 and compilation enabled in your configuration: - -```yaml -# Enable torch.compile (required for FP8 speedup) -compile: - enabled: true - mode: "default" - fullgraph: false - dynamic: false - -# Enable FP8 quantization -fp8: - enabled: true - recipe_name: tensorwise - enable_fsdp_float8_all_gather: true - precompute_float8_dynamic_scale_for_fsdp: true - force_recompute_fp8_weight_in_bwd: true - filter_fqns: ["lm_head"] - emulate: false -``` - -### FP8 Config Parameters - -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `recipe_name` | str | None | FP8 recipe: "tensorwise", "rowwise", or "rowwise_with_gw_hp" | -| `enable_fsdp_fp8_all_gather` | bool | False | Enable FP8 all-gather in FSDP for bandwidth savings | -| `force_recompute_fp8_weight_in_bwd` | bool | False | Force recomputation of FP8 weights in backward pass | -| `precompute_fp8_dynamic_scale_for_fsdp` | bool | False | Precompute FP8 scales for FSDP optimization | -| `filter_fqns` | list[str] | [] | Module names to exclude from FP8 conversion | -| `emulate` | bool | False | Use emulation instead of hardware acceleration | - -### Scaling Strategies - -#### Tensorwise Scaling (Default) -- Single scale per tensor -- Good performance, moderate accuracy -- Recommended for most use cases - -#### Rowwise Scaling -- Scale per row for better accuracy -- Slower than tensorwise -- Better numerical stability - -For more on scaling strategies, refer to the [TorchAO FP8 documentation](https://github.com/pytorch/ao/tree/main/torchao/float8). - -## Filter Modules - -You can exclude specific modules from FP8 conversion using `filter_fqns`: - -```yaml -fp8: - enabled: true - recipe_name: tensorwise - filter_fqns: ["lm_head"] # Skip these modules -``` - -### Speed and Convergence - -FP8 quantization provides measurable performance improvements while maintaining model convergence: - -- **Speed**: Over 1.2x training speedup on 8xH100 with tensorwise scaling. -- **Convergence**: FP8 training achieves loss parity with BF16 training. -- **Memory**: FP8 training achieves on par memory usage with BF16 baseline. - -![FP8 Convergence Comparison](./fp8_convergence.jpg) - -*Figure: Loss curves comparing FP8 tensorwise scaling + torch.compile vs. BF16 + torch.compile training on 8xH100 with 8k sequence length, demonstrating virtually identical convergence behavior with 1.24x speedup* - -## Ready-to-Use Recipes -We provide FP8 training configs for popular models: - -- **Llama**: [Llama 3.1 8B](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_1/llama3_1_8b_hellaswag_fp8.yaml) -- **Mistral**: [Mistral 7B](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_7b_hellaswag_fp8.yaml), [Mistral Nemo 2407](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_nemo_2407_hellaswag_fp8.yaml) -- **Qwen**: [Qwen 2.5 7B](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen2_5_7b_hellaswag_fp8.yaml) -- **Phi**: [Phi 4](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_4_hellaswag_fp8.yaml) - -Check out our [examples directory](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_finetune) for more recipes and configurations. - -To run any of these FP8 training recipes, use the following command: - -```bash -automodel --nproc-per-node=8 -``` - -For example, to train Llama 3.1 8B with FP8: -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_1/llama3_1_8b_hellaswag_fp8.yaml -``` - -## Performance Considerations - -FP8 requires specific conditions to be effective: -- Input tensors must have dimensions divisible by 16 -- Use compatible hardware (H100+) -- Train with `torch.compile` - -FP8 works best when the majority of GEMM operations are sufficiently large such that the speedup achieved by using FP8 tensor cores is greater than the overhead of dynamic quantization. - -### Ideal Conditions for FP8 Performance - -- Linear layers are large and compute-intensive -- The model consists of fewer small operations and more large matrix multiplications -- You have modern (H100+) hardware optimized for FP8 acceleration -- Moderate numerical precision is acceptable and slight approximations won't affect outcomes - -## References - -- [TorchAO FP8 Documentation](https://github.com/pytorch/ao/tree/main/torchao/float8) -- [FP8 Performance Benchmarks](https://github.com/pytorch/ao/tree/main/torchao/float8#performance) -- [NVIDIA FP8 Primer](https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/examples/fp8_primer.html) diff --git a/docs/fern/versions/nightly/pages/guides/fp8_convergence.jpg b/docs/fern/versions/nightly/pages/guides/fp8_convergence.jpg deleted file mode 100644 index 15733abf29d933356d6932eaa95128ad682681ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44260 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 diff --git a/docs/fern/versions/nightly/pages/guides/gradient-checkpointing.mdx b/docs/fern/versions/nightly/pages/guides/gradient-checkpointing.mdx deleted file mode 100644 index c1ccb64754..0000000000 --- a/docs/fern/versions/nightly/pages/guides/gradient-checkpointing.mdx +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "Gradient (Activation) Checkpointing in NeMo AutoModel" -description: "" -position: 2 ---- -Gradient checkpointing, also called _activation checkpointing_, trades a little extra compute for a **large reduction in GPU memory** by recomputing intermediate activations during the backwards pass instead of storing them. -It is especially powerful when combined with memory-efficient loss functions (e.g., Linear-Cut Cross-Entropy) and parameter sharding using FSDP. - -## Enable Gradient Checkpointing - -### Configure in YAML -Add the `activation_checkpointing: true` flag under your distributed strategy. -Example (snippet): - -```yaml -# examples/llm_finetune/llama_3_2_1b_my_finetune.yaml -... - -# FSDP2 (use strategy name; optional parallelism sizes) -distributed: - strategy: fsdp2 - activation_checkpointing: true - # dp_size: null - # tp_size: 1 - # cp_size: 1 - ... -``` - -### Configure Programmatically -```python -from nemo_automodel.components.distributed.config import FSDP2Config -from nemo_automodel.components.distributed.fsdp2 import FSDP2Manager - -config = FSDP2Config(activation_checkpointing=True) -# device_mesh is created elsewhere (e.g. by the recipe via setup_distributed) -manager = FSDP2Manager(config, device_mesh=device_mesh, moe_mesh=moe_mesh) -model = manager.parallelize(model) -``` - -## Combine with Linear-Cut Cross-Entropy (LC-CE) - -Linear-Cut Cross-Entropy (LC-CE) reduces the hidden-state memory required to compute the loss by calculating the softmax on the fly, thus avoiding the need to allocate memory for the logits. -It is already available using `nemo_automodel.components.loss.linear_ce.FusedLinearCrossEntropy` and can be enabled in recipes by using the following: - -```yaml -model: - ... - output_hidden_states: true - -loss_fn: - _target_: nemo_automodel.components.loss.linear_ce.FusedLinearCrossEntropy -``` - -LC-CE and gradient checkpointing target **different memory hot-spots** (output layer vs. transformer blocks) so their benefits stack almost linearly. - -## Example Memory Savings (H100-80GB, Llama-3.2-1B) -| Technique | Max GPU Mem (GB) | Δ vs Baseline | -|-----------|-----------------|---------------| -| Baseline | 53.03 | - | -| + FSDP (dp_size=8) | 47.59 | ↓ 10 % | -| + Gradient Checkpointing | 33.06 | ↓ 38 % | -| + LC-CE | 7.30 | ↓ 86 % | -| **FSDP + LC-CE + Checkpointing** | **7.30** | **↓ 86 %** | - - -- Measurements taken with local batch size = 8, sequence len = 2048, AdamW, PyTorch 2.8. -- Peak memory reported by `torch.cuda.max_memory_allocated()` averaged across DP ranks. -- Expect ±5 % variance depending on exact model, sequence length and GPU architecture. - - - -## Performance Considerations -1. **Extra compute**: Each checkpointed segment is recomputed once during the backward pass. In practice, the wall-clock overhead is ≈5-10% for transformer models. -2. **Throughput vs. Batch Size**: The goal is usually to _increase batch size_ or _sequence length_ while keeping throughput constant. - -## Verify It Works -Run your training script and inspect the peak memory: -```bash - -# If running on 8x GPUs -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama_3_2_1b_my_finetune.yaml - -# If running on 1x GPU -automodel examples/llm_finetune/llama3_2/llama_3_2_1b_my_finetune.yaml -``` -If we run with the above settings (activation ckpt = on, lc-ce = on, fsdp = on), look for a log line similar to: -``` -... | mem 7.30 GiB | ... -``` diff --git a/docs/fern/versions/nightly/pages/guides/huggingface-api-compatibility.mdx b/docs/fern/versions/nightly/pages/guides/huggingface-api-compatibility.mdx deleted file mode 100644 index c577194b27..0000000000 --- a/docs/fern/versions/nightly/pages/guides/huggingface-api-compatibility.mdx +++ /dev/null @@ -1,225 +0,0 @@ ---- -title: "🤗 Transformers API Compatibility" -description: "" -position: 5 ---- -NeMo AutoModel is built to work with the 🤗 Hugging Face ecosystem. -In practice, compatibility comes in two layers: - -- **API compatibility**: for many workflows, you can keep your existing `transformers` code and swap in NeMo AutoModel “drop-in” wrappers (`NeMoAutoModel*`, `NeMoAutoTokenizer`) with minimal changes. -- **Artifact compatibility**: NeMo AutoModel produces **Hugging Face-compatible checkpoints** (config + tokenizer + safetensors) that can be loaded by Hugging Face Transformers and downstream tools (vLLM, SGLang, etc.). - -This page summarizes what "HF compatibility" means in NeMo AutoModel, calls out differences you should be aware of, and provides side-by-side examples. - -## Transformers Version Compatibility: v4 and v5 - -### Transformers v4 (Current Default) - -NeMo AutoModel currently pins Hugging Face Transformers to the **v4** major line (see `pyproject.toml`, currently `transformers<=4.57.5`). - -This means: - -- NeMo AutoModel is primarily tested and released against **Transformers v4.x** -- New model releases on the Hugging Face Hub that require a newer Transformers may require upgrading NeMo AutoModel as well (similar to upgrading `transformers` directly) - -### Transformers v5 (Forward-Compatibility and Checkpoint Interoperability) - -Transformers **v5** introduces breaking changes across some internal utilities (e.g., cache APIs) and adds/reshapes tokenizer backends for some model families. - -NeMo AutoModel addresses this in two complementary ways: - -- **Forward-compatibility shims**: NeMo AutoModel includes small compatibility patches to smooth over known API differences across Transformers releases (for example, cache utility method names). The built-in recipes apply these patches automatically. -- **Backports where needed**: for some model families, NeMo AutoModel may vendor/backport Hugging Face code that originated in the v5 development line so users can run those models while staying on a pinned v4 dependency. -- **Stable artifact format**: NeMo AutoModel checkpoints are written in Hugging Face-compatible `save_pretrained` layouts (config + tokenizer + safetensors). These artifacts are designed to be loadable by both Transformers **v4** and **v5** (and non-Transformers tools that consume HF-style model repos). - - -If you are running Transformers v5 in another environment, you can still use NeMo AutoModel-produced consolidated checkpoints with Transformers' standard loading APIs. For details on the checkpoint layouts, see [checkpointing](/development/checkpointing). - - - -## Drop-In Compatibility and Key Differences - -### Drop-In (Same Mental Model as Transformers) - -- **Load by model ID or local path**: `from_pretrained(...)` -- **Standard HF config objects**: `AutoConfig` / `config.json` -- **Tokenizers**: standard `PreTrainedTokenizerBase` behavior, including `__call__` to create tensors and `decode`/`batch_decode` -- **Generation**: `model.generate(...)` and the usual generation kwargs - -### Differences (Where NeMo AutoModel Adds Value or Has Constraints) - -- **Performance features**: NeMo AutoModel can automatically apply optional kernel patches/optimizations (e.g., SDPA selection, Liger kernels, DeepEP, etc.) while keeping the public model API the same. -- **Distributed training stack**: NeMo AutoModel's recipes/CLI are designed for multi-GPU/multi-node fine-tuning with PyTorch-native distributed features (FSDP2, pipeline parallelism, etc.). -- **CUDA expectation**: NeMo AutoModel's `NeMoAutoModel*` wrappers are primarily optimized for NVIDIA GPU workflows, and offer support for CPU workflows as well. - - -`NeMoAutoModelForCausalLM.from_pretrained(...)` currently assumes CUDA is available (it uses `torch.cuda.current_device()` internally). If you need CPU-only inference, use Hugging Face `transformers` directly. - - - -## API Mapping (Transformers and NeMo AutoModel) - -### API Name Mapping - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
🤗 Hugging Face (transformers)NeMo AutoModel (nemo_automodel)Status
transformers.AutoModelForCausalLMnemo_automodel.NeMoAutoModelForCausalLM
transformers.AutoModelForImageTextToTextnemo_automodel.NeMoAutoModelForImageTextToText
transformers.AutoModelForSequenceClassificationnemo_automodel.NeMoAutoModelForSequenceClassification
transformers.AutoModelForTextToWaveformnemo_automodel.NeMoAutoModelForTextToWaveform
transformers.AutoTokenizer.from_pretrained(...)nemo_automodel.NeMoAutoTokenizer.from_pretrained(...)
model.generate(...)model.generate(...)🚧
model.save_pretrained(path)model.save_pretrained(path, checkpointer=...)🚧
- -## Side-by-Side Examples - -### Load a Model and Tokenizer (Transformers v4) - - - - - - - - - - - - - - -
🤗 Hugging Face (transformers)NeMo AutoModel (nemo_automodel)
-
{`import torch
-from transformers import AutoModelForCausalLM, AutoTokenizer
-
-model_id = "gpt2"
-
-tokenizer = AutoTokenizer.from_pretrained(model_id)
-model = AutoModelForCausalLM.from_pretrained(
-    model_id,
-    torch_dtype=torch.bfloat16,
-)`}
-
-
{`import torch
-from nemo_automodel import NeMoAutoModelForCausalLM, NeMoAutoTokenizer
-
-model_id = "gpt2"
-
-tokenizer = NeMoAutoTokenizer.from_pretrained(model_id)
-model = NeMoAutoModelForCausalLM.from_pretrained(
-    model_id,
-    torch_dtype=torch.bfloat16,
-)`}
-
- -### Text Generation - -This snippet assumes you already have a `model` and `tokenizer` (see the loading snippet above). - - - - - - - - - - - - - - -
🤗 Hugging Face (transformers)NeMo AutoModel (nemo_automodel)
-
{`import torch
-
-prompt = "Write a haiku about GPU kernels."
-inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
-
-with torch.inference_mode():
-    out = model.generate(**inputs, max_new_tokens=64)
-
-print(tokenizer.decode(out[0], skip_special_tokens=True))`}
-
-
{`import torch
-
-prompt = "Write a haiku about GPU kernels."
-inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
-
-with torch.inference_mode():
-    out = model.generate(**inputs, max_new_tokens=64)
-
-print(tokenizer.decode(out[0], skip_special_tokens=True))`}
-
- -### Tokenizers (Transformers vs NeMo AutoModel) - -NeMo AutoModel provides `NeMoAutoTokenizer` as a Transformers-like auto-tokenizer with a small registry for specialized backends (and a safe fallback when no specialization is needed). - - - - - - - - - - - - - - -
🤗 Hugging Face (transformers)NeMo AutoModel (nemo_automodel)
-
{`from transformers import AutoTokenizer
-
-tok = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")`}
-
-
{`from nemo_automodel import NeMoAutoTokenizer
-
-tok = NeMoAutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")`}
-
- -## Checkpoints: Save in NeMo AutoModel, Load Everywhere - -NeMo AutoModel training recipes write checkpoints in Hugging Face-compatible layouts, including consolidated safetensors that you can load directly with Transformers: - -- See [checkpointing](/development/checkpointing) for checkpoint formats and example directory layouts. -- See [model coverage](/model-coverage/overview) for notes on how model support depends on the pinned Transformers version. - -If your goal is: **train/fine-tune in NeMo AutoModel → deploy in the HF ecosystem**, the recommended workflow is to enable consolidated safetensors checkpoints and then load them with the standard HF APIs or downstream inference engines. diff --git a/docs/fern/versions/nightly/pages/guides/installation.mdx b/docs/fern/versions/nightly/pages/guides/installation.mdx deleted file mode 100644 index 8a4bab22a0..0000000000 --- a/docs/fern/versions/nightly/pages/guides/installation.mdx +++ /dev/null @@ -1,335 +0,0 @@ ---- -title: "Install NeMo AutoModel" -description: "" -position: 3 ---- -This guide explains how to install NeMo AutoModel for LLM, VLM, and OMNI models on various platforms and environments. Depending on your use case, there are several ways to install it: - -| Method | Dev Mode | Use Case | Recommended For | -| ----------------------- | ---------|----------------------------------------------------------------- | ---------------------------- | -| 📦 **PyPI** | - | Install stable release with minimal setup | Most users, production usage | -| 🐳 **Docker** | - | Use in isolated GPU environments, e.g., with NeMo container | Multi-node deployments | -| 🐍 **Git Repo** | ✅ | Use the latest code without cloning or installing extras manually | Power users, testers | -| 🧪 **Editable Install** | ✅ | Contribute to the codebase or make local modifications | Contributors, researchers | -| 🐳 **Docker + Mount** | ✅ | Use in isolated GPU environments, e.g., with NeMo container | Multi-node deployments | - -## Choose Your Installation Method - -Pick the installation method that matches your needs and platform. - -### Decision Criteria - -| Method | Best For | Pros | Cons | -|--------|----------|------|------| -| **Docker Container** | Production, multi-node, Debian-based systems | Reproducible environment, pre-configured dependencies, GPU driver isolation | Larger download size, container overhead | -| **virtualenv (PyPI/Git)** | Local development, quick prototyping, macOS | Fast setup, lightweight, direct code access | Manual dependency management, platform-specific issues | - -### When to Use Docker Containers - -Use Docker containers when you need: - -- **Multi-node deployments**: Containers ensure consistency across cluster nodes -- **Production environments**: Reproducible builds with tested dependency versions -- **GPU driver compatibility**: Isolates CUDA/driver versions from host system -- **Debian-based systems**: Recommended for Ubuntu, Debian, and derivatives due to dependency complexity -- **Complex dependencies**: Pre-configured environment with all optimizations (TransformerEngine, DeepEP, etc.) -- **Team consistency**: Same environment across development, testing, and production - -### When to Use virtualenv - -Use virtualenv (PyPI, Git, or editable install) when you need: - -- **Local development**: Fast iteration on code changes -- **Quick prototyping**: Minimal setup for experimentation -- **macOS systems**: Better native support without container overhead -- **Frequent code changes**: Contributors working on the codebase (use editable install) -- **Compatible GPU drivers**: System has correct CUDA toolkit and drivers installed -- **Lightweight setup**: Minimal disk space and memory footprint - -### Platform-Specific Recommendations - -#### Linux (Debian-based: Ubuntu, Debian) - -**Recommended: Docker Container** - -Debian-based systems can have dependency conflicts with system packages. Containers provide isolation and consistency. - -```bash -docker pull nvcr.io/nvidia/nemo-automodel:25.11.00 -docker run --gpus all -it --rm --shm-size=8g nvcr.io/nvidia/nemo-automodel:25.11.00 -``` - -**Alternative: virtualenv** (if Docker is not available) - -Ensure CUDA 11.8+ and compatible drivers are installed: - -```bash -# Check CUDA version -nvidia-smi - -# Install via PyPI -pip3 install nemo-automodel -``` - -#### Linux (RHEL, CentOS, Fedora) - -**Recommended: Docker Container** - -Containers avoid enterprise Linux package management complexity. - -Follow the same Docker commands as Debian-based systems above. - -#### macOS - -**Recommended: virtualenv** - -Docker on macOS has GPU limitations. Use native Python installation: - -```bash -# Using PyPI -pip3 install nemo-automodel - -# Or using uv for reproducible environments -uv pip install nemo-automodel -``` - - -GPU training on macOS is not supported. Use macOS for CPU-based experimentation or remote cluster submission. - - - -#### Windows - -**Recommended: WSL2 + Docker** - -Run NeMo AutoModel in WSL2 with Docker Desktop: - -1. Install WSL2 and Docker Desktop. -2. Use Docker container within WSL2 (follow Linux instructions). - -**Alternative: WSL2 and virtualenv** - -Install directly in WSL2 Ubuntu environment (follow Debian instructions). - -### Common Issues and Solutions - -**GPU driver compatibility errors** -- **Problem**: CUDA version mismatch between host and application -- **Solution**: Use Docker container to isolate driver versions - -**Dependency conflicts on Debian/Ubuntu** -- **Problem**: System packages conflict with Python packages -- **Solution**: Use Docker container or create isolated virtualenv with `uv` - -**Out of memory during container startup** -- **Problem**: Insufficient shared memory for PyTorch data loading -- **Solution**: Increase `--shm-size` parameter (e.g., `--shm-size=16g`) - -**TransformerEngine import failures** -- **Problem**: Incorrect CUDA toolkit or missing dependencies -- **Solution**: Use pre-configured Docker container - -## Prerequisites - -### System Requirements -- **Python**: 3.10 or higher -- **CUDA**: 11.8 or higher (for GPU support) -- **Memory**: Minimum 16GB RAM, 32GB+ recommended -- **Storage**: At least 50GB free space for models and datasets - -### Hardware Requirements - -- **GPU**: NVIDIA GPU with 8GB+ VRAM (16GB+ recommended) -- **CPU**: Multi-core processor (8+ cores recommended) -- **Network**: Stable internet connection for downloading models - -## Installation Options for Non-Developers -This section explains the easiest installation options for non-developers, including using pip3 via PyPI or leveraging a preconfigured NVIDIA NeMo Docker container. Both methods offer quick access to the latest stable release of NeMo AutoModel with all required dependencies. - -### Install via PyPI (Recommended) - -For most users, the easiest way to get started is using `pip3`. - -```bash -pip3 install nemo-automodel -``` - -This installs the latest stable release of NeMo AutoModel from PyPI. - -To verify the install, run `python -c "import nemo_automodel; print(nemo_automodel.__version__)"`. See [nemo-automodel on PyPI](https://pypi.org/project/nemo-automodel/). - - - -### Install with NeMo Docker Container -You can use NeMo AutoModel with the NeMo Docker container. Pull the container by running: -```bash -docker pull nvcr.io/nvidia/nemo-automodel:25.11.00 -``` - -The above `docker` command uses the [`25.11.00`](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel?version=25.11.00) container. Use the [most recent container](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel) version to ensure you get the latest version of AutoModel and its dependencies like PyTorch, Transformers, etc. - - - -Then you can enter the container using: -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v "$(pwd)"/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:25.11.00 -``` - - -**Persist your checkpoints.** By default, checkpoints are written to `checkpoints/` inside the container. Because `--rm` destroys the container on exit, any data stored only inside the container is lost. Always bind-mount a host directory for the checkpoint path (as shown with `-v` above) so that your trained weights survive after the container stops. You can also mount additional directories for datasets and Hugging Face cache: -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v /path/to/your/checkpoints:/opt/Automodel/checkpoints \ - -v /path/to/your/datasets:/datasets \ - -v /path/to/your/hf_cache:/root/.cache/huggingface \ - nvcr.io/nvidia/nemo-automodel:25.11.00 -``` - - - - -**Models that require CUDA-specific packages (e.g., Nemotron).** Some model families—such as Nemotron Nano and Nemotron Flash—depend on packages like `mamba-ssm` and `causal-conv1d` that must be compiled against a matching CUDA toolkit. Installing these from source on a bare-metal host can be error-prone. The NeMo Automodel Docker container ships with these dependencies pre-built, so **using the container is the recommended approach** for fine-tuning Nemotron and other models with similar requirements. - - - ---- -## Installation Options for Developers - -This section provides installation options for developers, including pulling the latest source from GitHub, using editable mode, or mounting the repo inside a NeMo Docker container. - -### Install from GitHub (Source) - -If you want the **latest features** from the `main` branch or want to contribute: - -#### Option A – Use `pip` With Git Repo -```bash -pip3 install git+https://github.com/NVIDIA-NeMo/Automodel.git -``` - -This installs the repo as a standard Python package (not editable). - - - -#### Option B – Use `uv` With Git Repo -```bash -uv pip install git+https://github.com/NVIDIA-NeMo/Automodel.git -``` - -`uv` handles virtual environment transparently and enables more reproducible installs. - - - -### Install in Developer Mode (Editable Install) - -To contribute or modify the code: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -pip3 install -e . -``` - - -This installs AutoModel in editable mode, so changes to the code are immediately reflected in Python. - - - -### Mount the Repo into a NeMo Docker Container - -To run `Automodel` inside a NeMo container while **mounting your local repo**, follow these steps: - -```bash -# Step 1: Clone the AutoModel repository. -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel - -# Step 2: Pull a compatible container image (replace the tag as needed). -docker pull nvcr.io/nvidia/nemo-automodel:25.11.00 - -# Step 3: Run the container, mount the repo, and run a quick sanity check. -docker run --gpus all -it --rm \ - -v $(pwd):/workspace/Automodel \ # Mount repo into container workspace - -v $(pwd)/Automodel:/opt/Automodel \ # Optional: Mount Automodel under /opt for flexibility - --shm-size=8g \ # Increase shared memory for PyTorch/data loading - nvcr.io/nvidia/nemo-automodel:25.11.00 /bin/bash -c "\ - cd /workspace/Automodel && \ # Enter the mounted repo - pip install -e . && \ # Install Automodel in editable mode - automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml" # Run a usage example -``` - -The above `docker` command mounts your local `Automodel` directory into the container at `/workspace/Automodel`. - - - -## Install Profiles - -NeMo AutoModel provides several install extras for different use cases. - -### Full Install (default) - -Installs the core library with all LLM training dependencies (PyTorch, CUDA, etc.): - -```bash -pip3 install nemo-automodel -``` - -### CLI-Only Install (Login Nodes) - -If you only need to **submit jobs** from a login node or CI environment (SLURM, -SkyPilot, NeMo-Run) and do **not** need to run training locally, use the -lightweight CLI-only install: - -```bash -pip3 install nemo-automodel[cli] -``` - -This installs only `pyyaml` -- no PyTorch, no CUDA. The `automodel` and `am` -CLI commands will be available for SLURM and SkyPilot job submission. If you -also need the NeMo-Run launcher, install it separately (`pip install nemo-run`). -If you accidentally try to run a local/interactive job with this install, you -will get a clear error with instructions to install the full package. - -### VLM Dependencies - -For vision-language model training, add the VLM extras: - -```bash -pip3 install nemo-automodel[vlm] -``` - -### CUDA-Specific Packages - -For models requiring TransformerEngine, bitsandbytes, Mamba, or other -CUDA-compiled packages: - -```bash -pip3 install nemo-automodel[cuda] -``` - -### All Extras - -Install everything (CUDA, VLM, NeMo-Run, etc.): - -```bash -pip3 install nemo-automodel[all] -``` - - -You can combine extras: `pip3 install nemo-automodel[vlm,cuda]` - - - -## Summary -| Goal | Command or Method | -| --------------------------- | --------------------------------------------------------------- | -| Stable install (PyPI) | `pip3 install nemo-automodel` | -| CLI-only (login nodes) | `pip3 install nemo-automodel[cli]` | -| Latest from GitHub | `pip3 install git+https://github.com/NVIDIA-NeMo/Automodel.git` | -| Editable install (dev mode) | `pip install -e .` after cloning | -| Run without installing | Use `PYTHONPATH=$(pwd)` to run scripts | -| Use in Docker container | Mount repo and `pip install -e .` inside container | -| Fast install (using `uv`) | `uv pip install ...` | diff --git a/docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx b/docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx deleted file mode 100644 index 46fadca317..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-dataset.mdx +++ /dev/null @@ -1,252 +0,0 @@ ---- -title: "Use the ColumnMappedTextInstructionDataset" -description: "" -position: 4 ---- -This guide explains how to use `ColumnMappedTextInstructionDataset` to quickly and flexibly load instruction-answer datasets for LLM fine-tuning, with minimal code changes and support for common tokenization strategies. - -The `ColumnMappedTextInstructionDataset` is a lightweight, plug-and-play helper that lets you train on instruction-answer style corpora without writing custom Python for every new schema. You simply specify which columns map to logical fields like `context`, `question`, and `answer`, and the loader handles the rest automatically. This enables: - -- Quick prototyping across diverse instruction datasets -- Schema flexibility without requiring code changes -- Consistent field names for training loops, regardless of dataset source - -`ColumnMappedTextInstructionDataset` is a **map-style** dataset (`torch.utils.data.Dataset`): it supports `len(ds)` and `ds[i]`, and it loads data **non-streaming**. - -It supports two data sources out-of-the-box: - -1. **Local JSON/JSONL files** - pass a single file path or a list of paths on disk. Newline-delimited JSON works great. -2. **Hugging Face Hub** - point to any dataset repo (`org/dataset`) that contains the required columns. - -For **streaming** (including **Delta Lake / Databricks**), use [`ColumnMappedTextInstructionIterableDataset`](/datasets/columnmapped-iterable). The iterable variant always streams by design to avoid accidentally materializing entire datasets to disk/memory. - ---- -## Quickstart -The fastest way to sanity-check the loader is to point it at an existing Hugging Face dataset and print the first sample. This section provides a minimal, runnable example to help you quickly try out the dataset. - -```python -from transformers import AutoTokenizer -from nemo_automodel.components.datasets.llm.column_mapped_text_instruction_dataset import ColumnMappedTextInstructionDataset - -tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B") - -ds = ColumnMappedTextInstructionDataset( - path_or_dataset_id="Muennighoff/natural-instructions", - column_mapping={ - "context": "definition", - "question": "inputs", - "answer": "targets" - }, - tokenizer=tokenizer, - answer_only_loss_mask=True, -) - -sample = ds[0] -print(sample.keys()) - -# Typical keys include: input_ids, labels, attention_mask (and an internal ___PAD_TOKEN_IDS___ helper). -# Note: when answer_only_loss_mask=True, prompt tokens are masked in labels with -100 -# (the standard CrossEntropy "ignore_index"). -``` - -The code above is intended only for a quick sanity check of the dataset and its tokenization output. For training or production use, configure the dataset using YAML as shown below. YAML offers a reproducible, maintainable, and scalable way to specify dataset and tokenization settings. - ---- -## Usage Examples - -This section provides practical usage examples, including how to load remote datasets, work with local files, and configure pipelines using YAML recipes. - -### Local JSONL Example - -Assume you have a local newline-delimited JSON file at `/data/my_corpus.jsonl` -with the simple schema `{instruction, output}`. A few sample rows: - -```json -{"instruction": "Translate 'Hello' to French", "output": "Bonjour"} -{"instruction": "Summarize the planet Neptune.", "output": "Neptune is the eighth planet from the Sun."} -``` - -You can load it using Python code like: - -```python -local_ds = ColumnMappedTextInstructionDataset( - path_or_dataset_id=["/data/my_corpus_1.jsonl", "/data/my_corpus_2.jsonl"], # can also be a single path (string) - column_mapping={ - "question": "instruction", - "answer": "output", - }, - tokenizer=tokenizer, - answer_only_loss_mask=False, # compute loss over full sequence -) - -print(local_ds[0].keys()) # dict_keys(['input_ids', 'labels', 'attention_mask', '___PAD_TOKEN_IDS___']) -``` - -You can configure the dataset entirely from your recipe YAML. For example: -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.column_mapped_text_instruction_dataset.ColumnMappedTextInstructionDataset - path_or_dataset_id: - - /data/my_corpus_1.jsonl - - /data/my_corpus_2.jsonl - column_mapping: - question: instruction - answer: output - answer_only_loss_mask: false -``` - -### Remote Dataset Example - -In the following section, we demonstrate how to load the instruction-tuning corpus -[`Muennighoff/natural-instructions`](https://huggingface.co/datasets/Muennighoff/natural-instructions). -The dataset schema is `{task_name, id, definition, inputs, targets}`. - -The following are examples from the training split: - -```json -{ - "task_name": "task001_quoref_question_generation", - "id": "task001-abc123", - "definition": "In this task, you're given passages that...", - "inputs": "Passage: A man is sitting at a piano...", - "targets": "What is the first name of the person who doubted it would be explosive?" -} -{ - "task_name": "task002_math_word_problems", - "id": "task002-def456", - "definition": "Solve the following word problem.", - "inputs": "If there are 3 apples and you take 2...", - "targets": "1" -} -``` - -For basic QA fine-tuning, we usually map `definition → context`, `inputs → question`, and `targets → answer` as follows: - -```python -from nemo_automodel.components.datasets.llm.column_mapped_text_instruction_dataset import ( - ColumnMappedTextInstructionDataset, -) -from transformers import AutoTokenizer - -tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B") - -remote_ds = ColumnMappedTextInstructionDataset( - path_or_dataset_id="Muennighoff/natural-instructions", # Hugging Face repo ID - column_mapping={ - "context": "definition", # high-level context - "question": "inputs", # the actual prompt / input - "answer": "targets", # expected answer string - }, - tokenizer=tokenizer, - split="train[:5%]", # demo slice; omit (i.e., `split="train",`) for full data - answer_only_loss_mask=True, -) -``` - -You can configure the entire dataset directly from your recipe YAML. For example: -```yaml -# dataset section of your recipe's config.yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.column_mapped_text_instruction_dataset.ColumnMappedTextInstructionDataset - path_or_dataset_id: Muennighoff/natural-instructions - split: train - column_mapping: - context: definition - question: inputs - answer: targets - answer_only_loss_mask: true -``` - -### Streaming / Delta Lake / Databricks - - -`ColumnMappedTextInstructionDataset` does not support streaming or Delta Lake / Databricks sources. For those, use [`ColumnMappedTextInstructionIterableDataset`](/datasets/columnmapped-iterable). - - - - -Delta Lake / Databricks (including `delta_sql_query` and authentication) is supported only by `ColumnMappedTextInstructionIterableDataset`. See [`column-mapped-text-instruction-iterable-dataset.md`](/datasets/columnmapped-iterable) for details. - - - -### Advanced Options -| Arg | Default | Description | -|-------------------------|---------|-------------| -| `split` | `"train"` | Which split to pull from a HF repo (`train`, `validation`, etc.). Ignored for local JSON/JSONL. | -| `name` | `None` | Name of the Hugging Face dataset configuration/subset to load. | -| `answer_only_loss_mask` | `True` | Mask prompt tokens in `labels` with `-100` (the standard CrossEntropy `ignore_index`). | -| `use_hf_chat_template` | `False` | If `True` and the tokenizer supports chat templates, format as a system/user/assistant conversation via `tokenizer.apply_chat_template(...)`. | -| `seq_length` | `None` | Optional max sequence length; used for padding/truncation when enabled. | -| `padding` | `"do_not_pad"` | Padding strategy passed to the tokenizer (`"do_not_pad"`, `"max_length"`, `True`, etc.). | -| `truncation` | `"do_not_truncate"` | Truncation strategy passed to the tokenizer (`"do_not_truncate"`, `True`, etc.). | -| `limit_dataset_samples` | `None` | Optionally load only the first \(N\) samples (useful for debugging). | - ---- -## Tokenization Paths -This section explains how the dataset formats and tokenizes samples. - -`ColumnMappedTextInstructionDataset` produces standard next-token training tensors: - -- `input_ids` -- `labels` -- `attention_mask` - -When `answer_only_loss_mask=True`, prompt tokens are masked in `labels` with `-100` (the standard CrossEntropy `ignore_index`). - -The dataset supports two formatting paths: - -1. **Chat-template path (opt-in)**: if `use_hf_chat_template=True` and the tokenizer exposes a `chat_template` and `apply_chat_template`, the dataset builds messages like: - - `[{"role": "system", "content": }, {"role": "user", "content": }, {"role": "assistant", "content": }]` - - and tokenizes them via `tokenizer.apply_chat_template(..., tokenize=True, return_dict=True)`. - -2. **Plain prompt/completion path (default)**: otherwise the dataset concatenates prompt and answer and tokenizes the result. - -In both cases, `labels` are the next-token targets (shifted by one relative to `input_ids`). The dataset also includes an internal `___PAD_TOKEN_IDS___` field used downstream for padding. - ---- -## Parameter Requirements - -The following section lists important requirements and caveats for correct usage. -- `column_mapping` must include `answer`, and must include at least one of `context` or `question` (2- or 3-column mapping only). -- If `use_hf_chat_template=True`, the tokenizer must support chat templates (`chat_template` + `apply_chat_template`). - ---- -## Slurm Configuration for Distributed Training - -For distributed training on Slurm clusters, add a `slurm` section to your YAML configuration. This section configures the Slurm batch job parameters and automatically generates the appropriate `#SBATCH` directives. - -### Slurm Configuration - -SLURM jobs are submitted with `sbatch` directly — no YAML section needed. -Copy the reference script, set the `CONFIG` variable to your YAML, and submit: - -```sh -cp slurm.sub my_cluster.sub -# Edit my_cluster.sub — change CONFIG, #SBATCH directives, container, mounts, etc. -sbatch my_cluster.sub -``` - -All cluster-specific settings (nodes, GPUs, partition, container, mounts, secrets) -live in your sbatch script. See the [cluster guide](/job-launchers/slurm-cluster) for -full examples (Pyxis, bare-metal, Apptainer). - -### Multi-Node Slurm Configuration - - -**Multi-Node Training**: When using Hugging Face datasets in multi-node setups, you need shared storage accessible by all nodes. Set `HF_DATASETS_CACHE` to a shared directory in your sbatch script (e.g., `export HF_DATASETS_CACHE=/shared/hf_cache`) to ensure all nodes can access the cached datasets. - - - -When using multiple nodes with Hugging Face datasets: - -1. **Shared Storage**: Ensure all nodes can access the same storage paths -2. **HF Cache**: Export `HF_HOME` and `HF_DATASETS_CACHE` in your sbatch script pointing to shared directories -3. **Mounts**: Add shared directories as container mounts in your sbatch script - -Configure all of this in your sbatch script (`my_cluster.sub`), not in the YAML. - ---- -### That's It! -With the mapping specified, the rest of the NeMo Automodel pipeline (pre-tokenization, packing, collate-fn, *etc.*) works as usual. diff --git a/docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx b/docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx deleted file mode 100644 index 9ab915af01..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx +++ /dev/null @@ -1,225 +0,0 @@ ---- -title: "Use the ColumnMappedTextInstructionIterableDataset (Streaming)" -description: "" -position: 5 ---- -This guide explains how to use `ColumnMappedTextInstructionIterableDataset` to **stream** instruction datasets for LLM fine-tuning, including **Delta Lake/Databricks** sources. - -Unlike `ColumnMappedTextInstructionDataset` (map-style, non-streaming), this class is a `torch.utils.data.IterableDataset` and **always** loads data in streaming mode. This is intentional: it helps ensure data is consumed as a stream and avoids accidentally materializing full datasets/tables to disk or memory (which is especially important for large or sensitive corpora). - -## When to Use This Dataset - -Use `ColumnMappedTextInstructionIterableDataset` when you need: - -- **Streaming-only behavior** (e.g., to reduce accidental data leakages from full dataset materialization) -- **Delta Lake/Databricks** (Unity Catalog, cloud lakehouse storage, DBFS, etc.) -- **Very large datasets** where map-style loading/caching is undesirable - -If you do *not* need streaming (and you want `len(ds)` / `ds[i]`), use [`ColumnMappedTextInstructionDataset`](/datasets/columnmapped-dataset). - -## Key Differences vs ColumnMappedTextInstructionDataset - -- **Iterable**: you iterate (`for sample in ds:`); you cannot rely on `len(ds)` or `ds[i]`. -- **Always streaming**: there is no `streaming=` flag; it is always enabled. -- **Repeat behavior**: by default, `repeat_on_exhaustion=True` (infinite stream). Set `repeat_on_exhaustion=False` to do a single pass. -- **(Optional) sharding/shuffle helpers**: use `.shard(num_shards, index)` / `.shuffle(buffer_size, seed)` when supported by the underlying backend. - -The column mapping and tokenization logic are shared with `ColumnMappedTextInstructionDataset`. See [Tokenization Paths](/datasets/columnmapped-dataset#tokenization-paths) for details on output fields (`input_ids`, `labels`, `attention_mask`) and masking behavior. - -## Quickstart (Hugging Face Streaming) - -```python -from transformers import AutoTokenizer - -from nemo_automodel.components.datasets.llm.column_mapped_text_instruction_iterable_dataset import ( - ColumnMappedTextInstructionIterableDataset, -) - -tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B") - -ds = ColumnMappedTextInstructionIterableDataset( - path_or_dataset_id="Muennighoff/natural-instructions", - split="train", - column_mapping={ - "context": "definition", - "question": "inputs", - "answer": "targets", - }, - tokenizer=tokenizer, - # Optional: - # limit_dataset_samples=10_000, - # repeat_on_exhaustion=False, # do one pass instead of infinite stream -) - -sample = next(iter(ds)) -print(sample.keys()) # input_ids / labels / attention_mask (and ___PAD_TOKEN_IDS___) -``` - -## Delta Lake/Databricks - -`ColumnMappedTextInstructionIterableDataset` supports Delta Lake tables from: - -- Local Delta tables (directories containing `_delta_log`) -- Cloud storage (S3, Azure Blob/ADLS via `abfss://`, GCS via `gs://`) -- Databricks (DBFS paths and Unity Catalog tables) - -### Installation - -Install the basic Delta Lake reader: - -```bash -pip install deltalake -``` - -For **Unity Catalog access outside of Spark** (optional), install: - -```bash -pip install databricks-sql-connector -``` - -### Local Delta Table - -```python -ds = ColumnMappedTextInstructionIterableDataset( - path_or_dataset_id="/path/to/delta_table", # directory containing _delta_log - column_mapping={"question": "prompt", "answer": "completion"}, - tokenizer=tokenizer, -) -``` - -### Databricks Unity Catalog - -Use the `delta://` prefix so the loader selects the Delta backend: - -```python -ds = ColumnMappedTextInstructionIterableDataset( - path_or_dataset_id="delta://catalog.schema.instruction_data", - column_mapping={ - "context": "system_prompt", - "question": "user_input", - "answer": "assistant_response", - }, - tokenizer=tokenizer, - delta_storage_options={ - "DATABRICKS_TOKEN": "dapi...", # or set DATABRICKS_TOKEN env var - "DATABRICKS_HOST": "https://your-workspace.databricks.com", - # Optional (depending on how you connect): - # "DATABRICKS_HTTP_PATH": "/sql/1.0/warehouses/...", - }, -) -``` - -### Cloud Storage (S3/Azure/GCS) - -```python -# S3 Delta table -ds = ColumnMappedTextInstructionIterableDataset( - path_or_dataset_id="s3://my-bucket/path/to/delta_table", - column_mapping={"question": "input", "answer": "output"}, - tokenizer=tokenizer, - delta_storage_options={ - "AWS_ACCESS_KEY_ID": "...", - "AWS_SECRET_ACCESS_KEY": "...", - "AWS_REGION": "us-east-1", - }, -) - -# Azure (ADLS Gen2/ABFS) -ds = ColumnMappedTextInstructionIterableDataset( - path_or_dataset_id="abfss://container@account.dfs.core.windows.net/delta_table", - column_mapping={"question": "input", "answer": "output"}, - tokenizer=tokenizer, - delta_storage_options={ - "AZURE_STORAGE_ACCOUNT_NAME": "...", - "AZURE_STORAGE_ACCOUNT_KEY": "...", - }, -) -``` - -### YAML Configuration (Delta Lake/Databricks) - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.column_mapped_text_instruction_iterable_dataset.ColumnMappedTextInstructionIterableDataset - path_or_dataset_id: delta://catalog.schema.training_data - column_mapping: - context: system_prompt - question: user_message - answer: assistant_message - answer_only_loss_mask: true - delta_storage_options: - DATABRICKS_TOKEN: ${oc.env:DATABRICKS_TOKEN} - DATABRICKS_HOST: ${oc.env:DATABRICKS_HOST} - # Optional: - # DATABRICKS_HTTP_PATH: ${oc.env:DATABRICKS_HTTP_PATH} -``` - -## Streaming from a Delta SQL Query (Computed/Aliased Columns) - -If you want to generate columns dynamically (joins, filters, computed prompt strings, etc.), pass a SQL query that returns the fields referenced by your `column_mapping`. - -```python -ds = ColumnMappedTextInstructionIterableDataset( - path_or_dataset_id="delta://catalog.schema.training_data", - column_mapping={"question": "question", "answer": "answer"}, - tokenizer=tokenizer, - delta_storage_options={ - "DATABRICKS_HOST": "https://your-workspace.databricks.com", - "DATABRICKS_TOKEN": "dapi...", - "DATABRICKS_HTTP_PATH": "/sql/1.0/warehouses/...", - }, - delta_sql_query=""" - SELECT - concat(system_prompt, '\n', user_message) AS question, - assistant_message AS answer - FROM catalog.schema.training_data - WHERE split = 'train' - """, -) -``` - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.column_mapped_text_instruction_iterable_dataset.ColumnMappedTextInstructionIterableDataset - path_or_dataset_id: delta://catalog.schema.training_data - column_mapping: - question: question - answer: answer - delta_sql_query: | - SELECT - concat(system_prompt, '\n', user_message) AS question, - assistant_message AS answer - FROM catalog.schema.training_data - WHERE split = 'train' - delta_storage_options: - DATABRICKS_HOST: ${oc.env:DATABRICKS_HOST} - DATABRICKS_TOKEN: ${oc.env:DATABRICKS_TOKEN} - DATABRICKS_HTTP_PATH: ${oc.env:DATABRICKS_HTTP_PATH} -``` - - -**SQL engine requirement:** `delta_sql_query` is executed via Spark (Databricks runtime/pyspark) when available, otherwise via `databricks-sql-connector`. It is not supported in a deltalake-only environment. - - - - -**Authentication:** The Delta Lake loader automatically picks up credentials from environment variables (`DATABRICKS_TOKEN`, `AWS_ACCESS_KEY_ID`, `AZURE_STORAGE_ACCOUNT_KEY`, etc.) if not explicitly provided in `delta_storage_options`. - - - -## Common Arguments - -| Arg | Default | Description | -|-------------------------|---------|-------------| -| `split` | `None` | Which split to stream from a HF repo (`train`, `validation`, etc.). Ignored for local files and Delta tables. | -| `name` | `None` | Name of the dataset configuration/subset to load. | -| `answer_only_loss_mask` | `True` | Mask prompt tokens in `labels` with `-100` (CrossEntropy `ignore_index`). | -| `use_hf_chat_template` | `False` | If `True` and the tokenizer supports chat templates, format via `tokenizer.apply_chat_template(...)`. | -| `seq_length` | `None` | Optional max sequence length; used for padding/truncation when enabled. | -| `padding` | `"do_not_pad"` | Padding strategy passed to the tokenizer. | -| `truncation` | `"do_not_truncate"` | Truncation strategy passed to the tokenizer. | -| `limit_dataset_samples` | `None` | Optionally limit the stream to the first \(N\) samples (best-effort; depends on backend). | -| `repeat_on_exhaustion` | `True` | If `True`, restart the stream on exhaustion (useful for step-based training). | -| `delta_storage_options` | `None` | Storage/auth options for Delta Lake backends (Databricks, S3, Azure, GCS). | -| `delta_version` | `None` | Specific Delta table version to read. | -| `delta_sql_query` | `None` | SQL query to generate rows for Delta sources (Spark / Databricks SQL only). | diff --git a/docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-multi.png b/docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-multi.png deleted file mode 100644 index 0dcb08d7ef1e30df062d2080724a29cffc427e29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59318 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 YD2IZlxeyRP-U9z*9x6%}i5tB7KOs@`umAu6 diff --git a/docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-single.png b/docs/fern/versions/nightly/pages/guides/llm/databricks-gpu-metrics-single.png deleted file mode 100644 index 9f297a649e9bc19bd5153994ad1125228564b488..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54011 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 L4iU>2(ewU4tB4NM diff --git a/docs/fern/versions/nightly/pages/guides/llm/databricks.mdx b/docs/fern/versions/nightly/pages/guides/llm/databricks.mdx deleted file mode 100644 index 8485ef4cba..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/databricks.mdx +++ /dev/null @@ -1,290 +0,0 @@ ---- -title: "Model Training on Databricks" -description: "" -position: 19 ---- -Databricks is a widely used platform for managing data, models, applications, and compute on the cloud. This guide shows how to use AutoModel for scalable, performant model training on Databricks. - -The specific example here fine-tunes a [Llama-3.2-1B](https://huggingface.co/meta-llama/Llama-3.2-1B) model using the [SQuAD dataset](https://huggingface.co/datasets/rajpurkar/squad) from Hugging Face, but any AutoModel functionality (for example, [model pre-training](/recipes-e2e-examples/pretraining), [VLMs](/model-coverage/vision-language-models/overview), [other supported models](/model-coverage/overview)) can also be run on Databricks. - -## Provision Compute - -Let's start by [provisioning](https://docs.databricks.com/aws/en/compute/configure) a Databricks classic compute cluster with the following setup: - -- Databricks runtime: [18.0 LTS (Machine Learning version)](https://docs.databricks.com/aws/en/release-notes/runtime/18.0ml) -- Worker instance type: `g6e.12xlarge` on AWS (4x L40S GPUs per node) -- Number of workers: 2 -- Global [environment variable](https://docs.databricks.com/aws/en/compute/configure#environment-variables): `GLOO_SOCKET_IFNAME=eth0` (see [this](https://docs.databricks.com/aws/en/machine-learning/train-model/distributed-training/spark-pytorch-distributor#gloo-failure-runtimeerror-connection-refused) for details) -- Cluster-scoped [init script](https://docs.databricks.com/aws/en/init-scripts/cluster-scoped): - -```bash -#!/bin/bash - -# Install AutoModel on all nodes -/databricks/python3/bin/pip install git+https://github.com/NVIDIA-NeMo/Automodel -``` - -This will provision three compute nodes – one driver node we'll attach a notebook to, and two worker nodes we'll use for multi-node training. - -Note that we've selected a small number of instances for demo purposes, but you can adjust the specific instance type and number of workers for your actual use case. - -## Train the Model - -With the above compute resources provisioned, we're ready to fine-tune a model using AutoModel. - -AutoModel uses YAML file recipes to configure various settings for the training process (for example, model, dataset, loss function, optimizer, etc.). Here we'll use this [preconfigured recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml) for fine-tuning a Llama-3.2-1B model using the SQuAD dataset from Hugging Face. In a notebook connected to our compute resource, download the configuration file: - -```bash -# Download configuration file -!curl -O https://raw.githubusercontent.com/NVIDIA-NeMo/Automodel/refs/heads/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -Here's what the model, dataset, and optimizer portions of the config file look like: - -```yaml -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad - split: train - -optimizer: - _target_: torch.optim.Adam - betas: [0.9, 0.999] - eps: 1e-8 - lr: 1.0e-5 - weight_decay: 0 - -``` - -See the full file for complete details (`!cat llama3_2_1b_squad.yaml`). - -Finally, we'll [authenticate](https://huggingface.co/docs/hub/en/security-tokens) the VM running the notebook with Hugging Face so we can download the model and dataset: - -```python -from getpass import getpass - -hf_token = getpass("HF token: ") -``` -```bash -!hf auth login --token {hf_token} -``` - -### Single-Node - -Since AutoModel is installed via the init script, the `automodel` CLI is available on all nodes. - -To run training on a single GPU, use this command: - -```bash -!automodel llama3_2_1b_squad.yaml \ - --step_scheduler.max_steps 20 \ - --checkpoint.checkpoint_dir /Volumes////checkpoints_single/ \ - --checkpoint.staging_dir /local_disk0/checkpoints_single/ \ - --checkpoint.is_async True -``` - -In addition to specifying the configuration file, we also use these options: - -- `--step_scheduler.max_steps`: Limits the number of training steps taken. Again, this is for example purposes – adapt for your actual use case as needed. -- `--checkpoint.checkpoint_dir`: Tells AutoModel where to [save model checkpoints](/development/checkpointing) from training. We recommend saving model checkpoints in a Databricks Unity Catalog [volume](https://docs.databricks.com/aws/en/volumes/). -- `--checkpoint.staging_dir`: Specifies a temporary staging location for model checkpoints. Files will be temporarily saved to this location before being moved to the final `checkpoint_dir` location. This is needed when saving checkpoints in Unity Catalog. -- `--checkpoint.is_async`: Uses asynchronous checkpointing. - -Looking at GPU metrics in Databricks, we see our single GPU is being well utilized (\~95% utilization). - - - Single GPU utilization of ~95% during model training. - - -To utilize all four GPUs available on this `g6e.12xlarge` instance, add `--nproc-per-node=4` to the same command: - -```bash -!automodel --nproc-per-node=4 llama3_2_1b_squad.yaml \ - --step_scheduler.max_steps 20 \ - --checkpoint.checkpoint_dir /Volumes////checkpoints_multi/ \ - --checkpoint.staging_dir /local_disk0/checkpoints_multi/ \ - --checkpoint.is_async True -``` - -The `automodel` CLI uses PyTorch's [Elastic Launch](https://docs.pytorch.org/docs/stable/elastic/run.html) internally to spawn and coordinate multiple training processes on the VM. Each training process runs on a separate GPU, and we can now see all four GPUs are being used (~95% utilization for each GPU). - - - Multi-GPU, single-node utilization of ~95% during model training. - - -### Multi-Node - -To scale further to multi-node training, we need to submit training jobs to all instances in our Databricks cluster. - -First, each instance needs to be authenticated with Hugging Face to download the model and dataset: - -```python -# Ensure workers are authenticated with Hugging Face - -import subprocess -import shlex - -def run_command(cmd): - p = subprocess.run(shlex.split(cmd), capture_output=True) - return p.stdout.decode() - -rdd = sc.parallelize(range(sc.defaultParallelism)) -rdd.mapPartitions(lambda _: [run_command("hf auth login --token " + hf_token)]).collect(); -``` - -Next, we use PySpark's [TorchDistributor](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.torch.distributor.TorchDistributor.html) to run the same training job across multiple instances like this: - -```py -from pyspark.ml.torch.distributor import TorchDistributor -import nemo_automodel.recipes.llm.train_ft as recipe_mod - -num_executor = 2 # Number of workers in cluster -num_gpus_per_executor = 4 # Number of GPUs per worker -distributor = TorchDistributor( - num_processes=num_executor * num_gpus_per_executor, - local_mode=False, - use_gpu=True, -) - -train_file = recipe_mod.__file__ -args = [ - "--config", "llama3_2_1b_squad.yaml", - "--step_scheduler.max_steps", "20", - "--checkpoint.checkpoint_dir", "/Volumes////checkpoints_dist/", - "--checkpoint.staging_dir", "/local_disk0/checkpoints_dist/", - "--checkpoint.is_async", "True", -] -distributor.run(train_file, *args) -``` - -`TorchDistributor` uses `torchrun` internally, so we point it at the recipe module directly (rather than the `automodel` CLI, which also wraps `torchrun`). - -We now see GPU utilization is \~95% for all GPUs on all worker nodes during training (8 GPUs in this particular case). - -## Track Experiments with MLflow - -Databricks includes built-in MLflow integration for tracking experiments, logging metrics, and storing artifacts. To use MLflow with AutoModel on Databricks, add the MLflow configuration to your YAML file. - -### Configure MLflow - -Edit your configuration file (e.g., `llama3_2_1b_squad.yaml`) to include the `mlflow` section: - -```yaml -mlflow: - experiment_name: "automodel-databricks-llama3-squad" - run_name: "" - tracking_uri: "databricks" - artifact_location: null - tags: - platform: "databricks" - task: "squad-finetune" - model_family: "llama3.2" -``` - -For Databricks, the key configuration parameters are: - -- `tracking_uri`: Set to `"databricks"` to use Databricks' managed MLflow tracking server -- `experiment_name`: Name of your experiment (will appear in the Databricks workspace) -- `artifact_location`: Leave as `null` to use default Databricks artifact storage, or specify a Unity Catalog volume path like `/Volumes////mlflow-artifacts` -- `tags`: Add custom tags to organize and filter your runs - - -Databricks automatically handles authentication when `tracking_uri` is set to `"databricks"`. No additional credentials are needed. - - - -### Run Training with MLflow - -Run training with MLflow tracking enabled using the same commands as before. The MLflow configuration will be read from your YAML file: - -**Single-node:** -```bash -!automodel llama3_2_1b_squad.yaml \ - --step_scheduler.max_steps 20 \ - --checkpoint.checkpoint_dir /Volumes////checkpoints/ -``` - -**Multi-GPU:** -```bash -!automodel --nproc-per-node=4 llama3_2_1b_squad.yaml \ - --step_scheduler.max_steps 20 \ - --checkpoint.checkpoint_dir /Volumes////checkpoints/ -``` - -**Multi-node with TorchDistributor:** -```python -import nemo_automodel.recipes.llm.train_ft as recipe_mod - -distributor = TorchDistributor( - num_processes=num_executor * num_gpus_per_executor, - local_mode=False, - use_gpu=True, -) - -args = [ - "--config", "llama3_2_1b_squad.yaml", - "--step_scheduler.max_steps", "20", - "--checkpoint.checkpoint_dir", "/Volumes////checkpoints/", -] -distributor.run(recipe_mod.__file__, *args) -``` - -### View Results - -During training, you'll see MLflow logging messages in your output: - -``` -MLflow run started: abc123def456 -View run at: databricks/#/mlflow/experiments/123/runs/abc123def456 -``` - -To view your experiments and metrics: - -1. Navigate to the **Experiments** page in your Databricks workspace -2. Find your experiment by name (e.g., `automodel-databricks-llama3-squad`) -3. Click on a run to view metrics, parameters, and artifacts - -The Databricks MLflow UI displays: -- Training and validation metrics over time -- Model parameters and hyperparameters -- Custom tags for filtering and comparison -- Artifacts and model checkpoints -- System metrics (GPU utilization, memory usage) - -### Store Artifacts in Unity Catalog - -To store MLflow artifacts in Unity Catalog volumes, specify the `artifact_location`: - -```yaml -mlflow: - experiment_name: "automodel-databricks-llama3-squad" - tracking_uri: "databricks" - artifact_location: "/Volumes////mlflow-artifacts" - tags: - platform: "databricks" -``` - -This ensures your artifacts are stored in a governed, versioned location within Unity Catalog. - -### Additional Configuration - -You can override MLflow settings from the command line: - -```bash -!automodel llama3_2_1b_squad.yaml \ - --mlflow.experiment_name "custom-experiment-name" \ - --mlflow.run_name "baseline-run-1" \ - --mlflow.tags.learning_rate "1e-5" -``` - -For more details on MLflow configuration options and best practices, see the [MLflow logging guide](/development/mlflow-logging). - -## Conclusion - -This guide showed how to use AutoModel for model training on Databricks-managed compute. It's relatively straightforward to scale from a single-GPU to multi-GPU to multi-node training to best suit your needs. - -While the example here fine-tunes a Llama-3.2-1B model using the SQuAD dataset, any supported AutoModel functionality (like model pre-training, VLMs, etc.) can also run, and scale, on Databricks. Check out [additional recipes and end-to-end examples](/recipes-e2e-examples/overview) to learn more. diff --git a/docs/fern/versions/nightly/pages/guides/llm/dataset.mdx b/docs/fern/versions/nightly/pages/guides/llm/dataset.mdx deleted file mode 100644 index 4c657c4112..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/dataset.mdx +++ /dev/null @@ -1,184 +0,0 @@ ---- -title: "Integrate Your Own Text Dataset" -description: "" -position: 2 ---- -This guide shows you how to integrate your own dataset into NeMo Automodel for training. You'll learn about two main dataset types: **completion datasets** for language modeling (like [HellaSwag](https://huggingface.co/datasets/rowan/hellaswag)) and **instruction datasets** for question-answering tasks (like [SQuAD](https://huggingface.co/datasets/rajpurkar/squad)). We'll cover how to create custom datasets by implementing the required methods and preprocessing functions, and finally show you how to specify your own data logic using YAML configuration with file paths—allowing you to define custom dataset processing without modifying the main codebase. - -## Quick Start Summary -| **Type** | **Use Case** | **Example** | **Preprocessor** | **Section** | -| --------------- | ------------------ | -------------- | --------------------------------- | --------------------------- | -| ✍️ Completion | Language modeling | HellaSwag | `SFTSingleTurnPreprocessor` | [Jump](#completion-datasets) | -| 🗣️ Instruction | Question answering | SQuAD | `make_*` function | [Jump](#instruction-datasets) | - -## Types of Supported Datasets - -NeMo Automodel supports a variety of datasets, depending on the task. -### Completion Datasets - -**Completion datasets** are single text sequences designed for language modeling where the model learns to predict the next token given a context. These datasets typically contain a context (prompt) and a target (completion) that the model should learn to generate. - -#### Example: HellaSwag - -The [HellaSwag](https://huggingface.co/datasets/rowan/hellaswag) dataset is a popular completion dataset used for commonsense reasoning. It contains situations with multiple-choice endings where the model must choose the most plausible continuation. - -**HellaSwag dataset structure:** -- **Context (`ctx`)**: A situation or scenario description -- **Endings**: Multiple possible completions (4 options) -- **Label**: Index of the correct ending - -**Example:** -``` -Context: "A man is sitting at a piano in a large room." -Endings: [ - "He starts playing a beautiful melody.", - "He eats a sandwich while sitting there.", - "He suddenly becomes invisible.", - "He transforms into a robot." -] -Label: 0 # First ending is correct -``` - -#### Preprocessing with SFTSingleTurnPreprocessor - -NeMo Automodel provides the `SFTSingleTurnPreprocessor` class to handle completion datasets. This processor: - -1. **Extracts context and target** using `get_context()` and `get_target()`. -2. **Tokenizes and cleans** context and target separately. -3. **Concatenates** them into one sequence. -4. **Creates loss mask**: `-100` for context, target IDs for target. -5. **Pads** sequences to equal length. - -#### Create Your Own Completion Dataset - -To adapt your dataset into this format, define a class like this: - -```python -from datasets import load_dataset -from nemo_automodel.components.datasets.utils import SFTSingleTurnPreprocessor - -class MyCompletionDataset: - def __init__(self, path_or_dataset, tokenizer, split="train"): - raw_datasets = load_dataset(path_or_dataset, split=split) - processor = SFTSingleTurnPreprocessor(tokenizer) - self.dataset = processor.process(raw_datasets, self) - - def get_context(self, examples): - """Extract context/prompt from your dataset""" - return examples["context_field"] # Replace with your context field - - def get_target(self, examples): - """Extract target/completion from your dataset""" - return examples["target_field"] # Replace with your target field - - def __getitem__(self, index): - return self.dataset[index] - - def __len__(self): - return len(self.dataset) -``` - -### Instruction Datasets - -**Instruction datasets** are question-answer pairs where the model learns to respond to specific instructions or questions. These datasets are structured as context-question pairs with corresponding answers, making them ideal for teaching models to follow instructions and provide accurate responses. - -#### Example: SQuAD - -The [SQuAD (Stanford Question Answering Dataset)](https://huggingface.co/datasets/rajpurkar/squad) is a popular instruction dataset for reading comprehension. It contains questions based on Wikipedia articles along with their answers. - -**SQuAD dataset structure:** -- **Context**: A paragraph of text from Wikipedia -- **Question**: A question about the context -- **Answers**: The correct answer with its position in the context - -#### Create Your Own Instruction Dataset - -The [`squad.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/llm/squad.py) file contains the implementation for processing the SQuAD dataset into a format suitable for instruction tuning. It defines a dataset class and preprocessing functions that extract the context, question, and answer fields, concatenate them into a prompt-completion format, and apply tokenization, padding, and loss masking. This serves as a template for building custom instruction datasets by following a similar structure and adapting the extraction logic to your dataset's schema. - -Based on the SQuAD implementation in `squad.py`, you can create your own instruction dataset using the `make_squad_dataset` pattern: - -```python -from datasets import load_dataset - -def make_my_instruction_dataset( - tokenizer, - seq_length=None, - limit_dataset_samples=None, - split="train", - dataset_name="your-dataset-name", -): - if limit_dataset_samples: - split = f"{split}[:{limit_dataset_samples}]" - - dataset = load_dataset(dataset_name, split=split) - - return dataset.map( - your_own_fmt_fn, # Your formatting function - batched=False, - remove_columns=dataset.column_names, - ) -``` - -## YAML-based Custom Dataset Configuration - -NeMo Automodel supports YAML-based dataset specification using the _target_ key. This lets you reference dataset-building classes or functions using either: - -- 1. Python Dotted Path - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.hellaswag.HellaSwag - path_or_dataset: rowan/hellaswag - split: train -``` - -- 2. File Path + Function Name - -``` -: -``` - -Where: -- ``: The absolute path to a Python file containing your dataset function -- ``: The name of the function to call from that file - -```yaml -dataset: - _target_: /path/to/your/custom_dataset.py:build_my_dataset - num_blocks: 111 -``` -This will call `build_my_dataset()` from the specified file with the other keys (e.g., num_blocks) as arguments. This approach allows you to integrate custom datasets via config alone—no need to alter the codebase or package structure. - -## Packed Sequence Support in NeMo AutoModel -NeMo AutoModel supports **packed sequences**, a technique to optimize training with variable-length sequences (e.g., text) by minimizing padding. - -### What is a Packed Sequence? -Instead of padding each sequence to a fixed length (wasting computation on `[PAD]` tokens), packed sequences: -- Concatenate short sequences into a single continuous sequence. -- Separate sequences with special tokens (e.g., `[EOS]`). -- Track lengths via a "attention mask" to prevent cross-sequence information leakage. - -### Benefits -- Reduces redundant computation on padding tokens leading to faster training. -- Enables larger effective batch sizes leading to better GPU utilization. -- Especially useful for language modeling and text datasets. - -### Enable Packed Sequences in NeMo Automodel - -To enable packed sequences, add these keys to your recipe's YAML config: -``` -packed_sequence: - # Set packed_sequence_size > 0 to run with packed sequences - packed_sequence_size: 1024 - split_across_pack: False -``` - -The `packed_sequence` has two options: -- **packed_sequence_size**: Defines the total token length of each packed sequence, higher values require higher GPU memory usage. -- **split_across_pack**: If two will split a sequence across different packed sequences. - -## Troubleshooting Tips - -- **Tokenization Mismatch?** Ensure your tokenizer aligns with the model's expected inputs. -- **Dataset too large?** Use `limit_dataset_samples` in your YAML config to load a subset, useful for quick debugging. -- **Loss not decreasing?** Verify that your loss mask correctly ignores prompt tokens. diff --git a/docs/fern/versions/nightly/pages/guides/llm/dsv4-flash.mdx b/docs/fern/versions/nightly/pages/guides/llm/dsv4-flash.mdx deleted file mode 100644 index ff44e4b9dc..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/dsv4-flash.mdx +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: "DeepSeek V4 Flash" -description: "" -position: 6 ---- -## Introduction - -[deepseek-ai/DeepSeek-V4-Flash](https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash) is the latest fine-grained Mixture-of-Experts language model from DeepSeek. It uses a 43-layer all-MoE backbone (no dense MLP layers) with 256 routed experts plus one shared expert per block and top-6 routing. The architecture introduces a hybrid per-layer attention zoo — Sliding-Window Attention (SWA), Compressed Sparse Attention (CSA, Compressor + Indexer), and Hierarchical Compressed Attention (HCA, Compressor only) — selectable per layer through `compress_ratios`. The first `num_hash_layers` blocks use a hash-clustering gate (`DeepseekV4HashGate`) for token-to-expert routing, and every block maintains `hc_mult=4` Hyper-Connection streams mixed via a learned col-norm-first Sinkhorn router. - -This guide walks you through fine-tuning DeepSeek V4 Flash on HellaSwag using NVIDIA NeMo Automodel. You will learn how to configure the recipe, launch training, and inspect the results. - -To set up your environment to run NeMo Automodel, follow the [installation guide](https://github.com/NVIDIA-NeMo/Automodel#-install-nemo-automodel). - -## Data - -### HellaSwag - -We use [HellaSwag](https://huggingface.co/datasets/Rowan/hellaswag), a commonsense natural-language-inference dataset consisting of context + four candidate continuations. The version used here is the standard `rowan/hellaswag` HuggingFace split, formatted for next-token-prediction fine-tuning. - -- **Train / validation splits** taken directly from the HuggingFace dataset. -- **Tokenizer**: shared with the base model (`AutoTokenizer.from_pretrained` on the DeepSeek V4 Flash checkpoint). -- **Padding**: `pad_seq_len_divisible=64` via the default collater. - -For the full HellaSwag dataset wrapper used in NeMo Automodel, see [`nemo_automodel.components.datasets.llm.hellaswag.HellaSwag`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/llm/hellaswag.py). - -## Architecture Notes - -DeepSeek V4 Flash differs from V3 / V3.2 in several load-bearing ways. The state-dict adapter and pipeline-parallel forward in NeMo Automodel handle each of these transparently: - -- **Attention**: GQA with a single KV head broadcast to all 64 attention heads, Q-LoRA (`q_lora_rank=1024`), and grouped O-LoRA (`o_lora_rank=1024`, `o_groups=8`) — not MLA. Per-head non-learnable rsqrt on Q after `wq_b` matches the inference reference. -- **Hybrid attention via `compress_ratios`**: - - `compress_ratio=0` → pure SWA with a learned per-head attention sink. - - `compress_ratio=4` → CSA: Compressor (overlap mode, pools `2 * ratio` raw tokens per compressed token) plus Indexer (selects top-k compressed positions per query). An explicit additive `[B, 1, S, P_total]` mask enforces per-query causal correctness. - - `compress_ratio=128` → HCA: Compressor only (non-overlap pooling), deterministic `p < (q + 1) // ratio` causal mask. -- **Dual RoPE bases**: `theta=10000` for `compress_ratio==0` layers; `theta=160000` (with YaRN scaling) for `compress_ratio>0` layers, applied to both the main attention Q/KV and the Compressor sub-module on those layers. RoPE is encoded as INTERLEAVED pairs (`view_as_complex` style) to match the released checkpoint. -- **Hash-routing first layers**: the first `num_hash_layers` (default 3) blocks use a `DeepseekV4HashGate` with a `tid2eid` lookup table. `input_ids` is threaded through the model and the V4-aware pipeline forward; under pipeline parallelism, hash layers live on stage 0 where `input_ids` is available. -- **Hyper-Connections (HC)**: every block maintains `hc_mult=4` streams of the hidden state. The mixer follows the released `hc_split_sinkhorn` formulas: `pre = sigmoid + eps`, `post = 2 * sigmoid` (no `+eps`), `comb = softmax(dim=-1) + eps` followed by a col-norm-first Sinkhorn (`iters - 1` alternating row/col passes), producing a doubly-stochastic mixing matrix per block. -- **MoE routing**: `sqrtsoftplus` scoring with `noaux_tc` topk method and clamped SwiGLU on routed experts (`swiglu_limit=10.0`). -- **Optional MTP layers** via `num_nextn_predict_layers`. - -### Checkpoint format - -The released DSV4-Flash safetensors mix several quantization formats. The state-dict adapter handles all of them transparently: - -- **Routed experts**: FP4 `e2m1fn` packed two values per int8 byte, with per-row 32-col FP8 `e8m0fnu` scales — unpacked on load, re-emitted in matching packed placeholders on `to_hf` so DCP shape/dtype validation lines up with the on-disk layout. -- **Shared experts + non-expert weights**: standard FP8 `e4m3fn` 128×128 block scales. -- **Hash layers' gate has no bias on disk**: the adapter reads `num_hash_layers` from the checkpoint's `config.json` and drops the corresponding bias keys before DCP load. -- **Indexer / Compressor key flattening**: on disk the Indexer sits as a sibling of the Compressor with its own nested compressor (`indexer.compressor.{ape,norm,wgate,wkv}` + `indexer.{wq_b,weights_proj}`); the adapter renames these to land at the flat `compressor.indexer.*` layout. - -A new in-tree `HuggingFaceStorageReader` recognizes `F8_E8M0` and `F8_E5M2` dtypes (the upstream reader silently dropped them), restoring DCP metadata on every rank for these checkpoints. - -## Launch Training - -A ready-to-use recipe ships at [`examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml). The yaml header documents how to scale `num_hidden_layers` and `ep_size` for the full 43-layer multi-node run. - -NeMo Automodel supports several ways to launch training — via the Automodel CLI with Slurm, interactive sessions, `torchrun`, and more. For full details on all launch options (Slurm batch jobs, multi-node configuration, environment variables, etc.), see the [Run on a Cluster](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/launcher/slurm.md) guide. - -### Standalone Slurm Script - -Below is a standalone Slurm script example for the HellaSwag recipe. Before running it, ensure your cluster environment is configured following the [Run on a Cluster](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/launcher/slurm.md) guide. Then submit the job: - -```bash -export TRANSFORMERS_OFFLINE=1 -export HF_HOME=your/path/to/hf_cache -export HF_DATASETS_OFFLINE=1 -export WANDB_API_KEY=your_wandb_key - -srun --output=output.out \ - --error=output.err \ - --container-image /your/path/to/automodel.image.sqsh --no-container-mount-home bash -c " - CUDA_DEVICE_MAX_CONNECTIONS=1 automodel \ - examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml \ - --nproc-per-node=8 \ - --model.config.pretrained_model_name_or_path=/your/local/dsv4-flash \ - --model.config.name_or_path=/your/local/dsv4-flash " -``` - -**Before you start**: -- Hugging Face applies rate limits on downloads. We recommend cloning the model repository to your local filesystem beforehand. -- Ensure your Hugging Face cache (`HF_HOME`) is configured and that the dataset is already cached locally. -- To enable Weights & Biases logging, set your `WANDB_API_KEY` and configure the `wandb` section in the YAML file. -- For the full 43-layer schedule, increase `ep_size` (and add `pp_size`) per the cluster you are running on; see the yaml header for guidance. - -## Layer-Parity Validation - -The bringup was validated against the official DeepSeek inference reference (`dsv4flash/inference/model.py`) by per-tensor dump bisection. On the 4-layer parity harness (`compress_ratios=[0, 0, 4, 128]`, `num_hash_layers=2`, PP=1, EP=8): - -- **Final-logits cosine similarity: 0.998 vs reference, top-1 token matches.** -- Every block cosine similarity ≥ 0.987. - -## Training Results - -The training loss curve below is from a 43-layer full-finetune run on HellaSwag with the full attention zoo (SWA + CSA + HCA) live. - -

- DeepSeek V4 Flash Training Loss Curve -

diff --git a/docs/fern/versions/nightly/pages/guides/llm/finetune.mdx b/docs/fern/versions/nightly/pages/guides/llm/finetune.mdx deleted file mode 100644 index d777758ca8..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/finetune.mdx +++ /dev/null @@ -1,942 +0,0 @@ ---- -title: "Supervised Fine-Tuning (SFT) and Parameter-Efficient Fine-Tuning (PEFT) with NeMo AutoModel" -description: "" -position: 2 ---- -## Introduction - -Pretrained language models are general-purpose: they know a lot about language but nothing about your particular domain, terminology, or task. Fine-tuning bridges that gap — you fine-tune the model on your own examples so it produces answers that are accurate and relevant for your use case, without the cost of training a model from scratch. The result is a model optimized for your data that you can evaluate, publish, and deploy. This guide walks you through that process end-to-end with NeMo AutoModel — from installation through training, evaluation, and deployment — using [Meta LLaMA 3.2 1B](https://huggingface.co/meta-llama/Llama-3.2-1B) and the [SQuAD v1.1](https://huggingface.co/datasets/rajpurkar/squad) dataset as a running example. - -NeMo AutoModel supports two fine-tuning modes: - -- **Supervised Fine-Tuning (SFT)** updates all model parameters. Use SFT when you need maximum accuracy and have sufficient compute. -- **Parameter-Efficient Fine-Tuning (PEFT)** using [LoRA](https://arxiv.org/abs/2106.09685) freezes the base model and trains small low-rank adapters. PEFT reduces trainable parameters to less than 1% of the original model, lowering memory and storage costs. - -### Workflow Overview - -```text -┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ -│ 1. Install │--->│ 2. Configure │--->│ 3. Train │--->│ 4. Inference │--->│ 5. Evaluate │--->│ 6. Publish │--->│ 7. Deploy │ -│ │ │ │ │ │ │ │ │ │ │ (optional) │ │ (optional) │ -│ pip install │ │ YAML config │ │ automodel CLI│ │ HF generate │ │ Val loss + │ │ HF Hub │ │ vLLM serving │ -│ or Docker │ │ Choose SFT │ │ or torchrun │ │ API │ │ lm-eval- │ │ upload │ │ │ -│ │ │ or PEFT │ │ │ │ │ │ harness │ │ │ │ │ -└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ -``` - -| Step | Section | SFT | PEFT | -|------|---------|-----|------| -| **1. Install** | [Install NeMo AutoModel](#install-nemo-automodel) | Same | Same | -| **2. Configure** | [Configure Your Training Recipe](#configure-your-training-recipe) | YAML without `peft:` section | YAML with `peft:` section | -| **3. Train** | [Fine-Tune the Model](#fine-tune-the-model) | Same command for both modes | Same command for both modes | -| **4. Inference** | [Run Inference](#run-inference) | Load consolidated checkpoint directly | Load base model + adapter | -| **5. Evaluate** | [Evaluate the Fine-Tuned Model](#evaluate-the-fine-tuned-model) | Validation loss during training; lm-eval-harness post-training | Same | -| **6. Publish** | [Publish to HF Hub](#publish-to-the-hugging-face-hub) | Upload `model/consolidated/` | Upload `model/` (adapter only) | -| **7. Deploy** | [Deploy with vLLM](#deploy-with-vllm) | `vllm.LLM(model=...)` | `vLLMHFExporter` with `--lora-model` | - -## Install NeMo AutoModel - -```bash -pip3 install nemo-automodel -``` - -Alternatively, if you run into dependency or driver issues, use the pre-built Docker container: - -```bash -docker pull nvcr.io/nvidia/nemo-automodel:26.02.00 -docker run --gpus all -it --rm --shm-size=8g -v $(pwd)/checkpoints:/tmp/checkpoints/ nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - - -Docker containers are ephemeral — files written inside the container are lost when it stops. The `-v` flag in the `docker run` command above bind-mounts a local `checkpoints/` directory into the container so that saved checkpoints persist across runs. For more details, see [Saving Checkpoints When Using Docker](/development/checkpointing#saving-checkpoints-when-using-docker). - - - -For the full set of installation methods, see the [installation guide](/get-started/installation). - -## Configure Your Training Recipe - -Training is configured through a [YAML](https://en.wikipedia.org/wiki/YAML) config file with three required sections — **model**, **dataset**, and **step_scheduler** — plus an optional **peft** section. The sections below walk through each one. For the complete copy-pastable file, see [Full Config YAML](#full-config-yaml). - -Under the hood, both SFT and PEFT are executed by a **recipe**: a self-contained Python class that wires together model loading, dataset preparation, training, checkpointing, and logging. The fine-tuning recipe is [`TrainFinetuneRecipeForNextTokenPrediction`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/recipes/llm/train_ft.py). The config file tells the recipe *what* to build; the recipe decides *how* to build it. - - -NeMo AutoModel configs use a convention borrowed from [Hydra](https://hydra.cc/): the special **`_target_`** key tells the framework *which* Python class or function to call, and **every other key** in the same YAML block is passed as a keyword argument to that call. For example: - -```yaml -optimizer: - _target_: torch.optim.Adam - lr: 1.0e-5 - weight_decay: 0 -``` - -is equivalent to writing this Python code: - -```python -from torch.optim import Adam - -optimizer = Adam(lr=1.0e-5, weight_decay=0) -``` - -The `_target_` value is a **dotted Python import path**: the same string you would use in an `import` statement. The framework resolves it at runtime by importing the module and looking up the attribute. This means you can point `_target_` at any class constructor or factory function, and the remaining keys become its arguments. - - -To discover which parameters a section accepts, look up the Python signature of its `_target_`. For instance, `torch.optim.Adam` accepts `lr`, `betas`, `eps`, and `weight_decay` — those are the keys you can set in the YAML. - - - -**From YAML to running code.** Here is the path a config takes through the framework: - -```text -finetune_config.yaml - │ - ▼ - ┌──────────────┐ load_yaml_config() parses the file into - │ ConfigNode │◄─── a tree of ConfigNode objects, one per - └──────┬───────┘ YAML section. - │ - ▼ - ┌──────────────┐ The recipe's setup() method reads - │ Recipe │◄─── each section from the ConfigNode tree - │ setup() │ and passes it to the matching builder. - └──────┬───────┘ - │ - ┌────┴─────────────────────────────────┐ - ▼ ▼ ▼ ▼ -build_model build_optimizer build_dataloader build_loss_fn ... - │ │ │ │ - ▼ ▼ ▼ ▼ -cfg.model cfg.optimizer cfg.dataset cfg.loss_fn - .instantiate() .instantiate() .instantiate() .instantiate() - │ │ │ │ - ▼ ▼ ▼ ▼ - Resolves Resolves Resolves Resolves - _target_, _target_, _target_, _target_, - calls it calls it calls it calls it - with kwargs with kwargs with kwargs with kwargs -``` - -Each builder function calls **`.instantiate()`** on its config section. `.instantiate()` does two things: - -1. **Resolves `_target_`** — imports the Python path and obtains the callable (class or function). -2. **Calls it** — passes every other key in the section as a keyword argument. - -Nested `_target_` blocks (like `collate_fn` inside `dataloader`) are recursively instantiated the same way. - -**The `recipe` key.** Every config file includes a top-level `recipe` key that tells the CLI *which recipe class* to run. You can write it as a **short name** or as a **fully-qualified Python path** — both resolve to the same class: - -```yaml -# Short name (the CLI looks up the class automatically) -recipe: TrainFinetuneRecipeForNextTokenPrediction - -# Fully-qualified path (used as-is) -recipe: nemo_automodel.recipes.llm.train_ft.TrainFinetuneRecipeForNextTokenPrediction -``` - -The short name form is a convenience — the CLI scans all recipe modules under `nemo_automodel.recipes` and matches the bare class name. If you invoke the recipe script directly with `torchrun` instead of the `automodel` CLI, the `recipe` key is not required because the script itself *is* the recipe. - -**Not every section uses `_target_`.** Some sections like `step_scheduler`, `distributed`, and `checkpoint` are plain key-value groups consumed directly by the recipe — they control training schedule, parallelism strategy, and checkpoint behavior without instantiating a Python object. - - -### Model - -```yaml -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B -``` - -| Key | Role | -|-----|------| -| `_target_` | Points to [`NeMoAutoModelForCausalLM.from_pretrained`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/_transformers/auto_model.py) — a factory method that downloads (or loads from cache) a pretrained Hugging Face model and wraps it with NeMo distributed-training support. | -| `pretrained_model_name_or_path` | A keyword argument to `from_pretrained`. Any argument that [`from_pretrained`](https://huggingface.co/docs/transformers/main_classes/model#transformers.PreTrainedModel.from_pretrained) accepts can be added here (e.g. `cache_dir`, `torch_dtype`). | - -This guide uses **Meta Llama 3.2 1B** as a running example. Replace `pretrained_model_name_or_path` with any supported [Hugging Face model ID](/model-coverage/large-language-models/overview). - - -Llama is a family of decoder-only transformer models developed by Meta. The 1B variant is a compact model suitable for research and edge deployment, featuring RoPE positional embeddings, grouped-query attention (GQA), and SwiGLU activations. - - - -Some Hugging Face models are **gated**. If the model page shows a "Request access" button: - -1. Log in with your Hugging Face account and accept the license. -2. Ensure the token you use (from `huggingface-cli login` or `HF_TOKEN`) belongs to the approved account. - -Pulling a gated model without an authorized token triggers a 403 error. - - -### Dataset - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad # HF-Hub ID used to pull the dataset - split: train - -validation_dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad - split: validation -``` - -| Key | Role | -|-----|------| -| `_target_` | Points to [`make_squad_dataset`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/llm/squad.py) — a factory function that downloads the SQuAD dataset, tokenizes it, and returns a `torch.utils.data.Dataset`. To use a different dataset, change `_target_` to a different factory function (see [Integrate Your Own Text Dataset](/datasets/text-dataset)). | -| `dataset_name`, `split` | Keyword arguments passed to `make_squad_dataset`. Each dataset factory defines its own parameters — check the function signature to see what's available. | - -This guide uses **SQuAD v1.1** as a running example. Swap the dataset by changing `_target_` and the dataset arguments — see [Integrate Your Own Text Dataset](/datasets/text-dataset) and [Dataset Overview: LLM, VLM, and Retrieval Datasets](/datasets/overview). - - -The Stanford Question Answering Dataset (SQuAD) is a reading comprehension dataset where each example consists of a Wikipedia passage, a question, and a span answer. SQuAD v1.1 guarantees all questions are answerable from the context, making it suitable for straightforward fine-tuning. - -Example: -```json -{ - "context": "Architecturally, the school has a Catholic character. ...", - "question": "To whom did the Virgin Mary allegedly appear in 1858 in Lourdes France?", - "answers": { "text": ["Saint Bernadette Soubirous"], "answer_start": [515] } -} -``` - - -### PEFT (Optional) - -```yaml -peft: - _target_: nemo_automodel.components._peft.lora.PeftConfig - target_modules: "*.proj" # glob pattern matching linear layer FQNs - dim: 8 # low-rank dimension of the adapters - alpha: 32 # scaling factor for learned weights -``` - -| Key | Role | -|-----|------| -| `_target_` | Points to [`PeftConfig`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/_peft/lora.py) — a dataclass that describes which layers to adapt and how. Unlike the model and dataset sections, this instantiation produces a *config object*, not the adapter itself. The recipe passes the resulting `PeftConfig` into `build_model`, which applies LoRA adapters to the model. | -| `target_modules` | A glob pattern matched against fully-qualified layer names (e.g. `"*.proj"` matches every layer whose name ends in `proj`). | -| `dim` | The low-rank dimension *r* — controls adapter capacity. Larger values learn more but use more memory. | -| `alpha` | Scaling factor applied to the adapter output (`alpha / dim`). Higher values give adapters more influence during training. | - -Including a `peft:` section enables LoRA fine-tuning. Remove it entirely to run SFT instead — see [Switching Between SFT and PEFT](#switching-between-sft-and-peft). - -#### QLoRA (Quantized Low-Rank Adaptation) - -If GPU memory is a constraint, [QLoRA](https://arxiv.org/abs/2305.14314) combines LoRA with 4-bit NormalFloat (NF4) quantization to reduce memory usage by up to 75% compared to full-parameter SFT in 16-bit precision, while maintaining comparable quality to standard LoRA. - -To enable QLoRA, add a `quantization:` section alongside the `peft:` section in your config. Note two differences from the standard PEFT config above: `target_modules` uses the broader `"*_proj"` pattern to apply LoRA to all projection layers (wider coverage compensates for precision loss from 4-bit weights), and `dim` is increased from 8 to 16 for additional adapter capacity. - -```yaml -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - -peft: - _target_: nemo_automodel.components._peft.lora.PeftConfig - target_modules: "*_proj" # broader glob than "*.proj" to cover all projection layers - dim: 16 # LoRA rank (higher than default to offset quantization) - alpha: 32 # scaling factor - dropout: 0.1 # LoRA dropout rate - -quantization: - load_in_4bit: True # enable 4-bit quantization - load_in_8bit: False # use 4-bit, not 8-bit - bnb_4bit_compute_dtype: bfloat16 # compute dtype - bnb_4bit_use_double_quant: True # double quantization for extra savings - bnb_4bit_quant_type: nf4 # NormalFloat quantization type - bnb_4bit_quant_storage: bfloat16 # storage dtype for quantized weights -``` - -### Training Schedule - -```yaml -step_scheduler: - num_epochs: 1 # Will train over the dataset once. -``` - -Unlike the sections above, `step_scheduler` has **no `_target_`** — it is not instantiated into a Python object. Instead, the recipe reads its keys directly to control the training loop (how many epochs to run, when to checkpoint, when to validate). This is typical of sections that configure *behavior* rather than *components*. - -All other settings (distributed strategy, optimizer, checkpointing, logging) use sensible defaults. See the [Full Configuration Reference](#full-configuration-reference) to customize them. - -### Full Config YAML - - -Save as `finetune_config.yaml`. This config runs PEFT (LoRA). To run SFT instead, remove the `peft:` section. For production-ready examples, see the hosted configs: [Llama 3.2 1B SFT](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml) and [Llama 3.2 1B PEFT](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_peft.yaml). - -```yaml -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - -peft: - _target_: nemo_automodel.components._peft.lora.PeftConfig - target_modules: "*.proj" - dim: 8 - alpha: 32 - -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad - split: train - -validation_dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad - split: validation - -step_scheduler: - num_epochs: 1 -``` - - -## Fine-Tune the Model - -You can run the recipe using the AutoModel CLI or directly with `torchrun` (advanced). - -```bash -automodel --nproc-per-node=8 finetune_config.yaml -``` - -The `--nproc-per-node=8` flag specifies the number of GPUs per node. Adjust to your case (for a single GPU, omit the `--nproc-per-node` option). - -### Invoke the Recipe Script Directly (advanced) - -Alternatively, you can invoke the recipe [script](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/recipes/llm/train_ft.py) directly using [torchrun](https://docs.pytorch.org/docs/stable/elastic/run.html), as shown below. - -``` bash -torchrun --nproc-per-node=8 nemo_automodel/recipes/llm/train_ft.py -c finetune_config.yaml -``` - -### Sample Output -Running the recipe using either the `automodel` app or by directly invoking the recipe script should produce -the following log: -``` -$ automodel finetune_config.yaml -INFO:nemo_automodel.cli.app:Config: finetune_config.yaml -INFO:nemo_automodel.cli.app:Recipe: nemo_automodel.recipes.llm.train_ft.TrainFinetuneRecipeForNextTokenPrediction -INFO:nemo_automodel.cli.app:Launching job interactively (local) -cfg-path: finetune_config.yaml -INFO:root:step 4 | epoch 0 | loss 1.5514 | grad_norm 102.0000 | mem: 11.66 GiB | tps 6924.50 -INFO:root:step 8 | epoch 0 | loss 0.7913 | grad_norm 46.2500 | mem: 14.58 GiB | tps 9328.79 -Saving checkpoint to checkpoints/epoch_0_step_10 -INFO:root:step 12 | epoch 0 | loss 0.4358 | grad_norm 23.8750 | mem: 15.48 GiB | tps 9068.99 -INFO:root:step 16 | epoch 0 | loss 0.2057 | grad_norm 12.9375 | mem: 16.47 GiB | tps 9148.28 -INFO:root:step 20 | epoch 0 | loss 0.2557 | grad_norm 13.4375 | mem: 12.35 GiB | tps 9196.97 -Saving checkpoint to checkpoints/epoch_0_step_20 -INFO:root:[val] step 20 | epoch 0 | loss 0.2469 -``` - -Each log line reports the current loss, gradient norm, peak GPU memory, and tokens per second (TPS). Small fluctuations between steps (e.g., 0.2057 to 0.2557 above) are normal — look at the overall downward trend rather than individual values. - -### Checkpoint Contents - -Checkpoints are saved in native Hugging Face format, so no conversion is required — they work directly with Transformers, PEFT, vLLM, lm-eval-harness, and other tools in the Hugging Face ecosystem. SFT and PEFT produce different checkpoint layouts. **SFT checkpoints** contain the full model weights at `model/consolidated/` — a single, self-contained Hugging Face model directory created by gathering distributed shards into one location — and can be loaded directly. **PEFT checkpoints** contain only the adapter weights (~MBs instead of GBs) — at inference time you must load the original base model and apply the adapter on top. This distinction affects every downstream step (inference, publishing, deployment). - - -**SFT checkpoint:** -```bash -$ tree checkpoints/epoch_0_step_10/ -checkpoints/epoch_0_step_10/ -├── config.yaml -├── dataloader.pt -├── model -│ ├── consolidated -│ │ ├── config.json -│ │ ├── model-00001-of-00001.safetensors -│ │ ├── model.safetensors.index.json -│ │ ├── special_tokens_map.json -│ │ ├── tokenizer.json -│ │ ├── tokenizer_config.json -│ │ └── generation_config.json -│ ├── shard-00001-model-00001-of-00001.safetensors -│ └── shard-00002-model-00001-of-00001.safetensors -├── optim -│ ├── __0_0.distcp -│ └── __1_0.distcp -├── rng.pt -└── step_scheduler.pt - -4 directories, 11 files -``` - -**PEFT checkpoint:** -```bash -$ tree checkpoints/epoch_0_step_10/ -checkpoints/epoch_0_step_10/ -├── dataloader.pt -├── config.yaml -├── model -│ ├── adapter_config.json -│ ├── adapter_model.safetensors -│ └── automodel_peft_config.json -├── optim -│ ├── __0_0.distcp -│ └── __1_0.distcp -├── rng.pt -└── step_scheduler.pt - -2 directories, 8 files -``` - - -## Run Inference - -Inference uses the Hugging Face `generate` API. Because SFT checkpoints are self-contained while PEFT checkpoints store only adapter weights (see [Checkpoint Contents](#checkpoint-contents)), the loading procedure differs between the two modes. - -### SFT Inference - -The SFT checkpoint at `model/consolidated/` is a complete Hugging Face model and can be loaded directly: - -```python -import torch -from transformers import AutoModelForCausalLM, AutoTokenizer - -ckpt_path = "checkpoints/epoch_0_step_10/model/consolidated" -tokenizer = AutoTokenizer.from_pretrained(ckpt_path) -model = AutoModelForCausalLM.from_pretrained(ckpt_path) - -device = "cuda" if torch.cuda.is_available() else "cpu" -model.to(device) - -prompt = ( - "Context: Architecturally, the school has a Catholic character. " - "Atop the Main Building's gold dome is a golden statue of the Virgin Mary. " - "Immediately in front of the Main Building and facing it, is a copper statue of Christ " - "with arms upraised with the legend 'Venite Ad Me Omnes'.\n\n" - "Question: What is atop the Main Building?\n\n" - "Answer:" -) -inputs = tokenizer(prompt, return_tensors="pt").to(device) -output = model.generate(**inputs, max_new_tokens=50) -print(tokenizer.decode(output[0], skip_special_tokens=True)) -``` - -### PEFT Inference - -PEFT adapters must be loaded on top of the base model: - -```python -import torch -from transformers import AutoModelForCausalLM, AutoTokenizer -from peft import PeftModel - -base_model_name = "meta-llama/Llama-3.2-1B" -tokenizer = AutoTokenizer.from_pretrained(base_model_name) -model = AutoModelForCausalLM.from_pretrained(base_model_name) - -adapter_path = "checkpoints/epoch_0_step_10/model/" -model = PeftModel.from_pretrained(model, adapter_path) - -device = "cuda" if torch.cuda.is_available() else "cpu" -model.to(device) - -prompt = ( - "Context: Architecturally, the school has a Catholic character. " - "Atop the Main Building's gold dome is a golden statue of the Virgin Mary. " - "Immediately in front of the Main Building and facing it, is a copper statue of Christ " - "with arms upraised with the legend 'Venite Ad Me Omnes'.\n\n" - "Question: What is atop the Main Building?\n\n" - "Answer:" -) -inputs = tokenizer(prompt, return_tensors="pt").to(device) -output = model.generate(**inputs, max_new_tokens=50) -print(tokenizer.decode(output[0], skip_special_tokens=True)) -``` - -## Evaluate the Fine-Tuned Model - -### During Training: Validation Loss - -The recipe automatically computes validation loss at the interval set by `val_every_steps`. Look for `[val]` lines in the training log: - -```text -INFO:root:[val] step 20 | epoch 0 | loss 0.2469 -``` - -A decreasing validation loss across checkpoints indicates the model is learning. If validation loss plateaus or increases while training loss continues to drop, the model may be overfitting — consider stopping earlier or reducing the learning rate. - -### After Training: lm-eval-harness - -For task-specific benchmarks (e.g., MMLU, GSM8k, HellaSwag accuracy), use [lm-eval-harness](https://github.com/EleutherAI/lm-evaluation-harness) with the fine-tuned checkpoint: - -```bash -pip install lm-eval - -# SFT checkpoint (using vLLM backend for faster evaluation) -lm_eval --model vllm \ - --model_args pretrained=checkpoints/epoch_0_step_20/model/consolidated/ \ - --tasks hellaswag \ - --batch_size auto - -# PEFT adapter (using Hugging Face backend with built-in PEFT support) -lm_eval --model hf \ - --model_args pretrained=meta-llama/Llama-3.2-1B,peft=checkpoints/epoch_0_step_20/model/ \ - --tasks hellaswag \ - --batch_size auto -``` - - -The SFT example uses the `vllm` backend for faster evaluation (requires `pip install vllm`; see [Deploy with vLLM](#deploy-with-vllm) for setup details). The PEFT example uses the `hf` backend with lm-eval's built-in PEFT support to load the adapter on top of the base model. - - - - -Run lm-eval-harness on the base model *before* fine-tuning to establish a baseline, then compare against the fine-tuned checkpoint. - - - -## Publish to the Hugging Face Hub - -Fine-tuned checkpoints and PEFT adapters are stored in Hugging Face-native format and can be uploaded directly to the Hub. - -1. Install the Hugging Face Hub library (if not already installed): - -```bash -pip3 install huggingface_hub -``` - -2. Log in to Hugging Face: - -```bash -huggingface-cli login -``` - -3. Upload: - -**SFT checkpoint:** -```python -from huggingface_hub import HfApi - -api = HfApi() -api.upload_folder( - folder_path="checkpoints/epoch_0_step_10/model/consolidated", - repo_id="your-username/llama3.2_1b-finetuned-squad", - repo_type="model", -) -``` - -**PEFT adapter:** -```python -from huggingface_hub import HfApi - -api = HfApi() -api.upload_folder( - folder_path="checkpoints/epoch_0_step_10/model", - repo_id="your-username/llama3.2_1b-lora-squad", - repo_type="model", -) -``` - -Once uploaded, load the checkpoint or adapter directly from the Hub: - -**SFT:** -```python -from transformers import AutoModelForCausalLM - -model = AutoModelForCausalLM.from_pretrained("your-username/llama3.2_1b-finetuned-squad") -``` - -**PEFT:** -```python -from transformers import AutoModelForCausalLM -from peft import PeftModel - -model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B") -model = PeftModel.from_pretrained(model, "your-username/llama3.2_1b-lora-squad") -``` - -## Deploy with vLLM - -[vLLM](https://github.com/vllm-project/vllm) is an efficient inference engine for production deployment of LLMs. - - -Make sure vLLM is installed (`pip install vllm`, or use an environment that includes it). - - - -### SFT Checkpoint with vLLM - -```python -from vllm import LLM, SamplingParams - -llm = LLM(model="checkpoints/epoch_0_step_10/model/consolidated/", model_impl="transformers") -params = SamplingParams(max_tokens=20) -outputs = llm.generate("Toronto is a city in Canada.", sampling_params=params) -print(f"Generated text: {outputs[0].outputs[0].text}") -``` -```text ->>> Generated text: It is the capital of Ontario. Toronto is a global hub for cultural tourism. The City of Toronto -``` - -### PEFT Adapter with vLLM - -PEFT adapter serving uses the `vLLMHFExporter` class, which is provided by the `nemo` package — a separate dependency from `nemo-automodel`. - - -Install both packages before proceeding: -```bash -pip install nemo vllm -``` - - - -```python -from nemo.export.vllm_hf_exporter import vLLMHFExporter - -if __name__ == '__main__': - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument('--model', required=True, type=str, help="Local path of the base model") - parser.add_argument('--lora-model', required=True, type=str, help="Local path of the LoRA adapter") - args = parser.parse_args() - - lora_model_name = "lora_model" - - exporter = vLLMHFExporter() - exporter.export(model=args.model, enable_lora=True) - exporter.add_lora_models(lora_model_name=lora_model_name, lora_model=args.lora_model) - - print("vLLM Output: ", exporter.forward(input_texts=["How are you doing?"], lora_model_name=lora_model_name)) -``` - -## Full Configuration Reference - -This section documents all available config fields for the fine-tuning recipe. For the quick-start config, see [Configure Your Training Recipe](#configure-your-training-recipe). - -### Switching Between SFT and PEFT - -The `peft:` section controls which mode runs: - -| Mode | What to do in the YAML | -|------|----------------------| -| **PEFT (LoRA)** | Include the `peft:` section as shown below. | -| **SFT (full-parameter)** | Remove/comment the `peft:` section entirely. | - -All other config sections remain the same for both modes. - -### Full Configuration - - -```yaml -# Recipe -# Selects which recipe class runs the training loop. -# Use a short name (auto-discovered) or a fully-qualified Python path: -# recipe: nemo_automodel.recipes.llm.train_ft.TrainFinetuneRecipeForNextTokenPrediction -recipe: TrainFinetuneRecipeForNextTokenPrediction - -# Training Schedule -# Controls epoch count, batch sizes, and how often to checkpoint / validate. -# No _target_ — these are plain values read directly by the recipe. -step_scheduler: - grad_acc_steps: 4 # number of micro-batches accumulated before each optimizer - # step. Effective batch = grad_acc_steps × batch_size. - ckpt_every_steps: 10 # save a checkpoint every N gradient steps - val_every_steps: 10 # run the validation loop every N gradient steps - num_epochs: 1 # how many full passes over the training dataset - -# Process Group -# Initializes the PyTorch distributed process group. -# No _target_ — consumed directly by the recipe. -# You normally would not need to tune this. -dist_env: - backend: nccl # communication backend: "nccl" (GPU, recommended) or "gloo" (CPU) - timeout_minutes: 1 # timeout for collective operations; increase for large models - # that take longer to initialize - -# Distributed Strategy -# Determines how model weights, data, and compute are split across GPUs. -# No _target_ — consumed directly by the recipe. -# See "Distributed Training: TP, PP, CP, and EP" in Advanced Topics for details. -distributed: - strategy: fsdp2 # parallelism strategy: "fsdp2" (recommended), "megatron_fsdp", - # or "ddp". FSDP2 shards parameters and optimizer states across - # the data-parallel group. - dp_size: null # data-parallel group size. null = auto-detect from - # world_size ÷ (tp_size × cp_size × pp_size). - tp_size: 1 # tensor-parallel size: splits weight matrices across GPUs. - # Set to 2, 4, or 8 if the model doesn't fit on one GPU. - # Should divide evenly into the number of attention heads. - cp_size: 1 # context-parallel size: splits the input sequence across GPUs. - # Increase for very long contexts (e.g. 32k+ tokens). - sequence_parallel: false # when true, extends TP to also shard activations along - # the sequence dimension for additional memory savings - -# Random Number Generator -# _target_ → StatefulRNG: a checkpointable RNG that ensures identical sequences -# across training restarts. Seed and ranked are kwargs to StatefulRNG(). -rng: - _target_: nemo_automodel.components.training.rng.StatefulRNG - seed: 1111 # global random seed for reproducibility - ranked: true # when true, each GPU rank gets a unique RNG stream derived - # from the seed, so data shuffling differs per GPU - -# Model -# _target_ → NeMoAutoModelForCausalLM.from_pretrained: downloads (or loads from -# cache) a pretrained HuggingFace model and wraps it with NeMo distributed-training -# support. Any from_pretrained kwarg is accepted (cache_dir, torch_dtype, etc.). -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - -# PEFT (remove / comment this entire section for full-parameter SFT) -# _target_ → PeftConfig: a dataclass describing which layers get LoRA adapters. -# The recipe passes this config into build_model(), which attaches adapters -# to the matching layers. -peft: - _target_: nemo_automodel.components._peft.lora.PeftConfig - target_modules: "*.proj" # glob pattern matched against fully-qualified layer names; - # "*.proj" matches every layer ending in "proj" - dim: 8 # low-rank dimension r — controls adapter capacity. - # Larger values are more expressive but use more memory. - alpha: 32 # LoRA scaling factor: adapter output is scaled by alpha/dim. - # Higher values give adapters more influence during training. - use_triton: True # use an optimized Triton kernel for LoRA forward/backward - # (requires the triton package) - -# Checkpointing -# No _target_ — plain key-value group consumed by the recipe. -checkpoint: - enabled: true # set to false to skip saving checkpoints entirely - checkpoint_dir: checkpoints/ # output directory. Docker users: bind-mount this path - # (e.g. -v $(pwd)/checkpoints:/workspace/checkpoints) - # to persist checkpoints across container restarts. - model_save_format: safetensors # "safetensors" (recommended, faster and safer) or - # "torch_save" (legacy pickle-based format) - save_consolidated: True # when true, writes a single HuggingFace-compatible checkpoint - # to model/consolidated/ that can be loaded directly by - # Transformers, vLLM, etc. Requires safetensors format. - -# Training Dataset -# _target_ → make_squad_dataset: a factory function that downloads the SQuAD -# dataset, tokenizes it, and returns a torch Dataset. To use a different dataset, -# change _target_ to another factory function (see the dataset guide). -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad # HuggingFace Hub dataset ID - split: train # which split to use (train, validation, test) - -# Validation Dataset -validation_dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad - split: validation - limit_dataset_samples: 64 # cap validation set to 64 samples for faster eval loops; - # remove this line to use the full validation set - -# Training Dataloader -# _target_ → StatefulDataLoader: a checkpointable DataLoader from torchdata that -# saves and restores iteration state across training restarts, so resumed runs -# don't re-process already-seen batches. -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: nemo_automodel.components.datasets.utils.default_collater - # function that pads and batches individual samples - # into tensors; can be swapped for custom collation - batch_size: 8 # samples per micro-batch per GPU - shuffle: true # whether to shuffle the dataset each epoch - -# Validation Dataloader -validation_dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: nemo_automodel.components.datasets.utils.default_collater - batch_size: 8 - -# Loss Function -# _target_ → MaskedCrossEntropy: standard cross-entropy loss that automatically -# ignores padding tokens so they don't affect the gradient. -# Other available loss functions (swap _target_ to use): -# - nemo_automodel.components.loss.chunked_ce.ChunkedCrossEntropy -# Computes CE in chunks along the sequence dimension to reduce peak memory. -# Useful for very long sequences. Accepts chunk_len (default 32). -# - nemo_automodel.components.loss.linear_ce.FusedLinearCrossEntropy -# Fuses the final linear projection (lm_head) with the CE computation, -# avoiding the full logit tensor. Significant **memory savings** for large vocabs. -# - nemo_automodel.components.loss.te_parallel_ce.TEParallelCrossEntropy -# TE-based parallel CE with a Triton kernel. Designed for tensor-parallel -# setups where logits are sharded across TP ranks. -loss_fn: - _target_: nemo_automodel.components.loss.masked_ce.MaskedCrossEntropy - -# Optimizer -# _target_ → torch.optim.Adam: any torch.optim class can be used here (e.g. -# AdamW, SGD). All remaining keys become kwargs to the constructor. -optimizer: - _target_: torch.optim.Adam - lr: 1.0e-5 # learning rate — the most important hyperparameter to tune - betas: [0.9, 0.999] # Adam momentum coefficients (β₁ for mean, β₂ for variance) - eps: 1e-8 # small constant added to the denominator for numerical stability - weight_decay: 0 # L2 regularization strength (0 = no regularization) - -# Logging (optional) -# Uncomment to enable Weights & Biases experiment tracking. -# wandb: -# project: # W&B project name -# entity: # W&B team or username -# name: # display name for this run -# save_dir: # local directory for W&B artifacts -``` - - -### Config Field Reference - -| Section | Required? | What to change | -|---------|-----------|----------------| -| `model` | Yes | Set `pretrained_model_name_or_path` to your Hugging Face model ID. Source: [`auto_model.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/_transformers/auto_model.py). | -| `peft` | PEFT only | Remove entirely for SFT. Adjust `dim` and `alpha` to tune adapter capacity. `use_triton: True` enables an optimized LoRA kernel (requires the `triton` package). For reduced memory usage, see [QLoRA](#qlora-quantized-low-rank-adaptation). Source: [`lora.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/_peft/lora.py). | -| `dataset` | Yes | Change `_target_`, `dataset_name`, and `split` for your data. Source: [`squad.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/llm/squad.py). | -| `dataloader` | Optional | Adjust `batch_size` and `shuffle`. Uses [`StatefulDataLoader`](https://meta-pytorch.org/data/main/torchdata.stateful_dataloader.html) for checkpointable iteration. Collation: [`utils.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/utils.py). | -| `loss_fn` | Optional | Default is [`MaskedCrossEntropy`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/loss/masked_ce.py). Alternatives: [`ChunkedCrossEntropy`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/loss/chunked_ce.py) (long sequences), [`FusedLinearCrossEntropy`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/loss/linear_ce.py) (large vocabs), [`TEParallelCrossEntropy`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/loss/te_parallel_ce.py) (tensor-parallel). | -| `rng` | Optional | Controls reproducibility. Source: [`rng.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/training/rng.py). | -| `step_scheduler` | Yes | `grad_acc_steps` sets how many micro-batches accumulate per gradient step. `ckpt_every_steps` and `val_every_steps` are counted in gradient steps. | -| `distributed` | Yes | `dp_size: null` means auto-detect from world size. Adjust `tp_size` for tensor parallelism across GPUs. | -| `checkpoint` | Recommended | Set `checkpoint_dir` to a persistent path, especially in Docker. | -| `optimizer` | Optional | Defaults are reasonable. Any `torch.optim` class can be substituted via `_target_`. | -| `wandb` | Optional | Uncomment and configure to enable Weights & Biases logging. | - -For the fine-tuning recipe itself, see [`train_ft.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/recipes/llm/train_ft.py). For more example configs, browse [`examples/llm_finetune/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_finetune). - -## Distributed Training: TP, PP, CP, and EP - -The `distributed:` section controls how the model and data are split across GPUs. NeMo AutoModel supports four parallelism dimensions, each of which slices the workload differently: - -| Dimension | Key | What it shards | When to use | -|-----------|-----|---------------|-------------| -| **Data Parallel (DP)** | `dp_size` | Replicates the model on each group of GPUs; each replica trains on a different data batch. | Default. Scales batch size linearly with GPU count. | -| **Tensor Parallel (TP)** | `tp_size` | Splits individual weight matrices (attention, MLP) across GPUs within a node. | Model is too large to fit on a single GPU, or you want to reduce per-GPU memory at the cost of extra communication. | -| **Pipeline Parallel (PP)** | `pp_size` | Assigns different *layers* (stages) to different GPUs and pipelines micro-batches through them. | Very deep models that don't fit even with TP, or multi-node training where TP's all-reduce is too expensive across nodes. | -| **Context Parallel (CP)** | `cp_size` | Splits the input *sequence* across GPUs so each GPU processes a portion of the context. | Very long sequences that exceed single-GPU memory. | -| **Expert Parallel (EP)** | `ep_size` | Distributes MoE experts across GPUs so each GPU holds a subset of experts. | Mixture-of-Experts models only. | - -These dimensions compose with each other. The relationship between them and total GPU count is: - -```text -world_size = pp_size × dp_size × cp_size × tp_size -``` - -When `dp_size` is set to `null` (the default), it is inferred automatically: - -```text -dp_size = world_size ÷ (tp_size × cp_size × pp_size) -``` - -EP does not appear in this formula — experts are distributed across the DP×CP rank groups, with the constraint that `(dp_size × cp_size)` must be divisible by `ep_size`. - -#### Data Parallel (default) - -Data parallelism is the default. With `strategy: fsdp2`, FSDP2 shards both model parameters and optimizer states across the DP group, so memory usage shrinks as you add GPUs: - -```yaml -distributed: - strategy: fsdp2 - dp_size: null # auto-detected from world_size ÷ (tp × cp × pp) - tp_size: 1 - cp_size: 1 -``` - -#### Tensor Parallelism - -TP splits weight matrices across GPUs within a single node. Set `tp_size` to the number of GPUs you want to shard over (typically 2, 4, or 8 — should divide evenly into the number of attention heads): - -```yaml -distributed: - strategy: fsdp2 - dp_size: null - tp_size: 4 - cp_size: 1 - sequence_parallel: false # set to true for additional memory savings -``` - -`sequence_parallel: true` extends TP to also shard activation memory along the sequence dimension, further reducing per-GPU memory at the cost of additional communication. - -#### Pipeline Parallelism - -PP assigns groups of layers to different GPUs and streams micro-batches through the stages. It requires an additional nested `pipeline:` section: - -```yaml -distributed: - strategy: fsdp2 - dp_size: null - tp_size: 4 - pp_size: 4 - cp_size: 1 - activation_checkpointing: true - - pipeline: - pp_schedule: interleaved1f1b # pipeline schedule (1f1b or interleaved1f1b) - pp_microbatch_size: 1 # micro-batch size per pipeline step - layers_per_stage: 4 # how many layers each stage handles - scale_grads_in_schedule: false -``` - -| Key | Role | -|-----|------| -| `pp_schedule` | The micro-batch schedule. `1f1b` is simpler; `interleaved1f1b` overlaps compute and communication for better throughput. | -| `pp_microbatch_size` | Number of samples per micro-batch fed into the pipeline. Must satisfy: `local_batch_size ÷ pp_microbatch_size ≥ pp_size`. | -| `layers_per_stage` | How many transformer layers each pipeline stage contains. If omitted, the framework splits layers evenly across `pp_size` stages. | - - -PP requires the model to define a `_pp_plan` that tells the framework how to split layers into stages. All built-in models include this plan; custom models must add one. - - - -#### Context Parallelism - -CP splits the sequence across GPUs — useful for very long contexts that exceed single-GPU memory. Set `cp_size` to the desired split factor: - -```yaml -distributed: - strategy: fsdp2 - dp_size: null - tp_size: 1 - cp_size: 2 -``` - - -When `cp_size > 1`, fused RoPE is automatically disabled. Some models also require the Transformer Engine (TE) attention backend for CP with packed sequences — the framework will raise an error with instructions if this applies. - - - -#### Expert Parallelism (MoE models) - -EP distributes MoE experts across GPUs. Set `ep_size` to the number of GPUs that share the full set of experts: - -```yaml -distributed: - strategy: fsdp2 - tp_size: 1 - cp_size: 1 - pp_size: 1 - ep_size: 8 - activation_checkpointing: true -``` - -EP only applies to Mixture-of-Experts models (e.g. Qwen3-MoE, Mixtral, DeepSeek-V3). For dense models, leave `ep_size` at `1` or omit it. - -#### Combining Multiple Dimensions - -You can combine TP, PP, CP, and EP in a single config. For example, a large MoE model on a multi-node cluster might use: - -```yaml -distributed: - strategy: fsdp2 - dp_size: null - tp_size: 1 - cp_size: 2 - pp_size: 1 - ep_size: 4 - activation_checkpointing: true -``` - -When choosing a combination, keep these rules in mind: - -- **`world_size` must divide evenly** into `pp_size × tp_size × cp_size` (the remainder becomes `dp_size`). -- **`(dp_size × cp_size) % ep_size == 0`** — EP shares the DP×CP groups. -- **TP within a node, PP across nodes** is the typical layout — TP requires fast NVLink bandwidth, while PP tolerates higher latency. -- **Start simple.** Use DP-only first. Add TP if the model doesn't fit on one GPU. Add PP for very large models. Add CP for long sequences. Add EP only for MoE architectures. - -## Next Steps - -- [Integrate Your Own Text Dataset](/datasets/text-dataset) — swap the SQuAD example for your own data. -- [Recipes and End-to-End Examples](/recipes-e2e-examples/overview) — browse the full set of recipes available in NeMo AutoModel. See also the [`examples/llm_finetune/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_finetune) directory for ready-to-run configs. -- [Dataset Overview: LLM, VLM, and Retrieval Datasets](/datasets/overview) — see all supported dataset types across LLM, VLM, and retrieval tasks. -- [Knowledge Distillation](/recipes-e2e-examples/knowledge-distillation) — distill a fine-tuned model into a smaller one. diff --git a/docs/fern/versions/nightly/pages/guides/llm/functiongemma-peft-loss.png b/docs/fern/versions/nightly/pages/guides/llm/functiongemma-peft-loss.png deleted file mode 100644 index 036ff9d8dbe08e8ac525559c11e75b0166e34c0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40019 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 CHT0kW diff --git a/docs/fern/versions/nightly/pages/guides/llm/functiongemma-sft-loss.png b/docs/fern/versions/nightly/pages/guides/llm/functiongemma-sft-loss.png deleted file mode 100644 index 8e05866ccd96cecdd2fa8c23b20dc20298506517..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38421 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 diff --git a/docs/fern/versions/nightly/pages/guides/llm/gpt2_loss.png b/docs/fern/versions/nightly/pages/guides/llm/gpt2_loss.png deleted file mode 100644 index 301577d71f9f4d980811366b4efb32b15702f913..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32804 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 diff --git a/docs/fern/versions/nightly/pages/guides/llm/hy3.mdx b/docs/fern/versions/nightly/pages/guides/llm/hy3.mdx deleted file mode 100644 index f0458f2b08..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/hy3.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "Hy3-preview" -description: "" -position: 7 ---- -## Introduction - -[tencent/Hy3-preview](https://huggingface.co/tencent/Hy3-preview) is a 295B Mixture-of-Experts language model from Tencent. It features 80 transformer layers (layer 0 dense, layers 1–79 MoE), 192 routed experts plus one shared expert per MoE block with top-8 sigmoid routing, Grouped Query Attention (64 Q / 8 KV heads, `head_dim=128`), per-head QK RMSNorm applied before RoPE, and an `expert_bias` buffer (surfaced as `e_score_correction_bias` in the Automodel gate) for expert-load correction during inference. The model supports a 256K context window via long-context RoPE (`rope_theta=11158840`). - -This guide walks you through fine-tuning Hy3-preview on HellaSwag using NVIDIA NeMo Automodel. You will learn how to configure the recipe, launch training, and inspect the results. - -To set up your environment to run NeMo Automodel, follow the [installation guide](https://github.com/NVIDIA-NeMo/Automodel#-install-nemo-automodel). - -## Data - -### HellaSwag - -We use [HellaSwag](https://huggingface.co/datasets/Rowan/hellaswag), a commonsense natural-language-inference dataset consisting of context + four candidate continuations. The version used here is the standard `rowan/hellaswag` HuggingFace split, formatted for next-token-prediction fine-tuning. - -- **Train / validation splits** taken directly from the HuggingFace dataset. -- **Tokenizer**: shared with the base model (`AutoTokenizer.from_pretrained` on the Hy3-preview checkpoint). -- **Padding**: `pad_seq_len_divisible=64` via the default collater. - -For the full HellaSwag dataset wrapper used in NeMo Automodel, see [`nemo_automodel.components.datasets.llm.hellaswag.HellaSwag`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/llm/hellaswag.py). - -## Architecture Notes - -Hy3-preview is a large-scale MoE with a few details that are worth calling out explicitly. The NeMo Automodel state-dict adapter and training recipe handle all of these transparently: - -- **Dense-first MoE layout**: layer 0 is a standard dense MLP (`intermediate_size=1536`); layers 1–79 use the MoE block (192 routed experts + 1 shared expert). This is controlled by `first_k_dense_replace=1` in the config. -- **GQA with per-head QK RMSNorm**: 64 Q heads and 8 KV heads (`head_dim=128`). A separate RMSNorm is applied independently to each head's Q and K projections before RoPE is applied — this is distinct from a single pre-attention layer norm and requires care when remapping projection weights. -- **Sigmoid routing with expert-bias correction**: expert selection uses a sigmoid score (not softmax). The `e_score_correction_bias` buffer tracks per-expert load imbalance; during fine-tuning the bias update factor is set to zero (`gate_bias_update_factor=0.0`) so the bias stays frozen. The buffer is created in the Automodel gate to ensure the HF checkpoint loads cleanly. -- **Shared expert**: each MoE block contains one always-active shared expert (`num_shared_experts=1`) whose output is added unconditionally alongside the routed output. -- **MTP layers**: the released checkpoint contains additional multi-token-prediction layers at indices ≥ 80 (`num_nextn_predict_layers`). These are filtered out by the state-dict adapter on load and are not used during standard SFT. -- **Long-context RoPE**: `rope_theta=11158840` with dynamic NTK-aware scaling (`beta_slow` / `beta_fast`) extending the context to 256K tokens. - -## Checkpoint Format - -The released `tencent/Hy3-preview` safetensors use a per-expert split layout and Tencent-specific key names that differ from the batched `GroupedExperts` convention used inside Automodel. The `HYV3StateDictAdapter` converts between the two transparently in three steps: - -**1. Per-expert tensors → grouped form.** -On disk every expert is stored as three separate rank-3 tensors: - -``` -model.layers.{L}.mlp.experts.{E}.gate_proj.weight # [moe_inter, hidden] -model.layers.{L}.mlp.experts.{E}.up_proj.weight # [moe_inter, hidden] -model.layers.{L}.mlp.experts.{E}.down_proj.weight # [hidden, moe_inter] -``` - -The adapter merges these across all 192 experts and stacks gate + up into a single fused tensor, landing at the Automodel layout: - -``` -model.layers.{L}.mlp.experts.gate_and_up_projs # [n_local, hidden, 2*moe_inter] -model.layers.{L}.mlp.experts.down_projs # [n_local, moe_inter, hidden] -``` - -where `n_local = n_experts / ep_size` (the slice owned by the current EP rank). - -**2. Three HYV3-specific key renames.** - -| On-disk (HF) key | Native Automodel key | -|---|---| -| `mlp.expert_bias` | `mlp.gate.e_score_correction_bias` | -| `mlp.router.gate.weight` | `mlp.gate.weight` | -| `mlp.shared_mlp.*` | `mlp.shared_experts.*` | - -All other keys (attention projections, norms, embeddings, `lm_head`) are identical between formats. - -**3. MTP layer filtering.** -Keys at layer indices ≥ `num_hidden_layers` (default 80) are silently dropped on load. - -## Launch Training - -A ready-to-use recipe ships at [`examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml). The yaml header documents how to adjust `ep_size` and `pp_size` for different cluster configurations. - -NeMo Automodel supports several ways to launch training — via the Automodel CLI with Slurm, interactive sessions, `torchrun`, and more. For full details on all launch options (Slurm batch jobs, multi-node configuration, environment variables, etc.), see the [Run on a Cluster](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/launcher/slurm.md) guide. - -### Standalone Slurm Script - -Below is a standalone Slurm script example for the HellaSwag recipe. Before running it, ensure your cluster environment is configured following the [Run on a Cluster](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/launcher/slurm.md) guide. Then submit the job: - -```bash -export TRANSFORMERS_OFFLINE=1 -export HF_HOME=your/path/to/hf_cache -export HF_DATASETS_OFFLINE=1 -export WANDB_API_KEY=your_wandb_key - -srun --output=output.out \ - --error=output.err \ - --container-image /your/path/to/automodel.image.sqsh --no-container-mount-home bash -c " - CUDA_DEVICE_MAX_CONNECTIONS=1 automodel \ - examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml \ - --nproc-per-node=8 \ - --model.config.pretrained_model_name_or_path=/your/local/hy3-preview \ - --model.config.name_or_path=/your/local/hy3-preview " -``` - -**Before you start**: -- Hugging Face applies rate limits on downloads. We recommend cloning the model repository to your local filesystem beforehand. -- Ensure your Hugging Face cache (`HF_HOME`) is configured and that the dataset is already cached locally. -- To enable Weights & Biases logging, set your `WANDB_API_KEY` and uncomment the `wandb` section at the bottom of the YAML file. -- The full recipe uses `pp_size=4` and `ep_size=32` (128 GPUs total). Valid `ep_size` values are any divisor of 192 (e.g. 8, 16, 24, 32, 48, 64, 96, 192); adjust `pp_size` and `--nproc-per-node` to match your node count. -- For a quick end-to-end smoke test on 8 GPUs use [`examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml). diff --git a/docs/fern/versions/nightly/pages/guides/llm/knowledge-distillation.mdx b/docs/fern/versions/nightly/pages/guides/llm/knowledge-distillation.mdx deleted file mode 100644 index ca01847b5b..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/knowledge-distillation.mdx +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: "Knowledge Distillation with NeMo AutoModel" -description: "" -position: 4 ---- -This guide walks through fine-tuning a **student** LLM with the help of a -larger **teacher** model using the `kd` (knowledge distillation) recipe. - -In particular, we will show how to distill a 3B (`meta-llama/Llama-3.2-3B`) model into a 1B (`meta-llama/Llama-3.2-1B`) model. - -## What is Knowledge Distillation? - -Knowledge distillation (KD) transfers the *dark knowledge* of a high-capacity -teacher model to a smaller student by minimizing the divergence between their -predicted distributions. The student learns from both the ground-truth labels -(Cross-Entropy loss, **CE**) and the soft targets of the teacher (Kullback-Leibler -loss, **KD**): - -$$ - \mathcal{L} = (1-\alpha) \cdot \mathcal{L}_{\textrm{CE}}(p^{s}, y) + \alpha \cdot \mathcal{KL}(p^{s}, p^{t}) -$$ - -where $\(\alpha\)$ is the `kd_ratio`, $\(T\)$ softmax `temperature` and $y$ the labels. For the arguments p: -$$p^{s} = softmax(z^{s}, T)$$. - -## Prepare the YAML Config - -A ready-to-use example is provided at -`examples/llm_kd/llama3_2/llama3_2_1b_kd.yaml`. Important sections: - -* `model` – the student to be fine-tuned (1 B parameters in the example) -* `teacher_model` – a larger frozen model used for supervision (7 B) -* `kd_ratio` – blend between CE and KD loss -* `temperature` – softens probability distributions before KL-divergence -* `peft` – **optional** LoRA config (commented). Uncomment to train only a - handful of parameters. - -Feel free to tweak these values as required. - -### Example YAML - -```yaml -# Example config for knowledge distillation fine-tuning -# Run with: -# automodel examples/llm_kd/llama3_2/llama3_2_1b_kd.yaml - -step_scheduler: - global_batch_size: 32 - local_batch_size: 1 - ckpt_every_steps: 200 - val_every_steps: 100 # will run every x number of gradient steps - num_epochs: 2 - -dist_env: - backend: nccl - timeout_minutes: 1 - -rng: - _target_: nemo_automodel.components.training.rng.StatefulRNG - seed: 1111 - ranked: true - -# Student -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - torch_dtype: bf16 - -# Teacher -teacher_model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-3B - torch_dtype: bf16 - -checkpoint: - enabled: true - checkpoint_dir: checkpoints/ - model_save_format: safetensors - save_consolidated: false - -distributed: - strategy: fsdp2 - dp_size: null - tp_size: 1 - cp_size: 1 - pp_size: 1 - sequence_parallel: false - -# PEFT can be enabled by uncommenting below – student weights will remain small -# peft: -# _target_: nemo_automodel.components._peft.lora.PeftConfig -# target_modules: '*_proj' -# dim: 16 -# alpha: 32 -# use_triton: true - -loss_fn: - _target_: nemo_automodel.components.loss.masked_ce.MaskedCrossEntropy - -# Knowledge-distillation hyper-params -kd_ratio: 0.5 # 0 → pure CE, 1 → pure KD -kd_loss_fn: - _target_: nemo_automodel.components.loss.kd_loss.KDLoss - ignore_index: -100 - temperature: 1.0 - fp32_upcast: true - -# Optimizer -optimizer: - _target_: torch.optim.Adam - betas: [0.9, 0.999] - eps: 1e-8 - lr: 1.0e-5 - weight_decay: 0 - -# Dataset / Dataloader -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad - split: train - -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: nemo_automodel.components.datasets.utils.default_collater - shuffle: false - -validation_dataset: - _target_: nemo_automodel.components.datasets.llm.hellaswag.HellaSwag - path_or_dataset: rowan/hellaswag - split: validation - num_samples_limit: 64 - -validation_dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: nemo_automodel.components.datasets.utils.default_collater -``` - -### Current Limitations - -* Pipeline parallelism (`pp_size > 1`) is not yet supported – planned for a future release. -* Distilling Vision-Language models (`vlm` recipe) is currently not supported. -* Student and teacher models must share the same tokenizer for now; support for different tokenizers will be added in the future. - -## Launch Training - -### Single-GPU Quick Run - -```bash -# Runs on a single device of the current host -automodel examples/llm_kd/llama3_2/llama3_2_1b_kd.yaml -``` - -### Multi-GPU (Single Node) - -```bash -# Leverage all GPUs on the local machine -torchrun --nproc-per-node $(nvidia-smi -L | wc -l) \ - nemo_automodel/recipes/llm/kd.py \ - -c examples/llm_kd/llama3_2/llama3_2_1b_kd.yaml -``` - -### Slurm Cluster - -The CLI seamlessly submits Slurm jobs when a `slurm` section is added to the -YAML. Refer to `docs/guides/installation.md` for cluster instructions. - -## Monitoring - -Metrics such as *train_loss*, *kd_loss*, *learning_rate* and *tokens/sec* are -logged to **WandB** when the corresponding section is enabled. - -## Checkpoints and Inference - -- Checkpoints are written under the directory configured in the `checkpoint.checkpoint_dir` field at every `ckpt_every_steps`. -- The final student model is saved according to the `checkpoint` section (e.g., `model_save_format: safetensors`, consolidated weights if `save_consolidated: true`). - -Load the distilled model: - -```python -import nemo_automodel as am -student = am.NeMoAutoModelForCausalLM.from_pretrained("checkpoints/final") -print(student("Translate to French: I love coding!").text) -``` diff --git a/docs/fern/versions/nightly/pages/guides/llm/large-moe-finetune.mdx b/docs/fern/versions/nightly/pages/guides/llm/large-moe-finetune.mdx deleted file mode 100644 index 4f858d418c..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/large-moe-finetune.mdx +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: "Fine-Tune Large MoE LLMs" -description: "" -position: 5 ---- -## Introduction - -Mixture-of-Experts (MoE) architectures have become the dominant design for frontier language models, activating only a fraction of their total parameters per token to deliver strong performance at reduced compute cost. This guide walks through fine-tuning four example MoE LLMs with NVIDIA NeMo Automodel. For a full list of supported architectures, see the [LLM model coverage](/model-coverage/large-language-models/overview) page. - -| Model | HF Checkpoint | Validated Using | -|-------|--------------|-----------------| -| GLM-5 | [`zai-org/GLM-5`](https://huggingface.co/zai-org/GLM-5) | 256 H100 GPUs (32 nodes x 8) | -| MiniMax-M2.5 | [`MiniMaxAI/MiniMax-M2.5`](https://huggingface.co/MiniMaxAI/MiniMax-M2.5) | 64 H100 GPUs (8 nodes x 8) | -| Step-3.5 Flash | [`stepfun-ai/Step-3.5-Flash`](https://huggingface.co/stepfun-ai/Step-3.5-Flash) | 64 H100 GPUs (8 nodes x 8) | -| DeepSeek-V3.2 | [`deepseek-ai/DeepSeek-V3.2`](https://huggingface.co/deepseek-ai/DeepSeek-V3.2) | 256 H100 GPUs (32 nodes x 8) | - -To set up your environment to run NeMo Automodel, follow the [installation guide](https://github.com/NVIDIA-NeMo/Automodel#-install-nemo-automodel). - -## Data - -### HellaSwag Dataset - -All four recipes use the [HellaSwag](https://huggingface.co/datasets/rowan/hellaswag) dataset, a commonsense natural language inference benchmark where the model must predict the most plausible continuation of a given scenario. - -- **Source**: `rowan/hellaswag` -- **Split**: `train` (used for both training and validation in these recipes) -- **Task**: Next-token prediction on commonsense sentence completions - -For details on how to swap in your own dataset, see the [LLM Dataset Guide](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/guides/llm/dataset.md) and the [Dataset Overview](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/guides/dataset-overview.md). - -## Recipes - -### MiniMax-M2.5 - -[`examples/llm_finetune/minimax_m2/minimax_m2.5_hellaswag_pp.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.5_hellaswag_pp.yaml) — validated using **64 H100 GPUs** (8 nodes x 8). - -Key distributed settings: - -```yaml -distributed: - strategy: fsdp2 - pp_size: 2 - ep_size: 32 - pipeline: - pp_schedule: interleaved1f1b - layers_per_stage: 2 -``` - -### GLM-5 - -[`examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml) — validated using **256 H100 GPUs** (32 nodes x 8). - -Key distributed settings: - -```yaml -distributed: - strategy: fsdp2 - pp_size: 4 - ep_size: 64 - activation_checkpointing: true - pipeline: - pp_schedule: interleaved1f1b - layers_per_stage: 2 -``` - -### Step-3.5 Flash (StepFun) - -[`examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml) — validated using **64 H100 GPUs** (8 nodes x 8). - -Key distributed settings: - -```yaml -distributed: - strategy: fsdp2 - pp_size: 2 - ep_size: 32 - pipeline: - pp_schedule: interleaved1f1b - layers_per_stage: 2 -``` - -### DeepSeek-V3.2 - -[`examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml) — validated using **256 H100 GPUs** (32 nodes x 8). - -Key distributed settings: - -```yaml -distributed: - strategy: fsdp2 - pp_size: 4 - ep_size: 64 - activation_checkpointing: true - pipeline: - pp_schedule: interleaved1f1b - layers_per_stage: 2 -``` - -## Launch Training - -NeMo Automodel supports several ways to launch training—via the Automodel CLI with Slurm, interactive sessions, `torchrun`, and more. For full details on all launch options (Slurm batch jobs, multi-node configuration, environment variables, etc.), see the [Run on a Cluster](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/launcher/slurm.md) guide. - -### Automodel CLI - -```bash -automodel finetune llm -c examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml -``` - -Replace the recipe path with the one for your target model. - -### torchrun - -```bash -export TRANSFORMERS_OFFLINE=1 -export HF_HOME=your/path/to/hf_cache -export HF_DATASETS_OFFLINE=1 -export WANDB_API_KEY=your_wandb_key - -torchrun --nproc-per-node=8 \ - --nnodes=8 \ - --rdzv_backend=c10d \ - --rdzv_endpoint=${MASTER_ADDR}:${PORT} \ - nemo_automodel/recipes/llm/benchmark.py \ - -c examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml \ - --model.pretrained_model_name_or_path=/your/local/model_weights -``` - -Replace the `-c` path, `--nnodes`, and `--model.pretrained_model_name_or_path` for the model you want to fine-tune. - -**Before you start**: -- Hugging Face applies rate limits on downloads. We recommend cloning the model repository to your local filesystem beforehand. -- Ensure your Hugging Face cache (`HF_HOME`) is configured and that the dataset is already cached locally. -- To enable Weights & Biases logging, set your `WANDB_API_KEY` and configure the `wandb` section in the YAML file. diff --git a/docs/fern/versions/nightly/pages/guides/llm/nanogpt-pretraining.mdx b/docs/fern/versions/nightly/pages/guides/llm/nanogpt-pretraining.mdx deleted file mode 100644 index 0caadec910..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/nanogpt-pretraining.mdx +++ /dev/null @@ -1,463 +0,0 @@ ---- -title: "LLM Pre-Training with NeMo AutoModel" -description: "" -position: 9 ---- -This guide covers **FineWeb** data preparation, **defining** a [NanoGPT‑style](https://github.com/KellerJordan/modded-nanogpt) model, and **launching and monitoring** a NeMo AutoModel pre‑training run. - -## Set Up Your Environment - -In this guide, we will use an interactive environment to install NeMo AutoModel from Git. You can also install NeMo AutoModel from PyPI or use our bi-monthly Docker container (see the [Installation Guide](/get-started/installation)). - -```bash -# clone / install AutoModel (editable for local hacks) -cd /path/to/workspace/ # specify to your path as needed. -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel/ -pip install -e ".[all]" # installs NeMo AutoModel + optional extras -``` - - -For this guide, we will use a single machine equipped with 8xH100 NVIDIA GPUs. - - - - -To run this guide on a single GPU, use the single-GPU command in the **Launch Training** section below and scale down the YAML (for example, reduce `step_scheduler.global_batch_size` / `local_batch_size`, and shrink the model using `model.n_layer` / `model.n_embd` / `model.n_head`). For more launch patterns, see [Run on Your Local Workstation](/job-launchers/local-workstation). - - - -## Preprocess the FineWeb Dataset - - -**File Size Limitation**: The `nanogpt_data_processor.py` script has a **4GB file size limit** (~2^32 bytes) due to 32-bit position tracking in the BOS index. This translates to: -- **~2 billion tokens** when using uint16 (vocabularies < 65,536 tokens, e.g., GPT-2) -- **~1 billion tokens** when using uint32 (larger vocabularies) - -Always use the `--max-tokens` flag to stay within these limits (e.g., `--max-tokens 2B` or `--max-tokens 1.5B`). - -For larger datasets, please see [pretraining.md](/recipes-e2e-examples/pretraining) which supports sharded preprocessing without these constraints. - - - -### Quick Introduction to the FineWeb Dataset -The [FineWeb](https://huggingface.co/datasets/HuggingFaceFW/fineweb) dataset consists of more than 18.5T tokens of cleaned and deduplicated English web data from [CommonCrawl](https://commoncrawl.org/). For this guide, we use the **`sample-10BT` subset** (10 billion tokens), from which we extract a smaller sample (e.g., 500M tokens) that fits within the preprocessing tool's limits. - -Briefly, FineWeb is built by extracting main text from CommonCrawl WARC HTML, keeping English pages using fastText language scoring, applying multiple quality filters (e.g., Gopher repetition/quality checks, C4-style rules, and custom heuristics for list-like or repeated/poorly formatted lines), and then MinHash-deduplicating each crawl independently (5-gram shingling with 14×8 hash functions). Basic PII normalization is applied (e.g., anonymizing emails and public IPs). The result is released per-crawl (and convenient sampled subsets), ready for high-throughput streaming. - - -To train on more than 2B tokens from FineWeb, see [pretraining.md](/recipes-e2e-examples/pretraining) which uses Megatron Core's sharded dataset format without file size constraints. - - - -### Preprocessing and Tokenization - -For the purposes of this guide, we provide a data preprocessing tool at [`nanogpt_data_processor.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/tools/nanogpt_data_processor.py) that streams datasets from the Hugging Face Hub, tokenizes using Hugging Face's `transformers.AutoTokenizer` (default: GPT-2), and writes the output in **memory-mapped binary shards** to files. During training, we use the [`NanogptDataset`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/llm/nanogpt_dataset.py) class that can stream efficiently at training time. - -```bash -# Step into repo root -cd /path/to/workspace/Automodel/ - -# Generate 500 million tokens using the 10B raw split -python tools/nanogpt_data_processor.py \ - --dataset HuggingFaceFW/fineweb \ - --set-name sample-10BT \ - --max-tokens 500M # stop after 500 million tokens; specify as needed, reduce for smaller runs. - -# Shards are stored in: tools/fineweb_max_tokens_500M/ -# dataset.bin (single binary file with all tokens) -``` - -**How the preprocessor works:** The script streams data iteratively from the Hugging Face Hub (avoiding loading the entire dataset into memory), uses a multiprocessing pipeline with separate reader and writer processes, and parallelizes tokenization across multiple CPU cores using `ProcessPoolExecutor`. This design enables efficient processing of very large datasets while maintaining low memory overhead. By default, uses the `gpt2` tokenizer, but can support other tokenizers using the `--tokenizer` option. - -Consider the following options: -1. Adjust `--max-tokens` to control how many tokens to process (must stay within the 4GB file size limit mentioned above). -2. Adjust `--chunk-size` for processing batch size. -3. Use `--num-workers` to control parallelization. -4. Specify `--output-dir` to change the output location. - -## Understand the NeMo AutoModel Training Workflow - -NeMo AutoModel follows a simple but powerful flow for training: - -1. A Python recipe script (for example, [`examples/llm_pretrain/pretrain.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_pretrain/pretrain.py)) serves as the entry point that wires up all training components based on a YAML configuration file. Any configuration option can be overridden using CLI arguments (e.g., `--model.name abc`). -2. The YAML file describes each component of the training job (such as `model`, `dataset`, `optimizer`, `distributed`, `checkpoint`, and optional `wandb`). -3. Each component is constructed from its `_target_`, which points to a Python callable (function or class constructor) to instantiate. The remaining keys in that YAML block become keyword arguments for that callable. - -How `_target_` is resolved: -- Import path to a Python object (for example, `my_pkg.models.build_model`). -- Local Python file path plus object name (for example, `/abs/path/to/my_model.py:build_model`). -- Library callables such as Hugging Face `transformers.AutoModelForCausalLM.from_config`. - -Nested objects can also specify their own `_target_` (common when building Hugging Face `config` objects first and passing them into a `from_config` method). Any YAML key can be overridden at launch time from the CLI, making it easy to tweak hyperparameters without editing files. - -With this context, let’s define a model using `_target_`, then point the dataset at your preprocessed shards, and finally review the full YAML. - -## Define Your Own Model Architecture - -NeMo AutoModel relies on a YAML-driven configuration to build every training component. In particular, the `model._target_` must reference a callable that returns an `nn.Module` (or a compatible Hugging Face model). You can point `_target_` at: - -- An import path to a Python object. -- A local Python file plus the object name using `path.py:object_name`. -- A library callable such as `transformers.AutoModelForCausalLM.from_config`. - -Below are examples for each pattern. - -### NanoGPT Source and File-Path `_target_` - -Below is the minimal GPT‑2 [implementation](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/models/gpt2.py) used for this NanoGPT‑style pretraining flow. -It is a pure‑PyTorch model with tied embeddings and standard transformer blocks: - -``` -""" -Self-contained GPT-2 (Causal LM) implementation. - -This module defines a pure-PyTorch model and defines the necessary -building blocks (attention, MLP, transformer block, and language-model head). -The public *build_gpt2_model* helper returns an ``nn.Module``. -""" -import math -from typing import Any - -import torch -import torch.nn as nn -import torch.nn.functional as F - -# The attention layer -class CausalSelfAttention(nn.Module): - """Multi-head self-attention with a causal mask.""" - - def __init__(self, embed_dim: int, num_heads: int, attn_dropout: float = 0.0): - super().__init__() - - if embed_dim % num_heads != 0: - raise ValueError("embed_dim must be divisible by num_heads") - - self.embed_dim = embed_dim - self.num_heads = num_heads - self.head_dim = embed_dim // num_heads - - self.qkv_proj = nn.Linear(embed_dim, 3 * embed_dim) - self.out_proj = nn.Linear(embed_dim, embed_dim) - self.attn_dropout = attn_dropout - - def forward(self, x: torch.Tensor) -> torch.Tensor: # (B, T, C) - bsz, seq_len, _ = x.shape - - # Project to QKV and reshape: (B, T, 3*C) → (B, n_head, T, head_dim) - qkv = self.qkv_proj(x).view(bsz, seq_len, 3, self.num_heads, self.head_dim) - q, k, v = qkv.unbind(dim=2) - q, k, v = (t.transpose(1, 2) for t in (q, k, v)) # (B, n_head, T, head_dim) - - # Use torch's optimized SDPA when available (PyTorch ≥2.0) - if hasattr(F, "scaled_dot_product_attention"): - attn_output = F.scaled_dot_product_attention( - q, k, v, dropout_p=self.attn_dropout, is_causal=True - ) # (B, n_head, T, head_dim) - else: - # Fallback implementation with an explicit causal mask - scores = q @ k.transpose(-2, -1) / math.sqrt(self.head_dim) - causal_mask = torch.tril(torch.ones(seq_len, seq_len, device=x.device, dtype=torch.bool)) - scores = scores.masked_fill(~causal_mask, float("-inf")) - attn_weights = F.softmax(scores, dim=-1) - attn_weights = F.dropout(attn_weights, p=self.attn_dropout, training=self.training) - attn_output = attn_weights @ v # (B, n_head, T, head_dim) - - # Merge heads - attn_output = attn_output.transpose(1, 2).contiguous().view(bsz, seq_len, self.embed_dim) - return self.out_proj(attn_output) - -# The MLP -class MLP(nn.Module): - """GPT-2 feed-forward network (GEGLU → Linear).""" - - def __init__(self, embed_dim: int, expansion_factor: int = 4): - super().__init__() - hidden_dim = expansion_factor * embed_dim - self.fc1 = nn.Linear(embed_dim, hidden_dim) - self.act = nn.GELU() - self.fc2 = nn.Linear(hidden_dim, embed_dim) - - def forward(self, x: torch.Tensor) -> torch.Tensor: # (B, T, C) - return self.fc2(self.act(self.fc1(x))) - -# Transformers -class TransformerBlock(nn.Module): - """A single transformer block (LN → Attn → Add → LN → MLP → Add).""" - - def __init__(self, embed_dim: int, num_heads: int, dropout: float = 0.0): - super().__init__() - self.ln_1 = nn.LayerNorm(embed_dim) - self.attn = CausalSelfAttention(embed_dim, num_heads, dropout) - self.ln_2 = nn.LayerNorm(embed_dim) - self.mlp = MLP(embed_dim) - - def forward(self, x: torch.Tensor) -> torch.Tensor: - x = x + self.attn(self.ln_1(x)) - x = x + self.mlp(self.ln_2(x)) - return x - -# The GPT-2 model definition -class GPT2LMHeadModel(nn.Module): - """Minimal GPT-2 Causal-LM with tied input/output embeddings.""" - - def __init__( - self, - *, - vocab_size: int, - n_positions: int, - n_embd: int, - n_layer: int, - n_head: int, - dropout: float = 0.1, - ) -> None: - super().__init__() - - self.wte = nn.Embedding(vocab_size, n_embd) - self.wpe = nn.Embedding(n_positions, n_embd) - self.drop = nn.Dropout(dropout) - - self.h = nn.ModuleList([TransformerBlock(n_embd, n_head, dropout) for _ in range(n_layer)]) - self.ln_f = nn.LayerNorm(n_embd) - - # Language model head (weights tied to token embedding matrix) - self.lm_head = nn.Linear(n_embd, vocab_size, bias=False) - self.lm_head.weight = self.wte.weight # weight tying - - # Initialize parameters following GPT-2 scheme - self._init_weights() - - def forward(self, input_ids: torch.LongTensor) -> torch.Tensor: # (B, T) → (B, T, V) - batch_size, seq_len = input_ids.shape - - if seq_len > self.wpe.num_embeddings: - raise ValueError(f"Sequence length {seq_len} exceeds maximum context size {self.wpe.num_embeddings}.") - - pos_ids = torch.arange(seq_len, device=input_ids.device).unsqueeze(0).expand(batch_size, seq_len) - - x = self.wte(input_ids) + self.wpe(pos_ids) - x = self.drop(x) - - for block in self.h: - x = block(x) - - x = self.ln_f(x) - logits = self.lm_head(x) - return logits - - def _init_weights(self): - """Parameter initialization following GPT-2 conventions.""" - - for module in self.modules(): - if isinstance(module, nn.Linear): - # GPT-2 uses normal(0, 0.02) - nn.init.normal_(module.weight, mean=0.0, std=0.02) - if module.bias is not None: - nn.init.zeros_(module.bias) - elif isinstance(module, nn.Embedding): - nn.init.normal_(module.weight, mean=0.0, std=0.02) - -# Helper entrypoint -def build_gpt2_model( - *, - vocab_size: int = 50257, - n_positions: int = 2048, - n_ctx: int | None = None, - n_embd: int = 768, - n_layer: int = 12, - n_head: int = 12, - bos_token_id: int = 50256, # kept for API backward-compat (unused) - eos_token_id: int = 50256, # kept for API backward-compat (unused) - attn_implementation: str = "flash_attention_2", # retained but ignored - **extra_cfg: Any, # ignored to preserve call-sites that used to pass config tweaks -) -> nn.Module: - """Instantiate and return a *pure-PyTorch* GPT-2 language model. - - The function intentionally keeps the same signature as the original - wrapper so existing YAML/CLI configurations continue to work. - Extra keyword arguments are quietly ignored. - """ - - # Map legacy *n_ctx* to *n_positions* if provided. - if n_ctx is not None and n_ctx != n_positions: - n_positions = n_ctx - - # Issue a gentle warning if the user passes unused extra kwargs. - if extra_cfg: - invalid = ", ".join(extra_cfg.keys()) - print( - f"[build_gpt2_model] Warning: Ignoring unsupported keyword arguments: {invalid}.", - flush=True, - ) - - return GPT2LMHeadModel( - vocab_size=vocab_size, - n_positions=n_positions, - n_embd=n_embd, - n_layer=n_layer, - n_head=n_head, - ) -``` - -In short, `build_gpt2_model(...)` constructs a compact GPT‑2 with configurable depth/width/heads and returns an `nn.Module` that outputs logits over the vocabulary. It’s intentionally lean (no KV‑cache or generation helpers) but perfectly suited for forward/backward passes and next‑token prediction. - -To use this exact implementation directly from a file path, point `_target_` to the file and object name (`path.py:object`). Absolute paths are recommended: - -```yaml -model: - _target_: /abs/path/to/repo/nemo_automodel/components/models/gpt2.py:build_gpt2_model - vocab_size: 50258 - n_positions: 2048 - n_embd: 768 - n_layer: 12 - n_head: 12 -``` - -This loads the file on disk and calls `build_gpt2_model(...)` with the remaining keys as keyword arguments. - -### Import Path to a Callable (Function or Class) - -Instead of a file path, you can reference the callable using its import path: - -```yaml -# examples/llm_pretrain/nanogpt_pretrain.yaml -model: - _target_: nemo_automodel.components.models.gpt2.build_gpt2_model - vocab_size: 50258 - n_positions: 2048 - n_embd: 768 - n_layer: 12 - n_head: 12 -``` - -### Hugging Face Models using `from_config` Function - -You can instantiate any Hugging Face causal LM with a config-first flow by targeting a `from_config` callable and providing a nested `config` node. The nested node is itself resolved using `_target_`, so you can compose Hugging Face configs directly in YAML. - -```yaml -model: - _target_: transformers.AutoModelForCausalLM.from_config - # Nested object: built first, then passed to from_config(config=...) - config: - _target_: transformers.AutoConfig.from_pretrained - pretrained_model_name_or_path: gpt2 # or "Qwen/Qwen2-1.5B", etc. - n_layer: 12 - n_head: 12 - n_positions: 2048 - vocab_size: 50258 -``` - -Alternatively, target a specific architecture: - -```yaml -model: - _target_: transformers.GPT2LMHeadModel.from_config - config: - _target_: transformers.GPT2Config - n_layer: 12 - n_head: 12 - n_positions: 2048 - vocab_size: 50258 -``` - - -- The `model._target_` may reference an import path or a local Python file using the `path.py:object` form. -- Any nested mapping that includes `_target_` (e.g., `config:`) is instantiated first and its result is passed upward. This is how the Hugging Face `from_config` pattern works. -- You can keep using the same training recipe (optimizer, data, distributed settings); only the `model:` block changes. - - - -## Inspect and Adjust the YAML Configuration - -[`examples/llm_pretrain/nanogpt_pretrain.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_pretrain/nanogpt_pretrain.yaml) is a complete configuration that: -* Defines a GPT-2 model using the `build_gpt2_model` shorthand (easy to scale up). -* Points `file_pattern` at preprocessed binary data files (configure based on your preprocessing output). -* Uses the new `NanogptDataset` with `seq_len=1024`. -* Sets a vanilla `AdamW` optimizer with learning rate `2e-4`. -* Includes FSDP2 distributed training configuration. - -Key configuration sections: - -```yaml -# Model configuration (two options available) -model: - _target_: nemo_automodel.components.models.gpt2.build_gpt2_model - vocab_size: 50258 - n_positions: 2048 - n_embd: 768 - n_layer: 12 - n_head: 12 - -# Dataset configuration -dataset: - _target_: nemo_automodel.components.datasets.llm.nanogpt_dataset.NanogptDataset - file_pattern: "tools/fineweb_max_tokens_500M/dataset.bin" - seq_len: 1024 - shuffle_files: true - -# Distributed training -distributed: - strategy: fsdp2 - dp_size: null - tp_size: 1 - cp_size: 1 -``` - -**About `_target_` configuration**: The `_target_` field specifies import paths to classes and functions within the nemo_automodel package (or any Python module). For example, `nemo_automodel.components.models.gpt2.build_gpt2_model` imports and calls the GPT-2 model builder function. You can also specify paths to your own Python files (e.g., `my_custom_models.MyTransformer`) to use custom `nn.Module` implementations, allowing full flexibility in model architecture while leveraging the training infrastructure. - -Update the `file_pattern` to match your data location. For example, if using `tools/nanogpt_data_processor.py` with the default settings: `"tools/fineweb_max_tokens_500M/dataset.bin"` - -Scale **width/depth**, `batch_size`, or `seq_len` as needed - the recipe is model-agnostic. - -## Launch Training - -```bash -# Single-GPU run (good for local testing) -python examples/llm_pretrain/pretrain.py \ - --config examples/llm_pretrain/nanogpt_pretrain.yaml - -# Multi-GPU (e.g., 8x H100) -torchrun --standalone --nproc-per-node 8 \ - examples/llm_pretrain/pretrain.py \ - --config examples/llm_pretrain/nanogpt_pretrain.yaml - -# Using the automodel CLI: -# single-GPU -automodel examples/llm_pretrain/nanogpt_pretrain.yaml - -# multi-GPU (8 GPUs) -automodel --nproc-per-node 8 examples/llm_pretrain/nanogpt_pretrain.yaml -``` - -Adjust the `distributed` section in the YAML config to change between DDP, FSDP2, etc. - - - -The `TrainFinetuneRecipeForNextTokenPrediction` class handles: -* Distributed (FSDP2 / TP / CP) wrapping if requested in the YAML. -* Gradient accumulation, LR scheduling, checkpointing, optional W&B logging. -* Validation loops if you supply `validation_dataset`. - -Checkpoints are written under `checkpoints/` by default as `safetensors` or `torch_save` (YAML-configurable). - -## Monitor and Evaluate Training - -* **TPS** (tokens per second), **gradient norm**, and **loss** statistics print every optimization step. -* Enable `wandb` in the YAML for dashboards (`wandb.project`, `wandb.entity`, etc.). -* Periodic checkpoints can be loaded using `TrainFinetuneRecipeForNextTokenPrediction.load_checkpoint()`. - -Example W&B configuration: -```yaml -wandb: - project: "nanogpt-pretraining" - entity: "your-wandb-entity" - name: "nanogpt-500M-tokens" -``` - -## Explore Further Work - -1. **Scaling up**: Swap the GPT-2 config for `LlamaForCausalLM`, `Qwen2`, or any Hugging Face-compatible causal model; increase `n_layer`, `n_embd`, etc. -2. **Mixed precision** - FSDP2 + `bfloat16` (`dtype: bfloat16` in distributed config) for memory savings. -3. **Sequence packing** - set `packed_sequence.packed_sequence_size` >0 to pack variable-length contexts and boost utilization. -4. **Custom datasets** - implement your own `IterableDataset` or convert existing corpora to the `.bin` format using `tools/nanogpt_data_processor.py` as a template. -5. **BOS alignment** - set `align_to_bos: true` in the dataset config to ensure sequences start with BOS tokens (requires `bos_token` parameter). diff --git a/docs/fern/versions/nightly/pages/guides/llm/pretraining.mdx b/docs/fern/versions/nightly/pages/guides/llm/pretraining.mdx deleted file mode 100644 index 262432952c..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/pretraining.mdx +++ /dev/null @@ -1,749 +0,0 @@ ---- -title: "Pretraining Megatron Core Datasets with NeMo AutoModel" -description: "" -position: 8 ---- -## Introduction - -Pretraining builds a base large language model (LLM) by training a randomly initialized model to predict the next token across massive, unlabeled datasets. - -Robust pretraining establishes a foundation of linguistic competence and world knowledge that scales with data, parameters, and compute. This base model then serves as the necessary starting point for later fine-tuning or domain-specific adaptation. - -NeMo AutoModel provides an end-to-end recipe to run LLM pretraining with Hugging Face–native models and Megatron-Core style datasets. - -## Model and Dataset Context - -In this guide, we pretrain OpenAI’s `GPT2-124M` model on a FineWeb-Edu subset of 10 billion tokens. - -### About the FineWeb-Edu Dataset - -[FineWeb-Edu](https://huggingface.co/datasets/HuggingFaceFW/fineweb-edu) is a dataset consisting of 1.3T tokens of educational web pages filtered from the larger [FineWeb](https://huggingface.co/datasets/HuggingFaceFW/fineweb) dataset. The educational web pages were filtered from the main dataset using a fine-tuned [Bert](https://huggingface.co/docs/transformers/en/model_doc/bert)-like classifier. Further reading on the filtering process can be found [here](https://huggingface.co/spaces/HuggingFaceFW/blogpost-fineweb-v1). - -Here’s a glimpse of what the data looks like: -```json -{ - "id": "", - "dump": "CC-MAIN-2013-20", - "text": "No. 24; Updated March 2011 - Click here to download and print a PDF version of this document. - Parents are usually the first to recognize that their child has a problem with emotions or behavior. Still, the decision to seek professional help can be difficult and painful for a parent. The first step is to gently try to talk to the child. An honest open talk about feelings can often help. Parents may choose to consult with the child's physicians, teachers, members of the clergy, or other adults who know the child well. These steps may resolve the problems for the child and family. - Following are a few signs which may indicate that a child and adolescent psychiatric evaluation will be useful ...", - "url": "https://www.aacap.org/AACAP/Families_and_Youth/Facts_for_Families/FFF-Guide/When-to-Seek-Help-for-Your-Child-024.aspx", - "date": null, - "file_path": "s3://commoncrawl/crawl-data/CC-MAIN-2013-20/segments/1368696381249/warc/CC-MAIN-20130516092621-00000-ip-10-60-113-184.ec2.internal.warc.gz", - "language": "en", - "language_score": 0.927742, - "token_count": 755, - "score": 3.375, - "int_score": 3, -} -``` - -#### Download the FineWeb-Edu Dataset - -For this guide, we use the FineWeb-Edu 10BT sample—a collection of approximately 10 billion tokens randomly drawn from the full FineWeb-Edu dataset. To prepare the data, run the following commands: - -```bash -# run this inside the AutoModel directory - -git clone https://github.com/facebookresearch/lingua.git -cd lingua -pip install -r requirements.txt -python setup/download_prepare_hf_data.py fineweb_edu_10bt --data_dir --seed 42 --nchunks 1 -cd .. -mv lingua/fineweb_edu . -``` -Replace `` with the amount of system memory allocated to `terashuf` (the tool used for sample shuffling), and set `` to the root directory where the data will be stored. You can run the following example command: -```bash -python setup/download_prepare_hf_data.py fineweb_edu_10bt 16 --data_dir ./fineweb_edu --seed 42 --nchunks 1 -``` - -The expected directory structure is like this: -```bash -$ tree fineweb_edu/ -fineweb_edu/ -├── fineweb_edu_10bt -│ ├── datatrove -│ │ ├── completions -│ │ │ ├── 00000 -│ │ │ ├── 00001 -│ │ │ ├── 00002 -│ │ │ ├── 00003 -│ │ │ ├── 00004 -│ │ │ ├── 00005 -│ │ │ │ ... -│ │ │ └── 00063 -│ │ ├── executor.json -│ │ ├── logs -│ │ │ ├── task_00000.log -│ │ │ ├── task_00001.log -│ │ │ ├── task_00002.log -│ │ │ ├── task_00003.log -│ │ │ ├── task_00004.log -│ │ │ ├── task_00005.log -│ │ │ │ ... -│ │ │ └── task_00063.log -│ │ ├── stats -│ │ │ ├── 00000.json -│ │ │ ├── 00001.json -│ │ │ ├── 00002.json -│ │ │ ├── 00003.json -│ │ │ ├── 00004.json -│ │ │ ├── 00005.json -│ │ │ │ ... -│ │ │ └── 00063.json -│ │ └── stats.json -│ ├── fineweb_edu_10bt.chunk.00000.jsonl -│ │ ... -│ ├── fineweb_edu_10bt.chunk.00013.jsonl -│ ├── sample -│ │ └── 10BT -│ │ ├── 000_00000.parquet -│ │ │ ... -│ │ └── 013_00000.parquet -│ └── terashuf -│ ├── LICENSE -│ ├── Makefile -│ ├── README.md -│ ├── terashuf -│ └── terashuf.cc -└── fineweb_edu_10bt_shuffled - ├── fineweb_edu_10bt.chunk.00.jsonl - └── fineweb_edu_10bt.val.jsonl -``` - -## Preprocess to a Megatron Core Dataset -NeMo AutoModel provides tooling to perform the task of tokenizing and saving in the Megatron Core dataset format. You can use it as follows: - -```bash -uv run tools/preprocess_megatron_dataset.py --input "fineweb_edu/fineweb_edu_10bt/fineweb_edu_10bt.chunk.*.jsonl" --json-keys text --output-prefix processed_data --output-path fineweb_edu/megatron_gpt2/ --workers 8 --pretrained-model-name-or-path openai-community/gpt2 --append-eod -``` - -The directory should look like this: -```bash -$ tree fineweb_edu/megatron_gpt2/ -fineweb_edu/megatron_gpt2/ -├── processed_data_0_text_document.bin -├── processed_data_0_text_document.idx -├── processed_data_10_text_document.bin -├── processed_data_10_text_document.idx -├── processed_data_11_text_document.bin -├── processed_data_11_text_document.idx -├── processed_data_12_text_document.bin -├── processed_data_12_text_document.idx -├── processed_data_13_text_document.bin -├── processed_data_13_text_document.idx -├── processed_data_1_text_document.bin -├── processed_data_1_text_document.idx -├── processed_data_2_text_document.bin -├── processed_data_2_text_document.idx -├── processed_data_3_text_document.bin -├── processed_data_3_text_document.idx -├── processed_data_4_text_document.bin -├── processed_data_4_text_document.idx -├── processed_data_5_text_document.bin -├── processed_data_5_text_document.idx -├── processed_data_6_text_document.bin -├── processed_data_6_text_document.idx -├── processed_data_7_text_document.bin -├── processed_data_7_text_document.idx -├── processed_data_8_text_document.bin -├── processed_data_8_text_document.idx -├── processed_data_9_text_document.bin -└── processed_data_9_text_document.idx - -1 directory, 28 files -``` - - -Replace `--workers` with the amount of CPU cores you'd like to use to tokenize in parallel. - - - -## Use a Recipe for Pretraining - -This example demonstrates how to perform pretraining on a large language model using NVIDIA's NeMo AutoModel library. We use the LLM [training recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/recipes/llm/train_ft.py), specifically `TrainFinetuneRecipeForNextTokenPrediction`, which orchestrates the pretraining process — including loading, dataset preparation, optimizer setup, distributed training, checkpointing, and logging. - -### What is a Recipe? - -A recipe in NeMo AutoModel is a **self-contained orchestration module** that wires together all -components needed to perform a specific task (e.g., pretraining). -Think of it as the equivalent of a Trainer class, but highly modular, stateful, and reproducible. - -The `TrainFinetuneRecipeForNextTokenPrediction` class is one such recipe. It inherits from `BaseRecipe` and implements: - -- `setup()`: builds all training components from the config - -- `run_train_validation_loop()`: executes training + validation steps - -- Misc: Checkpoint handling, logging, and RNG setup. - -### Recipe Config Example - -Below is the configuration from `examples/llm_pretrain/megatron_pretrain_gpt2.yaml`: - -```yaml -# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# To run this recipe, please use the following command: -# torchrun --nproc-per-node=8 examples/llm_pretrain/pretrain.py --config examples/llm_pretrain/megatron_pretrain_gpt2.yaml -# Adjust --nproc-per-node to the number of GPUs available on your host machine. - -# The model section is responsible for configuring the model we want to finetune. -# Since we want to use the GPT2-124M model, we pass `openai-community/gpt2` to the -# `pretrained_model_name_or_path` option. -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_config - config: - _target_: transformers.AutoConfig.from_pretrained - pretrained_model_name_or_path: openai-community/gpt2 - -# As mentioned earlier, we are using the FineWeb-Edu dataset. NeMo AutoModel provides the MegatronPretraining -# class which prepares the dataset by loading, packing, and shuffling. We use the "train" split for -# training. -dataset: - _target_: nemo_automodel.components.datasets.llm.megatron_dataset.MegatronPretraining - paths: fineweb_edu/megatron_gpt2/processed_data_*_text_document* # REPLACE THIS - index_mapping_dir: fineweb_edu/megatron_gpt2/mapping_dir # REPLACE THIS - tokenizer: - _target_: nemo_automodel._transformers.auto_tokenizer.NeMoAutoTokenizer.from_pretrained - pretrained_model_name_or_path: openai-community/gpt2 - seq_length: 1024 - split: "0.99, 0.01, 0.00" # train, validation, test - splits_to_build: "train" # has to be one of train, validation, test - -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: torch.utils.data.default_collate - dataloader_type: "single" # or "cyclic" - -# Similarly, for validation we use the "validation" split -validation_dataset: - _target_: nemo_automodel.components.datasets.llm.megatron_dataset.MegatronPretraining - paths: fineweb_edu/megatron_gpt2/processed_data_*_text_document* # REPLACE THIS - index_mapping_dir: fineweb_edu/megatron_gpt2/mapping_dir # REPLACE THIS - tokenizer: - _target_: nemo_automodel._transformers.auto_tokenizer.NeMoAutoTokenizer.from_pretrained - pretrained_model_name_or_path: openai-community/gpt2 - seq_length: 1024 - split: "0.99, 0.01, 0.00" # train, validation, test - splits_to_build: "validation" # has to be one of train, validation, test - num_val_samples: 1024 - -step_scheduler: - global_batch_size: 512 - local_batch_size: 32 - ckpt_every_steps: 1000 # checkpoints state every 1000 steps - val_every_steps: 250 # validates every 250 steps - num_epochs: 1 - max_steps: 18500 - -dist_env: - backend: nccl - timeout_minutes: 1 - -rng: - _target_: nemo_automodel.components.training.rng.StatefulRNG - seed: 1111 - ranked: true - -checkpoint: - enabled: true - checkpoint_dir: checkpoints/ - model_save_format: torch_save # torch_save or safetensors - save_consolidated: false # saves the model in a consolidated safetensors format. Requires model_save_format to be safetensors. - -# For distributed processing, we use FSDP2. -distributed: - strategy: fsdp2 - dp_size: null - dp_replicate_size: null # dp_shard_size = dp_size / dp_replicate_size when set. For DDP use strategy: ddp. - tp_size: 1 - cp_size: 1 - sequence_parallel: false - -loss_fn: - _target_: nemo_automodel.components.loss.masked_ce.MaskedCrossEntropy - -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: torch.utils.data.default_collate - -validation_dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: torch.utils.data.default_collate - -# We will use the standard AdamW optimizer, but you can specify any optimizer you want, by changing -# the import path using the _target_ option. -optimizer: - _target_: torch.optim.AdamW - betas: [0.9, 0.95] - lr: 0.0006 - weight_decay: 0.1 - -# We will use a cosine LR schedule with 700 warm-up steps. -# This means the LR will linearly increase to a maximum of 6e-4, after which -# it will decay to 0 over the course of training. -lr_scheduler: - lr_decay_style: cosine - lr_warmup_steps: 700 - min_lr: 0.0 - -# Uncomment and configure for W&B logging -# wandb: -# project: -# entity: -# name: -# save_dir: - -``` - -If you want to add weights to the dataset blends, you can do so by passing in a list. For example, `paths: ["30", "fineweb_edu/megatron_gpt2/processed_data_0_text_document", "70", "fineweb_edu/megatron_gpt2/processed_data_1_text_document"]`. - - - -## Load Large Models -In distributed training, the typical model-loading pipeline has each GPU load the entire model and then retain only the shard it needs. This approach becomes problematic when the model size exceeds the memory capacity of a single GPU. For instance, a 70B-parameter model requires about 140GB of memory for its parameters when using the BF16 data type (2 bytes per parameter). Since most widely used GPUs are limited to 80GB, the full model cannot be directly loaded onto a single device. - -In these scenarios, you can pass `is_meta_device: true` in the model config. The model will then be instantiated using [PyTorch's Meta device](https://docs.pytorch.org/docs/stable/meta.html) which loads no data, but stores all other parameter metadata necessary for sharding the model. Once the model is sharded, the model weights will be populated by only loading the weights required by the respective model shard. - -## Run the Pretraining Recipe - -Assuming you saved, or plan to use, the provided config at `examples/llm_pretrain/megatron_pretrain_gpt2.yaml`: - -```bash -uv run torchrun --nproc-per-node=2 examples/llm_pretrain/pretrain.py --config examples/llm_pretrain/megatron_pretrain_gpt2.yaml -``` - -### Sample Output - -You should see step‑wise logs reporting loss, memory usage, and tokens per second. Checkpoints will be saved under the `checkpoints/` directory as configured. - -```bash -$ uv run torchrun --nproc-per-node=2 examples/llm_pretrain/pretrain.py --config examples/llm_pretrain/megatron_pretrain_gpt2.yaml -cfg-path: examples/llm_pretrain/megatron_pretrain_gpt2.yaml -cfg-path: examples/llm_pretrain/megatron_pretrain_gpt2.yaml -> initializing torch distributed with 2 workers. -2025-09-01 07:13:17 | INFO | nemo_automodel.components.loggers.log_utils | Setting logging level to 20 -2025-09-01 07:13:17 | INFO | root | Experiment_details: -2025-09-01 07:13:17 | INFO | root | Timestamp: '2025-09-01T07:13:17' -2025-09-01 07:13:17 | INFO | root | User: root -2025-09-01 07:13:17 | INFO | root | Host: 9126f6644eca -2025-09-01 07:13:17 | INFO | root | World size: 2 -2025-09-01 07:13:17 | INFO | root | Backend: nccl -2025-09-01 07:13:17 | INFO | root | Recipe: TrainFinetuneRecipeForNextTokenPrediction -2025-09-01 07:13:17 | INFO | root | Model name: null -2025-09-01 07:13:17 | INFO | root | Recipe config: -2025-09-01 07:13:17 | INFO | root | step_scheduler: -2025-09-01 07:13:17 | INFO | root | global_batch_size: 512 -2025-09-01 07:13:17 | INFO | root | local_batch_size: 32 -2025-09-01 07:13:17 | INFO | root | ckpt_every_steps: 1000 -2025-09-01 07:13:17 | INFO | root | val_every_steps: 250 -2025-09-01 07:13:17 | INFO | root | num_epochs: 1 -2025-09-01 07:13:17 | INFO | root | max_steps: 18500 -2025-09-01 07:13:17 | INFO | root | dist_env: -2025-09-01 07:13:17 | INFO | root | backend: nccl -2025-09-01 07:13:17 | INFO | root | timeout_minutes: 1 -2025-09-01 07:13:17 | INFO | root | rng: -2025-09-01 07:13:17 | INFO | root | _target_: -2025-09-01 07:13:17 | INFO | root | seed: 1111 -2025-09-01 07:13:17 | INFO | root | ranked: True -2025-09-01 07:13:17 | INFO | root | model: -2025-09-01 07:13:17 | INFO | root | _target_: > -2025-09-01 07:13:17 | INFO | root | config: -2025-09-01 07:13:17 | INFO | root | _target_: > -2025-09-01 07:13:17 | INFO | root | pretrained_model_name_or_path: openai-community/gpt2 -2025-09-01 07:13:17 | INFO | root | checkpoint: -2025-09-01 07:13:17 | INFO | root | enabled: True -2025-09-01 07:13:17 | INFO | root | checkpoint_dir: checkpoints/ -2025-09-01 07:13:17 | INFO | root | model_save_format: torch_save -2025-09-01 07:13:17 | INFO | root | save_consolidated: False -2025-09-01 07:13:17 | INFO | root | distributed: -2025-09-01 07:13:17 | INFO | root | strategy: fsdp2 -2025-09-01 07:13:17 | INFO | root | dp_size: None -2025-09-01 07:13:17 | INFO | root | dp_replicate_size: None -2025-09-01 07:13:17 | INFO | root | tp_size: 1 -2025-09-01 07:13:17 | INFO | root | cp_size: 1 -2025-09-01 07:13:17 | INFO | root | sequence_parallel: False -2025-09-01 07:13:17 | INFO | root | loss_fn: -2025-09-01 07:13:17 | INFO | root | _target_: -2025-09-01 07:13:17 | INFO | root | dataset: -2025-09-01 07:13:17 | INFO | root | _target_: -2025-09-01 07:13:17 | INFO | root | paths: fineweb_edu/megatron_gpt2/processed_data_*_text_document* -2025-09-01 07:13:17 | INFO | root | index_mapping_dir: fineweb_edu/megatron_gpt2/mapping_dir -2025-09-01 07:13:17 | INFO | root | tokenizer: -2025-09-01 07:13:17 | INFO | root | _target_: > -2025-09-01 07:13:17 | INFO | root | pretrained_model_name_or_path: openai-community/gpt2 -2025-09-01 07:13:17 | INFO | root | seq_length: 1024 -2025-09-01 07:13:17 | INFO | root | split: (0.99, 0.01, 0.0) -2025-09-01 07:13:17 | INFO | root | splits_to_build: train -2025-09-01 07:13:17 | INFO | root | dataloader: -2025-09-01 07:13:17 | INFO | root | _target_: -2025-09-01 07:13:17 | INFO | root | collate_fn: -2025-09-01 07:13:17 | INFO | root | validation_dataset: -2025-09-01 07:13:17 | INFO | root | _target_: -2025-09-01 07:13:17 | INFO | root | paths: fineweb_edu/megatron_gpt2/processed_data_*_text_document* -2025-09-01 07:13:17 | INFO | root | index_mapping_dir: fineweb_edu/megatron_gpt2/mapping_dir -2025-09-01 07:13:17 | INFO | root | tokenizer: -2025-09-01 07:13:17 | INFO | root | _target_: > -2025-09-01 07:13:17 | INFO | root | pretrained_model_name_or_path: openai-community/gpt2 -2025-09-01 07:13:17 | INFO | root | seq_length: 1024 -2025-09-01 07:13:17 | INFO | root | split: (0.99, 0.01, 0.0) -2025-09-01 07:13:17 | INFO | root | splits_to_build: validation -2025-09-01 07:13:17 | INFO | root | num_val_samples: 1024 -2025-09-01 07:13:17 | INFO | root | validation_dataloader: -2025-09-01 07:13:17 | INFO | root | _target_: -2025-09-01 07:13:17 | INFO | root | collate_fn: -2025-09-01 07:13:17 | INFO | root | optimizer: -2025-09-01 07:13:17 | INFO | root | _target_: -2025-09-01 07:13:17 | INFO | root | betas: [0.9, 0.95] -2025-09-01 07:13:17 | INFO | root | lr: 0.0006 -2025-09-01 07:13:17 | INFO | root | weight_decay: 0.1 -2025-09-01 07:13:17 | INFO | root | lr_scheduler: -2025-09-01 07:13:17 | INFO | root | lr_decay_style: cosine -2025-09-01 07:13:17 | INFO | root | lr_warmup_steps: 700 -2025-09-01 07:13:17 | INFO | root | min_lr: 0.0 -2025-09-01 07:13:17 | INFO | root | Library versions: -2025-09-01 07:13:17 | INFO | root | - nemo_automodel: 0.2.0rc0 (/opt/Automodel/nemo_automodel/__init__.py) -2025-09-01 07:13:17 | INFO | root | - transformers: 4.55.4 (/opt/venv/lib/python3.12/site-packages/transformers/__init__.py) -2025-09-01 07:13:17 | INFO | root | - torch: 2.8.0+cu128 CUDA 12.8 -2025-09-01 07:13:27 | INFO | root | Patched model with SDPA method= [, , , ] -2025-09-01 07:13:27 | INFO | root | Model summary: -2025-09-01 07:13:27 | INFO | root | -------------------------------- -2025-09-01 07:13:27 | INFO | root | Trainable parameters: 124,439,808 -2025-09-01 07:13:27 | INFO | root | Total parameters: 124,439,808 -2025-09-01 07:13:27 | INFO | root | Trainable parameters percentage: 100.00% -2025-09-01 07:13:27 | INFO | root | Param L2 norm: 234.2000 -2025-09-01 07:13:27 | INFO | root | -------------------------------- -/opt/venv/lib/python3.12/site-packages/torch/distributed/distributed_c10d.py:4807: UserWarning: No device id is provided via `init_process_group` or `barrier `. Using the current device set by the user. - warnings.warn( # warn only once -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Let split_matrix = [(0, 0.99), (0.99, 1.0), None] -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.builder | Building GPTDataset splits with sizes=[9472000, 37888, None] and config=[random_seed: 1234, sequence_length: 1024, blend: [['fineweb_edu/megatron_gpt2/processed_data_0_text_document', 'fineweb_edu/megatron_gpt2/processed_data_10_text_document', 'fineweb_edu/megatron_gpt2/processed_data_11_text_document', 'fineweb_edu/megatron_gpt2/processed_data_12_text_document', 'fineweb_edu/megatron_gpt2/processed_data_13_text_document', 'fineweb_edu/megatron_gpt2/processed_data_1_text_document', 'fineweb_edu/megatron_gpt2/processed_data_2_text_document', 'fineweb_edu/megatron_gpt2/processed_data_3_text_document', 'fineweb_edu/megatron_gpt2/processed_data_4_text_document', 'fineweb_edu/megatron_gpt2/processed_data_5_text_document', 'fineweb_edu/megatron_gpt2/processed_data_6_text_document', 'fineweb_edu/megatron_gpt2/processed_data_7_text_document', 'fineweb_edu/megatron_gpt2/processed_data_8_text_document', 'fineweb_edu/megatron_gpt2/processed_data_9_text_document'], None], blend_per_split: None, split: 0.99, 0.01, 0.0, num_dataset_builder_threads: 1, path_to_cache: fineweb_edu/megatron_gpt2/mapping_dir, mmap_bin_files: True, tokenizer: openai-community/gpt2, mid_level_dataset_surplus: 0.005, reset_position_ids: False, reset_attention_mask: False, eod_mask_loss: False, create_attention_mask: False, drop_last_partial_validation_sequence: True, add_extra_token_to_sequence: True, split_matrix: [(0, 0.99), (0.99, 1.0), None]] -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_0_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 713000 | Documents: 713000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 728328 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_10_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 734000 | Documents: 734000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 725047 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_11_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 724000 | Documents: 724000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 726124 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_12_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 745000 | Documents: 745000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 723682 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_13_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 738000 | Documents: 738000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 725268 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_1_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 727000 | Documents: 727000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 726263 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_2_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 730000 | Documents: 730000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 726543 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_3_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 725000 | Documents: 725000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 726632 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_4_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 732000 | Documents: 732000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 726860 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_5_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 726000 | Documents: 726000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 727143 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_6_text_document.idx -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 735000 | Documents: 735000 -2025-09-01 07:13:28 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 725603 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_7_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 732000 | Documents: 732000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 726076 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_8_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 182101 | Documents: 182101 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 182792 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_9_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 729000 | Documents: 729000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset train indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 726153 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -/opt/venv/lib/python3.12/site-packages/torch/distributed/distributed_c10d.py:4807: UserWarning: No device id is provided via `init_process_group` or `barrier `. Using the current device set by the user. - warnings.warn( # warn only once -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.builder | Build and save the BlendedDataset indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.builder | Build and save the dataset and dataset sample indexes -2025-09-01 07:13:29 | INFO | root | Instantiating MegatronPretrainingSampler with total_samples: 9472000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Let split_matrix = [(0, 0.99), (0.99, 1.0), None] -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.builder | Building GPTDataset splits with sizes=[9472000, 1024, None] and config=[random_seed: 1234, sequence_length: 1024, blend: [['fineweb_edu/megatron_gpt2/processed_data_0_text_document', 'fineweb_edu/megatron_gpt2/processed_data_10_text_document', 'fineweb_edu/megatron_gpt2/processed_data_11_text_document', 'fineweb_edu/megatron_gpt2/processed_data_12_text_document', 'fineweb_edu/megatron_gpt2/processed_data_13_text_document', 'fineweb_edu/megatron_gpt2/processed_data_1_text_document', 'fineweb_edu/megatron_gpt2/processed_data_2_text_document', 'fineweb_edu/megatron_gpt2/processed_data_3_text_document', 'fineweb_edu/megatron_gpt2/processed_data_4_text_document', 'fineweb_edu/megatron_gpt2/processed_data_5_text_document', 'fineweb_edu/megatron_gpt2/processed_data_6_text_document', 'fineweb_edu/megatron_gpt2/processed_data_7_text_document', 'fineweb_edu/megatron_gpt2/processed_data_8_text_document', 'fineweb_edu/megatron_gpt2/processed_data_9_text_document'], None], blend_per_split: None, split: 0.99, 0.01, 0.0, num_dataset_builder_threads: 1, path_to_cache: fineweb_edu/megatron_gpt2/mapping_dir, mmap_bin_files: True, tokenizer: openai-community/gpt2, mid_level_dataset_surplus: 0.005, reset_position_ids: False, reset_attention_mask: False, eod_mask_loss: False, create_attention_mask: False, drop_last_partial_validation_sequence: True, add_extra_token_to_sequence: True, split_matrix: [(0, 0.99), (0.99, 1.0), None]] -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_0_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 713000 | Documents: 713000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7221 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_10_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 734000 | Documents: 734000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7215 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_11_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 724000 | Documents: 724000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7502 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_12_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 745000 | Documents: 745000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7209 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_13_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 738000 | Documents: 738000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7453 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_1_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 727000 | Documents: 727000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7492 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_2_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 730000 | Documents: 730000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7464 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_3_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 725000 | Documents: 725000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7362 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_4_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 732000 | Documents: 732000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7520 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_5_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 726000 | Documents: 726000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7326 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_6_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 735000 | Documents: 735000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7498 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_7_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 732000 | Documents: 732000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7531 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_8_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 182101 | Documents: 182101 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 1912 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Loading index file fineweb_edu/megatron_gpt2/processed_data_9_text_document.idx -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence lengths -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting sequence pointers -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Extracting document indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.indexed_dataset | Sequences: 729000 | Documents: 729000 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | Build and save the GPTDataset valid indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of samples: 7462 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.gpt_dataset | > total number of epochs: 1 -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.builder | Build and save the BlendedDataset indices -2025-09-01 07:13:29 | INFO | nemo_automodel.components.datasets.llm.megatron.builder | Build and save the dataset and dataset sample indexes -2025-09-01 07:13:29 | INFO | root | Instantiating MegatronPretrainingSampler with total_samples: 1024 -2025-09-01 07:13:29 | INFO | nemo_automodel.recipes.llm.train_ft | Building LR scheduler with total_steps=18500, warmup_steps=700, decay_style=cosine -2025-09-01 07:13:29 | INFO | nemo_automodel.components.optim.scheduler | learning rate decay style: cosine -2025-09-01 07:13:29 | INFO | root | Model Part 0: -2025-09-01 07:13:29 | INFO | root | FSDPGPT2LMHeadModel( -2025-09-01 07:13:29 | INFO | root | (transformer): GPT2Model( -2025-09-01 07:13:29 | INFO | root | (wte): Embedding(50257, 768) -2025-09-01 07:13:29 | INFO | root | (wpe): Embedding(1024, 768) -2025-09-01 07:13:29 | INFO | root | (drop): Dropout(p=0.1, inplace=False) -2025-09-01 07:13:29 | INFO | root | (h): ModuleList( -2025-09-01 07:13:29 | INFO | root | (0-11): 12 x FSDPGPT2Block( -2025-09-01 07:13:29 | INFO | root | (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True) -2025-09-01 07:13:29 | INFO | root | (attn): GPT2Attention( -2025-09-01 07:13:29 | INFO | root | (c_attn): Conv1D(nf=2304, nx=768) -2025-09-01 07:13:29 | INFO | root | (c_proj): Conv1D(nf=768, nx=768) -2025-09-01 07:13:29 | INFO | root | (attn_dropout): Dropout(p=0.1, inplace=False) -2025-09-01 07:13:29 | INFO | root | (resid_dropout): Dropout(p=0.1, inplace=False) -2025-09-01 07:13:29 | INFO | root | ) -2025-09-01 07:13:29 | INFO | root | (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True) -2025-09-01 07:13:29 | INFO | root | (mlp): GPT2MLP( -2025-09-01 07:13:29 | INFO | root | (c_fc): Conv1D(nf=3072, nx=768) -2025-09-01 07:13:29 | INFO | root | (c_proj): Conv1D(nf=768, nx=3072) -2025-09-01 07:13:29 | INFO | root | (act): NewGELUActivation() -2025-09-01 07:13:29 | INFO | root | (dropout): Dropout(p=0.1, inplace=False) -2025-09-01 07:13:29 | INFO | root | ) -2025-09-01 07:13:29 | INFO | root | ) -2025-09-01 07:13:29 | INFO | root | ) -2025-09-01 07:13:29 | INFO | root | (ln_f): LayerNorm((768,), eps=1e-05, elementwise_affine=True) -2025-09-01 07:13:29 | INFO | root | ) -2025-09-01 07:13:29 | INFO | root | (lm_head): Linear(in_features=768, out_features=50257, bias=False) -2025-09-01 07:13:29 | INFO | root | ) -2025-09-01 07:13:29 | INFO | root | Optimizer: -2025-09-01 07:13:29 | INFO | root | AdamW ( -2025-09-01 07:13:29 | INFO | root | Parameter Group 0 -2025-09-01 07:13:29 | INFO | root | amsgrad: False -2025-09-01 07:13:29 | INFO | root | betas: [0.9, 0.95] -2025-09-01 07:13:29 | INFO | root | capturable: False -2025-09-01 07:13:29 | INFO | root | decoupled_weight_decay: True -2025-09-01 07:13:29 | INFO | root | differentiable: False -2025-09-01 07:13:29 | INFO | root | eps: 1e-08 -2025-09-01 07:13:29 | INFO | root | foreach: None -2025-09-01 07:13:29 | INFO | root | fused: None -2025-09-01 07:13:29 | INFO | root | lr: 5.9999999999999995e-05 -2025-09-01 07:13:29 | INFO | root | maximize: False -2025-09-01 07:13:29 | INFO | root | weight_decay: 0.1 -2025-09-01 07:13:29 | INFO | root | ) -2025-09-01 07:13:29 | INFO | root | LR scheduler: -2025-09-01 07:13:29 | INFO | root | OptimizerParamScheduler( -2025-09-01 07:13:29 | INFO | root | optimizer: AdamW -2025-09-01 07:13:29 | INFO | root | learning_rate: -2025-09-01 07:13:29 | INFO | root | init_lr: 5.9999999999999995e-05 -2025-09-01 07:13:29 | INFO | root | max_lr: 0.0006 -2025-09-01 07:13:29 | INFO | root | min_lr: 0.0 -2025-09-01 07:13:29 | INFO | root | warmup_steps: 700 -2025-09-01 07:13:29 | INFO | root | decay_steps: 18500 -2025-09-01 07:13:29 | INFO | root | decay_style: cosine -2025-09-01 07:13:29 | INFO | root | weight_decay: -2025-09-01 07:13:29 | INFO | root | start_wd: 0.1 -2025-09-01 07:13:29 | INFO | root | end_wd: 0.1 -2025-09-01 07:13:29 | INFO | root | incr_steps: 18500 -2025-09-01 07:13:29 | INFO | root | incr_style: constant -2025-09-01 07:13:29 | INFO | root | current_step: 0 -2025-09-01 07:13:29 | INFO | root | ) -2025-09-01 07:13:29 | INFO | root | Step scheduler: -2025-09-01 07:13:29 | INFO | root | - Gradient accumulation steps: 8 -2025-09-01 07:13:29 | INFO | root | - Checkpoint every steps: 1000 -2025-09-01 07:13:29 | INFO | root | - Current Epoch: 0 -2025-09-01 07:13:29 | INFO | root | - Number of epochs: 1 -2025-09-01 07:13:29 | INFO | root | - Validation every steps: 250 -2025-09-01 07:13:29 | INFO | root | - Max train steps: 18500 -2025-09-01 07:13:33 | INFO | root | step 1 | epoch 0 | loss 10.9521 | grad_norm 12.9375 | lr 6.08e-05 | mem 38.39 GiB | tps 132005.57(66002.79/gpu) | num_label_tokens 524288 -2025-09-01 07:13:37 | INFO | root | step 2 | epoch 0 | loss 10.1146 | grad_norm 6.0312 | lr 6.15e-05 | mem 38.63 GiB | tps 146246.38(73123.19/gpu) | num_label_tokens 524288 -2025-09-01 07:13:41 | INFO | root | step 3 | epoch 0 | loss 9.7842 | grad_norm 3.0781 | lr 6.23e-05 | mem 38.63 GiB | tps 145236.76(72618.38/gpu) | num_label_tokens 524288 -2025-09-01 07:13:44 | INFO | root | step 4 | epoch 0 | loss 9.6514 | grad_norm 2.2812 | lr 6.31e-05 | mem 38.63 GiB | tps 144882.21(72441.11/gpu) | num_label_tokens 524288 -2025-09-01 07:13:48 | INFO | root | step 5 | epoch 0 | loss 9.5964 | grad_norm 2.2188 | lr 6.39e-05 | mem 38.63 GiB | tps 144711.55(72355.78/gpu) | num_label_tokens 524288 -``` -For each training batch, the fine-tuning recipe logs the current loss, along with current peak memory usage and tokens per second (TPS). - -As training progresses, you should observe the model loss beginning to converge. To verify your results, you can compare your convergence curves against the baseline benchmarks provided in the [llm.c repository](https://github.com/karpathy/llm.c/discussions/481). - - - Example of GPT-2 training convergence on FineWeb-Edu-10B - diff --git a/docs/fern/versions/nightly/pages/guides/llm/retrieval-dataset.mdx b/docs/fern/versions/nightly/pages/guides/llm/retrieval-dataset.mdx deleted file mode 100644 index b24fe17aed..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/retrieval-dataset.mdx +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: "Retrieval Dataset (Embedding Fine-tuning)" -description: "" -position: 3 ---- -NeMo Automodel supports **retrieval model fine-tuning** using a retrieval-style dataset: each training example is a **query** paired with **one positive** document and **one or more negative** documents. - -This dataset is used by the retrieval recipes (see `examples/retrieval/bi_encoder/` and `examples/retrieval/cross_encoder/`) together with the `BiEncoderCollator`. - -## What the Bi-Encoder Consumes - -The dataset factory `nemo_automodel.components.datasets.llm.make_retrieval_dataset` returns a Hugging Face `datasets.Dataset`. At runtime it transforms each raw record into the training-time schema: - -- `question`: query string -- `doc_text`: list of document texts in the order `[positive, negative_1, negative_2, ...]` -- `doc_image`: list of images (or empty strings), aligned with `doc_text` -- `query_instruction` / `passage_instruction`: optional, used when `use_dataset_instruction: true` and the corpus provides instructions via metadata - -## Supported Input Formats - -NeMo Automodel supports **two** input schemas: - -### Corpus ID-Based JSON (Merlin/NeMo-Retriever Style) - -This is the format used by NeMo retriever pipelines where documents live in a separate **corpus** and training examples reference documents by **ID**. - -**Training file example (single JSON):** - -```json -{ - "corpus": [ - { "path": "/abs/path/to/wiki_corpus" } - ], - "data": [ - { - "question_id": "q_001", - "question": "Explain transformers", - "corpus_id": "wiki_corpus", - "pos_doc": [{ "id": "d_123" }], - "neg_doc": [{ "id": "d_456" }, "d_789"] - } - ] -} -``` - -**Corpus requirements** - -Each corpus directory must contain a `merlin_metadata.json` file. - -Minimal example: - -```json -{ "class": "TextQADataset", "corpus_id": "wiki_corpus" } -``` - - -- `pos_doc` and `neg_doc` can be lists of `{"id": ...}` dicts or raw IDs (they are normalized internally). -- If you set `use_dataset_instruction: true`, optional fields like `query_instruction` and `passage_instruction` in `merlin_metadata.json` are surfaced to the collator. - - - -### Inline-Text JSONL (No Corpus Required) - -This is convenient for custom fine-tuning pipelines where the documents are included **inline**. - -**JSONL example (one example per line):** - -```json -{"query":"Explain transformers","pos_doc":"Transformers are a type of neural network...","neg_doc":["RNNs are...","CNNs are..."]} -{"query":"What is Python?","pos_doc":["A programming language."],"neg_doc":"A snake."} -``` - - -- `query` is accepted (`question` is also accepted as an alias). -- `pos_doc` and `neg_doc` can be either: - - strings (interpreted as document text), or - - lists of strings, or - - dicts with at least `text` (optionally `image`, `nr_ocr`) for multimodal use cases. -- If `corpus_id` is not provided, it defaults to `__inline__`. -- `use_dataset_instruction: true` has no effect for pure inline records (instructions come from corpus metadata). - - - -## YAML Usage (Dataset + Collator) - -Use the dataset factory plus the bi-encoder collator: - -```yaml -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - dataset: - _target_: nemo_automodel.components.datasets.llm.make_retrieval_dataset - data_dir_list: - - /abs/path/to/train.jsonl # or train.json (corpus-id format) - data_type: train - n_passages: 5 # 1 positive + 4 negatives - do_shuffle: true - use_dataset_instruction: false - collate_fn: - _target_: nemo_automodel.components.datasets.llm.BiEncoderCollator - q_max_len: 512 - p_max_len: 512 - query_prefix: "query:" - passage_prefix: "passage:" - pad_to_multiple_of: 8 -``` - -## Requirements - -- `pos_doc` must be **non-empty**. -- If training requests negatives (e.g., `n_passages > 1`), `neg_doc` must contain **at least one** document. diff --git a/docs/fern/versions/nightly/pages/guides/llm/sequence-classification.mdx b/docs/fern/versions/nightly/pages/guides/llm/sequence-classification.mdx deleted file mode 100644 index d3cbcae2a1..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/sequence-classification.mdx +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: "Sequence Classification (SFT/PEFT) with NeMo AutoModel" -description: "" -position: 10 ---- -## Introduction - -Sequence classification tasks (e.g., sentiment analysis, topic classification, GLUE tasks) map input text to a discrete label. NeMo AutoModel provides a lightweight recipe specialized for this setting that integrates with popular pretrained model formats and dataset sources. Integration with Hugging Face is supported. - -This guide shows how to train a sequence classification model using the `TrainFinetuneRecipeForSequenceClassification` recipe, including optional Parameter-Efficient Fine-Tuning (LoRA). - -## Quickstart - -Use the example config for GLUE MRPC with RoBERTa-large + LoRA: - -```bash -python3 examples/llm_seq_cls/seq_cls.py --config examples/llm_seq_cls/glue/mrpc_roberta_lora.yaml -``` - -- Loads `roberta-large` with `num_labels: 2` -- Builds GLUE MRPC datasets (train/validation) -- Optionally, enables LoRA via the `peft` block -- Trains and validates per `step_scheduler` - -## What is the Sequence Classification Recipe? - -`TrainFinetuneRecipeForSequenceClassification` is a config-driven trainer that orchestrates: -- Model and optimizer construction -- Dataset/Dataloader setup -- Training and validation loops -- Checkpointing and logging - -It follows the same design as the SFT recipe in the fine-tune guide, but uses a standard cross-entropy classification loss and a simplified batching pipeline. - -## Minimal Config Anatomy - -```yaml -# GLUE MRPC with RoBERTa-large + LoRA -step_scheduler: - global_batch_size: 32 - local_batch_size: 32 - ckpt_every_steps: 200 - val_every_steps: 100 - num_epochs: 2 - max_steps: 10 - -dist_env: - backend: nccl - timeout_minutes: 1 - -model: - _target_: nemo_automodel.NeMoAutoModelForSequenceClassification.from_pretrained - pretrained_model_name_or_path: roberta-large - num_labels: 2 - -checkpoint: - enabled: true - checkpoint_dir: checkpoints/ - model_save_format: safetensors - save_consolidated: true - -distributed: - strategy: fsdp2 - dp_size: null - dp_replicate_size: null - tp_size: 1 - cp_size: 1 - sequence_parallel: false - -peft: - _target_: nemo_automodel.components._peft.lora.PeftConfig - target_modules: - - "*.query" - - "*.value" - dim: 8 - alpha: 16 - dropout: 0.1 - -dataset: - _target_: nemo_automodel.components.datasets.llm.seq_cls.GLUE_MRPC - split: train - -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: nemo_automodel.components.datasets.utils.default_collater - -validation_dataset: - _target_: nemo_automodel.components.datasets.llm.seq_cls.GLUE_MRPC - split: validation - -validation_dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - collate_fn: nemo_automodel.components.datasets.utils.default_collater - -optimizer: - _target_: torch.optim.AdamW - betas: [0.9, 0.999] - eps: 1e-8 - lr: 3.0e-4 - weight_decay: 0 - -``` - -## Dataset Notes - -- For single-sentence datasets (e.g., `yelp_review_full`, `imdb`), use `YelpReviewFull` or `IMDB` from `nemo_automodel.components.datasets.llm.seq_cls`. -- For GLUE MRPC (sentence-pair classification), use `GLUE_MRPC`, which tokenizes `(sentence1, sentence2)` with padding/truncation. - -## LoRA (PEFT) Settings - -- `target_modules`: glob to select linear layers (e.g., `"*.proj"`). -- `dim` (rank), `alpha`, `dropout`: tune per model/compute budget. Values `dim=8, alpha=16, dropout=0.1` are a good starting point for RoBERTa. -- The recipe automatically applies the adapters; no additional code changes are required. - -## Running with torchrun - -```bash -torchrun --nproc-per-node=2 examples/llm_seq_cls/seq_cls.py --config examples/llm_seq_cls/glue/mrpc_roberta_lora.yaml -``` -You can adjust the number of GPUs as necessary using the `--nproc-per-node` knob. diff --git a/docs/fern/versions/nightly/pages/guides/llm/toolcalling.mdx b/docs/fern/versions/nightly/pages/guides/llm/toolcalling.mdx deleted file mode 100644 index 81eaa5fcc5..0000000000 --- a/docs/fern/versions/nightly/pages/guides/llm/toolcalling.mdx +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: "Function Calling with NeMo AutoModel using FunctionGemma" -description: "" -position: 3 ---- -This tutorial walks through fine-tuning [FunctionGemma](https://huggingface.co/google/functiongemma-270m-it), Google's 270M function-calling model, with NeMo AutoModel on the xLAM function-calling dataset. - -## FunctionGemma Introduction -FunctionGemma is a lightweight, 270M-parameter variant built on the Gemma 3 architecture with a function-calling chat format. It is intended to be fine-tuned for task-specific function calling, and its compact size makes it practical for edge or resource-constrained deployments. -- Gemma 3 architecture, updated tokenizer, and function-calling chat format. -- Trained specifically for function calling: multiple tool definitions, parallel calls, tool responses, and natural-language summaries. -- Small/edge friendly: ~270M params for fast, dense inference on-device. -- Text-only, function-oriented model (not a general dialogue model), best used after task-specific finetuning. - -## Prerequisites -- Install NeMo AutoModel and its extras: `pip install nemo-automodel`. -- A FunctionGemma checkpoint available locally or using [https://huggingface.co/google/functiongemma-270m-it](https://huggingface.co/google/functiongemma-270m-it). -- Small model footprint: can be fine-tuned on a single GPU; scale batch/sequence as needed. - -## xLAM Dataset -The xLAM function-calling dataset contains user queries, tool schemas, and tool call traces. It covers diverse tools and arguments so models learn to emit structured tool calls. -- Dataset URL: https://huggingface.co/datasets/Salesforce/xlam-function-calling-60k -- Each sample provides: - - `query`: the user request. - - `tools`: tool definitions (lightweight schema). - - `answers`: tool calls with serialized arguments. - -Example entry: -```json -{ - "id": 123, - "query": "Book me a table for two at 7pm in Seattle.", - "tools": [ - { - "name": "book_table", - "description": "Book a restaurant table", - "parameters": { - "party_size": {"type": "int"}, - "time": {"type": "string"}, - "city": {"type": "string"} - } - } - ], - "answers": [ - { - "name": "book_table", - "arguments": "{\"party_size\":2,\"time\":\"19:00\",\"city\":\"Seattle\"}" - } - ] -} -``` - -The helper `make_xlam_dataset` converts each xLAM row into OpenAI-style tool schemas and tool calls, then renders them through the chat template so loss is applied only on the tool-call arguments: - -```python -def _format_example( - example, - tokenizer, - eos_token_id, - pad_token_id, - seq_length=None, - padding=None, - truncation=None, -): - tools = _convert_tools(_json_load_if_str(example["tools"])) - tool_calls = _convert_tool_calls(_json_load_if_str(example["answers"]), example_id=example.get("id")) - - formatted_text = [ - {"role": "user", "content": example["query"]}, - {"role": "assistant", "content": "", "tool_calls": tool_calls}, - ] - - return format_chat_template( - tokenizer=tokenizer, - formatted_text=formatted_text, - tools=tools, - eos_token_id=eos_token_id, - pad_token_id=pad_token_id, - seq_length=seq_length, - padding=padding, - truncation=truncation, - answer_only_loss_mask=True, - ) -``` - -## Run Full-Parameter SFT -Use the ready-made config at [`examples/llm_finetune/gemma/functiongemma_xlam.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/functiongemma_xlam.yaml) to start fine-tuning: - -With the config in place, launch training (8 GPUs shown; adjust `--nproc-per-node` as needed): - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/gemma/functiongemma_xlam.yaml -``` - -You should be able to see a training loss curve similar to the one shown below: - -

- FunctionGemma SFT loss -

- -## Run PEFT (LoRA) -To apply LoRA (PEFT), uncomment the `peft` block in the config and tune rank/alpha/targets per the [SFT/PEFT guide](/recipes-e2e-examples/sft-peft). Example override: - -```yaml -peft: - _target_: nemo_automodel.components._peft.lora.PeftConfig - target_modules: '*_proj' - dim: 16 - alpha: 16 - use_triton: true -``` -Then fine-tune with the same recipe. Adjust the number of GPUs as needed. -```bash -automodel examples/llm_finetune/gemma/functiongemma_xlam.yaml -``` - -

- FunctionGemma PEFT loss -

diff --git a/docs/fern/versions/nightly/pages/guides/mlflow-logging.mdx b/docs/fern/versions/nightly/pages/guides/mlflow-logging.mdx deleted file mode 100644 index 6ba0c43b19..0000000000 --- a/docs/fern/versions/nightly/pages/guides/mlflow-logging.mdx +++ /dev/null @@ -1,260 +0,0 @@ ---- -title: "MLflow Logging in NeMo AutoModel" -description: "" -position: 5 ---- -## Introduction - -MLflow is an open-source platform for managing the machine learning lifecycle, including experiment tracking, model versioning, and deployment. NeMo AutoModel integrates with MLflow to log training metrics, parameters, and artifacts during model training. - -With MLflow integration, you can: -- Track and compare experiments across multiple runs -- Log hyperparameters and training configurations -- Monitor training and validation metrics in real-time -- Store model checkpoints and artifacts -- Visualize experiment results through the MLflow UI -- Share results with team members - -## Prerequisites - -Before using MLflow logging in NeMo AutoModel, ensure you have: - -1. **MLflow installed**: MLflow is installed with `nemo-automodel` by default. If you see an import error in your environment, install it manually: - ```bash - pip install mlflow - # or: - uv pip install mlflow - ``` - -2. **MLflow tracking server** (optional): For production use, set up a tracking server to centralize experiment data. For local development, MLflow will use a local file-based store by default. - -## Configuration - -Enable MLflow logging by adding an `mlflow` section to your recipe YAML configuration: - -```yaml -mlflow: - experiment_name: "automodel-llm-llama3_2_1b_squad-finetune" - run_name: "" - tracking_uri: null - artifact_location: null - tags: - task: "squad-finetune" - model_family: "llama3.2" - model_size: "1b" - dataset: "squad" - framework: "automodel" -``` - -### Configuration Parameters - -| Parameter | Type | Default | Description | -|-----------|------|---------|-------------| -| `experiment_name` | str | "automodel-experiment" | Name of the MLflow experiment. All runs are grouped under this experiment. | -| `run_name` | str | "" | Optional name for the current run. If empty, MLflow generates a unique name. | -| `tracking_uri` | str | null | URI of the MLflow tracking server. If null, uses local file-based storage. | -| `artifact_location` | str | null | Location to store artifacts. If null, uses default MLflow location. | -| `tags` | dict | {} | Dictionary of tags to attach to the run for organization and filtering. | - -### Tracking URI Options - -The `tracking_uri` parameter determines where MLflow stores experiment data: - -- **Local file storage (default)**: `null` or `file:///path/to/mlruns` -- **Remote tracking server**: `http://your-mlflow-server:5000` -- **Database backend**: `postgresql://user:password@host:port/database` - -For team collaboration, we recommend setting up a remote tracking server. - -## What Gets Logged - -NeMo AutoModel automatically logs the following information to MLflow: - -### Metrics -- Training loss at each step -- Validation loss and metrics -- Learning rate schedule -- Gradient norms (if gradient clipping is enabled) - -### Parameters -- Model configuration (architecture, size, pretrained checkpoint) -- Training hyperparameters (learning rate, batch size, optimizer settings) -- Dataset information -- Parallelism configuration (DP, TP, CP settings) - -### Tags -- Custom tags from configuration -- Automatically added tags: - - Model name from `pretrained_model_name_or_path` - - Global and local batch sizes - -### Artifacts -- Model checkpoints (if configured) -- Training configuration files - - -Only rank 0 in distributed training logs to MLflow to avoid duplicate entries and reduce overhead. - - - -## Usage Example - -Here's a complete example of training with MLflow logging enabled: - -### Configure Your Recipe - -Add the MLflow configuration to your YAML file (e.g., `llama3_2_1b_squad.yaml`): - -```yaml -step_scheduler: - global_batch_size: 64 - local_batch_size: 8 - ckpt_every_steps: 1000 - val_every_steps: 10 - num_epochs: 1 - -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - -mlflow: - experiment_name: "llama3-squad-finetune" - run_name: "baseline-run-1" - tracking_uri: null # Uses local storage - tags: - task: "question-answering" - dataset: "squad" - model: "llama-3.2-1b" -``` - -### Run Training - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -During training, you'll see MLflow logging messages: - -``` -MLflow run started: abc123def456 -View run at: file:///path/to/mlruns/#/experiments/1/runs/abc123def456 -``` - -### View Results in MLflow UI - -Launch the MLflow UI to visualize your experiments: - -```bash -mlflow ui -``` - -By default, the UI runs at `http://localhost:5000`. Open this URL in your browser to: -- Compare metrics across runs -- View parameter configurations -- Download artifacts -- Filter and search experiments by tags - -## Integration with Other Loggers - -MLflow can be used alongside other logging tools like Weights & Biases (WandB). Simply enable both in your configuration: - -```yaml -# Enable both MLflow and WandB -mlflow: - experiment_name: "my-experiment" - tags: - framework: "automodel" - -wandb: - project: "my-project" - entity: "my-team" - name: "my-run" -``` - -Both loggers will track the same metrics independently, allowing you to leverage the strengths of each platform. - -## Best Practices - -### Experiment Organization - -1. **Use descriptive experiment names**: Group related runs under meaningful experiment names. - ```yaml - experiment_name: "llama3-squad-ablation-study" - ``` - -2. **Tag your runs**: Add tags for easy filtering and comparison. - ```yaml - tags: - model_size: "1b" - learning_rate: "1e-5" - optimizer: "adam" - ``` - -3. **Use run names for variants**: Differentiate runs within an experiment. - ```yaml - run_name: "lr-1e5-bs64" - ``` - -### Remote Tracking Server - -For team collaboration, set up a shared MLflow tracking server: - -```yaml -mlflow: - tracking_uri: "http://mlflow-server.example.com:5000" - experiment_name: "team-llm-experiments" -``` - -### Artifact Storage - -For large-scale experiments, configure a dedicated artifact location: - -```yaml -mlflow: - artifact_location: "s3://my-bucket/mlflow-artifacts" -``` - -Supported storage backends include S3, Azure Blob Storage, Google Cloud Storage, and network file systems. - -### Performance Considerations - -- MLflow logging adds minimal overhead since only rank 0 logs. -- Metrics are logged asynchronously to avoid blocking training. -- For very frequent logging (every step), consider increasing `val_every_steps` to reduce I/O. - -## Troubleshooting - -### MLflow Not Installed - -If you see an import error: -``` -ImportError: MLflow is not installed. Please install it (e.g. pip install mlflow). -``` - -Install MLflow: -```bash -pip install mlflow -# or: -uv pip install mlflow -``` - -### Connection Issues - -If you can't connect to a remote tracking server: -- Verify the `tracking_uri` is correct -- Check network connectivity and firewall rules -- Ensure the tracking server is running - -### Missing Metrics - -If metrics aren't appearing in MLflow: -- Verify you're running on rank 0 or check rank 0 logs -- Ensure the MLflow run started successfully (check for "MLflow run started" message) -- Check that metrics are being computed during training - -## References - -- [MLflow Documentation](https://mlflow.org/docs/latest/index.html) -- [MLflow Tracking](https://mlflow.org/docs/latest/tracking.html) -- [MLflow Python API](https://mlflow.org/docs/latest/python_api/index.html) -- [NeMo AutoModel Examples](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples) diff --git a/docs/fern/versions/nightly/pages/guides/omni/gemma3-3n.mdx b/docs/fern/versions/nightly/pages/guides/omni/gemma3-3n.mdx deleted file mode 100644 index 6e658f44b9..0000000000 --- a/docs/fern/versions/nightly/pages/guides/omni/gemma3-3n.mdx +++ /dev/null @@ -1,327 +0,0 @@ ---- -title: "Fine-Tune Gemma 3 and Gemma 3n" -description: "" -position: 11 ---- -This document explains how to fine-tune Gemma 3 and Gemma 3n using NeMo AutoModel. It outlines key operations, including initiating SFT and PEFT-LoRA runs and managing experiment configurations using YAML. - -To set up your environment to run NeMo AutoModel, follow the [Installation Guide](https://github.com/NVIDIA-NeMo/Automodel#-install-nemo-automodel). - -## Data - -### MedPix-VQA Dataset - -The [MedPix-VQA](https://huggingface.co/datasets/mmoukouba/MedPix-VQA) dataset is a comprehensive medical Visual Question-Answering dataset designed for training and evaluating VQA models in the medical domain. It contains medical images from MedPix, a well-known medical image database, paired with questions and answers that focus on medical image interpretation. - -The dataset consists of 20,500 examples with the following structure: -- **Training Set**: 17,420 examples (85%) -- **Validation Set**: 3,080 examples (15%) -- **Columns**: `image_id`, `mode`, `case_id`, `question`, `answer` - -### Preprocess the Dataset - -NeMo AutoModel provides built-in preprocessing for the MedPix-VQA dataset through the `make_medpix_dataset` function. Here's how the preprocessing works: - -```python -from nemo_automodel.components.datasets.vlm.datasets import make_medpix_dataset - -# Load and preprocess the dataset -dataset = make_medpix_dataset( - path_or_dataset="mmoukouba/MedPix-VQA", - split="train" -) -``` - -The preprocessing pipeline performs the following steps: - -1. **Loads the dataset** using the Hugging Face `datasets` library. -2. **Extracts question-answer pairs** by processing the `question` and `answer` fields from the dataset. -3. **Converts to the Hugging Face message list format** to restructure the data into a chat-style format compatible with the Autoprocessor's `apply_chat_template` function. - -```python -# Example of the conversation format created -conversation = [ - { - "role": "user", - "content": [ - {"type": "image", "image": example["image_id"]}, - {"type": "text", "text": example["question"]}, - ], - }, - { - "role": "assistant", - "content": [{"type": "text", "text": example["answer"]}] - }, -] -``` - -### Use the Collate Functions - -NeMo AutoModel provides specialized collate functions for different VLM processors. The collate function is responsible for batching examples and preparing them for model input. - -Both Gemma 3 and Gemma 3n models work seamlessly with the Hugging Face `AutoProcessor` and use the default collate function: - -```python -processor = AutoProcessor.from_pretrained("google/gemma-3-4b-it") -# For Gemma 3n, get processor: -# processor = AutoProcessor.from_pretrained("google/gemma-3n-e4b-it") - -# For Gemma 3 and Gemma 3n, use the default collate function -def default_collate_fn(examples: list, processor) -> dict[str, torch.Tensor]: - batch = processor.apply_chat_template( - [example["conversation"] for example in examples], - tokenize=True, - add_generation_prompt=False, - return_tensors="pt", - return_dict=True, - ) - - labels = batch["input_ids"].clone()[:, 1:] - labels = torch.cat([labels, -100 * torch.ones_like(labels[:, :1])], dim=1) - batch["labels"] = labels - loss_mask = create_batch_loss_masks( - batch["input_ids"], processor, start_of_response_token=start_of_response_token - ) - batch["loss_mask"] = loss_mask - - return batch -``` - -The default collate function: -- Applies the processor's chat template to convert message lists into model-ready inputs. -- Creates labels for training to guide supervised learning. -- Masks prompts and special tokens so that only answer tokens are considered during loss calculation. - -### Preprocess Custom Datasets - -When using a custom dataset with a model whose Hugging Face `AutoProcessor` supports the `apply_chat_template` method, you'll need to convert your data into the Hugging Face message list format expected by the `apply_chat_template`. -We provide [examples](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/vlm/datasets.py) demonstrating how to perform this conversion. - -Some models, such as [Qwen2.5 VL](https://huggingface.co/Qwen/Qwen2.5-VL-3B-Instruct), have specific preprocessing requirements and require custom collate functions. For instance, Qwen2.5-VL uses the `qwen_vl_utils.process_vision_info` function to process images: - -```python - -texts = [processor.apply_chat_template(example["conversation"], tokenize=False) for example in examples] -image_inputs = [process_vision_info(example["conversation"])[0] for example in examples] - -batch = processor( - text=texts, - images=image_inputs, - padding=True, - return_tensors="pt", -) - -``` -If your dataset requires custom preprocessing logic, you can define a custom collate function. To use it, specify the function in your YAML configuration: - -```yaml -dataloader: - _target_: torchdata.stateful_dataloader.StatefulDataLoader - batch_size: 1 - collate_fn: - _target_: nemo_automodel.components.datasets.vlm.collate_fns.qwen2_5_collate_fn -``` - -We provide [example custom collate functions](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/vlm/collate_fns.py) that you can use as references for your implementation. - -## Run the Fine-Tune Script - -Use the `automodel` CLI to launch fine-tuning with a YAML configuration file. - -### Apply YAML-Based Configuration - -NeMo AutoModel uses a flexible configuration system that combines YAML configuration files with command-line overrides. This allows you to maintain base configurations while easily experimenting with different parameters. - -The simplest way to run fine-tuning is with a YAML configuration file. We provide configs for both Gemma 3 and Gemma 3n. - - -These VLM recipes require the optional `vlm` dependency set. If you see `ImportError: qwen_vl_utils is not installed`, install VLM dependencies first: - -```bash -uv sync --frozen --extra vlm -``` - -(If you're using pip: `pip3 install "nemo-automodel[vlm]"`.) - - - -#### Run Gemma 3 Fine-Tuning - -* **Single-GPU** - -```bash -automodel examples/vlm_finetune/gemma3/gemma3_vl_4b_medpix.yaml -``` - -* **Multi-GPU** - -```bash -automodel --nproc-per-node=2 examples/vlm_finetune/gemma3/gemma3_vl_4b_medpix.yaml -``` - -#### Run Gemma 3n Fine-Tuning - -* **Single-GPU** - -```bash -automodel examples/vlm_finetune/gemma3n/gemma3n_vl_4b_medpix.yaml -``` - -* **Multi-GPU** - -```bash -automodel --nproc-per-node=2 examples/vlm_finetune/gemma3n/gemma3n_vl_4b_medpix.yaml -``` - -#### Override Configuration Parameters - -You can override any configuration parameter using dot-notation without modifying the YAML file: - -```bash -automodel examples/vlm_finetune/gemma3/gemma3_vl_4b_medpix.yaml \ - --step_scheduler.ckpt_every_steps 100 \ - --step_scheduler.max_steps 1000 \ - --optimizer.lr 2e-5 \ - --rng.seed 1234 -``` - -### Configure Model Freezing - -NeMo AutoModel supports parameter freezing, allowing you to control which parts of a model remain trainable during fine-tuning. This is especially useful for VLMs, where you may want to preserve the pre-trained visual and audio encoders while adapting only the language model components. - -With the freezing configuration, you can selectively freeze specific parts of the model to suit your training objectives: - -```yaml -freeze_config: - freeze_embeddings: true # Freeze embeddings - freeze_vision_tower: true # Freeze vision encoder (recommended for VLMs) - freeze_audio_tower: true # Freeze audio encoder (for multimodal models) - freeze_language_model: false # Allow language model adaptation -``` - -### Run Parameter-Efficient Fine-Tuning - -For memory-efficient training, you can use Low-Rank Adaptation (LoRA) instead of full fine-tuning. NeMo AutoModel provides a dedicated PEFT recipe for Gemma 3: - -To run PEFT with Gemma 3: - -```bash -automodel examples/vlm_finetune/gemma3/gemma3_vl_4b_medpix_peft.yaml -``` - -The LoRA configuration excludes vision and audio components from adaptation to preserve pre-trained visual representations: - -```yaml -peft: - peft_fn: nemo_automodel._peft.lora.apply_lora_to_linear_modules - match_all_linear: False - exclude_modules: # exclude all vision and audio modules and lm_head - - "*vision_tower*" - - "*vision*" - - "*visual*" - - "*audio*" - - "*image_encoder*" - - "*lm_head*" - dim: 8 - alpha: 32 - use_triton: True -``` - -The training loss should look similar to the example below: - -![Training Loss Curve](./medpix_peft.jpg) - -### Checkpointing - -We support training state checkpointing in either [Safetensors](https://huggingface.co/docs/safetensors/en) or [PyTorch DCP](https://docs.pytorch.org/tutorials/recipes/distributed_checkpoint_recipe.html) format. - -```yaml -checkpoint: - enabled: true - checkpoint_dir: vlm_checkpoints/ - model_save_format: torch_save # or "safetensors" - save_consolidated: false -``` - -#### Integrate Weights & Biases - -You can enable W&B logging by setting your API key and configuring the logger: - -```bash -export WANDB_API_KEY= -``` - -Then, add the W&B configuration to your YAML file: - -```yaml -wandb: - project: nemo_automodel_vlm - entity: your_entity - name: gemma3_medpix_vqa_experiment - save_dir: ./wandb_logs -``` - -## Run Inference - -After fine-tuning your Gemma 3 or Gemma 3n model, you can use it for inference on new image-text tasks. - -### Generation Script - -The inference functionality is provided through [`examples/vlm_generate/generate.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_generate/generate.py), which supports loading fine-tuned checkpoints and performing image-text generation. - -#### Basic Usage - -```bash -uv run examples/vlm_generate/generate.py \ - --checkpoint-path /path/to/checkpoint \ - --prompt "Describe this image." \ - --base-model google/gemma-3-4b-it \ - --image /path/to/image.jpg -``` - -The output can be either `text` (default) or `json`, with an optional write file. - -For models trained on MedPix-VQA, load the trained checkpoint and generate outputs using the following command. Be sure to specify the same base model used during training: - -```bash -uv run examples/vlm_generate/generate.py \ - --checkpoint-path vlm_checkpoints/epoch_0_step_200 \ - --prompt "What medical condition is shown in this image?" \ - --base-model google/gemma-3-4b-it \ - --image medical_image.jpg -``` - -When checkpoints are saved from PEFT training, they contain only the adapter weights. To use them for generation, you need to specify the PEFT configuration. -Run the following command to load and generate from adapters trained on MedPix-VQA: - -```bash -uv run examples/vlm_generate/generate.py \ - --checkpoint-path peft_vlm_checkpoints/epoch_0_step_200/ \ - --prompt "What medical condition is shown in this image?" \ - --image-url medical_image.jpg \ - --base-model google/gemma-3-4b-it \ - --is-peft \ - --peft-exclude-modules *vision_tower* *vision* *visual* *audio* *image_encoder* *lm_head* -``` - -Given the following image: - -![Sample image from the MedPix dataset](./medpix.jpg) - -And the prompt: - -``` -How does the interhemispheric fissure appear in this image? -``` - -Example Gemma 3 response: - -``` -The interhemispheric fissure appears as a dark streak, indicating significant tissue loss. -``` - -Example Gemma 3n response: - -``` -The interhemispheric fissure appears somewhat obscured by the fluid-filled mass. -``` diff --git a/docs/fern/versions/nightly/pages/guides/omni/medpix.jpg b/docs/fern/versions/nightly/pages/guides/omni/medpix.jpg deleted file mode 100644 index 3812e4414e2fb8b8c92e55588842fc4637a56426..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19958 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 bHB1WbbI!FLQMfCIT)Xu@R)1R>{5kU% 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 diff --git a/docs/fern/versions/nightly/pages/guides/overview.mdx b/docs/fern/versions/nightly/pages/guides/overview.mdx deleted file mode 100644 index 8f44d8b9aa..0000000000 --- a/docs/fern/versions/nightly/pages/guides/overview.mdx +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: "Recipes and End-to-End Examples" -description: "" -position: 1 ---- -## Recipes and End-to-End Examples - -NeMo Automodel is organized around two key concepts: recipes and components. - -Recipes are executable scripts configured with YAML files. Each recipe defines its own training and validation loop, orchestrated through a `step_scheduler`. It specifies the model, dataset, loss function, optimizer, scheduler, checkpointing, and distributed training settings—allowing end-to-end training with a single command. - -Components are modular, plug-and-play building blocks referenced using the `_target_` field. These include models, datasets, loss functions, and distribution managers. Recipes assemble these components, making it easy to swap them out to change precision, distribution strategy, dataset, or task—without modifying the training loop itself. - -This page maps the ready-to-run recipes found in the `examples/` directory to their intended use cases, representative model families, and the most relevant how-to guides. - -- Examples root: [examples/ (GitHub)](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples) -- Getting started: [Install NeMo AutoModel](/get-started/installation) - -## Large Language Models (LLM) -This section provides practical recipes and configurations for working with large language models across three core workflows: fine-tuning, pretraining, and knowledge distillation. - -### Fine-Tuning - -End-to-end fine-tuning recipes for many open models. Each subfolder contains YAML configurations showing task setups (e.g., SQuAD, HellaSwag), precision options (e.g., FP8), and parameter-efficient methods (e.g., LoRA/QLoRA). - -- Folder: [examples/llm_finetune](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_finetune) -- Representative families: Llama 3.1/3.2/3.3, Gemma 2/3, Falcon 3, Mistral/Mixtral, Nemotron, Granite, Starcoder, Qwen, Baichuan, GLM, OLMo, Phi, GPT-OSS, Moonlight -- How-to guide: [LLM finetuning](/recipes-e2e-examples/sft-peft) - -### Pretraining - -Starter configurations and scripts for pretraining with datasets from different stacks (e.g., PyTorch, Megatron Core). - -- Folder: [examples/llm_pretrain](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_pretrain) -- Example models: GPT-2 baseline, NanoGPT, DeepSeek-V3, Moonlight 16B TE (Slurm) -- How-to guides: - - [LLM pretraining](/recipes-e2e-examples/pretraining) - - [Pretraining with NanoGPT](/recipes-e2e-examples/nanogpt-pretraining) - -### Knowledge Distillation (KD) - -Recipes for distilling knowledge from a large teacher model into a smaller, more efficient student model. - -- Folder: [examples/llm_kd](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_kd) -- Example model: Llama 3.2 1B -- How-to guide: [Knowledge distillation](/recipes-e2e-examples/knowledge-distillation) - -### Benchmark Configurations - -Curated configurations for benchmarking different training stacks and settings (e.g., Torch vs. TransformerEngine + DeepEP, various model sizes, MoE variants). - -- Folder: [examples/llm_benchmark](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark) -- Representative configurations: DeepSeek-V3, GPT-OSS (20B/120B), Kimi K2, Moonlight 16B, Qwen3 MoE 30B - -## Vision Language Models (VLM) -This section provides practical recipes and configurations for working with vision language models, covering fine-tuning and generation workflows for multimodal tasks. - -### Fine-Tuning - -Fine-tuning recipes for VLMs. - -- Folder: [examples/vlm_finetune](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/vlm_finetune) -- Representative family: Gemma 3 (various configurations) -- How-to guide: [Gemma 3n: Efficient multimodal fine-tuning](/recipes-e2e-examples/gemma-3-3n) - -### Generation - -Simple generation script and configurations for VLMs. - -- Folder: [examples/vlm_generate](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/vlm_generate) - -## Audio Models (ASR) - -This section provides recipes for fine-tuning omni / audio-capable models on automatic speech recognition (ASR) tasks. The recipes reuse the VLM training stack but operate on `{audio, text}` HuggingFace datasets (AMI, LibriSpeech, GigaSpeech, CommonVoice, etc.). - -### Fine-Tuning - -End-to-end ASR fine-tuning of `Qwen3-Omni-30B-A3B-Instruct` on any HuggingFace audio dataset, including a thinker-only checkpoint export step for downstream `transformers` / vLLM loading. - -- Folder: [examples/audio_finetune/qwen3_omni_asr](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/audio_finetune/qwen3_omni_asr) -- Representative model: Qwen3-Omni-30B-A3B-Instruct -- How-to guide: [Fine-tune Qwen3-Omni for ASR](/recipes-e2e-examples/qwen3-omni-asr) - -## Diffusion Models (Text-to-Image & Text-to-Video) - -Text-to-image and text-to-video diffusion models can generate visual content from natural language descriptions. Fine-tuning lets you adapt these models to a specific style, domain, or dataset — for example, generating product videos in your brand's aesthetic. Pretraining gives you full control when no existing model fits your needs. - -This section walks through the full workflow in NeMo AutoModel: preparing your dataset, training the model, and generating outputs. - -### Fine-Tuning - -Fine-tuning recipes for adapting pretrained diffusion models to your data. - -- Folder: [examples/diffusion/finetune](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/diffusion/finetune) -- Representative models: FLUX.1-dev (T2I, 12B), Wan 2.1 T2V 1.3B, HunyuanVideo 1.5 -- How-to guide: [Diffusion fine-tuning](/recipes-e2e-examples/diffusion-fine-tuning) - -### Pretraining - -Pretraining recipes for training diffusion models from scratch on large-scale datasets. - -- Folder: [examples/diffusion/pretrain](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/diffusion/pretrain) -- Representative models: Wan 2.1 T2V 1.3B, FLUX.1-dev -- How-to guide: [Diffusion fine-tuning (pretraining section)](/recipes-e2e-examples/diffusion-fine-tuning#configure-your-training-recipe) - -### Generation - -Generation scripts and configs for running inference with pretrained or fine-tuned diffusion models. - -- Folder: [examples/diffusion/generate](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/diffusion/generate) -- Representative models: Wan 2.1 1.3B, FLUX.1-dev, HunyuanVideo -- How-to guide: [Diffusion generation](/recipes-e2e-examples/diffusion-fine-tuning#generation--inference) - -### Dataset Preparation - -Preprocessing pipeline to create `.meta` files containing VAE latents and text embeddings. - -- How-to guide: [Diffusion dataset preparation](/datasets/diffusion-dataset) - ---- - -If you are new to the project, begin with the [Install NeMo AutoModel](/get-started/installation) guide. Then, select a recipe category above and follow its linked how-to guide(s). The provided YAML configurations can serve as templates—customize them by adapting model names, datasets, and precision settings to match your specific needs. diff --git a/docs/fern/versions/nightly/pages/guides/pipelining.mdx b/docs/fern/versions/nightly/pages/guides/pipelining.mdx deleted file mode 100644 index 2c4a3457c3..0000000000 --- a/docs/fern/versions/nightly/pages/guides/pipelining.mdx +++ /dev/null @@ -1,745 +0,0 @@ ---- -title: "Pipeline Parallelism with AutoPipeline" -description: "" -position: 3 ---- -## Introduction - -As large language models continue to grow in size, training and fine-tuning them efficiently across multiple GPUs has become increasingly challenging. While data parallelism works well for smaller models, models with billions of parameters require more sophisticated parallelization strategies to overcome memory constraints and communication overhead. - -Pipeline parallelism addresses these challenges by splitting a model's layers across different devices and processing them in a pipelined fashion. Each device processes a different stage of the model, enabling training of models that wouldn't fit on a single device while maintaining high GPU utilization through overlapped computation. - -AutoPipeline is NeMo AutoModel's high-level pipeline parallelism interface specifically designed for Hugging Face models, making pipeline parallelism as simple as data parallelism. Built on PyTorch's native `torch.distributed.pipelining`, AutoPipeline provides seamless pipeline parallelism support for any Hugging Face decoder-only causal language model with minimal code changes. - -For custom models and more granular control, the functional API in `nemo_automodel.components.distributed.pipelining.functional` provides modular, accessible building blocks that can be used with any PyTorch model architecture. - -This guide walks you through the complete process of using AutoPipeline for Hugging Face models and the functional API for custom models. You'll learn how to configure pipeline stages, integrate with existing training workflows, optimize performance, and combine pipeline parallelism with other parallelization strategies. - -**Prerequisites:** - -```bash -# Install uv from https://docs.astral.sh/uv/getting-started/installation/ -# Initialize the virtual environment using uv -uv venv - -# Install the latest stable release from PyPI -uv pip install nemo-automodel - -# Or install from source for the latest features -uv pip install git+https://github.com/NVIDIA-NeMo/Automodel.git -``` - -Before proceeding with this guide, please ensure that you have NeMo AutoModel installed on your machine. -For a complete guide and additional options please consult the AutoModel [Installation Guide](/get-started/installation). - - - -## Key Features - -AutoPipeline provides the following capabilities: - -- **Universal Hugging Face Support**: Works with any Hugging Face decoder-only causal language model including Llama, Qwen, Mistral, Gemma, and more -- **PyTorch Native Integration**: Built on PyTorch's `torch.distributed.pipelining` for optimal performance -- **Flexible Configuration**: Multiple scheduling strategies, configurable microbatch sizes, and automatic or manual layer splitting -- **Mixed Parallelism Support**: Combine pipeline parallelism with data parallelism, tensor parallelism, and FSDP -- **Modular Functional API**: For custom models, the functional module provides accessible, low-level building blocks -- **Minimal Opinions**: Easy to extend and integrate with existing training workflows - -## Quick Start with AutoPipeline (Hugging Face Models) - -Here's a minimal example to get started with AutoPipeline using 2 pipeline stages with a Hugging Face model: - -```python -import torch -from torch.distributed.device_mesh import init_device_mesh -from nemo_automodel.components.distributed.pipelining import AutoPipeline -from transformers import AutoModelForCausalLM -from transformers.integrations.accelerate import init_empty_weights -from transformers.modeling_utils import no_init_weights -from transformers.utils import ContextManagers - -def loss_fn(logits: torch.Tensor, targets: torch.Tensor) -> torch.Tensor: - """Define loss function for pipeline training.""" - return torch.nn.functional.cross_entropy( - logits.float().view(-1, logits.size(-1)), - targets.view(-1), - ignore_index=-100 - ) - -if __name__ == "__main__": - # 1) Initialize device mesh with 2 pipeline stages - world_mesh = init_device_mesh("cuda", mesh_shape=(2,), mesh_dim_names=("pp",)) - - # 2) Load model on meta device to avoid OOM with large models - init_ctx = ContextManagers([no_init_weights(), init_empty_weights()]) - with init_ctx: - model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B") - - # 3) Configure and build pipeline - ap = AutoPipeline( - world_mesh=world_mesh, - pp_axis_name="pp", - pp_schedule="1f1b", - pp_microbatch_size=1, - pp_batch_size=8, # Total batch size across pipeline - device=torch.cuda.current_device(), - dtype=torch.bfloat16, - ).build(model, loss_fn=loss_fn) - - # 4) Access pipeline components - print(ap.debug_summary()) - print(ap.pretty_print_stages()) -``` - -### Run the Quick Start Example - -Save the above code as `pipeline_example.py` and run with: - -```bash -# Run with 2 GPUs for 2 pipeline stages -uv run torchrun --nproc-per-node=2 pipeline_example.py -``` - -For a complete training example: - -```bash -# Run fine-tuning with 2-way pipeline parallelism using Llama 3.1 8B -automodel --nproc-per-node=2 examples/llm_finetune/llama3_1/llama3_1_8b_hellaswag_pp.yaml -``` - -## Configuration Options - -### Basic Configuration - -AutoPipeline provides comprehensive control over pipeline behavior: - -```python -ap = AutoPipeline( - # Device mesh configuration - world_mesh=world_mesh, # DeviceMesh with pipeline axis - pp_axis_name="pp", # Name of pipeline axis (default: "pp") - - # Schedule configuration - pp_schedule="1f1b", # Pipeline schedule ("1f1b", "looped_bfs", etc.) - pp_microbatch_size=1, # Microbatch size per stage - # pp_batch_size is automatically inferred from dataloader.batch_size - - # Stage configuration - layers_per_stage=None, # Layers per stage (None for auto) - module_fqns_per_model_part=None, # Manual module assignment - - # Model patching (HF-specific) - patch_inner_model=True, # Make decoder forward stage-friendly - patch_causal_lm_model=True, # Make CausalLM wrapper return tensors (hidden/logits) -).build(model, loss_fn=loss_fn) -``` - -### Model Patching (`patch_inner_model`, `patch_causal_lm_model`) - -AutoPipeline splits a model by deep-copying it per stage and pruning away modules that don't belong to that stage. Many Hugging Face models assume the full module tree is present and return `ModelOutput` objects; after pruning, their original `forward()` often breaks (or returns objects that are awkward to pipeline). - -These two flags switch AutoPipeline to lightweight, pipeline-friendly `forward()` implementations that return tensors (see `nemo_automodel.components.distributed.pipelining.hf_utils.patch_hf_model_for_pp`): - -- **`patch_inner_model`**: patches the *decoder module* (`model.model` for `...ForCausalLM`, otherwise the module itself) so each stage can run even after pruning. - - **Stage 0** (has `embed_tokens`): takes token IDs and produces hidden states. - - **Middle stages** (no `embed_tokens`): take hidden states from the previous stage (using `inputs_embeds`, or a float tensor passed through `input_ids`) and produce hidden states. - - Handles sliced layer containers (e.g., `layers` becoming dict-like after stage pruning) and returns a **tensor** of hidden states so stages can be chained. - - For compilation/performance, this patched forward prefers a precomputed `causal_mask_mapping` dict (it will fall back to computing masks and warn if you don't provide it). - -- **`patch_causal_lm_model`**: patches the *`...ForCausalLM` wrapper* forward (the module that owns `lm_head`) so pipeline stages return tensors: - - Returns **hidden states** when `lm_head` is absent on that stage. - - Returns **logits** when `lm_head` is present (typically only the last stage). - - Supports `logits_to_keep` to compute logits for only the last `k` tokens. - - Note: this is only used when the module you pipeline is a `...ForCausalLM`-style wrapper (i.e., it has a `.model` attribute). If you pass a base decoder module directly, `patch_causal_lm_model` typically has no effect. - -#### When Should I Change These? - -- **Leave both `True` (default)** for standard Hugging Face `AutoModelForCausalLM` / `...ForCausalLM` models. This is the common case and gives the expected behavior: token IDs -> hidden states -> logits across stages. -- **Set both `False`** when your model already has a pipeline-friendly forward (returns tensors and can accept hidden states when embeddings are absent) or it needs custom kwargs/paths that the HF patch doesn't preserve (common for NeMo AutoModel-native model implementations, packed-sequence/`thd` paths, extra args like `padding_mask`, etc.). Many benchmark configs for NeMo-native models do this (for example `examples/llm_benchmark/qwen/qwen3_moe_30b_torch.yaml`). -- **Set `patch_inner_model=False, patch_causal_lm_model=True`** when your inner model is already stage-friendly, but the wrapper forward still returns a `ModelOutput` and you only want the wrapper simplified to “hidden states or logits”. - -If you disable `patch_causal_lm_model`, your last stage will typically output hidden states instead of logits; in that case, make sure your `loss_fn` (or your last-stage module) applies the LM head explicitly. - -### Automatic vs. Manual Layer Distribution - -AutoPipeline offers flexible control over how your model is split across pipeline stages: - -#### Automatic Distribution -Let AutoPipeline automatically balance layers across stages: - -```python -ap = AutoPipeline( - world_mesh=world_mesh, - pp_schedule="1f1b", - layers_per_stage=8, # Each stage gets ~8 transformer layers -).build(model, loss_fn=loss_fn) -``` - -#### Manual Distribution -Specify exactly which modules go to each stage: - -```python -from nemo_automodel.components.distributed.pipelining.functional import ( - generate_hf_model_fqn_per_model_part -) - -# Generate balanced assignments -module_fqns = generate_hf_model_fqn_per_model_part( - num_stages=4, - num_layers=32, - include_embeddings=True, - include_lm_head=True, - include_rotary_emb=True, - fqn_prefix="model." -) - -# Or define custom assignments -custom_module_fqns = [ - # Stage 0: Embeddings + first 8 layers - ["model.embed_tokens", "model.rotary_emb"] + - [f"model.layers.{i}" for i in range(8)], - - # Stage 1: Next 8 layers - ["model.rotary_emb"] + [f"model.layers.{i}" for i in range(8, 16)], - - # Stage 2: Next 8 layers - ["model.rotary_emb"] + [f"model.layers.{i}" for i in range(16, 24)], - - # Stage 3: Final 8 layers + output - ["model.rotary_emb"] + [f"model.layers.{i}" for i in range(24, 32)] + - ["model.norm", "lm_head"] -] - -ap = AutoPipeline( - world_mesh=world_mesh, - module_fqns_per_model_part=custom_module_fqns, -).build(model, loss_fn=loss_fn) -``` - -## Understand Model Splitting - -When AutoPipeline splits your model, it intelligently distributes components across pipeline stages. Here's how a typical model gets split: - -### Example: 32-Layer Model Across 2 Stages - -```python -# Stage 0 (Rank 0): Input processing + first half -stage_0_modules = [ - "model.embed_tokens", # Token embeddings - "model.layers.0-15", # First 16 transformer layers - "model.rotary_emb" # Position embeddings (shared) -] - -# Stage 1 (Rank 1): Second half + output processing -stage_1_modules = [ - "model.layers.16-31", # Last 16 transformer layers - "model.norm", # Final layer norm - "lm_head", # Language modeling head - "model.rotary_emb" # Position embeddings (shared) -] -``` - -### Example: 32-Layer Model Across 4 Stages - -```python -# Stage 0 (Rank 0): Input processing -stage_0_modules = [ - "model.embed_tokens", # Token embeddings - "model.layers.0-7", # First 8 transformer layers - "model.rotary_emb" # Position embeddings (shared) -] - -# Stage 1 (Rank 1): Early layers -stage_1_modules = [ - "model.layers.8-15", # Next 8 transformer layers - "model.rotary_emb" -] - -# Stage 2 (Rank 2): Middle layers -stage_2_modules = [ - "model.layers.16-23", # Next 8 transformer layers - "model.rotary_emb" -] - -# Stage 3 (Rank 3): Output processing -stage_3_modules = [ - "model.layers.24-31", # Final 8 transformer layers - "model.norm", # Final layer norm - "lm_head", # Language modeling head - "model.rotary_emb" -] -``` - -Key observations: -- **Embeddings** only exist on the first stage -- **Language modeling head** only exists on the last stage -- **Rotary embeddings** are shared across all stages (for position encoding) -- **Transformer layers** are evenly distributed - -## Use the Functional API for Custom Models - -While AutoPipeline is specifically designed as a high-level interface for Hugging Face models, the functional API in `nemo_automodel.components.distributed.pipelining.functional` provides more modular and accessible building blocks that can be used with any PyTorch model, including custom architectures. This separation allows for cleaner code organization where AutoPipeline handles Hugging Face-specific optimizations while the functional module remains model-agnostic. - -### Key Functional API Components - -The functional API provides several utilities for building custom pipeline parallel systems: - -#### Stage ID Calculation -```python -from nemo_automodel.components.distributed.pipelining.functional import stage_ids_this_rank - -# Calculate which stages run on this rank -# For a "loop" style schedule (default) -stage_ids = stage_ids_this_rank(pp_rank=0, pp_size=4, num_stages=8, style="loop") -# Returns: (0, 4) - rank 0 gets stages 0 and 4 - -# For a "v" style schedule (for zero-bubble schedules) -stage_ids = stage_ids_this_rank(pp_rank=0, pp_size=4, num_stages=8, style="v") -# Returns: (0, 7) - rank 0 gets stages 0 and 7 -``` - -#### Module Name Generation -```python -from nemo_automodel.components.distributed.pipelining.functional import ( - generate_hf_model_fqn_per_model_part -) - -# Generate balanced module assignments for any model -module_names = generate_hf_model_fqn_per_model_part( - num_stages=4, - num_layers=32, - include_embeddings=True, - include_lm_head=True, - include_rotary_emb=False, # Set based on your model - fqn_prefix="" # Use "model." for nested models -) -``` - -#### Virtual Stage Calculation -```python -from nemo_automodel.components.distributed.pipelining.functional import calculate_virtual_stages - -# Calculate virtual stages for interleaved schedules -num_virtual_stages, stages_per_rank = calculate_virtual_stages( - num_layers=32, - layers_per_stage=4, # Each virtual stage has 4 layers - pp_size=4, - is_single_stage_schedule=False, - round_to_pp_multiple="up" # Round up to nearest multiple of pp_size -) -``` - -#### Pipeline Schedule Build -```python -from nemo_automodel.components.distributed.pipelining.functional import build_pipeline_schedule - -# Build a schedule for your stages -schedule = build_pipeline_schedule( - pipeline_parallel_schedule_csv=None, # Optional CSV schedule - pipeline_parallel_schedule="1f1b", - microbatch_size=1, - local_batch_size=8, - stages=stages, # List of PipelineStage objects - loss_fn=loss_fn, - scale_grads=False -) -``` - -### Example: Pipeline Parallelism for Custom Models - -Here's how to use the functional API to implement pipeline parallelism for a custom model: - -```python -import torch -import torch.nn as nn -from torch.distributed.device_mesh import init_device_mesh -from torch.distributed.pipelining import PipelineStage -from nemo_automodel.components.distributed.pipelining.functional import ( - stage_ids_this_rank, - build_pipeline_schedule, - calculate_virtual_stages -) - -class CustomTransformerBlock(nn.Module): - def __init__(self, hidden_size): - super().__init__() - self.attention = nn.MultiheadAttention(hidden_size, num_heads=8) - self.mlp = nn.Sequential( - nn.Linear(hidden_size, hidden_size * 4), - nn.GELU(), - nn.Linear(hidden_size * 4, hidden_size) - ) - self.norm1 = nn.LayerNorm(hidden_size) - self.norm2 = nn.LayerNorm(hidden_size) - - def forward(self, x): - # Simplified transformer block - attn_out, _ = self.attention(x, x, x) - x = self.norm1(x + attn_out) - x = self.norm2(x + self.mlp(x)) - return x - -class CustomModel(nn.Module): - def __init__(self, vocab_size, hidden_size, num_layers): - super().__init__() - self.embedding = nn.Embedding(vocab_size, hidden_size) - self.layers = nn.ModuleList([ - CustomTransformerBlock(hidden_size) for _ in range(num_layers) - ]) - self.output_proj = nn.Linear(hidden_size, vocab_size) - - def forward(self, input_ids): - x = self.embedding(input_ids) - for layer in self.layers: - x = layer(x) - return self.output_proj(x) - -def split_custom_model_for_pipeline(model, pp_rank, pp_size, num_stages): - """Split a custom model into pipeline stages.""" - - # Determine which stages this rank handles - stage_indices = stage_ids_this_rank(pp_rank, pp_size, num_stages, style="loop") - - stages = [] - for stage_idx in stage_indices: - # Create a stage-specific version of the model - # This is a simplified example - you'd need to implement proper splitting - stage_model = create_stage_model(model, stage_idx, num_stages) - - # Create PipelineStage - stage = PipelineStage( - stage_model, - stage_idx, - num_stages, - device=torch.cuda.current_device(), - group=None # Set your process group here - ) - stages.append(stage) - - return stages - -# Usage -def main(): - # Initialize device mesh - world_mesh = init_device_mesh("cuda", mesh_shape=(4,), mesh_dim_names=("pp",)) - pp_rank = world_mesh["pp"].get_local_rank() - pp_size = world_mesh["pp"].size() - - # Create model - model = CustomModel(vocab_size=50000, hidden_size=768, num_layers=24) - - # Calculate virtual stages - num_virtual_stages, stages_per_rank = calculate_virtual_stages( - num_layers=24, - layers_per_stage=3, # 8 virtual stages total - pp_size=4, - is_single_stage_schedule=False - ) - - # Split model into stages - stages = split_custom_model_for_pipeline(model, pp_rank, pp_size, num_virtual_stages) - - # Define loss function - def loss_fn(logits, targets): - return nn.functional.cross_entropy( - logits.view(-1, logits.size(-1)), - targets.view(-1) - ) - - # Build pipeline schedule - schedule = build_pipeline_schedule( - pipeline_parallel_schedule_csv=None, - pipeline_parallel_schedule="interleaved_1f1b", # Good for multi-stage - microbatch_size=1, - local_batch_size=8, - stages=stages, - loss_fn=loss_fn, - scale_grads=True - ) - - # Training loop - for batch in dataloader: - # Use schedule.step() for training - losses = [] - schedule.step(batch["input_ids"], target=batch["labels"], losses=losses) - - # losses will contain the loss values from the last stage - if losses: - print(f"Loss: {sum(losses) / len(losses)}") -``` - -### Advanced: Custom Model Splitting Logic - -For more complex custom models, you can implement your own splitting logic: - -```python -from nemo_automodel.components.distributed.pipelining.functional import pipeline_model - -def custom_parallelize_fn( - model, world_mesh, moe_mesh, *, - pp_enabled, dp_axis_names, **kwargs -): - """Custom parallelization function for each pipeline stage.""" - # Apply your custom parallelization logic here - # This is called for each pipeline stage - if dp_axis_names: - # Apply data parallelism - pass - # Add any other parallelization strategies - pass - -# Use pipeline_model for complete pipeline setup -schedule, model_parts, has_first, has_last, stages = pipeline_model( - model=your_custom_model, - world_mesh=world_mesh, - moe_mesh=None, - pp_axis_name="pp", - dp_axis_names=("dp",), - layers_per_stage=4, - pipeline_parallel_schedule="1f1b", - pipeline_parallel_schedule_csv=None, - microbatch_size=1, - local_batch_size=8, - device=torch.cuda.current_device(), - loss_fn=loss_fn, - parallelize_fn=custom_parallelize_fn, - module_fqns_per_model_part=None, # Provide custom module names - patch_inner_model=False, # Custom model: don't apply HF forward patches - patch_causal_lm_model=False, # Custom model: don't apply HF forward patches -) -``` - -### Tips for Using Functional API with Custom Models - -The functional API is designed to be more accessible and modular than AutoPipeline: - -1. **Module Naming**: Ensure your model has consistent module naming that can be mapped to stages -2. **State Management**: Handle model state (embeddings, buffers) carefully across stages -3. **Communication**: First and last stages need special handling for inputs/outputs -4. **Flexibility**: The functional API gives you complete control over how models are split and parallelized -5. **Testing**: Start with a small model and verify correct splitting before scaling up - -The functional module's modular design makes it easier to integrate pipeline parallelism into existing custom model training workflows without the Hugging Face-specific assumptions that AutoPipeline makes. - -## Mixed Parallelism - -AutoPipeline can be combined with other parallelization strategies for optimal performance: - -```python -def parallelize_fn( - model, world_mesh, moe_mesh, *, - pp_enabled, dp_axis_names, - cp_axis_name=None, tp_axis_name=None, ep_axis_name=None -): - """Apply additional parallelization to each pipeline stage.""" - # Example: Apply FSDP to each stage - if dp_axis_names: - from torch.distributed.fsdp import FullyShardedDataParallel as FSDP - # Wrap model with FSDP (simplified example) - # In practice, you'd configure FSDP parameters - pass - - # Example: Apply tensor parallelism - if tp_axis_name: - # Apply tensor parallelism to attention/MLP layers - pass - -# Build pipeline with custom parallelization -ap = AutoPipeline(world_mesh=world_mesh).build( - model, - loss_fn=loss_fn, - parallelize_fn=parallelize_fn -) -``` - -## Monitor and Debug - -AutoPipeline provides comprehensive tools for understanding your pipeline configuration: - -### Pipeline Information -```python -# Get pipeline info -info = ap.info -print(f"Pipeline enabled: {info.enabled}") -print(f"Has first stage: {info.has_first_stage}") -print(f"Has last stage: {info.has_last_stage}") - -# Access model parts -model_parts = ap.parts # List of pipeline stages -stage_modules = ap.list_stage_modules() # Module names per stage -``` - -### Analysis -```python -# Parameter distribution -stage_param_counts = ap.get_stage_param_counts() -total_params = ap.get_total_param_count() -trainable_params = ap.get_total_param_count(trainable_only=True) - -for i, params in enumerate(stage_param_counts): - percentage = (params / total_params) * 100 - print(f"Stage {i}: {params:,} parameters ({percentage:.1f}%)") - -# Debug summary -print(ap.debug_summary()) -print(ap.pretty_print_stages(max_modules_per_stage=10)) - -# Visualize schedule -ap.visualize_current_schedule("pipeline_schedule.png") -``` - -### Gradient Management -```python -# Scale gradients for mixed parallelism -ap.scale_grads_by_divisor(divisor=8) - -# Clip gradients across pipeline stages -grad_norm = ap.clip_grad_norm(max_norm=1.0, norm_type=2.0) -``` - -## Add Pipeline Parallelism to Existing Configurations - -You can easily add pipeline parallelism to any existing training configuration through command-line overrides or YAML modifications. - -### Command-Line Override Method - -Add pipeline parallelism to an existing config using command-line arguments: - -```bash -automodel --nproc-per-node=2 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --distributed.strategy fsdp2 \ - --distributed.pp_size 2 \ - --distributed.pipeline.pp_schedule 1f1b \ - --distributed.pipeline.pp_microbatch_size 1 \ - --distributed.pipeline.round_virtual_stages_to_pp_multiple up \ - --distributed.pipeline.scale_grads_in_schedule false -``` - -Key parameters to override: -- `--distributed.pp_size`: Number of pipeline stages (must match nproc-per-node) -- `pp_batch_size` is automatically inferred from `--dataloader.batch_size` -- `--distributed.pipeline.pp_schedule`: Pipeline schedule (1f1b, interleaved_1f1b, etc.) - -### YAML Configuration Method - -Add these sections to your existing YAML config: - -```yaml -distributed: - strategy: fsdp2 - dp_size: 1 - tp_size: 1 - cp_size: 1 - pp_size: 4 # Enable 4-way pipeline parallelism - sequence_parallel: false - pipeline: - pp_schedule: 1f1b - pp_microbatch_size: 1 - # pp_batch_size is automatically inferred from dataloader.batch_size - round_virtual_stages_to_pp_multiple: up - scale_grads_in_schedule: false - layers_per_stage: null # Auto-compute, or specify number -``` - -### Mixed Parallelism Examples - -#### Pipeline + Data Parallelism (4 GPUs Total) -```bash -automodel --nproc-per-node=4 your_config.yaml \ - --distributed.pp_size 2 \ - --distributed.dp_size 2 \ - --dataloader.batch_size 16 -``` - -#### Pipeline + Tensor Parallelism (4 GPUs Total) -```bash -automodel --nproc-per-node=4 your_config.yaml \ - --distributed.pp_size 2 \ - --distributed.tp_size 2 \ - --dataloader.batch_size 8 -``` - -#### Full Hybrid: PP + DP + TP (8 GPUs Total) -```bash -automodel --nproc-per-node=8 your_config.yaml \ - --distributed.pp_size 2 \ - --distributed.dp_size 2 \ - --distributed.tp_size 2 \ - --dataloader.batch_size 32 -``` - -## Integrate with Training Recipes - -AutoPipeline seamlessly integrates with NeMo AutoModel's recipe system. Here's a complete example YAML configuration: - -```yaml -# config.yaml -distributed: - strategy: fsdp2 - dp_size: 1 - tp_size: 1 - cp_size: 1 - pp_size: 2 # 2-way pipeline parallelism - sequence_parallel: false - pipeline: - pp_schedule: 1f1b - pp_microbatch_size: 1 - # pp_batch_size is automatically inferred from dataloader.batch_size - layers_per_stage: null # Auto-compute layer distribution - round_virtual_stages_to_pp_multiple: up - scale_grads_in_schedule: false - -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - -loss_fn: - _target_: nemo_automodel.components.loss.masked_ce.MaskedCrossEntropy - -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.SQuAD - path_or_dataset: squad - split: train - -dataloader: - batch_size: 8 - shuffle: true -``` - -Run training with: -```bash -# Run with 2 GPUs for 2-way pipeline parallelism -automodel --nproc-per-node=2 config.yaml -``` - -## Troubleshooting - -### Common Issues - -**Model doesn't fit in memory:** -- Increase number of pipeline stages -- Reduce microbatch size -- Enable gradient checkpointing - -**Pipeline bubbles reducing efficiency:** -- Increase batch size to have more microbatches -- Try different schedules (e.g., `interleaved_1f1b`) -- Adjust virtual stages configuration - -**Uneven stage distribution:** -- Use manual module assignment for fine control -- Adjust `layers_per_stage` parameter -- Check parameter counts with `get_stage_param_counts()` - -## Conclusion - -AutoPipeline and the functional API together provide a complete pipeline parallelism solution for both Hugging Face and custom models. AutoPipeline offers a high-level, optimized interface specifically for Hugging Face models, while the functional module provides modular, accessible building blocks for custom architectures. - -Key takeaways: -- Pipeline parallelism enables training of models too large for a single GPU -- AutoPipeline provides a simple API for Hugging Face models with powerful customization options -- The functional API offers modular components for implementing pipeline parallelism with any PyTorch model -- Both can be combined with other parallelization strategies for optimal performance -- Use built-in monitoring tools to understand and optimize your pipeline diff --git a/docs/fern/versions/nightly/pages/guides/quantization-aware-training.mdx b/docs/fern/versions/nightly/pages/guides/quantization-aware-training.mdx deleted file mode 100644 index e0caf4b497..0000000000 --- a/docs/fern/versions/nightly/pages/guides/quantization-aware-training.mdx +++ /dev/null @@ -1,314 +0,0 @@ ---- -title: "Quantization-Aware Training (QAT) in NeMo Automodel" -description: "" -position: 18 ---- -NeMo Automodel supports Quantization-Aware Training (QAT) for Supervised Fine-Tuning (SFT) using [TorchAO](https://github.com/pytorch/ao). QAT simulates quantization effects during the training process, allowing models to adapt to lower precision representations while learning. This approach produces quantized models that maintain significantly higher accuracy compared to applying quantization after training is complete. - -## What is Quantization-Aware Training? - -Quantization-Aware Training simulates the effects of quantization during the training process. By introducing fake quantization operations in the forward pass, the model learns to adapt to lower precision representations, maintaining better accuracy when deployed with actual quantization. - -### Benefits of QAT - -- **Better accuracy**: Models trained with QAT maintain higher accuracy when quantized compared to post-training quantization -- **Efficient deployment**: Quantized models require less memory and compute resources -- **Edge device support**: Enables deployment on resource-constrained devices -- **Production optimization**: Reduces inference costs while maintaining model quality - -### QAT vs. Post-Training Quantization - -| Aspect | QAT | Post-Training Quantization | -|--------|-----|---------------------------| -| **Accuracy** | Higher - model adapts during training | Lower - no adaptation | -| **Training time** | Longer - requires retraining | None - applied after training | -| **Use case** | Production deployments requiring best accuracy | Quick prototyping or less critical applications | -| **Flexibility** | Can fine-tune quantization parameters | Limited to fixed quantization schemes | - -## Requirements - -To use QAT in NeMo Automodel, you need: - -- **Software**: TorchAO library must be installed -- **Hardware**: Compatible NVIDIA GPU (recommended: A100 or newer) -- **Model**: Any supported model architecture for SFT - -## Install TorchAO - -Make sure you have TorchAO installed. Follow the [installation guide](https://github.com/pytorch/ao?tab=readme-ov-file#-installation) for TorchAO. - -```bash -pip install torchao -``` - -## How QAT Works in NeMo Automodel - -NeMo Automodel integrates TorchAO's QAT quantizers into the training pipeline. During training: - -1. **Model preparation**: The quantizer prepares the model by inserting fake quantization operations -2. **Forward pass**: Weights and activations are quantized using fake quantization -3. **Backward pass**: Gradients flow through the fake quantization operations -4. **Weight updates**: Model learns to minimize loss while accounting for quantization effects - -### Supported Quantization Schemes - -NeMo Automodel supports two TorchAO QAT quantizers: - -#### Int8 Dynamic Activation + Int4 Weight (8da4w-qat) -- **Quantizer**: `Int8DynActInt4WeightQATQuantizer` -- **Activations**: INT8 with dynamic quantization -- **Weights**: INT4 quantization -- **Use case**: Balanced accuracy and efficiency -- **Memory savings**: ~4x compared to FP16/BF16 - -#### Int4 Weight-Only (4w-qat) -- **Quantizer**: `Int4WeightOnlyQATQuantizer` -- **Activations**: Full precision -- **Weights**: INT4 quantization -- **Use case**: Maximum memory savings with minimal accuracy loss -- **Memory savings**: ~4x for weights only - -## Configuration - -To enable QAT in your training configuration, you need to specify the quantizer in your YAML configuration file. - -### Basic Configuration - -```yaml -# Enable QAT with Int8 Dynamic Activation + Int4 Weight quantization -qat: - enabled: true - quantizer: - _target_: torchao.quantization.qat.Int8DynActInt4WeightQATQuantizer - groupsize: 256 -``` - -### Int4 Weight-Only Configuration - -```yaml -# Enable QAT with Int4 Weight-Only quantization -qat: - enabled: true - quantizer: - _target_: torchao.quantization.qat.Int4WeightOnlyQATQuantizer - groupsize: 256 -``` - -### Configuration Parameters - -| Parameter | Type | Description | -|-----------|------|-------------| -| `enabled` | bool | Enable or disable QAT | -| `quantizer._target_` | str | Fully qualified class name of the TorchAO quantizer | -| `quantizer.groupsize` | int | Group size for weight quantization (typically 128 or 256) | - -### Delayed Fake Quantization - -You can optionally delay the activation of fake quantization to allow the model to train normally for a few steps before introducing quantization effects: - -```yaml -qat: - enabled: true - quantizer: - _target_: torchao.quantization.qat.Int8DynActInt4WeightQATQuantizer - groupsize: 256 - delay_fake_quant_steps: 1000 # Enable fake quant after 1000 steps -``` - -## Training Workflow - -### 1. Prepare Your Configuration - -Create a YAML configuration file with QAT enabled: - -```yaml -model: - model_name: meta-llama/Llama-3.2-1B - -task: - type: sft - -qat: - enabled: true - quantizer: - _target_: torchao.quantization.qat.Int8DynActInt4WeightQATQuantizer - groupsize: 256 - -trainer: - max_steps: 10000 - val_check_interval: 500 -``` - -### 2. Run Training - -Launch training with your QAT-enabled configuration: - -```bash -automodel --nproc-per-node=8 your_qat_config.yaml -``` - -### 3. Monitor Training - -During training, the model will: -- Apply fake quantization to weights and activations -- Learn to minimize loss while accounting for quantization effects -- Produce checkpoints that can be converted to actual quantized models - -### 4. Deploy Quantized Model - -After training, convert the QAT checkpoint to a fully quantized model for deployment: - -```python -from torchao.quantization import quantize_ - -# Load your trained model -model = load_model_from_checkpoint(checkpoint_path) - -# Apply actual quantization (not fake quantization) -quantize_(model, int8_dynamic_activation_int4_weight()) - -# Deploy the quantized model -model.eval() -``` - -## Performance Considerations - -### Training Performance - -- **Training time**: QAT adds overhead during training due to fake quantization operations -- **Memory usage**: Similar to full-precision training during the training phase -- **Convergence**: May require slightly more training steps to converge compared to full-precision training - -### Inference Performance - -After converting to actual quantization: - -- **Speed**: 2-4x faster inference depending on hardware and model size -- **Memory**: ~4x reduction in model size -- **Accuracy**: Minimal degradation compared to full-precision models (typically <1% difference) - -### When to Use QAT - -QAT is most beneficial when: - -- **Deploying to production**: Where inference efficiency is critical -- **Edge devices**: Resource-constrained environments -- **Large-scale serving**: Reducing infrastructure costs -- **Accuracy is important**: When post-training quantization causes unacceptable accuracy loss - -### When Not to Use QAT - -Consider alternatives when: - -- **Quick prototyping**: Post-training quantization is faster -- **Small models**: Quantization overhead may not be worth it -- **Limited training resources**: QAT requires retraining the model -- **Accuracy is not critical**: Post-training quantization may be sufficient - -## Best Practices - -### 1. Start with Post-Training Quantization - -Before investing in QAT, try post-training quantization to establish a baseline: - -```python -# Quick post-training quantization test -from torchao.quantization import quantize_ -quantize_(model, int8_dynamic_activation_int4_weight()) -``` - -If accuracy is acceptable, you may not need QAT. - -### 2. Choose the Right Quantization Scheme - -- **8da4w-qat**: Best balance of accuracy and efficiency for most use cases -- **4w-qat**: Use when memory is the primary constraint and activations can remain full precision - -### 3. Tune Group Size - -The `groupsize` parameter affects the granularity of quantization: - -- **Smaller groups (128)**: Better accuracy, slightly more memory -- **Larger groups (256)**: More efficient, may have minor accuracy impact - -Start with 256 and reduce to 128 if accuracy is insufficient. - -### 4. Monitor Validation Metrics - -Track validation metrics closely during QAT training: - -- Compare against full-precision baseline -- Watch for convergence issues -- Adjust learning rate if needed (QAT may benefit from slightly lower learning rates) - -### 5. Use Delayed Fake Quantization - -For better convergence, consider delaying fake quantization: - -```yaml -qat: - delay_fake_quant_steps: 1000 # Let model train normally first -``` - -This allows the model to learn basic patterns before introducing quantization constraints. - -## Accuracy vs. Efficiency Trade-offs - -### Expected Accuracy Impact - -| Quantization Method | Typical Accuracy Loss | Memory Savings | -|---------------------|----------------------|----------------| -| Full Precision (BF16) | Baseline | Baseline | -| Post-Training Quantization | 1-3% | 4x | -| QAT (8da4w) | <1% | 4x | -| QAT (4w) | <1.5% | 4x (weights only) | - -### Optimization Strategies - -If accuracy is below expectations: - -1. **Increase training steps**: QAT may need more training to converge -2. **Reduce learning rate**: Lower learning rates can help with quantization constraints -3. **Use 8da4w instead of 4w**: Better accuracy with minimal additional cost -4. **Reduce group size**: Smaller groups provide finer-grained quantization -5. **Delay fake quantization**: Give the model time to learn before quantizing - -## Limitations and Known Issues - -### Current Limitations - -- **SFT only**: QAT is currently supported for Supervised Fine-Tuning tasks only -- **Model compatibility**: Not all model architectures may be compatible with TorchAO quantizers -- **Training overhead**: QAT adds computational overhead during training - -### Troubleshooting - -#### Issue: Training diverges or doesn't converge - -**Solution**: Try these approaches: -- Reduce learning rate by 2-5x -- Increase `delay_fake_quant_steps` to 2000-5000 -- Use a smaller group size (128 instead of 256) -- Verify your baseline model trains successfully without QAT - -#### Issue: Accuracy is significantly worse than expected - -**Solution**: -- Ensure you're comparing against the same baseline (same training steps, data, etc.) -- Try 8da4w quantization instead of 4w -- Reduce group size to 128 -- Increase training steps by 20-30% - -#### Issue: Out of memory during training - -**Solution**: -- QAT should have similar memory usage to full-precision training -- Reduce batch size if needed -- Use gradient accumulation to maintain effective batch size - -## References - -- [TorchAO Documentation](https://github.com/pytorch/ao) -- [TorchAO QAT Guide](https://github.com/pytorch/ao/tree/main/torchao/quantization/qat) -- [Quantization Fundamentals](https://pytorch.org/docs/stable/quantization.html) -- [INT8 Quantization for Deep Learning](https://arxiv.org/abs/1806.08342) diff --git a/docs/fern/versions/nightly/pages/guides/vlm/dataset.mdx b/docs/fern/versions/nightly/pages/guides/vlm/dataset.mdx deleted file mode 100644 index 74cfb2c878..0000000000 --- a/docs/fern/versions/nightly/pages/guides/vlm/dataset.mdx +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: "Integrate Your Own Multi-Modal Dataset" -description: "" -position: 6 ---- -This guide shows you how to integrate your own dataset into NeMo Automodel for training. -You'll learn about **multi-modal datasets** that combine text with images or other modalities. We'll cover how to create custom datasets by implementing the required methods and preprocessing functions, and finally show you how to specify your own data logic using YAML configuration with file paths—allowing you to define custom dataset processing without modifying the main codebase. - -## Quick Start Summary -| **Type** | **Use Case** | **Example** | **Preprocessor** | **Section** | -| --------------- | ------------------ | -------------- | --------------------------------- | --------------------------- | -| 🖼️ Multi-modal | Vision + Language | MedPix-VQA | `apply_chat_template`, collate fn | [Jump](#multi-modal-datasets) | -| 🎤 Audio | Speech + Language | Common Voice 17| `apply_chat_template`, collate fn | [Jump](#audio-datasets) | - -## Multi-modal Datasets - -Multi-modal datasets combine text with other input types (e.g., images, audio, or video) and are essential for training Vision-Language Models (VLMs). These datasets introduce specific challenges such as aligning modalities, batching diverse data types, and formatting prompts for multi-turn, multi-modal dialogue. - -NeMo Automodel supports multi-modal dataset integration through flexible preprocessing, custom formatting, and YAML-based configuration. - -### Typical Types in Multi-modal Datasets -A multi-modal dataset typically contains: -- **Images, videos, audios** or other non-text modalities. -- **Textual inputs** such as questions, instructions, or captions. -- **Answers** or expected outputs from the model. - -These are formatted into structured conversations or instruction-response pairs for use with VLMs like BLIP, Llava, or Flamingo. - -#### Example: MedPix-VQA Dataset - -The [MedPix-VQA](https://huggingface.co/datasets/mmoukouba/MedPix-VQA) dataset is a comprehensive medical Visual Question Answering dataset designed for training and evaluating VQA models in the medical domain. It contains radiological images (from MedPix; well-known medial image dataset) and associated QA pairs used for medical image interpretation. - -**Structure**: -- 20,500 total examples -- Columns: `image_id`, `mode`, `case_id`, `question`, `answer` - -```json -{ - "image_id": "medpix_0143.jpg", - "mode": "CT", - "case_id": "case_101", - "question": "What abnormality is visible in the left hemisphere?", - "answer": "Subdural hematoma" -} -``` - -The example dataset preprocessing performs the following steps: - -1. Loads the dataset using Hugging Face's `datasets` library. -2. Extracts the `question` and `answer`. -3. Transforms the data into a chat-like format that is compatible with Hugging Face's Autoprocessor `apply_chat_template` function. For example: - -```python -conversation = [ - { - "role": "user", - "content": [ - {"type": "image", "image": example["image_id"]}, - {"type": "text", "text": example["question"]}, - ], - }, - { - "role": "assistant", - "content": [{"type": "text", "text": example["answer"]}] - }, -] -``` - -For more detailed examples of how to process multi-modal datasets for VLMs, see the examples in [`datasets.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/vlm/datasets.py). - -## Audio Datasets - -Audio datasets combine speech input with text transcriptions and are essential for training models capable of speech recognition and transcription tasks. NeMo Automodel supports audio dataset integration through specialized preprocessing functions and custom collate functions for multimodal models like Phi-4. - -### Example: Common Voice 17 Dataset - -The [Common Voice 17](https://huggingface.co/datasets/ysdede/commonvoice_17_tr_fixed) dataset is a comprehensive speech recognition dataset containing audio clips and corresponding transcriptions. This particular version focuses on Turkish speech data and has been preprocessed and fixed for compatibility with modern training frameworks. - -**Structure**: -- **Audio**: Speech recordings in various formats -- **Transcription**: Text transcriptions of the spoken content -- **Use case**: Speech-to-text transcription for multimodal models - -```json -{ - "audio": { - "path": "common_voice_tr_17528071.mp3", - "array": [-0.1600779, -0.13843077], - "sampling_rate": 16000 - }, - "transcription": "Kosova başkentinswki yolcu sayısı arttı." -} -``` - -The example dataset preprocessing performs the following steps: - -1. Loads the dataset using Hugging Face's `datasets` library. -2. Extracts the `audio` and `transcription` fields. - -For more detailed examples of how to process multi-modal datasets, see the examples in [`datasets.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/vlm/datasets.py). - -### Collate Functions - -NeMo Automodel provides specialized collate functions for different VLM processors. The collate function is responsible for batching examples and preparing them for model input. - -Multi-modal models require custom collate functions to batch and process each sample correctly. If your model uses a Hugging Face `AutoProcessor`, you can use it directly. Otherwise, you can define your own collate logic and point to it in your YAML config. We provide [example custom collate functions](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/vlm/collate_fns.py) that you can use as references for your implementation. After you implement your own collate function, you can specify it in your YAML config. - -## YAML-based Custom Dataset Configuration - -NeMo Automodel supports YAML-based dataset specification using the _target_ key. This lets you reference dataset-building classes or functions using either: - -- 1. Python Dotted Path - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.llm.hellaswag.HellaSwag - path_or_dataset: rowan/hellaswag - split: train -``` - -- 2. File Path + Function Name - -``` -: -``` - -Where: -- ``: The absolute path to a Python file containing your dataset function -- ``: The name of the function to call from that file - -```yaml -dataset: - _target_: /path/to/your/custom_dataset.py:build_my_dataset - num_blocks: 111 -``` -This will call `build_my_dataset()` from the specified file with the other keys (e.g., num_blocks) as arguments. This approach allows you to integrate custom datasets via config alone—no need to alter the codebase or package structure. - -## Custom Chat Template - -By default, VLM fine-tuning uses the chat template built into the model's `AutoProcessor`. To use a custom template, add `chat_template` under `dataset:` in your YAML config: - -```yaml -dataset: - _target_: nemo_automodel.components.datasets.vlm.datasets.make_medpix_dataset - split: train - chat_template: /path/to/template.jinja -``` - -Accepted values: -- A Jinja template string (e.g., `"{% for msg in messages %}..."`) -- A path to a `.jinja` template file -- A path to a JSON file containing a `chat_template` key (e.g., `tokenizer_config.json`) - -The override is applied to both `processor.chat_template` and `processor.tokenizer.chat_template` before dataset loading. - -## Troubleshooting Tips - -- **Tokenization Mismatch?** Ensure your tokenizer aligns with the model's expected inputs. -- **Dataset too large?** Use `limit_dataset_samples` in your YAML config to load a subset, useful for quick debugging. -- **Loss not decreasing?** Verify that your loss mask correctly ignores prompt tokens. diff --git a/docs/fern/versions/nightly/pages/guides/vlm/gemma4.mdx b/docs/fern/versions/nightly/pages/guides/vlm/gemma4.mdx deleted file mode 100644 index 7fdafb7385..0000000000 --- a/docs/fern/versions/nightly/pages/guides/vlm/gemma4.mdx +++ /dev/null @@ -1,515 +0,0 @@ ---- -title: "Fine-Tuning Gemma 4 31B on CORD-v2 Receipts — End-to-End Guide" -description: "" -position: 12 ---- -**A step-by-step guide for fine-tuning Gemma 4 31B to extract structured receipt data -from scanned images using [NeMo Automodel](https://github.com/NVIDIA-NeMo/Automodel).** - ---- - -## What is Gemma 4 31B? - -Gemma 4 31B is a dense vision-language model with a 60-layer transformer decoder, -SigLIP vision encoder, and support for multimodal inputs (images, audio, text). - -Key architectural details: -- Mixed attention: sliding window (512 tokens) + full attention (every 6th layer) -- 32 attention heads, 16 KV heads (GQA) -- Hidden dim 5376, vocab size 262,144 -- bfloat16, final logit softcapping at 30.0 -- Thinking-channel support (`<|channel>thought\n` prefix) - -## The Task - -We fine-tune Gemma 4 31B on the **CORD-v2** (Consolidated Receipt Dataset) to extract -structured fields from scanned receipts: - -| Field | Example | -|-------|---------| -| `menu` | Item names, quantities, unit prices, sub-totals | -| `sub_total` | Subtotal details (subtotal price, discount, tax, etc.) | -| `total` | Total price, cash price, change price, etc. | -| `void_menu` | Voided items (if any) | - -The **base model** produces free-form descriptions. After fine-tuning, it outputs -**structured XML-like token sequences** matching the receipt fields. - -## Guide Overview - -| Step | Description | -|------|-------------| -| **Step 0** | Environment setup | -| **Step 1** | Explore the CORD-v2 dataset | -| **Step 2** | Evaluate the base model (before fine-tuning) | -| **Step 3** | Training configuration | -| **Step 4** | Launch fine-tuning | -| **Step 5** | Evaluate the fine-tuned model | -| **Step 6** | Compare results | - -## Hardware Requirements - -- **8x A100 80 GB** (or 8x H100) GPUs required for 31B with FSDP2 + activation checkpointing -- **Estimated training time**: ~45 min on 8x H100 (800 training samples, 500 steps) - ---- - -## Step 0 — Environment Setup - -This guide runs **inside** the NeMo Automodel Docker container: - -```bash -docker run -it --rm --gpus all --ipc=host --network host \ - -v $(pwd):/workspace \ - nvcr.io/nvidia/nemo-automodel:26.02 - -# Inside the container: -huggingface-cli login # needed for gated model access -cd /opt/Automodel -``` - -> **Note**: Gemma 4 requires the transformers version that include the model implementation. Please make sure proper transformers is installed. - ---- - -## Step 1 — Explore the CORD-v2 Dataset - -[CORD-v2](https://huggingface.co/datasets/naver-clova-ix/cord-v2) is a Consolidated -Receipt Dataset for Post-OCR Parsing containing scanned receipts with structured -ground-truth JSON labels. - -```python -import json -from datasets import load_dataset - -dataset = load_dataset("naver-clova-ix/cord-v2") - -print(f"Train : {len(dataset['train'])} samples") -print(f"Validation : {len(dataset['validation'])} samples") -print(f"Test : {len(dataset['test'])} samples") - -# Inspect a sample -ex = dataset["train"][0] -gt = json.loads(ex["ground_truth"])["gt_parse"] -print(f"\nGround-truth keys: {list(gt.keys())}") - -for key in gt: - if isinstance(gt[key], list): - print(f"\n {key} ({len(gt[key])} items):") - for item in gt[key][:2]: - print(f" {item}") - else: - print(f"\n {key}: {gt[key]}") -``` - -Expected output: -``` -Train : 800 samples -Validation : 100 samples -Test : 100 samples - -Ground-truth keys: ['menu', 'sub_total', 'total', 'void_menu'] - - menu (7 items): - {'nm': 'ABRA KADABRA FLAME GRILLED', 'num': '1', 'unitprice': '39,000', 'cnt': '1', 'price': '39,000'} - {'nm': 'Lemon Tea', 'num': '1', 'unitprice': '7,000', 'cnt': '1', 'price': '7,000'} - - sub_total: {'subtotal_price': '87,000', 'discount_price': '0', 'tax_price': '7,909'} - - total: {'total_price': '87,000', 'cashprice': '100,000', 'changeprice': '13,000'} - - void_menu: [] -``` - -### Target format: JSON-to-token conversion - -NeMo Automodel converts structured JSON into an XML-like **token sequence** using -the `json2token()` function. This is the format the model is trained to produce: - -```python -from nemo_automodel.components.datasets.vlm.utils import json2token - -token_seq = json2token(gt, sort_json_key=True) -print(f"Token sequence (first 300 chars):\n {token_seq[:300]}...") -print(f"\nTotal length: {len(token_seq)} chars") -``` - -Expected output: -``` -Token sequence (first 300 chars): - 1ABRA KADABRA FLAME GRILLED1 - 39,00039,0001 - Lemon Tea17,0007,000 - ... - -Total length: 827 chars -``` - ---- - -## Step 2 — Evaluate the Base Model (Before Fine-Tuning) - -Load the pretrained Gemma 4 31B model and run it on receipt images. The base model -will produce free-form descriptions instead of structured token sequences. - -```python -import os -import json -import torch -from transformers import AutoProcessor -from nemo_automodel import NeMoAutoModelForImageTextToText -from nemo_automodel.components.datasets.vlm.utils import json2token -from datasets import load_dataset - -# --- Helpers --- - -def compute_ned(pred: str, target: str) -> float: - """Normalized Edit Distance (0 = perfect match, 1 = completely different).""" - m, n = len(pred), len(target) - if max(m, n) == 0: - return 0.0 - dp = list(range(n + 1)) - for i in range(1, m + 1): - prev, dp[0] = dp[0], i - for j in range(1, n + 1): - tmp = dp[j] - dp[j] = prev if pred[i - 1] == target[j - 1] else 1 + min(dp[j], dp[j - 1], prev) - prev = tmp - return dp[n] / max(m, n) - -def run_gemma4_inference(model, processor, pil_image, prompt="Describe this image.", - max_new_tokens=1024): - """Run Gemma 4 inference on a single image.""" - messages = [ - { - "role": "user", - "content": [ - {"type": "image", "image": pil_image}, - {"type": "text", "text": prompt}, - ], - }, - ] - inputs = processor.apply_chat_template( - messages, - tokenize=True, - add_generation_prompt=True, - return_tensors="pt", - return_dict=True, - ).to(model.device) - - with torch.inference_mode(): - outputs = model.generate(**inputs, max_new_tokens=max_new_tokens, do_sample=False) - - generated_text = processor.decode(outputs[0], skip_special_tokens=True) - prompt_length = len(processor.decode(inputs["input_ids"][0], skip_special_tokens=True)) - return generated_text[prompt_length:].strip() - -def evaluate_receipts(model, processor, test_dataset, n_samples=20): - """Evaluate model on receipt test set, return avg NED and per-sample results.""" - model.eval() - results = [] - n = min(n_samples, len(test_dataset)) - for i in range(n): - ex = test_dataset[i] - gt = json.loads(ex["ground_truth"])["gt_parse"] - target = json2token(gt, sort_json_key=True) - pred = run_gemma4_inference(model, processor, ex["image"]) - ned = compute_ned(pred, target) - results.append({"idx": i, "ned": ned, "pred": pred, "target": target, "gt": gt}) - print(f" Sample {i:2d}: NED = {ned:.4f}") - avg_ned = sum(r["ned"] for r in results) / len(results) - print(f"\n Average NED: {avg_ned:.4f}") - return avg_ned, results - -# --- Load base model --- - -MODEL_PATH = "google/gemma-4-31B-it" - -processor = AutoProcessor.from_pretrained(MODEL_PATH) -base_model = NeMoAutoModelForImageTextToText.from_pretrained( - MODEL_PATH, - torch_dtype=torch.bfloat16, - use_liger_kernel=True, - attn_implementation="flash_attention_2", - text_config={"use_cache": False}, -).eval().to("cuda") - -print(f"Parameters: {sum(p.numel() for p in base_model.parameters()):,}") - -# --- Evaluate --- - -dataset = load_dataset("naver-clova-ix/cord-v2") -print("\nEvaluating base model on receipt test set:") -base_avg_ned, base_results = evaluate_receipts(base_model, processor, dataset["test"]) -``` - -Expected base model output (receipt image): -``` - Sample 0: NED = 0.8734 - Sample 1: NED = 0.9012 - ... - Average NED: 0.8850 -``` - -**Example base model prediction** (free-form, not structured): -``` -The image shows a receipt from a restaurant. The total amount is 87,000 with items -including ABRA KADABRA FLAME GRILLED for 39,000 and Lemon Tea for 7,000... -``` - -> The base model produces readable descriptions but not the structured token format -> we need. Fine-tuning teaches it to output `......` sequences. - ---- - -## Step 3 — Training Configuration -### YAML config - -You can save the yaml below as `gemma4_31b_cord_v2.yaml` for training cord_v2 dataset. - -```yaml - -step_scheduler: - global_batch_size: 8 - local_batch_size: 1 - ckpt_every_steps: 100 - val_every_steps: 100 - max_steps: 500 - -dist_env: - backend: nccl - timeout_minutes: 60 - -model: - _target_: nemo_automodel.NeMoAutoModelForImageTextToText.from_pretrained - pretrained_model_name_or_path: google/gemma-4-31B-it - torch_dtype: torch.bfloat16 - use_liger_kernel: true - use_sdpa_patching: false - attn_implementation: flash_attention_2 - text_config: - use_cache: false - -checkpoint: - enabled: true - checkpoint_dir: vlm_checkpoints/gemma4_31b_cord_v2/ - model_save_format: safetensors - save_consolidated: true - -distributed: - strategy: fsdp2 - activation_checkpointing: true - -loss_fn: - _target_: nemo_automodel.components.loss.masked_ce.MaskedCrossEntropy - -dataset: - _target_: nemo_automodel.components.datasets.vlm.datasets.make_cord_v2_dataset - path_or_dataset: naver-clova-ix/cord-v2 - split: train - -dataloader: - collate_fn: - _target_: nemo_automodel.components.datasets.vlm.collate_fns.gemma4_prefix_collate_fn - -validation_dataset: - _target_: nemo_automodel.components.datasets.vlm.datasets.make_cord_v2_dataset - path_or_dataset: naver-clova-ix/cord-v2 - split: validation - -optimizer: - _target_: torch.optim.AdamW - lr: 1e-5 - weight_decay: 0.01 - betas: [0.9, 0.95] - -lr_scheduler: - lr_decay_style: cosine - -freeze_config: - freeze_embeddings: true - freeze_vision_tower: true - freeze_audio_tower: true - freeze_language_model: false -``` - -### Why `gemma4_prefix_collate_fn`? - -Gemma 4 31B instruction-tuned models always emit a thinking-channel prefix -(`<|channel>thought\n`) before the actual response. When this prefix -is absent from training sequences, the model predicts `<|channel>` but the label -says answer text, inflating initial loss to ~9. The `gemma4_prefix_collate_fn` -injects this prefix (masked as -100 in labels so the model is not penalized for it) -and brings initial loss down to ~3. - ---- - -## Step 4 — Launch Fine-Tuning - -```bash -torchrun --nproc-per-node=8 \ - examples/vlm_finetune/finetune.py \ - -c gemma4_31b_cord_v2.yaml \ - 2>&1 | tee logs/train_gemma4_31b_cord_v2.log -``` - -### What to watch - -- **Loss** drops rapidly from ~0.73 to ~0.04 in the first 50 steps, then stabilizes around 0.005 -- **Validation loss** reaches ~0.018 by step 199 (best checkpoint) -- Training takes ~15 min on 8x H100 (300 steps, 800 training samples) - -### Training log - -``` -step 0 | loss 0.7350 | grad_norm 35.65 | lr 1.18e-06 | mem 60.90 GiB | tps/gpu 45 -step 10 | loss 0.5489 | grad_norm 26.19 | lr 2.98e-06 | mem 40.36 GiB | tps/gpu 425 -step 20 | loss 0.1455 | grad_norm 10.53 | lr 4.78e-06 | mem 40.42 GiB | tps/gpu 438 -step 50 | loss 0.0406 | grad_norm 27.16 | lr 1.00e-05 | mem 40.34 GiB | tps/gpu 377 -step 100 | loss 0.0148 | grad_norm 7.02 | lr 9.70e-06 | mem 40.36 GiB | tps/gpu 449 -step 200 | loss 0.0065 | grad_norm 2.28 | lr 7.52e-06 | mem 40.44 GiB | tps/gpu 441 -step 300 | loss 0.0041 | grad_norm 2.10 | lr 3.16e-06 | mem 40.53 GiB | tps/gpu 448 - -Validation: - step 99 | val_loss 0.0225 - step 199 | val_loss 0.0183 <-- LOWEST_VAL (best checkpoint) - step 299 | val_loss 0.0192 -``` - -### Checkpoints saved - -``` -vlm_checkpoints/gemma4_31b_cord_v2/ - epoch_0_step_99/ - epoch_0_step_199/ - epoch_0_step_299/ - model/ - consolidated/ <-- HF-compatible checkpoint for inference - config.json - model.safetensors.index.json - model-00001-of-00013.safetensors - ... - optim/ - rng/ - dataloader/ - LATEST -> epoch_0_step_299 - LOWEST_VAL -> epoch_0_step_199 - training.jsonl <-- per-step metrics - validation.jsonl <-- per-validation metrics -``` - -> **Tip**: `LOWEST_VAL` symlink points to the checkpoint with the best validation loss. -> Use this for inference evaluation. - ---- - -## Step 5 — Evaluate the Fine-Tuned Model - -### Load consolidated checkpoint with HF AutoModelForMultimodalLM - -Because we set `save_consolidated: true` in the config, each checkpoint contains -an HF-compatible `model/consolidated/` directory. Use HF's `AutoModelForMultimodalLM` -for inference (generation), and load the processor from the **base model** path. - -```python -import json -import os -import torch -from datasets import load_dataset -from transformers import AutoProcessor, AutoModelForMultimodalLM -from nemo_automodel.components.datasets.vlm.utils import json2token - -# Paths -BASE_MODEL = "google/gemma-4-31B-it" -CKPT_DIR = "vlm_checkpoints/gemma4_31b_cord_v2" -best_ckpt = os.path.realpath(os.path.join(CKPT_DIR, "LOWEST_VAL")) -consolidated = os.path.join(best_ckpt, "model", "consolidated") - -# Load processor from base model, model from fine-tuned checkpoint -processor = AutoProcessor.from_pretrained(BASE_MODEL) -model = AutoModelForMultimodalLM.from_pretrained( - consolidated, - dtype=torch.bfloat16, - device_map="auto", -).eval() - -# Evaluate on test set -dataset = load_dataset("naver-clova-ix/cord-v2") -print("Evaluating fine-tuned model:") -ft_avg_ned, ft_results = evaluate_receipts(model, processor, dataset["test"]) -``` - -### Fine-tuned output (test sample 1 -- perfect NED=0.0) - -``` -9100091000 -17500J.STB PROMO -46000Y.B.BAT27500 -Y.BASO PROM -``` - -### Parsing the structured output - -You can convert the token sequence back to a structured dict: - -```python -import re - -def token2json(token_seq): - """Convert a token sequence back to a JSON-like dict.""" - result = {} - pattern = r"(.*?)" - matches = re.findall(pattern, token_seq, re.DOTALL) - for key, value in matches: - if "" in value: - items = value.split("") - result[key] = [token2json(item) if " - Mistral Medium 3.5 Training Loss Curve -

diff --git a/docs/fern/versions/nightly/pages/guides/vlm/mistralm35.png b/docs/fern/versions/nightly/pages/guides/vlm/mistralm35.png deleted file mode 100644 index 132b75c28703e8223ae69f0a4dc49814bacfb7bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162658 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 Z1Xf?3nU`4ve}Mla#biZai|9T6{{Z-_cJ%-N diff --git a/docs/fern/versions/nightly/pages/guides/vlm/nemotron-omni.mdx b/docs/fern/versions/nightly/pages/guides/vlm/nemotron-omni.mdx deleted file mode 100644 index 30ec1e7644..0000000000 --- a/docs/fern/versions/nightly/pages/guides/vlm/nemotron-omni.mdx +++ /dev/null @@ -1,483 +0,0 @@ ---- -title: "Nemotron-Omni" -description: "" -position: 14 ---- -**A step-by-step guide for fine-tuning NemotronOmni (33B MoE) to extract structured -receipt data from scanned images using [NeMo Automodel](https://github.com/NVIDIA-NeMo/Automodel). -Covers both full SFT and LoRA PEFT.** - ---- - -## What is NemotronOmni? - -NemotronOmni (`NemotronH_Nano_Omni_Reasoning_V3`) is a ~33B multimodal MoE model supporting -image, video, and audio inputs. - -Key architectural details: -- **LLM backbone**: NemotronV3 hybrid Mamba2 + Attention + MoE, 52 layers, hidden dim 2688 -- **Vision encoder**: RADIO v2.5-H (ViT-Huge), 256 vision tokens per tile -- **Audio encoder**: Parakeet FastConformer (1024-dim) -- **MoE**: 128 experts per MoE layer, top-6 routing with sigmoid gating -- **Total parameters**: 33B (31.5B trainable with frozen vision/audio towers) - -## Fine-Tune for Receipt Field Extraction - -We fine-tune NemotronOmni on the **CORD-v2** (Consolidated Receipt Dataset) to extract -structured fields from scanned receipts: - -| Field | Example | -|-------|---------| -| `menu` | Item names, quantities, prices | -| `sub_total` | Subtotal, tax, discount | -| `total` | Total price, cash paid, change | - -The **base model** produces free-form descriptions. After fine-tuning, it outputs -**structured XML-like token sequences** matching the receipt fields. - -## Guide Overview - -| Step | Description | -|------|-------------| -| **Step 0** | Environment setup | -| **Step 1** | Explore the CORD-v2 dataset | -| **Step 2** | Training configuration (SFT and LoRA) | -| **Step 3** | Launch fine-tuning | -| **Step 4** | Run inference on the fine-tuned model | -| **Step 5** | Compare SFT vs LoRA results | - -## Hardware Requirements - -- **8x H100 80 GB** GPUs required (MoE with EP=8) -- **SFT memory**: ~49 GiB per GPU -- **LoRA memory**: ~30 GiB per GPU -- **Estimated training time**: ~10 min on 8x H100 (400 steps, 800 training samples) - ---- - -## Step 0 — Set Up the Environment - -```bash -# Inside the NeMo AutoModel container (26.04+): -cd /opt/Automodel - -# Or from a source checkout: -git clone -b nemotron-omni ssh://git@gitlab-master.nvidia.com:12051/huiyingl/automodel-omni.git -cd automodel-omni -``` - - -NemotronOmni requires `mamba_ssm`, `causal_conv1d`, and `decord` packages, which are included in the NeMo AutoModel container. - - - ---- - -## Step 1 — Explore the CORD-v2 Dataset - -[CORD-v2](https://huggingface.co/datasets/naver-clova-ix/cord-v2) contains scanned -receipts with structured ground-truth JSON labels. - -```python -import json -from datasets import load_dataset - -dataset = load_dataset("naver-clova-ix/cord-v2") - -print(f"Train : {len(dataset['train'])} samples") -print(f"Validation : {len(dataset['validation'])} samples") -print(f"Test : {len(dataset['test'])} samples") - -# Inspect a sample -ex = dataset["train"][0] -gt = json.loads(ex["ground_truth"])["gt_parse"] -print(f"\nGround-truth keys: {list(gt.keys())}") -``` - -Expected output: -``` -Train : 800 samples -Validation : 100 samples -Test : 100 samples - -Ground-truth keys: ['menu', 'sub_total', 'total', 'void_menu'] -``` - -### Target Format: JSON-to-Token Conversion - -NeMo Automodel converts structured JSON into an XML-like **token sequence** using -the `json2token()` function. This is the format the model is trained to produce: - -``` -45,5004,500 -50,00016,500 -REAL GANACHE113,000 -EGG TART1 -``` - ---- - -## Step 2 — Training Configuration - -### Full SFT Config - -**Config file**: `examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2.yaml` - -```yaml -recipe: FinetuneRecipeForVLM - -step_scheduler: - global_batch_size: 8 - local_batch_size: 1 - ckpt_every_steps: 100 - val_every_steps: 200 - max_steps: 400 - -model: - _target_: nemo_automodel.NeMoAutoModelForImageTextToText.from_pretrained - pretrained_model_name_or_path: - trust_remote_code: true - torch_dtype: torch.bfloat16 - backend: - _target_: nemo_automodel.components.models.common.BackendConfig - attn: sdpa - linear: torch - rms_norm: torch_fp32 - rope_fusion: false - enable_deepep: false - fake_balanced_gate: false - enable_hf_state_dict_adapter: true - -distributed: - strategy: fsdp2 - ep_size: 8 # 128 MoE experts across 8 GPUs - -freeze_config: - freeze_embeddings: true - freeze_vision_tower: true - freeze_audio_tower: true - freeze_language_model: false - -dataset: - _target_: nemo_automodel.components.datasets.vlm.datasets.make_cord_v2_dataset - path_or_dataset: naver-clova-ix/cord-v2 - split: train - -dataloader: - collate_fn: - _target_: nemo_automodel.components.datasets.vlm.collate_fns.nemotron_omni_collate_fn - max_length: 4096 - -optimizer: - _target_: torch.optim.AdamW - lr: 1e-4 - weight_decay: 0.01 - betas: [0.9, 0.95] -``` - -### LoRA PEFT Config - -**Config file**: `examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2_peft.yaml` - -Adds a `peft:` block to apply LoRA to language model linear layers only: - -```yaml -peft: - _target_: nemo_automodel.components._peft.lora.PeftConfig - match_all_linear: false - exclude_modules: - - "*vision_tower*" - - "*vision_model*" - - "*audio*" - - "*sound*" - - "*lm_head*" - - "*mlp1*" - dim: 64 - alpha: 128 - use_triton: true - -optimizer: - _target_: torch.optim.AdamW - lr: 1e-3 -``` - -### Collate function - -NemotronOmni uses InternVL-style image handling where each `` token in the -input is replaced by 256 vision embeddings during the model's forward pass. The -collate function: -1. Extracts images from the conversation -2. Applies the chat template (which adds `` prefix for the assistant turn) -3. Processes images through the NemotronOmni processor -4. Builds `image_flags` tensors and creates training labels - ---- - -## Step 3 — Launch Fine-Tuning - -### Full SFT - -```bash -torchrun --nproc-per-node=8 \ - examples/vlm_finetune/finetune.py \ - -c examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2.yaml -``` - -### LoRA PEFT - -```bash -torchrun --nproc-per-node=8 \ - examples/vlm_finetune/finetune.py \ - -c examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2_peft.yaml -``` - -### Training log — Full SFT - -``` -Trainable parameters: 31,570,023,872 -Trainable parameters percentage: 95.63% - -step 0 | loss 0.6866 | grad_norm 7.57 | lr 1.00e-04 | mem 37.29 GiB | tps/gpu 33 -step 10 | loss 0.0705 | grad_norm 1.00 | lr 1.00e-04 | mem 48.95 GiB | tps/gpu 2419 -step 50 | loss 0.0173 | grad_norm 0.43 | lr 1.00e-04 | mem 48.72 GiB | tps/gpu 2615 -step 100 | loss 0.0115 | grad_norm 0.37 | lr 1.00e-04 | mem 48.84 GiB | tps/gpu 2642 -step 200 | loss 0.0099 | grad_norm 0.20 | lr 1.00e-04 | mem 48.76 GiB | tps/gpu 2616 -step 300 | loss 0.0056 | grad_norm 0.15 | lr 1.00e-04 | mem 48.72 GiB | tps/gpu 2087 -step 399 | loss 0.0039 | grad_norm 0.17 | lr 1.00e-04 | mem 48.79 GiB | tps/gpu 2616 - -Validation: - step 99 | val_loss 0.0363 - step 199 | val_loss 0.0342 <-- LOWEST_VAL - step 299 | val_loss 0.0414 - step 399 | val_loss 0.0425 -``` - -### Training log — LoRA PEFT - -``` -Trainable parameters: 55,422,976 -Trainable parameters percentage: 0.17% - -step 0 | loss 0.6866 | grad_norm 1.92 | lr 1.00e-03 | mem 30.26 GiB | tps/gpu 34 -step 10 | loss 0.0557 | grad_norm 0.30 | lr 1.00e-03 | mem 30.16 GiB | tps/gpu 2455 -step 50 | loss 0.0392 | grad_norm 0.32 | lr 1.00e-03 | mem 30.16 GiB | tps/gpu 3352 -step 100 | loss 0.0309 | grad_norm 0.27 | lr 1.00e-03 | mem 30.20 GiB | tps/gpu 2456 -step 200 | loss 0.0280 | grad_norm 0.23 | lr 1.00e-03 | mem 30.34 GiB | tps/gpu 2477 -step 300 | loss 0.0326 | grad_norm 0.31 | lr 1.00e-03 | mem 30.52 GiB | tps/gpu 2737 -step 399 | loss 0.0171 | grad_norm 0.24 | lr 1.00e-03 | mem 30.33 GiB | tps/gpu 3258 - -Validation: - step 99 | val_loss 0.0449 <-- LOWEST_VAL - step 199 | val_loss 0.0524 - step 299 | val_loss 0.0482 - step 399 | val_loss 0.0566 -``` - -### Checkpoints saved - -``` -checkpoint_dir/ - epoch_0_step_99/ - epoch_1_step_199/ - epoch_2_step_299/ - epoch_3_step_399/ - model/ - consolidated/ <-- HF-compatible checkpoint for inference - config.json - model.safetensors.index.json - model-00001-of-00017.safetensors - ... - optim/ - rng/ - dataloader/ - LATEST -> epoch_3_step_399 - LOWEST_VAL -> epoch_1_step_199 - training.jsonl - validation.jsonl -``` - -For LoRA, the checkpoint saves adapter weights instead: -``` - model/ - adapter_model.safetensors (~27 MB) - adapter_config.json -``` - -> **Tip**: `LOWEST_VAL` symlink points to the checkpoint with the best validation loss. - ---- - -## Step 4 — Run Inference on the Fine-Tuned Model - -### Full SFT inference - -Load the consolidated checkpoint and run inference on a handful of validation samples -to spot-check structured output. - -```python -import torch -import json -from transformers import AutoModel, AutoProcessor -from datasets import load_dataset -from nemo_automodel.components.datasets.vlm.utils import json2token - -CKPT = "/LOWEST_VAL/model/consolidated" - -# Load processor -processor = AutoProcessor.from_pretrained(CKPT, trust_remote_code=True) -tokenizer = processor.tokenizer - -# `device_map` streams weights directly to GPU; skipping the AutoModel.from_config -# CPU-instantiation step saves ~5 min on the 30B v3 dump. -model = AutoModel.from_pretrained( - CKPT, trust_remote_code=True, torch_dtype=torch.bfloat16, - device_map={"": torch.cuda.current_device()}, -) - -# Reset RADIO's `summary_idxs` (non-persistent buffer; can be a meta tensor after load) -if hasattr(model, "vision_model") and hasattr(model.vision_model, "radio_model"): - model.vision_model.radio_model.summary_idxs = None - -model.eval() - -# Load dataset -dataset = load_dataset("naver-clova-ix/cord-v2") - -# v3 processor returns extra placeholder-expansion metadata that is NOT a generate() kwarg. -PROCESSOR_METADATA_KEYS = ("num_patches", "num_tokens", "imgs_sizes") - -# Run inference on the first 5 validation samples -for i in range(5): - sample = dataset["validation"][i] - image = sample["image"].convert("RGB") - gt = json.loads(sample["ground_truth"])["gt_parse"] - gt_text = json2token(gt, sort_json_key=True) - - # Build prompt — enable_thinking=False for structured output - messages = [{"role": "user", "content": "\nDescribe this image."}] - text = tokenizer.apply_chat_template( - messages, tokenize=False, - add_generation_prompt=True, enable_thinking=False, - ) - inputs = processor(text=text, images=[image], return_tensors="pt") - for k in PROCESSOR_METADATA_KEYS: - inputs.pop(k, None) - inputs = {k: v.to("cuda") if isinstance(v, torch.Tensor) else v for k, v in inputs.items()} - - with torch.no_grad(): - output_ids = model.generate(**inputs, max_new_tokens=1024, do_sample=False) - - generated = tokenizer.decode( - output_ids[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True, - ).strip() - - print(f"\n=== Sample {i} ===") - print(f"Ground truth: {gt_text}") - print(f"Prediction: {generated}") -``` - -### LoRA PEFT inference - -NeMo Automodel saves LoRA adapters under its internal wrapper FQNs -(e.g. `language_model.model.layers.X.mixer.in_proj`), which differ from the HF -base model namespace (`language_model.backbone.layers.X.mixer.in_proj`). -To apply the adapter, merge the delta weights directly into the base model with -a small FQN translation: - -```python -import json, re -import torch -from pathlib import Path -from safetensors import safe_open -from transformers import AutoModel, AutoProcessor - -BASE = "" -ADAPTER = "/LOWEST_VAL/model" - -# Load base directly to GPU. Skip AutoModel.from_config — instantiating a 30B -# model on CPU just to read the class type adds 5+ minutes. -processor = AutoProcessor.from_pretrained(BASE, trust_remote_code=True) -model = AutoModel.from_pretrained( - BASE, trust_remote_code=True, dtype=torch.bfloat16, - device_map={"": torch.cuda.current_device()}, -) -if hasattr(model, "vision_model") and hasattr(model.vision_model, "radio_model"): - model.vision_model.radio_model.summary_idxs = None - -# Wrapper -> HF base FQN translation. vision_projector.* targets are listed in -# adapter_config.json but no tensors are saved for them, so we just skip those. -def translate(fqn): - if fqn.startswith("language_model.model."): - return "language_model.backbone." + fqn[len("language_model.model."):] - return None - -cfg = json.loads((Path(ADAPTER) / "adapter_config.json").read_text()) -scale = cfg["lora_alpha"] / cfg["r"] - -pairs = {} -with safe_open(str(Path(ADAPTER) / "adapter_model.safetensors"), framework="pt") as f: - for k in f.keys(): - m = re.match(r"^base_model\.model\.(.+)\.lora_(A|B)\.weight$", k) - if m: - pairs.setdefault(m.group(1), {})[m.group(2)] = f.get_tensor(k) - -modules = dict(model.named_modules()) -for wrapper_fqn, ab in pairs.items(): - hf_fqn = translate(wrapper_fqn) - if hf_fqn is None or hf_fqn not in modules: - continue - W = modules[hf_fqn].weight - A = ab["A"].to(device=W.device, dtype=torch.float32) - B = ab["B"].to(device=W.device, dtype=torch.float32) - with torch.no_grad(): - W.add_(((B @ A) * scale).to(W.dtype)) - -model.eval() -# ... then run the same generate() loop as in the SFT example above. -``` - -**Resources** — single GPU; ~60 GB GPU RAM for the bf16 30B base. -**Runtime** — ~75 s base load + ~1 s LoRA merge + ~5–15 s per sample. - ---- - -## Step 5 — Results Comparison - -### Evaluation on 5 CORD-v2 Validation Samples - -#### Full SFT (lr=1e-4, 400 steps, epoch_3_step_399) - -| Sample | Ground Truth | Prediction | Match | -|--------|-------------|------------|-------| -| 1 | `...REAL GANACHE...EGG TART...PIZZA TOAST...` | Exact match | 100% | -| 2 | `...JAMUR...TAHU...` | Exact match | 100% | -| 3 | `...Gojek Chicken Chilli Sauce H...` | Correct values, slight name segmentation diff | 33% | -| 4 | `...VANILLA CHOCO HEART CAKE...` | Exact match | 100% | -| 5 | `...Sate Padang...` | Correct, extra `` field | ~0% | - -**3/5 exact matches. All samples produce correct structured output.** - -#### LoRA PEFT (rank=64, lr=1e-3, 400 steps, epoch_0_step_99) - -| Sample | Ground Truth | Prediction | Match | -|--------|-------------|------------|-------| -| 1 | `...REAL GANACHE...` | Exact match | 100% | -| 2 | `...JAMUR...TAHU...` | Exact match | 100% | -| 3 | `...Gojek Chicken Chilli Sauce H...` | Correct values, slight name segmentation diff | 33% | -| 4 | `...VANILLA CHOCO HEART CAKE...` | Exact match | 100% | -| 5 | `...Sate Padang...` | Exact match | 100% | - -**4/5 exact matches. All samples produce correct structured output.** - -### Summary - -| | Full SFT | LoRA PEFT | -|---|---|---| -| Trainable params | 31.5B (95.63%) | 55M (0.17%) | -| Learning rate | 1e-4 | 1e-3 | -| GPU memory | ~49 GiB | ~30 GiB | -| Training time (8x H100) | ~10 min | ~6 min | -| Best val loss | 0.034 (step 199) | 0.045 (step 99) | -| Final train loss | 0.004 | 0.017 | -| Checkpoint size | ~64 GB | ~27 MB | -| Exact matches (5 val) | 3/5 | 4/5 | diff --git a/docs/fern/versions/nightly/pages/guides/vlm/qwen3-5.mdx b/docs/fern/versions/nightly/pages/guides/vlm/qwen3-5.mdx deleted file mode 100644 index d0408f31ef..0000000000 --- a/docs/fern/versions/nightly/pages/guides/vlm/qwen3-5.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: "Fine-Tune Qwen3.5-VL" -description: "" -position: 13 ---- -## Introduction - -[Qwen/Qwen3.5-397B-A17B](https://huggingface.co/Qwen/Qwen3.5-397B-A17B) is the latest vision-language model in the Qwen series developed by Alibaba. It’s a 397B-parameter (17B active) hybrid MoE model that uses a repeated layout of Gated DeltaNet and Gated Attention blocks, each paired with sparse MoE (512 experts; 10 routed + 1 shared active). Qwen3.5 is a major upgrade that unifies vision+language, boosts efficiency and multilingual coverage, delivering higher performance at lower latency/cost for developers and enterprises. Qwen3.5-397B-A17B shows competitive benchmark performance across knowledge, reasoning, coding, and agent tasks. -

- Qwen3.5 benchmark -

- -This guide walks you through fine-tuning Qwen3.5 on a medical Visual Question Answering task using NVIDIA NeMo Automodel. You will learn how to prepare the dataset, launch training on a Slurm cluster, and inspect the results. - -To set up your environment to run NeMo Automodel, follow the [installation guide](https://github.com/NVIDIA-NeMo/Automodel#-install-nemo-automodel). - -## Data - -### MedPix-VQA Dataset - -We use the [MedPix-VQA](https://huggingface.co/datasets/mmoukouba/MedPix-VQA) dataset, a comprehensive medical Visual Question Answering dataset containing radiological images paired with question-answer pairs for medical image interpretation. - -- **20,500 total examples** (85% train / 15% validation) -- **Columns**: `image_id`, `mode`, `case_id`, `question`, `answer` - -For a full walkthrough of how MedPix-VQA is preprocessed and integrated into NeMo Automodel—including the chat-template conversion and collate functions—see the [Multi-Modal Dataset Guide](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/guides/vlm/dataset.md#multi-modal-datasets). - -## Launch Training - -We provide a ready-to-use recipe at [`examples/vlm_finetune/qwen3_5_moe/qwen3_5_moe_medpix.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5_moe/qwen3_5_moe_medpix.yaml). This recipe is configured to run on 32 x 8 H100 nodes. - -NeMo Automodel supports several ways to launch training—via the Automodel CLI with Slurm, interactive sessions, `torchrun`, and more. For full details on all launch options (Slurm batch jobs, multi-node configuration, environment variables, etc.), see the [Run on a Cluster](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/launcher/slurm.md) guide. - -### Standalone Slurm Script - -We also provide a standalone Slurm script example for Qwen3.5. Before running it, ensure your cluster environment is configured following the [Run on a Cluster](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/launcher/slurm.md) guide. Then submit the job with the following command: - -```bash -export TRANSFORMERS_OFFLINE=1 -export HF_HOME=your/path/to/hf_cache -export HF_DATASETS_OFFLINE=1 -export WANDB_API_KEY=your_wandb_key - -srun --output=output.out \ - --error=output.err \ - --container-image /your/path/to/automodel26.02.image.sqsh --no-container-mount-home bash -c " - CUDA_DEVICE_MAX_CONNECTIONS=1 automodel \ - examples/vlm_finetune/qwen3_5_moe/qwen3_5_moe_medpix.yaml \ - --nproc-per-node=8 \ - --model.pretrained_model_name_or_path=/your/local/qwen3.5weights \ - --processor.pretrained_model_name_or_path=/your/local/qwen3.5weights " -``` - -**Before you start**: -- Hugging Face applies rate limits on downloads. We recommend cloning the model repository to your local filesystem beforehand. -- Ensure your Hugging Face cache (`HF_HOME`) is configured and that the dataset is already cached locally. -- To enable Weights & Biases logging, set your `WANDB_API_KEY` and configure the `wandb` section in the YAML file. - -## Training Results - -The training loss curves for Qwen3.5-VL fine-tuned on MedPix-VQA are shown below. - -

- Qwen3.5-VL Training Loss Curve -

diff --git a/docs/fern/versions/nightly/pages/guides/vlm/qwen3_5.png b/docs/fern/versions/nightly/pages/guides/vlm/qwen3_5.png deleted file mode 100644 index 1f0ddc0ef2dd12980cb86609809481f21a0f6228..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152665 zcmeFZby!qu+c&(17PcY=NSBDTMF z`c}Ykg2&{RbWrr0j8YVA>d|1aMUU3tOVxMAs;WOL6=R?4a53Z~<0RNzgPM13%BO3Z zv4=gQZ?|I7IdouDH)-usH>AfqfAIEd*8J~Auh??go z$mCh2{G{F3Ncx-cw@zhaJC}{tkV38D#V)6;z26T^1bd)A!JoOFR5EA2#JX|om8$Gs zqDD%>J3UPQOE|qDA{U4a^d@f^Z-l-ynUTHqoW|xFZB|DA_A))pUoiMVKXd#SGxQaN3;uTr{5XHW`1@{L?+=)Nf5!X?zJngh3yX_`zw&yv1_qXP z##Z)UbNlSUg>%+os&)`W%z*xZi9fx*0>DiiC+nZQf(xAuHeP-og&re5(p6H){$Lln3Hu=v?mUbuG z0vqH&f5UN`{T9bRV}nN@ps(`Enm8Mnt3Ecd05k)02;Ar9dT@0A|M=!VGydyImH#|> z`~IC<|9>%ies!bc;f=SvUJ(A`5Tv#c)3*smOkPh5hZ-{?)6j{fJkcDd&=2pQk2o#ebdg zf#$=8D}vG*cY92AAecbhF>K^|>;hxEB*(xVzV(Dw{y(+R(Zwj_HVHl<)zZwL(+Q!DKI=5ZwTYR{qklPf?5Lpmz%&4DX$@z^;`Svt^eEPFf2Up3f%vFjaP_h zAnB066w?2;y5qIOZf*bfO`yLGro+HOFm;C9!~E~W0pHRG(@nh=eEQoR<*f1N&oKrH z9jYcL7sC17wwin}aUW4OIi6*%`ML0$a*vP;vFxg<(N8};ip(u!#YG(M7fCxV4YEbB zP}8bLPo+MI?kr_*X*^5LmzQNf&R<}2AE|c94(Cu-GVRHtTCx`1&K%z!^Xd~%mAJY| zI7&)7`!q-8wrKuC-LubM!`K~+3U*o?&OQHqgdMrP97Wa>bY)ZZUW{KVQgHBUFyHL7V3!xcIRoz-|0+77FbO2QoK0B zU7=e(t?H$-+7fxnWsVAWpGD&!Oed|>)X08W-SQ}-t=%fj~bD#Lk z7JT00?N{1IclR2mzwL=Zc(JO}a+*?Pa(G+`!;!stR<($+dyO$2-jPU#0WzySn5e7& zf`iDCE$LkjQDhNSxQR=Ddhs+D31FQ3MQY?cd^q#4>8ZsKufD8~ItM*Dho;A8w48>{ zr^ao&v2coojw*+o3pzjr38rd|@Veqr$XW1QJG<^{co{2B-YE2&=CYywY^79$7wgl+oC@CX*22Fib2rfcD)ZVWVoyLbt043vA*gu>e9Kx`0E3PX8D+80jNXqPy*H}!3eOt3Q)xDR9?EIBcQ;WRtE&%-cu$erWfo*}ye7)88C zQ{fC0(2xOk7QF7y}-Lu6xf>&)d#K*AVprsW*YtlbRU-W$h* ze`f8w=+Wy4O<<>o@qPor3eH`uI>V)>a3BK)m7%ZB*sPa;OBWdG&sY{8h0DMOmr$kh zpP{cGAUieu3(n~!`dqmRZtn<8RXuwYlU|aa!XD$IV(YUuv<=NI3v^q7@Y1-(j|0i zKFH?nIwSp&LGGzpOf&_IzXQ21!IG>-sy<9+6#I6@4cYiJ{PF)Hc!UOZas`c{uAnQ zkVJ2;G8TH)<76rprQNggtd8^ORYg1JW1n1HT<#dmxw*RFUbrHW{ObH<^?I8@3|rzw znIm&rjRwo9(e%Y5%B>R1$_sL+7CweoZxk*J6p6OoN3z~86~A0Vro2(9ArZmMP*k_` zh`>*|IohZ+(o~d+iMnN9jF?T0Rg^+bPA$>qRk69vpl**=ooCIHUV-hb^}@nCsW!>q zJ4+XRpK{Sp6zB~cYmIjlAW_XQvX~ORWtudMUl`-i$@|TmV)@1o*3f9D2=b?YgN1ds40Slv24tx%zbmS&-VLl zdNXx%M?CI@`GA~SzssI0F{ia%2!Gt{4ay_7<=#582F`q<|~ zGy|4tEqM$EqFHuP-bWU;lGT%)sve}Z=hr(C$R}Otv`BYf&6{tnq|e|-AZ2HU96jlF zn=ya?NR?B5T*n`Crkgi|w-(tWs75Lqze|xDwDhlbW==gG%_KN79E_1Z%Nerk(RU5+4Z+f?A}s=l-mb z%i<>YhGD$j*1%ql@|;M10{;dP0uJSr_GBqaBF%>tn<86-Z6+8Sv{{tI)YNWA^X_V9 zx^>IVU7YnmonKr3;;VLFYASGOPyFLn9idTM=PU^84^A7B7B|EqxGIh<92wQa7E89LI#OSAnG_FHn7W zTY?GGCtHyMTQTF8c01k*n+_)=@KAkprnL`FoSBCo*t5%~UK|{y?f!6Vd;Ei+!Jiz} zr%8{`&30CV39u-k^a7b|sW?u&;&DMB=1W+|fb;D7MOLV-ae&F9?Y?r|vpV%XiDk2V zCfiN3{CRo;61LEZlFW}|p7V8?g^?VG@;Jk8i3e=P4h1oz5>hDl=|xoPBVYX5^+Y$% zm(_P2{VeOrQI%hs@rsReYa6K5bAEp00(mQ=wRmv7_$Yv&k;8Dr7_TiGy|MnM zJxVW7K<$Q1+y`#m>9%;=F$AtbUg>biDvumN&~lZLcXz(bMf3M7myf^|#sIt#k7HyI z^2d6PjWA^!i!_SM%%9Ef<*r;Fg^A>OidQx3FIJXx?)l%H^qqc%+{#=RK)RP!^Vx*5 z9!!yVxP^TWFlZUFx=K2go#vmw<5E~HIDt7(<5uQ5TvVSBSu|L@8u9J&F^Q^y|FiH- zE4}rI6>qK-T!yqg79IACv=4z&r~`drjOHP8R3I-kV;28rTx>DcVU`_h|ZlCtkd`rz}UYDfhwZna6e)0TIIj>wePBzh( z&r}Cp{4&?L;bffV&i%T4wziY6$gLs`nxiCR@3x0ezY?_TziobkE0SnjnX?!?iZ{k_ zV4TmkTZ#^2VUoEM*}dzVUf0YZTxnQtZHxQEAxQ>qr!vpLPdEjK6>}9aZ1Z!Yed1bL z3BwLQC~bkd`}nPp9aFmE0c@rMANfgS#-p3r7enr^zyuWvkL9~t^oiy28)b>wknEC z4!%tm7vIxX^oPoU(OIkBidOX~RZR4uKCENZAKchxkV1|PC65J9#BlYrlLFgt&sbJl zntw_k<>2XAt6^`$H&AJjUHiB*LV05?qV;c{gNS@#lh6Cu{rIXd{=77*0a(__hAhRY z3M0SSWQXnLF%D&|E_F}jA~y=tVx&@3JaDUZrZtv(-l3w_$*LlCS!!>+Y}8X!>)L8k zIIF5ephc$&vtriuvBQ-Ylg9M!L3zqDqdjRAgH=|E#mhg%4}YrXs&Ous-zfA%xvExf za5HruY<~^@F_lEX@w0j21Ua1*0Tg8O%Nz%1mzb=VQJ7O*?E-z-!SV5I26yl1cV~0V zcX5%!3I?Mim7bXPweba7`_R|(UHAL5RVY$%lj-y`LPFmhlm{3lBH1p9`u*;XLMX3RqWCt<4cL(kdH z-8!a(o-2y&bt_5L+#Zz~R&3d#-`-xG+5#p3=@_*)ml8;hYP%MF&*g2#W|+Sy8YT~r zORE9+TE)(vxUzN_RC7=Yup(D|L&K(4?$Mk4l}?<}6O6}>SOSO)x6J#xtkDYTgN2_n zR`77C8cBsB_zCBP*Y1bLxy~^?!$PzM3Tn-DXR=Yd-;yVE?jiZW(U0p@5&76}G7q zis^yjz#295;N#=#e|sD8v{XYiQ#BbL;^D*5jXRCTeaBpLwqZ8va&@oVypm_%@R^iL z2~y~V6H>=0@lJ{_oG8B@dgOWQm^0y~ z91xXvHPW$1AT-RXgN0y>vwmK^J1EAj98q~}&Vud1v*LXQ3TF~yG*5w*6Z^(PbwnAT zQ;C~uHlQAh2kD!~lsX9{y&2Jgb4TmFOXx>v-k|d$8ATb)N6^s;f__HLC^_9@P(86l zkdGKJ3-nhfoR2R*V<~WHCLRcjVoa5c>g`?2y)^Vrj`vs!s4fF3Q1R>1I5h&|9az5B zg2SNyiKLz&hCJAMEJ`~27=Mq+1i@s$D%`TFOjwVHJX!uY$baa_I0*(EyG19SIaW0- z*kyocTEwYcLKt))e!xC+?f*vFrzraWDLrrj{|Yg2Q&y{)e#w^1)LKM}P427EG*tVX zp4-xefw-cIhF?=n;bEp%16d2%2DEdAYPGhmPD;i%4T!`PT5LP+dMw@B@WamUmck-X0YM>1oDHfBX*CY(nSX^y?~mw9Vc z`#*Ux#C;$J)2vMA(Bg}jz=$m#ckFK=D!gqJ)}5oGNpL6X9sX_VMP6Bnh?@rDMr-@C zcWg!#8gE7{@g0QgNr!rpjLx{lFUW8$^xs5{)haVbwuUO_xwZAhiDXAM{3LB}>JaUX zC>iP%pNKg>75L67a(HZ8l{7og0fpq9oF-WMZ}x{O7k{g)^ysFNA2`KP(0Y*^z)XMn z(<78XJoKsK&W#+dsfgsiBVp7ar)a9q>$y6|u-4Xhc~aY=*!acV53%OG^oCH*y2g>H z(HmZtDzqG4dod4sHy<)7r{!pkHVjxbj_&i@4vBEj=WkQ@b8O2vKPE7CljOJP&UAGz zG%j^t>0%wolM=~EBUJjeNHoPfhaBCv_2=R(Nf=ECBJp6yMy^jiW6M$SG06CFK7S<5 zH)e4%$#B|_H>F{VDAB+Bc~fWSbe!2+^Rm6)^J9NzEChdL7~b)0yUzbaK%PL>Ezu$M z3GzTV*CTPhi^WMG_eGp__iF949{ZMw+W4Dxk*!hgi!OE+V-7~znKH@d6vYP9N-m4< zI$~CzHa0bcUtrWWz2DE(v@Q>&ykScStNCtj+Apn_N+F! zwf^y%{KdZgZom_@LjzlJ@eoYPP?Y7}Kfj3Ns3}D?`e}YKaGHZ6=ys z8+QD-MAlz~;WU@4YxkuaCuI7Db(I7cdkw{wj2Bfui4l|{l=ag(c&`=3I7)q^?y%~K zbXK26o8S_K9BiY?F1K`JJX0E{VTk9{Vjb`P=s1;KK?X3pH6ER$h|8#zE^~hA-yeX$!U^?CDQA3^vG%&#k<)r`7IiX(+v`d|76|jaDMXs zt}5~V<_luA3q9QYcc#uY<|)XNH@Zep;RK=#lel0uAMJb7NCiGw+C^86d#I-PmIpa_ z2ob){ciqKd+h1f!r}7B(tX=)(@s+b(j4hYqDntT+8qvJeyPaK_=RS*5k>$`%N3W~B zXCLm48q#3O%|-I1{HS-O^yiI1DI_Z@UUbt~ys?(e72~oQ={4C)U>RH##NV}`;8BO~ zoo-5RCb~)b(RYwx)56qr>J{hQJbiM{tDe|CW3!b}dJZi<4Z^6y?ldW?TT2f~9j7k4 zisb~#$-8WlI%I3)2Rs%~Cg@K;T>0ppTrwNY;wKifCAjH4Rm82oJvvfryBR=xkeWl~ zynWjwW<-TuuqL)eYb|vL7m>BBkg@L-6Scat)K0y@8Ns;arQWiYZKnX`z^$TgYH7sY zsg%87OzWPy7BLypwmpwB3U8MAABN+i41nEr(*E)>U_Qi-qf!vgVj8E0VD6`cmDV(j8sbZn$j*k7p#j~KHL+hnsZO&azxyZiGSQgdXQ2{n(XW_X0m z`rhn`8E~SCVr~o^t|GqvND1V+wEM~~Kf*}B{h@YOxoZ4`yWf6|NyI`!Ylu8t>ZS~8_f5%A=EcnDTV-?t;?A}8)z$Bj8_TtJ)Z z@ms)z)Qj~W#V5gkVepG?MCPSyrsd`jjVg~Ipq;vqyzQnT578!IgC#gDCQUy3V7N?p zEjL(O6r1IfOmG!qbZiP4&*-e(l1rK z6)u9Ib7+@{oG}_Eky0L*%lr#B*?WXo|)7$21-}P z51prf)wsh}{HX;yMR#g5r2-ZYWk0VHO$7x5m*M6iH;Qzi(kwP(wiHFJIvZ{4T2Fis z`&>X7rKmwr+DxJ0=akQtYQI$bz@u^=7PS?{IVd)rIoA3!?WJe0)4`8-0$l?4ypjSG zJmCU|Q(n5;*BLo4@H>0cfb)V)F62dNLNJl6BR{JN`sk8AZPCxuAHm@6{P zX#eC`nm<ZS3!*48Ehn1UKuui6nJJkDsZ$5~D1TT_p(da32R z89VEkJ!=Z)JKDw0nQ=d>O)^HzPqMQ_FwUCwo%>;vgGG5ido%bY4>al?C8m|TyWSro zL(Dy*7w}ZnmglZfsCMv}rM?ZK}VrKQ(4HKdO}*w8z%3 zO@sE9e)O8=Q0sAFs1UeqGNn}+%S$Nt!sFOc+fHcD!oy?SY;a>uld(I@>hL|IHaiNQ zXJY5u&71Vfy#JFNwTpW4Glz;Y6y-;0mO}m*E5U4{&zRo@ZeDFt`k7W$tC)!4w$V4S z!Re(v$FI>8!Nj8OXc?hi!c;hP@4m3QaK#I*r1C;b`Be9*diWEPOxf2YKJr4@^-EMp z@9tbRQSwapnw;Ts37lGF2A9WHjeu7X$`osbdOotbe$d!#u})F{+xLh&+UlY^VIqn1 z9?OCr4zEo=q1_rG8ei;du(&Vrl3l>jgc0JQWt(vw4Huu6|0+G|Ab5Ni<302qiF0)O zFN|H_=k>IYg>yu@r{*)oYG$TUD5jR?boZuuEMNSe{w)D~L~OC(~bQtA^!`D3*Y;ij|& zTuDjAF5naUz&GICQUqLxG>-?w0@ zMY?ZWbp4ldd^wX*QT56yi<&XYuNKFK)1q?rfMmNT{RbC&^+w`Y3FjNpM&8_b14$#X zSHxLko~vw~<%Yr&7n=oNU?Z|Fm{!iQ4JvdYOEN3n;yY>@$l48&iqQUN8S34+;7lo* z+@&{x>BV7xL@Aet+KzKy{|=IZnK9gPE{uk`B5MIM}ZhgD9jXx^c}cc=a>mRK+ETxd|;X^FNujTY8L)HL1lng|l8RAKEBU zqjoCd`d#{LfVJ`G^Im5G$3Kgq9>{I+R9n%P)j4VeJZx-I+I8HM54jx8M=M0A6)BoV z&Fcar?T+&a_~<&g^>pVwzizBGf36&T5(f#Gxb6|r zsnh8VtQ>H=y4>$;XGT{5-8j;|S}Etx45JGcQ@>Vll3D-zAsSzhxslJfYjRQt{re#y zYp~;ScJse0v?uqA@q^3V^YUshPi0_eE`q)z3h0aE-@~2|AROK1F_4#fwiWOd$dJ>1 zKK8f%dBjHn^x{ZwQl)wPy@-=J9ziXjB!Z^&KfnI}HhBz_KqRL8!Nh4K&uRo)QV0G{ zb)JlQQ505{c(|W6Hwg7xl3(_yO}s60hT7(M{h$WoWU`Ho@Qj#XI<*?GE@`}SF32&- zCj3ZV{A!Z49@<$L2s}CJ3Co!^J`UxA*g?UN(9nbZo!72ZspSwmgJfiQWP1F~MGgUNuO)@) zKYx~1uSSH(ecz5dj@kc1)<$$=R$%S#yQO@4K5GA-Q^=Iyx&fr2qH>cXz*W7}Vu+R` z!6{84_o=F`#UDiG! zJ%$zp-du++{N)vuqsly@?${w{K9Gw$eWvH&G3cV9sEH3Vx&-lMx@6>Vsvm@e6pe+( z4O7Tz!`q*t7_-9{-QT4nxO7u{=%Ivw8LV?BSyw6Y*Ja&nMB>#k&{iWavO=e(_0(%a&e%u6Tr+tEULWTG#k0JMQ1dMbw ztF%|DO}gT6NnOOZB;-Li?oZH~{37A0tn3FXj zOO6)$%O;U;?>(AGD~Z9PrD5e(pIHMCwCjZHF*JFh`aS@4a2WkR)lLQroMn?B%UrtbL za}#*;U6{|*E^=#T-{UqERz%>v?cs*uI+0(QyH$Ed>%IyBG{nh}yCM!zV8=8vnQr`g zY=J)`JAe3!Hy+{%|7(co^%Df1H>nhLG`Z->!vHlxd7*=~SeH8%-+y#|LW$Ta%}3r2 z!6$)4$>y@;5T^GER8=U#UY%*K9@m9&DK@E*!HoCf+KQuw>hPf(oYq2Z+ z*9GpYWom{@f^|X?QS4VsbBrA?L88gT2NW3ND*_85G`$#bC@vy_wBzQ!N?&vKR5nMM zzNyD&*A}fBOk-{|VZ3RBi(xB$cEkN;0n-ojUV&uTEtNE-m9N51!+JA@CBC=QLPJRAUBkvTL1hU5kl`%KO6;{O z=J#v9F^LS`-D#XQ&_1Z88|r@Nw_GPI5q|U6P+lzsYWJ`hqJB>l zxs}a07h@HaNavNWmW+$|!EM3HU*&l7Y1;t`DZ=)t*t#P>R9lt?^w)%EyE#O>y;}G- z++Z3TRzO)ZK27#ZKBcSu4hBy-qdL)R1%%2A_4vLTMG`qP*ku8D*39rK5Fyp4m(Vm2 zvL(1~0S$X0>S?EXa0lk|mWXVQS0xeQlGHz|PA*s5ec(dFT7U}M! zm+`0y%2>o5qGZ;VCP_OFLf2E}Ug%9`TTM3y335d8SuWCZnklSDq~@unJu#W>TzxuF z!>9aRDlX0U>*j`c-%a<0s^!_unVy3;^r8=Y%lWJj#&HLO$EJW$f z^91vkGMIxS?73ud#2fE*$j^Dd$SgPyJU;*J54`eH->4eZhC{Ri?zUicM?H(_HEltV z-@SQUVNR*`MuN?~=4SJE%h|@&;8lUlxxaFzJvZbZhs?E3w?7|XI0_!_ModLQDvBnn zp<^i~VXqE-%hkvUwn!Q_lc!buN^D|8D4VSTCc$^qksYX5445wCwwn zONyg4PFtIl$#6PCcl`|e@(qmp*$$GsaB|V$S-=h39V%$@fD|S%H)K<$o7ll`WJX+`w!@%S38XEXcGh+E_Wc`Qmk*4 zGpRXOi{lJ?+J!83)PmZ868nw|=m1NLU+l;#5U(Pz_X|x87898Z_wyr?;ESdAlYQ;y zekutXe%=;r-VyJb`t;CAGP2Y#e^sU2IkTG6FzJD{j9{i(YT<)5ulm$ar2^L5?27@y z8;LR(+{ClYKCkxFRL+=TL*tO(JyVX>BON) zR=LA)4!aove6Jgzc}wWrew9Uh^>3v&-;b_>%$v|&`!kw$6K-rGpCJwuU$Ca zf`0VD)cSD;>XEC4{w1W2>+~zMz-$(7R&26P%%quBtdJ2*sz`KyaIlK`wMBP9trewq z@&~U2&Gg)5btyuL_4Rdwx1e6Lzw8;RZdt8HMj=bQLq>bp2<8Hh^>}Ycg{2Pp zx#Jsr*9TTW=CCg$1O&rZYo|FM991)Ao<||K$)lLo?D{|pYME7HEt_Pl8gDnfoY(bp ziqvJ6)LR{R(RKTL73;q}I|~moiInX+pPQ^TCbds}F`RA``H{#HJ^K-P{r8vqFp$S- z=^FJ4`%{-5RJ-h`CK`>LcB)Rl)W7V5lFRP=sCxI33LE=TJrvmR&D1{7X~+nU*7d&} z!SfdEgCDl3+>;j^eA7|)-2jMM@c2nf$%&GI8Y-~+Zre*?MESK$bJOuC%UhJ2m5w7g zq`dnE6)V+TwyVC=uWw^-pq$3&dIEFi>SL>fVliBsaDNM8+keBqIyuNvwHqiWLq)dl zANMmS(+YnETdn-TWQf~4iuJY~rb1nMc_EUAHXQ_2@;r5XR#`1-J4|Mgl^HUb61L~C zr0erc1#P#~pJ2v+u)OD)ZeXHqs7tnl<$w`&gc8;PXsuDc23xTRTj~t*|0brXr>R>a z;HyUX9{0rEI>AKmA`D9c?;gB?K2e#AoQrFeWm_HTu3ToHVt99#d|pfeZ)5J`;^3wl z&4UGlS-Zul&SG)lvDv$Zp3HW|4&Htjs4}eNlYPp}N78a9+`^WxaY{Ii)5}Oyy=#vu zYBy)lZdax0GHmI@9QWU_AG4{~y2dco92G`hY{s*yb6$t>${|a=%6w;=YcgD=vve1` zvvgoLG~zR!&a~_6&}y2C*P!gp@&FD)d#fJbZN)e%jC!q2Oqg}tY6ZoSdo&NS4pNnm zu@Oa)?#xAzp1)_h+kK)Id2-Tg8yh>m`Sgt+)$RYm|8YeaH#P#@SJ^RfW1ij_xm6*d zzFoGZI|BNfztbhV_Q1RjHp{r4?XVpgsHqggz5Bumt`7wd*DRxE^A*MRzux7Lh#xFT zQQi*RE2Z{25a|{h^}`*d6;;UjV1+dKILM`lGt#HcOerT2Q@MNg>p)~(47V1IOAstl8;ykmj^SSF|O>Y7bq;B{7Cf1{KSZ>s0%PjDZub#de zaioWol&=B5-K1x{xL?yh^w_Dht^me={E-wZo4*>`_^YA4p)r+LMc>sBrdS1J=UPr5 zI$fzg3Yxqv&v`2fApumcttT82r5cR+JsuI}$%s z&x_(67##GA(LFf8aB-hmciqYUGBG^-z{O(2xiL>wcuylaV1a*!bieiXWrJ^T6>Ud) z_!(HTtDn5zug%e}lOud18Noc2PKuJp7@t|hX#b1&0XCK1*5I2vEqR|kv7V|T@Z3tM`c(Pm8Be5l4`$~@gO7!?{I zIsxBIRZo}nNOlfbyepW%rtQwD44S((9A3KF&(gF8aqNBjEfrhVkWu!%`FlVt0|@=d zxOmjizLZ3iz?Fri=Ju!#y&H|4W1uG_D_cR}QLI*FRO)PIK;?VXb%^V7VeQzpSwo{3 zRScc^QHnR<%&88nfS0{{OUIy~l@vCy9gY9Ir@n0&Ze;qH=@^WzD*@R0I;MijLr<>> zy1a~S?Ki5PC)YjHf{M%dA-*sG8<2Ji$J5>(zj=;+^rh;3Y4+%_^l5)PTzVZsWegzCBip#HX--1N8P<_)$$ z9;I6bv|Q?FBAlslUIlzNR^T(USI@^5Wd+2fnRIWX&&t@fy2!2P!mk^dDcKgH9oDlOGVdf@{mWYww?F0X*}<7WMus7-KAi~S!!-4`FXFT9 z!^^yuI`gDX_U$$n2qz@I;9W=c;cg|!?yH$^h-BliJw{m;A(6K|Ij1F#>HQU)X6ygT znE<=hB@}CqbKFn)PoDNBNIxaNwA;Cdp<^U;&O6>F(4%sH6mowN%_Q~#4^P6FxPKnymVbl{=BFnuZU8BPgz#b#`NyD>-+By@*h$1e~a z#oueSv{kY5=P&u+9+oel@1jYA4a@PjQ_5nK+{q@+U9#4O zG&00fd^=um9(YUs;DZb)$GtC%pE|kbtc+Ni78JbShl6k&dOx#{^3Q$10F@?PIk?91 zQGVyr+a(5weeN?0+Hw4t%qyS(Eo>lrOh>96<2p#bSJr`kzA8*(4j^j5k3gt1wkuc8 z0c~Z+ktcjd&!@w^!RzqPUID|vK|^bh(J}pbW04k+y|94q){Lx=Upy{|Px;$63%z@` zlWyayNJ+Ka`}wIt4cZSRR8Ncr3f3gAvXimk5uq0Ouy12d%56XV#26*lUFB(j%9=;K;C7lZ?@IA%yB zu-#bMey=MHEexnXe|40hFa{!UqwHZdrj8(r6H49C+`q;Z6}_$$CU@ihl3G}AWxf&ckmM8DJM`r zl`QblzXZ;+idqptL(6`M5A~LBun>;eVbktcReJL@Bp0N~6CSVyT1e5mEI+n2H#duS zO(lo90e{}=Wl4{;%{9%@_;XaB7<1*GbdJ90lzx^jBF}TNu=?0+Q^zgJ4ZTf1sX21Uq+o- zpG~k37aSg^EK^Q2laHu7gp{_n8L=7q?S0;<$$*z`1B9dg1sHOX{o9e(biD-4_iY9` zNJ;S-rA}C&?rEL9=mYw0uvBh82#5NqEDJu=YrUcSbhFDco@dMjMt`viw0OAUE$m;d zR!$ffdE zzo&C=58;)oHf=Ulb4hqpIAd}2a?-aW=n!Yn*hA&-EHW$vZGpUb5s^UFrdPCQe{@^GACz%i{k@-U8$Qh6 zZk?xiW8towmdiC4?>2hhO5&&sQ4D=?VIHEC1{0v4tL3?}Nzl&o5 zVeKa%T%m|7twO{oSQ5PnFq+UMVbnb1BoL92o;jh^WWMCB#dh5Mus&=@nY^ zrFh?*iCB-$OUuSNUWP;oDcNUU*D7G>@HsZx=h+-)@Qzt8l_aG-|3g&cO*9GT#Zb`< z(YfQgjkp_teqK{lTwn<@|b_)4jSje+RjL$4!WP4PQjm$9tx!5QPO=C zPs6g;Yi(GK?T-}IjDq@WYk!flI^Sc7-;Rq8-bDTSVjq{wXL}v3zCxw|T4FcM=m7L^ z_QJSkY0f|oF<=NA&9`3{fu|Nyk4@PT)r9x=9tyT{?$*Ge1^?ucr~VEdRb_Lw{e!)L zVGj4HkF;|DsJ@izt&U?hoIN;BfM!GRZ)-fjh6eagqIV9$da8~aY=53GV*5iXQmPd1 z+!`7yZwRZR4J1R+n5H3eqyyjdxNat7j&)S3J1<4h)vvNlSZ<$$Iqozq9r0#8ZN{wV zuO+UV9~`SsXA7UI9GM`pvnI%X=k_P6M!1-5xl5MCDxvp_fXF8$Ti+}B9Witixkv4` z+!~seMdB9u_u_UsQAU}C=Vx7cLUpE*8A7<8dI!Fzf5g~3 zMLGimdJ_?{%B}P%t0Qj~exI8njS&ze8&w zZ~ggWzFj(_K9_+aU;exr96@%Dmpo{y2Y)hKCOwltbKXR_Ac z9qj0?o?aMZd!-8i>XGNi&pbBA%I8nh5V2@X~_j%GsK;Kbe_#;5|}!! zSq^S2#DB*e9$RBQvIXrv)&NyJ>1$VA>aKT@9&86^al;BwqebM<pgVeLYOLz#U)FGjVB%Ebj=}yn);U z=4gyuLZh{~=oyCu58x364r5>yXeam)C<;*onLQr0ZL^j@2x2vZCgPsK@VT5fWHotp zM&&EFhp)!nq}SNZtmOzDQ+2H0Qz%P0uBd08m?dcfOe(Zla+HLCmjt7%KUKCD^Ej%7 zzXVb~WTBVTzJ0fJ4OqmtPdoH}-{$2Gy_IUb=p6AE#sMn(;7{7Ycd%EF_WMMmymIgj zHnD@dsAZF)5|4A>RTFhbubLQV0^=?37XZCJvPkE=M}87?pMJ4M0pmERFlrTrE}8Se ztbs&-T_8k><39WNWfhNu?wmZULbR~Pjq$NMI5b?WbXlf0F>Z#eUOvLW3Co(bZ_6<$ z*OIM%2D2ogWZ;nF>xASzONS(_BUv0JMhl5o85SZd1}!G4XH3&0pn`thZ`S{aVd_i} zZkx6~#TXyre9`r+Q_mmn588L}Hwl{+bhw-b+-od5UPa}Zs61!>y=+1(@GAS+gW6%D zrM<@L_MJl<7Wx7D`&`jd8GOeMln>BdA39k6$Q8g+YoY0tqk}SkhpiV2z(GTEBIfUY z10b-so+?2!;l(JFeJxzXLfo!hy{u7fL!G((bN0M?1L!rrx|#Y`WmNv0rR@`rNDKgtXVy#*~YvGxVA7yz@lW?9bw2`!K=VZ>LLyD)40acOKRLuC-N zT$Wfu9c&W;EvVhtF1`%(0NzLPeVHY@%ZRT>yQ3$v=ot6Vub?S-!~Z{D65?|m#2${K zj6{%VFX1XayT6dH+{chjnL-N6Yxe?UP>}-X!Eu96u}TkA&66^XJ{T#%4exz>EkE_x zVfDH|BkXqOV|C8+@VAZ(wosktQmwDjjSIq#zAvK1ZZMN3&N28Q!49(MRBzNx!ab1 z=cqzI{VLt^ymv%van+4-pVz0{M+hU21VmvAuJ?^tu33P5Fz#?j)I=teSu*LAVR{*! z*uqQ&au`v|xx}Vu#$uLHS>>>ruld2Km=naR((Gi1#*ZduOn-ovzvw6eOObWu2kpfg zw2;LQ0n@CBmf(A5Bp3$N2}X0yRU9&>9L1Z>$+I)5nH(3r6pZC0?wjl5L;5+nM(g~B zf9btFTHXrd{aqAsJf{)uMM>D^*nPVwj$jZRM1cmBXD&=la6}Q>uxiTuzw;NoKnF=X z>LXH}Z>0I0ei0uF#}F&1;~lRBNk4Z-UkkYre7=2|+iIA)_)Z0A7g+1#luUJNZo@(} z_BeENp-;m}@iqq>TUxTymKH=A7~@bdR*nC4XzNheO9`HqGrAU(p5`6sbnCHD=m%~Q ze~$S>fwjb?`=i^+{;{NGzlB}k>aac9I~B%8@Yh?_4W>Ujz?q;oP~9P2$8Qy^q{{&0 zZ0z)a6F!V~!vCO=&gYEo+ykoRG>p>$-hgH*v}rKoEaewx%$6>Eg9Sv=rAguLKVDWw z%`DIC-3d3cPknO@Cbq4lxnUyP6Q$|=lK3@OgG1%mqrPB%G}90}DDDpP#;M9>pbVy`yHO3Ktjj+a+X0UOX5AwTUYnS{jFp4VGhR$Myd2+r0gkSqvz7 ztcBLr2~zB5pMHK@P{K9{m0PS6=(iQ_hK9vnE)(ij61GTKuy4>$<$Y707U62+&+j7( zI#o@i%s4}+a(U;I=NB~_$&LKh{7X0Cf*E5rXh`yhE^wG&!8`n~728?vsC@!27^1s+ zt2X>&KCI<0ypT1U2N;pqN4~Cu41xS1+Se^s$JEiI1PX8!%BDG!@eh7_6esGIGeM)D z=ta}o-ZL~GYA{t)xIE3%P_5YcQZ%(eoW9ee@|bcPoh9C$<8<9|bMN}zS!9OGB$xE{ zux5?k0@dOkn>wj6<6@Z@>rer z4QZ4RG5en48UcQa^kR(d=9FgYvu`=VeMP(eP(Rs+F50k&>>Iyhl;*zO-okpcX_m3L zl^3~Z#JBjz-X(Js)A5l8-*j3f%c3yNC{Van;%QfLhVgMD9neF^K7XzZ2l2M?Jx+`q zg1yS*^xM|TrO|0mvQ#8GX28p2 zhE7pQK}EVly1PMAx^pP$knaBO@p+#272mbKwdRMvoHOTKv9G=NIWT9amlz&w&+Hm^ z4T~&aSh{!HcXAJJD--60F)C%2J8ih;{GLl>T%wg5c{l6s04pjKokL7olXg-_GnwuyfD%Yn)FLDyx4y^+!9a>F10Q!%^THQC9*XK$@ zZbF7L`2I;)LHY$i_5a1Hdl3K3diV{N&)62kx_tZpivAYxf$66+Lq>F6{-<-9pEe6J zxVv0Ln7*M!Wc7%h&OgCpyy9U{`_Kj$9-{MDcJs;8Gi}KZMo|m$(=!6NHPwakzg19~ zW(jf_S38YJVpR!lQ(xB?z$<%<bK0-)_tsdPqXIZkHk{!)+bVTRt8NU%`Q33<1r_y zAu5*dzPD-<(%7xYEHEec+7Y2qbW;AAbfMkbU^b=a@lF)~)DGEZS+HI41Gkk57vq7X z1_!Ao;fozW#s7-1kNwf{3nj7s*6}r(4AQw@ozZM~sbHBqYa7km@A{kt_3G@U-zOCu zbkLYLOaBa9OY#m7^bG&T>|rLmXqrS$k5|g!^`m^3Qb8CfhRD%@Deow{HRq|}3cq$} zGTT1Y^R&82>c*k&3T#OVR&LC&M$opn(y>aj=c%VF>Ot8QkfI=y9wRC1Rm^Rt^KsolfK^rURSQ(`ks zjbzhQ^Yg?^ZxYRSjY*55tlT^W{vW@aUMUAhdcnu7f!E?}QrIgOaLQctj~ERt+aa5V zWV~Ijw$8R=?O*1_>UZWUQP~A^i&p9?g#iOMCwS>PKkA7-v^W<3@?oGZV!~s2 z4ACEhX1?RzczLH?`)1vnAp!ZEwhl~RG>)vC0Mb&el*!ih(a&4V=#J^Q#@V`Z)?wTK zNb&}|fF%F(-L6m6ene)Ek^fEmpe)$@C%K8Vvp@m`_WEW8jaW z0JaOOJSjwn5p(75YIUl?zL8B^z-!4#9$Go+7XPcvPi8RTfo==#HDf`6mu)oHKQvtt zDS#5<>!d2JrYw~C7L(gwfBQWA{Z$v14^RkMuijXwWnjb%$26*a#04DpC4W)lLCV4tz!hV#Z24{&t6r`YbjW zvaw-8O_eV5B2E%y)sh5|yB5fZjHkVm@c=fnx$g_SeM?8B>!mb0AaFTLu^EokAtnpg zE_rdU=A_%EgZ6q&%s=@HZX6dg$NyF91#EU8fN7APJn;6>;9HX%`V<1s(}??S%es1e zn_U7+SwBC1`XUQ1kh~@1eWRX1vebUEEg)WCl2104M;=!>J!yNzq>xrEd@L)OoEFnlA>8iPKDF#?yeTprzR zS3lA#w_X&4)-&nX6O0`V2$aW4on5c3)cI9*DmHt8i!VY6ZN!}b<=2c(34m+;%E0{n z^X~ku`)B^v+^Gb)0(Y_wF4oa5%6nX9rlrE}$2`#Zv@lx=i@(3_6S2#AkR;?`^0#bn zIbr)bwN*DtctV#&HvZXBg>y%*yh&K)gT28YND|Llc`7zij!SJOy7|xcBF9u2^JE#% z-TNW2+(uDkAk&O2;()GV0!iufgOz3EZ6Y~AN)04lwnqw_dO7q+N?z9;;vXG4$c+Jo ztQtP6AXzO8V^DUKdTpc^qV9I@rttL`Yt`h&lPqu6j~*hEIpk}UzM{sE4v#M&UJjnH zlfeI~yLI_k5zK(=5gpbpAYdE*DrlEvnypIpPwE_zmifOt-^HMymx)oQ>T;J#KOe%jV{SeVRN*QrlHnl zv`T~i^`~C1qaf3j0~^wnZxL}DYukgFS>9*+2Gf-f95%b?*5SWzLO_$+gE=X!SFZxd z4X&O?fzIsWjc0KR<&E&nX!9a98jMyXKvuM@i=(>|`F#a^5a5y5vs)JHxLI-Kq%WI# zJ0TVHK(4<6%&gyfe{6T*gYqmm@yeyMO793vf^>++ey`j%Jf2d7Rg-cpaYS=-ybGU; zXwr2wUsskvP51?Xxt8}+2ey9g;tBC1Eb;Z+?)AnK`Kf^SJM31HxaKm6+o8&I;=yo+ z0#fYt3d#8<+->+aYU{h4v+Olno=MJ^7DmZ_(&YNDQMEP9>+D7#Lp%s4z&iY`7zZG3CUz(f`qyE;n!;)yI-*94Xbnr3*aT$7F79K3x1`X!x>wN3qsvh|PJm zvuq`#X!VsJK2hHP5&DV3H0dq%ycVv@KU$7lM$-Xh==t2PHlYRwdNJxB~3@-GU=p& zu&M^*F}_uO|NXj)2n58*_nj4rzuAVpK)?mNU{+ma11}6{1f0siT_(wMo7q|&;AxnQ zfcDe}<%+5{x=G6`+xxPdq`CQKl~On$l$#&(uVV0I6K9;|D3OB2b>Y_6pV5y?4w6y_ z3Qo&?%!blcOuf1lw@d?shhK?&5QYw-i|^c^Lpj3HwJi3)sEu(B;Dk$WX3`26^S`1iPcC??>JZ# zpHsvlEhz8tOzYEuR84sCAcV*EO9SGSU)TmexriUZIBtFxzCz_PVfV6`o!E17hq8g~ z&V=oTJG)9-CgK_Z)cA^G&t(IlQO}qhnuylHzpMC`)Q3dG&hXBd8jTF zI$&_VIt4Jv?~tON$Y_@+>uD!-i@tex*w)L$-*I8i#vCZk=r6qd-!9hE*LDF^3a^FO z-OEs-r2wZ@m!6e??)yJBOXG3uj#-R<#YNP zFXw7S4a3SE$fXoH^QjOVKmq~VoPUQ;PagnndWXlsHt?%=->z*1*6`>bf-NCkhzn4d zuW>a_*3jL|m*Eb^W8KptD#qt}jK^HT(+NW_fV3j6Jw_Qg712N45xk9-NV1)+mG#jn zRhIU0-=q}4YJ9VW8O@@@Fv+53Jk~0h9jRJ>8UUXi>hzHoqp)i-6q+RVnR4+J(PPNbQt1WGr zd~ON-P?b{1=GNrujJ&GZwXg%TL>D{;H%?sz;Vl)|fkA(qQIW42L6b$mYif0J7US8p zKq2^=oXo0}=|g?kbSZ69vu|MzWMC6jtB4A@=;6T$R4BXnjd`9_oO9xB(!HBH;H`V$ z+3}#}zCyR_%UY9zsdmEr+6>Nu|J^sHwv?7M)mBZSrJOaD0yn7Hk=8D z?5`#)^l0)D6Ws;2!zvQz7PO(i(V&;Rq2jky;SKoq+>jmompLHyPvZ?93;KNND>;Zu z6=6TKUV-x2kY$OOUXL?H{`V4B*x4J@{}A2(k$fnCyZCI!sT?K*} zZj*~?Sbuu_*23YYdGdr1`;lw4(I7?7dnk_RbM3(&_pq^l1f@I#(@><{w8uWggF?`r zLmxjUA*Du3!Tts{R%vNmdx%3VdgH~P5M6uizB^reIgu>yaOtd~mUt+Xb-h9T7Uv=<&BFC-gpTWKz(P3F2s?(`#^H7#6LC~&T3t2(T- z)HaS9RCd-w$!5z0D#H%Ngo=Xhe5OS~kYaL$kDvrH6x8Mo&o`Q(qPnS!whe|2Jb9Jo zel5q7r(Bw})iGuxYTm^dP){mso*NlGJuf4WhiEe`cnz{wHXtlN(6DE?ei-Rk`2C6h zMC$eFES+alpK7bw-olTg;oL!IVh z=l&aQMk2(55iZuuB=OWBPV5@IXR2UJX{=`u2nFb`&l_9_w(m8nvI@9*BjSDGhw9A3 zW1~ltWt6+YW7TMG9;)N%bR$Mc?12MFxY{zE9CNrN_rTct5PKscBb*vAWEGW{z_+O3 z#>HuA*EZ~UFJnnqsx`p+`2Y%Jzp7t2xpMX`pkVBNhIbc_NqgkQlSb3RzuE zG7wob<(Xeb)9!({ZsZOj-8<3OXu#?Z9oAHub;LdnYFZYI*`t&1ZfU(Dwi*-@tE=Vj zcB(f|1BI$I^K&2p4~?V#{TU4cLG?w_?tyuQ9tg|$Ug(SQ(|lW{`OFiA-Bubz8-zb) zx|-)l*yi|^BxzV6mNt}FUP!ENi4k9rVLPe()_zpL;q;wpIzOtfs0QR9Jq%4?cZ5CD zL}rt0%VfLFjbiW-5`H>C(hOfs6F$w1dH)^$poCFVPe z0v1?J_vZLAdC{*5Vy8l`lU&5sU#6u3S`{|_S{#IXDtxx;kLl)s1}jB-6lC(Hc1nn+ z2pOu+!_E~MojDB?Lu+^^>V-;;)-2t*we*=c5X<~vL za<9Gb@f5`*{wD!Mn+d_T_w(XGZp7jH)~E$N z$Mu=Pk>|S3Ufyfbf1t#J8z{T+TLB%CiAt@r#zrgqP^!+F4g}_9jf>_wjSu7#`!_{z4l%me0@6f{`Ks?yMftiEy^3h`2lB)NpA zv(ALET$~l0i{}Un(uni&(m+u&w&PIyuhU!bQZ3l0(Ei#8xn%vW>NpvDn#E*8l?_I*<+-4?d$@>61%D;yGN+IqA9b` zQsHQsuyf~#fKzMQg=A1Y2Wn@^x6d&w;ZC#oV0E1utyR^*T%fUVU^KX}HU{7e*FJp| zMWtTC&x;P-eSWveAme0TT+5peX@RSA!wU!02-l{@o`8DVyyi=V`Q3NZi4LiZP@CO2 zP+@{;_5P^eJ1Oci~z7~{OqpAxZzCD$Sa4?+)JSM6jNZxqa{H6~x|k%7@HB5VTHsJH>Q$+5aN$ww=t9s5K*_IXBa(8$IyFG>YN#Y>3XuJ}wIaJJMBZ0aj_+>Aw z?7d-OglU8@tRgx~9&lXTDPv|>Kqc^QBZAm@l6d0ic$Ly5;fJk0`OGy$Hi2wNF7@GO z=F=zk@xuZ&V~bxfSGg|&2cD8xbAYv_BGMTrs(=J!afUscq$v|aL;VJ%2Cu(1@jZQ* z#7+V(%N9jOaFg`Fn=wfJ&jM{Ylhe-r)lOW=ekiSq7Y`!3mEQj6KQ0&&3C zuVDdS-(CoG-JCo_eSf3_A>n!Zaw71#;F_w;JbOyqcjtkA&bfop5=$<3B)#7}SK zMsE%kS6$AfEFxKQIOc7dD3QLDW(SJ-tzRS-b^Hb3)+`rql-o${Q3oSoG z0e1y2S)L4`7$|JbKfN988{S}dlG;qmMS_9Sx8rTi1%_AL2XERkKm71C9cDJyIS=>V zdM#Q=;MH?M0b(@h^{_5uKfx<2#(;dH`%_u;g`a+?+c=)rn#dt zheb+a(h!`s&ivA=M}j;CZv0h^dfzXEo|xLl8nvu?JT}T%;!kc^)b5Ok#FXUz=nK%X&7xf3#$4N&D#V@74`ki~WK2pQ| zcrvs=KGYzD4??N`3QJw5F<5-A3C>1K;=%cOg;}QF;)4k zj;|)z#U@D(q2C2lqFZR9pcATl6rj$|=d__-u}?doR-Or)4&}kVQ7&H_S(uzA%^f{e zgAyO;d6~7oeXyvxCe{{jW8DRS4~-fWw%?W=A3)swYlc)*Sbq&m$VJi z8jq0~%L)+y1hmXMgL#p{zZh!V3x$gk{|J%1Q}0tE|Fr)TL5N*amrraqLs`oZ7EYon zuowIuVLkz9lddcCSLfy5=eES8A)r@n}9?m_tWrW-Uj_ zj^gj}yivN5lRgxX*O)8G^&mV){c&cMhoh8v=quu)wbRB%TSsAAymp3P}iy_({G< z>*(^SNQ(9dDCnW!t5`d+3&Z>8SC2a-Jo8qm`%j}qpSct@ZFT6wRxqnEov=%RFAtSI zJnst~Q)z0TIz?5}9KcisM_e_F89#U&}{4wt(TPbh1a}Xvy^Egn2g|!?qT+ifJNz)-43s55RoQ zi}d-&A|kD|I?H@9Ur3JJJsF%oC-V%t;AfxBFpgb~k(6L5w&1UgtrI#(aRxG7vx-@|Vha~vY9 zIYw?Ec=D&tu=%_R#>niU(g7+LsN_u52I-S2SnGXQ;hlQhOb1bEx}|S)Wdx}m4;`PQ zFA3IR`=Tg*mF7#fsas2zMe6$X62~tWVmNjf@jG|Pp1>%z?@A{S8#{iJm*cvOkKTo* zDeYan4_QoE_Bu>CCJ`8&er+l{MsYQn^!Kdi&ZnOW2dmo#*({LJEbe)Y?YabS0CQ8Y zz3}fBAZLPmHJHz|*nnYW=JC6vJBbB?TF5s880y40gzvKysGre$xj?P=#brf^Ti(1a(+FX-!IpwwKE}K?z=Vyi+c5X842mNY0X~4rt6SAn0fq*sNxP~Q{dN0>h{OI zUwjS>RVjb#4}9^WJ34q$ z@+Vk>GmBm7MS;Ey>uUVWp&Z-C(1p;+=b(O&akaWCc!_)Pfjy#M#WA?a|Y4d@VM~EkmaUJbe#5Q5f3G4bFo8oCclcit| z&()2Ph1=A68E`tE#k_c7Ja>_~U8HsCKx$GKVRK5d7SR@@hK>L$UscgN6GMz{{s0tW z#6~bZLQEc$7^+|`-%l)ef+Z#OPpwl=gcQrzoge+4;rQm2Kxk72Qlb6W2>daPET{5c z#L*ll)iKz%hi8sI>gbbcOb&?G)~P-__c?u;xDd>nQ&hNRr_Ez$?J4^0HkRK$l?jya zev12ueEG20v(}#p;KvVGbfympiSN`BU~+y0;F#*C?3~BI87#+fn+q0KCQ?y~GHcfd zb{A4s7}2{2QKcXj@z7LjHVhAs#p#T0smNACFLg|d|H66pV@N&jkiQpesb)VH<{LdWv)}L~TyA-*YQ1_zgA83UD=z_bp6#2dZaq zDD3dd^R`~gn@%pAQGxfC?dHx4R;J1cp$38yPF@Cc>nVlk4j9YO7GxJnsaBV8$g|LD zAn!;UZ+gv$fL%>MPH)haM^?TRJ^@Mj^13tT`F4g8idAElr&FY8-3i)a*_6#wk#=3% zdkeY3wZeJ^38n-PJ35+JtHb@u&k}T20z$0i~@!1v^^$LN!l`&k7q{K)tT}xuI1RrM8N9o z{Q&?X5*9az#4JUy0{HJr{+SJZMRgHq#f{YLrBEV-jVk9-TxBeXKf?S;#2BvgT-G4x zvdr}R$}+U|?wrzylPUc1ypMU7GQ^$0Rxw8y6fSCas3t6t`w1>p6ikekdaoI5>d{tL zy(}~_A=d)!>=^3fiU@v^p-3eYy6vszr$wJw z9+%r+ZFJAp@2hN8e5u+LImvs7J;b~fJF8ff&#Tt=ipMmXbb>HqWs!z2Dl$a6z~2KW z_JRz62@eJSWH-T|?4|;;8##REZg#IiJ#l@L-A?#w*XAxaqRxFXnX4v4!vwDu!0)q? zVZsfyi(}wUd4UyIfQqZQ2*3Tc>ULCjdyU(0G^{vnyo9;2;D3^?0B@>jN^pr{+DK2< z;}5ynA81cKyF4jL-x&1A`fav$JfW8rTjnE+v7`BtQP<;B<(!4O*#z>|sZ+Viifj}} zTiGs$e@LaBfOIV?k#KCtMU^-P+Do}?TGOA9dwG^il$th?o_n3MwiTK_T?qVnpCUe% z%M(7@V&-^XZMp-&qRLNhswbM`lB!cvQM&0&mK7?b*4f(z^Fj!ezz$3!;GYg9Gsr{( zkjndHvv)#8v=8l!7L@Eht&#fkLX)CA%oFZ>w42PA=Fb*VqIa{&V?LqdoMv4$m78u= zB;=gVHLgx2$bEYvuztW;l!_$GpX5w<&V8|zygH({bHzw{`(a?Pn3)G_%TCKQ=@5yC z!VV^7rI*j|WxYJx3L`o&mycZI6hm zMhJ6+7a~8*8fe)(mm=Y&XIg^uB=09;m|a%ch$;EwHP+8Q&R@TtqEQ?4Nx1s1|6xz^ zR|)*4-j}8Bz~aKaI4(x*jAg?kNKRx)o1a=;sD5py?jtP8=abRKF~!>)2Uhz{QdeVrU-?n0UV^g&~UVa>CaQ$$>6!rG3 zi8VDsp7&$rjAz-+lB53``eB*pK%6%^4D<1eHQl`k(Y9?gHQZA*bmvUjTb2f+8M$Zs zzTtyhO*LOuQPTFSn)X#H(66te%OLw_kNG#MeRg?u|AhH^o25pbY+{yCY5zBCn5kuO z$nJJjqE$FB)AKD1-&V@D)SXPgZta(_IyaxEtaGUqGX757*6OLF&^*~C3GFf*`dZK6 zp0{1C+ugxb$V}oW-~6Y6nY=+K{9gleJ#bzORcR9LWYCv~KsfKz!Di^6i8~(P%9;pf zApGj~#9qjIURZ+SBK3P~cf& zY6=k{3GBb!k7R|7#&WIk*KX}dJoB2CChZ)VD^9$!TB^35DqT6+%wudxJ0ADw@nxtI zxgw~&2(vWL`xG$pqfS2K7jYqeJ&N*!2fcN-+;K2?La}brg}rq(|H=Ac_>j--FM`q2 zSL9xsUQ)v`1_IR_G?nxGWuIW#G$=*)J6bV)8iG#TF6WMZB?^nr>f{w+N<2JEN|(5% z*VLoyN%L~NJ}kTi_xUVv^Lw`tn1xq0W{ zd>CxBgYpmR6ZJv^MiV+gq!?+Di%Hxchh98c&;5~y0BeSss$IzHdDZOm>)az>9yI8JEed2Wd)vG_<5~bhi0A7zwm(4$VVlQy|1pn` zkK-H7?C}BUR$J?@=jv}Rh|3*Th=0L>$}aZcv}tbtC#2T<7iMaTfc?a^`6RN|Np$LLANgDVRDD;VB)V=oxt}KOqD#O#lkY=+Jr+qDAb}BnA}w=Y+2Wd*6|I5}fQ3CS zaty58xb_?eny>{sPaUsIyjLQ9hH|o!B`$Xbl7#o>bT68;Y`*hNXp^Hi1H$CRR^Qo; ze4y=^r_*3S81vTSW(hi_JUN!ly&NlI2`^^2{M6xQZ)N^~EU)|;HQV9mpano)6vOTK zl$De^E8G072W6JY5tgfLf$Kr;dHe&J=4!G4>{pt+WPR?*+#~fOoSmL}STD~Ztg^7K z!R*r2HX2|n@6Y|`=fB;Lme8L=%qq^Wm$^q~*pj&NNm+^RRC#b7bdwe&ay~jjn&{;;1ACWk|qZv9whTLm9Seksv@?7VSU zn-5ewNOIoXFaL$S70|h(-rV_iq`ZjiHL-OyxZ!LO=b|Ha?cTP`Z(9%P`PWXDY~D_^_nj@>$8G+TvRe#vCQou`|e=6J5d?cJD^(Ik@aL!%A;1VrpmCGOLUS;-&(_%^T_lgN!fqWmwVu#aQ{gs_m6!Mow z&VH)UCAQyIvb$`TnrA^1d2YK;*ky zZ})u}_w`ht;jA#hZ|?5n={<#4cqQ0E+sj7giLmi67LmG7Kt&yNhW-Opla{T}X?ml*W zwQJ1mvdOkzC9Xnl@9l;VH~%mX%hi*k4Eh?^JuR%KKjMQ_I>Po-J?_*4GfZ$YbiuOd zmUQ;)GTvzF&^j&v3;u4$XU||!i%+EVZ2!hR-DNWA0iRjZjY_?u-R$j*c+>5YwmUPn zdtL3v!Og z#*?b;F4jVI6?^@k3ltBr*zW z(Rphx)JVqY*HNRFe)=Ky5tFBs80tL9*xnkdA!HSyvsV}{b8MEG$3}d zLHYc0ieo0j1h_@sq4D*qF+>=d(|udfA?}T5OcUa>d3D-svYR7WTQbD1bnW2IkcWej zjJ4DBZyV01Yj67ZH!k#(G)u^2yyZ56_1MGTz@dm)SsB4+9AvAj?ndd{V_NGe^GPoZ z;?X5DKGhGbwdUn^wbtrOe8cD2w)^e z_TG>9R(l8|W4PUp<5Bg6^BruEb}5%Yun2&BfoHBJ6b^jKJdp0szoMZP$#QCEZQ{u` z4@T@t>3?@6&uJ=ygR%g%erT*|kSPt9IU;(J+^8w^*lUeWtGGJHQa1gy_AXp-U8HgLpW7ax)h~rSDkQmhQ&M5I; zamX39IdAbzG+JNnsV!wegsp9aqwiShl7Khr%W$8};n7jq*(KRu}+Zy#4~7s7U`R3**u5a!ubkXMK{Q?1?1ehrmbRhjKjSE;4dz%MD- zFdF2!^(@PJS(s8N1gSl2i{APq_pX-kIVdbVn5A*Qpoo9EtzPD^D#zrH?`hOu(Jme^ zNMM3_AsNWFCU|zkWuECQ%RqfudkI&+$0YvGxget{U*BZKtQLT@$D}6K7()*M1wdCK zhb6)y#}Hgmet4Y56eiJ1-9yRE?R9?|o4vUX6+GG}CR!L!tGfEyqw)4B6Bcn! zdQVoS9?}Q3AvNL&IURPUP2x?IKRzgm3px;E$9XXZcrxJWqq5X>pt+63o31T$vWcJj1!_!hUZpHF-dKZrQI_1F zTm1eW%L@?f5c~6%f1zp71^0skwx7A_hn!-rOB&^QIT*M)eATrpV;-`-J!5kfrdR-b zoc||>%GFgj-_GXN{M^*D=dy(>lK*>BJHSaflOt6&e*@(^rVSy}$5tPDag=Q=D$S`M zQm+HXi!8t=H{cN*;ZA$_iuT=92|`vm3)q*PlPP6tK^$JEWff})>sPvL%V^&n67xmg ziLRHXTF#v9+P2&=&)8Y}B--W?l3^P%B6j6N4hu(_OE1*4@rDTVd_SP--VtA#eGvLo z;6vzwihVJ=eHPVX%+*$?+J7|++YkB?Zey9+dwpsV_G9*m*~1^h8_&&@@H%+aSi!gx zD7e;}$F;7O{GDIIMIO=1iO)Yi@MpSFi0f*Sj*E%DNPCkUg)nlVBUTa~Ql`2Y{5k$q zyDN7*)RK2ppr9r9`nZyZyxTCCsR*~|p6b#3eWlSh!uHXicMcZ<%c zImTi6s7e1$}X-|k|+NHu*cRQ3tt^A^9-F1(csg=6>Tu-ST zYo7Nt?`C)WHkp8@(~|7~i@n1!Lo!;en%+3q?&4yKhgG~GnW+b9SeI!@*V-*Q%0|zr zR8(MtD=Fa2*b}8Cm7)N-EM(6TKXgkUfUwkEsDX_Cf0jo9!X2}wEZdIo;h+}*B%wXk zkZ{4vr+xR|<0mbgNJGbkev!GfW8(vCcmUvpoS%&R*!XEE)1m51nY~*AEI+LN!%E|i z$=?9-iVAsJBr19!CXDMOM65e)-EypQ%BAe$f!DIzp2L01VyUR>{!kD_5+Is=@X- zRH7Cqs;Zl%Q>EzY;=j@cZa&q9!9}Hl7KHBLBr{rsfzvSTF9RnAn2^!;a5+dGHcWeI zLK#Jur4!O@7$UvjEJ-fhHpe64RVJkt>Uo?OW*AY#1X~G~-_G!&RW2zDbBkUs+VQl) ziKl++7QXd1eynKwru4VDtQ#PdqCfo`CRuO?z5!GhSiuaQy~cFGTbh34zjqOg%_a@V zrIQ&WWR;lUm~5Lo`pvgR{pACk`}8o^cX2#wzy=y9f^2%I>uvdLsVez9W#=kAmzbO< z*atqC$gA-n(4^~wVyMz#Ue^rUROQ?Iv3=6QoArqm^uL5g9uF{}q7V<H0UV+|<87uzIxDG$OcpOMeD~W-U){F)#tMavsRS7}0 zRg9*4trOThECOBVEq<%I$GjHL58fpD!VU zjmm6_wye(~pFVTmrYDxiUCN@j>gHHElv&eD0BY&?9TAy8fc5XRU z!Gjcoer$mtLxBHT_11xIn8gN32*mf`4ovh_`y&fJKy3yJ`p-5`)o+Py&g=@-dGcD< z%ORg*HBFXmI^tI6-i`3|TU>co%2q_2N<4DdZ;i-imi4i{xG=5t(%NTd_l|4He0ASA zKmG#z;;S|7V(chE*cQV7>rbx=z{FgIlKkezy?^i zV~u2)&+DkuFSY~VRdpAX0ot9%(>l~p-El6V2Q*QY_k?GQW$kiDVn+Lvrf~}^)z1AJ z#8Z-r0KmA23{;>upMu>gc4k9%pXlWIw8I|ymY}N#F5umP0$2Y5jiMm$Z!Gm2lnhi1 zwZZyIv>71>d5cvT_OEF_%Fd^iphu^%+o{as_fXyh$yUor9 zHg%TA?=+KuwW7iqi>?^iT?YgYwbi*@_xQ`_+--vjssR4fY`bD2jJfs4Dz5t3y3o-v zV-p@f|K*t;_q>5C>Ya?DLCY`cAfg$__a=faY~F{J4?2UZ!*F9@fQi7S?Fa z!^s;#21*f^{Dzt7n0nU{p2n9lo$4r^`P^;fdTRXR(tB?@Z>XMoYd0+*A3V?gLg>gs z0u+cg4Aaf}scP=Y^;W0*GUxiaIwOKk6|75L?OY=!^R;IcHKYK)8~L0U`TKk7%=)Fr z&Fm|r1?}JR^h56d(+d%5a`5v*(mi*A`ovN!HReL^vL^FHD|IY~A?3OLLO7?=uQG>Vw7a8HEW7 z3lu3KjQqX`JFfQJEYRzArC&Ah%;~4?!;Qj)9^yN}U_&2?3(2*D)Idg-JmAKLXY=Sp zRem-uWX*R-79Rx1eHqdlXoBs#HqyHg6;n$m`3bt!Ckf}@(1hXW(#lx3*XA}zIQ)F8 zC-Hk&VZwPPc$$flZGI=3+`i*nrBn85&)~ZSNmH%%Y1(;rW3_j$Z?P6(Z)Eq|EjiTT z58Xg4x4~F#fu(>>6JilpHP)-e#u|E)m}{_sL7NdB3vUTiUc;%-%iCQMpNGWpK`5T@=WdgPjCz8}-h;Hisn=~G90jPLJYRSs z${yKYRkc~<&kzxW37$0F?-+-c?wC!C?Ua%@om*PADATfA%RYGR(_6*DsDH5h?#v{_ zh%A11Gq6EBOU^z!r1|?6|7ZMG1`}zLh%mJc#x3nGi5&rkz{%PNZ>QA1&(JExd#M$#r>beoOF!ptn8=>Byd*iI_O|bo<@mJ4x)W2(Q&K8WC^FJHYKgywbIE0xZa_MF zu%7`J#K5|F60sX@lwAOtd5Gz6O93K&4{y#~;T}X7Z05eE`mwao+=--Y8bl<$XO;$y zbN$+ArPd%apWl96+ED0BcOC)Lj&7`Q2$+uaoN1M8J6gpOG zhhN!K^j(3bY>F?fV+doo*Q?Vf+`P$--l8ml(Z$VjB~qFG6fOW!O=9hrWn(J@mw z?dqBunQophJINs9wV=`_5>z2wl6?8uwDN%Q^t+8L?t2;nt5B0jBd7Tj!oZWFt%kE7 zZr_~x7>1*FPJ)jTs|pc>W%JQ<`qlq&3Q${4G;LuQ?!E*b#(b2Ayto7mcYuv32STR( z7WKC=dIVBDfP2DCD|y(KB14*76SYsbO%mHXLX+9OT+kKdIm?~3|Am9tTUxJDcWX03 zTkET;{`6vWRdTJiymn|_{rwtUqR#SCN-yIvJV|ZVZ4}PR-(98AJtheR4}GlQwslQ{ zGY6wzEWb#Dc`Z;*W2LZ@iVx3Tr1_MS6YQFJZd`a|1Y@xnYPHW*JARVhfc-}@SNQV2XxibE$ z5vf8@svsgAlwPA^2pt3g=`|EdC<4+!=^YiMh2DFUj`ZGp@4dr!2Ynv#nRn)U=lzik z!z6dk*|TTQp51G&mC|NjnMV+*mybH|HNqyAEPk2^)ZtbuaYsxCHctgyNw2^0IMZB~ ztx?$`@TB4KtoI-dV&4>J6mfVDxFQqCp4;Il2`51#AdgG#FmFaj?5uSCzhz*Wv4977 z^mFRH%q=G!t%Sw+uQDMAT>2@^^<3!*{s%vy1#89hhsHG{q6pRPWZqr_d(O%DT|F%g z#JK0XSa57y`67jO$1c1q6c-stW1ysxW7N#RI+PIwW(xbKUi}Q%`05aX zE4}Oel-PLR)B~6#MY&f6IAfxN&#XhQ`y>0B+joegi?dF+L|yECZNWeq9ifXi|ye?e~E|bZkyR!CreFM8RL2oA|h@HsMaK=2QEq; zjDL6&zzp^GW)&FbzMG9l0&RIxn?gjqTlujHkU{1M4T~5P`%WX@kngqf zVHSRyb+MO9r3!iX*=mQ6X5H6}N6MA!JXNJ4h7Zp0FgHv0C zD}>eRdzI*~n3oVQU?T@VhZwZyf|vpmIAM#^*e?q_ANR0^i*zyjq#*Y*O`9NHSvG7h zm$wud1EpE+gk(K#uK2?Q!?A5WH6>nT9%CbAkaqo)yWA`j&7IQ{Qzk33WsH{r&p6qoZngc`i=OP&_ zqwPgcZuzCVHq+Yc$V`(9ORj_ouvl9RtFcFMO|?6~?6A%HA{m{=%7j_TiH5HZ_5!yZ z7Xbf$UFZRe%=qd!Nf=PN26mY771bnm`7eMo41GJhH$=lM42sb(m@LK7CWPy-x9mw) zq?9+u8{+wyE)eDI>?fcBt8r&vL%Zb$nl3{@(zC9l{wqdckYM^Y3s z{}V$W<@IGUAaPr5ySFDQ$2-LyxTL^PL4N5l#WSpI~BBgRROeR{6%ob8G=>4 zU1DYR8Fd4F9daIVd1drejbZ^vPhsJV8r=VqemN$4?(O89gyvtdFbw<`KrPN`BFD^y zC^;CnvKY*RjEM?p6dwa`Z`QQvrQ0pH$=ApGgNJm-RA)lc%_Hdrz)KCT=4v91rA!DP ze}B&J8`~YDGzTfor!>gJrmh}1yRW!%ILoX)a-L-?Jj=%|W<0!A;H^Z8g%QIMYDm!k@mh6*9gq@uw*idu;XI{j~6KVWJM{Nd@R@^Webr!?XZLc+P;0 zJ+c5|AzBxaAxOO4BT&?99)(g*q$Ms^Kg*ogeLpcnvS1u(D$eWM{}Pr{G~^75ay}0? z--dy|cvaf6nCV2l`@3#a3y8t{)oPtkVU3qd1+MpA+SPT3hjXP>i-Yli*dz`6VtI68 zbARD-iBxLb+#%0b^1PgRd(XD&ae}wy9=LFA=Icix2bL?uAMH$ZP(K`sI4x9oHYJw( zIuu6Ps0G4`%jfdqB>2g*7&|q3imSthk~g(oQmo^nO&2Y>(%NWrs@v!I;A{>#cbXI@ z+IYrl#+ZhTgM>k?Uw&=%JpA!F3`mLAdqZG@C)154 zoZfucEXxn63&4wgXcVd%M}3;|a&g!lG~B3N31E&deHwRqhCVGlDlb2a)4$+TJNFWx zNdp=HIDcYtS)d2ZrrS8svk~m|_TIIw(?;6wCIo8WT(z`2>@6+ZTx>)nUDk8PWAtaL za|Y_V2K=%6S!&gv_O`AnLb1t4v`c;PmQ90Y3-F*u4=qf3`iT}$Qfi(L{Yhfa#6E2- zcc~G$mOQfBQDU)vTXq-{$ey3I`IOrNs6ZWXr9-C{zbf)#cmVeQ+p`Np#K8Z;bFDI? z{E#87Xf|S^BKHN0#_3f!{Dvgzx!vIVDc`5>YQ6dZ;s^MvAqM#{T2M2VpP#32_;?p{ zZtw=IHMzMark`vt<*}IgN(mo$;|2ex?Sxn1CT-0njU-y;Jp;p!T+^u|arX~*J>G6Pkal_PLI-N8fc z_?t9Q88WpjW3c4NLNM(NwAcJiZn{$NOtbzl>4=!pP1*~?V7$*2LvAI4C)L{{bV zR}Gu8Naa(E{cye5IQ!MISd;KGy+I4_midMscog`)0MF+9Txjbz$74(L2dCx8<##;W zXI@V72AlseN()xkEPvc$i2K~j1&wBlM0O_3U^y$woYjk}mA@20* zQ;$n4xJx{kS9QowZVa{4mIv+XXT!kBh$0>J@H$`ybkyJo^J%1 zgzXJmx3GGmTBpiuBsMEd`tW0yLllV#JVijv_X{I7)dqX)m}TxhhEq(zGs|vrrWC!@ z;Y(VXA13)|6uH(XuCb5%*iX2FGJoDjjePI};H{#8a856bf}9wzgt0ii?)qMg?s7yq znPRRdCq@%_rDkA1Uuq~Y7C$=;zt2NcskIzFckJ}>I;l(`{i--?MX8Six1}7_vPmB` zaa+a7&En%G!+9rvzeIAea^KVa#Dncn-ZQCs$BD-rM$IihIJffQ|9_Y_Y}XeE-5Uo= zT4-Rw!k2fETCB|Jvg_21f{mdx-=tot=+}RzjJA6i_=N{H|NQ`;nJ`u+$9osGR5qP= zgIX%IMRe%%og!5_x^K=9!Jm!IFZUPj71$m5^#&rC50zfc@&)!0N6N?^68QSB?y;LR zdF&M%OBz5dP&a|N=#{L2&?Sdxi*EO*+v-N%tZYHUn;SrVg{_X0{)?*&{~%|_)8K$( zn08;>{i0)7j*qT+-}vzqLs5oz&R#G9fHLz4fyy5%x*g?6r++!yZwh@ED9d>jHMTp4 zZ8Z=K#ONX1F>j$P-Zek+hd=mn8NE_;HyuON*|2H%sJ1pG)@YW9qvYUQq|Y5Umi>kgi1=MqYP`k(h6x0=nqzMgg(FJr7R#i z;vka=J;1-;h=d8gPO9$Txg&4P8kwPk_*5=~W6x>%>i7{737d*H90Mn^bM^t(eo{Q0 z{b~M06Yj-M^+s+AGGAiHCk|J3A)r=XcBUQ|kP$9Nu_PU^^Hj|bsk`0*92v=T^AAex zH@;<(k|7r|N&e<75xNDOo8w!TFl^_AF!sNBXM9PFwF{9u-DEpq*?8;#;Xg6rF{?n% zpR5f8#vm3KG=tai76Qd(zMJ#~E{O;4^x^PhCDE5_uT#MqOy+*CM@F&~6I zf2MqwckcL_{z;6<;WquvVBuhOW86vs*@&jMP;xiCC;j_@X@FW% zz@JUK6$XGeZ@ui@X8s!Y?J;lD^L4);Fx)n6@ze;-4_ro1u-i#5WaES+G2w(xZDr&1 z&g+AO9wqWTd@-CSCEI@Hyd5={1a1ik@7JFpaibB{Y`HVDkvn~nWPGr&*ctoYZTTd_ z2K=V3-V1>Ao>Obvxw(ocBAkx4cFFn^`}&P+ATk8WF3!#~ikfUC#HfnLp$W7fc6{l4 zzjcS2s8+pOz%zeH%5amdtt( z0DGihH!~6{V1!8M2i$?3G6{aND6jte@LHBYZW?5`ZLnbgin7)Nq9q=UCF@z%n8k>g zhNizcE)a`W^gLlfUt!wOCBHbey|_u$sSgRlM0JTH?X;a?B6A#iP;*;@wUnW@?>*ud zg#^Osr+oof_-)fz={Og?L%DE-(3ON7-Q!RBI5ng9@nU5PMjhzY-q!++i1q1TLDqk& z4-g;23Dm4MWDW;mw+Zi1yLc^`|#eLz791<6_KvQ=y(db5sm!i z;PvoY^I(Nk#b?JdTBFlN)et7T0G5&yDdoeA?;P*~7ya(pp)QrtY?I*yH$UXr$20K) zek)$`+#%=fujGOf0Op*O$RJ5;26cMOSZqFV);Z5C))8+*A@PH=KU>S&M2>g1MUk=FHt=*_^Uo{;`lOdFA%_6s_mn$Dw z06r;4GJ?P@+isHH_Ox;I5i{j(ir|LNEeAy3r6pa`5tQEallLUiaF_MdUvQ_y)@Pvq zj;GRR^F+OPmu?j-XzxA9pej2j@v_9LnfKo57n1t^Fz$M4$+{5U{#eiaQn)A+kK2{hRWoCGkgOAvow0|B; zBG7b%G9e&$tJHclWE{9I%DLKv**7$-mXgCe0lBxf6n}h&^D~_4i z>5KrUQsY_-cd7|OWggp6MNtt1Ae3RcIsgpu-1>4!?oM$Knx!WKdW4+ zk#RR|c)n2KmQjqvR~TN+yy4zKKi2%b=Vo!q!n-!>nE6#mSkX_`5dk<>!#LTS`h(@o zyKmZS{Swp;45tP=CX!~K`U_Bc%$?b=?O;z9`5L|oIJi}jtFHpzn56NFKd0w6dWVtwi9GTs^LB=J( zdOSS8O;&&Xy`s2PWArU%$=sSH9fYNoWL1v)p*=@=^vw9C`f7 zZy$*~6W*& zUWYs+vJ5+SxR-e??IG`V8N2%h&C?9|CiM68{Dw!{wk>Z?9roJE*hUlwCro3EjY2rd z3UqVHDL3R{y5(uH@KnPQpY(a11fp3 zG^dgp3F$kX4$*>+$VNd=)ItSzJSABMJJ@KnNpT02exU!Do=%KkZA9)Y1U98mfDQ^1 z0H|odQpn*pJa&eAR??hi%L8>?sX?Ypmz!7Os4+vIdjwvL5?{wh7ydBX#@e5{jSrN> zE+uX>F`j*shX{J_j@j@b$IHsL_X8mv1CJdeklTD@FMXM1yfpbK)N zt);8?Y{Y`GrD*o>1&Cs>r)O-=XYI_jS7nXa>KqHdN?Mr!4v@)HadnXi+T>;tou}cX z?;+BV!L2kn8m>o&d=kQ@XKBQ(_7;9%W#8p>puJt+wkKJ!U+J zrW*9Itd20pMNa+P`d|(2M5FCv3eaxNipt{;+E+SDtcU3M6m}}OfB>ScjLe5dk?*J; zK`;_^*ZbRC4TO=w|oQ(xwHXTa3Gu30E z+R!j?Eze4!ne-8x2`>%vm019353On%5ylhvRJZ&n zz~t};^LD*pOPsdgnf~DWnn&N9CcOIO2MBOC36} zQ?D4r=E4gzbv<(awzOU|rP)SM>Nk({K&^?jsdE6 z4;w{8JG&r)(k_>8e0zC+Oe*$xKS+pb^|p4#QEcS=o@11B2KF~|SRX#ng<5FvU`3l} zu&t{X#i-EU#!~))c*I_CLuyi%bMz5@Bwk_*=SX2(8iT1SZe=?7)7uZJxG0jh-$rY^ z{No#6bREkS#BwOq02KH%CXqgp0V|UAZaQkN7~!hcJ5!%%{Sy3#TEmNHL~l9v9enfF zj-c!m2e5+;vuVR!Mp9nlF;kNewRA~+fpD#$UcFoy+rd`lBciL9nRJN=9) zt)DDmUB+q@^B@Ia*R_5fpk$ad`NTx#Gkn(ZKxtAJRhWrjnrYBqaB(MmptgfJaZ@aJ51ES9~DBuZvnO(EA^K-Ex6P1a4OAT2WjIw5#8zEiK#@F{*T?_ z$-qfn+U-!%^coEAp=kOmc>U#pGZ3f{MeY=p8)JkiHHZL9vJ&rU9Xl1M8!71+phb(! zR{Uk3C5S!+DIJO}{GnWlIU6brT8C<3N3 zP%!PVeFemG^q@)EsMC(wdI9qCY^(ce)dNVyD{+C02!@8nCmq`(TC{$Ar;Dwfw{sGF z)kuXedaCLK4;bbb9ac^6UiYZfw|a3gOsE+F2(`|GW@%S7CIH-9hPQrpqtyV5s2DQ+u)Fj0B@eD*v3kOfpJfFWkJh{wf zUgoh>U&p5Ma}v=JonhWb(U%o)3O{KVM{qFD*VZ=IWPxX5aRs15xwQq7b`SgLbSd`= zRKmj~?tK${@vw`yRY?{AR~is!+2cEDXN`ZU$9he`wNg}KVK`fgazhoT4n9HiI&O)i zI>AZfeTSOsfTdKSQ@g?Ogtt zj7V-%&Z6T~uR%0_-jkyBa-1d}$JE#TI4$&r>yn$J(|OMyCv>(fv{ofiZx;QihvO!6 z2pE;aEQR|Fbl*&GD!&c@=#wbG z07gvBJHrC7TEu5Fi-g6<@^sNv?31!xR@)v6)VaZ{b*FZtG{ib{C8u&|Qt5 z4os$u4$D#1XigyA4~pbTl5{A+ueQ=a)sP&>lsZ)Ta_p5K^v0f`>gWszSrs0ZEEu6u zZ-83^`6P}~yGKmB>dfy_7J(O!d4&%N{h}f{r|3^2-v?*a_0^`(WHvSQjOiqB6`25p z5@G9J++x)!PXoi++$Z7%JpR0knW>R z$PKNNjD9PF3gsnm@v=K)?o{t6o(%MOq=SVQp1CX9Afw%M%A(XOe*AtfZV&&cW$1pD z{ZN6vY);O*drQh17WJQNm0?4&kxQDr`-zdIOE{H(Jv84NXt8+_h^g?W4|^ z*1h@xoMf=)RIYWLjx0swOO3A4$k`W93c8GJpx^^z%hJX?hPEf!I3%9_09oLp@7@`? zaZ@?Z_xINghFBX3C@p>vJHAP^^l84MOR0KV_9o!#enTvy&S}i&Ex5*<%%M@~O3K*U z?Mo+wPDE3PemBsv@NG?DCCrYV{NdK0b~z2bfMH+$h!Z7tMd#vT7NbE@OV-_6yMr{K zr*`bpiDtBcX?Ebn?;7NcMMzKoeGTjEqQ!$^RuU~p)Oa&t$+0TLVTRjtHGQXgl{+1A zO?lKv#_#CXQTv(1RGv(sY}Rd!x2Yin#!dTy)_(m#b6Zqt^B3CR((T&oDS#Z(kgCvfN*46%LfYp6{5 zN+Gx?x62hak#2vFBRK1!x_;5y6v%;0(2x*hCHnR$*ZmgaE*&j-B4_!*_6=d`u2W)T z4Fsy19umv$P?WC!mD`^`f2mEh(ZknU}{*b?!LjPom0rE_6mDM%Ip7|wSm3om}nZqoo9ew!sv6R3g z_J@X>;#ch6c?;^$ZzDJE`)BCGT`$%5Y+wD7;NQa0+QB}d&UyB2rST|X`uqO<42zcR zhp)r59%f~{XC~q-R<9k)?!zEq>zuKVv3B)OZey9KKX}P`+3t9~$PXd54$tz!VPY~? zXH~U?W-!|I|V*7HT0Ii%}j?yiUQZ zWwqb@W`}F{FC+iu0bt}sJ;RgN0HCtz+sW>__=N4AZd_(~Kt`%R`v%O);x$;$JN41a z93}S^1AFKmYFaAT5;d51glN2C@^lRkv#GzGR#)fPKjuE4l^Th0E!(2I?_NGK&@kA< zSzXb5*>3C2PDcOh;H)T(ZA;O^y%T7i;XvC6$C)enoEpUjOIliSC{*Wbj46$Rz*g`Q z@mV1)qd#qI&f>u`P@xB0WPS&@uVY5wX5J}X?+~piNDuKfC7(grGILH|#JpCT0turN z4}WP4MOWc2l!eY_b9a0hQb50+MWB=;)K{-jg%^V)?G~8yV~wY1@q4>vYT>5A}wTn{Mg>a8J0>N z1q|7V@Ny?EWU!xx-7pmukvcG9v5*V2O<4{&tqbH?E@-4gKJheE0(OYrr(gG0Doqd2 zwMu|)mEIcq$Yx}(n`$d8|r^~<$o(OffyGmp9_r49>?h?Tek;Mpq#B%>*Ly?YK zA$#EXtx)#BqLi`Xz2^ODPMja?$MB;sDE<_YfHyC8cZ#Wv@6{UCU7~G&KPZA5}hZz5; zM|zSBCD=nh<&J#JQliag_nQJQc<26r!}FoJrer(Dhp^pxYEG`ORpB}Yjk!&S@&;~M zim}Q2TYYe35Z`0?9ClZcRvdDo^&o8bsjD)iey97RDfsBquvhvliJUA23S2~NJcLdG zj8}iT{ZuAYy!a#N9>#|Ps_`(8chzPpkkj*XabEqiODZ|euX{%Tcg8<#l_NuseYb6c|e-r5bYz1ZaoET1<} z(NdukoHY7u9cTewjpDr5RV!Mj8c4rmjQA+gIo@IA8*=uuMziQ%i5Q%}pN_2=?!o>Ll&9aR9=*=Q z{yEX*^ESC!2Q%TIYHMUhbp}s+^E$p@2`5$bWH2vJnkY2EZ!m+wX=|_vl%7&0e^enuBxw&Cbr1Dyh#tIKq(Jkd5L^4Gn3#| zDQc0IY&3cN$}+@m!~Qfe+nX1!ej7-oMpd1cCEj*%5(ZK<s*QMv24Oo)_6YlKVuFqOY6mQSt&1dhx6u z1+a+#y&a8^731;XTBo8Qb0POALkkiq$!OL z9x#|Ow2{J{v=56q4NP{9JpJ}(I!Qcj56GD&xMIkz&0hKKj{hX zm#nx(*Sn*<;^nsUZWJY0GzO}?6k9yvTz_@KT+EuR!IAl7aV104q%)PrD@9_<}Okl8(C{{;aagTqJjtX_)meMzgV9zBZ#)y|Lq#IYmi}p4Q6Yucl*}OVS zAq{UZb@}qJT!A#lm^@Nc%*_YVT0%pU>ElQ|7vZo%sF9Nnw=1%=?_(|eY=T?IThK^$ z&7LpaUVQcDGf9l(S-oxd%f@%dbSz%9JZ#7UE>G=bsBcjS_OG}Sm}R=U-y(76(6cTf?~a{5)Nxf8Lw>{A@c!tt z*Lga3q4@%Z`3``4E>li34s7qRoeK~8h(q!{WQ~7LVK_xopoCfLeeec!W*9+Wppcei z7L<2a(c$=|j+=EfjzW>2=s@r;QS&2sIXs{H7wD7DCx zMHRgrCMLT3*QAUA6q-4Rt$d)Ogf;nnZ=mD?*BiB( z`24HWV45bG0sw1mh(!zCe-pzbwfe*WZ_s>yzFY6RlzP4-RcEj%yGb}Q3WsTCICeMy z1{*8Szkg8kO{GItggdpGNh&?3Ji-R3rEObWsz7aTtGy06q#fa~IdziiG@#qrNEc+Tp*EPg!>AOelA$NdOqCZ_hJhrm6F z^-w=+Y80P5DPFX$pST2@@FQm%OnP8{Fg#FYDW$s;={5x2i>ti(=i>Yh zUB$=S`Rc}V5Q|%y0=;K{f1%p`k0Y%Hvc_$fDPDVKkHI}|GmI` zqh-OfOeffh78>a1Obb|uz=l#gfaMW@+G=Z3PSGP$^;UWS1D z1yB82+LUHsa2@d6y)hbvmip|I@zT~g%xfyMH_XWgCO$YJb~pFy^t`=szCeIQ9Rp10 zZ(6tqmjME}aaOlQYalb(T`*DZkqtI!V?sHKt_SZ8XWb*y#Q&?nFbEi5AqP(y{UI&L z`$h89ZWlfmEYVY@VJn3R7_Zj~%D$Qcr-pER1HI*VYsNX#@qH5IPm)yEY*V)`=l6tv zbKAt?q8!?0+TM&e0|QL$Wap#dInU-@cD_uA|1!jsq=hCkU3PG07oas#a?DvYA3^Tg ze7I2S^PA&YfC1$F=)v=^vW%ih-B|`OEP_-sHKJ!wRe&stW5XVbpHHf{-D84Db9w7( z6)vwoAy6fRund;U)&sB^boiY_MKGQ*gh- zh(b)&X!J-Y*Vkt+rp&#e{A0z1sA8OeBIVK|U;f2F(9cisG@;%exj;--nHu`kTeolh zm018`Y@q{ckA4LQsoF6yY3dZpm~(P}G<2&7(o?@)62_AI<~sGqrThfcbdDpUWcoH` zLA_ZPFtwHU+oR%d=!PRDX^jquhf0eITlOLo#<4Gq2!y2!aH*Jy0hqsYzc1I-$xr23 z;>aO4?tPJQT6V6Re>A@qI4fD|nqM1_VQJd=(H*HMlm>H}c~7;b61<6uJ@M|Th&EdP zo1sz$-E835o!@&)8s~KxQ7*&utkMZe3)%)yyeJuy9Q~ON(KT8aDHPcnCxQ-SoTVS?d1l9@MUdNmCO-@TNKS)c0Emv;h%i zirX^OPY^eTASW!J6#U0vqPM;+@M}{={Q@ahD>=4r6t5?ECwc9s{BW>SFdk63?cKnA zp+AbdlJ7fVtXX1u0I;;%|Q{Vqo-NhvojwqN0S>27CZA z2V{_`+SxHhO|jFi=8Kx1M7f3x1sPAoc~`6DGa54HSa73cgZ`lCgw)PmoL2(ZDuHaY zo9QKH%)}+=PY02wqgQpi$un!4=4}PI{{Ag6jx8OC6%DKexFb0p)b<2F3vc{gk`L@S zAt#aUmitMIg*%onr)e&amF>rz%Imd860Oc<6`j#uz`;5ho^QF`i(5|MY9-Ai%XNp> z1H2ag&)ZVUX4baQF33cV@rKV3AE^`1AB{M#O!quz61ltk9ON)w<=FmnpsyXE{1i8} zYcAfd+S}dU zy@ThVUEVQG@;|2*fcVV~cCy6S_oR;3clA6u6TU*Z{c_OI z-v(SagC^Q#b=--}U1H(w$R9H5d1?Bavo>x@ao{PwQ**!%ppBIgCX;P8&QG#yF-$2b zDhfr)eY52_eZzWDBRWO|UsYOno~;wBG?iyVw8ecW@cXh?Ciwo<>ODY7O8hZYzFe*J zXR@zB_2kgZX5Wc|VWl4)1HHE}885nKz~2#Kl|>-LOq8L12mc$}!Y?;rMj%6jp(y47V|%uKlmfW|FCRLHfhkSOofY}}m` zc`RZ>c0uNz7r-RCrzTc;iNl)(os zm20PmhzR>J1dsmN)Q2JQwbsNp{{iBIFy^qLu2pLAo*2Cs&-AkCbUxbsp=jHN+zyOA z4Upqmwd6qb6Q9)gM57UUt^2LmR?BR$-&XQhR54O}QN?%|g$&Q4@Gx7zR9Yzv+bQ4X zfz~Tqx10>LNk7Y*958*z*k@g-^PE)w;K3$^`1Fk(F|GQC^<-ZdJ?yM?HIS}Uc1l4a ziWiEdU`hsHyZw(p5dBAEQRpsj{`?CZ5!8-NA%z^eicu9dr?a2XPwE4XvHZOeCP z)qb4%aKcRxos{OVr zx8|2t-$tfx+44lY*$f{Gy(M2idoA*#80X{5A-hQiV?y)LCE9}|ucTsFn^#%!5K(Nc z;D+p>^cJkOmhqoW=QIZB_z^*DF;3;;;^^pS`tD2 zNw8Tim9K!avI2ZfU7gsP>BsZhkaHU7Si+w)tEnhQ;Vsh=7lE^Z`#`79{3TOXL-7;L z2h2)%iZ6T%#8t^CH40B>j8XhpB)zW*2F{jZw;I4SQi%e))VC_(PXCH z0ty`kINl7~E|T6oi!&E&_;K}LD{%gYGbh3Nb5IQ5M%;GHs7=~rdBFUFUhK7)wIifg z8Mf66IhRS{?R`Q3Jv4XfA#nV4ucMsuR1@(%Y)iv_C2zmDs)IhpmWOF+@oqpdW*7_u zT@Cq;6$9RbN~K66^vw-UH&7a8jtx8xQhBqan1O?>!vO&0H+WFJcWvXdg}|Qg)6p+PjOzDKvmVz5 z+2m@h`!ayWHs|?@9jb0j=QuH-5K7m9-hf5I^CznrZHYyDE%bb61)8_M08IfeDzOls zbLyIg(u@?U6?xeDyUOwH=5T23hn&>sSSzHfO47&h zM30uumAsq8Kn*qXu%_K>1Ifj?umi#jcJgoqfLb#As*%X7*c-%vx$sP-XkPlnFsPtI zV=b~0uxDp1l|o;hm`4w9%9L0nssA?uyG#I3TFE_obdtKY&_k4QGs%4LVSN|6b)w@j z-qW_Yv6Hpf`R}12onSIki7S-3l)i(fX(uzKId3H?PmVj4w*4JhZeouY_>;@JQy?_O zc{3_bd0L`Q43*9Lo+}d^zjzN&fOdR#r<5T}9qZ~)2!0A6q6T1qajI3vsf4m)%>Bn< z3ZorY1;ubL-7Q{oc3%*bJAGx#sAnBgVRm{_e&yXD%zsI+PD7yYYD^CAyY`fs3W&fC zhjIBp0=d!u*x(a5Ug_MoguX;$DQ-^(C&Ncxf0p0*y3C+XV1i2R^)(bG3T++)pC$|F z;r1AeaAYYC*8NcoK{V%S&Yh!~42MAL5gqzL>&P@7q1C*46Iz?E5spXXRtLd-?HH8g z5MCby*~tcEYk}3~G}!N~S`R1!+VC9i{U3_}Zkdu?E$!T=3)K*{VLjv}7to=B+hmBt zu>Fo2_GnWtK!2~@sT;{cq@Dxo@#h_rHCubz)I~=)k<)fVTvEZnNDbV@UT|?pNu;$6BHq?d+1f%mnV?7onoZN;= zNX7`|bfI|~L^5$SCdxyLc9N6k!;9m&oN+px;xE6d5am;2iYHJ06UGK8HU9^~_~&73 zKJZy?!RsQE$<7jd$~U_*(odLM%63?-cDLn!Xp^WRu+8o19S_1zd5%i~gCZDtbJ&#f z{h9r4eB|7ySdI%(gs$6fLu@2ZeqyHh|Y%Qt@Cs>ReK z{=oU&@ro$|n)Y1qY$jER&*3BBn~m}Mg(BtkFv5_2UX_cFotxRK?EZCAe*f_$(&;H? zrb)e39>7>dBAE+piFRGg6vYU-`IJf1n4Ub*K?QB9lj#Lve#i*y=p#;QK-E7^`@T4O zVgJJkPhEbEIAd^zR~JnPkH4N)Fh)8myA;_a7Y~$LmSr>VFVPgwPlj*jWgtFtj=a_8 zIT@PkoF6}^lm}B%L96?IA@W_P07U*h0mA(WA*)mW3`BBVYbq)uuH-b|BLTvjJY_o= zsne|fbuQMCI=@Lu;O;Rfsvx%Y2%A|EL4wTQlNi*gDO|sER-kL9mzkbUeX@oeDmwXE z(cWXDD(zpf&qbcI*RkDd3>#q|ddm9-@9&cg=xD!`T6XgW`QmKJ4Rm{=-=Rt%+}W%-2e;9s4nGU=k+ZGqb|C|0Bhe#6BSU(#0!Qx`R$70y^0gh=9ejhh)Pf-6p6}rbcnrj~T zcqyDUHjq^p`4C2d3}5a;#(LBm-*kct3&sk(Jb5bVH?;C@r(n!)qToJH)wK&P*YT73 zFb@vwfcEFHgqMymHIX!C>X_a}ZT^EC7-qL|SP6tc&Ky`WFYdAq%j!w!=B$cfL4cx=T!BVb7x|v#e=wlAsPGpk! z*pGPjzWFdH(rjzY*nuc>K+lMcjl`P>C(`VxLjRJw=goqh>_*q&)xC{-znj;Kpy%~K zPU1#1-*Me%iw5T-?yoD~=os)Rc05!Or>yZBW9k!6eC?;mNi$Y2A=((KCih(H{ zDz2D;uPa{pyOFvv2Bs$78{kEyd*2C!`S5BOsFz$TV!e-_xwePLI}*M`(t(i^GaD1@ z`89Tjr;NfA^9|vAow9pOBBk)nVTYMaB?Xo5OScW}WqvQ&Jf_1nr%)y}VsmIldYezU z<@DDIe(Jd>c*Jta-md-Z=tljO?<#$*o8DE4JapaE8)|z3OlmwfK{@W%EfSDBJ2so! zIoi`9WEml|EfG9jU`R(-U6aR>yQKGQ%iEpBCl*6$d#Ii3S2OHoXOxR(@Z!32owLUT z?0MFt_Z-0>^;bo&Px*J?$-^%mhHeWAP8GCD6hxO&{+2nu5L&a=b3hoG;yXA_{7zxM zAWWR@=apFHvj&Qmc}C#pN`#wrS0zV=WZ@FC%2qjbD%(9JhZN=VB=fOD?zWuQ7Iwjw zYnol|iWmh-B!YmZqaXbx!6_DVJa4JDG0kQ;V=ZDzRhMxK-rJUI&x49d^o15UxVd*nsauNSRlQ0gW{&uF2 zUI^xR?!N8gzn3})nDP}u;Dw)q-kr)g^Xu|g!dJz?mt+Y8irwuvt1?G*!5?&Oh76B} zT`PHxWp@csrj6yHGrwe()Q0H*SefXAwkYQJ59aK)NZgux6Zcx#_j3cQVH**orlmVE zrDq*_*`nBGbab^Ay`-0P{6}cc$`#eKo{I@?q%x@}P}|wrb)x3vEUJoxDq0ElgzlsCU}&qP4W7&S&{!G~b3 z3iXnA_gcUSOf9ec1S?W-7$oJ$Boq*3P4L*hIV4`XI>*z`7x`4%A%c}iW#KCN0d6UgdQ%`3x^cwy6ldd?&bk)2;TqId=h*;aziqRKPIw-WKwY`19 zll1*_P!zR=Wneu`?>0*L;cpLbET@(z{IMg*r5UKg0wh+ zAJWWnB4rui=m_~5D{F6X)V1vmD$M^-ig&Jn0>B-1=p~#Gy)%<7vR8B%=w}Fqfy6I|wmJOnAKyaOmlQ50Z zQa51z@}rYPfRgdhVBia%3@G)8FbEal@`~)x87)4|45vJd%(Ayi`lJ|U3W`b(e~a|j z!||zwK=-O%Zee4X$r2`@|K~v1?wnkXXZDF=wn_J+^UYV#g=^@q2yp_f>~fMLkBf1g z0t>Vx|2E|LXi-`KFQK1eXyG<^R&K@mLSdZ#<{wt5)JCERWjMXi!+F7qh2ymH;4wxf zIs6OJ?`1k)XM7{TTKXT}`e%uSsOT|u@4Q3mJjO7Sld2RuUpfR>2xKH)1w10@Qra(_ zJ6}tXv*tB?kbQS3sQ;43!1-gj2{rG`M|I@9IUgzI`TB7Xf-1Oo$Vml{EJ-u#v)DEF zwBt*2fBIeSy!zLCs6goXh|>O}8css3z_2aF+CKgo#RK#xI{we2z|`bj6k`0f@qbN% zsvmO~yOJ6^CKSX!v=zrG3%ZA0Eqy*F6xLc@8Vc`bq1@M662A*Up^hOJ9Q)k1e~5 z___S3UR4f)xU$2Y9d$6r>jmwV6PWhJ()kY_&6P}&m&o1KArTiSfCr1XT_)5~%|BY_Wp>-2;JSz0V<#TZ=GNDz%{C}eo z3OLvAKIztXFUM58QpNXsxu^h%a&_K^Wmtju3>)v+ZJ@HU&4sxZr2*Y*@6FS z_(s5I^5bq{Ra$pDE1V1N_nS~AAbb8r>36Y&_W;~$(dpA_iSOm zGKRupWv)4&`SjoO%tdBRar*G^mxo<{ee(!uYcBquY)w5Y*&Dyo)RQ6kFUensrD1XNV;hHH_GoK-JHz53be zJ+aMyRDbl4GQ8qn>59i8)_DGPi$HICB#$?$qO*r;0QJ+2g#1>-E`TiF8hgQY)PfH6lIS~7$ zf6PO^%3m`ww0w39%qT?5FLS{v>Y7tfwvooA<>BH874{KDb#-;^viY=dMnG)=c1SS( zH)6f{!UZ6b&!e1Re2bfond3!Bwe!UZE906Svzo*{trto<$&!tP3B7{|B)VGGL z%T~9HJ!YViCWsnMiBZ|>Iknf%0aot$7b{O#_=RU_x6U;YxdS3EhrXdZV!kme@F~qs z(6euns+FdRotutT#Gw+?oyM4~p7e0YqLaPpr}v60pDmD`uK(?h`1*$bM}Atix-XJ; z#;=XWW>Ag041u?>>@R$Ml>NHeaG5QaH6Q%FY?ooBbA`cX*4G7j3Dr`Yq4V(3s}H@Q z9Z`kI6}%7}5}*AJFy767sa4;2N)ET_YkI|Q8BWzBHP#lqkht|R&7HYWn!PA^>TY1n z${2AKk#Y;?Lh?p;N5>wO#6kvN2L7Y|wP~*&EecFB#M7sheiRj6U! z6)`^T?68lnauct9RG}BS=+-y5-n<>Jgl0KGayrB8MpDD4vvyXR-emG27oN!YjA7AM zpL3Xcat*C7UAp2T_;lF`2;2QzK*6%_lUHx1!Sd%x2I9Z3NN!Hxr#Jn0e=NU|rNQQU z63G<+@4Gnr~sUMQDPr9E=Qymz*}&|&h4 z<#={RSR`)hlo&;Q>Zj-4Cjh$gSZGgh`$=L9b>EYo5Ou#Hr`hIs;`-+pw_SBd8)AcL zE)J1bCxG(V)caAL8!O$?UspRAwS{MpYjqN=<-^K;A1Qs^M`p_?NsRf{Q}Q4UWUBfb z4h6~FoNY5ai%`ZlN98iS36`6^C%G~=I6_x9^n#b7{?y4EqJIC<6}x;1C_Jtz8Wpl) zSoLd$Iezhj8`BuGQ=;?crYDN^+-pk8jsnyXQ=`zlx}9;BE05xj!B+inney)P;9Wm; z_$ii40sxcR=uwOP zIa+A$6eaHSb?$M2vzynZx_?Vcc-Bl{*?6er#%$}`#W#``(u>e}h%VwSc^tPe(c;46&Qe_C1wIAZcN@sp=W(aOp~VtAPfd>spR#o%rQvr}ue+ zWC-dHAgFgoHLUg2=vzP^t{?BQM#i2WHZrVH--NwDc|I%NTpZ!|Ds-+Y&55md+hpv_ z#YQ%1OC9`?|BI~GhhU`vt3MU6kdCOYXclT7gYwWCN*-wYV z#~(KRq-w4Y4GJ7gwG|{e{qOIMrAw}GksLUse;hajH4qN_`*&^umFQPYx%n+emO6HG z<|LF7C5D{9d?xs}bVx&wuFLr`^{975Zhp$)C`^4l0LRQQzzt0(N_7P}u;*5b2n3>>bX-?|1zxw7zX zgh3=&xFc@-;lKIaCjY8-FVIoch=3#TKGf1$j-h}7-6YL>r^?>Kd0E*yjL)Q-;=r$))b3fMEoi~#@QqcostC{`Q(^%`=x8*I{oT{>ED*15& zt_bg2KQ?bKD|;AKHo4}~4KYKiSS=bf$W6{<%AeVDcdWQf$S1sGu`R#8aak47j_(C~ zAUuLOV4Jt!33-2yOuRKoP++^9md@{u=F)~_GknRbnWrC8rL6K?8W2w`Qg`*=(&ZeQI7bzC z1#2P3;USIaBwnjt0IQeiEGns4edG3m3wt)VR3)^G;knrL=e6ZFx z6oX=2KgIVd=h5T08Bg)HH@zS!ju!HOQ-a~1E1tJi&Pdc(_^W3_1`WtaZ|(gxbn7tp z=-q0FE<#SX@2Zy6v(lX#K-WY6)kxtpm8G^?$gg{p7O?qabM3NQ%vP^^IpP zkO{kB0%u=PG0c}aDTc}@n51AFUF@06rwL@NeyvAZKn?Tftd-@e$N0nZy`D(wfKG6- zac7-~%9ZVzV?!`_ZJ}GUP=#lo@w5^Y#U&F~+Z=U$766vzvyT7l^*BUDx7&=hHM;^Q8{n@in>B!fRmXpfQ6;qaP%j&xDr~DQOD&Ur>bMy`f6F1SV81^Dn-9zKI#ycEdsIJrkU zvRR|nX=Q4p%vIHLpjauj{qyqZk@EENd%5f`86b(KCT2H!L40gWVSY5D=BSKQf^f3d z##3eU$wY3Ug>MQe@DAzbW?l|1fxcqyR=#N}C^3nwiG#(?m)`dXE$gqfCbn}VHv;S3 zAXu|o30%hc7|F46^`zB8FsY-sTvlc? zRCp(qAfgP?Xx!4!#oyIBRP}PI@t3IB^Me`r{QJ6e>}&CUUO0TPK0zjrW8UKwbS^QhfDW-XP{X{M@3;JC`7!Qc4lT~tR>tC8s)syr6OiOzI5~uejXXB zxm|_F=R6YA@mqxq-C=*Q=nr)4yG~N#TCn!ZZ#IRGOqL~9mo}j_bbb|3xJD(jK)yFDJUb)Xx%R36pVeuZXwdkno4o~t^53#V*x{m{ zkfCyWW!S-cNIlb^F;Z9vZ$ibs{2)40o4t7KdIqfzb^DSrnTQ_pZtc_aGgoGPFxB`j z&n$r61FGL9g1?TP-0ItK_IZN-sX7@kpO+E15?PT~Bz%=! z#${;#=o@`ih%L!2ptle%;aq?=vbvwG%$dC%qGYQ>9Mdt-ywDyk9ylJBXQZR0BTbbq z&=32tsa03NfvtC)$?R7#PV)CMDzmGhbrXLpyV`#)ANTdp#4U#5PL>6Cke)}L)i=Je z6iG$elfA45w4YY=W}H-kS%wIo04aG5Ezv6t$3_n3ryN~+@8|pJ+B1qi*4gLa4 zGv?+!>FSEP(V^>Gv7Nk7>%?^)Wlh`z(^{V*Y^^GyHoX8FU7US+-Tomv$D%v71}ofw z?;^{WC40nxHUR$D45f7nH0xA{V&BS)4b09Ml3n+_^Fe+1e-fn`7J|%I3=-c|@Sla` zT0r4r{bZ}aVZ3eJe-mOr^d^ge=;A$lYhidA-!ZL$#}29FOc)R0o$CYrtvs*p^UC-8 zh+HwMR{A2!A1RqN`zG2ZcebBV334iq1^t5}j^|i!QG0Rvo!H2N@2=5#)B|{N4x>{A zSnJDe{V`(r+FtMniyS3tA(;B z+@-q7L;apf{*J#ck7iGU=;C7y@l1$AV(Kemjd=SF)i&w1Y#M8z@VM{9C*O9G5!W8nqEC6DM9i`+M~E&DUwAC)MT z8Lnhmhw4S{)NIi9o1%xZ5jC81mTM8BBSK%Zy>lY_QNiNV?$roWylh?<+@`a*cUNSj zFK-O@Au7-33x+jvxflB?ttzs=bI}R1w54=10eJxubVZXjFNe;zcP^9@VMT5-wsj;( zRske<=9=ufW-ox$QRpk$Ur#9N$u60F8Us+m3BI!d$01b7A&M?9Argw|zL&uk)P+dW z_)dxQ&PW22Xht%NWbq&myGqVG$3f;m9^-K}05TYVCkV<7Ua3pt=Uo4>rJ-82j&~@_ zT|>_&(LCwavK!f>L?}4IN%!XwlmrglJ4Gi?^&a};JN-oc73SbCnnDfj!B@TK|qtbx3UJfzpu(eM%r_*jairF##mz3&A@ebgr< zdl`!Q`JJ8RF^YQcEM1RfkXY{Qv`6tkw)B7YSPPOlczAnzij(Dox1AVy0-E7!B(_BL z>b~9wA&SH9>&tOKHLJ6MY)gV~Cl7?)&5zMJ7$QNYBJ=qUWQllQfhv84BdV)ONq91t zUS|^~r=4vefJ2YAZgAAk;)ixw@;JM{exSLVgo{YGT{+wGN}1<2w6k}yYf)L0LaBJ! zZQ~)`>hB!hsQH3yG28LWUv1At#Z5C!%)0VME#DDj6im(zEXj?`_&TnV2vsO+s1}1| zw4*-hDP+f|+7=9(S*eYL(mb*4lxg4PI1}wwhgiXUMn+wqzgfnm{>#2JszucnnG24+ zE}@?aNvB&u|IF0NMpq(|ki4|%a)jsAqr`aslpEfDCq*uX+(aY7n+*AIm_gow%p$Qs zh=g_VrJTF2J4RkLv#1eUtX~IeL1O$DXJVIV5x{E&cS5UPZ?mz@0|5|o$Y1?~fWy87Sw$$;TKTUx+u!aylRqOxK| z?QZ7-p40D*{H0$BJr1Q&AKOSoFi*p~$s7`E@50Y^7Z%LAQ`#4dHxw_?e)fb2KC1gg zLzr6DDIkB0#~nk_>KDnGFTA3y5x`&l2Ca6fEO9;~aUgfhXz*Ul) zy=u;q<>$3VI!@8}YVd5dp8PCupm8@X{T-x;j*tXJfaX{x~gUpvsxw zTF`-8aI6a`LBVIX=#uUHWxc-?IKPRy(97S4{8Y%N)*#O;ep&mR!^hpNAI1;j>1)2X zn&D{397eop_WWOSw_mpPa_MMSz{2Rao69It`_(xapnDi~1?!>6Dh*QX9G*FdG z!1+wc%p5kov{&iy*KK?Ey3rVHtfM=a>T|vnhp8jS=S$q~A{ikTVMPP{Bl%w+fm&?6 zMa;(CKQqtr^@8LAk3@JO^vn<9m(ECEMAY6ZMf#s9#5XVWhZnjmOKBy1N|&t8W+0c^ z?QCrg{rx);+hvHIJ26;jo;5cq=)AnKv0>=s_K1@rGb@WbnNV}-Qgi!|9{Sthfb7EK z#mp@6`weeiKU7mQu@<(}iJ-_7xBC==Wj8@|p2(lc>i?>FJSDUh0h= zD(5&Uslwb23$y_xDKWFclFELXz#o`Rb*p+!KFd)LJkFAQ=(lG*OXg0oq5M^)3o)Ve zz&SzQ<|;eWPv#KH6PRMzTR1BAD#yYQ3~v!Tm`OJ$7y>+#nHlqk+5>}`rQM&~jyNz( zv_%hB-*w7vlkv69eKoWVp+GsDFeggg#h01cwuwjrPJWtO;sq5f-< z6!qwYU(YL_(OUuA0ipB~B6FxeveYd@5^zWx52Q5hEk*rS-}w=NbC8bGd_(Z=z|t&^ zAv-z}b1pxslhg+HWL+7uB3&?BHUNlVEVTJ{77(VBBn*XIHX0%^L8;OuLq0(vfi^is z<{)#?G3LsbmygINB!E>1$+=Z>PhgXPzJ&mNyL{<9S-wokFP8@Z;uf%hW5K0Ng;M=n zkQm#?RRi`x;iL->N*{p>0(#Q$2M`+zL!oXyFyTA@&sr%0B0;ZK&&x>KB@Up{0X6Dv z$W1)o--Fnw3KWi=AfK=~GE(AAZc?@Iae3ev#6o{C7aa|>1-S4jhjih=KnMB+WJE7g zsrWqrT|fSJBLRPTzG*&DGMyU|bm-)2GjMeT^A!NW0X41yoHp(}7(ye!rtB3&V&uC^ zPCR5V*Tbwzl%js+zd@_qs!YU`u|${uTPgD(>co;Wh+ z!F*CAq%rUeWnIyxnsd#OBS%Q6jL3pt{gwxFrias#CPT~e5`v8%?tedEj?sgUAD)4_ z%bJP0`+iX&ZSlFFa!o)$z-?j^m&6{1|2jGn(0GH<<_jrp^dFVEr^PRZkg~HG|72%3 zPVU3-OiIR~Q*qDx75eNftg?^B!IB%$<-v8LRoArk}$>VM$kf7ZWk1W;icR>*aO4vq3kpUrYOiu~ddvMron7Mm>$66&?KQFC*Xi%( z=}(QL0v`nj41-Q5s2bck`dj#I=UI3hD>@AS5`4I<(j02ch$i6UuzXBibx3Xyd=gz~ z;SaWgO;DV<4@XEz?k0@`q@WNwX96(RcO3=v2mfLK7INi-n`%~OW=e9h#JEi=T$s$8 z^M%f;+QkcJGBcCaEiJ!y*p8GcgDlDUJ9p?9uQVz7&}iz|hwUET>B-N(`nX{T!?;f2 z!GrToXk8qtP>vQ;1i73T;&tYyWX3deKDY<(1GohR2^o`KTe!^RxIj>LaUrvaaKj}xRXTv$JyK1di zhvb~f)~_>4RgM?HB8HgwwVQLq@nW;7+g^dqzq8)y_g!1Fwy)(!cw>?_>@B}aecY-X5-gO`+! zr}MJ$Q)R|nlNMfIp)%{8RTiBcb8P6JG&SBrv0kr@n}A+ds(~4fvj*})a&HvEzP}RW zY26SE4AoG%e%AxDbdD1yb)y!G)vv&|1OVK(^!fNtGdWtX)in$7bVQ`>$jw9sv)szx ziL7K@zqwn@KrJjNM#N@LU`zmtUs`>AMF9G+{+;Oen{upuO=3FQx#6CiZkofTmID5q z9==Y87t`XEKcRfK^{!z1)rO#vEmLv_Zn+xY2MCwR9uCIhH&ZJuVEXN#8kgl(_hq4IwlymyToeP#h zS65d06vfC)YYy4R%QP&SBN#L&7Mjo4*YL)tcj6d>QJmd*D(u6G@GB##kZ!8$u4A}- zM*6sGa~JgLykG7vzSik`=Q|e5=zD(r*AZiy>NJ&=KI2Cix!)%9@UpUvJG0S5y!@NE zYigCQi%XlYry$1RA}Nh0AZb6s*Iw^b@l7Rb=d1!$jF*%f#v;^U8YQ?D0xWQAZRgR; zAFhm>b9z23_^|9pC3l0Qu~#j}GE9xDdOt~4dWD}_)g!HWqI~D3|&x*U0Kg-6S#~;<^g0Phn$5oopOt;DqXbVYX zcCT4{jmwe4cV(7d=b8c-ph1TCFm`&Qt;lp{*U4Xk*K>|#3HLZoUN$2$H=;@be`jml zRELD_9w)ns^FI4v#rZx8E^N^rzL-~W-j26Un@e^s^tN5?in!Iu&!;*ZJ(5F^Mjl$; zc^$8wQoJp9*6!>|f{nVs@s2;fQnmP+1|Kcc@`+mJIQ(VG_p0(l94N6VP2M#O*C$pE zSJHz<6uE0pA#F%&L#=aFBi%adWws;tS;5%jUB<+<4{fn!@+-CYH>)BG?5V40Mws+T z7*jqjLa#HJg*RSx_x?&XTFSC7Jq)GnWjHw)h}4xVebALE#e5?jbwdz9M;4mNy7;N8 zkGgz>n25c-v9M(&4u8^RT2EOst-Z`UhLIl*8;(9pT$fgid3@%uY6~JOcI#&ca@34&NxGi zzjj`Rvz6RhK=Y(`A4F?B}hq4N>yR1dypdAnNQ3uHS% zdhT&IV$#}IYrE4d4|SZIY(<*LfI+!-i!-ZHI!M_9`zfXM=7LqZ{Au$dMnH3AL(c(x zOL^H%9b;Ghz{4a#xuC{4?vCO@mg~KKtx}inn$V)3By4rErVGloax^1!F4mn*y8rAt zo+2n5X8b)_D#7mEtQT{lN=Q)Eb)2gKE2910tlMV~TyAz8-GCnaeR$SGDf*6Hs;0Gv zGXSQ!u{CPigx~lrV6m~u>GS1^kLOan~pYo#CzK{ZJ=IY$!i-sesKO)J+vxE_wFb=AC@4{Zf zbK*{(QkO;PxC`vIPaGD08Y(w8Ek_xllO2-QUn7fFTO}bQy);`ep8=sE z?M0tO1-UiBiuJ;ceznz{=|=sPcje@tVRCwkM1izCwM);s&a>g5%o=)3A) zV>O74fvyJMemwUb6ICjM8j!{0nk*wa5n3f>8za(FhGcEXECgTFBTw|NOGlUmp>}CW z2*nzWjg8)(-hP4ZzUEI01CpM<5<<%ucG?R<13#{)6&xR**>ql7pcPj-O!9kudz)~6l!Yd8^M_8cKZ#3M~^{t6 z{mIgC^=m2->+MT|MUSfAn7px2OWpAji}WIjqTdY)wjT+`f}@A5cOr)|V;H{yj8{w! z;cTTI9aw(kLU}(7I6Tj;%Cxo@M9L!e(kmMy!Z=r7)U!@AP z#)=%|ByA@k7N_UlE!g|9Hj!oeX!OoUI!UzyaJZK&exo9CCe2b9m~(VTa|kwqb#^1Iv7nde zeWS5Du~vLXcEK}rRWR7&CO#+2=SRW%y9M0}zHbHVB@3QHaMx|opzsX)SHU#;O<=FjA8V;=M#Of{jkX{v*iQ;&C)!ms=)%*nS6@1=Ze$!&XsHsVZ znxVQJgb(8Y0)6B$se0ZZH|~p^ra~s9ybW}3-nTBU!#DSsd=B zJdtaAV>7DIq5H(n4a4J=d6j7!Q48LkbbbAPJdmdd%$-XbR>}0Pn=&n%{o~l9IveiZ zTOk_#QA?gui%$@$@A`C(f>I>LnQOsw>buU6YJK< zk8ePl$0FI)CGS;T)>5u2kG>8Ugn($-@oG;llvx}uwT-^MS;l*tQx!CR-ACG6k4Y`q zss;-6e-~zh&4h7E75Cf7d z+QEZDcVP(0$312hzk4>4ErM5;5KzOA%XVNx9?NzX>H4zee1U)?Bv~?NK`Bu>|BXlf zk=r(jtmGbT*58kHJ^myw^Ntx3J=xN6+WERN@DBepym%wR8JqOu6Wiwi?$X+aa z1&g%zfxQb0TRQ#QkO6j09Y5*RlmoxBsmZ{cy%PTISl4krg7?>#1S%r-)lmuU_zLgO z`6ygf+}b1J#-?843R<9QrAObexdM;aZjUZ|TbY*yO2ZxumsxXx!U^L+%oNRGC#1`h|68KU-yF!WeZy5u-=0h@Rxq5epiQ9VKc5d#-7E+lhv!xPzBxZoBHW}xmLb&C z0wAp~V_m!+a|x^ENeq#ULDKK>(#opQ<8i>5K)fE(ENCl!4Uu@0RC{7NPCfY7PbBgC zj?my`p_M>av+7EQRT(aOkoLZRo9I{J2Zx6A{ z1pE6?Y<2|`-PR>7J|na8ss~xNevEm@++O9M8h0k2==t<%HCvq_2*Aj!t=tPvFBBXo zRjb^;(2IQyyR77$_A-j0Ue#!MlO?*-)m8)XbBsx z<2c=Mw?&x>+}4?xP~XkBf>+;X8?&efN%SjpI`Ut8HJW} zR4d4%m=3~n6JMj96UlB#m&V4Y4e&q)jKkji#*6PPqWX}ph@3v8G8$Ru8UGZ)@U$741J}&W>8=1`QH~YI z6IM3`d3_dlRnm`1Twl)0tAono__ec-s!qMDqv&h)R-t1S)H`KYPSBr-kiPrc$YTb* zDzX>cdL{;IO|dtn3d5Rv%)e@74N!FO_p<*+Whw;>SJdh>)-Y9KD@UG)1$DwdU#^Ww z&xJq<+C6epGU=|@S$vdrxXk;v$E_EFdtP2J8G)sR!L_u5n3Q!MX7 zW?f{zmJcabhk0VcFtTidoG@&~(W>9)=Mz_sH*uXNw`vNp6n-il+ucyNP^6;@s?u1n zRnL}^s*+Ll3Q~PxACSIJFjC3V-i=~ziY`8b`863$;#rFbh|MH zlGyZHDf*Er9a_Gr;_SmE;SmDS(t?~mvy@Sy*14ciO$`b)VRT~tfd z`*3(?l+$79W1$A-O2^fDPOr@=gL<)cJS?SKcKyg=QJDqh)a=Nd?vRB9*SH~$CPsCc;3tzt8M5ZW@bv~X8WM*=k zBr`*!l>}GETB)Z4!KAbZs{bv2q>)?h1}NJ;wNOes)8Qm*%zhX_R5fN7(H`R}w2zNl zpe=xzw?^b-s*cq0^d-$ZFOPooz}2>lNGAk`+SN?S4(W|iY5H&u+z9+EV!CDEj=`(m zj@7&bH-uG);1PuO0uA~19Q|}b;Ysr3n~oss=NLdE@h0roLI;Bh# zmJ0NZWdaoB0ZSiU2O)Cs&>5J|uK;gRk?X1quh*9X^4`mq3tW75)}PbSm)19!t`iCP z|7qJ7E`|(TO{3==Bbjp``W8ZPwb{bR`3-)6m#+BXx7DA>ctg|jIk&|pl`!%JK09RG z9fUX0RAL)`%Ol?Ldp93sSUB<967D#gpVx6zLIh0CZDxSidoHww$Lrbse^F?nx1DLb!K+>KjKI3Z4)i_q>~7B!GLsc&he>= zT5>bc_?g)GsJ*o{pnxKDA=H;zoZO0gkD)OV9k2nQ3L&U9AU8qgEn{ z+l^l2*UpJJ59Kba?GYSDUdMTx+&9V!%16Q9w=am#GuDHKf`_>3d#$J1x#i^K>^yZA zI;okkVtfLDRY!$)c@u~-c?MM-k{SF)cuD$IW5b$90E_3=6yMmX%Cw8I9jA@Y6Vu_{ zuuU3|5^w*>+OJk$=mAX$3m5$;1YLKorfO1IGkYN!>p_*23wpv^TA)4IdKF<2VLz5n zqJthxRk1X)F=*H$!bP9HTt4E9PQUifQG0f(0j1CuI~4Vc@NMsNT-CReN|tlm>us5< z4QI(QPOslIt2^_kPE{R4P_44VzJWoVMkjgi(oJHM13g;)`cjETxly4{KKPWoyiHI0 zD_gBD{dzG4PMCbu2U_L(CF0KS0~SCB4GpO;OUXG1`cKOJub(DPfIQFR)q_C8XOMsX zmd#&t^FNrtU)lY1(Ee-C`|8qxbUYd3SqQ!Ejd}Y0d3SjOP})!~()MQ~CJAI2l0d&iP|H+W?IitSd>H`QsYt zn;D?zFm3i{&w)H%SpRH{J}|}I3!qal&8k~_f4<(&8Qk96 zJymmH^jgrDymcq)*@Zu62x^57gWH9DfAJj{eF-!$mR89Y(;q;6oWN#86`3g?7(D`D zBl?d{e|i1Syh%TWJO@<&5L$S1{~XCiC<>V%I-1#G-@o6q9LOFmz0%9E{}w+FzJx;) z09Q+{&Q|OpcL#}dx}W;kw0Mhq7(2t{^74!0=l^a9{f8|QIsk?)-jY4!MC$2aLCh}n zTbq%}*J)6=DRE zwQbRL7iYp#`^Zo2bszunrL&5D8FEUY9kIg?lJ2G`)^e5n^o|n)9=?5OPuHUiTfdZl zJwn9<6bAR4m6MzKn0exGy+`knKCOCEXT2i3$;KZ;?~&-N4*5nuO$+F!ka{|~VBDJ~ z3Tm-_b7T1?R!G$aJR6Mr_Zs3S#iUze6?pkk^^Xe5PaReo?rz{2=0z5rk)TzK#!us; zx!!?Y`#>|ds)L9x(=StD(YL5(ntz-M2fa!ivC{WIZ&UTp&q4bc#22(+0R{Q#^%3R= z7`s?&QF85vWchX#wI|#_4Bi7eax5-pgOZ7C=eOYpcQ1i*v&I{EhvDzvhxa5uPs%ph zIU`W}WX4Lb_}M!V`*BTxvPAauoM_f*uv_~VG0u=jm)U%TTEklbAYvZiG5!^%kJK#| z8@UgTOW}uOD2y_$h=UEQnTw|XH!1bW0nXJQ)e)HNUbOxwb}h!PYLl#t{sq4lbxy+^ zz`|0h?vEeP9=`HQWUw=dcLVPyS68=59+#ZGsi>lK38LZ{d-=@)viz4{Lk8>=_`WLu%%+2O0Q)+5*x~52WA8w}a;(XB{LL#Lot_l3LsfhaTL8{VI?2 z1WBN2I>@A=|L9@)M@0AiR0vx7W9YO7-u;*5?jLtr9ss*kb2fX8!~4cKptp|wdIL1N zn5G`@em(bJp78$?K?$4?2oXdpE{XqnY0A0ZNod1 zOrG}Es9alHYkj7wE0r#k>c^Qp1^IslQ8I;{zsOhPy5bpE&*J2-q!<;YG%JqNv)~Dh ziP?~eGWbM{Nwyj)H1Gd@=)W+)0Rkl~QD##6w$?IO{ue6jr}J5Gcs``)+`ky*UtgpF z-O(!d6nc*SkKE`B`D}Y&LjUF0dvC$E-IV(D^nZRdMZL{IX#U@fE`JknHe=66k^h-K zXCY6|{EOfJMb#6ah9D*+D4FHo&pJRH-#m!hc=e7DtnqS`xP9E^N5!XQ4pNDhN3G6V z#&Wd0pxA0?^tw3Tpob7swe$SLC^1-STbzu-sVfE-S|bHJMfiIU$|g0pTAB*G)6$6A z7jb(Y0euk$E$wl#)nvs`^NvyXo>XOiQhz8ob5^eJz24~q3-PldXRYiInq2J5=uNQ< zZ6sBY+Y~8aqYi^?w2zHLLzirg^E0`#ZM*nfUX6>{7e0#JE4bx}v04 zY73gQvYY>~MhM^!l-qf{3cteo`3Y3@XD_bw7mbQayJ$X}JurnKTctz6} zM<%G7ujaj@r9gDKbi4o3LHkSw@+hYSBDzf*u^idaq7VYXpEJcevO|S>DNC&FK!J&` zJQ;<^F1xhd3n!ZF^niFtrwFI`$8~ktL6sa~{s&o@sjIqFqiL%r|M4N|OGu{yh}*PI zl39^*74q^cmV+wyVnjW&u{T$=P4$iGtY|4{WnYfI&ZANr4)>vxZx4(tf6VXs6z~0j zQ|(@3nQtKyZ$& zNMP<@+Xv%@r@#tcTRfI|phigTDzKw3x*uNMzp?TLKw(VvF!mi#7ztfqnAfLLz4nW+ z-zRX0OJwzt^n>gB2!;uuXtz2*B+&2yF_7{cIIt^fq_E_-N0Hcp(N6$190`flI>1k1 zw|yby7nZUQEH!}?BK_=pYIuN|Qb0s;B}I1efTwwp6!fTn)}uK3eWCtWF zpF{z4it~XvZi6{Cr3t1V9L5g}bA;kS!GXyXFrI}38Ahs|J1|T-D2Pfrm2&;S<#G^F zG?iGSGas0w8JNsR^@pUh82&I_@@-%g)A1Xcdq*JsV_(izgQdFNx_>~wgZ?)1iS;>N zs{@|Lv75lnpx_8NNcM0riXN0X{9w@*#z}ae$LrjKS!;xR6tSt{-sW^q$-GqiG*qAmr~z zhFVFd=kHTZ{xg`L5};$0*+G9iLA#rw5hx(S#d z?TXiz{egt$XRt%Bp%U%;cZiR)6DK@l#rE$+I4N}yg;&{k#umiyJ=mYz^p({8oGX6^ zNV<+Qrq^xXtP_L)oAW2dTawPp`eW|C)MQun_a9W|EB_mCCnMsg$g%yBWs(9RyBbZt ze}Mmc^PlAWzts5u0X5`@XxpO2Ro~EYoJI$`c}NpT1t#VPjlg;k^X74jxntodBESqlTQJ*O6R_6ugX3dhJbWl z>7GdX6*9Rkqs6B`wO-+cTp8g={{7d(PO1V0;x>>?vtMu%ioujp&=$*kcac#!NXB@Y6UQMYDBFW#TdhM?0Y%8XH1Xaz& z$g_J{dbv0$y8yc&G(DqZHvKCvSt~1I_EW#~y51_gtG4LQ=sN+Ynw?(8N7~o1b8pOc zM%Fnm^98bsDhX6h1xf#sYHY|AM~K08o72_d+hV2`f6;xpefsG6DeWl49N-yY`#9(gX8v`t-&q%7wZPOsIkmyHSs z*%s~iJ(p^uZwcG&y18%Ul$p1E<}{Cm4n!mcNf@w-?QZDyVg(G!)!tNZ7Jk@Wu+A{7 zim>U*iDt|9QAI|my2Pc!En8<;{@TzBq-yN~9ZN=_T|*qm=onmwpstIiW!GWmMNz@Lr(Go>VMwE7~#QdwN znc}+mFS3$IoKr`Y{5Wyq5YlAZzdOmiCG3)DM7L0h4Q8sN3iVNe17?t!6`95Z&(zZI zki*zW?&jap=(QPQHgxmzGN%tQ_QXSxMM=R@4?ASQ>%qNtsy|CXGudFHG(zs{W)@p~ z8K0~+-pwQ&vEgEA-O{ZPwwPUT ze*7=F3XuoKn8JlmnUtFUbS3}ShlORiiA(ON8q5s9W?k+=;vIIMs}zZg)SW2h^0kFz zbJ~>5L=<+8dp5^NI)Ot2WG^})JHlO-hnoXlQYpqtL8ncH7cgPHDy}W%V1BVX3NTFU zrjJ#^F0OIWJf|ZzwsUv4=}k(dl7jI4vd(W*(UoGKcySCN@r^;@nVFA-=AzP)TOV0V z{;V~-OKtpoM(bgo5o{h>Pw4nHS%z?je{k{c-tk&Zut+xbr|+=VFXf_;8afVUY!?mbgOc*Wui^XrW7FMMR z$qxUOrc6<<;=0C3(k*_cNnUXRWBQ&|mw!TGb2^Kzhf@GEYHy6R((y3Qh!VE=qF!BM zzEe0;7%q9Yf2uFi7^V!mI*`S6h#E|C&G+kczm6=xi{k8E;`fP z#0h<2CD12>Md#nb{kp>(Bk18-61>y&mm)tw3arWx>B^AYBKbs$(Z@?;Ps3KWMr@JAsy?e;4-g|UaD^|eGV%6z z$ro?sorTU#DoEu)o%4-oA8{T!EGs~)-8q$^Ulv!5T@L`~xbj8!cvtX=Q(m)Cl)9Qcmkr9aP-;2XtLzr-Q3^FJ6tA-<}j`dr>y1}U?jGhw1? z{U%zd2hI-h4Q3$kHd}jp@mIG3$GIw0X_m;duCpaE2xhU%{p!UGGF^F%zlmkIxQ@I; z^!Po@ILsnYZM)Js?;}0?aN4ZTPPooYlm%6@UDXO-+2>a6#fFHSBnK)vT(R(b$r9gS zW>yHQaD-zvuBm9I=K@LBhH_oovOJ)EGAq9OSs=A%U_7C(2X z{!+28z)ta2zqI5asaP|=1hV{~(&d7Njt)QMSAVwi%*M`s4V&0A_EKCg(d%8u@WI0ui<~^R_*&LBq0h^kDqJ89qkJ=g!j{j(a7CBnB7X~;n1VsNlU`xow&kKa6Ykk?Eb%}OeWa+s(Q5!;W~ zAX`-(+5A(t{_+z}{E_sN=cc8g^JR|qq_(db3wmfvuuy>L*XcdIu(Z)xcUDzS_?~y{ zZkF)Q+Xnj3BOP+^j!zh;()`WOQz{NC#x@ENAMB8YW6vcY*B05e?Wq*=)>B#83JR2{ z>Ry$OO&jyPLX#jG4&J?xcay1Jt`}x3%-2O(p#L?!=+O*)OpVxy|(LJ))h@ zoq?1IMXq_^0^tv5$^~D-JQ4cJRW3@f#yt@tqo4(ebpvXxmc0~wx~5+``2?e?td=Zp z*9l40j9V!x<4qeM$N(+_MSYx<(qEbSdVRo7Bd;^|7|8sr!$uA)h3K1>tk?T=ols?; z^U&0jVPf-vd{u)s>4(?obxk;7(Zl`muVWS$R&l86@JfFNY<1MQ1?>Z5do-`-N=;r{ zyj*7mGI!il=az2G+`VCR>>KRG_w!aiw#{hn+Qr`BFmsa_h+-1CU=E zf#Zuhs2yv;tZ>_FRpVYGo1+uRnc>A;*Z0-azXPTd#%p45?D4Rb9iivHZ(B$K1mwBw z-Z|`V?}KIXDYpD&DCEzd3B>j57`GP8#{Dny-ZQGHtqU6sMGzImiqdVM(iEguML`9L ziu5kM1f&Fn5Q?Z+DN+Jb6#-Ft3oQXeq=X_hkN}|v2n3`gKuEY7@IB}AjB&?z|KC5# zV1%8u*P3h2xt{gRXV&%hVs5&3u2A*BQT6~0=g0WZ2t*kK_c`#E4yZM57ZOxw0FhpBa zyq#!BU*0!RLkw(p;YH6nj**Atyfy0rHwK7Bw#|=b;3FZP>vjnF<@NOlPHkuc5Wm|q zVjL2+bvoj&)L*nG)X?wdp*C6`Mn#K&PoTD5KX4;HR3=CF@ntN=9rSGFzPM6oI@gbMGP4l=jWYC zmA#uFb(1pS9@NQYDyYb8gwKL>!_=|?i5iXi-N>+S8p35u?L6$9 zmQ}4DOERq$7u?DJ5(j#+m7-!-y*|0vl#ll08O|}5?(F;mWQGmr5zsOB8oIFWFg&7~ zHcZP7Hd=U&C)Kh{RC~3@ZLE@Ln#HH*flfza$x8VbHC|L#OXcK=gbCub+Lgzz0!gvY zJ5T7jrB%7Xb6YgWFQ>$-Ti0{$r~mA#!ZLY&_h?i+ovT}7SA{oC7ZP+2WcYnrQC#Ed z#8|*oRxD~G)HVuA+zAq;7HW{L&UP%}N%T?X?L@Y0z+SY1fpeLt-Y@Z96218z)W1L3 zX=g7*0dYV}_fE)eC)R&;)=u2F zbF3lr?)c|d6MvZOU*p_KGFl7)-xNR#|F9E{Cb$Zi7J*(_LRks4z0cuh9+SQ886Ul3z1oc( zZt;4hp5X;)UAZHNRUAsCWfQ?RjjxAU`oD!Q6D1>67?sFY%gdH|)nlFtR$IUUF}ey~ zy$kRPZQr4B$^0dt2t?`&T7VUL&dJQ~V9${V^&X~zVfQC~P-r`p;0Lpu>HnzF{QZI2 zYLYDE10QVjHB8vjdvs6HI0dgTx(X=PiGn%#E^Oz+%ZzLW_!h|^_fB7C(sb)C>ZN`V zcs!qaz<-eK$dkaYe|Vqg-0?iOxL+!QbS2fWvZqOj^8 z>NYfi`$yXE8E?3U#}y4b+{7VHm2?0W5gz>rtlP@*@rOCAW+X+?Vi*H;a* zWtkj`?c3V65>N2kd_84e^=pt;7D(R!*dO>$`Gk&rK_^vA7}T1GiHM7OpWTuxr_lBD zw)LEHk#}W>%Qde|_GI!LCvxs2Qw`gg-=;8V`~37TxOeXg;0=#=_g?)QfB&)#;G09JfPX8hK1Ophbz4ZV2T;LmSZA0T@Rq<^90lRYm?ABiI z|0f?7x*jqM$T?qze%f?p5Hg)yX8Jr-fJ_5Jz2e0XOHhP4zZ*!r>UhSb#0d4X#4||R zZ_2&s$;^?N!A!k(nXU11dgv`^i4Br6YYu3NWSWA^|)Wi>0!RLGb6We_0&l@k}*a#4r&^Run-gHl|#^U%T;=lqK=}Y5-qClGK&1U*P%acXZoyF6ns;=GkkJ! z?aCFZLDNHxlR@cW%?C-8$eY^S&E;ysP5o*=F-)e6yWxYsfA#o3+0nVbmjLX9*nx!- zp6wy0J!a-(Av$2LJPy=t-JyVSN{2GI>%SdDv?=htvc%=jFVZodysE53Dw0QtcR@ z*8N~tzY=csIak?REC;PF%PsY@vrKSHn|KfTxM)W}%ig;S2a0gd!QwX8Xhs#(ckB}% zLM0KxoIFaCt1z0iaf$86q*5#)nTm;%jMio|vt!1MXM8&a{ThMQLW^st2I<>>&^}C> z43(*d^nT7*9?)1&ansE5f#Q~NO-S3BqVq)&9HKG>tt;~DA;mghDpKc4n*|c=v#-$e zu(X7Q1!&22TT%gZAGN`e4j|x3HINV&}tq5TS(2rFcsCF3lIvT ztq&)!pJNfe-n_*b6QOwsaeitwbE^0#W8nf(s>LVM$tx4XvY`Cvt=8>j%{JRDacY}V zf0Etx{voK^9dJy)@mrhN`eY~K`M zT5ME<3vUJf_VL?XVgGCm2&do=DQ^eCSRnYDy+Y|G0{$*!Z2#i}tycmk8ZHl^+*Qqq?Xt)I`4&h+&Ql*o#bd0hN2N}V1Vdi|$h>-i6oK^rE1 zOK-On5srZa&!RgLBUk27TW(J~GM82s>vV(tyGOC|(2CLLrjs;FP0R^%xmXohoc`6| zKE?xHUJ%BE(%{F@qim|bN7cQU#++v$64KRvh`V;bUUJ)h=J3c@Sd$VFQr#GizPkqd z;7Uh`Cr!@R(aal%&+y+>-~nx8(d z^7{jAluR4VIuuRxL;K(L4XUGM(i4JGWN)|kFWauyaQe2Cep#+ys|{^!!qLE$m}fX> zvXj5l|S3RRp3)cO%?g^}_OrHtkrFPV1szY2{qD%V$`Yo97xOtO-x3 z79j(T-E=i3N$(KwfX(r&c9mH66#AE)^#M38?$~T|yqQ#`Nn9cq8rt3G2_R5OjN-|q zom}fLAABJb)L6^Mf}ek9V$u1d{n+HlLu9o_oc-_ zzpfR_w!PTpHad*zqsfAoDrFG2=5+>&NcOs*!Owv<3SRko^NpVOw?sd~8aXGXlMia& zrP*!RuJ=AGKO4AtLv?+|Yu#ZXC|+C3_clCb{&_fGAC28`X3=uFywU8Z|Cb7}<)c|! zax&uhB_2?X?e%+{o%0&_3X|pDi3M2Fh)x%j&l?}*IS|7A!3RQq`>+qAMzVW96oFy0 zIGfydYa-fLN!QJ9MwgiKGtqnaf(Ν!)eaP2iRz3Y(E>=l>Dfg)U!z8KiLbbvMh1 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 AL;wH) diff --git a/docs/fern/versions/nightly/pages/guides/vlm/qwen3_5scores.png b/docs/fern/versions/nightly/pages/guides/vlm/qwen3_5scores.png deleted file mode 100644 index f636a60890e67f6e9f014539e0fe3c36bfe0a493..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 598134 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 z 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

C1*+ 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

KZY_gJ#P>$9%3z|EPx8}A6J=gB2k-gPV!Sg- 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 z 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

lY&R7RBa;1jH{c%<>wM(4Yd4g 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

wRub*JGC5>+Qf?fuJ-jt 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 diff --git a/docs/fern/versions/nightly/pages/index.mdx b/docs/fern/versions/nightly/pages/index.mdx deleted file mode 100644 index 55dc2708eb..0000000000 --- a/docs/fern/versions/nightly/pages/index.mdx +++ /dev/null @@ -1,161 +0,0 @@ ---- -title: "NeMo AutoModel Documentation" -description: "NeMo AutoModel is a PyTorch DTensor-native SPMD open-source training library for scalable LLM and VLM training and fine-tuning with day-0 Hugging Face model support" ---- -import { Tag } from "@/components/Tag"; - -PyTorch-native training that scales from 1 GPU to thousands with a single config change. Load any Hugging Face model, point at your data, and start training; no checkpoint conversion and no boilerplate. -**Quick links:** [🤗 HF Compatible](/get-started/hf-compatibility) | [🚀 Performance](/performance/performance-summary) | [📐 Scalability](/get-started/key-features) | [🎯 SFT & PEFT](/recipes-e2e-examples/sft-peft) | [🎨 Diffusion](/recipes-e2e-examples/diffusion-fine-tuning) | [👁️ VLM](/recipes-e2e-examples/gemma-4) - - - -Overview of NeMo AutoModel and its capabilities. - - - -Supported workflows, parallelism, recipes, and benchmarks. - - - -A `transformers`-compatible library with accelerated model implementations. - - - -Built on `transformers` for day-0 model support and OOTB compatibility. - - - - -## Get Started - -```bash -uv pip install nemo-automodel - -automodel --nproc-per-node=2 llama3_2_1b_squad.yaml -``` - -See the [installation guide](/get-started/installation) for Docker, source builds, and multi-node setup. -See the [configuration guide](/get-started/configuration) for YAML recipes and CLI overrides. -Launch on a [local workstation](/job-launchers/local-workstation) or [SLURM cluster](/job-launchers/slurm-cluster). - -## Latest Model Support - -New models are added regularly. Pick a model below to start fine-tuning, or see the [full release log](/model-coverage/release-log). - -| Date | Modality | Model | -|------|----------|-------| -| 2026-05-18 | Audio | Qwen3-Omni ASR ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/audio_finetune/qwen3_omni_asr/ami_sft.yaml)) | -| 2026-04-07 | LLM | [GLM-5.1](https://github.com/NVIDIA-NeMo/Automodel/discussions/1719) ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_5.1_hellaswag_pp.yaml)) | -| 2026-04-02 | VLM | Gemma 4 ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_4b.yaml)) | -| 2026-03-16 | VLM | [Mistral Small 4](https://github.com/NVIDIA-NeMo/Automodel/discussions/1558) ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral4/mistral4_medpix.yaml)) | -| 2026-03-11 | LLM | [Nemotron Super v3](https://github.com/NVIDIA-NeMo/Automodel/discussions/976) ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_super_v3_hellaswag.yaml)) | -| 2026-03-03 | Diffusion | FLUX.1-dev ([recipe](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/flux_t2i_flow.yaml)) | - -## Recipes & Guides - -Find the right guide for your task: fine-tuning, pretraining, distillation, diffusion, and more. - -| I want to... | Choose this when... | Input Data | Model | Guide | -| --------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------- | --------- | --------------------------------------------------------- | -| **SFT (full fine-tune)** | You need maximum accuracy and have the GPU budget to update all weights | Instruction / chat dataset | LLM | [Start fine-tuning](/recipes-e2e-examples/sft-peft) | -| **PEFT (LoRA)** | You want to fine-tune on limited GPU memory; updates <1 % of parameters | Instruction / chat dataset | LLM | [Start LoRA](/recipes-e2e-examples/sft-peft) | -| **Tool / function calling** | Your model needs to call APIs or tools with structured arguments | Function-calling dataset (queries + tool schemas) | LLM | [Add tool calling](/recipes-e2e-examples/function-calling) | -| **Fine-tune VLM** | Your task involves both images and text (e.g., visual QA, captioning) | Image + text dataset | VLM | [Fine-tune VLM](/recipes-e2e-examples/gemma-3-3n) | -| **Fine-tune Gemma 4** | You want to fine-tune Gemma 4 for structured extraction from images (e.g., receipts) | Image + text dataset | VLM | [Fine-tune Gemma 4](/recipes-e2e-examples/gemma-4) | -| **Fine-tune dLLM** | You want to fine-tune a diffusion language model (e.g., LLaDA) using masked denoising | Instruction / chat dataset | dLLM | [Fine-tune dLLM](/recipes-e2e-examples/dllm-fine-tuning) | -| **Fine-tune Diffusion** | You want to fine-tune a diffusion model for image or video generation | Video / Image dataset | Diffusion | [Fine-tune Diffusion](/recipes-e2e-examples/diffusion-fine-tuning) | -| **Fine-tune VLM-MoE** | You need large-scale vision-language training with sparse MoE efficiency | Image + text dataset | VLM (MoE) | [Fine-tune VLM-MoE](/recipes-e2e-examples/qwen3-5-vl) | -| **Fine-tune Audio ASR** | Adapt Qwen3-Omni for speech recognition on HF audio datasets | Audio + transcript dataset | Qwen3-Omni | [Fine-tune Qwen3-Omni ASR](/recipes-e2e-examples/qwen3-omni-asr) | -| **Embedding fine-tune** | You want to improve text similarity for search, retrieval, or RAG | Text pairs / retrieval corpus | LLM | Coming Soon | -| **Fine-tune a large MoE** | You are adapting a large sparse MoE model (DeepSeek-V3, GLM-5, etc.) to your domain | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune MoE](/recipes-e2e-examples/large-moe-fine-tuning) | -| **Fine-tune DeepSeek V4 Flash** | You want to fine-tune the DeepSeek V4 Flash hybrid-attention MoE (SWA / CSA / HCA + hash-routing) | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune DeepSeek V4 Flash](/recipes-e2e-examples/deepseek-v4-flash) | -| **Fine-tune Hy3-preview** | You want to fine-tune Tencent's 295B MoE with sigmoid routing and per-head QK RMSNorm | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune Hy3-preview](/recipes-e2e-examples/hy3-preview) | -| **Sequence classification** | You need to classify text into categories (sentiment, topic, NLI) | Text + labels (e.g., GLUE MRPC) | LLM | [Train classifier](/recipes-e2e-examples/sequence-classification) | -| **QAT fine-tune** | You want a quantized model that keeps accuracy for efficient deployment | Text dataset | LLM | [Enable QAT](/recipes-e2e-examples/qat) | -| **Knowledge distillation** | You want a smaller, faster model that retains most of the teacher's quality | Instruction dataset + teacher model | LLM | [Distill a model](/recipes-e2e-examples/knowledge-distillation) | -| **Pretrain an LLM** | You are building a base model from scratch on your own corpus | Large unlabeled text corpus (e.g., FineWeb-Edu) | LLM | [Start pretraining](/recipes-e2e-examples/pretraining) | -| **Pretrain (NanoGPT)** | You want quick pretraining experiments on a single node | FineWeb / text corpus | LLM | [Try NanoGPT](/recipes-e2e-examples/nanogpt-pretraining) | - -## Performance - -Training throughput on NVIDIA GPUs with optimized kernels for Hugging Face models. - -| Model | GPUs | TFLOPs/sec/GPU | Tokens/sec/GPU | Optimizations | -| ---------------- | ---- | -------------- | -------------- | ---------------------- | -| DeepSeek V3 671B | 256 | 250 | 1,002 | TE + DeepEP | -| GPT-OSS 20B | 8 | 279 | 13,058 | TE + DeepEP + FlexAttn | -| Qwen3 MoE 30B | 8 | 277 | 12,040 | TE + DeepEP | - -See the [full benchmark results](/performance/performance-summary) for configuration details and more models. - -## Advanced Topics - -Parallelism, precision, checkpointing strategies, and experiment tracking. - - - -Torch-native pipelining composable with FSDP2 and DTensor. - - - - -Mixed-precision FP8 training with torchao. -FP8 mixed-precision - - - -Distributed checkpoints with SafeTensors output. -DCP safetensors - - - -Trade compute for memory with activation checkpointing. -memory-efficiency - - - -Train with quantization for deployment-ready models. -QAT - - - -Track experiments and metrics with MLflow and Wandb. -MLflow Wandb - - - - -## For Developers - - - -Components, recipes, and CLI architecture. - - - -Auto-generated Python API documentation. - - - -Drop-in accelerated backend for TRL, lm-eval-harness, OpenRLHF, or any code that loads Hugging Face models. - - - - ---- - -:: - -:: - -:: - -:: - -:: - -:: - -:: - -:: diff --git a/docs/fern/versions/nightly/pages/launcher/local-workstation.mdx b/docs/fern/versions/nightly/pages/launcher/local-workstation.mdx deleted file mode 100644 index b2fcb26b9e..0000000000 --- a/docs/fern/versions/nightly/pages/launcher/local-workstation.mdx +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: "Run on Your Local Workstation" -description: "" -position: 2 ---- -Use this guide for local, single-node workflows on a workstation or an interactive Slurm allocation. For setup details, refer to our [Installation Guide](/get-started/installation). -For batch multi-node jobs, see the [Run on a Cluster](/job-launchers/slurm-cluster) or [SkyPilot](/job-launchers/skypilot) guides. - -NeMo AutoModel uses recipes to run end-to-end workflows. If you're new to recipes, see the [Repository Structure](/get-started/repo-structure) guide. - -## Quick Start: Choose Your Job Launch Option - -- **CLI (recommended)** - ```bash - automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml - ``` - -- **Direct recipe script** - - Single GPU - ```bash - python nemo_automodel/recipes/llm/train_ft.py -c examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml - ``` - - Multi-GPU (single node) - ```bash - torchrun --nproc-per-node=2 nemo_automodel/recipes/llm/train_ft.py -c examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml - ``` - -## Run with AutoModel CLI (Single Node) - -The AutoModel CLI is the preferred method for most users. It offers a unified interface to launch training scaling from a local workstation (this guide) to large clusters (see our [cluster guide](/job-launchers/slurm-cluster)). - -### Basic Usage - -The CLI follows this format: -```bash -automodel [--nproc-per-node N] [--key.subkey=override ...] -``` - -A short alias `am` is also available. Both commands also work with `uv run` (e.g., `uv run automodel `). - -Where: -- ``: Path to your YAML configuration file (must contain a `recipe._target_` key) -- `--nproc-per-node`: Optional override for the number of GPUs to use - -The recipe class is specified inside the YAML via the `recipe._target_` key: -```yaml -recipe: - _target_: nemo_automodel.recipes.llm.train_ft.TrainFinetuneRecipeForNextTokenPrediction -``` - -### Train on a Single GPU - -For simple fine-tuning on a single GPU: - -```bash -automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -### Train on Multiple GPUs (Single Node) - -For interactive single-node jobs, the CLI automatically detects the number of available GPUs and -uses `torchrun` for multi-GPU training. You can manually specify the number of GPUs using the `--nproc-per-node` option: - -```bash -automodel --nproc-per-node 2 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -If you don't specify `--nproc-per-node`, it will use all available GPUs on your system. - -Looking for Slurm or cloud training? See [Run on a Cluster](/job-launchers/slurm-cluster) or [SkyPilot](/job-launchers/skypilot). - -## Run with uv (Development Mode) - -When you need more control over the environment or are actively developing with the codebase, you can use `uv` to run training scripts directly. This approach gives you direct access to the underlying Python scripts and is ideal for debugging or customization. - -### Train on a Single GPU - -```bash -uv run nemo_automodel/recipes/llm/train_ft.py -c examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -### Train on Multiple GPUs with Torchrun (Single Node) - -For multi-GPU single-node training, use `torchrun` directly: - -```bash -uv run torchrun --nproc-per-node=2 nemo_automodel/recipes/llm/train_ft.py -c examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -### Why Use uv? - -uv provides several advantages for development and experimentation: - -- **Automatic environment management**: uv automatically creates and manages virtual environments, ensuring consistent dependencies without manual setup. -- **Lock file synchronization**: Keeps your local environment perfectly synchronized with the project's `uv.lock` file. -- **No installation required**: Run scripts directly from the repository without installing packages system-wide. -- **Development flexibility**: Direct access to Python scripts for debugging, profiling, and customization. -- **Dependency isolation**: Each project gets its own isolated environment, preventing conflicts. - -## Run with Torchrun - -If you have NeMo AutoModel installed in your environment and prefer to run recipes directly without uv, you can use `torchrun` directly: - -### Train on a Single GPU - -```bash -python nemo_automodel/recipes/llm/train_ft.py -c examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -### Train on Multiple GPUs (Single Node) - -```bash -torchrun --nproc-per-node=2 nemo_automodel/recipes/llm/train_ft.py -c examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -This approach requires that you have already installed NeMo AutoModel and its dependencies in your Python environment (see the [installation guide](/get-started/installation) for details). - -## Customize Configuration Settings - -All approaches use the same YAML configuration files. You can easily customize training by following the steps in this section. - -1. **Override config values**: Use command-line arguments to directly replace default settings. -For example, if you want to fine-tune `Qwen/Qwen3-0.6B` instead of `meta-llama/Llama-3.2-1B`, you can use: - ```bash - automodel config.yaml --model.pretrained_model_name_or_path Qwen/Qwen3-0.6B - ``` - -2. **Edit the config file**: Modify the YAML directly for persistent changes. - -3. **Create custom configs**: Copy and modify existing configurations from the `examples/` directory. - -## When to Use Which Approach - -**Use the AutoModel CLI when:** -- You want a simple, unified interface -- You are running locally on a single machine -- You don't need to modify the underlying code -- You prefer a higher-level abstraction - -**Use uv when:** -- You're developing or debugging the codebase -- You want automatic dependency management -- You need maximum control over the execution -- You want to avoid manual environment setup -- You're experimenting with custom modifications - -**Use Torchrun when:** -- You have a stable, pre-configured environment -- You prefer explicit control over Python execution -- You're working in environments where uv is not available -- You're integrating with existing PyTorch workflows - -All approaches use the same configuration files and provide the same training capabilities on a single node. For multi-node training, see [Run on a Cluster](/job-launchers/slurm-cluster). diff --git a/docs/fern/versions/nightly/pages/launcher/nemo-run.mdx b/docs/fern/versions/nightly/pages/launcher/nemo-run.mdx deleted file mode 100644 index 855ad340f9..0000000000 --- a/docs/fern/versions/nightly/pages/launcher/nemo-run.mdx +++ /dev/null @@ -1,240 +0,0 @@ ---- -title: "Run with NeMo-Run" -description: "" -position: 4 ---- -In this guide, you will learn how to launch NeMo AutoModel training jobs using [NeMo-Run](https://github.com/NVIDIA-NeMo/Run). NeMo-Run supports multiple backends including Slurm, Kubernetes, Docker, and local execution. For cloud-based training, see [Run on Any Cloud with SkyPilot](/job-launchers/skypilot). For direct sbatch usage, see [Run on a Cluster (Slurm)](/job-launchers/slurm-cluster). For single-node workstation usage, see [Run on Your Local Workstation](/job-launchers/local-workstation). - -NeMo-Run is an open-source tool from NVIDIA that manages job submission across different execution backends. You define your compute configuration once in a Python file and reuse it across all your training jobs. - -## Before You Begin - -1. **Install NeMo-Run** (it is not bundled with AutoModel): - -```bash -pip install nemo-run -``` - -2. **Create an executor definitions file** at `$NEMORUN_HOME/executors.py`. `NEMORUN_HOME` defaults to `~/.nemo_run`; set the environment variable to use a different location. This file tells NeMo-Run how to reach your compute target. Every executor you reference in a YAML config must be defined here. See [Executor Setup](#executor-setup) for a complete example. - -3. **Verify connectivity** to the target in your executor (e.g. SSH for Slurm, kubeconfig for Kubernetes). - -4. **Set required environment variables** (if needed by your training config): - -```bash -export HF_TOKEN=hf_... # Required for gated models (e.g. Llama) -export WANDB_API_KEY=... # Optional: Weights & Biases logging -``` - -## Executor Setup - -The `executor:` field in your YAML config is a name that maps to an entry in `$NEMORUN_HOME/executors.py`. This file must define a module-level `EXECUTOR_MAP` dictionary. NeMo-Run supports several executor types -- here are examples of the most common ones: - -### Slurm Executor - -```python -import nemo_run as run - -def my_slurm_cluster(): - executor = run.SlurmExecutor( - account="my_account", - partition="batch", - tunnel=run.SSHTunnel( - user="myuser", - host="login-node.example.com", - job_dir="/remote/path/nemo_run/jobs", - ), - nodes=1, - ntasks_per_node=8, - gpus_per_node=8, - mem="0", - exclusive=True, - packager=run.Packager(), - ) - executor.container_image = "nvcr.io/nvidia/nemo-automodel:26.02" - executor.container_mounts = ["/data:/data", "/checkpoints:/checkpoints"] - executor.env_vars = {"HF_HOME": "/data/hf_cache"} - executor.time = "04:00:00" - return executor - -EXECUTOR_MAP = { - "my_slurm": my_slurm_cluster(), -} -``` - -### Kubernetes Executor - -```python -import nemo_run as run - -def my_k8s_cluster(): - return run.KubeflowExecutor( - namespace="training", - image="nvcr.io/nvidia/nemo-automodel:26.02", - num_nodes=1, - nprocs_per_node=8, - gpus_per_node=8, - ) - -EXECUTOR_MAP = { - "my_k8s": my_k8s_cluster(), -} -``` - -### Multiple Executors - -You can define as many executors as you need for different backends, clusters, or resource configurations: - -```python -EXECUTOR_MAP = { - "slurm_dev": my_slurm_dev(), - "slurm_prod": my_slurm_prod(), - "k8s": my_k8s_cluster(), -} -``` - -- Keys in `EXECUTOR_MAP` are names you reference in YAML (`executor: slurm_dev`). -- Values can be executor instances or zero-argument callables that return one. -- Override fields in the YAML (`nodes`, `devices`, `container_image`, etc.) are applied on top of the executor defaults. - -## Quickstart - -Any existing AutoModel YAML config can be run via NeMo-Run by adding a `nemo_run:` section at the top. For example, given an existing config that you run locally: - -```bash -automodel examples/llm_finetune/qwen/qwen3_moe_30b_te_packed_sequence.yaml -``` - -Add a `nemo_run:` block to submit it to a remote executor instead: - -```yaml -# -- Add this section to any existing config ---------------------------------- -nemo_run: - executor: my_slurm # Name from EXECUTOR_MAP in $NEMORUN_HOME/executors.py - container_image: /images/custom.sqsh # Override executor's default image - nodes: 1 # Override number of nodes - ntasks_per_node: 8 # GPUs per node - time: "04:00:00" # Override time limit - job_name: qwen3_moe_finetune # Experiment and job name - -# -- Everything below is your existing training config (unchanged) ------------ -recipe: TrainFinetuneRecipeForNextTokenPrediction - -step_scheduler: - global_batch_size: 32 - # ... rest of your config ... -``` - -Then run the same command: - -```bash -automodel your_config.yaml -``` - -The CLI detects the `nemo_run:` key, strips it from the training config, loads the named executor from `$NEMORUN_HOME/executors.py`, and submits the job -- all in one command. - -## Configuration Reference - -### All `nemo_run:` Fields - -| Field | Default | Description | -|---|---|---| -| `executor` | `"local"` | Name from `EXECUTOR_MAP` in `$NEMORUN_HOME/executors.py`, or `"local"` for local execution | -| `job_name` | `` | Experiment and job name | -| `detach` | `true` | Return immediately after submission | -| `tail_logs` | `false` | Stream logs after submission | -| `executors_file` | `$NEMORUN_HOME/executors.py` | Path to the executor definitions file | -| `job_dir` | `./nemo_run_jobs` | Local directory for job artifacts (config snapshot) | -| *(any other key)* | *(from executor)* | Applied directly to the executor via `setattr`. Use the executor's native attribute names (e.g. `nodes`, `ntasks_per_node`, `partition`, `container_image`, `time`, `env_vars`). Dicts are merged, lists are extended. | - -## Examples - -### Single-Node Fine-Tuning (1 x 8 GPUs) - -```yaml -nemo_run: - executor: my_slurm - nodes: 1 - ntasks_per_node: 8 - job_name: single_node_finetune -``` - -### Multi-Node Distributed Training (2 x 8 GPUs) - -```yaml -nemo_run: - executor: my_slurm - nodes: 2 - ntasks_per_node: 8 - time: "08:00:00" - job_name: multinode_pretrain -``` - -For multi-node jobs the launcher automatically adds `--nnodes`, `--node-rank`, `--rdzv-backend`, `--master-addr`, and `--master-port` to the `torchrun` command. - -### Custom Container Image and Mounts - -```yaml -nemo_run: - executor: my_slurm - container_image: /images/automodel_nightly.sqsh - container_mounts: - - /scratch/datasets:/datasets - - /scratch/checkpoints:/checkpoints - env_vars: - HF_HOME: /datasets/hf_cache - NCCL_DEBUG: INFO -``` - -### Local Execution (No Cluster) - -Use `executor: local` to run on the current machine. No `$NEMORUN_HOME/executors.py` entry is needed: - -```yaml -nemo_run: - executor: local - ntasks_per_node: 2 - job_name: local_test -``` - -## Monitor and Manage Jobs - -NeMo-Run stores experiment metadata under `$NEMORUN_HOME/experiments/`. Set `tail_logs: true` in the YAML to stream job output after submission. - -For Slurm-based executors, standard Slurm commands also work: - -```bash -squeue -u $USER # List your queued and running jobs -scancel # Cancel a running or pending job -sacct -j # View job accounting information -``` - -For Kubernetes-based executors, use `kubectl` to monitor pods and jobs. - -## How It Works - -1. The `automodel` CLI detects the `nemo_run:` key and imports `NemoRunLauncher`. -2. The `nemo_run:` section is popped from the config. The remaining training config is written to `nemo_run_jobs//job_config.yaml` for record-keeping. -3. The launcher loads a pre-configured executor from `$NEMORUN_HOME/executors.py` by name (or creates a `LocalExecutor` for `executor: local`). Override fields are applied on top of the executor defaults. -4. The training config YAML is embedded in a self-contained inline bash script via a heredoc, so no separate file transfer is needed. -5. A `torchrun` command is built with `--nproc-per-node` and (for multi-node) distributed rendezvous arguments. -6. The script is submitted via `nemo_run.Experiment`. By default the call returns immediately (`detach=True`). - -## Customize Configuration - -Override any training parameter from the command line, same as with local runs: - -```bash -automodel config_with_nemo_run.yaml \ - --model.pretrained_model_name_or_path meta-llama/Llama-3.2-3B -``` - -## When to Use NeMo-Run vs. SkyPilot vs. Slurm - -| | NeMo-Run | SkyPilot | Slurm (sbatch) | -|---|---|---|---| -| **Infrastructure** | Slurm, Kubernetes, Docker, local | Public cloud (AWS, GCP, Azure) | On-prem HPC | -| **Container support** | Yes (Pyxis/Enroot, Docker, K8s pods) | N/A (cloud VMs) | Manual (in sbatch script) | -| **Setup required** | `nemo-run` + `$NEMORUN_HOME/executors.py` | Cloud credentials + `sky check` | Cluster access + sbatch script | -| **Job submission** | `automodel config.yaml` | `automodel config.yaml` | `sbatch slurm.sub` | -| **Good for** | Managed multi-backend execution, reusable executor configs | Cloud burst, cost optimization, spot instances | Direct Slurm scripts, full control over sbatch | diff --git a/docs/fern/versions/nightly/pages/launcher/overview.mdx b/docs/fern/versions/nightly/pages/launcher/overview.mdx deleted file mode 100644 index 25dbad8fd8..0000000000 --- a/docs/fern/versions/nightly/pages/launcher/overview.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "Job Launchers" -description: "" -position: 1 ---- -NeMo AutoModel provides several ways to launch training. The right choice depends on your hardware and environment. - -## Which Launcher Should I Use? - -| Launcher | Best for | GPUs | Guide | -|---|---|---|---| -| **Local Workstation** | Getting started, debugging, single-node training | 1-8 on one machine | [Run on Your Local Workstation](/job-launchers/local-workstation) | -| **NeMo-Run** | Managed execution on Slurm, Kubernetes, Docker, local | 1+ | [NeMo-Run](/job-launchers/nemo-run) | -| **SkyPilot** | Cloud training or Kubernetes clusters | Any | [SkyPilot](/job-launchers/skypilot) | -| **Slurm** | Multi-node batch jobs on HPC clusters | 8+ across nodes | [Run on a Cluster](/job-launchers/slurm-cluster) | - -### I Have 1–2 GPUs on My Workstation - -Use the **interactive** launcher. No scheduler or cluster software is needed: - -```bash -automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -See the [Run on Your Local Workstation](/job-launchers/local-workstation) guide. - -### I Have Access to a Slurm Cluster - -Add a `slurm:` section to your YAML config and submit with the same `automodel` command. The CLI generates the `torchrun` invocation and calls `sbatch` for you: - -```bash -automodel config_with_slurm.yaml -``` - -See the [Run on a Cluster](/job-launchers/slurm-cluster) guide. - -### I Want Managed Job Submission (Slurm, Kubernetes, Docker) - -Add a `nemo_run:` section to your YAML config. NeMo-Run loads a pre-configured executor for your compute target and submits the job: - -```bash -automodel config_with_nemo_run.yaml -``` - -See the [NeMo-Run](/job-launchers/nemo-run) guide. - -### I Want to Train on the Cloud - -Add a `skypilot:` section to your YAML config. SkyPilot provisions VMs on any major cloud and handles spot-instance preemption automatically: - -```bash -automodel config_with_skypilot.yaml -``` - -See the [SkyPilot](/job-launchers/skypilot) guide. - -### I Want to Train on Kubernetes with SkyPilot - -Use the same `skypilot:` launcher, but set `cloud: kubernetes`. This is a good fit when your team already has a GPU-backed Kubernetes cluster and you want SkyPilot to handle job submission and multi-node orchestration: - -```bash -automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml -``` - -See the [SkyPilot + Kubernetes tutorial](/job-launchers/skypilot-k8s). - -## All Launchers Use the Same Config - -Every launcher shares the same YAML recipe format. The only difference is an optional launcher section (`slurm:`, `nemo_run:`, or `skypilot:`) that tells the CLI where to run. Without a launcher section, training runs interactively on the current machine. diff --git a/docs/fern/versions/nightly/pages/launcher/skypilot-kubernetes.mdx b/docs/fern/versions/nightly/pages/launcher/skypilot-kubernetes.mdx deleted file mode 100644 index 0dd5af1159..0000000000 --- a/docs/fern/versions/nightly/pages/launcher/skypilot-kubernetes.mdx +++ /dev/null @@ -1,238 +0,0 @@ ---- -title: "SkyPilot k8s" -description: "" -position: 6 ---- -This tutorial shows how to run NeMo AutoModel on a Kubernetes cluster through SkyPilot. - -You will: - -1. Check that SkyPilot can see your Kubernetes cluster and GPUs. -2. Launch a small NeMo AutoModel fine-tuning job on one GPU. -3. Scale the same job to two nodes. -4. Follow logs and clean everything up when you are done. - -This guide is written for new AutoModel users, so it keeps the moving pieces as small as possible. - -## Before you begin - -You need: - -- a working Kubernetes context in `kubectl` -- at least one GPU-backed node in the cluster -- SkyPilot installed with Kubernetes support -- a local NeMo AutoModel checkout -- a Hugging Face token in `HF_TOKEN` if you plan to use a gated model such as Llama - -If you are setting up SkyPilot on Kubernetes for the first time, the official SkyPilot Kubernetes setup guide is here: - -- [https://docs.skypilot.co/en/latest/reference/kubernetes/kubernetes-setup.html](https://docs.skypilot.co/en/latest/reference/kubernetes/kubernetes-setup.html) - -Install the SkyPilot Kubernetes client in your AutoModel environment: - -```bash -uv pip install "skypilot[kubernetes]" -``` - -Set the token once in your shell: - -```bash -export HF_TOKEN=hf_your_token_here -``` - -## Step 1: Verify the cluster - -Start with three quick checks: - -```bash -kubectl config current-context -kubectl get nodes -sky check kubernetes -``` - -You want `sky check kubernetes` to report that Kubernetes is enabled. - -Next, ask SkyPilot which GPUs it can request from the cluster: - -```bash -sky show-gpus --infra k8s -``` - -Example output: - -```text -$ sky show-gpus --infra k8s -Kubernetes GPUs -GPU REQUESTABLE_QTY_PER_NODE UTILIZATION -L4 1, 2, 4 8 of 8 free -H100 1, 2, 4, 8 8 of 8 free - -Kubernetes per node GPU availability -NODE GPU UTILIZATION -gpu-node-a H100 8 of 8 free -``` - -If you do not see any GPUs here, stop and fix the Kubernetes or SkyPilot setup first. AutoModel is ready, but SkyPilot still cannot place GPU jobs. - -## Step 2: Run a single-node job - -The easiest starting point is a one-GPU fine-tune using the existing Llama 3.2 1B SQuAD example. - -This repository now includes a Kubernetes-flavored SkyPilot config at [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml). - -Launch it from the repo root: - -```bash -automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml -``` - -The important part of that YAML is the `skypilot:` block: - -```yaml -skypilot: - cloud: kubernetes - accelerators: H100:1 - use_spot: false - disk_size: 200 - job_name: llama3-2-1b-k8s - hf_token: ${HF_TOKEN} -``` - -What AutoModel does for you: - -- writes a launcher-free copy of the training config to `skypilot_jobs//job_config.yaml` -- syncs the repo to the SkyPilot workdir -- runs `torchrun` on the Kubernetes worker pod -- forwards your training config unchanged after removing the `skypilot:` section - -Example submission output: - -```text -$ automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml -INFO Config: /workspace/Automodel/examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml -INFO Recipe: nemo_automodel.recipes.llm.train_ft.TrainFinetuneRecipeForNextTokenPrediction -INFO Launching job via SkyPilot -INFO SkyPilot job artifacts in: /workspace/Automodel/skypilot_jobs/1712150400 -``` - -Then watch the cluster come up: - -```bash -sky status -sky logs llama3-2-1b-k8s -kubectl get pods -``` - -Example log snippet: - -```text -$ sky status -Clusters -NAME LAUNCHED RESOURCES STATUS -llama3-2-1b-k8s 1m ago 1x Kubernetes(H100:1) UP - -$ sky logs llama3-2-1b-k8s -... -torchrun --nproc_per_node=1 ~/sky_workdir/nemo_automodel/recipes/llm/train_ft.py -c /tmp/automodel_job_config.yaml -... -``` - -## Step 3: Scale to two nodes - -Once the single-node job works, scaling out is just a small YAML change. - -Use the two-node example at [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes_2nodes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes_2nodes.yaml): - -```bash -automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes_2nodes.yaml -``` - -The launcher block looks like this: - -```yaml -skypilot: - cloud: kubernetes - accelerators: H100:1 - num_nodes: 2 - use_spot: false - disk_size: 200 - job_name: llama3-2-1b-k8s-2nodes - hf_token: ${HF_TOKEN} -``` - -For multi-node jobs, AutoModel switches the generated command to a distributed `torchrun` launch that uses SkyPilot's node metadata: - -```text -torchrun \ - --nproc_per_node=1 \ - --nnodes=$SKYPILOT_NUM_NODES \ - --node_rank=$SKYPILOT_NODE_RANK \ - --rdzv_backend=c10d \ - --master_addr=$(echo $SKYPILOT_NODE_IPS | head -n1) \ - --master_port=12375 \ - ~/sky_workdir/nemo_automodel/recipes/llm/train_ft.py \ - -c /tmp/automodel_job_config.yaml -``` - -That means you do not need to hand-build rendezvous arguments yourself. - -Use these commands while the job is starting: - -```bash -sky status -sky logs llama3-2-1b-k8s-2nodes -kubectl get pods -o wide -``` - -What you want to see: - -- two SkyPilot-managed worker pods -- both pods scheduled onto GPU nodes -- logs that include `--nnodes=$SKYPILOT_NUM_NODES` - -## Step 4: Clean up - -When the run is finished, tear the cluster down so it stops consuming resources: - -```bash -sky down llama3-2-1b-k8s -sky down llama3-2-1b-k8s-2nodes -``` - -You can remove old local launcher artifacts too: - -```bash -rm -rf skypilot_jobs -``` - -## Common first-run issues - -### `sky check kubernetes` fails - -Usually this means SkyPilot cannot use your current kubeconfig context yet. Re-check the context with `kubectl config current-context`, then compare it with SkyPilot's Kubernetes setup guide. - -### `sky show-gpus --infra k8s` shows no GPUs - -SkyPilot can only schedule GPUs that Kubernetes exposes. Make sure the GPU device plugin or operator is installed and the GPU nodes are healthy. - -### The job starts, but model download fails - -For gated models, make sure `HF_TOKEN` is exported in the shell that runs `automodel`. The SkyPilot launcher forwards it to the remote job. - -### Multi-node launch stalls during rendezvous - -Start with the single-node example first. If that works, check that: - -- your cluster has enough free GPU nodes for `num_nodes` -- worker pods can talk to each other over the cluster network -- the logs include the generated `torchrun` multi-node arguments shown above - -## Which file should I edit? - -If you want to adapt this tutorial for your own model, the quickest path is: - -1. Copy [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml). -2. Change the `model` and dataset sections. -3. Keep the `skypilot:` block small until the first run succeeds. - -That way, when something goes wrong, you only have a few knobs to inspect. diff --git a/docs/fern/versions/nightly/pages/launcher/skypilot.mdx b/docs/fern/versions/nightly/pages/launcher/skypilot.mdx deleted file mode 100644 index 90a074849b..0000000000 --- a/docs/fern/versions/nightly/pages/launcher/skypilot.mdx +++ /dev/null @@ -1,198 +0,0 @@ ---- -title: "Run on Any Cloud with SkyPilot" -description: "" -position: 5 ---- -In this guide, you will learn how to launch NeMo AutoModel training jobs with [SkyPilot](https://docs.skypilot.co/en/stable/docs/). SkyPilot can target public clouds such as AWS, GCP, Azure, and Lambda, and it can also submit jobs to Kubernetes clusters. For a beginner-friendly Kubernetes walkthrough, see [SkyPilot + Kubernetes tutorial](/job-launchers/skypilot-k8s). For on-premises cluster usage without SkyPilot, see [Run on a Cluster (Slurm)](/job-launchers/slurm-cluster). For single-node workstation usage, see [Run on Your Local Workstation](/job-launchers/local-workstation). - -SkyPilot is an open-source framework that abstracts cloud infrastructure so you can train on whichever cloud is cheapest or most available at launch time — including automatic spot-instance handling for significant cost savings. - -## Before You Begin - -Complete the following setup steps before launching your first AutoModel job on a cloud provider. - -1. **Install SkyPilot** with the connector for your target infrastructure: - -```bash -uv pip install "skypilot[gcp]" # Google Cloud -uv pip install "skypilot[aws]" # Amazon Web Services -uv pip install "skypilot[azure]" # Microsoft Azure -uv pip install "skypilot[lambda]" # Lambda Cloud -uv pip install "skypilot[kubernetes]" # Any Kubernetes cluster -``` - -2. **Configure access** for your target infrastructure, then verify: - -```bash -sky check -``` - -You should see at least one cloud listed as **OK**. - -3. **Set required environment variables:** - -```bash -export HF_TOKEN=hf_... # Required for gated models (e.g. Llama) -export WANDB_API_KEY=... # Optional: Weights & Biases logging -``` - -## Quickstart - -Add a `skypilot:` section to any existing config YAML, then run the same `automodel` command you already know: - -```bash -automodel your_config_with_skypilot.yaml -``` - -The CLI detects the `skypilot:` key, strips it from the training config, uploads the code and config to a cloud VM, and launches training — all in one command. - -## Configuration Reference - -Below is an annotated example for fine-tuning Llama-3.2-1B on SQuAD on a GCP spot T4. A ready-to-run copy lives at [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot.yaml). - -```yaml -# ── SkyPilot launcher section ───────────────────────────────────────────── -# Removed before the training config reaches the remote VM. -skypilot: - cloud: gcp # aws | gcp | azure | lambda | kubernetes - accelerators: T4:1 # GPU type:count per node, e.g. A100:8 - use_spot: true # ~80 % cost reduction vs on-demand - disk_size: 100 # Remote VM disk size in GB - num_nodes: 1 # Increase for multi-node distributed training - region: us-central1 # Optional — SkyPilot picks cheapest if omitted - job_name: llama3_2_finetune # Also used as the SkyPilot cluster name - - # Use env-var placeholders so secrets are never stored in YAML - hf_token: ${HF_TOKEN} - # wandb_key: ${WANDB_API_KEY} - - # Optional: extra shell commands run on the VM after `pip install -e .` - # setup: | - # pip install some-extra-dependency - - # Optional: override the default output directory (default: ./skypilot_jobs) - # job_dir: /path/to/skypilot/jobs - -# ── Training config (forwarded to the VM unchanged) ─────────────────────── -step_scheduler: - global_batch_size: 64 - local_batch_size: 8 - num_epochs: 1 - -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - -# ... rest of your training config ... -``` - -### All `skypilot:` Fields - -| Field | Default | Description | -|---|---|---| -| `cloud` | *(required)* | Cloud provider: `aws`, `gcp`, `azure`, `lambda`, `kubernetes` | -| `accelerators` | `T4:1` | GPU type and count per node, e.g. `A100:8`, `V100:4` | -| `num_nodes` | `1` | Number of VMs for distributed training | -| `use_spot` | `true` | Use spot/preemptible instances | -| `disk_size` | `100` | Remote VM disk size in GB | -| `region` | *(auto)* | Cloud region; SkyPilot selects cheapest if omitted | -| `zone` | *(auto)* | Availability zone within the region | -| `instance_type` | *(auto)* | Specific instance type; auto-selected if omitted | -| `job_name` | `_` | Job and SkyPilot cluster name | -| `setup` | *(auto)* | Extra setup commands run after `pip install -e .` | -| `hf_home` | `~/.cache/huggingface` | Hugging Face cache directory on the remote VM | -| `hf_token` | `$HF_TOKEN` env | Hugging Face token for gated model access | -| `wandb_key` | `$WANDB_API_KEY` env | Weights & Biases API key | -| `env_vars` | `{}` | Additional environment variables for the remote VM | -| `job_dir` | `./skypilot_jobs` | Local directory for job artifacts (config snapshot, logs) | -| `gpus_per_node` | *(parsed from `accelerators`)* | Override GPU count per node passed to `torchrun` | - -## Cloud Examples - -### AWS — On-Demand A10G - -```yaml -skypilot: - cloud: aws - accelerators: A10G:1 - use_spot: false - region: us-east-1 - job_name: llm_aws_finetune - hf_token: ${HF_TOKEN} -``` - -### GCP — Spot V100, 8 GPUs (Single Node) - -```yaml -skypilot: - cloud: gcp - accelerators: V100:8 - use_spot: true - region: us-west1 - job_name: llm_gcp_v100_8gpu - hf_token: ${HF_TOKEN} -``` - -### Multi-Node Distributed Training (2 x 8 x A100) - -```yaml -skypilot: - cloud: gcp - accelerators: A100:8 - num_nodes: 2 - use_spot: false - job_name: llm_multinode_a100 - hf_token: ${HF_TOKEN} -``` - -For multi-node jobs, the launcher automatically adds the SkyPilot rendezvous environment variables (`$SKYPILOT_NODE_RANK`, `$SKYPILOT_NUM_NODES`, `$SKYPILOT_NODE_IPS`) to the `torchrun` command. - -## Monitor and Manage Jobs - -After submitting, use standard SkyPilot commands: - -```bash -sky status # List running clusters and their status -sky logs # Stream training logs -sky ssh # SSH into the VM for debugging -sky cancel # Cancel a running job -sky down # Terminate the cluster and stop billing -``` - -## How It Works - -1. The `automodel` CLI detects the `skypilot:` key in the YAML and calls `launch_with_skypilot()`. -2. The training config (with `skypilot:` removed) is written to a local `skypilot_jobs//job_config.yaml`. -3. A `sky.Task` is created with: - - **workdir** — the current directory synced to `~/sky_workdir` on the remote VM. - - **file_mounts** — the job config uploaded to `/tmp/automodel_job_config.yaml`. - - **setup** — `pip install -e .` (plus any custom `setup:` commands). - - **run** — a `torchrun` command pointing at the recipe script and config. -4. `sky.launch()` provisions the VM, runs setup, then executes training. The call returns immediately (`detach_run=True`); use `sky logs` to follow progress. - -## Customize Configuration - -Override any training parameter from the command line, same as with local runs: - -```bash -automodel config_with_skypilot.yaml \ - --model.pretrained_model_name_or_path meta-llama/Llama-3.2-3B -``` - -## Kubernetes Users - -If you want to run on a Kubernetes cluster, use `cloud: kubernetes` and follow the dedicated [SkyPilot + Kubernetes tutorial](/job-launchers/skypilot-k8s). That guide includes: - -- a copy-paste single-node config -- a two-node example -- sample `sky` and `kubectl` output to help you sanity-check your setup -- a short troubleshooting section for common first-run issues - -## When to Use SkyPilot vs. Slurm - -| | SkyPilot | Slurm | -|---|---|---| -| **Infrastructure** | Any public cloud | On-premises HPC cluster | -| **Spot instances** | Yes (automatic) | Depends on cluster config | -| **Setup required** | Cloud credentials + `sky check` | Cluster access | -| **Good for** | Flexible cloud burst, cost optimization | Fixed on-prem GPU clusters | diff --git a/docs/fern/versions/nightly/pages/launcher/slurm.mdx b/docs/fern/versions/nightly/pages/launcher/slurm.mdx deleted file mode 100644 index 1978b0c6bc..0000000000 --- a/docs/fern/versions/nightly/pages/launcher/slurm.mdx +++ /dev/null @@ -1,192 +0,0 @@ ---- -title: "Run on a Cluster" -description: "" -position: 3 ---- -In this guide, you will learn how to submit distributed training jobs on Slurm clusters (single- or multi-node). For single-node workstation usage, see [Run on Your Local Workstation](/job-launchers/local-workstation). For setup details, refer to our [Installation Guide](/get-started/installation). - -NeMo AutoModel uses recipes to run end-to-end workflows. If you're new to recipes, see the [Repository Structure](/get-started/repo-structure) guide. - -## Quickstart - -```bash -# Edit the reference script for your cluster, then submit: -cp slurm.sub my_cluster.sub -vim my_cluster.sub -sbatch my_cluster.sub -``` - -For interactive testing on a Slurm node: - - Single node, single GPU - ```bash - automodel your_config.yaml - ``` - - Single node, multiple GPUs - ```bash - automodel --nproc-per-node 8 your_config.yaml - ``` - -## Submit a Batch Job with Slurm - -SLURM clusters vary widely: some use Pyxis containers, others use -Singularity/Apptainer, and many run bare-metal with environment modules. -Instead of trying to cover all variations in code, AutoModel provides a -reference sbatch script that you copy and adapt to your cluster. - -### Getting Started - -1. Copy the reference script: - -```bash -cp slurm.sub my_cluster.sub -``` - -2. Edit `my_cluster.sub` — change `CONFIG`, `#SBATCH` directives (account, - partition, nodes, time), container runtime, mounts, and secrets for your - cluster. - -3. Submit the job: - -```bash -sbatch my_cluster.sub -``` - -### How It Works - -The reference `slurm.sub` script: - -1. Sets `CONFIG` to point at your YAML recipe config -2. Allocates nodes via SBATCH directives -3. Sets up the multi-node environment (`MASTER_ADDR`, `MASTER_PORT`) -4. Runs `torchrun -m nemo_automodel.cli.app $CONFIG` on each node via `srun` -5. Each torchrun worker detects the distributed environment and runs the recipe in-process - -All cluster-specific configuration (SBATCH directives, container runtime, -mounts, NCCL tuning, secrets) lives in your sbatch script where you can see -and edit it directly. - -### Examples - -**Pyxis container (NVIDIA clusters):** - -```bash -#!/bin/bash -#SBATCH -A my_account -#SBATCH -p batch -#SBATCH -t 01:00:00 -#SBATCH -N 8 -#SBATCH --gpus-per-node=8 -#SBATCH --ntasks-per-node=1 -#SBATCH -J automodel-finetune -#SBATCH --output=slurm_jobs/%x_%j.out -#SBATCH --error=slurm_jobs/%x_%j.err - -CONFIG=examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml - -CONT=/lustre/fsw/images/automodel.sqsh -CONT_NAME=automodel-training -CONT_MOUNT="\ -/home/$USER/Automodel:/opt/Automodel,\ -/home/$USER/.cache/huggingface:/root/.cache/huggingface" - -export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1) -export MASTER_PORT=13742 - -srun \ - --container-name="${CONT_NAME}" \ - --container-image="${CONT}" \ - --container-mounts="${CONT_MOUNT}" \ - --container-entrypoint \ - --no-container-mount-home \ - --export=ALL \ - bash -c "\ - cd /opt/Automodel && \ - torchrun \ - --nproc-per-node=\${SLURM_GPUS_PER_NODE:-8} \ - --nnodes=\${SLURM_NNODES:-1} \ - --rdzv_backend=c10d \ - --rdzv_endpoint=\${MASTER_ADDR}:\${MASTER_PORT} \ - -m nemo_automodel.cli.app ${CONFIG}" -``` - -**Bare-metal (no container):** - -```bash -#!/bin/bash -#SBATCH -A my_account -#SBATCH -p gpu -#SBATCH -N 2 -#SBATCH --gpus-per-node=8 -#SBATCH --time=01:00:00 - -CONFIG=examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml - -export MASTER_ADDR=$(scontrol show hostnames "$SLURM_JOB_NODELIST" | head -n 1) -export MASTER_PORT=13742 - -module load cuda/12.8 -source /opt/venvs/automodel/bin/activate - -srun bash -c "\ - torchrun \ - --nproc-per-node=\${SLURM_GPUS_PER_NODE:-8} \ - --nnodes=\${SLURM_NNODES:-1} \ - --rdzv_backend=c10d \ - --rdzv_endpoint=\${MASTER_ADDR}:\${MASTER_PORT} \ - -m nemo_automodel.cli.app ${CONFIG}" -``` - -**Apptainer / Singularity:** - -```bash -#!/bin/bash -#SBATCH -A my_account -#SBATCH -p gpu -#SBATCH -N 2 -#SBATCH --gpus-per-node=8 -#SBATCH --time=01:00:00 - -CONFIG=examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml - -export MASTER_ADDR=$(scontrol show hostnames "$SLURM_JOB_NODELIST" | head -n 1) -export MASTER_PORT=13742 - -srun apptainer exec --nv /shared/images/automodel.sif \ - bash -c "\ - torchrun \ - --nproc-per-node=\${SLURM_GPUS_PER_NODE:-8} \ - --nnodes=\${SLURM_NNODES:-1} \ - --rdzv_backend=c10d \ - --rdzv_endpoint=\${MASTER_ADDR}:\${MASTER_PORT} \ - -m nemo_automodel.cli.app ${CONFIG}" -``` - -### Launch with Modified Code - -If the script is executed from within a Git repository accessible to Slurm -workers, automodel will use the repository source over the installation -inside the container image (it prepends `$CWD` to `PYTHONPATH` when it -detects an editable checkout). - -```bash -git clone git@github.com:NVIDIA-NeMo/Automodel.git automodel_test_repo -cd automodel_test_repo/ -sbatch slurm.sub -``` - -## Customize Configuration Settings - -You can customize training by following the steps in this section. - -1. **Override config values**: Edit the `CONFIG` variable and add CLI overrides - in your torchrun command inside the sbatch script. For example, to change - the model: - ```bash - -m nemo_automodel.cli.app ${CONFIG} --model.pretrained_model_name_or_path Qwen/Qwen3-0.6B - ``` - -2. **Edit the config file**: Modify the YAML directly for persistent changes. - -3. **Create custom configs**: Copy and modify existing configurations from the `examples/` directory. - -For single-node workflows, see our [Run on Your Local Workstation](/job-launchers/local-workstation) guide. diff --git a/docs/fern/versions/nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx deleted file mode 100644 index c83291307c..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/diffusion/black-forest-labs/flux.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "FLUX.1-dev" -description: "" ---- -[FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev) is a 12B parameter text-to-image diffusion transformer from Black Forest Labs, trained with flow matching. It produces high-fidelity images and is designed for non-commercial research and development use. - - - -| | | -|---|---| -| **Task** | Text-to-Image | -| **Architecture** | DiT (Flow Matching) | -| **Parameters** | 12B | -| **HF Org** | [black-forest-labs](https://huggingface.co/black-forest-labs) | - - - -## Available Models - -- **FLUX.1-dev**: 12B parameters - -## Task - -- Text-to-Image (T2I) - -## Example HF Models - -| Model | HF ID | -|---|---| -| FLUX.1-dev | [`black-forest-labs/FLUX.1-dev`](https://huggingface.co/black-forest-labs/FLUX.1-dev) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [flux_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/flux_t2i_flow.yaml) | Fine-tune — FLUX.1-dev with flow matching | -| [flux_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/pretrain/flux_t2i_flow.yaml) | Pretrain — FLUX.1-dev with flow matching | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/flux_t2i_flow.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/flux_t2i_flow.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [Diffusion Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). - -## Training - -See the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning) and [Dataset Preparation](/datasets/diffusion-dataset). - -## Hugging Face Model Cards - -- [black-forest-labs/FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev) diff --git a/docs/fern/versions/nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx deleted file mode 100644 index c6f1d0889a..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "HunyuanVideo 1.5" -description: "" ---- -[HunyuanVideo 1.5](https://huggingface.co/hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v) is a 13B parameter text-to-video diffusion model from the Hunyuan community, supporting 720p resolution video generation with flow matching training. - - - -| | | -|---|---| -| **Task** | Text-to-Video | -| **Architecture** | DiT (Flow Matching) | -| **Parameters** | 13B | -| **HF Org** | [hunyuanvideo-community](https://huggingface.co/hunyuanvideo-community) | - - - -## Available Models - -- **HunyuanVideo-1.5-Diffusers-720p_t2v**: 13B parameters - -## Task - -- Text-to-Video (T2V) - -## Example HF Models - -| Model | HF ID | -|---|---| -| HunyuanVideo 1.5 720p T2V | [`hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v`](https://huggingface.co/hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [hunyuan_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/hunyuan_t2v_flow.yaml) | Fine-tune — HunyuanVideo 1.5 with flow matching | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/hunyuan_t2v_flow.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/hunyuan_t2v_flow.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [Diffusion Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). - -## Training - -See the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning) and [Dataset Preparation](/datasets/diffusion-dataset). - -## Hugging Face Model Cards - -- [hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v](https://huggingface.co/hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v) diff --git a/docs/fern/versions/nightly/pages/model-coverage/diffusion/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/index.mdx deleted file mode 100644 index 3c3fcf0667..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/diffusion/index.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "Diffusion Models" -description: "" -position: 6 ---- -## Introduction - -Diffusion models are a class of generative models that learn to produce images or videos by iteratively denoising samples from a noise distribution. NeMo AutoModel supports training diffusion models using **flow matching**, a framework that regresses velocity fields along straight interpolation paths between noise and data. - -NeMo AutoModel integrates with [Hugging Face Diffusers](https://huggingface.co/docs/diffusers) for model loading and generation, while providing its own distributed training infrastructure via the `TrainDiffusionRecipe`. This recipe handles FSDP2 parallelization, flow matching loss computation, multiresolution bucketed dataloading, and checkpoint management. - -## Supported Models - -| Owner | Model | Task | Architecture | -|---|---|---|---| -| Wan AI | [Wan 2.1 T2V](/model-coverage/diffusion/wan-2-1-t2v) | Text-to-Video | DiT (Flow Matching) | -| Black Forest Labs | [FLUX.1-dev](/model-coverage/diffusion/flux-1-dev) | Text-to-Image | DiT (Flow Matching) | -| Hunyuan Community | [HunyuanVideo 1.5](/model-coverage/diffusion/hunyuanvideo-1-5) | Text-to-Video | DiT (Flow Matching) | -| Qwen / Alibaba Cloud | [Qwen-Image](/model-coverage/diffusion/qwen-image) | Text-to-Image | DiT (Flow Matching) | - -## Supported Workflows - -- **Pretraining**: Train from randomly initialized weights on large-scale datasets -- **Fine-tuning**: Adapt pretrained model weights to a specific dataset or style -- **Generation**: Run inference with pretrained or fine-tuned checkpoints - -## Dataset - -Diffusion training requires pre-encoded `.meta` files containing VAE latents and text embeddings. Raw videos or images must be preprocessed before training. See the [Diffusion Dataset Preparation](/datasets/diffusion-dataset) guide. - -## Train Diffusion Models - -For a complete walkthrough of training configuration, model-specific settings, and launch commands, see the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). diff --git a/docs/fern/versions/nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx deleted file mode 100644 index e171db2403..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/diffusion/qwen/qwen-image.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Qwen-Image" -description: "" ---- -[Qwen-Image](https://huggingface.co/Qwen/Qwen-Image) is Alibaba Cloud's text-to-image diffusion transformer. NeMo AutoModel supports Qwen-Image training via its flow-matching pipeline with a dedicated `qwen_image` adapter, enabling FSDP2 parallelization, multiresolution bucketed dataloading and LoRA-style fine-tuning. - - - -| | | -|---|---| -| **Task** | Text-to-Image | -| **Architecture** | DiT (Flow Matching) | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen-Image** - -## Task - -- Text-to-Image (T2I) - -## Example HF Models - -| Model | HF ID | -|---|---| -| Qwen-Image | [`Qwen/Qwen-Image`](https://huggingface.co/Qwen/Qwen-Image) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [qwen_image_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/qwen_image_t2i_flow.yaml) | Fine-tune — Qwen-Image with flow matching | -| [qwen_image_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/pretrain/qwen_image_t2i_flow.yaml) | Pretrain — Qwen-Image with flow matching | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/qwen_image_t2i_flow.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/qwen_image_t2i_flow.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). - -## Fine-Tuning - -See the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). - -## Hugging Face Model Cards - -- [Qwen/Qwen-Image](https://huggingface.co/Qwen/Qwen-Image) diff --git a/docs/fern/versions/nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx b/docs/fern/versions/nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx deleted file mode 100644 index befb82feef..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "Wan 2.1 T2V" -description: "" ---- -[Wan 2.1](https://huggingface.co/Wan-AI/Wan2.1-T2V-1.3B-Diffusers) is a text-to-video diffusion model from Wan AI, trained with flow matching on a large-scale video dataset. It generates high-quality short video clips from text prompts. - - - -| | | -|---|---| -| **Task** | Text-to-Video | -| **Architecture** | DiT (Flow Matching) | -| **Parameters** | 1.3B | -| **HF Org** | [Wan-AI](https://huggingface.co/Wan-AI) | - - - -## Available Models - -- **Wan2.1-T2V-1.3B**: 1.3B parameters - -## Task - -- Text-to-Video (T2V) - -## Example HF Models - -| Model | HF ID | -|---|---| -| Wan 2.1 T2V 1.3B | [`Wan-AI/Wan2.1-T2V-1.3B-Diffusers`](https://huggingface.co/Wan-AI/Wan2.1-T2V-1.3B-Diffusers) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow.yaml) | Fine-tune — Wan 2.1 T2V with flow matching | -| [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/pretrain/wan2_1_t2v_flow.yaml) | Pretrain — Wan 2.1 T2V with flow matching | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/wan2_1_t2v_flow.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -torchrun --nproc-per-node=8 \ - examples/diffusion/finetune/finetune.py \ - -c examples/diffusion/finetune/wan2_1_t2v_flow.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [Diffusion Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). - -## Training - -See the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning) and [Dataset Preparation](/datasets/diffusion-dataset). - -## Hugging Face Model Cards - -- [Wan-AI/Wan2.1-T2V-1.3B-Diffusers](https://huggingface.co/Wan-AI/Wan2.1-T2V-1.3B-Diffusers) diff --git a/docs/fern/versions/nightly/pages/model-coverage/embedding/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/embedding/index.mdx deleted file mode 100644 index 8c860cec33..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/embedding/index.mdx +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: "Embedding Models" -description: "" -position: 1 ---- - -## Introduction - -Text embedding models transform text into dense vector representations that power semantic search, dense retrieval, retrieval-augmented generation (RAG), and classification tasks. NeMo AutoModel includes a training recipe for converting Llama decoder-only models into encoder architectures with bidirectional attention, and falls back to Hugging Face AutoModel for other encoder backbones. - -For cross-encoder pairwise scoring, see [Reranking Models](/model-coverage/reranking-models/overview). - -Embedding models use bi-encoders to produce dense representations for queries and documents independently. They are the standard path for embedding generation and first-stage dense retrieval. - -### Optimized Backbones (Bidirectional Attention) - -| Owner | Model | Architecture | Auto Class | Tasks | -|---|---|---|---|---| -| NVIDIA | [Llama (Bidirectional)](/model-coverage/embedding-models/llama-bidirectional) | `LlamaBidirectionalModel` | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Embedding, Dense Retrieval | -| Mistral AI | [Ministral3 (Bidirectional)](/model-coverage/embedding-models/ministral3-bidirectional) | `Ministral3BidirectionalModel` | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Embedding, Dense Retrieval | - -### Hugging Face Auto Backbones - -Any Hugging Face model that can be loaded with `AutoModel` can be used as an embedding backbone. This fallback path uses the model's native attention; no bidirectional conversion is applied. - -## Example Recipes - -| Recipe | Description | -|---|---| -| [llama3_2_1b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama3_2_1b.yaml) | Bi-encoder — Llama 3.2 1B embedding model | -| [llama_embed_nemotron_8b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama_embed_nemotron_8b/llama_embed_nemotron_8b.yaml) | Bi-encoder — Llama-Embed-Nemotron-8B reproduction recipe | -| [ministral3_3b_instruct.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/ministral3_3b_instruct.yaml) | Bi-encoder — Ministral3-3B recipe | - -## Supported Workflows - -- **Fine-tuning (Bi-Encoder):** Contrastive learning on query-document pairs to produce embedding models -- **LoRA/PEFT:** Parameter-efficient fine-tuning for embedding backbones -- **ONNX Export:** Export trained embedding models for deployment (case by case, model dependent) - -## Dataset - -Retrieval fine-tuning requires query-document pairs: each example is a query paired with one positive document and one or more negative documents. Both inline JSONL and corpus ID-based JSON formats are supported. See the [Retrieval Dataset](/datasets/retrieval-dataset) guide. - -{/* -@akoumpa: uncomment this when finetune guide is published. -## Train Embedding Models - -For a complete walkthrough of training configuration, model-specific settings, and launch commands, see the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune). -*/} diff --git a/docs/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx b/docs/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx deleted file mode 100644 index 255d59bb3d..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: "Ministral3 (Bidirectional) for Embedding" -description: "" ---- - -NeMo AutoModel provides a bidirectional variant of [Mistral AI's Ministral3](https://mistral.ai/news/ministraux/) for embedding and dense retrieval tasks. Unlike the standard causal (left-to-right) Ministral3 used for text generation, this variant uses **bidirectional attention**, so each token can attend to both past and future tokens in the sequence, producing richer representations for semantic similarity and dense retrieval. - -The bidirectional encoder can be loaded directly from text-only checkpoints (e.g. `mistralai/Ministral-3B-Instruct`) and also automatically extracts the language model from Ministral3 VLM checkpoints (e.g. `mistralai/Ministral-3-3B-Base-2512` or `mistralai/Ministral-3-3B-Instruct-2512`). - -| | | -|---|---| -| **Tasks** | Embedding, Dense Retrieval | -| **Architecture** | `Ministral3BidirectionalModel` | -| **Parameters** | 3B | -| **HF Org** | [mistralai](https://huggingface.co/mistralai) | - -## Available Models - -Any Ministral3 checkpoint can be loaded as a bidirectional backbone. The following configurations are tested: - -- **Ministral-3-3B-Base-2512** — VLM checkpoint, language model is extracted automatically -- **Ministral-3-3B-Instruct-2512** — VLM checkpoint, language model is extracted automatically - -## Embedding Models - -The bidirectional bi-encoder path is used for embedding generation and dense retrieval. - -| Architecture | Task | Auto Class | Description | -|---|---|---|---| -| `Ministral3BidirectionalModel` | Embedding | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Bidirectional Ministral3 with mean pooling for dense embeddings | - -## Pooling Strategies - -The bi-encoder supports multiple pooling strategies to aggregate token representations into a single embedding vector: - -| Strategy | Description | -|---|---| -| `avg` | Average of all token hidden states (default) | -| `cls` | First token hidden state | -| `last` | Last non-padding token hidden state | -| `weighted_avg` | Weighted average of token hidden states | - -## Example HF Models - -| Model | HF ID | -|---|---| -| Ministral-3 3B Base | [`mistralai/Ministral-3-3B-Base-2512`](https://huggingface.co/mistralai/Ministral-3-3B-Base-2512) | -| Ministral-3 3B Instruct | [`mistralai/Ministral-3-3B-Instruct-2512`](https://huggingface.co/mistralai/Ministral-3-3B-Instruct-2512) | - -## Try with NeMo AutoModel - -**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](/get-started/installation)) for information: - -```bash -uv pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo (point any Llama bi-encoder recipe at a Ministral3 checkpoint, or write a recipe targeting `mistralai/Ministral-3-3B-Base-2512`): - -```bash -torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/llama3_2_1b.yaml -torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/ministral3_3b_instruct.yaml -``` - -See the [Installation Guide](/get-started/installation). - -{/* TODO: uncomment when finetune guide is published. -## Fine-Tuning - -See the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune) for bi-encoder training instructions, including LoRA and PEFT configuration. -*/} - -## Hugging Face Model Cards - -- [mistralai/Ministral-3-3B-Base-2512](https://huggingface.co/mistralai/Ministral-3-3B-Base-2512) -- [mistralai/Ministral-3-3B-Instruct-2512](https://huggingface.co/mistralai/Ministral-3-3B-Instruct-2512) diff --git a/docs/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx b/docs/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx deleted file mode 100644 index dd4851039a..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/embedding/nvidia/llama-bidirectional.mdx +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: "Llama (Bidirectional) for Embedding" -description: "" ---- - -NeMo AutoModel provides a bidirectional variant of [Meta's Llama](https://www.llama.com/) for embedding and dense retrieval tasks. Unlike the standard causal (left-to-right) Llama used for text generation, this variant uses **bidirectional attention**, so each token can attend to both past and future tokens in the sequence, producing richer representations for semantic similarity and dense retrieval. - -For the cross-encoder variant, see [Llama (Bidirectional) for Reranking](/model-coverage/reranking-models/llama-bidirectional). - -| | | -|---|---| -| **Tasks** | Embedding, Dense Retrieval | -| **Architecture** | `LlamaBidirectionalModel` | -| **Parameters** | 1B – 8B | -| **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | - -## Available Models - -Any Llama checkpoint can be loaded as a bidirectional backbone. The following configurations are tested: - -- **Llama 3.2 1B** — fast iteration, fits on a single GPU -- **Llama 3.1 8B** — higher-quality embeddings for production use - -## Embedding Models - -The bidirectional bi-encoder path is used for embedding generation and dense retrieval. - -| Architecture | Task | Auto Class | Description | -|---|---|---|---| -| `LlamaBidirectionalModel` | Embedding | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Bidirectional Llama with mean pooling for dense embeddings | - -## Pooling Strategies - -The bi-encoder supports multiple pooling strategies to aggregate token representations into a single embedding vector: - -| Strategy | Description | -|---|---| -| `avg` | Average of all token hidden states (default) | -| `cls` | First token hidden state | -| `last` | Last non-padding token hidden state | -| `weighted_avg` | Weighted average of token hidden states | - -## Example HF Models - -| Model | HF ID | -|---|---| -| Llama 3.2 1B | [`meta-llama/Llama-3.2-1B`](https://huggingface.co/meta-llama/Llama-3.2-1B) | -| Llama 3.1 8B | [`meta-llama/Llama-3.1-8B`](https://huggingface.co/meta-llama/Llama-3.1-8B) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [llama3_2_1b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama3_2_1b.yaml) | Bi-encoder — Llama 3.2 1B embedding model | -| [llama_embed_nemotron_8b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama_embed_nemotron_8b/llama_embed_nemotron_8b.yaml) | Bi-encoder — reproduction recipe for [`nvidia/llama-embed-nemotron-8b`](https://huggingface.co/nvidia/llama-embed-nemotron-8b) (uses [`nvidia/embed-nemotron-dataset-v1`](https://huggingface.co/datasets/nvidia/embed-nemotron-dataset-v1)) | - -## Try with NeMo AutoModel - -**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](/get-started/installation)) for information: - -```bash -uv pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/llama3_2_1b.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.04.00 -``` - -**2. Navigate** to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/llama3_2_1b.yaml -``` - - -See the [Installation Guide](/get-started/installation). - -{/* TODO: uncomment when finetune guide is published. -## Fine-Tuning - -See the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune) for bi-encoder training instructions, including LoRA and PEFT configuration. -*/} - -## Hugging Face Model Card - -NVIDIA trained and released the `Llama Nemotron Embedding 1B` model, which leverages a bidirectional attention mechanism for multilingual and cross-lingual question–answer retrieval. The model supports long documents (up to 8,192 tokens) and dynamic embedding sizes via Matryoshka embeddings. For more details, see the model card on Hugging Face. - -- [nvidia/llama-nemotron-embed-1b-v2](https://huggingface.co/nvidia/llama-nemotron-embed-1b-v2) -- [nvidia/llama-embed-nemotron-8b](https://huggingface.co/nvidia/llama-embed-nemotron-8b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/latest-models.mdx b/docs/fern/versions/nightly/pages/model-coverage/latest-models.mdx deleted file mode 100644 index 65d22cb680..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/latest-models.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "Model Release Log" -description: "" -position: 2 ---- -A reverse-chronological log of every model added to NeMo AutoModel. The **Recipe** column links to a working example YAML you can run immediately. - -See the [Model Coverage Overview](/model-coverage/overview) for release summaries, and the [LLM](/model-coverage/large-language-models/overview) / [VLM](/model-coverage/vision-language-models/overview) / [Omni](/model-coverage/omni/overview) / [Diffusion](/model-coverage/diffusion/overview) pages for the full architecture listings. - -| Date | Model | HF Model ID | Modality | Recipe | Try on Brev | -|------|-------|-------------|----------|--------|------| -| 2026-04-29 | Mistral Medium 3.5 | [`mistralai/Mistral-Medium-3.5-128B`](https://huggingface.co/mistralai/Mistral-Medium-3.5-128B) | VLM | [mistral3p5_128b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral3p5/mistral3p5_128b_medpix.yaml) | 🚧 | -| 2026-04-28 | Hy3-preview | [`tencent/Hy3-preview`](https://huggingface.co/tencent/Hy3-preview) | LLM | [hy3_preview_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml) | 🚧 | -| 2026-04-25 | DeepSeek V4 Flash | [`deepseek-ai/DeepSeek-V4-Flash`](https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash) | LLM | [deepseek_v4_flash_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml) | 🚧 | -| 2026-04-22 | Qwen3.6-27B | [`Qwen/Qwen3.6-27B`](https://huggingface.co/Qwen/Qwen3.6-27B) | VLM | [qwen3_6_27b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5/qwen3_6_27b.yaml) | 🚧 | -| 2026-04-16 | LLaVA-OneVision-1.5 (4B / 8B) | [`lmms-lab/LLaVA-OneVision-1.5-4B-Instruct`](https://huggingface.co/lmms-lab/LLaVA-OneVision-1.5-4B-Instruct) | VLM | [llava_ov_1_5_4b_finetune.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/llava_onevision/llava_ov_1_5_4b_finetune.yaml) | 🚧 | -| 2026-04-16 | Qwen3.6 MoE | [`Qwen/Qwen3.6-35B-A3B`](https://huggingface.co/Qwen/Qwen3.6-35B-A3B) | VLM | [qwen3_6_35b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5_moe/qwen3_6_35b.yaml) | 🚧 | -| 2026-04-12 | MiniMax-M2.7 | [`MiniMaxAI/MiniMax-M2.7`](https://huggingface.co/MiniMaxAI/MiniMax-M2.7) | LLM | [minimax_m2.7_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.7_hellaswag_pp.yaml) | -| 2026-04-07 | GLM-5.1 | [`zai-org/GLM-5.1`](https://huggingface.co/zai-org/GLM-5.1) | LLM | [glm_5.1_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_5.1_hellaswag_pp.yaml) | 🚧 | -| 2026-04-02 | Gemma 4 | [`google/gemma-4-E4B-it`](https://huggingface.co/google/gemma-4-E4B-it) | VLM | [gemma4_4b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_4b.yaml) | 🚧 | -| 2026-03-16 | Mistral Small 4 | [`mistralai/Mistral-Small-4-119B-2603`](https://huggingface.co/mistralai/Mistral-Small-4-119B-2603) | VLM | [mistral4_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral4/mistral4_medpix.yaml) | 🚧 | -| 2026-03-11 | Nemotron Super v3 | [`nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-BF16`](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-BF16) | LLM | [nemotron_super_v3_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_super_v3_hellaswag.yaml) | 🚧 | -| 2026-03-11 | GLM-5 | [`zai-org/GLM-5`](https://huggingface.co/zai-org/GLM-5) | LLM | [glm_5_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml) | 🚧 | -| 2026-03-03 | FLUX.1-dev | [`black-forest-labs/FLUX.1-dev`](https://huggingface.co/black-forest-labs/FLUX.1-dev) | Diffusion | [flux_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/flux_t2i_flow.yaml) | 🚧 | -| 2026-03-03 | Wan 2.1 T2V | [`Wan-AI/Wan2.1-T2V-1.3B-Diffusers`](https://huggingface.co/Wan-AI/Wan2.1-T2V-1.3B-Diffusers) | Diffusion | [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow.yaml) | 🚧 | -| 2026-03-03 | HunyuanVideo 1.5 | [`hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v`](https://huggingface.co/hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v) | Diffusion | [hunyuan_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/hunyuan_t2v_flow.yaml) | 🚧 | -| 2026-03-02 | Qwen3.5 (0.8B – 9B) | [`Qwen/Qwen3.5-9B`](https://huggingface.co/Qwen/Qwen3.5-9B) | VLM | [qwen3_5_9b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5/qwen3_5_9b.yaml) | 🚧 | -| 2026-02-16 | Qwen3.5 MoE | [`Qwen/Qwen3.5-397B-A17B`](https://huggingface.co/Qwen/Qwen3.5-397B-A17B) | VLM | [qwen3_5_moe_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5_moe/qwen3_5_moe_medpix.yaml) | 🚧 | -| 2026-02-13 | MiniMax-M2.5 | [`MiniMaxAI/MiniMax-M2.5`](https://huggingface.co/MiniMaxAI/MiniMax-M2.5) | LLM | [minimax_m2.5_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.5_hellaswag_pp.yaml) | 🚧 | -| 2026-02-11 | GLM-4.7-Flash | [`zai-org/GLM-4.7-Flash`](https://huggingface.co/zai-org/GLM-4.7-Flash) | LLM | [glm_4.7_flash_te_packed_sequence.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.7_flash_te_packed_sequence.yaml) | 🚧 | -| 2026-02-09 | MiniMax-M2.1 | [`MiniMaxAI/MiniMax-M2`](https://huggingface.co/MiniMaxAI/MiniMax-M2) | LLM | [minimax_m2.1_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.1_hellaswag_pp.yaml) | 🚧 | -| 2026-02-06 | Qwen3-VL-235B | [`Qwen/Qwen3-VL-235B-A22B-Instruct`](https://huggingface.co/Qwen/Qwen3-VL-235B-A22B-Instruct) | VLM | [qwen3_vl_moe_235b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_moe_235b.yaml) | 🚧 | -| 2026-02-06 | GLM-4.7 | [`zai-org/GLM-4.7`](https://huggingface.co/zai-org/GLM-4.7) | LLM | [glm_4.7_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.7_te_deepep.yaml) | 🚧 | -| 2026-02-06 | Step-3.5-Flash | [`stepfun-ai/Step-3.5-Flash`](https://huggingface.co/stepfun-ai/Step-3.5-Flash) | LLM | [step_3.5_flash_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml) | 🚧 | -| 2026-02-05 | DeepSeek-V3.2 | [`deepseek-ai/DeepSeek-V3.2`](https://huggingface.co/deepseek-ai/DeepSeek-V3.2) | LLM | [deepseek_v32_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml) | 🚧 | -| 2026-02-04 | Kimi-K2.5 VL | [`moonshotai/Kimi-K2.5`](https://huggingface.co/moonshotai/Kimi-K2.5) | VLM | [kimi25vl_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/kimi/kimi25vl_medpix.yaml) | 🚧 | -| 2026-01-30 | Kimi-VL | [`moonshotai/Kimi-VL-A3B-Instruct`](https://huggingface.co/moonshotai/Kimi-VL-A3B-Instruct) | VLM | [kimi2vl_cordv2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/kimi/kimi2vl_cordv2.yaml) | 🚧 | -| 2026-01-12 | Nemotron Flash 1B | [`nvidia/Nemotron-Flash-1B`](https://huggingface.co/nvidia/Nemotron-Flash-1B) | LLM | [nemotron_flash_1b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad.yaml) | 🚧 | -| 2026-01-12 | Nemotron Parse v1.1 | [`nvidia/NVIDIA-Nemotron-Parse-v1.1`](https://huggingface.co/nvidia/NVIDIA-Nemotron-Parse-v1.1) | VLM | [nemotron_parse_v1_1.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml) | Launch on Brev | -| 2026-01-07 | Devstral-Small-2512 | [`mistralai/Devstral-Small-2-24B-Instruct-2512`](https://huggingface.co/mistralai/Devstral-Small-2-24B-Instruct-2512) | LLM | [devstral2_small_2512_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/devstral/devstral2_small_2512_squad.yaml) | 🚧 | -| 2025-12-15 | Nemotron-3-Nano-30B-A3B | [`nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-FP8`](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-FP8) | LLM | [nemotron_nano_v3_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_v3_hellaswag.yaml) | 🚧 | -| 2025-12-05 | Ministral 3 (3B / 8B / 14B) | [`mistralai/Ministral-8B-Instruct-2410`](https://huggingface.co/mistralai/Ministral-8B-Instruct-2410) | VLM | [ministral3_8b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral/ministral3_8b_medpix.yaml) | 🚧 | -| 2025-11-24 | GLM-4.5-Air | [`zai-org/GLM-4.5-Air`](https://huggingface.co/zai-org/GLM-4.5-Air) | LLM | [glm_4.5_air_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.5_air_te_deepep.yaml) | 🚧 | -| 2025-11-19 | InternVL 3.5 | [`OpenGVLab/InternVL3_5-4B`](https://huggingface.co/OpenGVLab/InternVL3_5-4B) | VLM | [internvl_3_5_4b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/internvl/internvl_3_5_4b.yaml) | 🚧 | -| 2025-11-10 | Qwen3-Omni | [`Qwen/Qwen3-30B-A3B`](https://huggingface.co/Qwen/Qwen3-30B-A3B) | Omni | [qwen3_omni_moe_30b_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_omni_moe_30b_te_deepep.yaml) | 🚧 | -| 2025-10-24 | Qwen3-Next | [`Qwen/Qwen3-235B-A22B`](https://huggingface.co/Qwen/Qwen3-235B-A22B) | LLM | [qwen3_next_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_next_te_deepep.yaml) | 🚧 | -| 2025-10-23 | Qwen3-VL (4B / 8B) | [`Qwen/Qwen3-VL-8B-Instruct`](https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct) | VLM | [qwen3_vl_4b_instruct_rdr.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_4b_instruct_rdr.yaml) | 🚧 | -| 2025-10-05 | Mixtral 8x7B | [`mistralai/Mixtral-8x7B-Instruct-v0.1`](https://huggingface.co/mistralai/Mixtral-8x7B-Instruct-v0.1) | LLM | [mixtral-8x7b-v0-1_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad.yaml) | 🚧 | -| 2025-09-29 | DeepSeek-V3 | [`deepseek-ai/DeepSeek-V3`](https://huggingface.co/deepseek-ai/DeepSeek-V3) | LLM | [deepseekv3_pretrain.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_pretrain/deepseekv3_pretrain.yaml) | 🚧 | -| 2025-09-23 | GPT-OSS 20B / 120B | [`openai/gpt-oss-20b`](https://huggingface.co/openai/gpt-oss-20b) | LLM | [gpt_oss_20b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gpt_oss/gpt_oss_20b.yaml) | 🚧 | -| 2025-09-08 | Moonlight 16B | [`moonshotai/Moonlight-16B-A3B`](https://huggingface.co/moonshotai/Moonlight-16B-A3B) | LLM | [moonlight_16b_te.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/moonlight/moonlight_16b_te.yaml) | 🚧 | -| 2025-08-27 | Mistral / Mistral-Nemo | [`mistralai/Mistral-7B-v0.1`](https://huggingface.co/mistralai/Mistral-7B-v0.1) | LLM | [mistral_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_7b_squad.yaml) | 🚧 | -| 2025-08-27 | Qwen2 / Qwen2.5 | [`Qwen/Qwen2.5-7B`](https://huggingface.co/Qwen/Qwen2.5-7B) | LLM | [qwen2_5_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen2_5_7b_squad.yaml) | 🚧 | -| 2025-08-27 | Gemma 2 / 3 | [`google/gemma-2-9b-it`](https://huggingface.co/google/gemma-2-9b-it) | LLM | [gemma_2_9b_it_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/gemma_2_9b_it_squad.yaml) | 🚧 | -| 2025-08-27 | Phi 2 / 3 / 4 | [`microsoft/phi-4`](https://huggingface.co/microsoft/phi-4) | LLM | [phi_4_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_4_squad.yaml) | 🚧 | -| 2025-08-27 | Granite 3.x | [`ibm-granite/granite-3.3-2b-instruct`](https://huggingface.co/ibm-granite/granite-3.3-2b-instruct) | LLM | [granite_3_3_2b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/granite/granite_3_3_2b_instruct_squad.yaml) | 🚧 | -| 2025-08-27 | OLMo 2 | [`allenai/OLMo-2-0425-1B-Instruct`](https://huggingface.co/allenai/OLMo-2-0425-1B-Instruct) | LLM | [olmo_2_0425_1b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad.yaml) | 🚧 | -| 2025-08-27 | Seed-Coder / Seed-OSS | [`ByteDance-Seed/Seed-Coder-8B-Instruct`](https://huggingface.co/ByteDance-Seed/Seed-Coder-8B-Instruct) | LLM | [seed_coder_8b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/seed/seed_coder_8b_instruct_squad.yaml) | 🚧 | -| 2025-08-27 | Baichuan 2 | [`baichuan-inc/Baichuan2-7B-Chat`](https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat) | LLM | [baichuan_2_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/baichuan/baichuan_2_7b_squad.yaml) | 🚧 | -| 2025-08-27 | Cohere Command-R | [`CohereForAI/c4ai-command-r-v01`](https://huggingface.co/CohereForAI/c4ai-command-r-v01) | LLM | [cohere_command_r_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/cohere/cohere_command_r_7b_squad.yaml) | 🚧 | -| 2025-08-27 | StarCoder 2 | [`bigcode/starcoder2-3b`](https://huggingface.co/bigcode/starcoder2-3b) | LLM | [starcoder_2_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/starcoder/starcoder_2_7b_squad.yaml) | 🚧 | -| 2025-08-27 | Falcon 3 | [`tiiuae/Falcon3-7B-Instruct`](https://huggingface.co/tiiuae/Falcon3-7B-Instruct) | LLM | [falcon3_7b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/falcon/falcon3_7b_instruct_squad.yaml) | 🚧 | -| 2025-08-27 | GLM-4 / GLM-4-MoE | [`zai-org/glm-4-9b-chat-hf`](https://huggingface.co/zai-org/glm-4-9b-chat-hf) | LLM | [glm_4_9b_chat_hf_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4_9b_chat_hf_squad.yaml) | 🚧 | -| 2025-08-27 | Qwen3 / Qwen3-MoE | [`Qwen/Qwen3-0.6B`](https://huggingface.co/Qwen/Qwen3-0.6B) | LLM | [qwen3_0p6b_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_0p6b_hellaswag.yaml) | 🚧 | -| 2025-08-23 | Gemma 3 VL | [`google/gemma-3-4b-it`](https://huggingface.co/google/gemma-3-4b-it) | VLM | [gemma3_vl_4b_cord_v2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml) | 🚧 | -| 2025-08-23 | Gemma 3n | [`google/gemma-3n-e4b-it`](https://huggingface.co/google/gemma-3n-e4b-it) | VLM | [gemma3n_vl_4b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3n/gemma3n_vl_4b_medpix.yaml) | 🚧 | -| 2025-08-23 | Llama 3.x | [`meta-llama/Llama-3.2-1B`](https://huggingface.co/meta-llama/Llama-3.2-1B) | LLM | [llama3_2_1b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml) | 🚧 | -| 2025-08-23 | Qwen2.5-VL | [`Qwen/Qwen2.5-VL-7B-Instruct`](https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct) | VLM | [qwen2_5_vl_3b_rdr.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen2_5/qwen2_5_vl_3b_rdr.yaml) | 🚧 | -| 2025-08-23 | Phi-4-multimodal | [`microsoft/Phi-4-multimodal-instruct`](https://huggingface.co/microsoft/Phi-4-multimodal-instruct) | Omni | [phi4_mm_cv17.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/phi4/phi4_mm_cv17.yaml) | 🚧 | diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo.mdx deleted file mode 100644 index 71f8f56efc..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "OLMo" -description: "" ---- -[OLMo](https://allenai.org/olmo) (Open Language Model) is Allen AI's fully open language model — open weights, open training data, and open training code. OLMo-1B and OLMo-7B are trained on Dolma. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `OLMoForCausalLM` | -| **Parameters** | 1B – 7B | -| **HF Org** | [allenai](https://huggingface.co/allenai) | - - - -## Available Models - -- **OLMo-7B-hf**: 7B -- **OLMo-1B-hf**: 1B - -## Architecture - -- `OLMoForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| OLMo 1B | [`allenai/OLMo-1B-hf`](https://huggingface.co/allenai/OLMo-1B-hf) | -| OLMo 7B | [`allenai/OLMo-7B-hf`](https://huggingface.co/allenai/OLMo-7B-hf) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [allenai/OLMo-1B-hf](https://huggingface.co/allenai/OLMo-1B-hf) -- [allenai/OLMo-7B-hf](https://huggingface.co/allenai/OLMo-7B-hf) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo2.mdx deleted file mode 100644 index 84cbacb670..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmo2.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "OLMo2" -description: "" ---- -[OLMo2](https://allenai.org/olmo) is Allen AI's second-generation open language model with improved architecture and training, including RMSNorm and rotary position embeddings. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `OLMo2ForCausalLM` | -| **Parameters** | 1B – 13B | -| **HF Org** | [allenai](https://huggingface.co/allenai) | - - - -## Available Models - -- **OLMo-2-0425-1B-Instruct** -- **OLMo2-7B-1124** -- **OLMo2-13B-1124** - -## Architecture - -- `OLMo2ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| OLMo2 7B | [`allenai/OLMo2-7B-1124`](https://huggingface.co/allenai/OLMo2-7B-1124) | -| OLMo2 0425 1B Instruct | [`allenai/OLMo-2-0425-1B-Instruct`](https://huggingface.co/allenai/OLMo-2-0425-1B-Instruct) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [olmo_2_0425_1b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad.yaml) | SFT — OLMo2 0425 1B Instruct on SQuAD | -| [olmo_2_0425_1b_instruct_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad_peft.yaml) | LoRA — OLMo2 0425 1B Instruct on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [allenai/OLMo2-7B-1124](https://huggingface.co/allenai/OLMo2-7B-1124) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmoe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmoe.mdx deleted file mode 100644 index c6d88ca379..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/allenai/olmoe.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: "OLMoE" -description: "" ---- -[OLMoE](https://allenai.org/olmo) is Allen AI's open Mixture-of-Experts language model. It activates 1B parameters per token from a 7B total parameter pool. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `OLMoEForCausalLM` | -| **Parameters** | 7B total / 1B active | -| **HF Org** | [allenai](https://huggingface.co/allenai) | - - - -## Available Models - -- **OLMoE-1B-7B-0924**: 7B total, 1B activated -- **OLMoE-1B-7B-0924-Instruct**: instruction-tuned variant - -## Architecture - -- `OLMoEForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| OLMoE 1B 7B | [`allenai/OLMoE-1B-7B-0924`](https://huggingface.co/allenai/OLMoE-1B-7B-0924) | -| OLMoE 1B 7B Instruct | [`allenai/OLMoE-1B-7B-0924-Instruct`](https://huggingface.co/allenai/OLMoE-1B-7B-0924-Instruct) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [allenai/OLMoE-1B-7B-0924](https://huggingface.co/allenai/OLMoE-1B-7B-0924) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/baai/aquila.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/baai/aquila.mdx deleted file mode 100644 index 45ad4fe6bc..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/baai/aquila.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "Aquila / Aquila2" -description: "" ---- -[Aquila](https://huggingface.co/BAAI/Aquila-7B) is a Chinese-English bilingual language model from the Beijing Academy of Artificial Intelligence (BAAI). - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `AquilaForCausalLM` | -| **Parameters** | 7B – 34B | -| **HF Org** | [BAAI](https://huggingface.co/BAAI) | - - - -## Available Models - -- **Aquila-7B** -- **AquilaChat-7B**: instruction-tuned -- **Aquila2-34B** - -## Architecture - -- `AquilaForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Aquila 7B | [`BAAI/Aquila-7B`](https://huggingface.co/BAAI/Aquila-7B) | -| AquilaChat 7B | [`BAAI/AquilaChat-7B`](https://huggingface.co/BAAI/AquilaChat-7B) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [BAAI/Aquila-7B](https://huggingface.co/BAAI/Aquila-7B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx deleted file mode 100644 index bd2d4dcfd2..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/baichuan-inc/baichuan.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Baichuan / Baichuan2" -description: "" ---- -[Baichuan](https://github.com/baichuan-inc/Baichuan2) is a Chinese-English bilingual language model series from Baichuan Inc., featuring strong Chinese language performance. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `BaiChuanForCausalLM` | -| **Parameters** | 7B – 13B | -| **HF Org** | [baichuan-inc](https://huggingface.co/baichuan-inc) | - - - -## Available Models - -- **Baichuan2-13B-Chat** -- **Baichuan2-7B-Chat** -- **Baichuan-7B** - -## Architecture - -- `BaiChuanForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Baichuan2 13B Chat | [`baichuan-inc/Baichuan2-13B-Chat`](https://huggingface.co/baichuan-inc/Baichuan2-13B-Chat) | -| Baichuan 7B | [`baichuan-inc/Baichuan-7B`](https://huggingface.co/baichuan-inc/Baichuan-7B) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [baichuan_2_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/baichuan/baichuan_2_7b_squad.yaml) | SFT — Baichuan2 7B on SQuAD | -| [baichuan_2_7b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/baichuan/baichuan_2_7b_squad_peft.yaml) | LoRA — Baichuan2 7B on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/baichuan/baichuan_2_7b_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/baichuan/baichuan_2_7b_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [baichuan-inc/Baichuan2-13B-Chat](https://huggingface.co/baichuan-inc/Baichuan2-13B-Chat) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx deleted file mode 100644 index 7f9b11894d..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/baidu/ernie4-5.mdx +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "ERNIE 4.5" -description: "" ---- -[ERNIE 4.5](https://huggingface.co/baidu) is Baidu's dense and Mixture-of-Experts language model family with long-context text checkpoints on Hugging Face. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architectures** | `Ernie4_5ForCausalLM`, `Ernie4_5_MoeForCausalLM` | -| **Parameters** | 0.36B dense; 21B total / 3B active MoE | -| **Context Length** | 131,072 tokens | -| **HF Org** | [baidu](https://huggingface.co/baidu) | - - - -## Available Models - -- **ERNIE-4.5-0.3B-PT**: dense text checkpoint with 0.36B parameters. -- **ERNIE-4.5-21B-A3B-PT**: text MoE checkpoint with 21B total parameters and 3B activated parameters per token. - -## Architectures - -- `Ernie4_5ForCausalLM`: dense Hugging Face implementation path. -- `Ernie4_5_MoeForCausalLM`: custom NeMo AutoModel implementation with expert parallelism support. - -## Example HF Models - -| Model | HF ID | -|---|---| -| ERNIE 4.5 0.3B PT | [`baidu/ERNIE-4.5-0.3B-PT`](https://huggingface.co/baidu/ERNIE-4.5-0.3B-PT) | -| ERNIE 4.5 21B A3B PT | [`baidu/ERNIE-4.5-21B-A3B-PT`](https://huggingface.co/baidu/ERNIE-4.5-21B-A3B-PT) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [ernie4_5_0p3b_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ernie4_5/ernie4_5_0p3b_hellaswag.yaml) | SFT — ERNIE 4.5 0.3B on HellaSwag with the Hugging Face implementation | -| [ernie4_5_21b_a3b_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ernie4_5/ernie4_5_21b_a3b_hellaswag.yaml) | SFT — ERNIE 4.5 21B A3B on HellaSwag with TE attention and DeepEP | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run a dense recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/ernie4_5/ernie4_5_0p3b_hellaswag.yaml -``` - -**4. Run the MoE recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/ernie4_5/ernie4_5_21b_a3b_hellaswag.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2. Navigate to the AutoModel directory**: - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/ernie4_5/ernie4_5_21b_a3b_hellaswag.yaml -``` - - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [baidu/ERNIE-4.5-0.3B-PT](https://huggingface.co/baidu/ERNIE-4.5-0.3B-PT) -- [baidu/ERNIE-4.5-21B-A3B-PT](https://huggingface.co/baidu/ERNIE-4.5-21B-A3B-PT) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder.mdx deleted file mode 100644 index 0a3a0dea6f..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "StarCoder" -description: "" ---- -[StarCoder](https://huggingface.co/blog/starcoder) is BigCode's code language model trained on the Stack dataset. It uses Multi-Query Attention and Fill-in-the-Middle (FIM) objectives. WizardCoder also uses this architecture. - - - -| | | -|---|---| -| **Task** | Code Generation | -| **Architecture** | `GPTBigCodeForCausalLM` | -| **Parameters** | 1B – 15.5B | -| **HF Org** | [bigcode](https://huggingface.co/bigcode) | - - - -## Available Models - -- **StarCoder**: 15.5B -- **gpt_bigcode-santacoder**: 1.1B -- **WizardCoder-15B-V1.0** (WizardLM) - -## Architecture - -- `GPTBigCodeForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| StarCoder | [`bigcode/starcoder`](https://huggingface.co/bigcode/starcoder) | -| SantaCoder | [`bigcode/gpt_bigcode-santacoder`](https://huggingface.co/bigcode/gpt_bigcode-santacoder) | -| WizardCoder 15B | [`WizardLM/WizardCoder-15B-V1.0`](https://huggingface.co/WizardLM/WizardCoder-15B-V1.0) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [bigcode/starcoder](https://huggingface.co/bigcode/starcoder) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx deleted file mode 100644 index 954481b25b..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/bigcode/starcoder2.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "StarCoder2" -description: "" ---- -[StarCoder2](https://huggingface.co/blog/starcoder2) is BigCode's second-generation code language model, available in 3B, 7B, and 15B sizes, trained on 600+ programming languages from The Stack v2. - - - -| | | -|---|---| -| **Task** | Code Generation | -| **Architecture** | `Starcoder2ForCausalLM` | -| **Parameters** | 3B – 15B | -| **HF Org** | [bigcode](https://huggingface.co/bigcode) | - - - -## Available Models - -- **starcoder2-3b**: 3B -- **starcoder2-7b**: 7B -- **starcoder2-15b**: 15B - -## Architecture - -- `Starcoder2ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| StarCoder2 3B | [`bigcode/starcoder2-3b`](https://huggingface.co/bigcode/starcoder2-3b) | -| StarCoder2 7B | [`bigcode/starcoder2-7b`](https://huggingface.co/bigcode/starcoder2-7b) | -| StarCoder2 15B | [`bigcode/starcoder2-15b`](https://huggingface.co/bigcode/starcoder2-15b) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [starcoder_2_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/starcoder/starcoder_2_7b_squad.yaml) | SFT — StarCoder2 7B on SQuAD | -| [starcoder_2_7b_hellaswag_fp8.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/starcoder/starcoder_2_7b_hellaswag_fp8.yaml) | SFT — StarCoder2 7B on HellaSwag with FP8 | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/starcoder/starcoder_2_7b_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/starcoder/starcoder_2_7b_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [bigcode/starcoder2-7b](https://huggingface.co/bigcode/starcoder2-7b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx deleted file mode 100644 index 0af60d0566..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/bytedance-seed/seed.mdx +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Seed (ByteDance)" -description: "" ---- -[Seed-Coder](https://huggingface.co/ByteDance-Seed/Seed-Coder-8B-Instruct) and [Seed-OSS](https://huggingface.co/ByteDance-Seed/Seed-OSS-36B-Instruct) are open-weight models from ByteDance. Both use the `Qwen2ForCausalLM` architecture under the hood. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `Qwen2ForCausalLM` | -| **Parameters** | 8B – 36B | -| **HF Org** | [ByteDance-Seed](https://huggingface.co/ByteDance-Seed) | - - - -## Available Models - -- **Seed-Coder-8B-Instruct**: 8B code model -- **Seed-OSS-36B-Instruct**: 36B general model - -## Architecture - -- `Qwen2ForCausalLM` (reuses Qwen2 architecture) - -## Example HF Models - -| Model | HF ID | -|---|---| -| Seed-Coder 8B Instruct | [`ByteDance-Seed/Seed-Coder-8B-Instruct`](https://huggingface.co/ByteDance-Seed/Seed-Coder-8B-Instruct) | -| Seed-OSS 36B Instruct | [`ByteDance-Seed/Seed-OSS-36B-Instruct`](https://huggingface.co/ByteDance-Seed/Seed-OSS-36B-Instruct) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [seed_coder_8b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/seed/seed_coder_8b_instruct_squad.yaml) | SFT — Seed-Coder 8B on SQuAD | -| [seed_coder_8b_instruct_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/seed/seed_coder_8b_instruct_squad_peft.yaml) | LoRA — Seed-Coder 8B on SQuAD | -| [seed_oss_36B_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/seed/seed_oss_36B_hellaswag.yaml) | SFT — Seed-OSS 36B on HellaSwag | -| [seed_oss_36B_hellaswag_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/seed/seed_oss_36B_hellaswag_peft.yaml) | LoRA — Seed-OSS 36B on HellaSwag | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/seed/seed_coder_8b_instruct_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/seed/seed_coder_8b_instruct_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [ByteDance-Seed/Seed-Coder-8B-Instruct](https://huggingface.co/ByteDance-Seed/Seed-Coder-8B-Instruct) -- [ByteDance-Seed/Seed-OSS-36B-Instruct](https://huggingface.co/ByteDance-Seed/Seed-OSS-36B-Instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/cohere/command-r.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/cohere/command-r.mdx deleted file mode 100644 index 3bfcf0f705..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/cohere/command-r.mdx +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Command-R" -description: "" ---- -[Cohere Command-R](https://cohere.com/command) is a series of enterprise-grade language models optimized for retrieval-augmented generation (RAG) and tool use. Command-R7B uses the updated `Cohere2ForCausalLM` architecture. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `CohereForCausalLM` / `Cohere2ForCausalLM` | -| **Parameters** | 7B – 104B | -| **HF Org** | [CohereForAI](https://huggingface.co/CohereForAI) | - - - -## Available Models - -- **c4ai-command-r-v01**: 35B -- **c4ai-command-r-plus**: 104B -- **c4ai-command-r7b-12-2024**: 7B (`Cohere2ForCausalLM`) - -## Architectures - -- `CohereForCausalLM` — Command-R v01, Plus -- `Cohere2ForCausalLM` — Command-R7B - -## Example HF Models - -| Model | HF ID | -|---|---| -| Command-R v01 | [`CohereForAI/c4ai-command-r-v01`](https://huggingface.co/CohereForAI/c4ai-command-r-v01) | -| Command-R7B | [`CohereForAI/c4ai-command-r7b-12-2024`](https://huggingface.co/CohereForAI/c4ai-command-r7b-12-2024) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [cohere_command_r_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/cohere/cohere_command_r_7b_squad.yaml) | SFT — Command-R 7B on SQuAD | -| [cohere_command_r_7b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/cohere/cohere_command_r_7b_squad_peft.yaml) | LoRA — Command-R 7B on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/cohere/cohere_command_r_7b_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/cohere/cohere_command_r_7b_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [CohereForAI/c4ai-command-r-v01](https://huggingface.co/CohereForAI/c4ai-command-r-v01) -- [CohereForAI/c4ai-command-r7b-12-2024](https://huggingface.co/CohereForAI/c4ai-command-r7b-12-2024) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx deleted file mode 100644 index 0438764734..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek-v3.mdx +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: "DeepSeek-V3" -description: "" ---- -[DeepSeek-V3](https://github.com/deepseek-ai/DeepSeek-V3) is a large-scale Mixture-of-Experts model with 671B total parameters and 37B activated per token. It features Multi-head Latent Attention (MLA), innovative load balancing, and Multi-Token Prediction (MTP). DeepSeek-V3.2 is an updated release with further improvements. - -[Moonlight](https://huggingface.co/moonshotai/Moonlight-16B-A3B) by Moonshot AI also uses this architecture with 16B total / 3B activated parameters. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `DeepseekV3ForCausalLM` / `DeepseekV32ForCausalLM` | -| **Parameters** | 671B total / 37B active | -| **HF Org** | [deepseek-ai](https://huggingface.co/deepseek-ai) | - - - -## Available Models - -- **DeepSeek-V3**: 671B total, 37B activated -- **DeepSeek-V3.2** (`DeepseekV32ForCausalLM`): updated architecture -- **Moonlight-16B-A3B** (Moonshot AI): 16B total, 3B activated - -## Architectures - -- `DeepseekV3ForCausalLM` -- `DeepseekV32ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| DeepSeek-V3 | [`deepseek-ai/DeepSeek-V3`](https://huggingface.co/deepseek-ai/DeepSeek-V3) | -| DeepSeek-V3-Base | [`deepseek-ai/DeepSeek-V3-Base`](https://huggingface.co/deepseek-ai/DeepSeek-V3-Base) | -| DeepSeek-V3.2 | [`deepseek-ai/DeepSeek-V3.2`](https://huggingface.co/deepseek-ai/DeepSeek-V3.2) | -| Moonlight 16B A3B | [`moonshotai/Moonlight-16B-A3B`](https://huggingface.co/moonshotai/Moonlight-16B-A3B) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [deepseek_v32_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml) | SFT — DeepSeek-V3.2 on HellaSwag with pipeline parallelism | -| [moonlight_16b_te.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/moonlight/moonlight_16b_te.yaml) | SFT — Moonlight 16B with Transformer Engine | -| [moonlight_16b_te_packed_sequence.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/moonlight/moonlight_16b_te_packed_sequence.yaml) | SFT — Moonlight 16B with packed sequences | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - - -This recipe was validated on **32 nodes × 8 GPUs (256 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. - - - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [deepseek-ai/DeepSeek-V3](https://huggingface.co/deepseek-ai/DeepSeek-V3) -- [deepseek-ai/DeepSeek-V3-Base](https://huggingface.co/deepseek-ai/DeepSeek-V3-Base) -- [moonshotai/Moonlight-16B-A3B](https://huggingface.co/moonshotai/Moonlight-16B-A3B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx deleted file mode 100644 index f88166d74c..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/deepseek.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "DeepSeek" -description: "" ---- -[DeepSeek](https://github.com/deepseek-ai) is a series of open-weight language models from DeepSeek AI. The first-generation models (V1/V2) use standard transformer decoder and Multi-head Latent Attention architectures. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `DeepseekForCausalLM` | -| **Parameters** | 7B – 67B | -| **HF Org** | [deepseek-ai](https://huggingface.co/deepseek-ai) | - - - -## Available Models - -- **DeepSeek-V2**: 236B total, 21B activated (MoE) -- **DeepSeek-V2-Chat**: instruction-tuned variant -- **DeepSeek-LLM 7B/67B**: dense models - -## Architecture - -- `DeepseekForCausalLM` — DeepSeek v1/v2 dense models - -## Example HF Models - -| Model | HF ID | -|---|---| -| DeepSeek LLM 7B Chat | [`deepseek-ai/deepseek-llm-7b-chat`](https://huggingface.co/deepseek-ai/deepseek-llm-7b-chat) | -| DeepSeek LLM 67B Chat | [`deepseek-ai/deepseek-llm-67b-chat`](https://huggingface.co/deepseek-ai/deepseek-llm-67b-chat) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [deepseek-ai/deepseek-llm-7b-chat](https://huggingface.co/deepseek-ai/deepseek-llm-7b-chat) -- [deepseek-ai/deepseek-llm-67b-chat](https://huggingface.co/deepseek-ai/deepseek-llm-67b-chat) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx deleted file mode 100644 index 62fe3421d0..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/deepseek-ai/dsv4-flash.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "DeepSeek V4 Flash" -description: "" ---- -[DeepSeek V4 Flash](https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash) is DeepSeek's latest fine-grained Mixture-of-Experts language model. It uses a 43-layer all-MoE backbone with 256 routed experts plus one shared expert per block, top-6 routing, and a hybrid per-layer attention zoo (SWA / CSA / HCA) selectable through `compress_ratios`. The first `num_hash_layers` blocks use a hash-clustering gate, and every block maintains `hc_mult=4` Hyper-Connection streams mixed via a learned col-norm-first Sinkhorn router. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `DeepseekV4ForCausalLM` | -| **Parameters** | fine-grained MoE, 256 routed + 1 shared expert | -| **HF Org** | [deepseek-ai](https://huggingface.co/deepseek-ai) | - - - -## Available Models - -- **DeepSeek-V4-Flash** - -## Architecture - -- `DeepseekV4ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| DeepSeek V4 Flash | [`deepseek-ai/DeepSeek-V4-Flash`](https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [`deepseek_v4_flash_hellaswag.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml) | SFT — DeepSeek V4 Flash on HellaSwag with pipeline parallelism | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - - -The full 43-layer schedule requires a multi-node run; see the recipe yaml header for `ep_size` / `pp_size` guidance. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. - - - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [Fine-Tune DeepSeek V4 Flash](/recipes-e2e-examples/deepseek-v4-flash) guide and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [deepseek-ai/DeepSeek-V4-Flash](https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx deleted file mode 100644 index 88e3995b49..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-j.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: "GPT-J" -description: "" ---- -[GPT-J](https://github.com/kingoflolz/mesh-transformer-jax) is a 6B parameter transformer language model trained by EleutherAI on the Pile dataset. It was one of the earliest large open-weight models. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `GPTJForCausalLM` | -| **Parameters** | 6B | -| **HF Org** | [EleutherAI](https://huggingface.co/EleutherAI) | - - - -## Available Models - -- **gpt-j-6b**: 6B parameters -- **gpt4all-j**: GPT-J fine-tuned for instruction following (Nomic AI) - -## Architecture - -- `GPTJForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| GPT-J 6B | [`EleutherAI/gpt-j-6b`](https://huggingface.co/EleutherAI/gpt-j-6b) | -| GPT4All-J | [`nomic-ai/gpt4all-j`](https://huggingface.co/nomic-ai/gpt4all-j) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [EleutherAI/gpt-j-6b](https://huggingface.co/EleutherAI/gpt-j-6b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx deleted file mode 100644 index 13ac558350..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/eleutherai/gpt-neox.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "GPT-NeoX / Pythia" -description: "" ---- -[GPT-NeoX](https://github.com/EleutherAI/gpt-neox) is EleutherAI's large-scale language model architecture. The same `GPTNeoXForCausalLM` architecture is used by the Pythia scaling suite, OpenAssistant, Databricks Dolly, and StableLM models. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `GPTNeoXForCausalLM` | -| **Parameters** | 1B – 20B | -| **HF Org** | [EleutherAI](https://huggingface.co/EleutherAI) | - - - -## Available Models - -- **GPT-NeoX-20B** (EleutherAI) -- **Pythia** suite: 70M, 160M, 410M, 1B, 1.4B, 2.8B, 6.9B, 12B (EleutherAI) -- **OA-SFT-Pythia-12B** (OpenAssistant) -- **Dolly-v2-12B** (Databricks) -- **StableLM-tuned-alpha-7B** (Stability AI) - -## Architecture - -- `GPTNeoXForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| GPT-NeoX 20B | [`EleutherAI/gpt-neox-20b`](https://huggingface.co/EleutherAI/gpt-neox-20b) | -| Pythia 12B | [`EleutherAI/pythia-12b`](https://huggingface.co/EleutherAI/pythia-12b) | -| OpenAssistant SFT Pythia 12B | [`OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5`](https://huggingface.co/OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5) | -| Dolly v2 12B | [`databrickslabs/dolly`](https://github.com/databrickslabs/dolly) | -| StableLM tuned alpha 7B | [`stabilityai/stablelm-tuned-alpha-7b`](https://huggingface.co/stabilityai/stablelm-tuned-alpha-7b) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [EleutherAI/gpt-neox-20b](https://huggingface.co/EleutherAI/gpt-neox-20b) -- [EleutherAI/pythia-12b](https://huggingface.co/EleutherAI/pythia-12b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/google/gemma.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/google/gemma.mdx deleted file mode 100644 index 1c22045c56..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/google/gemma.mdx +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: "Gemma" -description: "" ---- -[Google's Gemma](https://ai.google.dev/gemma) is a family of open-weight language models built on the same research and technology as Gemini. Gemma models are available in multiple sizes and versions, with improvements in each generation including local sliding window attention (Gemma 2) and interleaved global/local attention (Gemma 3). - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `GemmaForCausalLM` / `Gemma2ForCausalLM` / `Gemma3ForCausalLM` | -| **Parameters** | 1B – 27B | -| **HF Org** | [google](https://huggingface.co/google) | - - - -## Available Models - -- **Gemma 3**: 1B, 4B, 12B, 27B -- **Gemma 2**: 2B, 9B, 27B -- **Gemma (v1)**: 2B, 7B - -## Architectures - -- `GemmaForCausalLM` — Gemma v1 -- `Gemma2ForCausalLM` — Gemma 2 -- `Gemma3ForCausalLM` — Gemma 3 - -## Example HF Models - -| Model | HF ID | -|---|---| -| Gemma 1.1 2B IT | [`google/gemma-1.1-2b-it`](https://huggingface.co/google/gemma-1.1-2b-it) | -| Gemma 2B | [`google/gemma-2b`](https://huggingface.co/google/gemma-2b) | -| Gemma 2 9B IT | [`google/gemma-2-9b-it`](https://huggingface.co/google/gemma-2-9b-it) | -| Gemma 2 27B | [`google/gemma-2-27b`](https://huggingface.co/google/gemma-2-27b) | -| Gemma 3 1B IT | [`google/gemma-3-1b-it`](https://huggingface.co/google/gemma-3-1b-it) | -| Gemma 3 4B IT | [`google/gemma-3-4b-it`](https://huggingface.co/google/gemma-3-4b-it) | -| Gemma 3 27B IT | [`google/gemma-3-27b-it`](https://huggingface.co/google/gemma-3-27b-it) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [gemma_2_9b_it_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/gemma_2_9b_it_squad.yaml) | SFT — Gemma 2 9B IT on SQuAD | -| [gemma_2_9b_it_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/gemma_2_9b_it_squad_peft.yaml) | LoRA — Gemma 2 9B IT on SQuAD | -| [gemma_3_270m_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/gemma_3_270m_squad.yaml) | SFT — Gemma 3 270M on SQuAD | -| [gemma_3_270m_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/gemma_3_270m_squad_peft.yaml) | LoRA — Gemma 3 270M on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/gemma/gemma_2_9b_it_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/gemma/gemma_2_9b_it_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) for full SFT and LoRA instructions. - -## Hugging Face Model Cards - -- [google/gemma-2b](https://huggingface.co/google/gemma-2b) -- [google/gemma-2-9b-it](https://huggingface.co/google/gemma-2-9b-it) -- [google/gemma-3-1b-it](https://huggingface.co/google/gemma-3-1b-it) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/bamba.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/bamba.mdx deleted file mode 100644 index bb32a608b3..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/bamba.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Bamba" -description: "" ---- -[Bamba](https://huggingface.co/ibm-ai-platform/Bamba-9B) is a hybrid SSM-attention language model from IBM, combining Mamba-2 selective state space layers with standard transformer attention for efficient long-context processing. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `BambaForCausalLM` | -| **Parameters** | 9B | -| **HF Org** | [ibm-ai-platform](https://huggingface.co/ibm-ai-platform) | - - - -## Available Models - -- **Bamba-9B**: 9B parameters - -## Architecture - -- `BambaForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Bamba 9B | [`ibm-ai-platform/Bamba-9B`](https://huggingface.co/ibm-ai-platform/Bamba-9B) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [ibm-ai-platform/Bamba-9B](https://huggingface.co/ibm-ai-platform/Bamba-9B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite-moe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite-moe.mdx deleted file mode 100644 index a11e8a7666..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite-moe.mdx +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: "Granite MoE" -description: "" ---- -IBM Granite MoE models extend the Granite architecture with Mixture-of-Experts layers for more efficient scaling. PowerMoE (IBM Research) also uses this architecture. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `GraniteMoeForCausalLM` | -| **Parameters** | 1B – 3B | -| **HF Org** | [ibm-granite](https://huggingface.co/ibm-granite) | - - - -## Available Models - -- **Granite 3.0 1B A400M Base** — 1B total, 400M activated -- **Granite 3.0 3B A800M Instruct** — 3B total, 800M activated -- **PowerMoE-3B** (IBM Research) — 3B total -- **MoE-7B-1B-Active-Shared-Experts** (IBM Research, test model) - -## Architectures - -- `GraniteMoeForCausalLM` -- `GraniteMoeSharedForCausalLM` — variant with shared experts - -## Example HF Models - -| Model | HF ID | -|---|---| -| Granite 3.0 1B A400M Base | [`ibm-granite/granite-3.0-1b-a400m-base`](https://huggingface.co/ibm-granite/granite-3.0-1b-a400m-base) | -| Granite 3.0 3B A800M Instruct | [`ibm-granite/granite-3.0-3b-a800m-instruct`](https://huggingface.co/ibm-granite/granite-3.0-3b-a800m-instruct) | -| PowerMoE 3B | [`ibm/PowerMoE-3b`](https://huggingface.co/ibm/PowerMoE-3b) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [ibm-granite/granite-3.0-1b-a400m-base](https://huggingface.co/ibm-granite/granite-3.0-1b-a400m-base) -- [ibm/PowerMoE-3b](https://huggingface.co/ibm/PowerMoE-3b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite.mdx deleted file mode 100644 index bdf4565ab3..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/ibm/granite.mdx +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: "Granite" -description: "" ---- -[IBM Granite](https://www.ibm.com/granite) is IBM's family of enterprise-focused language models. Granite 3.x models are trained on a mix of code and language data and are optimized for enterprise tasks including summarization, classification, and RAG. PowerLM (IBM Research) also uses this architecture. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `GraniteForCausalLM` | -| **Parameters** | 2B – 8B | -| **HF Org** | [ibm-granite](https://huggingface.co/ibm-granite) | - - - -## Available Models - -- **Granite 3.3 2B Instruct** -- **Granite 3.1 8B Instruct** -- **Granite 3.0 2B Base** -- **PowerLM-3B** (IBM Research) - -## Architecture - -- `GraniteForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Granite 3.0 2B Base | [`ibm-granite/granite-3.0-2b-base`](https://huggingface.co/ibm-granite/granite-3.0-2b-base) | -| Granite 3.1 8B Instruct | [`ibm-granite/granite-3.1-8b-instruct`](https://huggingface.co/ibm-granite/granite-3.1-8b-instruct) | -| PowerLM 3B | [`ibm/PowerLM-3b`](https://huggingface.co/ibm/PowerLM-3b) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [granite_3_3_2b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/granite/granite_3_3_2b_instruct_squad.yaml) | SFT — Granite 3.3 2B Instruct on SQuAD | -| [granite_3_3_2b_instruct_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/granite/granite_3_3_2b_instruct_squad_peft.yaml) | LoRA — Granite 3.3 2B Instruct on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/granite/granite_3_3_2b_instruct_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/granite/granite_3_3_2b_instruct_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [ibm-granite/granite-3.0-2b-base](https://huggingface.co/ibm-granite/granite-3.0-2b-base) -- [ibm-granite/granite-3.1-8b-instruct](https://huggingface.co/ibm-granite/granite-3.1-8b-instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/inceptionai/jais.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/inceptionai/jais.mdx deleted file mode 100644 index e8c821059a..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/inceptionai/jais.mdx +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Jais" -description: "" ---- -[Jais](https://huggingface.co/inceptionai/jais-13b) is an Arabic-English bilingual language model from Inception (formerly G42/Inception AI), trained on a large Arabic and English corpus. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `JAISLMHeadModel` | -| **Parameters** | 13B – 30B | -| **HF Org** | [inceptionai](https://huggingface.co/inceptionai) | - - - -## Available Models - -- **jais-30b-chat-v3**: 30B -- **jais-30b-v3**: 30B base -- **jais-13b-chat**: 13B -- **jais-13b**: 13B base - -## Architecture - -- `JAISLMHeadModel` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Jais 13B | [`inceptionai/jais-13b`](https://huggingface.co/inceptionai/jais-13b) | -| Jais 13B Chat | [`inceptionai/jais-13b-chat`](https://huggingface.co/inceptionai/jais-13b-chat) | -| Jais 30B v3 | [`inceptionai/jais-30b-v3`](https://huggingface.co/inceptionai/jais-30b-v3) | -| Jais 30B Chat v3 | [`inceptionai/jais-30b-chat-v3`](https://huggingface.co/inceptionai/jais-30b-chat-v3) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [inceptionai/jais-13b](https://huggingface.co/inceptionai/jais-13b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx deleted file mode 100644 index 2b3ba8e111..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/inclusionai/ling-2.mdx +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: "Ling 2.0" -description: "" ---- -[Ling 2.0](https://huggingface.co/collections/inclusionAI/ling-20) is the Mixture-of-Experts LLM family from inclusionAI (Ant Group), released under the `bailing_moe` HF architecture (`BailingMoeV2ForCausalLM`). The line spans a 16 B mini through a 1 T flagship while sharing the same architecture. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `BailingMoeV2ForCausalLM` | -| **Parameters** | 16 B – 1 T total | -| **HF Org** | [inclusionAI](https://huggingface.co/inclusionAI) | - - - -## Available Models - -- **Ling-mini-2.0**: 16 B total / ~1.4 B activated per token (20 layers, 256 experts, 8 activated). -- **Ling-flash-2.0**: 100 B total / ~6 B activated per token (32 layers, 256 experts, 8 activated). -- **Ling-1T**: 1 T total / ~50 B activated per token (80 layers, `first_k_dense_replace=4`). -- **Ling-mini-base-2.0** / **Ling-flash-base-2.0**: base (pre-instruct) variants. - -All variants share the same architecture: GQA + per-head QK-RMSNorm + half RoPE (`partial_rotary_factor=0.5`) + sigmoid-routed grouped MoE with one shared expert and a per-expert correction bias (aux-loss-free routing). - -## Architecture - -- `BailingMoeV2ForCausalLM` (HF `model_type: "bailing_moe"`) -- GQA attention; `use_qk_norm: true` -- Half RoPE (`partial_rotary_factor=0.5`) -- DeepSeek-V3-style routing: sigmoid scoring, per-expert bias, grouped top-k (`n_group=8`, `topk_group=4`) -- 1 shared expert at `moe_intermediate_size` -- `first_k_dense_replace` dense MLP layer(s) at the start of the stack - -## Example HF Models - -| Model | HF ID | -|---|---| -| Ling-mini-2.0 | [`inclusionAI/Ling-mini-2.0`](https://huggingface.co/inclusionAI/Ling-mini-2.0) | -| Ling-flash-2.0 | [`inclusionAI/Ling-flash-2.0`](https://huggingface.co/inclusionAI/Ling-flash-2.0) | -| Ling-1T | [`inclusionAI/Ling-1T`](https://huggingface.co/inclusionAI/Ling-1T) | - -## Example Recipes - -| Recipe | Description | Min HW | -|---|---|---| -| [ling_mini_2_0_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_mini_2_0_squad.yaml) | LoRA SFT — Ling-mini-2.0 on SQuAD | 2× H100 80GB | -| [ling_mini_2_0_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_mini_2_0_hellaswag.yaml) | LoRA SFT — Ling-mini-2.0 on HellaSwag | 2× H100 80GB | -| [ling_mini_2_0_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_mini_2_0_sft.yaml) | Full SFT — Ling-mini-2.0 on HellaSwag, FSDP2 + EP=8 | 8× H100 80GB | -| [ling_flash_2_0_lora.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_flash_2_0_lora.yaml) | LoRA SFT — Ling-flash-2.0 on HellaSwag | 8× H100 80GB | -| [ling_flash_2_0_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_flash_2_0_sft.yaml) | Full SFT — Ling-flash-2.0 on HellaSwag, FSDP2 + EP=32 | 32× H100 80GB (4 nodes) | -| [ling_1t_lora_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_1t_lora_pp.yaml) | LoRA SFT — Ling-1T on HellaSwag, FSDP2 + PP=8 + EP=8 | 64× H100 80GB (8 nodes) | -| [ling_1t_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_1t_sft.yaml) | Full SFT — Ling-1T on HellaSwag, FSDP2 + PP=4 + EP=64 | 256× H100 80GB (32 nodes) | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)). - -**2. Run LoRA fine-tuning:** - -```bash -automodel examples/llm_finetune/ling/ling_mini_2_0_squad.yaml --nproc-per-node 1 -``` - -A single 80 GB H100 / A100 fits Ling-mini-2.0 in bf16 with the LoRA defaults in the example. Set `distributed.ep_size > 1` for multi-GPU expert parallelism on the larger variants. diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/index.mdx deleted file mode 100644 index 4c624cc947..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/index.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Large Language Models (LLMs)" -description: "" -position: 3 ---- -## Introduction -Large Language Models (LLMs) power a variety of tasks such as dialogue systems, text classification, summarization, and more. -NeMo AutoModel provides a simple interface for loading and fine-tuning LLMs hosted on the Hugging Face Hub. - -## Run LLMs with NeMo AutoModel -To run LLMs with NeMo AutoModel, make sure you're using NeMo container version [`25.11.00`](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel?version=25.11.00) or later. If the model you intend to fine-tune requires a newer version of Transformers, you may need to upgrade to the latest version of NeMo AutoModel by using: - -```bash -pip3 install --upgrade git+git@github.com:NVIDIA-NeMo/AutoModel.git -``` - -For other installation options (e.g., uv), see the [NeMo AutoModel Installation Guide](/get-started/installation). - -## Supported Models - -NeMo AutoModel supports the [AutoModelForCausalLM](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html#automodelforcausallm) in the [Text Generation](https://huggingface.co/models?pipeline_tag=text-generation&sort=trending) category. During preprocessing, it uses `transformers.AutoTokenizer`, which is sufficient for most LLM cases. If your model requires custom text handling, override the tokenizer in your recipe YAML or provide a custom dataset `_target_`. See [LLM datasets](/datasets/text-dataset) and [dataset overview](/datasets/overview). - -| Owner | Model Family | Architectures | -|---|---|---| -| Meta | [Llama](/model-coverage/large-language-models/llama) | `LlamaForCausalLM` | -| Google | [Gemma](/model-coverage/large-language-models/gemma) | `GemmaForCausalLM`, `Gemma2ForCausalLM`, `Gemma3ForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen2](/model-coverage/large-language-models/qwen2) | `Qwen2ForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen2 MoE](/model-coverage/large-language-models/qwen2-moe) | `Qwen2MoeForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen3](/model-coverage/large-language-models/qwen3) | `Qwen3ForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen3 MoE](/model-coverage/large-language-models/qwen3-moe) | `Qwen3MoeForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen3-Next](/model-coverage/large-language-models/qwen3-next) | `Qwen3NextForCausalLM` | -| Baidu | [ERNIE 4.5](/model-coverage/large-language-models/ernie-4-5) | `Ernie4_5ForCausalLM`, `Ernie4_5_MoeForCausalLM` | -| DeepSeek | [DeepSeek](/model-coverage/large-language-models/deepseek) | `DeepseekForCausalLM` | -| DeepSeek | [DeepSeek-V3](/model-coverage/large-language-models/deepseek-v3) | `DeepseekV3ForCausalLM`, `DeepseekV32ForCausalLM` | -| DeepSeek | [DeepSeek V4 Flash](/model-coverage/large-language-models/deepseek-v4-flash) | `DeepseekV4ForCausalLM` | -| Mistral AI | [Mistral](/model-coverage/large-language-models/mistral) | `MistralForCausalLM` | -| Mistral AI | [Mixtral](/model-coverage/large-language-models/mixtral) | `MixtralForCausalLM` | -| Mistral AI | [Ministral3 / Devstral](/model-coverage/large-language-models/ministral3-devstral) | `Mistral3ForConditionalGeneration` | -| Microsoft | [Phi](/model-coverage/large-language-models/phi) | `PhiForCausalLM` | -| Microsoft | [Phi-3 / Phi-4](/model-coverage/large-language-models/phi-3-phi-4) | `Phi3ForCausalLM` | -| Microsoft | [Phi-3-Small](/model-coverage/large-language-models/phi-3-small) | `Phi3SmallForCausalLM` | -| NVIDIA | [Nemotron / Minitron](/model-coverage/large-language-models/nemotron-minitron) | `NemotronForCausalLM` | -| NVIDIA | [Nemotron-H](/model-coverage/large-language-models/nemotron-h) | `NemotronHForCausalLM` | -| NVIDIA | [Nemotron-Flash](/model-coverage/large-language-models/nemotron-flash) | `NemotronFlashForCausalLM` | -| NVIDIA | [Nemotron-Super](/model-coverage/large-language-models/nemotron-super-llama-3-3-nemotron-super-49b) | `DeciLMForCausalLM` | -| ZAI / Zhipu AI | [ChatGLM](/model-coverage/large-language-models/chatglm) | `ChatGLMModel` | -| ZAI / Zhipu AI | [GLM-4](/model-coverage/large-language-models/glm-4) | `GlmForCausalLM`, `Glm4ForCausalLM` | -| ZAI / Zhipu AI | [GLM-4 MoE](/model-coverage/large-language-models/glm-4-moe-glm-4-5-glm-4-7) | `Glm4MoeForCausalLM`, `Glm4MoeLiteForCausalLM` | -| ZAI / Zhipu AI | [GLM-5 / GLM-5.1](/model-coverage/large-language-models/glm-5-moe-dsa) | `GlmMoeDsaForCausalLM` | -| IBM | [Granite](/model-coverage/large-language-models/granite) | `GraniteForCausalLM` | -| IBM | [Granite MoE](/model-coverage/large-language-models/granite-moe) | `GraniteMoeForCausalLM`, `GraniteMoeSharedForCausalLM` | -| IBM | [Bamba](/model-coverage/large-language-models/bamba) | `BambaForCausalLM` | -| Allen AI | [OLMo](/model-coverage/large-language-models/olmo) | `OLMoForCausalLM` | -| Allen AI | [OLMo2](/model-coverage/large-language-models/olmo2) | `OLMo2ForCausalLM` | -| Allen AI | [OLMoE](/model-coverage/large-language-models/olmoe) | `OLMoEForCausalLM` | -| OpenAI | [GPT-OSS](/model-coverage/large-language-models/gpt-oss) | `GptOssForCausalLM` | -| OpenAI | [GPT-2](/model-coverage/large-language-models/gpt-2) | `GPT2LMHeadModel` | -| EleutherAI | [GPT-J](/model-coverage/large-language-models/gpt-j) | `GPTJForCausalLM` | -| EleutherAI | [GPT-NeoX / Pythia](/model-coverage/large-language-models/gpt-neox-pythia) | `GPTNeoXForCausalLM` | -| BigCode | [StarCoder](/model-coverage/large-language-models/starcoder) | `GPTBigCodeForCausalLM` | -| BigCode | [StarCoder2](/model-coverage/large-language-models/starcoder2) | `Starcoder2ForCausalLM` | -| BAAI | [Aquila / Aquila2](/model-coverage/large-language-models/aquila-aquila2) | `AquilaForCausalLM` | -| Baichuan Inc | [Baichuan / Baichuan2](/model-coverage/large-language-models/baichuan-baichuan2) | `BaiChuanForCausalLM` | -| Cohere | [Command-R](/model-coverage/large-language-models/command-r) | `CohereForCausalLM`, `Cohere2ForCausalLM` | -| TII | [Falcon](/model-coverage/large-language-models/falcon) | `FalconForCausalLM` | -| LG AI Research | [EXAONE](/model-coverage/large-language-models/exaone) | `ExaoneForCausalLM` | -| InternLM | [InternLM](/model-coverage/large-language-models/internlm) | `InternLMForCausalLM`, `InternLM2ForCausalLM`, `InternLM3ForCausalLM` | -| Inception AI | [Jais](/model-coverage/large-language-models/jais) | `JAISLMHeadModel` | -| MiniMax | [MiniMax-M2](/model-coverage/large-language-models/minimax-m2) | `MiniMaxM2ForCausalLM` | -| OpenBMB | [MiniCPM](/model-coverage/large-language-models/minicpm) | `MiniCPMForCausalLM`, `MiniCPM3ForCausalLM` | -| Moonshot AI | [Moonlight](/model-coverage/large-language-models/moonlight) | `DeepseekV3ForCausalLM` | -| ByteDance Seed | [Seed (ByteDance)](/model-coverage/large-language-models/seed-bytedance) | `Qwen2ForCausalLM` | -| Upstage | [Solar Pro](/model-coverage/large-language-models/solar-pro) | `SolarForCausalLM` | -| OrionStar | [Orion](/model-coverage/large-language-models/orion) | `OrionForCausalLM` | -| Stability AI | [StableLM](/model-coverage/large-language-models/stablelm) | `StableLmForCausalLM` | -| Stepfun AI | [Step-3.5](/model-coverage/large-language-models/step-3-5) | `Step3p5ForCausalLM` | -| Parasail AI | [GritLM](/model-coverage/large-language-models/gritlm) | `GritLM` | -| Tencent | [Hy3-preview](/model-coverage/large-language-models/hy3-preview) | `HYV3ForCausalLM` | -| Xiaomi MiMo | [MiMo-V2-Flash](/model-coverage/large-language-models/mimo-v2-flash) | `MiMoV2FlashForCausalLM` | -| inclusionAI | [Ling 2.0](/model-coverage/large-language-models/ling-2-0) | `BailingMoeV2ForCausalLM` | - -## Fine-Tuning LLMs with NeMo AutoModel - -The models listed above can be fine-tuned using NeMo AutoModel. We support two primary fine-tuning approaches: - -1. **Parameter-Efficient Fine-Tuning (PEFT)**: Updates only a small subset of parameters (typically <1%) using techniques like Low-Rank Adaptation (LoRA). -2. **Supervised Fine-Tuning (SFT)**: Updates all or most model parameters for deeper adaptation. - -See the [Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) to learn how to apply both methods to your data. - - -In these guides, we use the `SQuAD v1.1` dataset for demonstration purposes, but you can use your own data. Update the recipe YAML `dataset` / `validation_dataset` sections accordingly. See [LLM datasets](/datasets/text-dataset) and [dataset overview](/datasets/overview). - - diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/internlm/internlm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/internlm/internlm.mdx deleted file mode 100644 index cd062bdc36..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/internlm/internlm.mdx +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: "InternLM" -description: "" ---- -[InternLM](https://github.com/InternLM/InternLM) is a bilingual (Chinese-English) language model series from Shanghai AI Laboratory, with versions 1, 2, and 3 each improving on reasoning, instruction following, and long-context capabilities. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `InternLMForCausalLM` / `InternLM2ForCausalLM` / `InternLM3ForCausalLM` | -| **Parameters** | 7B – 8B | -| **HF Org** | [internlm](https://huggingface.co/internlm) | - - - -## Available Models - -- **InternLM3-8B-Instruct** (InternLM3) -- **InternLM2-7B**, **InternLM2-Chat-7B** (InternLM2) -- **InternLM-7B**, **InternLM-Chat-7B** (InternLM v1) - -## Architectures - -- `InternLMForCausalLM` — InternLM v1 -- `InternLM2ForCausalLM` — InternLM2 -- `InternLM3ForCausalLM` — InternLM3 - -## Example HF Models - -| Model | HF ID | -|---|---| -| InternLM3 8B Instruct | [`internlm/internlm3-8b-instruct`](https://huggingface.co/internlm/internlm3-8b-instruct) | -| InternLM2 7B | [`internlm/internlm2-7b`](https://huggingface.co/internlm/internlm2-7b) | -| InternLM 7B | [`internlm/internlm-7b`](https://huggingface.co/internlm/internlm-7b) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [internlm/internlm3-8b-instruct](https://huggingface.co/internlm/internlm3-8b-instruct) -- [internlm/internlm2-7b](https://huggingface.co/internlm/internlm2-7b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx deleted file mode 100644 index 8f45a99ca7..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/lgai-exaone/exaone.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "EXAONE" -description: "" ---- -EXAONE is a bilingual (Korean-English) language model series from LG AI Research, with strong performance on Korean-language benchmarks. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `ExaoneForCausalLM` | -| **Parameters** | 7.8B | -| **HF Org** | [LGAI-EXAONE](https://huggingface.co/LGAI-EXAONE) | - - - -## Available Models - -- **EXAONE-3.0-7.8B-Instruct** -- **EXAONE-3.5-7.8B-Instruct** - -## Architecture - -- `ExaoneForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| EXAONE 3.0 7.8B Instruct | [`LGAI-EXAONE/EXAONE-3.0-7.8B-Instruct`](https://huggingface.co/LGAI-EXAONE/EXAONE-3.0-7.8B-Instruct) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [LGAI-EXAONE/EXAONE-3.0-7.8B-Instruct](https://huggingface.co/LGAI-EXAONE/EXAONE-3.0-7.8B-Instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/meta/llama.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/meta/llama.mdx deleted file mode 100644 index 7291f5947f..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/meta/llama.mdx +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "Llama" -description: "" ---- -[Meta's Llama](https://www.llama.com/) is a family of open-weight autoregressive language models built on the transformer decoder architecture. Key design choices include pre-normalization with RMSNorm, SwiGLU activations, and Rotary Positional Embeddings (RoPE). Llama 3+ models add Grouped Query Attention (GQA) for memory-efficient inference at larger scales. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `LlamaForCausalLM` | -| **Parameters** | 1B – 405B | -| **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | - - - -## Available Models - -- **Llama 3.2**: 1B, 3B -- **Llama 3.1**: 8B, 70B, 405B (128K context) -- **Llama 3**: 8B, 70B -- **Llama 2**: 7B, 13B, 70B -- **LLaMA (v1)**: 7B, 13B, 30B, 65B -- **Yi** (01-ai): 6B, 34B — uses `LlamaForCausalLM` - -## Architecture - -- `LlamaForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Llama 3.2 1B | [`meta-llama/Llama-3.2-1B`](https://huggingface.co/meta-llama/Llama-3.2-1B) | -| Llama 3.2 3B | [`meta-llama/Llama-3.2-3B`](https://huggingface.co/meta-llama/Llama-3.2-3B) | -| Llama 3.1 8B | [`meta-llama/Meta-Llama-3.1-8B-Instruct`](https://huggingface.co/meta-llama/Meta-Llama-3.1-8B-Instruct) | -| Llama 3.1 70B | [`meta-llama/Meta-Llama-3.1-70B-Instruct`](https://huggingface.co/meta-llama/Meta-Llama-3.1-70B-Instruct) | -| Llama 3.1 405B | [`meta-llama/Meta-Llama-3.1-405B-Instruct`](https://huggingface.co/meta-llama/Meta-Llama-3.1-405B-Instruct) | -| Llama 3 8B | [`meta-llama/Meta-Llama-3-8B-Instruct`](https://huggingface.co/meta-llama/Meta-Llama-3-8B-Instruct) | -| Llama 3 70B | [`meta-llama/Meta-Llama-3-70B-Instruct`](https://huggingface.co/meta-llama/Meta-Llama-3-70B-Instruct) | -| Llama 2 70B | [`meta-llama/Llama-2-70b-hf`](https://huggingface.co/meta-llama/Llama-2-70b-hf) | -| Yi 34B | [`01-ai/Yi-34B`](https://huggingface.co/01-ai/Yi-34B) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [llama3_2_1b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml) | SFT — Llama 3.2 1B on SQuAD | -| [llama_3_3_70b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_3/llama_3_3_70b_instruct_squad.yaml) | SFT — Llama 3.3 70B Instruct on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) for full SFT and LoRA instructions. - -## Hugging Face Model Cards - -- [meta-llama/Meta-Llama-3.1-8B](https://huggingface.co/meta-llama/Meta-Llama-3.1-8B) -- [meta-llama/Meta-Llama-3.1-70B](https://huggingface.co/meta-llama/Meta-Llama-3.1-70B) -- [meta-llama/Llama-3.2-1B](https://huggingface.co/meta-llama/Llama-3.2-1B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi.mdx deleted file mode 100644 index f5acdd6a7d..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Phi" -description: "" ---- -[Microsoft's Phi](https://azure.microsoft.com/en-us/products/phi) are compact, high-capability language models designed to punch above their weight class. Phi-1.5 and Phi-2 use a standard transformer decoder architecture (`PhiForCausalLM`). For Phi-3 and Phi-4 see [Phi-3 / Phi-4](/model-coverage/large-language-models/phi-3-phi-4). - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `PhiForCausalLM` | -| **Parameters** | 1.3B – 2.7B | -| **HF Org** | [microsoft](https://huggingface.co/microsoft) | - - - -## Available Models - -- **Phi-2**: 2.7B -- **Phi-1.5**: 1.3B - -## Architecture - -- `PhiForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Phi-2 | [`microsoft/phi-2`](https://huggingface.co/microsoft/phi-2) | -| Phi-1.5 | [`microsoft/phi-1_5`](https://huggingface.co/microsoft/phi-1_5) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [phi_2_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_2_squad.yaml) | SFT — Phi-2 on SQuAD | -| [phi_2_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_2_squad_peft.yaml) | LoRA — Phi-2 on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/phi/phi_2_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/phi/phi_2_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [microsoft/phi-2](https://huggingface.co/microsoft/phi-2) -- [microsoft/phi-1_5](https://huggingface.co/microsoft/phi-1_5) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx deleted file mode 100644 index 93e9cd24ca..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3-small.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "Phi-3-Small" -description: "" ---- -[Phi-3-Small](https://azure.microsoft.com/en-us/products/phi) is Microsoft's 7B model using a distinct `Phi3SmallForCausalLM` architecture with blocksparse attention, separate from the standard Phi-3 family. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `Phi3SmallForCausalLM` | -| **Parameters** | 7B | -| **HF Org** | [microsoft](https://huggingface.co/microsoft) | - - - -## Available Models - -- **Phi-3-small-8k-instruct**: 7B, 8K context -- **Phi-3-small-128k-instruct**: 7B, 128K context - -## Architecture - -- `Phi3SmallForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Phi-3-small-8k-instruct | [`microsoft/Phi-3-small-8k-instruct`](https://huggingface.co/microsoft/Phi-3-small-8k-instruct) | -| Phi-3-small-128k-instruct | [`microsoft/Phi-3-small-128k-instruct`](https://huggingface.co/microsoft/Phi-3-small-128k-instruct) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [microsoft/Phi-3-small-8k-instruct](https://huggingface.co/microsoft/Phi-3-small-8k-instruct) -- [microsoft/Phi-3-small-128k-instruct](https://huggingface.co/microsoft/Phi-3-small-128k-instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3.mdx deleted file mode 100644 index df62afe4c9..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/microsoft/phi3.mdx +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Phi-3 / Phi-4" -description: "" ---- -[Phi-3](https://azure.microsoft.com/en-us/products/phi) and [Phi-4](https://azure.microsoft.com/en-us/products/phi) are Microsoft's high-capability small language models using a shared transformer decoder architecture (`Phi3ForCausalLM`). Phi-4-mini and Phi-4 achieve strong benchmark results at relatively small parameter counts. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `Phi3ForCausalLM` | -| **Parameters** | 3.8B – 14B | -| **HF Org** | [microsoft](https://huggingface.co/microsoft) | - - - -## Available Models - -- **Phi-4**: 14B -- **Phi-4-mini-instruct**: 3.8B -- **Phi-3.5-mini-instruct**: 3.8B -- **Phi-3-medium-128k-instruct**: 14B -- **Phi-3-mini-128k-instruct**: 3.8B -- **Phi-3-mini-4k-instruct**: 3.8B - -## Architecture - -- `Phi3ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Phi-4 | [`microsoft/Phi-4`](https://huggingface.co/microsoft/Phi-4) | -| Phi-4-mini-instruct | [`microsoft/Phi-4-mini-instruct`](https://huggingface.co/microsoft/Phi-4-mini-instruct) | -| Phi-3-mini-4k-instruct | [`microsoft/Phi-3-mini-4k-instruct`](https://huggingface.co/microsoft/Phi-3-mini-4k-instruct) | -| Phi-3-mini-128k-instruct | [`microsoft/Phi-3-mini-128k-instruct`](https://huggingface.co/microsoft/Phi-3-mini-128k-instruct) | -| Phi-3-medium-128k-instruct | [`microsoft/Phi-3-medium-128k-instruct`](https://huggingface.co/microsoft/Phi-3-medium-128k-instruct) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [phi_4_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_4_squad.yaml) | SFT — Phi-4 on SQuAD | -| [phi_4_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_4_squad_peft.yaml) | LoRA — Phi-4 on SQuAD | -| [phi_3_mini_it_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_3_mini_it_squad.yaml) | SFT — Phi-3-mini Instruct on SQuAD | -| [phi_3_mini_it_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_3_mini_it_squad_peft.yaml) | LoRA — Phi-3-mini Instruct on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/phi/phi_4_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/phi/phi_4_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [microsoft/Phi-4](https://huggingface.co/microsoft/Phi-4) -- [microsoft/Phi-4-mini-instruct](https://huggingface.co/microsoft/Phi-4-mini-instruct) -- [microsoft/Phi-3-mini-4k-instruct](https://huggingface.co/microsoft/Phi-3-mini-4k-instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx deleted file mode 100644 index e29af336ff..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/minimax/minimax-m2.mdx +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "MiniMax-M2" -description: "" ---- -[MiniMax-M2](https://huggingface.co/MiniMaxAI) is MiniMax's large Mixture-of-Experts language model with linear attention for efficient long-context inference. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `MiniMaxM2ForCausalLM` | -| **Parameters** | varies | -| **HF Org** | [MiniMaxAI](https://huggingface.co/MiniMaxAI) | - - - -## Available Models - -- **MiniMax-M2.1** -- **MiniMax-M2.5** -- **MiniMax-M2.7** -## Architecture - -- `MiniMaxM2ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| MiniMax M2.1 | [`MiniMaxAI/MiniMax-M2.1`](https://huggingface.co/MiniMaxAI/MiniMax-M2.1) | -| MiniMax M2.5 | [`MiniMaxAI/MiniMax-M2.5`](https://huggingface.co/MiniMaxAI/MiniMax-M2.5) | -| MiniMax M2.7 | [`MiniMaxAI/MiniMax-M2.7`](https://huggingface.co/MiniMaxAI/MiniMax-M2.7) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [minimax_m2.1_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.1_hellaswag_pp.yaml) | SFT — MiniMax-M2.1 on HellaSwag with pipeline parallelism | -| [minimax_m2.5_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.5_hellaswag_pp.yaml) | SFT — MiniMax-M2.5 on HellaSwag with pipeline parallelism | -| [minimax_m2.7_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.7_hellaswag_pp.yaml) | SFT — MiniMax-M2.7 on HellaSwag with pipeline parallelism | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - - -This recipe was validated on **8 nodes × 8 GPUs (64 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. - - - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/minimax_m2/minimax_m2.1_hellaswag_pp.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/minimax_m2/minimax_m2.1_hellaswag_pp.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [MiniMaxAI/MiniMax-M2.1](https://huggingface.co/MiniMaxAI/MiniMax-M2.1) -- [MiniMaxAI/MiniMax-M2.5](https://huggingface.co/MiniMaxAI/MiniMax-M2.5) -- [MiniMaxAI/MiniMax-M2.7](https://huggingface.co/MiniMaxAI/MiniMax-M2.7) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/ministral3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/ministral3.mdx deleted file mode 100644 index 4900bfff74..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/ministral3.mdx +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Ministral3 / Devstral" -description: "" ---- -[Ministral](https://mistral.ai/news/ministraux/) is Mistral AI's efficient small model series optimized for on-device and edge use cases. [Devstral](https://mistral.ai/news/devstral/) is a code-focused model built on the same architecture, designed for software engineering agents. - -Both use the `Mistral3ForConditionalGeneration` architecture. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `Mistral3ForConditionalGeneration` | -| **Parameters** | 3B – 24B | -| **HF Org** | [mistralai](https://huggingface.co/mistralai) | - - - -## Available Models - -**Ministral3:** -- **Ministral-3-3B-Instruct-2512** -- **Ministral-3-8B-Instruct-2512** -- **Ministral-3-14B-Instruct-2512** - -**Devstral:** -- **Devstral-Small-2-24B-Instruct-2512** - -## Architecture - -- `Mistral3ForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Ministral-3 3B Instruct | [`mistralai/Ministral-3-3B-Instruct-2512`](https://huggingface.co/mistralai/Ministral-3-3B-Instruct-2512) | -| Ministral-3 8B Instruct | [`mistralai/Ministral-3-8B-Instruct-2512`](https://huggingface.co/mistralai/Ministral-3-8B-Instruct-2512) | -| Ministral-3 14B Instruct | [`mistralai/Ministral-3-14B-Instruct-2512`](https://huggingface.co/mistralai/Ministral-3-14B-Instruct-2512) | -| Devstral Small 2 24B | [`mistralai/Devstral-Small-2-24B-Instruct-2512`](https://huggingface.co/mistralai/Devstral-Small-2-24B-Instruct-2512) | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/devstral/devstral2_small_2512_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/devstral/devstral2_small_2512_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [mistralai/Ministral-3-8B-Instruct-2512](https://huggingface.co/mistralai/Ministral-3-8B-Instruct-2512) -- [mistralai/Devstral-Small-2-24B-Instruct-2512](https://huggingface.co/mistralai/Devstral-Small-2-24B-Instruct-2512) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mistral.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mistral.mdx deleted file mode 100644 index 6229435f1c..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mistral.mdx +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "Mistral" -description: "" ---- -[Mistral AI](https://mistral.ai/) models are efficient transformer decoder models featuring sliding window attention for long context support. Mistral-Nemo is a 12B model developed jointly with NVIDIA. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `MistralForCausalLM` | -| **Parameters** | 7B – 12B | -| **HF Org** | [mistralai](https://huggingface.co/mistralai) | - - - -## Available Models - -- **Mistral-7B**: v0.1, v0.2, v0.3 -- **Mistral-7B-Instruct**: v0.1, v0.2, v0.3 -- **Mistral-Nemo-Instruct-2407**: 12B - -## Architecture - -- `MistralForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Mistral 7B v0.1 | [`mistralai/Mistral-7B-v0.1`](https://huggingface.co/mistralai/Mistral-7B-v0.1) | -| Mistral 7B Instruct v0.1 | [`mistralai/Mistral-7B-Instruct-v0.1`](https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.1) | -| Mistral Nemo Instruct 2407 | [`mistralai/Mistral-Nemo-Instruct-2407`](https://huggingface.co/mistralai/Mistral-Nemo-Instruct-2407) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [mistral_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_7b_squad.yaml) | SFT — Mistral 7B on SQuAD | -| [mistral_7b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_7b_squad_peft.yaml) | LoRA — Mistral 7B on SQuAD | -| [mistral_nemo_2407_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_nemo_2407_squad.yaml) | SFT — Mistral Nemo 2407 on SQuAD | -| [mistral_nemo_2407_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_nemo_2407_squad_peft.yaml) | LoRA — Mistral Nemo 2407 on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/mistral/mistral_7b_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/mistral/mistral_7b_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [mistralai/Mistral-7B-v0.1](https://huggingface.co/mistralai/Mistral-7B-v0.1) -- [mistralai/Mistral-Nemo-Instruct-2407](https://huggingface.co/mistralai/Mistral-Nemo-Instruct-2407) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mixtral.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mixtral.mdx deleted file mode 100644 index 4e1dfafa0b..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/mistralai/mixtral.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "Mixtral" -description: "" ---- -[Mixtral](https://mistral.ai/news/mixtral-of-experts/) is Mistral AI's Mixture-of-Experts model series. Each token is processed by a subset of experts, enabling a large total parameter count with efficient per-token compute. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `MixtralForCausalLM` | -| **Parameters** | 47B total / 13B active | -| **HF Org** | [mistralai](https://huggingface.co/mistralai) | - - - -## Available Models - -- **Mixtral-8x7B**: 8 experts, 2 active per token (~13B active) -- **Mixtral-8x7B-Instruct**: instruction-tuned variant -- **Mixtral-8x22B**: 8 experts, 2 active per token (~39B active) - -## Architecture - -- `MixtralForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Mixtral 8x7B v0.1 | [`mistralai/Mixtral-8x7B-v0.1`](https://huggingface.co/mistralai/Mixtral-8x7B-v0.1) | -| Mixtral 8x7B Instruct v0.1 | [`mistralai/Mixtral-8x7B-Instruct-v0.1`](https://huggingface.co/mistralai/Mixtral-8x7B-Instruct-v0.1) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [mixtral-8x7b-v0-1_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad.yaml) | SFT — Mixtral 8x7B on SQuAD | -| [mixtral-8x7b-v0-1_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad_peft.yaml) | LoRA — Mixtral 8x7B on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [mistralai/Mixtral-8x7B-v0.1](https://huggingface.co/mistralai/Mixtral-8x7B-v0.1) -- [mistralai/Mixtral-8x7B-Instruct-v0.1](https://huggingface.co/mistralai/Mixtral-8x7B-Instruct-v0.1) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx deleted file mode 100644 index fc5f33f4a5..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/moonshotai/moonlight.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "Moonlight" -description: "" ---- -[Moonlight](https://huggingface.co/moonshotai/Moonlight-16B-A3B) is a Mixture-of-Experts language model from Moonshot AI trained using Muon optimizer. It uses the `DeepseekV3ForCausalLM` architecture with 16B total parameters and 3B activated per token. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `DeepseekV3ForCausalLM` | -| **Parameters** | 16B total / 3B active | -| **HF Org** | [moonshotai](https://huggingface.co/moonshotai) | - - - -## Available Models - -- **Moonlight-16B-A3B**: 16B total, 3B activated - -## Architecture - -- `DeepseekV3ForCausalLM` (same architecture as DeepSeek-V3) - -## Example HF Models - -| Model | HF ID | -|---|---| -| Moonlight 16B A3B | [`moonshotai/Moonlight-16B-A3B`](https://huggingface.co/moonshotai/Moonlight-16B-A3B) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [moonlight_16b_te.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/moonlight/moonlight_16b_te.yaml) | SFT — Moonlight 16B with Transformer Engine | -| [moonlight_16b_te_packed_sequence.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/moonlight/moonlight_16b_te_packed_sequence.yaml) | SFT — Moonlight 16B with packed sequences | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/moonlight/moonlight_16b_te.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/moonlight/moonlight_16b_te.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [moonshotai/Moonlight-16B-A3B](https://huggingface.co/moonshotai/Moonlight-16B-A3B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx deleted file mode 100644 index 89acdb12f2..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-flash.mdx +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Nemotron-Flash" -description: "" ---- -[NVIDIA Nemotron-Flash](https://huggingface.co/nvidia/Nemotron-Flash-1B) is a compact, fast language model designed for low-latency inference workloads. - - -This model requires `trust_remote_code: true` in your recipe YAML. - - - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `NemotronFlashForCausalLM` | -| **Parameters** | 1B | -| **HF Org** | [nvidia](https://huggingface.co/nvidia) | - - - -## Available Models - -- **Nemotron-Flash-1B**: 1B parameters - -## Architecture - -- `NemotronFlashForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Nemotron-Flash 1B | [`nvidia/Nemotron-Flash-1B`](https://huggingface.co/nvidia/Nemotron-Flash-1B) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [nemotron_flash_1b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad.yaml) | SFT — Nemotron-Flash 1B on SQuAD | -| [nemotron_flash_1b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad_peft.yaml) | LoRA — Nemotron-Flash 1B on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [nvidia/Nemotron-Flash-1B](https://huggingface.co/nvidia/Nemotron-Flash-1B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx deleted file mode 100644 index 6aba76ed5e..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-h.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "Nemotron-H" -description: "" ---- -[NVIDIA Nemotron-H](https://developer.nvidia.com/blog/nemotron-h-reasoning-enabling-throughput-gains-with-no-compromises/) is a hybrid Mamba-2 / transformer architecture that interleaves selective state space layers with standard attention layers for improved efficiency on long sequences. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `NemotronHForCausalLM` | -| **Parameters** | 9B – 30B | -| **HF Org** | [nvidia](https://huggingface.co/nvidia) | - - - -## Available Models - -- **NVIDIA-Nemotron-Nano-9B-v2**: 9B hybrid model -- **NVIDIA-Nemotron-Nano-12B-v2**: 12B hybrid model -- **NVIDIA-Nemotron-3-Nano-30B-A3B-BF16**: 30B total, 3B activated (sparse MoE + Mamba-2) - -## Architecture - -- `NemotronHForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Nemotron-Nano 9B v2 | [`nvidia/NVIDIA-Nemotron-Nano-9B-v2`](https://huggingface.co/nvidia/NVIDIA-Nemotron-Nano-9B-v2) | -| Nemotron-Nano 12B v2 | [`nvidia/NVIDIA-Nemotron-Nano-12B-v2`](https://huggingface.co/nvidia/NVIDIA-Nemotron-Nano-12B-v2) | -| Nemotron-3-Nano 30B A3B | [`nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16`](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [nemotron_nano_9b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_9b_squad.yaml) | SFT — Nemotron-Nano 9B on SQuAD | -| [nemotron_nano_9b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_9b_squad_peft.yaml) | LoRA — Nemotron-Nano 9B on SQuAD | -| [nemotron_nano_v3_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_v3_hellaswag.yaml) | SFT — Nemotron-3-Nano 30B on HellaSwag | -| [nemotron_nano_v3_hellaswag_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_v3_hellaswag_peft.yaml) | LoRA — Nemotron-3-Nano 30B on HellaSwag | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/nemotron/nemotron_nano_9b_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/nemotron/nemotron_nano_9b_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [nvidia/NVIDIA-Nemotron-Nano-9B-v2](https://huggingface.co/nvidia/NVIDIA-Nemotron-Nano-9B-v2) -- [nvidia/NVIDIA-Nemotron-Nano-12B-v2](https://huggingface.co/nvidia/NVIDIA-Nemotron-Nano-12B-v2) -- [nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx deleted file mode 100644 index fe101f565f..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron-super.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Nemotron-Super (Llama-3.3-Nemotron-Super-49B)" -description: "" ---- -[Llama-3.3-Nemotron-Super-49B-v1](https://huggingface.co/nvidia/Llama-3_3-Nemotron-Super-49B-v1) is a NVIDIA model derived from Llama-3.1-70B through Neural Architecture Search (NAS)-based pruning and knowledge distillation, resulting in a 49B model with strong reasoning capabilities. It uses the `DeciLMForCausalLM` architecture. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `DeciLMForCausalLM` | -| **Parameters** | 49B | -| **HF Org** | [nvidia](https://huggingface.co/nvidia) | - - - -## Available Models - -- **Llama-3.3-Nemotron-Super-49B-v1**: 49B parameters - -## Architecture - -- `DeciLMForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Llama-3.3-Nemotron-Super-49B-v1 | [`nvidia/Llama-3_3-Nemotron-Super-49B-v1`](https://huggingface.co/nvidia/Llama-3_3-Nemotron-Super-49B-v1) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [nvidia/Llama-3_3-Nemotron-Super-49B-v1](https://huggingface.co/nvidia/Llama-3_3-Nemotron-Super-49B-v1) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron.mdx deleted file mode 100644 index be57e1e7eb..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/nvidia/nemotron.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Nemotron / Minitron" -description: "" ---- -[NVIDIA Nemotron](https://www.nvidia.com/en-us/ai-data-science/foundation-models/) and [Minitron](https://developer.nvidia.com/blog/how-to-prune-and-distill-llama-3-1-8b-to-an-nvidia-llama-3-1-minitron-4b-model/) are NVIDIA's family of language models. Minitron models are produced by pruning and distilling larger Llama/Nemotron models into compact, high-performance checkpoints. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `NemotronForCausalLM` | -| **Parameters** | 8B | -| **HF Org** | [nvidia](https://huggingface.co/nvidia) | - - - -## Available Models - -- **Minitron-8B-Base**: pruned and distilled from Llama-3.1-8B - -## Architecture - -- `NemotronForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Minitron 8B Base | [`nvidia/Minitron-8B-Base`](https://huggingface.co/nvidia/Minitron-8B-Base) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [nvidia/Minitron-8B-Base](https://huggingface.co/nvidia/Minitron-8B-Base) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt-oss.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt-oss.mdx deleted file mode 100644 index 79b3cfded6..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt-oss.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "GPT-OSS" -description: "" ---- -[GPT-OSS](https://huggingface.co/openai/gpt-oss-20b) is OpenAI's open-weight model family featuring QuickGELU activations and activation clamping for training stability. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `GptOssForCausalLM` | -| **Parameters** | 20B – 120B | -| **HF Org** | [openai](https://huggingface.co/openai) | - - - -## Available Models - -- **gpt-oss-20b**: 20B parameters -- **gpt-oss-120b**: 120B parameters - -## Architecture - -- `GptOssForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| GPT-OSS 20B | [`openai/gpt-oss-20b`](https://huggingface.co/openai/gpt-oss-20b) | -| GPT-OSS 120B | [`openai/gpt-oss-120b`](https://huggingface.co/openai/gpt-oss-120b) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [gpt_oss_20b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gpt_oss/gpt_oss_20b.yaml) | SFT — GPT-OSS 20B | -| [gpt_oss_120b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gpt_oss/gpt_oss_120b.yaml) | SFT — GPT-OSS 120B | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/gpt_oss/gpt_oss_20b.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/gpt_oss/gpt_oss_20b.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [openai/gpt-oss-20b](https://huggingface.co/openai/gpt-oss-20b) -- [openai/gpt-oss-120b](https://huggingface.co/openai/gpt-oss-120b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt2.mdx deleted file mode 100644 index d54cc7ea53..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/openai/gpt2.mdx +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: "GPT-2" -description: "" ---- -[GPT-2](https://huggingface.co/openai-community/gpt2) is OpenAI's foundational decoder-only transformer. NeMo AutoModel uses it as a baseline for the Megatron pretraining smoke test and tutorials — its small footprint makes it a convenient target to validate data pipelines, distributed configs, and logging without needing large compute. - - - -| | | -|---|---| -| **Task** | Text Generation (pretraining baseline) | -| **Architecture** | `GPT2LMHeadModel` | -| **Parameters** | 124M – 1.5B | -| **HF Org** | [openai-community](https://huggingface.co/openai-community) | - - - -## Available Models - -- **gpt2** (124M) -- **gpt2-medium** (355M) -- **gpt2-large** (774M) -- **gpt2-xl** (1.5B) - -## Architecture - -- `GPT2LMHeadModel` - -## Example HF Models - -| Model | HF ID | -|---|---| -| GPT-2 | [`openai-community/gpt2`](https://huggingface.co/openai-community/gpt2) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [megatron_pretrain_gpt2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_pretrain/megatron_pretrain_gpt2.yaml) | Megatron pretraining smoke test — GPT-2 on FineWeb-Edu | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_pretrain/megatron_pretrain_gpt2.yaml -``` - -See the [Installation Guide](/get-started/installation) and [LLM Pretraining Guide](/recipes-e2e-examples/pretraining). - -## Hugging Face Model Cards - -- [openai-community/gpt2](https://huggingface.co/openai-community/gpt2) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/openbmb/minicpm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/openbmb/minicpm.mdx deleted file mode 100644 index 74972c4e21..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/openbmb/minicpm.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "MiniCPM" -description: "" ---- -[MiniCPM](https://github.com/OpenBMB/MiniCPM) is a compact language model series from OpenBMB / Tsinghua University, designed to deliver strong performance at small parameter counts using model merging and continuous training techniques. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `MiniCPMForCausalLM` / `MiniCPM3ForCausalLM` | -| **Parameters** | 2B – 4B | -| **HF Org** | [openbmb](https://huggingface.co/openbmb) | - - - -## Available Models - -- **MiniCPM3-4B** (`MiniCPM3ForCausalLM`): 4B -- **MiniCPM-2B-sft-bf16** (`MiniCPMForCausalLM`): 2B, SFT -- **MiniCPM-2B-dpo-bf16** (`MiniCPMForCausalLM`): 2B, DPO - -## Architectures - -- `MiniCPMForCausalLM` — MiniCPM v1/v2 -- `MiniCPM3ForCausalLM` — MiniCPM3 - -## Example HF Models - -| Model | HF ID | -|---|---| -| MiniCPM 2B SFT | [`openbmb/MiniCPM-2B-sft-bf16`](https://huggingface.co/openbmb/MiniCPM-2B-sft-bf16) | -| MiniCPM3 4B | [`openbmb/MiniCPM3-4B`](https://huggingface.co/openbmb/MiniCPM3-4B) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [openbmb/MiniCPM-2B-sft-bf16](https://huggingface.co/openbmb/MiniCPM-2B-sft-bf16) -- [openbmb/MiniCPM3-4B](https://huggingface.co/openbmb/MiniCPM3-4B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/orionstar/orion.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/orionstar/orion.mdx deleted file mode 100644 index a5c5751e5f..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/orionstar/orion.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: "Orion" -description: "" ---- -[Orion](https://github.com/OrionStarAI/Orion) is a bilingual (Chinese-English) language model from OrionStar AI, with 14B parameters and strong performance on Chinese benchmarks. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `OrionForCausalLM` | -| **Parameters** | 14B | -| **HF Org** | [OrionStarAI](https://huggingface.co/OrionStarAI) | - - - -## Available Models - -- **Orion-14B-Base**: 14B -- **Orion-14B-Chat**: 14B instruction-tuned - -## Architecture - -- `OrionForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Orion 14B Base | [`OrionStarAI/Orion-14B-Base`](https://huggingface.co/OrionStarAI/Orion-14B-Base) | -| Orion 14B Chat | [`OrionStarAI/Orion-14B-Chat`](https://huggingface.co/OrionStarAI/Orion-14B-Chat) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [OrionStarAI/Orion-14B-Base](https://huggingface.co/OrionStarAI/Orion-14B-Base) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx deleted file mode 100644 index f97d52e013..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/parasail-ai/gritlm.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "GritLM" -description: "" ---- -[GritLM](https://github.com/ContextualAI/gritlm) (Generative Representational Instruction Tuning) is a unified model that performs both generative language modeling and text embedding in a single model, from Parasail AI. - - - -| | | -|---|---| -| **Task** | Text Generation + Embedding | -| **Architecture** | `GritLM` | -| **Parameters** | 7B | -| **HF Org** | [parasail-ai](https://huggingface.co/parasail-ai) | - - - -## Available Models - -- **GritLM-7B-vllm** - -## Architecture - -- `GritLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| GritLM 7B vllm | [`parasail-ai/GritLM-7B-vllm`](https://huggingface.co/parasail-ai/GritLM-7B-vllm) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [parasail-ai/GritLM-7B-vllm](https://huggingface.co/parasail-ai/GritLM-7B-vllm) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx deleted file mode 100644 index 9f27cfe793..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2-moe.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "Qwen2 MoE" -description: "" ---- -[Qwen1.5-MoE](https://qwenlm.github.io/) is a Mixture-of-Experts variant from Alibaba Cloud that activates only a fraction of parameters per token, enabling efficient training and inference at scale. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `Qwen2MoeForCausalLM` | -| **Parameters** | 14.3B total / 2.7B active | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen1.5-MoE-A2.7B**: 14.3B total parameters, 2.7B activated per token - -## Architecture - -- `Qwen2MoeForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Qwen1.5 MoE A2.7B | [`Qwen/Qwen1.5-MoE-A2.7B`](https://huggingface.co/Qwen/Qwen1.5-MoE-A2.7B) | -| Qwen1.5 MoE A2.7B Chat | [`Qwen/Qwen1.5-MoE-A2.7B-Chat`](https://huggingface.co/Qwen/Qwen1.5-MoE-A2.7B-Chat) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [qwen1_5_moe_a2_7b_qlora.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen1_5_moe_a2_7b_qlora.yaml) | QLoRA — Qwen1.5 MoE A2.7B | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen1_5_moe_a2_7b_qlora.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen1_5_moe_a2_7b_qlora.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [Qwen/Qwen1.5-MoE-A2.7B](https://huggingface.co/Qwen/Qwen1.5-MoE-A2.7B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2.mdx deleted file mode 100644 index 370a8a049c..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen2.mdx +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "Qwen2" -description: "" ---- -[Qwen2](https://qwenlm.github.io/) is Alibaba Cloud's second-generation large language model series. It features grouped query attention, YARN-based long-context extension, and dual chunk attention for long sequences. QwQ-32B-Preview, a reasoning-focused model, also uses this architecture. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `Qwen2ForCausalLM` | -| **Parameters** | 0.5B – 72B | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen2.5**: 0.5B, 1.5B, 3B, 7B, 14B, 32B, 72B -- **Qwen2**: 0.5B, 1.5B, 7B, 57B-A14B (MoE), 72B -- **QwQ-32B-Preview** — reasoning model - -## Architecture - -- `Qwen2ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Qwen2.5 7B Instruct | [`Qwen/Qwen2.5-7B-Instruct`](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct) | -| Qwen2.5 72B Instruct | [`Qwen/Qwen2.5-72B-Instruct`](https://huggingface.co/Qwen/Qwen2.5-72B-Instruct) | -| Qwen2 7B Instruct | [`Qwen/Qwen2-7B-Instruct`](https://huggingface.co/Qwen/Qwen2-7B-Instruct) | -| QwQ 32B Preview | [`Qwen/QwQ-32B-Preview`](https://huggingface.co/Qwen/QwQ-32B-Preview) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [qwen2_5_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen2_5_7b_squad.yaml) | SFT — Qwen2.5 7B on SQuAD | -| [qwq_32b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwq_32b_squad_peft.yaml) | LoRA — QwQ 32B on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen2_5_7b_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen2_5_7b_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) for full SFT and LoRA instructions. - -## Hugging Face Model Cards - -- [Qwen/Qwen2.5-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct) -- [Qwen/Qwen2-7B-Instruct](https://huggingface.co/Qwen/Qwen2-7B-Instruct) -- [Qwen/QwQ-32B-Preview](https://huggingface.co/Qwen/QwQ-32B-Preview) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx deleted file mode 100644 index 9480382536..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-moe.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Qwen3 MoE" -description: "" ---- -[Qwen3 MoE](https://qwenlm.github.io/blog/qwen3/) is the Mixture-of-Experts variant of the Qwen3 series from Alibaba Cloud, activating a small fraction of parameters per token for efficient large-scale training. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `Qwen3MoeForCausalLM` | -| **Parameters** | 30B – 235B total | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen3-30B-A3B**: 30B total parameters, 3B activated per token -- **Qwen3-235B-A22B**: 235B total parameters, 22B activated per token - -## Architecture - -- `Qwen3MoeForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Qwen3 30B A3B | [`Qwen/Qwen3-30B-A3B`](https://huggingface.co/Qwen/Qwen3-30B-A3B) | -| Qwen3 235B A22B | [`Qwen/Qwen3-235B-A22B`](https://huggingface.co/Qwen/Qwen3-235B-A22B) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [qwen3_moe_30b_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_moe_30b_te_deepep.yaml) | SFT — Qwen3 MoE 30B with TE + DeepEP | -| [qwen3_moe_30b_lora.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_moe_30b_lora.yaml) | LoRA — Qwen3 MoE 30B | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_moe_30b_te_deepep.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_moe_30b_te_deepep.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [Qwen/Qwen3-30B-A3B](https://huggingface.co/Qwen/Qwen3-30B-A3B) -- [Qwen/Qwen3-235B-A22B](https://huggingface.co/Qwen/Qwen3-235B-A22B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx deleted file mode 100644 index 5a008ea924..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3-next.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "Qwen3-Next" -description: "" ---- -Qwen3-Next is an advanced MoE language model from Alibaba Cloud's Qwen team designed for high-throughput inference with large total parameter counts and efficient per-token activation. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `Qwen3NextForCausalLM` | -| **Parameters** | 80B total / 3B active | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen3-Next-80B-A3B**: 80B total parameters, 3B activated per token - -## Architecture - -- `Qwen3NextForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Qwen3-Next 80B A3B Instruct | [`Qwen/Qwen3-Next-80B-A3B-Instruct`](https://huggingface.co/Qwen/Qwen3-Next-80B-A3B-Instruct) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [qwen3_next_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_next_te_deepep.yaml) | SFT — Qwen3-Next with TE + DeepEP | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - - -This recipe was validated on **4 nodes × 8 GPUs (32 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. - - - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_next_te_deepep.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_next_te_deepep.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [Qwen/Qwen3-Next-80B-A3B-Instruct](https://huggingface.co/Qwen/Qwen3-Next-80B-A3B-Instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3.mdx deleted file mode 100644 index a899d63172..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/qwen/qwen3.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Qwen3" -description: "" ---- -[Qwen3](https://qwenlm.github.io/blog/qwen3/) is Alibaba Cloud's third-generation dense language model series, featuring improved reasoning, instruction following, and multilingual capabilities over Qwen2. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `Qwen3ForCausalLM` | -| **Parameters** | 0.6B – 32B | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen3**: 0.6B, 1.7B, 4B, 8B, 14B, 32B - -## Architecture - -- `Qwen3ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Qwen3 0.6B | [`Qwen/Qwen3-0.6B`](https://huggingface.co/Qwen/Qwen3-0.6B) | -| Qwen3 8B | [`Qwen/Qwen3-8B`](https://huggingface.co/Qwen/Qwen3-8B) | -| Qwen3 32B | [`Qwen/Qwen3-32B`](https://huggingface.co/Qwen/Qwen3-32B) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [qwen3_0p6b_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_0p6b_hellaswag.yaml) | SFT — Qwen3 0.6B on HellaSwag | -| [qwen3_8b_squad_spark.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_8b_squad_spark.yaml) | SFT — Qwen3 8B on SQuAD (Spark) | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_0p6b_hellaswag.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_0p6b_hellaswag.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) for full SFT and LoRA instructions. - -## Hugging Face Model Cards - -- [Qwen/Qwen3-8B](https://huggingface.co/Qwen/Qwen3-8B) -- [Qwen/Qwen3-32B](https://huggingface.co/Qwen/Qwen3-32B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx deleted file mode 100644 index d528cd9dd0..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/stabilityai/stablelm.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: "StableLM" -description: "" ---- -[StableLM](https://huggingface.co/stabilityai) is Stability AI's series of open language models, available in base and instruction-tuned variants across multiple sizes. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `StableLmForCausalLM` | -| **Parameters** | 3B – 7B | -| **HF Org** | [stabilityai](https://huggingface.co/stabilityai) | - - - -## Available Models - -- **stablelm-3b-4e1t**: 3B -- **stablelm-base-alpha-7b-v2**: 7B - -## Architecture - -- `StableLmForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| StableLM 3B 4E1T | [`stabilityai/stablelm-3b-4e1t`](https://huggingface.co/stabilityai/stablelm-3b-4e1t) | -| StableLM Base Alpha 7B v2 | [`stabilityai/stablelm-base-alpha-7b-v2`](https://huggingface.co/stabilityai/stablelm-base-alpha-7b-v2) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [stabilityai/stablelm-3b-4e1t](https://huggingface.co/stabilityai/stablelm-3b-4e1t) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx deleted file mode 100644 index f896f45f09..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/stepfun-ai/step-3-5.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "Step-3.5" -description: "" ---- -[Step-3.5-Flash](https://huggingface.co/stepfun-ai/Step-3.5-Flash) is a Mixture-of-Experts language model from Stepfun AI, designed for efficient inference. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `Step3p5ForCausalLM` | -| **Parameters** | varies | -| **HF Org** | [stepfun-ai](https://huggingface.co/stepfun-ai) | - - - -## Available Models - -- **Step-3.5-Flash** - -## Architecture - -- `Step3p5ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Step-3.5-Flash | [`stepfun-ai/Step-3.5-Flash`](https://huggingface.co/stepfun-ai/Step-3.5-Flash) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [step_3.5_flash_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml) | SFT — Step-3.5-Flash on HellaSwag with pipeline parallelism | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - - -This recipe was validated on **16 nodes × 8 GPUs (128 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. - - - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [stepfun-ai/Step-3.5-Flash](https://huggingface.co/stepfun-ai/Step-3.5-Flash) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/tencent/hy3.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/tencent/hy3.mdx deleted file mode 100644 index 616315d3c1..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/tencent/hy3.mdx +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: "Hy3 (HunyuanLarge)" -description: "" ---- -[Hy3-preview](https://huggingface.co/tencent/Hy3-preview) is a 295B Mixture-of-Experts language model from Tencent. It features 80 transformer layers (layer 0 dense, layers 1–79 MoE), 192 routed experts plus 1 shared expert with top-8 sigmoid routing, Grouped Query Attention (64 Q / 8 KV heads), per-head QK RMSNorm, RoPE, and an `e_score_correction_bias` gate buffer for expert-load correction. It supports a 256K context window. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `HYV3ForCausalLM` | -| **Parameters** | 295B total | -| **HF Org** | [tencent](https://huggingface.co/tencent) | - - - -## Available Models - -- **Hy3-preview**: 295B total, top-8 routed experts activated per token - -## Architectures - -- `HYV3ForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Hy3-preview | [`tencent/Hy3-preview`](https://huggingface.co/tencent/Hy3-preview) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [hy3_preview_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml) | SFT — Hy3-preview with DeepEP | - -## Try with NeMo AutoModel - -**1. Install** ([NeMo AutoModel](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml -``` - -See the [NeMo AutoModel Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [tencent/Hy3-preview](https://huggingface.co/tencent/Hy3-preview) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/chatglm.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/chatglm.mdx deleted file mode 100644 index bb45d2413b..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/chatglm.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "ChatGLM" -description: "" ---- -[ChatGLM](https://github.com/zai-org/ChatGLM-6B) is a bilingual (Chinese-English) conversational language model from Zhipu AI. ChatGLM2 and ChatGLM3 extend the original with improved performance, longer context, and more efficient attention. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `ChatGLMModel` | -| **Parameters** | 6B | -| **HF Org** | [zai-org](https://huggingface.co/zai-org) | - - - -## Available Models - -- **ChatGLM3-6B** -- **ChatGLM2-6B** - -## Architecture - -- `ChatGLMModel` / `ChatGLMForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| ChatGLM3 6B | [`zai-org/chatglm3-6b`](https://huggingface.co/zai-org/chatglm3-6b) | -| ChatGLM2 6B | [`zai-org/chatglm2-6b`](https://huggingface.co/zai-org/chatglm2-6b) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [zai-org/chatglm3-6b](https://huggingface.co/zai-org/chatglm3-6b) -- [zai-org/chatglm2-6b](https://huggingface.co/zai-org/chatglm2-6b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx deleted file mode 100644 index 35278c7b5d..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4-moe.mdx +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: "GLM-4 MoE (GLM-4.5 / GLM-4.7)" -description: "" ---- -[GLM-4.5 and GLM-4.7](https://huggingface.co/zai-org) are Mixture-of-Experts variants of the GLM family released under the `zai-org` HuggingFace organization. GLM-4.7-Flash is a lighter variant with fewer active parameters. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `Glm4MoeForCausalLM` / `Glm4MoeLiteForCausalLM` | -| **Parameters** | varies | -| **HF Org** | [zai-org](https://huggingface.co/zai-org) | - - - -## Available Models - -- **GLM-4.5-Air** (`Glm4MoeForCausalLM`) -- **GLM-4.7** (`Glm4MoeForCausalLM`) -- **GLM-4.7-Flash** (`Glm4MoeLiteForCausalLM`): lightweight MoE variant - -## Architectures - -- `Glm4MoeForCausalLM` — GLM-4.5, GLM-4.7 -- `Glm4MoeLiteForCausalLM` — GLM-4.7-Flash - -## Example HF Models - -| Model | HF ID | -|---|---| -| GLM-4.5-Air | [`zai-org/GLM-4.5-Air`](https://huggingface.co/zai-org/GLM-4.5-Air) | -| GLM-4.7 | [`zai-org/GLM-4.7`](https://huggingface.co/zai-org/GLM-4.7) | -| GLM-4.7-Flash | [`zai-org/GLM-4.7-Flash`](https://huggingface.co/zai-org/GLM-4.7-Flash) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [glm_4.5_air_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.5_air_te_deepep.yaml) | SFT — GLM-4.5-Air with TE + DeepEP | -| [glm_4.7_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.7_te_deepep.yaml) | SFT — GLM-4.7 with TE + DeepEP | -| [glm_4.7_flash_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.7_flash_te_deepep.yaml) | SFT — GLM-4.7-Flash with TE + DeepEP | -| [glm_4.7_flash_te_packed_sequence.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.7_flash_te_packed_sequence.yaml) | SFT — GLM-4.7-Flash with packed sequences | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - - -This recipe was validated on **8 nodes × 8 GPUs (64 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. - - - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_4.5_air_te_deepep.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_4.5_air_te_deepep.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [zai-org/GLM-4.5-Air](https://huggingface.co/zai-org/GLM-4.5-Air) -- [zai-org/GLM-4.7](https://huggingface.co/zai-org/GLM-4.7) -- [zai-org/GLM-4.7-Flash](https://huggingface.co/zai-org/GLM-4.7-Flash) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4.mdx deleted file mode 100644 index 7fbc9e4560..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm4.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "GLM-4" -description: "" ---- -[GLM-4](https://github.com/zai-org/GLM-4) is Zhipu AI's fourth-generation General Language Model, featuring strong multilingual capabilities and tool-use support. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `GlmForCausalLM` / `Glm4ForCausalLM` | -| **Parameters** | 9B – 32B | -| **HF Org** | [zai-org](https://huggingface.co/zai-org) | - - - -## Available Models - -- **GLM-4-9B-Chat-HF** (`GlmForCausalLM`): 9B -- **GLM-4-32B-0414** (`Glm4ForCausalLM`): 32B - -## Architectures - -- `GlmForCausalLM` — GLM-4 series -- `Glm4ForCausalLM` — GLM-4-0414 series - -## Example HF Models - -| Model | HF ID | -|---|---| -| GLM-4-9B-Chat-HF | [`zai-org/glm-4-9b-chat-hf`](https://huggingface.co/zai-org/glm-4-9b-chat-hf) | -| GLM-4-32B-0414 | [`zai-org/GLM-4-32B-0414`](https://huggingface.co/zai-org/GLM-4-32B-0414) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [glm_4_9b_chat_hf_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4_9b_chat_hf_squad.yaml) | SFT — GLM-4 9B on SQuAD | -| [glm_4_9b_chat_hf_hellaswag_fp8.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4_9b_chat_hf_hellaswag_fp8.yaml) | SFT — GLM-4 9B on HellaSwag with FP8 | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_4_9b_chat_hf_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_4_9b_chat_hf_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [zai-org/glm-4-9b-chat-hf](https://huggingface.co/zai-org/glm-4-9b-chat-hf) -- [zai-org/GLM-4-32B-0414](https://huggingface.co/zai-org/GLM-4-32B-0414) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx deleted file mode 100644 index abdd960c41..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/thudm/glm5-moe-dsa.mdx +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: "GLM-5 / GLM-5.1 (MoE + DSA)" -description: "" ---- -[GLM-5](https://huggingface.co/zai-org/GLM-5) and [GLM-5.1](https://huggingface.co/zai-org/GLM-5.1) are Zhipu AI's latest open-source large Mixture-of-Experts models featuring a DeepSeek-style MLA (Multi-head Latent Attention) + DSA (Dynamic Sparse Attention) architecture. GLM-5.1 shares the `glm_moe_dsa` architecture with GLM-5, with updated weights. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE) | -| **Architecture** | `GlmMoeDsaForCausalLM` | -| **Parameters** | 256 routed experts, 8 active per token | -| **HF Org** | [zai-org](https://huggingface.co/zai-org) | - - - -## Key Features - -- **Mixture of Experts (MoE)**: 256 routed experts with 8 active per token -- **78 layers**, hidden size 6144, with MLA using KV compression (kv_lora_rank=512) and head_dim=64 -- **~200k context window** (max_position_embeddings=202,752) -- **3 dense layers** followed by MoE layers (first_k_dense_replace=3) - -## Available Models - -- **GLM-5** (`GlmMoeDsaForCausalLM`) -- **GLM-5.1** (`GlmMoeDsaForCausalLM`): updated weights - -## Example HF Models - -| Model | HF ID | -|---|---| -| GLM-5 | [`zai-org/GLM-5`](https://huggingface.co/zai-org/GLM-5) | -| GLM-5.1 | [`zai-org/GLM-5.1`](https://huggingface.co/zai-org/GLM-5.1) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [glm_5_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml) | SFT — GLM-5 with EP=64, PP=4 on 32 nodes | -| [glm_5.1_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_5.1_hellaswag_pp.yaml) | SFT — GLM-5.1 with EP=64, PP=4 on 32 nodes | - -## Parallel Setup - -The recipe scales training using Expert Parallelism and Pipeline Parallelism (EP=64, PP=4 across 32 nodes of 8× H100 GPUs). - -```yaml -distributed: - strategy: fsdp2 - tp_size: 1 - cp_size: 1 - pp_size: 4 - ep_size: 64 - sequence_parallel: false - activation_checkpointing: true - pipeline: - pp_schedule: interleaved1f1b - pp_microbatch_size: 1 - round_virtual_stages_to_pp_multiple: down - scale_grads_in_schedule: false - patch_inner_model: false - patch_causal_lm_model: false - layers_per_stage: 2 - moe: - reshard_after_forward: false - wrap_outer_model: false -``` - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - - -This recipe was validated on **32 nodes × 8 GPUs (256 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. - - - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). - -## Hugging Face Model Cards - -- [zai-org/GLM-5](https://huggingface.co/zai-org/GLM-5) -- [zai-org/GLM-5.1](https://huggingface.co/zai-org/GLM-5.1) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/tiiuae/falcon.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/tiiuae/falcon.mdx deleted file mode 100644 index 64a8b33266..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/tiiuae/falcon.mdx +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: "Falcon" -description: "" ---- -[Falcon](https://falconllm.tii.ae/) is a series of open language models from the Technology Innovation Institute (TII) in Abu Dhabi, known for being trained on a high-quality curated web corpus (RefinedWeb). - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `FalconForCausalLM` | -| **Parameters** | 7B – 40B | -| **HF Org** | [tiiuae](https://huggingface.co/tiiuae) | - - - -## Available Models - -- **Falcon-40B**, **Falcon-40B-Instruct** -- **Falcon-7B**, **Falcon-7B-Instruct** -- **Falcon-RW-7B** -- **Falcon3-7B-Instruct** - -## Architecture - -- `FalconForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Falcon 7B | [`tiiuae/falcon-7b`](https://huggingface.co/tiiuae/falcon-7b) | -| Falcon 40B | [`tiiuae/falcon-40b`](https://huggingface.co/tiiuae/falcon-40b) | -| Falcon RW 7B | [`tiiuae/falcon-rw-7b`](https://huggingface.co/tiiuae/falcon-rw-7b) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [falcon3_7b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/falcon/falcon3_7b_instruct_squad.yaml) | SFT — Falcon3 7B Instruct on SQuAD | -| [falcon3_7b_instruct_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/falcon/falcon3_7b_instruct_squad_peft.yaml) | LoRA — Falcon3 7B Instruct on SQuAD | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/falcon/falcon3_7b_instruct_squad.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/falcon/falcon3_7b_instruct_squad.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [tiiuae/falcon-7b](https://huggingface.co/tiiuae/falcon-7b) -- [tiiuae/falcon-40b](https://huggingface.co/tiiuae/falcon-40b) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/upstage/solar.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/upstage/solar.mdx deleted file mode 100644 index 5e93657c25..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/upstage/solar.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Solar Pro" -description: "" ---- -[Solar Pro](https://huggingface.co/upstage/solar-pro-preview-instruct) is an enterprise language model from Upstage, built on a depth up-scaling technique applied to Llama-based architectures. - - - -| | | -|---|---| -| **Task** | Text Generation | -| **Architecture** | `SolarForCausalLM` | -| **Parameters** | 22B | -| **HF Org** | [upstage](https://huggingface.co/upstage) | - - - -## Available Models - -- **solar-pro-preview-instruct** - -## Architecture - -- `SolarForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Solar Pro Preview Instruct | [`upstage/solar-pro-preview-instruct`](https://huggingface.co/upstage/solar-pro-preview-instruct) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base LLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [upstage/solar-pro-preview-instruct](https://huggingface.co/upstage/solar-pro-preview-instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx b/docs/fern/versions/nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx deleted file mode 100644 index 6158e436ac..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "MiMo-V2-Flash" -description: "" ---- -[MiMo-V2-Flash](https://huggingface.co/XiaomiMiMo/MiMo-V2-Flash) is Xiaomi's hybrid attention Mixture-of-Experts language model. It alternates full and sliding-window attention layers, uses a `sigmoid_with_bias` router with group-limited expert routing, and ships as an FP8 HF checkpoint. - - - -| | | -|---|---| -| **Task** | Text Generation (MoE, hybrid attention) | -| **Architecture** | `MiMoV2FlashForCausalLM` | -| **Parameters** | Approx. several hundred B total / much smaller active | -| **HF Org** | [XiaomiMiMo](https://huggingface.co/XiaomiMiMo) | - - - -## Available Models - -- **MiMo-V2-Flash**: hybrid full/sliding-window attention with FP8 weights. - -## Architecture - -- `MiMoV2FlashForCausalLM` -- Sliding-window attention via the `MiMoV2FlashAttention(is_swa=True)` path. -- MoE blocks use the shared `nemo_automodel.components.moe.layers.MoE` with `score_func="sigmoid_with_bias"` and `gate_precision=fp32` so routing decisions stay numerically stable when activations are bf16. -- FP8 round-trip in `MiMoV2FlashStateDictAdapter` covers the bulk of attention/expert weights; layer norms, the gate, `lm_head`, and `embed_tokens` stay in bf16 per `NON_QUANTIZED_KEY_PATTERNS`. - -## Example HF Models - -| Model | HF ID | -|---|---| -| MiMo-V2-Flash | [`XiaomiMiMo/MiMo-V2-Flash`](https://huggingface.co/XiaomiMiMo/MiMo-V2-Flash) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [mimo_v2_flash_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mimo_v2_flash/mimo_v2_flash_hellaswag.yaml) | SFT — MiMo-V2-Flash on HellaSwag | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/mimo_v2_flash/mimo_v2_flash_hellaswag.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2. Navigate to the AutoModel directory**: - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/llm_finetune/mimo_v2_flash/mimo_v2_flash_hellaswag.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Fine-Tuning - -See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). - -## Hugging Face Model Cards - -- [XiaomiMiMo/MiMo-V2-Flash](https://huggingface.co/XiaomiMiMo/MiMo-V2-Flash) diff --git a/docs/fern/versions/nightly/pages/model-coverage/omni/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/omni/index.mdx deleted file mode 100644 index 342cddfe02..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/omni/index.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "Omni Models" -description: "" -position: 5 ---- -Omni models go beyond image-text understanding to support additional modalities such as audio, video, or a combination of all — text, image, audio, and video in a single unified model. - -## Run Omni Models with NeMo AutoModel - -To run omni models with NeMo AutoModel, use NeMo container version [`25.11.00`](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel?version=25.11.00) or later. If the model you want to fine-tune requires a newer version of Transformers, you may need to upgrade: - -```bash -pip3 install --upgrade git+git@github.com:NVIDIA-NeMo/AutoModel.git -``` - -For other installation options, see our [NeMo AutoModel Installation Guide](/get-started/installation). - -## Supported Models - -| Owner | Model | Modalities | Architecture | -|---|---|---|---| -| Qwen / Alibaba Cloud | [Qwen3-Omni](/model-coverage/omni/qwen3-omni) | Text · Image · Audio · Video | `Qwen3OmniForConditionalGeneration` | -| Microsoft | [Phi-4-multimodal](/model-coverage/omni/phi-4-multimodal) | Text · Image · Audio | `Phi4MultimodalForCausalLM` | -| NVIDIA | [Nemotron-3-Nano-Omni](/model-coverage/omni/nemotron-omni) | Text · Image · Audio | `NemotronH_Nano_Omni_Reasoning_V3` | - -## Fine-Tune Omni Models - -All supported omni models can be fine-tuned using full SFT or PEFT (LoRA) approaches. See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n) for general setup instructions. diff --git a/docs/fern/versions/nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx b/docs/fern/versions/nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx deleted file mode 100644 index d40fe05796..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/omni/microsoft/phi4-multimodal.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Phi-4-multimodal" -description: "" ---- -[Phi-4-multimodal-instruct](https://huggingface.co/microsoft/Phi-4-multimodal-instruct) is Microsoft's multimodal extension of Phi-4, supporting text, image, and audio inputs — making it suitable for speech, vision, and combined multimodal tasks. - - - -| | | -|---|---| -| **Task** | Omnimodal (Text·Image·Audio) | -| **Architecture** | `Phi4MultimodalForCausalLM` | -| **Parameters** | 5.6B | -| **HF Org** | [microsoft](https://huggingface.co/microsoft) | - - - -## Available Models - -- **Phi-4-multimodal-instruct**: 5.6B - -## Architecture - -- `Phi4MultimodalForCausalLM` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Phi-4-multimodal-instruct | [`microsoft/Phi-4-multimodal-instruct`](https://huggingface.co/microsoft/Phi-4-multimodal-instruct) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [phi4_mm_cv17.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/phi4/phi4_mm_cv17.yaml) | CommonVoice 17 | SFT — Phi-4-multimodal on CommonVoice (audio-text) | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/phi4/phi4_mm_cv17.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/phi4/phi4_mm_cv17.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [Omni Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM / Omni Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [microsoft/Phi-4-multimodal-instruct](https://huggingface.co/microsoft/Phi-4-multimodal-instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx b/docs/fern/versions/nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx deleted file mode 100644 index 003e979a7b..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/omni/nvidia/nemotron-omni.mdx +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "Nemotron-3-Nano-Omni" -description: "" ---- -[Nemotron-3-Nano-Omni-30B-A3B-Reasoning](https://huggingface.co/nvidia) is NVIDIA's -omnimodal reasoning model. It pairs a NemotronH (hybrid Mamba-2 + Attention) MoE -language backbone with a RADIO v2.5-H vision encoder and a Parakeet (FastConformer) -sound encoder, supporting interleaved text, image, and audio inputs. - - - -| | | -|---|---| -| **Task** | Omnimodal (Text·Image·Audio) | -| **Architecture** | `NemotronH_Nano_Omni_Reasoning_V3` | -| **Parameters** | 30B total / 3B active | -| **HF Org** | [nvidia](https://huggingface.co/nvidia) | - - - -## Available Models - -- **Nemotron-3-Nano-Omni-30B-A3B-Reasoning**: 30B total, 3B activated (MoE) - -## Architecture - -- `NemotronH_Nano_Omni_Reasoning_V3` - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [nemotron_omni_cord_v2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2.yaml) | CORD-v2 | Full SFT — receipt parsing | -| [nemotron_omni_cord_v2_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2_peft.yaml) | CORD-v2 | LoRA PEFT — receipt parsing | - -## Try with NeMo AutoModel - -**1. Install** ([NeMo AutoModel](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo (8x H100 example): - -```bash -automodel examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2.yaml --nproc-per-node 8 -``` - -For a full walkthrough — dataset preparation, SFT vs. LoRA configs, and -post-training inference — see the -[Nemotron-Omni guide](/recipes-e2e-examples/nemotron-omni). diff --git a/docs/fern/versions/nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx b/docs/fern/versions/nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx deleted file mode 100644 index d273479964..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/omni/qwen/qwen3-omni.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Qwen3-Omni" -description: "" ---- -[Qwen3-Omni](https://qwenlm.github.io/blog/qwen3/) is Alibaba Cloud's omnimodal model supporting text, image, audio, and video inputs in a single unified architecture with a MoE language backbone. - - - -| | | -|---|---| -| **Task** | Omnimodal (Text·Image·Audio·Video) | -| **Architecture** | `Qwen3OmniForConditionalGeneration` | -| **Parameters** | 30B total / 3B active | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen3-Omni-30B-A3B-Instruct**: 30B total, 3B activated (MoE) - -## Architecture - -- `Qwen3OmniForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Qwen3-Omni 30B A3B Instruct | [`Qwen/Qwen3-Omni-30B-A3B-Instruct`](https://huggingface.co/Qwen/Qwen3-Omni-30B-A3B-Instruct) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [qwen3_omni_moe_30b_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_omni_moe_30b_te_deepep.yaml) | MedPix-VQA | SFT — Qwen3-Omni 30B with TE + DeepEP | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/qwen3/qwen3_omni_moe_30b_te_deepep.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/qwen3/qwen3_omni_moe_30b_te_deepep.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [Omni Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM / Omni Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [Qwen/Qwen3-Omni-30B-A3B-Instruct](https://huggingface.co/Qwen/Qwen3-Omni-30B-A3B-Instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/overview.mdx b/docs/fern/versions/nightly/pages/model-coverage/overview.mdx deleted file mode 100644 index fa7f939008..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/overview.mdx +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "Model Coverage Overview" -description: "" -position: 1 ---- -NeMo AutoModel integrates with Hugging Face `transformers`. Any LLM or VLM that can be instantiated through `transformers` can also be used using NeMo AutoModel, subject to runtime, third-party software dependencies, and feature compatibility. - -## Supported Hugging Face Auto Classes - -| Auto Class | Task | Status | Details | -|------------|------|--------|---------| -| `AutoModelForCausalLM` | Text Generation (LLM) | Supported | See [LLM model list](/model-coverage/large-language-models/overview). | -| `AutoModelForImageTextToText` | Image-Text-to-Text (VLM) | Supported | See [VLM model list](/model-coverage/vision-language-models/overview). | -| `AutoModelForSequenceClassification` | Sequence Classification | WIP | Early support; interfaces may change. | -| Diffusers Pipelines | Diffusion Generation (T2I, T2V) | Supported | See [Diffusion model list](/model-coverage/diffusion/overview). | -| `NeMoAutoModelBiEncoder` | Embedding Models | Supported | See [Embedding model list](/model-coverage/embedding-models/overview). | -| `NeMoAutoModelCrossEncoder` | Reranking Models | Supported | See [Reranking model list](/model-coverage/reranking-models/overview). | - -## Release Log - -The table below tracks when model support and key features were added across NeMo AutoModel releases. For the full list of tested architectures and example configs, see the [LLM](/model-coverage/large-language-models/overview) and [VLM](/model-coverage/vision-language-models/overview) pages. - -| Release | Date | New Models | Key Features | -|---------|------|------------|--------------| -| **0.3.0** (upcoming) | — | Kimi-VL, Kimi-K25-VL, Gemma 3n, Nemotron-Parse, Qwen3-VL-MoE, Qwen3-Omni, InternVL 3.5, Ministral3, Phi-4-multimodal, Devstral-Small-2, Step-3.5-Flash, Qwen3-Next, Nemotron-3-Nano-30B, FLUX.1-dev, Wan 2.1 T2V, HunyuanVideo 1.5 | MoE LoRA, expanded VLM coverage, diffusion model training (flow matching) | -| **0.2.0** | Dec 2025 | GPT-OSS 20B/120B, Qwen3, Qwen3-MoE, GLM-4/4-MoE, Qwen2.5-VL, Qwen3-VL | Single- and multi-turn tool calling, streaming dataset, QAT for SFT, sequence classification, async DCP checkpointing, MLflow, CP + sequence packing for MoE | -| **0.1.0** | Oct 2025 | DeepSeek V3/V3.2, 40+ LLM architectures, Gemma 3 VLM | Pretraining, knowledge distillation, FP8 (torchao), pipeline parallelism, HSDP, auto pipelining, ColumnMapped dataset | -| **0.1.0a0** | Sep 2025 | Initial LLM and VLM support (Llama, Mistral, Qwen2, Gemma, Phi, and more) | MegatronFSDP, packed sequences, Triton LoRA kernels | - -## Day-0 Support - -- NeMo AutoModel closely tracks the latest `transformers` version and updates its dependency regularly. -- New models released on the Hugging Face Hub may require the latest `transformers` version, necessitating a package upgrade. -- We are working on a CI pipeline that automatically bumps the supported `transformers` version when a new release is detected, enabling even faster day-0 support. - - -## Custom Model Registry - -NeMo AutoModel includes a custom model registry that allows teams to: - -- Add custom implementations to extend support to models not yet covered upstream. -- Provide optimized or faster implementations for specific models while retaining the same AutoModel interface. - -## Having Issues? - -If a model from the Hub doesn't work as expected, see the [Troubleshooting Unsupported Models](/model-coverage/overview) guide for common issues and solutions. diff --git a/docs/fern/versions/nightly/pages/model-coverage/reranker/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/reranker/index.mdx deleted file mode 100644 index fc22d03f88..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/reranker/index.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "Reranking Models" -description: "" -position: 1 ---- - -## Introduction - -Reranking models use cross-encoders to score a query-document pair jointly. They are typically used after an embedding model has produced an initial candidate set. NeMo AutoModel supports optimized bidirectional Llama rerankers and falls back to Hugging Face `AutoModelForSequenceClassification` for other architectures. - -For first-stage dense retrieval, see [Embedding Models](/model-coverage/embedding-models/overview). - -## Optimized Backbones (Bidirectional Attention) - -| Owner | Model | Architecture | Wrapper Class | Tasks | -|---|---|---|---|---| -| NVIDIA | [llama-nemotron-rerank-1b-v2](/model-coverage/reranking-models/llama-bidirectional) | `LlamaBidirectionalForSequenceClassification` | `NeMoAutoModelCrossEncoder` | Reranking | - -## Hugging Face Auto Backbones - -Any Hugging Face model loadable using `AutoModelForSequenceClassification` can be used as a reranking backbone. This fallback path uses the model's native attention; no bidirectional conversion is applied. - -## Supported Workflows - -- **Fine-tuning (Cross-Encoder):** Cross-entropy training on query-document pairs to produce rerankers -- **LoRA/PEFT:** Parameter-efficient fine-tuning for reranking backbones - -## Dataset - -Retrieval fine-tuning requires query-document pairs: each example is a query paired with one positive document and one or more negative documents. Both inline JSONL and corpus ID-based JSON formats are supported. See the [Retrieval Dataset](/datasets/retrieval-dataset) guide. - -{/* TODO: uncomment when finetune guide is published. -## Train Reranking Models - -For a complete walkthrough of training configuration, model-specific settings, and launch commands, see the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune). -*/} diff --git a/docs/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx b/docs/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx deleted file mode 100644 index 110b811236..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/reranker/nvidia/llama-bidirectional.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: "Llama (Bidirectional) for Reranking" -description: "" ---- - -NeMo AutoModel provides a bidirectional variant of [Meta's Llama](https://www.llama.com/) for reranking tasks. Unlike the standard causal (left-to-right) Llama used for text generation, this variant uses **bidirectional attention**, allowing the query and document to interact across the full sequence before a classification head produces a relevance score. - -For the bi-encoder variant, see [Llama (Bidirectional) for Embedding](/model-coverage/embedding-models/llama-bidirectional). - -| | | -|---|---| -| **Tasks** | Reranking | -| **Architecture** | `LlamaBidirectionalForSequenceClassification` | -| **Parameters** | 1B – 8B | -| **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | - -## Available Models - -Any Llama checkpoint can be loaded as a bidirectional reranking backbone. The following configurations have been tested: - -- **Llama 3.2 1B** — fast iteration, fits on a single GPU -- **Llama 3.1 8B** — higher-quality reranking for production use - -## Reranking Models - -The cross-encoder path is used for pairwise relevance scoring and reranking. - -| Architecture | Task | Wrapper Class | Description | -|---|---|---|---| -| `LlamaBidirectionalForSequenceClassification` | Reranking | `NeMoAutoModelCrossEncoder` | Bidirectional Llama with classification head for relevance scoring | - -## Example HF Models - -| Model | HF ID | -|---|---| -| Llama 3.2 1B | [`meta-llama/Llama-3.2-1B`](https://huggingface.co/meta-llama/Llama-3.2-1B) | -| Llama 3.1 8B | [`meta-llama/Llama-3.1-8B`](https://huggingface.co/meta-llama/Llama-3.1-8B) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [llama3_2_1b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/cross_encoder/llama3_2_1b.yaml) | Cross-encoder — Llama 3.2 1B reranker | - -## Try with NeMo AutoModel - -**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](/get-started/installation)) for information: - -```bash -uv pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -torchrun --nproc-per-node=8 examples/retrieval/cross_encoder/finetune.py --config examples/retrieval/cross_encoder/llama3_2_1b.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.04.00 -``` - -**2. Navigate to the AutoModel directory** (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -torchrun --nproc-per-node=8 examples/retrieval/cross_encoder/finetune.py --config examples/retrieval/cross_encoder/llama3_2_1b.yaml -``` - - -See the [Installation Guide](/get-started/installation). - -{/* TODO: uncomment when finetune guide is published. -## Fine-Tuning - -See the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune) for cross-encoder training instructions, including LoRA/PEFT configuration. -*/} - -## Hugging Face Model Cards - -NVIDIA trained and released the `Llama Nemotron Reranking 1B` model, optimized to produce a relevance logit score indicating how well a document matches a given query. The model was fine-tuned with a bidirectional attention mechanism for multilingual and cross-lingual question–answer retrieval, with support for long documents (up to 8,192 tokens). - -- [nvidia/llama-nemotron-rerank-1b-v2](https://huggingface.co/nvidia/llama-nemotron-rerank-1b-v2) diff --git a/docs/fern/versions/nightly/pages/model-coverage/troubleshooting.mdx b/docs/fern/versions/nightly/pages/model-coverage/troubleshooting.mdx deleted file mode 100644 index 635bda4511..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/troubleshooting.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: "Troubleshooting Unsupported Models" -description: "" ---- -Sometimes a model listed on the Hugging Face Hub may not work with NeMo AutoModel. -If you encounter any such model, please open a [GitHub issue](https://github.com/NVIDIA-NeMo/Automodel/issues) with the model ID and any stack trace you see. - -## Common Issues - -| Issue | Example Error | Solution | -|-------|---------------|----------| -| Model has explicitly disabled training in its definition code | — | Request support via a [GitHub issue](https://github.com/NVIDIA-NeMo/Automodel/issues). We can add the model through our custom registry. | -| Model requires a newer `transformers` version | `The checkpoint you are trying to load has model type deepseek_v32 but Transformers does not recognize this architecture.` | Upgrade `transformers` (and NeMo AutoModel if needed), or open a GitHub issue. | -| Model upper-bounds `transformers`, requiring an older version | — | Open a [GitHub issue](https://github.com/NVIDIA-NeMo/Automodel/issues). | -| Unsupported checkpoint format | `OSError: meta-llama/Llama-2-70b does not appear to have a file named pytorch_model.bin, model.safetensors, ...` | Open a GitHub issue or request the model publisher to share a SafeTensors checkpoint. | - -These cases typically stem from upstream packaging or dependency constraints. You would encounter the same issues when using `transformers` directly, as AutoModel mirrors the familiar load and fine-tune semantics. - -## Steps to Try - -1. **Upgrade NeMo AutoModel** to a release that supports the required `transformers` version. See [Install NeMo AutoModel](/get-started/installation). -2. **Enable remote code** — if the model uses custom code, set `trust_remote_code: true` in your `model:` config. See [Hugging Face API Compatibility](/get-started/hf-compatibility). -3. **Open a GitHub issue** with the model ID and error so we can prioritize support or add a registry-backed implementation. diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx deleted file mode 100644 index 4f24b7e3d3..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma3-vl.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "Gemma 3 VL / Gemma 3n" -description: "" ---- -[Gemma 3 VL](https://ai.google.dev/gemma/docs/core) is Google's multimodal extension of Gemma 3, supporting image-text inputs for tasks like image captioning and visual question answering. Gemma 3n is a next-generation efficiency-focused variant. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `Gemma3ForConditionalGeneration` | -| **Parameters** | 4B – 27B | -| **HF Org** | [google](https://huggingface.co/google) | - - - -## Available Models - -- **Gemma 3 27B IT** (VL) -- **Gemma 3 4B IT** (VL) -- **Gemma 3n 4B** (VL) - -## Architecture - -- `Gemma3ForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Gemma 3 4B IT | [`google/gemma-3-4b-it`](https://huggingface.co/google/gemma-3-4b-it) | -| Gemma 3 27B IT | [`google/gemma-3-27b-it`](https://huggingface.co/google/gemma-3-27b-it) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [gemma3_vl_4b_cord_v2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml) | cord-v2 | SFT — Gemma 3 4B VL on CORD-v2 | -| [gemma3_vl_4b_cord_v2_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2_peft.yaml) | cord-v2 | LoRA — Gemma 3 4B VL on CORD-v2 | -| [gemma3_vl_4b_cord_v2_megatron_fsdp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2_megatron_fsdp.yaml) | cord-v2 | SFT — Gemma 3 4B VL with MegatronFSDP | -| [gemma3_vl_4b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3/gemma3_vl_4b_medpix.yaml) | MedPix-VQA | SFT — Gemma 3 4B VL on MedPix | -| [gemma3n_vl_4b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3n/gemma3n_vl_4b_medpix.yaml) | MedPix-VQA | SFT — Gemma 3n 4B VL on MedPix | -| [gemma3n_vl_4b_medpix_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3n/gemma3n_vl_4b_medpix_peft.yaml) | MedPix-VQA | LoRA — Gemma 3n 4B VL on MedPix | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [Gemma 3 & Gemma 3n Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n) for detailed instructions on dataset preparation, configuration, and multi-GPU training. - -## Hugging Face Model Cards - -- [google/gemma-3-4b-it](https://huggingface.co/google/gemma-3-4b-it) -- [google/gemma-3-27b-it](https://huggingface.co/google/gemma-3-27b-it) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma4.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma4.mdx deleted file mode 100644 index e6a72033f8..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/google/gemma4.mdx +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: "Gemma 4" -description: "" ---- -[Gemma 4](https://ai.google.dev/gemma) is Google's next-generation multimodal Gemma family, supporting image-text inputs with a Mixture-of-Experts (MoE) language backbone at larger scales. NeMo AutoModel replaces the HF-native dense matmul over experts with the NeMo `GroupedExperts` backend, enabling Expert Parallelism (EP) via the standard MoE parallelizer. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `Gemma4ForConditionalGeneration` | -| **Parameters** | 2B – 31B (dense) · 26B-A4B (MoE) | -| **HF Org** | [google](https://huggingface.co/google) | - - - -## Available Models - -- **Gemma 4 E2B IT** (VL, dense) -- **Gemma 4 E4B IT** (VL, dense, kv-shared layers) -- **Gemma 4 31B IT** (VL, dense) -- **Gemma 4 26B-A4B IT** (VL, MoE) - -## Architecture - -- `Gemma4ForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Gemma 4 E2B IT | [`google/gemma-4-E2B-it`](https://huggingface.co/google/gemma-4-E2B-it) | -| Gemma 4 E4B IT | [`google/gemma-4-E4B-it`](https://huggingface.co/google/gemma-4-E4B-it) | -| Gemma 4 31B IT | [`google/gemma-4-31B-it`](https://huggingface.co/google/gemma-4-31B-it) | -| Gemma 4 26B-A4B IT (MoE) | [`google/gemma-4-26B-A4B-it`](https://huggingface.co/google/gemma-4-26B-A4B-it) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [gemma4_2b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_2b.yaml) | SFT — Gemma 4 E2B on MedPix | -| [gemma4_2b_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_2b_peft.yaml) | LoRA — Gemma 4 E2B on MedPix | -| [gemma4_4b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_4b.yaml) | SFT — Gemma 4 E4B on MedPix | -| [gemma4_4b_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_4b_peft.yaml) | LoRA — Gemma 4 E4B on MedPix | -| [gemma4_31b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b.yaml) | SFT — Gemma 4 31B on MedPix | -| [gemma4_31b_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b_peft.yaml) | LoRA — Gemma 4 31B on MedPix | -| [gemma4_31b_tp4.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b_tp4.yaml) | SFT — Gemma 4 31B with TP=4 | -| [gemma4_31b_tp4_pp2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b_tp4_pp2.yaml) | SFT — Gemma 4 31B with TP=4, PP=2 | -| [gemma4_31b_tp4_pp4.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b_tp4_pp4.yaml) | SFT — Gemma 4 31B with TP=4, PP=4 (multi-node) | -| [gemma4_26b_a4b_moe.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_26b_a4b_moe.yaml) | SFT — Gemma 4 26B-A4B MoE on MedPix | -| [gemma4_26b_a4b_moe_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_26b_a4b_moe_peft.yaml) | LoRA — Gemma 4 26B-A4B MoE on MedPix | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma4/gemma4_4b.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma4/gemma4_4b.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [google/gemma-4-E2B-it](https://huggingface.co/google/gemma-4-E2B-it) -- [google/gemma-4-E4B-it](https://huggingface.co/google/gemma-4-E4B-it) -- [google/gemma-4-31B-it](https://huggingface.co/google/gemma-4-31B-it) -- [google/gemma-4-26B-A4B-it](https://huggingface.co/google/gemma-4-26B-A4B-it) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx deleted file mode 100644 index 285b40b41e..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/huggingface/smolvlm.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: "SmolVLM" -description: "" ---- -[SmolVLM](https://huggingface.co/blog/smolvlm) is HuggingFace's compact vision language model designed for on-device and memory-constrained deployment, featuring an efficient image token compression strategy. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `SmolVLMForConditionalGeneration` | -| **Parameters** | 256M – 2B | -| **HF Org** | [HuggingFaceTB](https://huggingface.co/HuggingFaceTB) | - - - -## Available Models - -- **SmolVLM-Instruct**: 2B -- **SmolVLM-256M-Instruct**: 256M - -## Architecture - -- `SmolVLMForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| SmolVLM Instruct | [`HuggingFaceTB/SmolVLM-Instruct`](https://huggingface.co/HuggingFaceTB/SmolVLM-Instruct) | -| SmolVLM 256M Instruct | [`HuggingFaceTB/SmolVLM-256M-Instruct`](https://huggingface.co/HuggingFaceTB/SmolVLM-256M-Instruct) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base VLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [HuggingFaceTB/SmolVLM-Instruct](https://huggingface.co/HuggingFaceTB/SmolVLM-Instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/index.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/index.mdx deleted file mode 100644 index 2ff5a830c9..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/index.mdx +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "Vision Language Models (VLMs)" -description: "" -position: 4 ---- -## Introduction - -Vision Language Models (VLMs) integrate vision and language processing capabilities, enabling models to understand images and generate text descriptions, answer visual questions, and perform multimodal reasoning. - -NeMo AutoModel LLM APIs can be easily extended to support VLM tasks. While most of the training setup is the same as for LLMs, some additional steps are required to prepare the data and model for VLM training. - -## Run VLMs with NeMo AutoModel - -To run VLMs with NeMo AutoModel, use NeMo container version [`25.11.00`](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel?version=25.11.00) or later. If the model you want to fine-tune requires a newer version of Transformers, you may need to upgrade: - -```bash -pip3 install --upgrade git+git@github.com:NVIDIA-NeMo/AutoModel.git -``` - -For other installation options, see our [Installation Guide](/get-started/installation). - -## Supported Models - -NeMo AutoModel supports [AutoModelForImageTextToText](https://huggingface.co/docs/transformers/main/model_doc/auto#transformers.AutoModelForImageTextToText) in the [Image-Text-to-Text](https://huggingface.co/models?pipeline_tag=image-text-to-text&sort=trending) category. - -| Owner | Model | Architectures | -|---|---|---| -| Moonshot AI | [Kimi-VL](/model-coverage/vision-language-models/kimi-vl) | `KimiVLForConditionalGeneration` | -| Google | [Gemma 3 VL / Gemma 3n](/model-coverage/vision-language-models/gemma-3-vl-gemma-3n) | `Gemma3ForConditionalGeneration` | -| Google | [Gemma 4](/model-coverage/vision-language-models/gemma-4) | `Gemma4ForConditionalGeneration` | -| Qwen / Alibaba Cloud | [Qwen2.5-VL](/model-coverage/vision-language-models/qwen2-5-vl) | `Qwen2VLForConditionalGeneration`, `Qwen2_5VLForConditionalGeneration` | -| Qwen / Alibaba Cloud | [Qwen3-VL / Qwen3-VL-MoE](/model-coverage/vision-language-models/qwen3-vl-qwen3-vl-moe) | `Qwen3VLForConditionalGeneration` | -| Qwen / Alibaba Cloud | [Qwen3.5-VL](/model-coverage/vision-language-models/qwen3-5-vl) | `Qwen3_5VLForConditionalGeneration`, `Qwen3_5MoeVLForConditionalGeneration` | -| NVIDIA | [Nemotron-Parse](/model-coverage/vision-language-models/nemotron-parse) | `NemotronParseForConditionalGeneration` | -| Mistral AI | [Ministral3 VL](/model-coverage/vision-language-models/ministral3-vl) | `Mistral3ForConditionalGeneration` | -| Mistral AI | [Mistral-Small-4](/model-coverage/vision-language-models/mistral-small-4) | `MistralForConditionalGeneration` | -| Mistral AI | [Mistral Medium 3.5](/model-coverage/vision-language-models/mistral-medium-3-5) | `Mistral3ForConditionalGeneration` (FP8) | -| InternLM / Shanghai AI Lab | [InternVL](/model-coverage/vision-language-models/internvl) | `InternVLForConditionalGeneration` | -| Meta | [Llama 4](/model-coverage/vision-language-models/llama-4) | `Llama4ForConditionalGeneration` | -| HuggingFace | [SmolVLM](/model-coverage/vision-language-models/smolvlm) | `SmolVLMForConditionalGeneration` | -| LLaVA | [LLaVA](/model-coverage/vision-language-models/llava) | `LlavaForConditionalGeneration`, `LlavaNextForConditionalGeneration`, `LlavaNextVideoForConditionalGeneration`, `LlavaOnevisionForConditionalGeneration` | -| lmms-lab | [LLaVA-OneVision 1.5](/model-coverage/vision-language-models/llava-onevision) | `LlavaOneVisionForConditionalGeneration` | - -## Fine-Tuning - -All supported models can be fine-tuned using either full SFT or PEFT (LoRA) approaches. See the [Gemma 3 Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n) for a complete walkthrough covering dataset preparation, configuration, and multi-GPU training. - - -In these guides, we use the `quintend/rdr-items` and `naver-clova-ix/cord-v2` datasets for demonstration purposes. Update the recipe YAML `dataset` section to use your own data. See [VLM datasets](/datasets/multi-modal-dataset) and [dataset overview](/datasets/overview). - - diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/internlm/internvl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/internlm/internvl.mdx deleted file mode 100644 index 73df1ee41c..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/internlm/internvl.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "InternVL" -description: "" ---- -[InternVL](https://github.com/OpenGVLab/InternVL) is a vision language model from Shanghai AI Laboratory (OpenGVLab), combining a large vision encoder with an InternLM language backbone for strong multimodal performance. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `InternVLForConditionalGeneration` | -| **Parameters** | 4B – 8B | -| **HF Org** | [OpenGVLab](https://huggingface.co/OpenGVLab) | - - - -## Available Models - -- **InternVL3.5-4B** -- **InternVL3.5-8B** - -## Architecture - -- `InternVLForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| InternVL3.5 4B | [`OpenGVLab/InternVL3_5-4B`](https://huggingface.co/OpenGVLab/InternVL3_5-4B) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [internvl_3_5_4b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/internvl/internvl_3_5_4b.yaml) | MedPix-VQA | SFT — InternVL3.5 4B on MedPix | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/internvl/internvl_3_5_4b.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/internvl/internvl_3_5_4b.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [OpenGVLab/InternVL3_5-4B](https://huggingface.co/OpenGVLab/InternVL3_5-4B) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/llava-hf/llava.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/llava-hf/llava.mdx deleted file mode 100644 index bae42c4029..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/llava-hf/llava.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "LLaVA" -description: "" ---- -[LLaVA](https://llava-vl.github.io/) (Large Language and Vision Assistant) is a pioneering open-source multimodal model connecting a vision encoder to a language model via a projection layer. Multiple versions and variants are supported via the `llava-hf` organization on Hugging Face. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `LlavaForConditionalGeneration` / `LlavaNextForConditionalGeneration` | -| **Parameters** | 7B – 34B | -| **HF Org** | [llava-hf](https://huggingface.co/llava-hf) | - - - -## Available Models - -- **LLaVA-1.5** (`LlavaForConditionalGeneration`): 7B, 13B -- **LLaVA-1.6 / LLaVA-NeXT** (`LlavaNextForConditionalGeneration`): 7B, 34B -- **LLaVA-NeXT-Video** (`LlavaNextVideoForConditionalGeneration`): 7B -- **LLaVA-OneVision** (`LlavaOnevisionForConditionalGeneration`): 7B - -## Architectures - -- `LlavaForConditionalGeneration` — LLaVA 1.5 -- `LlavaNextForConditionalGeneration` — LLaVA-NeXT / 1.6 -- `LlavaNextVideoForConditionalGeneration` — LLaVA-NeXT-Video -- `LlavaOnevisionForConditionalGeneration` — LLaVA-OneVision - -## Example HF Models - -| Model | HF ID | -|---|---| -| LLaVA 1.5 7B | [`llava-hf/llava-1.5-7b-hf`](https://huggingface.co/llava-hf/llava-1.5-7b-hf) | -| LLaVA 1.5 13B | [`llava-hf/llava-1.5-13b-hf`](https://huggingface.co/llava-hf/llava-1.5-13b-hf) | -| LLaVA-NeXT Mistral 7B | [`llava-hf/llava-v1.6-mistral-7b-hf`](https://huggingface.co/llava-hf/llava-v1.6-mistral-7b-hf) | -| LLaVA-NeXT 34B | [`llava-hf/llava-v1.6-34b-hf`](https://huggingface.co/llava-hf/llava-v1.6-34b-hf) | -| LLaVA-NeXT-Video 7B | [`llava-hf/LLaVA-NeXT-Video-7B-hf`](https://huggingface.co/llava-hf/LLaVA-NeXT-Video-7B-hf) | -| LLaVA-OneVision 7B | [`llava-hf/llava-onevision-qwen2-7b-ov-hf`](https://huggingface.co/llava-hf/llava-onevision-qwen2-7b-ov-hf) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base VLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [llava-hf/llava-1.5-7b-hf](https://huggingface.co/llava-hf/llava-1.5-7b-hf) -- [llava-hf/llava-v1.6-mistral-7b-hf](https://huggingface.co/llava-hf/llava-v1.6-mistral-7b-hf) -- [llava-hf/llava-onevision-qwen2-7b-ov-hf](https://huggingface.co/llava-hf/llava-onevision-qwen2-7b-ov-hf) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx deleted file mode 100644 index 186e0d669a..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/lmms-lab/llava-onevision.mdx +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "LLaVA-OneVision 1.5" -description: "" ---- -[LLaVA-OneVision 1.5](https://github.com/EvolvingLMMs-Lab/LLaVA-OneVision-2) is a vision-language model combining a **Rice ViT** encoder with a **Qwen3** language backbone, capable of handling both image and video understanding. NeMo AutoModel ships a custom NVIDIA implementation (`LlavaOneVisionForConditionalGeneration`) with FSDP2/HSDP support, LoRA fine-tuning and distributed training. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `LlavaOneVisionForConditionalGeneration` | -| **Parameters** | 4B · 8B | -| **HF Org** | [lmms-lab](https://huggingface.co/lmms-lab) | - - - -## Available Models - -- **LLaVA-OneVision 1.5 4B**: Qwen3 4B text backbone + Rice ViT (1024 hidden, 24 layers) -- **LLaVA-OneVision 1.5 8B**: Qwen3 8B text backbone + Rice ViT (1024 hidden, 24 layers) - -## Architecture - -- `LlavaOneVisionForConditionalGeneration` - -Vision tower is the **Rice Transformer**: 14×14 patch embed with 2D RoPE, standard Transformer blocks (LayerNorm + Attention + MLP), and a 2×2 spatial Patch Merger that projects to the language-model hidden size. - -## Example HF Models - -| Model | HF ID | -|---|---| -| LLaVA-OneVision-1.5 4B Instruct | [`lmms-lab/LLaVA-OneVision-1.5-4B-Instruct`](https://huggingface.co/lmms-lab/LLaVA-OneVision-1.5-4B-Instruct) | -| LLaVA-OneVision-1.5 8B Instruct | [`lmms-lab/LLaVA-OneVision-1.5-8B-Instruct`](https://huggingface.co/lmms-lab/LLaVA-OneVision-1.5-8B-Instruct) | - -## Example Recipes - -| Recipe | Description | -|---|---| -| [llava_ov_1_5_4b_finetune.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/llava_onevision/llava_ov_1_5_4b_finetune.yaml) | SFT — LLaVA-OneVision-1.5 4B on LLaVA-Instruct-150K | -| [llava_ov_1_5_8b_lora.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/llava_onevision/llava_ov_1_5_8b_lora.yaml) | LoRA — LLaVA-OneVision-1.5 8B on LLaVA-Instruct-150K | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/llava_onevision/llava_ov_1_5_4b_finetune.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/llava_onevision/llava_ov_1_5_4b_finetune.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [lmms-lab/LLaVA-OneVision-1.5-4B-Instruct](https://huggingface.co/lmms-lab/LLaVA-OneVision-1.5-4B-Instruct) -- [lmms-lab/LLaVA-OneVision-1.5-8B-Instruct](https://huggingface.co/lmms-lab/LLaVA-OneVision-1.5-8B-Instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/meta/llama4.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/meta/llama4.mdx deleted file mode 100644 index f677e0ce2c..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/meta/llama4.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "Llama 4" -description: "" ---- -[Llama 4](https://ai.meta.com/blog/llama-4-multimodal-intelligence/) is Meta's first natively multimodal model family. Llama 4 Scout and Maverick are MoE models supporting interleaved image and text inputs. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `Llama4ForConditionalGeneration` | -| **Parameters** | 17B active (MoE) | -| **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | - - - -## Available Models - -- **Llama-4-Scout-17B-16E-Instruct**: 17B active / 16 experts -- **Llama-4-Maverick-17B-128E-Instruct**: 17B active / 128 experts - -## Architecture - -- `Llama4ForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Llama-4-Scout-17B-16E-Instruct | [`meta-llama/Llama-4-Scout-17B-16E-Instruct`](https://huggingface.co/meta-llama/Llama-4-Scout-17B-16E-Instruct) | -| Llama-4-Maverick-17B-128E-Instruct | [`meta-llama/Llama-4-Maverick-17B-128E-Instruct`](https://huggingface.co/meta-llama/Llama-4-Maverick-17B-128E-Instruct) | - -## Try with NeMo AutoModel - -Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get example recipes you can adapt: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Fine-tune** by adapting a base VLM recipe — override the model ID on the CLI: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml \ - --model.pretrained_model_name_or_path -``` - -Replace `` with the model ID from **Example HF Models** above. - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** The recipes are at `/opt/Automodel/examples/` — navigate there: - -```bash -cd /opt/Automodel -``` - -**3. Fine-tune**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml \ - --model.pretrained_model_name_or_path -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [meta-llama/Llama-4-Scout-17B-16E-Instruct](https://huggingface.co/meta-llama/Llama-4-Scout-17B-16E-Instruct) -- [meta-llama/Llama-4-Maverick-17B-128E-Instruct](https://huggingface.co/meta-llama/Llama-4-Maverick-17B-128E-Instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx deleted file mode 100644 index 10fa50ab2f..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/ministral3-vl.mdx +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Ministral3 VL" -description: "" ---- -[Ministral3](https://mistral.ai/news/ministraux/) is Mistral AI's efficient small model series. The vision-capable variants support image-text inputs for multimodal tasks. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `Mistral3ForConditionalGeneration` | -| **Parameters** | 3B – 14B | -| **HF Org** | [mistralai](https://huggingface.co/mistralai) | - - - -## Available Models - -- **Ministral-3-14B-Instruct-2512** -- **Ministral-3-8B-Instruct-2512** -- **Ministral-3-3B-Instruct-2512** - -## Architecture - -- `Mistral3ForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Ministral-3 3B Instruct | [`mistralai/Ministral-3-3B-Instruct-2512`](https://huggingface.co/mistralai/Ministral-3-3B-Instruct-2512) | -| Ministral-3 8B Instruct | [`mistralai/Ministral-3-8B-Instruct-2512`](https://huggingface.co/mistralai/Ministral-3-8B-Instruct-2512) | -| Ministral-3 14B Instruct | [`mistralai/Ministral-3-14B-Instruct-2512`](https://huggingface.co/mistralai/Ministral-3-14B-Instruct-2512) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [ministral3_3b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral/ministral3_3b_medpix.yaml) | MedPix-VQA | SFT — Ministral3 3B on MedPix | -| [ministral3_8b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral/ministral3_8b_medpix.yaml) | MedPix-VQA | SFT — Ministral3 8B on MedPix | -| [ministral3_14b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral/ministral3_14b_medpix.yaml) | MedPix-VQA | SFT — Ministral3 14B on MedPix | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/mistral/ministral3_3b_medpix.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/mistral/ministral3_3b_medpix.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [mistralai/Ministral-3-8B-Instruct-2512](https://huggingface.co/mistralai/Ministral-3-8B-Instruct-2512) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx deleted file mode 100644 index 13a6a57d7e..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx +++ /dev/null @@ -1,162 +0,0 @@ ---- -title: "Mistral Medium 3.5" -description: "" ---- -[Mistral Medium 3.5](https://huggingface.co/mistralai) is Mistral AI's -flagship **128B dense** model that merges instruction-following, reasoning, -and coding into a single checkpoint with a configurable reasoning mode. -It unifies the lineage of *Mistral Medium 3.1*, *Magistral Medium*, and -*Devstral 2* into one model, and ships natively in FP8 (per-tensor -`weight_scale_inv`) so the full model fits inside an H200 node or 2 × -H100 nodes — a notable footprint advantage over comparably-capable -Mixture-of-Experts (MoE) systems. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `Mistral3ForConditionalGeneration` (Pixtral vision tower + dense Ministral-3 text decoder) | -| **Parameters** | 128B (dense, FP8 on disk) | -| **Context Window** | 256k tokens | -| **Languages** | 40+ (English, French, Spanish, German, Russian, Chinese, Japanese, Italian, Portuguese, Arabic, Hindi, Korean, plus Indic / Nordic / Eastern European tail) | -| **License** | Modified MIT (open-weights, ≤ $20M annual revenue threshold) | -| **HF Org** | [mistralai](https://huggingface.co/mistralai) | - - - -## Architecture - -Mistral Medium 3.5 is a **dense** transformer — no MoE routing — built on -the same text backbone as -[`mistralai/Devstral-2-123B-Instruct-2512`](https://huggingface.co/mistralai/Devstral-2-123B-Instruct-2512): -88 Ministral-3 decoder layers (hidden 12288, 96 attention heads, -8 KV heads, GQA) with the standard llama-style RoPE + RMSNorm + SwiGLU -MLP layout. The multimodal variant adds a Pixtral vision tower and -multi-modal projector on top, making it an -`AutoModelForImageTextToText` checkpoint. - -Compared with MoE models of similar capability, the dense layout -trades sparse-activation throughput for a substantially smaller -deployment footprint — relevant when you want to fine-tune or serve -the model on a single node. - -## Key Strengths - -- **Compactness.** Dense 128B fits in fewer GPUs than the comparable - MoE class — a single H200 node or 2 × H100 nodes for inference. -- **Configurable reasoning mode.** One checkpoint covers chat, - agentic, and reasoning workloads; the reasoning mode is toggled at - inference time. -- **Strong agentic performance.** Competitive on tool-use and - decision-making benchmarks; suitable as a base for connector-driven - agent workflows. -- **Long context.** 256k-token window for document parsing and - research-assistant use cases. - -Trade-offs disclosed in the model card: weaker non-agentic benchmark -performance and more verbose outputs than some closed-source -competitors. - -## Use Cases - -- Agentic workflows with connectors -- Cloud and local async coding -- Document parsing (multimodal — text + image) -- Research assistants -- General chat -- Base model for downstream fine-tuning - -## Available Models - -- **Mistral-Medium-3.5 128B** - -## Class - -- HF: `Mistral3ForConditionalGeneration` -- NeMo AutoModel custom: `Mistral3FP8VLMForConditionalGeneration` - ([source](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/models/mistral3_vlm/model.py)) - -The custom class extends HF's `Mistral3ForConditionalGeneration` and -attaches a `Mistral3FP8StateDictAdapter.for_vlm_full()` so the FP8 -checkpoint dequantizes per-shard inside the standard DCP load — the -full BF16 model is never materialized on a single rank, allowing TP+PP -training to fit on H100-80GB. - -## Example HF Models - -| Model | HF ID | -|---|---| -| Mistral Medium 3.5 128B | [`mistralai/Mistral-Medium-3.5`](https://huggingface.co/mistralai) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [mistral3p5_128b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral3p5/mistral3p5_128b_medpix.yaml) | MedPix-VQA | SFT — Mistral Medium 3.5 128B on MedPix, 8 nodes × 8 GPUs (TP=8 PP=8) | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - - -This recipe was validated on **8 nodes × 8 GPUs (64 H100s)** with -TP=8 PP=8 DP=1. See the [Launcher Guide](/job-launchers/slurm-cluster) -for multi-node setup. Inference / single-node fine-tune fits in -**1 × H200** or **2 × H100** nodes thanks to the dense + FP8 layout. - - - -**3. Run the recipe** via Slurm (see the -[fine-tuning guide](/recipes-e2e-examples/mistral-medium-3-5) for a -complete launch script): - -```bash -sbatch your_slurm_script.sub -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/mistral3p5/mistral3p5_128b_medpix.yaml -``` - - -See the [Installation Guide](/get-started/installation) and the -[Mistral Medium 3.5 Fine-Tuning Guide](/recipes-e2e-examples/mistral-medium-3-5). - -## Fine-Tuning - -See the [Mistral Medium 3.5 Fine-Tuning Guide](/recipes-e2e-examples/mistral-medium-3-5). - -## Hugging Face Model Cards - -- [mistralai](https://huggingface.co/mistralai) -- Related architecture: [`mistralai/Devstral-2-123B-Instruct-2512`](https://huggingface.co/mistralai/Devstral-2-123B-Instruct-2512) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx deleted file mode 100644 index cf6820c599..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/mistralai/mistral-small-4.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "Mistral-Small-4" -description: "" ---- -[Mistral-Small-4-119B](https://huggingface.co/mistralai/Mistral-Small-4-119B-2603) is Mistral AI's multimodal MoE model supporting both text and image inputs at scale. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `MistralForConditionalGeneration` | -| **Parameters** | 119B (MoE) | -| **HF Org** | [mistralai](https://huggingface.co/mistralai) | - - - -## Available Models - -- **Mistral-Small-4-119B-2603** - -## Architecture - -- `MistralForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Mistral-Small-4 119B | [`mistralai/Mistral-Small-4-119B-2603`](https://huggingface.co/mistralai/Mistral-Small-4-119B-2603) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [mistral4_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral4/mistral4_medpix.yaml) | MedPix-VQA | SFT — Mistral-Small-4 on MedPix | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - - -This recipe was validated on **4 nodes × 8 GPUs (32 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. - - - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/mistral4/mistral4_medpix.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/mistral4/mistral4_medpix.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [mistralai/Mistral-Small-4-119B-2603](https://huggingface.co/mistralai/Mistral-Small-4-119B-2603) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx deleted file mode 100644 index e23bbf80b1..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/moonshotai/kimi-vl.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: "Kimi-VL" -description: "" ---- -[Kimi-VL](https://huggingface.co/moonshotai/Kimi-VL-A3B-Instruct) and Kimi-K25-VL are vision language models from Moonshot AI. Kimi-VL-A3B uses a MoE language backbone (3B active parameters) with a vision encoder, supporting image understanding and multimodal reasoning. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `KimiVLForConditionalGeneration` | -| **Parameters** | ~3B active (MoE) | -| **HF Org** | [moonshotai](https://huggingface.co/moonshotai) | - - - -## Available Models - -- **Kimi-VL-A3B-Instruct** -- **Kimi-K25-VL** - -## Architecture - -- `KimiVLForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Kimi-VL-A3B-Instruct | [`moonshotai/Kimi-VL-A3B-Instruct`](https://huggingface.co/moonshotai/Kimi-VL-A3B-Instruct) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [kimi2vl_cordv2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/kimi/kimi2vl_cordv2.yaml) | cord-v2 | SFT — Kimi-VL on CORD-v2 | -| [kimi25vl_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/kimi/kimi25vl_medpix.yaml) | MedPix-VQA | SFT — Kimi-K25-VL on MedPix | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/kimi/kimi2vl_cordv2.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/kimi/kimi2vl_cordv2.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [moonshotai/Kimi-VL-A3B-Instruct](https://huggingface.co/moonshotai/Kimi-VL-A3B-Instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx deleted file mode 100644 index 272be22e76..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/nvidia/nemotron-parse.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Nemotron-Parse" -description: "" ---- -[Nemotron-Parse-v1.1](https://huggingface.co/nvidia/NVIDIA-Nemotron-Parse-v1.1) is NVIDIA's document parsing VLM, specializing in extracting structured information from complex documents including tables, forms, and mixed-content PDFs. - - - -| | | -|---|---| -| **Task** | Document Parsing | -| **Architecture** | `NemotronParseForConditionalGeneration` | -| **Parameters** | varies | -| **HF Org** | [nvidia](https://huggingface.co/nvidia) | - - - -## Available Models - -- **Nemotron-Parse-v1.1** - -## Architecture - -- `NemotronParseForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Nemotron-Parse v1.1 | [`nvidia/NVIDIA-Nemotron-Parse-v1.1`](https://huggingface.co/nvidia/NVIDIA-Nemotron-Parse-v1.1) | - -## Example Recipes - -| Recipe | Dataset | Description | Try on Brev | -|---|---|---|---| -| [nemotron_parse_v1_1.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml) | cord-v2 | SFT — Nemotron-Parse on CORD-v2 | [![Launch on Brev](https://brev-assets.s3.us-west-1.amazonaws.com/nv-lb-dark.svg)](https://brev.nvidia.com/launchable/deploy/now?launchableID=env-3C6LDKU2DfOvpVTFhjw3YQ4djPM) | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning Tutorial on Brev - -Launch the end-to-end Nemotron Parse fine-tuning tutorial on Brev with a single click: - -[![Launch on Brev](https://brev-assets.s3.us-west-1.amazonaws.com/nv-lb-dark.svg)](https://brev.nvidia.com/launchable/deploy/now?launchableID=env-3C6LDKU2DfOvpVTFhjw3YQ4djPM) - -See also the [tutorial notebook](https://github.com/NVIDIA-NeMo/Automodel/blob/main/tutorials/nemotron-parse/finetune.ipynb) and the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [nvidia/NVIDIA-Nemotron-Parse-v1.1](https://huggingface.co/nvidia/NVIDIA-Nemotron-Parse-v1.1) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx deleted file mode 100644 index d7e09efa5c..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen2-5-vl.mdx +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "Qwen2.5-VL" -description: "" ---- -[Qwen2.5-VL](https://qwenlm.github.io/blog/qwen2.5-vl/) is Alibaba Cloud's vision language model series supporting image and video understanding. It features dynamic resolution processing and integrates with the Qwen2.5 language backbone. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `Qwen2_5VLForConditionalGeneration` | -| **Parameters** | 2B – 72B | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen2.5-VL-72B-Instruct** -- **Qwen2.5-VL-32B-Instruct** -- **Qwen2.5-VL-7B-Instruct** -- **Qwen2.5-VL-3B-Instruct** -- **Qwen2-VL-7B-Instruct**, **Qwen2-VL-2B-Instruct** (Qwen2 VL) - -## Architectures - -- `Qwen2_5VLForConditionalGeneration` — Qwen2.5-VL -- `Qwen2VLForConditionalGeneration` — Qwen2-VL - -## Example HF Models - -| Model | HF ID | -|---|---| -| Qwen2.5-VL 3B Instruct | [`Qwen/Qwen2.5-VL-3B-Instruct`](https://huggingface.co/Qwen/Qwen2.5-VL-3B-Instruct) | -| Qwen2.5-VL 7B Instruct | [`Qwen/Qwen2.5-VL-7B-Instruct`](https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct) | -| Qwen2-VL 7B Instruct | [`Qwen/Qwen2-VL-7B-Instruct`](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [qwen2_5_vl_3b_rdr.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen2_5/qwen2_5_vl_3b_rdr.yaml) | rdr-items | SFT — Qwen2.5-VL 3B on RDR Items | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/qwen2_5/qwen2_5_vl_3b_rdr.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/qwen2_5/qwen2_5_vl_3b_rdr.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [Qwen/Qwen2.5-VL-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-VL-7B-Instruct) -- [Qwen/Qwen2-VL-7B-Instruct](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx deleted file mode 100644 index 37408a0939..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-5-vl.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Qwen3.5-VL" -description: "" ---- -Qwen3.5-VL is Alibaba Cloud's next-generation vision language model series, including dense and MoE variants for image and multimodal understanding tasks. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `Qwen3_5VLForConditionalGeneration` | -| **Parameters** | 4B – 35B+ | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen3.5-VL-4B**: 4B dense model -- **Qwen3.5-VL-9B**: 9B dense model -- **Qwen3.5-MoE**: large MoE variant (35B+) -- **Qwen3.6-27B**: 27B dense model -- **Qwen3.6-35B-A3B**: next-generation MoE variant (35B total, 3B active) - -## Architectures - -- `Qwen3_5VLForConditionalGeneration` — dense models -- `Qwen3_5MoeVLForConditionalGeneration` — MoE variant - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [qwen3_5_4b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5/qwen3_5_4b.yaml) | MedPix-VQA | SFT — Qwen3.5-VL 4B on MedPix | -| [qwen3_5_9b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5/qwen3_5_9b.yaml) | MedPix-VQA | SFT — Qwen3.5-VL 9B on MedPix | -| [qwen3_5_moe_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5_moe/qwen3_5_moe_medpix.yaml) | MedPix-VQA | SFT — Qwen3.5-MoE on MedPix | -| [qwen3_5_35b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5_moe/qwen3_5_35b.yaml) | MedPix-VQA | SFT — Qwen3.5 35B on MedPix | -| [qwen3_6_27b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5/qwen3_6_27b.yaml) | MedPix-VQA | SFT — Qwen3.6-27B on MedPix | -| [qwen3_6_35b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5_moe/qwen3_6_35b.yaml) | MedPix-VQA | SFT — Qwen3.6 35B-A3B on MedPix | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/qwen3_5/qwen3_5_4b.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/qwen3_5/qwen3_5_4b.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [Qwen](https://huggingface.co/Qwen) diff --git a/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx b/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx deleted file mode 100644 index 2762e81426..0000000000 --- a/docs/fern/versions/nightly/pages/model-coverage/vlm/qwen/qwen3-vl.mdx +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "Qwen3-VL / Qwen3-VL-MoE" -description: "" ---- -[Qwen3-VL](https://qwenlm.github.io/blog/qwen3/) is Alibaba Cloud's third-generation vision language model series. The MoE variant activates a fraction of parameters per token for efficient large-scale inference. - - - -| | | -|---|---| -| **Task** | Image-Text-to-Text | -| **Architecture** | `Qwen3VLForConditionalGeneration` | -| **Parameters** | 4B – 235B | -| **HF Org** | [Qwen](https://huggingface.co/Qwen) | - - - -## Available Models - -- **Qwen3-VL-8B-Instruct**: 8B -- **Qwen3-VL-4B-Instruct**: 4B -- **Qwen3-VL-MoE-30B**: 30B total (MoE) -- **Qwen3-VL-MoE-235B**: 235B total (MoE) - -## Architecture - -- `Qwen3VLForConditionalGeneration` - -## Example HF Models - -| Model | HF ID | -|---|---| -| Qwen3-VL 4B Instruct | [`Qwen/Qwen3-VL-4B-Instruct`](https://huggingface.co/Qwen/Qwen3-VL-4B-Instruct) | -| Qwen3-VL 8B Instruct | [`Qwen/Qwen3-VL-8B-Instruct`](https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct) | - -## Example Recipes - -| Recipe | Dataset | Description | -|---|---|---| -| [qwen3_vl_4b_instruct_rdr.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_4b_instruct_rdr.yaml) | rdr-items | SFT — Qwen3-VL 4B on RDR Items | -| [qwen3_vl_8b_instruct_rdr.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_8b_instruct_rdr.yaml) | rdr-items | SFT — Qwen3-VL 8B on RDR Items | -| [qwen3_vl_moe_30b_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_moe_30b_te_deepep.yaml) | MedPix-VQA | SFT — Qwen3-VL-MoE 30B with TE + DeepEP | -| [qwen3_vl_moe_235b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_moe_235b.yaml) | MedPix-VQA | SFT — Qwen3-VL-MoE 235B | - -## Try with NeMo AutoModel - -**1. Install** ([full instructions](/get-started/installation)): - -```bash -pip install nemo-automodel -``` - -**2. Clone the repo** to get the example recipes: - -```bash -git clone https://github.com/NVIDIA-NeMo/Automodel.git -cd Automodel -``` - -**3. Run the recipe** from inside the repo: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/qwen3/qwen3_vl_4b_instruct_rdr.yaml -``` - - -**1. Pull the container** and mount a checkpoint directory: - -```bash -docker run --gpus all -it --rm \ - --shm-size=8g \ - -v $(pwd)/checkpoints:/opt/Automodel/checkpoints \ - nvcr.io/nvidia/nemo-automodel:26.02.00 -``` - -**2.** Navigate to the AutoModel directory (where the recipes are): - -```bash -cd /opt/Automodel -``` - -**3. Run the recipe**: - -```bash -automodel --nproc-per-node=8 examples/vlm_finetune/qwen3/qwen3_vl_4b_instruct_rdr.yaml -``` - - -See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Fine-Tuning - -See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). - -## Hugging Face Model Cards - -- [Qwen/Qwen3-VL-4B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-4B-Instruct) -- [Qwen/Qwen3-VL-8B-Instruct](https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct) diff --git a/docs/fern/versions/nightly/pages/performance-summary.mdx b/docs/fern/versions/nightly/pages/performance-summary.mdx deleted file mode 100644 index be080d534b..0000000000 --- a/docs/fern/versions/nightly/pages/performance-summary.mdx +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: "Performance Summary" -description: "" -position: 1 ---- -This document provides performance benchmarks for various large language models using NeMo AutoModel with the PyTorch backend. - -## Pre-Training Performance - -The table below shows training performance for full sequences with no padding across different model architectures and scales. - -### System: DGX-H100, Precision: BF16 - -| Model | #GPUs | GBS | MBS | LBS | GA | Seq Length | TP | PP | CP | EP | VP | FSDP | Kernel Optimizations | Time per Global Step (s) | Model TFLOPs/sec/GPU | Tokens/sec/GPU | -|-------|------:|----:|----:|----:|---:|-----------:|---:|---:|---:|---:|---:|-----:|---------|-------------------------:|---------------------:|---------------:| -| Nemotron V3 Super 120B (26.02) | 64 | 512 | 2 | 2 | 4 | 4096 | 1 | 1 | 1 | 64 | - | 64 | TE + DeepEP + TorchSDPA | 7.286 | 334 | 4,497 | -| Nemotron V3 Nano 30B (26.02) | 8 | 512 | 4 | 4 | 16 | 4096 | 1 | 1 | 1 | 8 | - | 8 | TE + DeepEP + TorchSDPA | 15.614 | 328 | 16,789 | -| DeepSeek V3 671B | 1024 | 8192 | 1 | 8 | 4 | 4096 | 1 | 4 | 1 | 64 | 8 | 256 | TE + DeepEP | 37.87 | 216 | 865 | -| DeepSeek V3 671B | 256 | 512 | 1 | 8 | 1 | 4096 | 1 | 4 | 1 | 64 | 8 | 64 | TE + DeepEP | 8.18 | 250 | 1,002 | -| Kimi K2 | 256 | 512 | 1 | 8 | 2 | 4096 | 1 | 8 | 1 | 32 | 4 | 32 | TE + DeepEP | 8.86 | 189 | 924 | -| Qwen3 MoE 30B | 8 | 512 | 4 | 4 | 16 | 4096 | 1 | 1 | 1 | 8 | - | 8 | TE + DeepEP | 21.773 | 277 | 12,040 | -| GPT-OSS 20B | 8 | 256 | 2 | 2 | 16 | 4096 | 1 | 1 | 1 | - | - | 8 | TE + DeepEP + FlexAttn | 10.04 | 279 | 13,058 | -| GPT-OSS 120B | 64 | 512 | 2 | 2 | 4 | 4096 | 1 | 1 | 1 | - | - | 64 | TE + DeepEP + FlexAttn | 4.30 | 231 | 7,626 | -| Llama3 70B | 64 | 128 | 1 | 1 | 4 | 8192 | 1 | 1 | 2 | - | - | 32 | TE + fsdp2_prefetch | 18.90 | 389 | 866.77 | - -## Fine-Tuning (LoRA) Performance - -The table below shows fine-tuning (LoRA) performance for full sequences with no padding across different model architectures and scales. - -### System: DGX-H100, Precision: BF16 - -| Model | #GPUs | GBS | MBS | LBS | GA | Seq Length | TP | PP | CP | EP | VP | FSDP | Kernel Optimizations | Time per Global Step (s) | Model TFLOPs/sec/GPU | Tokens/sec/GPU | -|-------|------:|----:|----:|----:|---:|-----------:|---:|---:|---:|---:|---:|-----:|---------|-------------------------:|---------------------:|---------------:| -| Llama3 8B | 1 | 32 | 2 | 2 | 16 | 4096 | 1 | 1 | 1 | - | 1 | 1 | TE + triton | 10.51 | 402 | 12472.87 | -| Qwen2.5 7B | 1 | 32 | 2 | 2 | 16 | 4096 | 1 | 1 | 1 | - | 1 | 1 | TE + triton | 9.29 | 423 | 14110.05 | -| Llama3 70B | 8 | 32 | 2 | 2 | 4 | 4096 | 2 | 1 | 1 | - | 1 | 4 | TE + triton + fsdp2_prefetch | 15.00 | 316 | 1091.85 | -| Qwen2.5 32B | 8 | 32 | 2 | 2 | 4 | 4096 | 2 | 1 | 1 | - | 1 | 4 | TE + triton + fsdp2_prefetch | 7.28 | 301 | 2250.31 | -| Llama3 70B 2-node | 16 | 32 | 2 | 2 | 2 | 4096 | 2 | 1 | 1 | - | 1 | 8 | TE + triton + fsdp2_prefetch | 8.32 | 285 | 984.85 | -| Qwen2.5 32B 2-node | 16 | 32 | 2 | 2 | 2 | 4096 | 2 | 1 | 1 | - | 1 | 8 | TE + triton + fsdp2_prefetch | 3.95 | 277 | 2072.89 | - -## Glossary - -- **MFU**: Model FLOPs Utilization - ratio of achieved compute to peak hardware capability -- **TP**: Tensor Parallelism - splits individual layers across GPUs -- **PP**: Pipeline Parallelism - splits model layers into stages -- **EP**: Expert Parallelism - distributes MoE experts across GPUs -- **DP**: Data Parallelism - replicates model and splits data -- **VP**: Virtual Pipeline - number of pipeline stages per GPU for interleaving -- **MBS**: Micro-Batch Size - size of one forward pass in pipeline -- **LBS**: Local Batch Size - size of one step per GPU -- **GBS**: Global Batch Size - total batch size across all GPUs -- **GA**: Gradient Accumulation - number of local-batches before optimizer step -- **TE**: Transformer Engine kernel optimizations - RMSNorm, Linear and DotProductAttention -- **DeepEP**: Deep Expert Parallelism - advanced EP routing for MoE models -- **FlexAttn**: PyTorch's [Flex Attention](https://docs.pytorch.org/docs/stable/nn.attention.flex_attention.html) - -## Configuration Files - -Pre-training and fine-tuning (LoRA) benchmark configurations are available in [`examples/llm_benchmark/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark): - -- [`deepseek_v3_te_deepep.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/deepseek/deepseek_v3_te_deepep.yaml) - DeepSeek V3 with TE + DeepEP -- [`kimi_k2_te_deepep.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/kimi/kimi_k2_te_deepep.yaml) - Kimi K2 optimized configuration -- [`qwen3_moe_30b_te_deepep.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/qwen/qwen3_moe_30b_te_deepep.yaml) - Qwen3 MoE with TE + DeepEP -- [`gptoss_20b_te_deepep.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/gpt_oss/gptoss_20b_te_deepep.yaml) - GPT-OSS 20B with optimizations -- [`gptoss_120b_te_deepep.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/gpt_oss/gptoss_120b_te_deepep.yaml) - GPT-OSS 120B optimized -- [`custom_llama3_1_70b_pretrain_benchmark_8nodes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/llama3_3/custom_llama3_1_70b_pretrain_benchmark_8nodes.yaml) - Llama3-70B optimized -- [`llama3_1_8b_peft_benchmark.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/llama3_1/llama3_1_8b_peft_benchmark.yaml) - Llama-8B fine-tuning (LoRA) optimized -- [`qwen2_5_7b_peft_benchmark.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/qwen/qwen2_5_7b_peft_benchmark.yaml) - Qwen2.5-7B fine-tuning (LoRA) optimized -- [`custom_llama3_3_70b_instruct_peft_benchmark.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/llama3_3/custom_llama3_3_70b_instruct_peft_benchmark.yaml) - Llama-70B fine-tuning (LoRA) optimized -- [`custom_qwen2_5_32b_peft_benchmark.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/qwen/custom_qwen2_5_32b_peft_benchmark.yaml) - Qwen2.5-32B fine-tuning (LoRA) optimized -- [`custom_llama3_3_70b_instruct_peft_benchmark_2nodes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/llama3_3/custom_llama3_3_70b_instruct_peft_benchmark_2nodes.yaml) - Llama-70B fine-tuning (LoRA) optimized on 2 nodes -- [`custom_qwen2_5_32b_peft_benchmark_2nodes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/qwen/custom_qwen2_5_32b_peft_benchmark_2nodes.yaml) - Qwen2.5-32B fine-tuning (LoRA) optimized on 2 nodes - - -- All benchmarks use mock data for consistent performance measurement. -- Fake balanced gate is enabled to simulate ideal expert routing. -- No gradient clipping applied for pure performance measurement. -- MFU calculated using peak TFLOPs for the system (989 for BF16 H100). -- Step times include forward and backward passes + optimizer step for the global batch. - - - -## Version Information -- **Last Updated**: 2025-10-02 -- **NeMo AutoModel Version**: `main` Branch diff --git a/docs/fern/versions/nightly/pages/release-notes.mdx b/docs/fern/versions/nightly/pages/release-notes.mdx deleted file mode 100644 index 2c33c9fb47..0000000000 --- a/docs/fern/versions/nightly/pages/release-notes.mdx +++ /dev/null @@ -1,258 +0,0 @@ ---- -title: "Release Notes" -description: "" ---- -## 0.4.0 · 26.04 (2026-04-28) · [PyPI](https://pypi.org/project/nemo-automodel/0.4.0/) · [GH](https://github.com/NVIDIA-NeMo/Automodel/releases/tag/v0.4.0) · [NGC Docker](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel/tags?version=26.04.00) - -### Highlights - -- **Discrete-diffusion LLMs (dLLM).** SFT and generation support for dLLM - models, including Llada. -- **Embedding and retrieval training.** Reranker training, biencoder datasets - loaded directly from the Hugging Face Hub, in-batch negative sampling, and - ONNX export for biencoder models. -- **SkyPilot launcher.** Native multi-node launch on cloud (SkyPilot, - including Kubernetes), in addition to local interactive runs. SkyPilot and - NeMo Run launchers are selected with YAML sections in the config; SLURM jobs - use the `sbatch slurm.sub` workflow. -- **CLI install profile.** The `nemo-automodel[cli]` extra declares `pyyaml` - beyond the package's base dependencies for job-submission configs. -- **Refreshed CLI.** `automodel ` (alias `am`) replaces the older - `automodel -c ` form. - -### New Models - -- **LLM:** GLM-5, MiniMax-M2.5, Nemotron Super v3, Nemotron Nano 4B/8B. -- **MoE / VLM:** Qwen3.5-MoE (397B-A17B, 35B-A3B). -- **VLM:** Gemma 4, Mistral Small 4, Qwen3.5 small dense models. -- **Diffusion:** FLUX.1-dev, Wan 2.1 T2V, HunyuanVideo 1.5; Wan - multi-resolution and LoRA recipes for diffusion. - -### Distributed Training - -- Context parallelism for Qwen3.5-MoE and Nemotron v3. -- Pipeline parallelism for knowledge distillation. -- HybridEP and UCCL-EP as alternative expert-parallel dispatchers. -- FSDP2 weight prefetching and async TP optimization. -- TP > 1 in knowledge distillation. - -### Performance and Kernels - -- TE Linear layers enabled for PEFT/LoRA. -- `torch._grouped_mm` expert backend. -- fp32 RMSNorm backend and `cast_model_to_dtype` controls. -- TP-aware KD loss with distributed softmax and T² scaling. -- FlashOptim optimizer integration. -- Sequence-packing updates: Qwen3.5-MoE VLM neat-packing recipe with EP+PP; - Generic THD collation for chat datasets; CP/BSHD padding fixes. - -### PEFT - -- MoE LoRA: rank scaling, `torch_mm` integration, expert-LoRA init using - `config.expert_dim`. -- `merge_lora` tool for materializing adapters into the base model. -- QLoRA PEFT checkpoints saved with the HF adapter prefix. - -### Recipes and Workflow - -- New recipes for Gemma 4 (LoRA), Nemotron Nano 4B SQuAD, Mistral Small 4, - Tulu-3 E2E convergence, GPT-OSS 20B / Moonlight 16B convergence, and - reranker / biencoder training. -- MFU logging for LLM and dLLM train recipes. -- Native Comet ML experiment tracking. -- NEFTune noisy embeddings for instruction fine-tuning. -- Scheduler-driven manual garbage collection. -- Common inference utility and `.generate()` with KV cache for Nemotron v3. - -### Checkpointing - -- `v4_compatible` checkpoint format. -- Diffusion full fine-tuning and pretraining examples use safetensors - checkpoint format; diffusion LoRA examples use `torch_save`. -- QLoRA / LoRA loading robustness; tied-weight handling moved out of - `_init_model`. - -### Fixes - -- FSDP2 meta-device crash for Qwen3.5 GatedDeltaNet fp32 params. -- Activation checkpointing silently skipped on registered VLMs (ModuleList - flattening). -- Gradient checkpointing for MoE models on single GPU (`ep_size=1`). -- Gradient clipping with `torch_mm` + EP (GPT-OSS 120B recipe). -- Rotary embeddings for v4 models; `inputs_embeds` passthrough for Nano v3. - -### Breaking Changes - -A migration guide for the new CLI, the `recipe` YAML section, the SLURM -`sbatch`-script workflow, and the `nemo-automodel[cli]` install profile is in -[Breaking Changes](/development/breaking-changes). - ---- - -## 0.3.0 · 26.02 (2026-02-26) · [PyPI](https://pypi.org/project/nemo-automodel/0.3.0/) · [GH](https://github.com/NVIDIA-NeMo/Automodel/releases/tag/v0.3.0) · [NGC Docker](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel/tags?version=26.02.00) - -### Highlights - -- **Transformers v4 / v5 alignment.** New `transformers v4` API support and a - v5 refactor for device-mesh-only model init. -- **Streaming safetensors writer** for faster checkpoint export. -- **Faster fp8 dequant kernels** with DTensor dequantization fixes for DSv3. - -### New Models - -- **LLM:** DeepSeek V3.2, Step-3.5-Flash, MiniMax-M2.1, - Nemotron-3-Nano-30B-A3B, Nemotron Flash 1B, GLM-4.7, - Devstral-Small-2-24B. -- **MoE / VLM / Omni:** Qwen3-VL (4B/8B), Qwen3-VL-MoE (30B/235B), - Kimi-VL, Kimi-K2.5 VL, Nemotron-Parse VLM, InternVL3.5-4B, - Ministral3 (3B/8B/14B), Phi-4-multimodal. - -### Distributed Training - -- v5 refactor: device-mesh-only model init. -- TP plan for Ministral; Ministral3 ported to transformers v4. -- Pipeline-parallelism validation support. -- Parallel diffusers `generate()`. - -### Performance and Kernels - -- TE fp8 for models that support it. -- `GroupedExpertsTE` backend (prerequisite for MoE fp8). -- TE RoPE fusion for custom MoE models; norm fusion and RoPE cache for dense - models. -- Improved import time. - -### PEFT - -- DoRA implementation. -- LoRA support for custom MoEs. -- LoRA support in Biencoder. - -### Datasets and Workflow - -- Databricks Delta Lake dataset support; consolidation for Databricks. -- Parquet file support; inline text dataset format. -- `ColumnMapped`: configurable special tokens, chat-template flags, and - answer-only masking. -- Hard negative mining and biencoder + inline-dataset tests. -- nsys benchmark support and model-layer name scoping in the CLI. -- Updated checkpoint auto-loading with explicit `restore_from`. -- Dion optimizer. -- Functiongemma + xlam tool-calling recipes. - -### Fixes - -- `inputs_embeds` passthrough for Nano v3. -- `from_pretrained` / `from_config` simplification with model-id pass-through. -- Tied-embedding detection improvements. - ---- - -## 0.2.0 · 25.11 (2025-12-04) · [PyPI](https://pypi.org/project/nemo-automodel/0.2.0/) · [GH](https://github.com/NVIDIA-NeMo/Automodel/releases/tag/v0.2.0) · [NGC Docker](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel/tags?version=25.11.00) - -### Highlights - -- **Async checkpointing.** Checkpoint refactor with async DCP and HF - safetensors backport / consolidation. -- **Custom MoE optimizations.** FSDP optimizations, packed-sequence + context - parallel through TE, configurable router precision, fp32 `lm_head` and - fp32 `apply_rope`. -- **Performance documentation.** New performance-summary doc and benchmarking - recipe with configs. -- **Multinode + cluster guidance.** Multinode configs and updated launcher - docs. - -### New Models - -- **MoE:** Qwen3 MoE custom implementation, Qwen3 Next, GPT-OSS (custom - implementation, dequantization, DGX Spark recipe), GLM 4 / 4.5 / 4.6 MoE, - GLM 4.5 Air, Moonlight 2L test, Phi 4 (TP plan). -- **Omni / VLM:** Qwen3-Omni OOTB recipe and custom implementation. -- **DeepSeek v3** with fp8 base checkpoint loading. -- **Sequence classification:** Qwen3ForSequenceClassification registered; - generic SFT sequence-classification recipe. - -### Distributed Training - -- VLM expert-parallel recipe support. -- PP for VLM; PEFT with PP. -- Sharding optimization for SP / LoRA. -- `clip_grad_norm` across all parallelism modes. -- `fully_shard_by_dtype` option. -- Out-of-tree (OOT) parallelism decorator. - -### Performance and Kernels - -- Mask creation moved into the data pipeline for better performance. -- TE attention for GPT-OSS. -- Faster fp8 dequant; auto-detect base-weights dequant. - -### PEFT - -- LoRA-aware `ColwiseParallel` / `RowwiseParallel`. -- LoRA + TE. -- MFU estimation for LoRA. -- Additional PEFT LoRA recipes. - -### Datasets and Recipes - -- Multiturn chat dataset; VLM multiturn chat support. -- Tool-calling dataset and recipe. -- Streaming dataset. -- Multiple validation datasets with per-dataset logging. -- ColumnMapped: surface truncating + padding options. -- Configurable max-clip-grad; configurable remote-logging frequency using - `step_scheduler`. -- Validation-loss checkpoint, run-val-at-ckpt, best-ckpt symlink. -- InternVL recipe; Qwen3-VL 30B recipe; Llama-Embed-Nemotron-8B training. - -### Logging and Observability - -- MLflow integration. -- Metric logger with JSONL output. -- YAML logging-to-stdout improvements. - -### Workflow - -- Knowledge-distillation custom validation step; `ScopedModuleOffloading` to - reduce memory. -- Model Registry component. -- SIGTERM handling. -- `NEMO_ENABLE_USER_MODULES` for user-extension modules. -- Rank-0 download for custom models. -- Dereference env vars in YAML. - ---- - -## 0.1.2 (2025-10-23) · [PyPI](https://pypi.org/project/nemo-automodel/0.1.2/) · [GH](https://github.com/NVIDIA-NeMo/Automodel/releases/tag/v0.1.2) - -Patch release. - -- **Fix:** `max_steps` now set inside the constructor (#650). -- **Fix:** step scheduler switched to zero-based indexing (#627). -- **Fix:** sample-limit handling for `ColumnMapped` datasets (#521). - ---- - -## 0.1.0 (2025-10-08) · [PyPI](https://pypi.org/project/nemo-automodel/0.1.0/) · [GH](https://github.com/NVIDIA-NeMo/Automodel/releases/tag/v0.1.0) - -Initial public release of NeMo AutoModel. - -### Highlights - -- PyTorch-native training framework for LLMs and VLMs with Hugging Face - Transformers integration via `NeMoAuto*` wrapper classes. -- YAML-driven recipes for SFT and PEFT. -- FSDP2 / HSDP / DDP distributed training with DTensor sharding. -- Megatron-FSDP available as the default heavy-duty sharding option (replaces - the earlier nvFSDP path). -- Knowledge distillation recipe. -- MoE component with DeepSeek v3 model implementation. -- `ColumnMappedTextInstructionDataset` for instruction tuning. -- Gradient checkpointing. -- SLURM launcher. - ---- - -For the list of newly supported models per release, see the -[Model Coverage Release Log](/model-coverage/release-log). diff --git a/docs/fern/versions/nightly/pages/repository-structure.mdx b/docs/fern/versions/nightly/pages/repository-structure.mdx deleted file mode 100644 index d4679fd299..0000000000 --- a/docs/fern/versions/nightly/pages/repository-structure.mdx +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: "Repository Structure" -description: "" -position: 6 ---- -This introductory guide presents the structure of the NeMo AutoModel repository, provides a brief overview of its parts, introduces concepts such as components and recipes, and explains how everything fits together. - -## What is NeMo AutoModel? -NeMo AutoModel is a PyTorch library for fine-tuning and pretraining large-scale models. In particular, it provides: -- **Optimized implementations** for training efficiency, including fused kernels and memory-saving techniques. -- [**Day-0 support**](/model-coverage/overview) for LLMs and VLMs available on the Hugging Face Hub. -- **Seamless integration** with Hugging Face datasets, tokenizers, and related tools. -- **Distributed training strategies** using FSDP2 and MegatronFSDP across multi-GPU and multi-node environments. -- **End-to-end workflows** with recipes for data preparation, training, and evaluation. - -## Repository Structure -The AutoModel source code is available under the [`nemo_automodel`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/nemo_automodel) directory. It is organized into three directories: -- [`components/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/nemo_automodel/components) - Self-contained modules -- [`recipes/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/nemo_automodel/recipes) - End-to-end training workflows -- [`cli/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/nemo_automodel/cli) - CLI entry-point and job launcher dispatch. - -### Components Directory -The `components/` directory contains isolated modules used in training loops. -Each component is designed to be dependency-light and reusable without cross-module imports. - -#### Directory Structure -The following directory listing shows all components along with explanations of their contents. -``` -$ tree -L 1 nemo_automodel/components/ - -├── _peft/ - Implementations of PEFT methods, such as LoRA. -├── attention/ - Efficient attention modules and related utilities (e.g., flash attention, rotary embeddings). -├── checkpoint/ - Checkpoint save and load-related logic. -├── config/ - Utils to load YAML files and CLI-parsing helpers. -├── datasets/ - LLM and VLM datasets and utils (collate functions, preprocessing). -├── distributed/ - Distributed processing primitives (DDP, FSDP2, MegatronFSDP) and pipeline parallelism (AutoPipeline). -├── launcher/ - Job launcher for interactive and batch (Slurm, K8s) processing. -├── loggers/ - Metric/event logging for Weights & Biases and other tools. -├── loss/ - Loss functions (such as cross-entropy and linear cross-entropy, etc.). -├── models/ - Optimized model implementations for LLMs and VLMs. -├── moe/ - Mixture of Experts modules and routing utilities for scalable model architectures. -├── optim/ - Optimizers and LR schedulers, including fused or second-order variants. -├── quantization/ - Quantization layers and helpers for 4-bit/8-bit or other reduced-precision training and inference. -├── training/ - Training and fine-tuning utils. -└── utils/ - Small, dependency-free helpers (seed, profiler, timing, fs). -``` - -#### Key Features -- Each component can be used independently in other projects. -- Each component has its own dependencies, without cross-module imports. -- Unit tests are colocated with the component they cover. - -### Recipes Directory -Recipes define **end-to-end workflows** (data and model loading → training with custom loop → saving the output checkpoint) -for a variety of tasks, such as training, fine-tuning, and knowledge distillation. - -#### Available Recipes -The following directory listing shows all components along with explanations of their contents. -``` -$ tree -L 2 nemo_automodel/recipes/ -├── llm -│   ├── benchmark.py - Benchmark recipe for LLMs -│   ├── kd.py - Knowledge Distillation for LLMs -│   └── train_ft.py - Train recipe for LLMs (Pretrain & Finetune SFT, PEFT). -└── vlm - └── finetune.py - Finetune recipe for VLMs (SFT, PEFT). -``` - -#### Run a Recipe - -Recipes are launched via the `automodel` CLI: -```bash -automodel --nproc-per-node 2 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -The above command will fine-tune the Llama3.2-1B model on the SQuAD dataset with two GPUs using the [`llama3_2_1b_squad.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml) config. -For a single-GPU run, omit `--nproc-per-node`: -```bash -automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml -``` - -Each recipe imports the components it needs from the `nemo_automodel/components/` catalog. -The recipe/components structure enables you to: -- Decouple individual components and replace them with custom implementations when needed. -- Avoid rigid, class-based trainer structures by using linear scripts that expose training logic for maximum flexibility and control. - -{/* For an in-depth explanation of the LLM recipe please also see the [LLM recipe deep-dive guide](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/llm_recipe_deep_dive). */} - -#### Configure a Recipe -An example YAML configuration is shown below. The complete config is available [here](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml): -```yaml -step_scheduler: - grad_acc_steps: 4 - ckpt_every_steps: 1000 - val_every_steps: 10 # will run every x number of gradient steps - num_epochs: 1 - -model: - _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_pretrained - pretrained_model_name_or_path: meta-llama/Llama-3.2-1B - -dataset: - _target_: nemo_automodel.components.datasets.llm.squad.make_squad_dataset - dataset_name: rajpurkar/squad - split: train -``` - -More recipe examples are available under the [`examples/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples) directory. - -### CLI Directory (`cli/`) -The `automodel` (or `am`) CLI application simplifies job execution across different environments, from -single-GPU interactive sessions to batch multi-node runs. It supports interactive (local), SLURM, -SkyPilot, and NeMo-Run launchers. The CLI lives at the repository root in the -`cli/` package, separate from the core `nemo_automodel` library. - -## Next Steps - -Learn how to train models with NeMo AutoModel on: -- **Your local workstation**: See [`docs/launcher/local-workstation.md`](/job-launchers/local-workstation). -- **A cluster**: See [`docs/launcher/slurm.md`](/job-launchers/slurm-cluster). diff --git a/docs/guides/audio/qwen3-omni-asr.md b/docs/guides/audio/qwen3-omni-asr.mdx similarity index 100% rename from docs/guides/audio/qwen3-omni-asr.md rename to docs/guides/audio/qwen3-omni-asr.mdx diff --git a/docs/guides/checkpointing.md b/docs/guides/checkpointing.mdx similarity index 100% rename from docs/guides/checkpointing.md rename to docs/guides/checkpointing.mdx diff --git a/docs/guides/configuration.md b/docs/guides/configuration.mdx similarity index 100% rename from docs/guides/configuration.md rename to docs/guides/configuration.mdx diff --git a/docs/guides/dataset-overview.md b/docs/guides/dataset-overview.mdx similarity index 100% rename from docs/guides/dataset-overview.md rename to docs/guides/dataset-overview.mdx diff --git a/docs/guides/diffusion/dataset.md b/docs/guides/diffusion/dataset.mdx similarity index 100% rename from docs/guides/diffusion/dataset.md rename to docs/guides/diffusion/dataset.mdx diff --git a/docs/guides/diffusion/finetune.md b/docs/guides/diffusion/finetune.mdx similarity index 100% rename from docs/guides/diffusion/finetune.md rename to docs/guides/diffusion/finetune.mdx diff --git a/docs/guides/dllm/finetune.md b/docs/guides/dllm/finetune.mdx similarity index 100% rename from docs/guides/dllm/finetune.md rename to docs/guides/dllm/finetune.mdx diff --git a/docs/guides/fp8-training.md b/docs/guides/fp8-training.mdx similarity index 100% rename from docs/guides/fp8-training.md rename to docs/guides/fp8-training.mdx diff --git a/docs/guides/gradient-checkpointing.md b/docs/guides/gradient-checkpointing.mdx similarity index 100% rename from docs/guides/gradient-checkpointing.md rename to docs/guides/gradient-checkpointing.mdx diff --git a/docs/guides/huggingface-api-compatibility.md b/docs/guides/huggingface-api-compatibility.mdx similarity index 100% rename from docs/guides/huggingface-api-compatibility.md rename to docs/guides/huggingface-api-compatibility.mdx diff --git a/docs/guides/installation.md b/docs/guides/installation.mdx similarity index 100% rename from docs/guides/installation.md rename to docs/guides/installation.mdx diff --git a/docs/guides/llm/column-mapped-text-instruction-dataset.md b/docs/guides/llm/column-mapped-text-instruction-dataset.mdx similarity index 100% rename from docs/guides/llm/column-mapped-text-instruction-dataset.md rename to docs/guides/llm/column-mapped-text-instruction-dataset.mdx diff --git a/docs/guides/llm/column-mapped-text-instruction-iterable-dataset.md b/docs/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx similarity index 100% rename from docs/guides/llm/column-mapped-text-instruction-iterable-dataset.md rename to docs/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx diff --git a/docs/guides/llm/databricks.md b/docs/guides/llm/databricks.mdx similarity index 100% rename from docs/guides/llm/databricks.md rename to docs/guides/llm/databricks.mdx diff --git a/docs/guides/llm/dataset.md b/docs/guides/llm/dataset.mdx similarity index 100% rename from docs/guides/llm/dataset.md rename to docs/guides/llm/dataset.mdx diff --git a/docs/guides/llm/dsv4-flash.md b/docs/guides/llm/dsv4-flash.mdx similarity index 100% rename from docs/guides/llm/dsv4-flash.md rename to docs/guides/llm/dsv4-flash.mdx diff --git a/docs/guides/llm/finetune.md b/docs/guides/llm/finetune.mdx similarity index 100% rename from docs/guides/llm/finetune.md rename to docs/guides/llm/finetune.mdx diff --git a/docs/guides/llm/hy3.md b/docs/guides/llm/hy3.mdx similarity index 100% rename from docs/guides/llm/hy3.md rename to docs/guides/llm/hy3.mdx diff --git a/docs/guides/llm/knowledge-distillation.md b/docs/guides/llm/knowledge-distillation.mdx similarity index 100% rename from docs/guides/llm/knowledge-distillation.md rename to docs/guides/llm/knowledge-distillation.mdx diff --git a/docs/guides/llm/large-moe-finetune.md b/docs/guides/llm/large-moe-finetune.mdx similarity index 100% rename from docs/guides/llm/large-moe-finetune.md rename to docs/guides/llm/large-moe-finetune.mdx diff --git a/docs/guides/llm/nanogpt-pretraining.md b/docs/guides/llm/nanogpt-pretraining.mdx similarity index 100% rename from docs/guides/llm/nanogpt-pretraining.md rename to docs/guides/llm/nanogpt-pretraining.mdx diff --git a/docs/guides/llm/pretraining.md b/docs/guides/llm/pretraining.mdx similarity index 100% rename from docs/guides/llm/pretraining.md rename to docs/guides/llm/pretraining.mdx diff --git a/docs/guides/llm/retrieval-dataset.md b/docs/guides/llm/retrieval-dataset.mdx similarity index 100% rename from docs/guides/llm/retrieval-dataset.md rename to docs/guides/llm/retrieval-dataset.mdx diff --git a/docs/guides/llm/sequence-classification.md b/docs/guides/llm/sequence-classification.mdx similarity index 100% rename from docs/guides/llm/sequence-classification.md rename to docs/guides/llm/sequence-classification.mdx diff --git a/docs/guides/llm/toolcalling.md b/docs/guides/llm/toolcalling.mdx similarity index 100% rename from docs/guides/llm/toolcalling.md rename to docs/guides/llm/toolcalling.mdx diff --git a/docs/guides/mlflow-logging.md b/docs/guides/mlflow-logging.mdx similarity index 100% rename from docs/guides/mlflow-logging.md rename to docs/guides/mlflow-logging.mdx diff --git a/docs/guides/omni/gemma3-3n.md b/docs/guides/omni/gemma3-3n.mdx similarity index 100% rename from docs/guides/omni/gemma3-3n.md rename to docs/guides/omni/gemma3-3n.mdx diff --git a/docs/guides/overview.md b/docs/guides/overview.mdx similarity index 100% rename from docs/guides/overview.md rename to docs/guides/overview.mdx diff --git a/docs/guides/pipelining.md b/docs/guides/pipelining.mdx similarity index 100% rename from docs/guides/pipelining.md rename to docs/guides/pipelining.mdx diff --git a/docs/guides/quantization-aware-training.md b/docs/guides/quantization-aware-training.mdx similarity index 100% rename from docs/guides/quantization-aware-training.md rename to docs/guides/quantization-aware-training.mdx diff --git a/docs/guides/vlm/dataset.md b/docs/guides/vlm/dataset.mdx similarity index 100% rename from docs/guides/vlm/dataset.md rename to docs/guides/vlm/dataset.mdx diff --git a/docs/guides/vlm/gemma4.md b/docs/guides/vlm/gemma4.mdx similarity index 100% rename from docs/guides/vlm/gemma4.md rename to docs/guides/vlm/gemma4.mdx diff --git a/docs/guides/vlm/mistral-medium-3-5.md b/docs/guides/vlm/mistral-medium-3-5.mdx similarity index 100% rename from docs/guides/vlm/mistral-medium-3-5.md rename to docs/guides/vlm/mistral-medium-3-5.mdx diff --git a/docs/guides/vlm/nemotron-omni.md b/docs/guides/vlm/nemotron-omni.mdx similarity index 100% rename from docs/guides/vlm/nemotron-omni.md rename to docs/guides/vlm/nemotron-omni.mdx diff --git a/docs/guides/vlm/qwen3-5.md b/docs/guides/vlm/qwen3-5.mdx similarity index 100% rename from docs/guides/vlm/qwen3-5.md rename to docs/guides/vlm/qwen3-5.mdx diff --git a/docs/index.md b/docs/index.mdx similarity index 100% rename from docs/index.md rename to docs/index.mdx diff --git a/docs/launcher/local-workstation.md b/docs/launcher/local-workstation.mdx similarity index 100% rename from docs/launcher/local-workstation.md rename to docs/launcher/local-workstation.mdx diff --git a/docs/launcher/nemo-run.md b/docs/launcher/nemo-run.mdx similarity index 100% rename from docs/launcher/nemo-run.md rename to docs/launcher/nemo-run.mdx diff --git a/docs/launcher/overview.md b/docs/launcher/overview.mdx similarity index 100% rename from docs/launcher/overview.md rename to docs/launcher/overview.mdx diff --git a/docs/launcher/skypilot-kubernetes.md b/docs/launcher/skypilot-kubernetes.mdx similarity index 100% rename from docs/launcher/skypilot-kubernetes.md rename to docs/launcher/skypilot-kubernetes.mdx diff --git a/docs/launcher/skypilot.md b/docs/launcher/skypilot.mdx similarity index 100% rename from docs/launcher/skypilot.md rename to docs/launcher/skypilot.mdx diff --git a/docs/launcher/slurm.md b/docs/launcher/slurm.mdx similarity index 100% rename from docs/launcher/slurm.md rename to docs/launcher/slurm.mdx diff --git a/docs/model-coverage/diffusion/black-forest-labs/flux.md b/docs/model-coverage/diffusion/black-forest-labs/flux.mdx similarity index 100% rename from docs/model-coverage/diffusion/black-forest-labs/flux.md rename to docs/model-coverage/diffusion/black-forest-labs/flux.mdx diff --git a/docs/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.md b/docs/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx similarity index 100% rename from docs/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.md rename to docs/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx diff --git a/docs/model-coverage/diffusion/index.md b/docs/model-coverage/diffusion/index.mdx similarity index 100% rename from docs/model-coverage/diffusion/index.md rename to docs/model-coverage/diffusion/index.mdx diff --git a/docs/model-coverage/diffusion/qwen/qwen-image.md b/docs/model-coverage/diffusion/qwen/qwen-image.mdx similarity index 100% rename from docs/model-coverage/diffusion/qwen/qwen-image.md rename to docs/model-coverage/diffusion/qwen/qwen-image.mdx diff --git a/docs/model-coverage/diffusion/wan-ai/wan2-1-t2v.md b/docs/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx similarity index 100% rename from docs/model-coverage/diffusion/wan-ai/wan2-1-t2v.md rename to docs/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx diff --git a/docs/model-coverage/embedding/index.md b/docs/model-coverage/embedding/index.mdx similarity index 100% rename from docs/model-coverage/embedding/index.md rename to docs/model-coverage/embedding/index.mdx diff --git a/docs/model-coverage/embedding/mistralai/ministral3-bidirectional.md b/docs/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx similarity index 100% rename from docs/model-coverage/embedding/mistralai/ministral3-bidirectional.md rename to docs/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx diff --git a/docs/model-coverage/embedding/nvidia/llama-bidirectional.md b/docs/model-coverage/embedding/nvidia/llama-bidirectional.mdx similarity index 100% rename from docs/model-coverage/embedding/nvidia/llama-bidirectional.md rename to docs/model-coverage/embedding/nvidia/llama-bidirectional.mdx diff --git a/docs/model-coverage/latest-models.md b/docs/model-coverage/latest-models.mdx similarity index 100% rename from docs/model-coverage/latest-models.md rename to docs/model-coverage/latest-models.mdx diff --git a/docs/model-coverage/llm/allenai/olmo.md b/docs/model-coverage/llm/allenai/olmo.mdx similarity index 100% rename from docs/model-coverage/llm/allenai/olmo.md rename to docs/model-coverage/llm/allenai/olmo.mdx diff --git a/docs/model-coverage/llm/allenai/olmo2.md b/docs/model-coverage/llm/allenai/olmo2.mdx similarity index 100% rename from docs/model-coverage/llm/allenai/olmo2.md rename to docs/model-coverage/llm/allenai/olmo2.mdx diff --git a/docs/model-coverage/llm/allenai/olmoe.md b/docs/model-coverage/llm/allenai/olmoe.mdx similarity index 100% rename from docs/model-coverage/llm/allenai/olmoe.md rename to docs/model-coverage/llm/allenai/olmoe.mdx diff --git a/docs/model-coverage/llm/baai/aquila.md b/docs/model-coverage/llm/baai/aquila.mdx similarity index 100% rename from docs/model-coverage/llm/baai/aquila.md rename to docs/model-coverage/llm/baai/aquila.mdx diff --git a/docs/model-coverage/llm/baichuan-inc/baichuan.md b/docs/model-coverage/llm/baichuan-inc/baichuan.mdx similarity index 100% rename from docs/model-coverage/llm/baichuan-inc/baichuan.md rename to docs/model-coverage/llm/baichuan-inc/baichuan.mdx diff --git a/docs/model-coverage/llm/baidu/ernie4-5.md b/docs/model-coverage/llm/baidu/ernie4-5.mdx similarity index 100% rename from docs/model-coverage/llm/baidu/ernie4-5.md rename to docs/model-coverage/llm/baidu/ernie4-5.mdx diff --git a/docs/model-coverage/llm/bigcode/starcoder.md b/docs/model-coverage/llm/bigcode/starcoder.mdx similarity index 100% rename from docs/model-coverage/llm/bigcode/starcoder.md rename to docs/model-coverage/llm/bigcode/starcoder.mdx diff --git a/docs/model-coverage/llm/bigcode/starcoder2.md b/docs/model-coverage/llm/bigcode/starcoder2.mdx similarity index 100% rename from docs/model-coverage/llm/bigcode/starcoder2.md rename to docs/model-coverage/llm/bigcode/starcoder2.mdx diff --git a/docs/model-coverage/llm/bytedance-seed/seed.md b/docs/model-coverage/llm/bytedance-seed/seed.mdx similarity index 100% rename from docs/model-coverage/llm/bytedance-seed/seed.md rename to docs/model-coverage/llm/bytedance-seed/seed.mdx diff --git a/docs/model-coverage/llm/cohere/command-r.md b/docs/model-coverage/llm/cohere/command-r.mdx similarity index 100% rename from docs/model-coverage/llm/cohere/command-r.md rename to docs/model-coverage/llm/cohere/command-r.mdx diff --git a/docs/model-coverage/llm/deepseek-ai/deepseek-v3.md b/docs/model-coverage/llm/deepseek-ai/deepseek-v3.mdx similarity index 100% rename from docs/model-coverage/llm/deepseek-ai/deepseek-v3.md rename to docs/model-coverage/llm/deepseek-ai/deepseek-v3.mdx diff --git a/docs/model-coverage/llm/deepseek-ai/deepseek.md b/docs/model-coverage/llm/deepseek-ai/deepseek.mdx similarity index 100% rename from docs/model-coverage/llm/deepseek-ai/deepseek.md rename to docs/model-coverage/llm/deepseek-ai/deepseek.mdx diff --git a/docs/model-coverage/llm/deepseek-ai/dsv4-flash.md b/docs/model-coverage/llm/deepseek-ai/dsv4-flash.mdx similarity index 100% rename from docs/model-coverage/llm/deepseek-ai/dsv4-flash.md rename to docs/model-coverage/llm/deepseek-ai/dsv4-flash.mdx diff --git a/docs/model-coverage/llm/eleutherai/gpt-j.md b/docs/model-coverage/llm/eleutherai/gpt-j.mdx similarity index 100% rename from docs/model-coverage/llm/eleutherai/gpt-j.md rename to docs/model-coverage/llm/eleutherai/gpt-j.mdx diff --git a/docs/model-coverage/llm/eleutherai/gpt-neox.md b/docs/model-coverage/llm/eleutherai/gpt-neox.mdx similarity index 100% rename from docs/model-coverage/llm/eleutherai/gpt-neox.md rename to docs/model-coverage/llm/eleutherai/gpt-neox.mdx diff --git a/docs/model-coverage/llm/google/gemma.md b/docs/model-coverage/llm/google/gemma.mdx similarity index 100% rename from docs/model-coverage/llm/google/gemma.md rename to docs/model-coverage/llm/google/gemma.mdx diff --git a/docs/model-coverage/llm/ibm/bamba.md b/docs/model-coverage/llm/ibm/bamba.mdx similarity index 100% rename from docs/model-coverage/llm/ibm/bamba.md rename to docs/model-coverage/llm/ibm/bamba.mdx diff --git a/docs/model-coverage/llm/ibm/granite-moe.md b/docs/model-coverage/llm/ibm/granite-moe.mdx similarity index 100% rename from docs/model-coverage/llm/ibm/granite-moe.md rename to docs/model-coverage/llm/ibm/granite-moe.mdx diff --git a/docs/model-coverage/llm/ibm/granite.md b/docs/model-coverage/llm/ibm/granite.mdx similarity index 100% rename from docs/model-coverage/llm/ibm/granite.md rename to docs/model-coverage/llm/ibm/granite.mdx diff --git a/docs/model-coverage/llm/inceptionai/jais.md b/docs/model-coverage/llm/inceptionai/jais.mdx similarity index 100% rename from docs/model-coverage/llm/inceptionai/jais.md rename to docs/model-coverage/llm/inceptionai/jais.mdx diff --git a/docs/model-coverage/llm/inclusionai/ling-2.md b/docs/model-coverage/llm/inclusionai/ling-2.mdx similarity index 100% rename from docs/model-coverage/llm/inclusionai/ling-2.md rename to docs/model-coverage/llm/inclusionai/ling-2.mdx diff --git a/docs/model-coverage/llm/index.md b/docs/model-coverage/llm/index.mdx similarity index 100% rename from docs/model-coverage/llm/index.md rename to docs/model-coverage/llm/index.mdx diff --git a/docs/model-coverage/llm/internlm/internlm.md b/docs/model-coverage/llm/internlm/internlm.mdx similarity index 100% rename from docs/model-coverage/llm/internlm/internlm.md rename to docs/model-coverage/llm/internlm/internlm.mdx diff --git a/docs/model-coverage/llm/lgai-exaone/exaone.md b/docs/model-coverage/llm/lgai-exaone/exaone.mdx similarity index 100% rename from docs/model-coverage/llm/lgai-exaone/exaone.md rename to docs/model-coverage/llm/lgai-exaone/exaone.mdx diff --git a/docs/model-coverage/llm/meta/llama.md b/docs/model-coverage/llm/meta/llama.mdx similarity index 100% rename from docs/model-coverage/llm/meta/llama.md rename to docs/model-coverage/llm/meta/llama.mdx diff --git a/docs/model-coverage/llm/microsoft/phi.md b/docs/model-coverage/llm/microsoft/phi.mdx similarity index 100% rename from docs/model-coverage/llm/microsoft/phi.md rename to docs/model-coverage/llm/microsoft/phi.mdx diff --git a/docs/model-coverage/llm/microsoft/phi3-small.md b/docs/model-coverage/llm/microsoft/phi3-small.mdx similarity index 100% rename from docs/model-coverage/llm/microsoft/phi3-small.md rename to docs/model-coverage/llm/microsoft/phi3-small.mdx diff --git a/docs/model-coverage/llm/microsoft/phi3.md b/docs/model-coverage/llm/microsoft/phi3.mdx similarity index 100% rename from docs/model-coverage/llm/microsoft/phi3.md rename to docs/model-coverage/llm/microsoft/phi3.mdx diff --git a/docs/model-coverage/llm/minimax/minimax-m2.md b/docs/model-coverage/llm/minimax/minimax-m2.mdx similarity index 100% rename from docs/model-coverage/llm/minimax/minimax-m2.md rename to docs/model-coverage/llm/minimax/minimax-m2.mdx diff --git a/docs/model-coverage/llm/mistralai/ministral3.md b/docs/model-coverage/llm/mistralai/ministral3.mdx similarity index 100% rename from docs/model-coverage/llm/mistralai/ministral3.md rename to docs/model-coverage/llm/mistralai/ministral3.mdx diff --git a/docs/model-coverage/llm/mistralai/mistral.md b/docs/model-coverage/llm/mistralai/mistral.mdx similarity index 100% rename from docs/model-coverage/llm/mistralai/mistral.md rename to docs/model-coverage/llm/mistralai/mistral.mdx diff --git a/docs/model-coverage/llm/mistralai/mixtral.md b/docs/model-coverage/llm/mistralai/mixtral.mdx similarity index 100% rename from docs/model-coverage/llm/mistralai/mixtral.md rename to docs/model-coverage/llm/mistralai/mixtral.mdx diff --git a/docs/model-coverage/llm/moonshotai/moonlight.md b/docs/model-coverage/llm/moonshotai/moonlight.mdx similarity index 100% rename from docs/model-coverage/llm/moonshotai/moonlight.md rename to docs/model-coverage/llm/moonshotai/moonlight.mdx diff --git a/docs/model-coverage/llm/nvidia/nemotron-flash.md b/docs/model-coverage/llm/nvidia/nemotron-flash.mdx similarity index 100% rename from docs/model-coverage/llm/nvidia/nemotron-flash.md rename to docs/model-coverage/llm/nvidia/nemotron-flash.mdx diff --git a/docs/model-coverage/llm/nvidia/nemotron-h.md b/docs/model-coverage/llm/nvidia/nemotron-h.mdx similarity index 100% rename from docs/model-coverage/llm/nvidia/nemotron-h.md rename to docs/model-coverage/llm/nvidia/nemotron-h.mdx diff --git a/docs/model-coverage/llm/nvidia/nemotron-super.md b/docs/model-coverage/llm/nvidia/nemotron-super.mdx similarity index 100% rename from docs/model-coverage/llm/nvidia/nemotron-super.md rename to docs/model-coverage/llm/nvidia/nemotron-super.mdx diff --git a/docs/model-coverage/llm/nvidia/nemotron.md b/docs/model-coverage/llm/nvidia/nemotron.mdx similarity index 100% rename from docs/model-coverage/llm/nvidia/nemotron.md rename to docs/model-coverage/llm/nvidia/nemotron.mdx diff --git a/docs/model-coverage/llm/openai/gpt-oss.md b/docs/model-coverage/llm/openai/gpt-oss.mdx similarity index 100% rename from docs/model-coverage/llm/openai/gpt-oss.md rename to docs/model-coverage/llm/openai/gpt-oss.mdx diff --git a/docs/model-coverage/llm/openai/gpt2.md b/docs/model-coverage/llm/openai/gpt2.mdx similarity index 100% rename from docs/model-coverage/llm/openai/gpt2.md rename to docs/model-coverage/llm/openai/gpt2.mdx diff --git a/docs/model-coverage/llm/openbmb/minicpm.md b/docs/model-coverage/llm/openbmb/minicpm.mdx similarity index 100% rename from docs/model-coverage/llm/openbmb/minicpm.md rename to docs/model-coverage/llm/openbmb/minicpm.mdx diff --git a/docs/model-coverage/llm/orionstar/orion.md b/docs/model-coverage/llm/orionstar/orion.mdx similarity index 100% rename from docs/model-coverage/llm/orionstar/orion.md rename to docs/model-coverage/llm/orionstar/orion.mdx diff --git a/docs/model-coverage/llm/parasail-ai/gritlm.md b/docs/model-coverage/llm/parasail-ai/gritlm.mdx similarity index 100% rename from docs/model-coverage/llm/parasail-ai/gritlm.md rename to docs/model-coverage/llm/parasail-ai/gritlm.mdx diff --git a/docs/model-coverage/llm/qwen/qwen2-moe.md b/docs/model-coverage/llm/qwen/qwen2-moe.mdx similarity index 100% rename from docs/model-coverage/llm/qwen/qwen2-moe.md rename to docs/model-coverage/llm/qwen/qwen2-moe.mdx diff --git a/docs/model-coverage/llm/qwen/qwen2.md b/docs/model-coverage/llm/qwen/qwen2.mdx similarity index 100% rename from docs/model-coverage/llm/qwen/qwen2.md rename to docs/model-coverage/llm/qwen/qwen2.mdx diff --git a/docs/model-coverage/llm/qwen/qwen3-moe.md b/docs/model-coverage/llm/qwen/qwen3-moe.mdx similarity index 100% rename from docs/model-coverage/llm/qwen/qwen3-moe.md rename to docs/model-coverage/llm/qwen/qwen3-moe.mdx diff --git a/docs/model-coverage/llm/qwen/qwen3-next.md b/docs/model-coverage/llm/qwen/qwen3-next.mdx similarity index 100% rename from docs/model-coverage/llm/qwen/qwen3-next.md rename to docs/model-coverage/llm/qwen/qwen3-next.mdx diff --git a/docs/model-coverage/llm/qwen/qwen3.md b/docs/model-coverage/llm/qwen/qwen3.mdx similarity index 100% rename from docs/model-coverage/llm/qwen/qwen3.md rename to docs/model-coverage/llm/qwen/qwen3.mdx diff --git a/docs/model-coverage/llm/stabilityai/stablelm.md b/docs/model-coverage/llm/stabilityai/stablelm.mdx similarity index 100% rename from docs/model-coverage/llm/stabilityai/stablelm.md rename to docs/model-coverage/llm/stabilityai/stablelm.mdx diff --git a/docs/model-coverage/llm/stepfun-ai/step-3-5.md b/docs/model-coverage/llm/stepfun-ai/step-3-5.mdx similarity index 100% rename from docs/model-coverage/llm/stepfun-ai/step-3-5.md rename to docs/model-coverage/llm/stepfun-ai/step-3-5.mdx diff --git a/docs/model-coverage/llm/tencent/hy3.md b/docs/model-coverage/llm/tencent/hy3.mdx similarity index 100% rename from docs/model-coverage/llm/tencent/hy3.md rename to docs/model-coverage/llm/tencent/hy3.mdx diff --git a/docs/model-coverage/llm/thudm/chatglm.md b/docs/model-coverage/llm/thudm/chatglm.mdx similarity index 100% rename from docs/model-coverage/llm/thudm/chatglm.md rename to docs/model-coverage/llm/thudm/chatglm.mdx diff --git a/docs/model-coverage/llm/thudm/glm4-moe.md b/docs/model-coverage/llm/thudm/glm4-moe.mdx similarity index 100% rename from docs/model-coverage/llm/thudm/glm4-moe.md rename to docs/model-coverage/llm/thudm/glm4-moe.mdx diff --git a/docs/model-coverage/llm/thudm/glm4.md b/docs/model-coverage/llm/thudm/glm4.mdx similarity index 100% rename from docs/model-coverage/llm/thudm/glm4.md rename to docs/model-coverage/llm/thudm/glm4.mdx diff --git a/docs/model-coverage/llm/thudm/glm5-moe-dsa.md b/docs/model-coverage/llm/thudm/glm5-moe-dsa.mdx similarity index 100% rename from docs/model-coverage/llm/thudm/glm5-moe-dsa.md rename to docs/model-coverage/llm/thudm/glm5-moe-dsa.mdx diff --git a/docs/model-coverage/llm/tiiuae/falcon.md b/docs/model-coverage/llm/tiiuae/falcon.mdx similarity index 100% rename from docs/model-coverage/llm/tiiuae/falcon.md rename to docs/model-coverage/llm/tiiuae/falcon.mdx diff --git a/docs/model-coverage/llm/upstage/solar.md b/docs/model-coverage/llm/upstage/solar.mdx similarity index 100% rename from docs/model-coverage/llm/upstage/solar.md rename to docs/model-coverage/llm/upstage/solar.mdx diff --git a/docs/model-coverage/llm/xiaomimimo/mimo-v2-flash.md b/docs/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx similarity index 100% rename from docs/model-coverage/llm/xiaomimimo/mimo-v2-flash.md rename to docs/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx diff --git a/docs/model-coverage/omni/index.md b/docs/model-coverage/omni/index.mdx similarity index 100% rename from docs/model-coverage/omni/index.md rename to docs/model-coverage/omni/index.mdx diff --git a/docs/model-coverage/omni/microsoft/phi4-multimodal.md b/docs/model-coverage/omni/microsoft/phi4-multimodal.mdx similarity index 100% rename from docs/model-coverage/omni/microsoft/phi4-multimodal.md rename to docs/model-coverage/omni/microsoft/phi4-multimodal.mdx diff --git a/docs/model-coverage/omni/nvidia/nemotron-omni.md b/docs/model-coverage/omni/nvidia/nemotron-omni.mdx similarity index 100% rename from docs/model-coverage/omni/nvidia/nemotron-omni.md rename to docs/model-coverage/omni/nvidia/nemotron-omni.mdx diff --git a/docs/model-coverage/omni/qwen/qwen3-omni.md b/docs/model-coverage/omni/qwen/qwen3-omni.mdx similarity index 100% rename from docs/model-coverage/omni/qwen/qwen3-omni.md rename to docs/model-coverage/omni/qwen/qwen3-omni.mdx diff --git a/docs/model-coverage/overview.md b/docs/model-coverage/overview.mdx similarity index 100% rename from docs/model-coverage/overview.md rename to docs/model-coverage/overview.mdx diff --git a/docs/model-coverage/reranker/index.md b/docs/model-coverage/reranker/index.mdx similarity index 100% rename from docs/model-coverage/reranker/index.md rename to docs/model-coverage/reranker/index.mdx diff --git a/docs/model-coverage/reranker/nvidia/llama-bidirectional.md b/docs/model-coverage/reranker/nvidia/llama-bidirectional.mdx similarity index 100% rename from docs/model-coverage/reranker/nvidia/llama-bidirectional.md rename to docs/model-coverage/reranker/nvidia/llama-bidirectional.mdx diff --git a/docs/model-coverage/troubleshooting.md b/docs/model-coverage/troubleshooting.mdx similarity index 100% rename from docs/model-coverage/troubleshooting.md rename to docs/model-coverage/troubleshooting.mdx diff --git a/docs/model-coverage/vlm/google/gemma3-vl.md b/docs/model-coverage/vlm/google/gemma3-vl.mdx similarity index 100% rename from docs/model-coverage/vlm/google/gemma3-vl.md rename to docs/model-coverage/vlm/google/gemma3-vl.mdx diff --git a/docs/model-coverage/vlm/google/gemma4.md b/docs/model-coverage/vlm/google/gemma4.mdx similarity index 100% rename from docs/model-coverage/vlm/google/gemma4.md rename to docs/model-coverage/vlm/google/gemma4.mdx diff --git a/docs/model-coverage/vlm/huggingface/smolvlm.md b/docs/model-coverage/vlm/huggingface/smolvlm.mdx similarity index 100% rename from docs/model-coverage/vlm/huggingface/smolvlm.md rename to docs/model-coverage/vlm/huggingface/smolvlm.mdx diff --git a/docs/model-coverage/vlm/index.md b/docs/model-coverage/vlm/index.mdx similarity index 100% rename from docs/model-coverage/vlm/index.md rename to docs/model-coverage/vlm/index.mdx diff --git a/docs/model-coverage/vlm/internlm/internvl.md b/docs/model-coverage/vlm/internlm/internvl.mdx similarity index 100% rename from docs/model-coverage/vlm/internlm/internvl.md rename to docs/model-coverage/vlm/internlm/internvl.mdx diff --git a/docs/model-coverage/vlm/llava-hf/llava.md b/docs/model-coverage/vlm/llava-hf/llava.mdx similarity index 100% rename from docs/model-coverage/vlm/llava-hf/llava.md rename to docs/model-coverage/vlm/llava-hf/llava.mdx diff --git a/docs/model-coverage/vlm/lmms-lab/llava-onevision.md b/docs/model-coverage/vlm/lmms-lab/llava-onevision.mdx similarity index 100% rename from docs/model-coverage/vlm/lmms-lab/llava-onevision.md rename to docs/model-coverage/vlm/lmms-lab/llava-onevision.mdx diff --git a/docs/model-coverage/vlm/meta/llama4.md b/docs/model-coverage/vlm/meta/llama4.mdx similarity index 100% rename from docs/model-coverage/vlm/meta/llama4.md rename to docs/model-coverage/vlm/meta/llama4.mdx diff --git a/docs/model-coverage/vlm/mistralai/ministral3-vl.md b/docs/model-coverage/vlm/mistralai/ministral3-vl.mdx similarity index 100% rename from docs/model-coverage/vlm/mistralai/ministral3-vl.md rename to docs/model-coverage/vlm/mistralai/ministral3-vl.mdx diff --git a/docs/model-coverage/vlm/mistralai/mistral-medium-3-5.md b/docs/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx similarity index 100% rename from docs/model-coverage/vlm/mistralai/mistral-medium-3-5.md rename to docs/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx diff --git a/docs/model-coverage/vlm/mistralai/mistral-small-4.md b/docs/model-coverage/vlm/mistralai/mistral-small-4.mdx similarity index 100% rename from docs/model-coverage/vlm/mistralai/mistral-small-4.md rename to docs/model-coverage/vlm/mistralai/mistral-small-4.mdx diff --git a/docs/model-coverage/vlm/moonshotai/kimi-vl.md b/docs/model-coverage/vlm/moonshotai/kimi-vl.mdx similarity index 100% rename from docs/model-coverage/vlm/moonshotai/kimi-vl.md rename to docs/model-coverage/vlm/moonshotai/kimi-vl.mdx diff --git a/docs/model-coverage/vlm/nvidia/nemotron-parse.md b/docs/model-coverage/vlm/nvidia/nemotron-parse.mdx similarity index 100% rename from docs/model-coverage/vlm/nvidia/nemotron-parse.md rename to docs/model-coverage/vlm/nvidia/nemotron-parse.mdx diff --git a/docs/model-coverage/vlm/qwen/qwen2-5-vl.md b/docs/model-coverage/vlm/qwen/qwen2-5-vl.mdx similarity index 100% rename from docs/model-coverage/vlm/qwen/qwen2-5-vl.md rename to docs/model-coverage/vlm/qwen/qwen2-5-vl.mdx diff --git a/docs/model-coverage/vlm/qwen/qwen3-5-vl.md b/docs/model-coverage/vlm/qwen/qwen3-5-vl.mdx similarity index 100% rename from docs/model-coverage/vlm/qwen/qwen3-5-vl.md rename to docs/model-coverage/vlm/qwen/qwen3-5-vl.mdx diff --git a/docs/model-coverage/vlm/qwen/qwen3-vl.md b/docs/model-coverage/vlm/qwen/qwen3-vl.mdx similarity index 100% rename from docs/model-coverage/vlm/qwen/qwen3-vl.md rename to docs/model-coverage/vlm/qwen/qwen3-vl.mdx diff --git a/docs/performance-summary.md b/docs/performance-summary.mdx similarity index 100% rename from docs/performance-summary.md rename to docs/performance-summary.mdx diff --git a/docs/release-notes.md b/docs/release-notes.mdx similarity index 100% rename from docs/release-notes.md rename to docs/release-notes.mdx diff --git a/docs/repository-structure.md b/docs/repository-structure.mdx similarity index 100% rename from docs/repository-structure.md rename to docs/repository-structure.mdx From 8ae8b449c8eaba393fec743f4fd7a4435d2d536f Mon Sep 17 00:00:00 2001 From: Lawrence Lane Date: Thu, 21 May 2026 17:22:53 -0400 Subject: [PATCH 4/7] docs(fern-migrate): convert Sphinx MD to Fern MDX (140 pages) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restores the converted Fern-MDX body at every docs/<...>.mdx path. The diff against the prior commit is the **complete, per-file Sphinx → Fern conversion** — for any page, `git show HEAD -- docs/<...>.mdx` isolates exactly what the migration rewrote at that path: * Replace leading `# H1` heading with Fern frontmatter (title / description / position). * MyST directives → Fern-native MDX components: :::{card} → plain table or `` / `` :::{dropdown} / :::{note} → `` / `` / `` {bdg-*}`label` → `label` {download}`text ` → absolute GitHub blob URL link {toctree} → removed (nav lives in nightly.yml) (label)= MyST anchors → removed * Cross-version internal links → version-agnostic (`/get-started/installation`, no `/latest/` or `/nightly/` prefix). * Cross-repo refs (yaml, source) → absolute GitHub URLs. * Image refs stay relative (`./image.png`) so they resolve against the page-scoped copies in docs/

/. Content, ordering, and link targets are preserved — only the representation changes. fern check passes. Signed-off-by: Lawrence Lane --- docs/about/index.mdx | 32 +- docs/about/key-features.mdx | 86 ++--- docs/announcements.mdx | 9 +- docs/breaking-changes.mdx | 7 +- docs/documentation.mdx | 7 +- docs/guides/audio/qwen3-omni-asr.mdx | 5 +- docs/guides/checkpointing.mdx | 28 +- docs/guides/configuration.mdx | 20 +- docs/guides/dataset-overview.mdx | 43 +-- docs/guides/diffusion/dataset.mdx | 16 +- docs/guides/diffusion/finetune.mdx | 50 +-- docs/guides/dllm/finetune.mdx | 18 +- docs/guides/fp8-training.mdx | 21 +- docs/guides/gradient-checkpointing.mdx | 14 +- docs/guides/huggingface-api-compatibility.mdx | 56 ++-- docs/guides/installation.mdx | 58 ++-- ...column-mapped-text-instruction-dataset.mdx | 32 +- ...pped-text-instruction-iterable-dataset.mdx | 22 +- docs/guides/llm/databricks.mdx | 41 ++- docs/guides/llm/dataset.mdx | 12 +- docs/guides/llm/dsv4-flash.mdx | 9 +- docs/guides/llm/finetune.mdx | 96 +++--- docs/guides/llm/hy3.mdx | 7 +- docs/guides/llm/knowledge-distillation.mdx | 8 +- docs/guides/llm/large-moe-finetune.mdx | 9 +- docs/guides/llm/nanogpt-pretraining.mdx | 50 +-- docs/guides/llm/pretraining.mdx | 29 +- docs/guides/llm/retrieval-dataset.mdx | 19 +- docs/guides/llm/sequence-classification.mdx | 9 +- docs/guides/llm/toolcalling.mdx | 21 +- docs/guides/mlflow-logging.mdx | 14 +- docs/guides/omni/gemma3-3n.mdx | 30 +- docs/guides/overview.mdx | 30 +- docs/guides/pipelining.mdx | 15 +- docs/guides/quantization-aware-training.mdx | 13 +- docs/guides/vlm/dataset.mdx | 11 +- docs/guides/vlm/gemma4.mdx | 11 +- docs/guides/vlm/mistral-medium-3-5.mdx | 11 +- docs/guides/vlm/nemotron-omni.mdx | 12 +- docs/guides/vlm/qwen3-5.mdx | 13 +- docs/index.mdx | 301 +++++------------- docs/launcher/local-workstation.mdx | 21 +- docs/launcher/nemo-run.mdx | 9 +- docs/launcher/overview.mdx | 25 +- docs/launcher/skypilot-kubernetes.mdx | 15 +- docs/launcher/skypilot.mdx | 13 +- docs/launcher/slurm.mdx | 16 +- .../diffusion/black-forest-labs/flux.mdx | 27 +- .../hunyuanvideo-community/hunyuanvideo.mdx | 25 +- docs/model-coverage/diffusion/index.mdx | 30 +- .../diffusion/qwen/qwen-image.mdx | 27 +- .../diffusion/wan-ai/wan2-1-t2v.mdx | 27 +- docs/model-coverage/embedding/index.mdx | 35 +- .../mistralai/ministral3-bidirectional.mdx | 17 +- .../embedding/nvidia/llama-bidirectional.mdx | 27 +- docs/model-coverage/latest-models.mdx | 11 +- docs/model-coverage/llm/allenai/olmo.mdx | 23 +- docs/model-coverage/llm/allenai/olmo2.mdx | 27 +- docs/model-coverage/llm/allenai/olmoe.mdx | 23 +- docs/model-coverage/llm/baai/aquila.mdx | 23 +- .../llm/baichuan-inc/baichuan.mdx | 27 +- docs/model-coverage/llm/baidu/ernie4-5.mdx | 24 +- docs/model-coverage/llm/bigcode/starcoder.mdx | 23 +- .../model-coverage/llm/bigcode/starcoder2.mdx | 27 +- .../llm/bytedance-seed/seed.mdx | 31 +- docs/model-coverage/llm/cohere/command-r.mdx | 27 +- .../llm/deepseek-ai/deepseek-v3.mdx | 36 ++- .../llm/deepseek-ai/deepseek.mdx | 23 +- .../llm/deepseek-ai/dsv4-flash.mdx | 30 +- docs/model-coverage/llm/eleutherai/gpt-j.mdx | 23 +- .../llm/eleutherai/gpt-neox.mdx | 23 +- docs/model-coverage/llm/google/gemma.mdx | 31 +- docs/model-coverage/llm/ibm/bamba.mdx | 23 +- docs/model-coverage/llm/ibm/granite-moe.mdx | 23 +- docs/model-coverage/llm/ibm/granite.mdx | 27 +- docs/model-coverage/llm/inceptionai/jais.mdx | 23 +- .../model-coverage/llm/inclusionai/ling-2.mdx | 42 ++- docs/model-coverage/llm/index.mdx | 193 ++++------- docs/model-coverage/llm/internlm/internlm.mdx | 23 +- .../model-coverage/llm/lgai-exaone/exaone.mdx | 23 +- docs/model-coverage/llm/meta/llama.mdx | 27 +- docs/model-coverage/llm/microsoft/phi.mdx | 27 +- .../llm/microsoft/phi3-small.mdx | 23 +- docs/model-coverage/llm/microsoft/phi3.mdx | 31 +- .../model-coverage/llm/minimax/minimax-m2.mdx | 36 ++- .../llm/mistralai/ministral3.mdx | 22 +- docs/model-coverage/llm/mistralai/mistral.mdx | 31 +- docs/model-coverage/llm/mistralai/mixtral.mdx | 27 +- .../llm/moonshotai/moonlight.mdx | 27 +- .../llm/nvidia/nemotron-flash.mdx | 32 +- docs/model-coverage/llm/nvidia/nemotron-h.mdx | 31 +- .../llm/nvidia/nemotron-super.mdx | 23 +- docs/model-coverage/llm/nvidia/nemotron.mdx | 23 +- docs/model-coverage/llm/openai/gpt-oss.mdx | 27 +- docs/model-coverage/llm/openai/gpt2.mdx | 19 +- docs/model-coverage/llm/openbmb/minicpm.mdx | 23 +- docs/model-coverage/llm/orionstar/orion.mdx | 23 +- .../model-coverage/llm/parasail-ai/gritlm.mdx | 23 +- docs/model-coverage/llm/qwen/qwen2-moe.mdx | 25 +- docs/model-coverage/llm/qwen/qwen2.mdx | 27 +- docs/model-coverage/llm/qwen/qwen3-moe.mdx | 27 +- docs/model-coverage/llm/qwen/qwen3-next.mdx | 32 +- docs/model-coverage/llm/qwen/qwen3.mdx | 27 +- .../llm/stabilityai/stablelm.mdx | 23 +- .../llm/stepfun-ai/step-3-5.mdx | 32 +- docs/model-coverage/llm/tencent/hy3.mdx | 20 +- docs/model-coverage/llm/thudm/chatglm.mdx | 23 +- docs/model-coverage/llm/thudm/glm4-moe.mdx | 38 ++- docs/model-coverage/llm/thudm/glm4.mdx | 27 +- .../model-coverage/llm/thudm/glm5-moe-dsa.mdx | 33 +- docs/model-coverage/llm/tiiuae/falcon.mdx | 27 +- docs/model-coverage/llm/upstage/solar.mdx | 23 +- .../llm/xiaomimimo/mimo-v2-flash.mdx | 36 +-- docs/model-coverage/omni/index.mdx | 25 +- .../omni/microsoft/phi4-multimodal.mdx | 25 +- .../omni/nvidia/nemotron-omni.mdx | 20 +- docs/model-coverage/omni/qwen/qwen3-omni.mdx | 25 +- docs/model-coverage/overview.mdx | 22 +- docs/model-coverage/reranker/index.mdx | 26 +- .../reranker/nvidia/llama-bidirectional.mdx | 25 +- docs/model-coverage/troubleshooting.mdx | 12 +- docs/model-coverage/vlm/google/gemma3-vl.mdx | 35 +- docs/model-coverage/vlm/google/gemma4.mdx | 45 +-- .../vlm/huggingface/smolvlm.mdx | 23 +- docs/model-coverage/vlm/index.mdx | 66 ++-- docs/model-coverage/vlm/internlm/internvl.mdx | 25 +- docs/model-coverage/vlm/llava-hf/llava.mdx | 23 +- .../vlm/lmms-lab/llava-onevision.mdx | 27 +- docs/model-coverage/vlm/meta/llama4.mdx | 23 +- .../vlm/mistralai/ministral3-vl.mdx | 29 +- .../vlm/mistralai/mistral-medium-3-5.mdx | 36 ++- .../vlm/mistralai/mistral-small-4.mdx | 32 +- .../model-coverage/vlm/moonshotai/kimi-vl.mdx | 27 +- .../vlm/nvidia/nemotron-parse.mdx | 25 +- docs/model-coverage/vlm/qwen/qwen2-5-vl.mdx | 25 +- docs/model-coverage/vlm/qwen/qwen3-5-vl.mdx | 35 +- docs/model-coverage/vlm/qwen/qwen3-vl.mdx | 31 +- docs/performance-summary.mdx | 12 +- docs/release-notes.mdx | 10 +- docs/repository-structure.mdx | 17 +- 140 files changed, 2049 insertions(+), 1990 deletions(-) diff --git a/docs/about/index.mdx b/docs/about/index.mdx index 40dc5b5974..d35e674693 100644 --- a/docs/about/index.mdx +++ b/docs/about/index.mdx @@ -1,16 +1,8 @@ --- +title: "About NeMo AutoModel" description: "Overview of NeMo AutoModel, a PyTorch DTensor-native SPMD library with optimized model implementations and a Hugging Face-compatible API for training, fine-tuning, and as an accelerated backend for other frameworks" -categories: ["getting-started"] -tags: ["overview", "spmd", "dtensor", "distributed", "getting-started"] -personas: ["machine-learning-engineer", "researcher", "devops"] -difficulty: "beginner" -content_type: "concept" +position: 1 --- - -(about-overview)= - -# About NeMo AutoModel - NeMo AutoModel is a PyTorch DTensor-native SPMD (Single Program, Multiple Data) open-source library under [NVIDIA NeMo Framework](https://github.com/NVIDIA-NeMo). It provides **optimized model implementations** with a **Hugging Face-compatible API**, so any model on the Hub works out of the box with no checkpoint conversion. On top of that, it ships ready-made **recipes** for training and fine-tuning LLMs and VLMs at scale. Because AutoModel exposes the same Autoclass interface as `transformers`, it can also be used as a **drop-in accelerated backend for other libraries** -- reinforcement learning frameworks, evaluation harnesses, or any codebase that loads Hugging Face models. @@ -55,7 +47,7 @@ NeMo AutoModel builds on top of `transformers` rather than replacing it: - Checkpoints stay in the native Hugging Face format -- no conversion step before or after training. - New models released on the Hub get day-0 support because AutoModel tracks the latest `transformers` version. -See the [Hugging Face API Compatibility](../guides/huggingface-api-compatibility.md) guide and [Model Coverage](../model-coverage/overview.md) for details. +See the [Hugging Face API Compatibility](/get-started/hf-compatibility) guide and [Model Coverage](/model-coverage/overview) for details. ## Optimized Model Implementations @@ -83,19 +75,13 @@ The returned model is a standard `nn.Module` with the same forward signature as ## What's Next -::::{grid} 1 2 2 2 -:gutter: 1 1 1 2 - -:::{grid-item-card} {octicon}`zap;1.5em;sd-mr-1` Key Features and Concepts -:link: about-key-features -:link-type: ref + + Explore the main features, supported workflows, and core concepts. -::: + -:::{grid-item-card} {octicon}`rocket;1.5em;sd-mr-1` Quickstart -:link: ../index -:link-type: doc + Jump to the quickstart table to find the right guide for your task. -::: + -:::: + diff --git a/docs/about/key-features.mdx b/docs/about/key-features.mdx index 3f8b43168b..288cbff071 100644 --- a/docs/about/key-features.mdx +++ b/docs/about/key-features.mdx @@ -1,16 +1,8 @@ --- +title: "Key Features and Concepts" description: "Key features and core concepts of NeMo AutoModel for scalable LLM and VLM training with Hugging Face integration" -categories: ["concepts-architecture"] -tags: ["features", "benchmarks", "parallelism", "peft", "distributed", "recipes", "components"] -personas: ["machine-learning-engineer", "researcher", "devops"] -difficulty: "beginner" -content_type: "concept" +position: 2 --- - -(about-key-features)= - -# Key Features and Concepts - NeMo AutoModel provides GPU-accelerated, `transformers`-compatible training for LLMs and VLMs. It combines Hugging Face's model ecosystem with NVIDIA's optimized training stack, delivering high throughput without sacrificing ease of use. ## Why NeMo AutoModel? @@ -29,7 +21,7 @@ NeMo AutoModel provides GPU-accelerated, `transformers`-compatible training for | GPT-OSS 20B | 8 | 279 | 13,058 | TE + DeepEP + FlexAttn | | Qwen3 MoE 30B | 8 | 212 | 11,842 | TE + DeepEP | -See the [full benchmark results](../performance-summary.md) for configuration details and more models. +See the [full benchmark results](/performance/performance-summary) for configuration details and more models. --- @@ -37,46 +29,32 @@ See the [full benchmark results](../performance-summary.md) for configuration de NeMo AutoModel supports a range of training tasks across LLM and VLM modalities. -::::{grid} 1 2 2 3 -:gutter: 2 - -:::{grid-item-card} {octicon}`mortar-board;1.5em;sd-mr-1` Supervised Fine-Tuning (SFT) -:link: ../guides/llm/finetune -:link-type: doc + + Full-parameter fine-tuning for task-specific adaptation. -::: + -:::{grid-item-card} {octicon}`cpu;1.5em;sd-mr-1` PEFT (LoRA / QLoRA) -:link: ../guides/llm/finetune -:link-type: doc + Memory-efficient fine-tuning by updating only low-rank adapter weights. -::: + -:::{grid-item-card} {octicon}`iterations;1.5em;sd-mr-1` Pre-Training -:link: ../guides/llm/pretraining -:link-type: doc + Train models from scratch on large-scale datasets. -::: + -:::{grid-item-card} {octicon}`dependabot;1.5em;sd-mr-1` Knowledge Distillation -:link: ../guides/llm/knowledge-distillation -:link-type: doc + Transfer knowledge from a large teacher to a smaller student model. -::: + -:::{grid-item-card} {octicon}`tools;1.5em;sd-mr-1` Tool Calling -:link: ../guides/llm/toolcalling -:link-type: doc + Fine-tune models for structured function calling with tool schemas. -::: + -:::{grid-item-card} {octicon}`meter;1.5em;sd-mr-1` Quantization-Aware Training -:link: ../guides/quantization-aware-training -:link-type: doc + Train with quantization for deployment-ready models. -::: + -:::: + --- @@ -84,26 +62,24 @@ Train with quantization for deployment-ready models. NeMo AutoModel leverages PyTorch-native parallelism strategies to scale training from a single GPU to multi-node clusters. -::::{grid} 1 2 2 2 -:gutter: 2 - -:::{grid-item-card} {octicon}`git-merge;1.5em;sd-mr-1` FSDP2 + + Fully Sharded Data Parallelism with DTensor for memory-efficient distributed training. Supports Hybrid Sharding (HSDP) for multi-node. -::: + -:::{grid-item-card} {octicon}`git-merge;1.5em;sd-mr-1` Pipeline Parallelism + Torch-native pipelining composable with FSDP2 and DTensor for 3D parallelism. -::: + -:::{grid-item-card} {octicon}`zap;1.5em;sd-mr-1` FP8 Mixed Precision + FP8 training via torchao for reduced memory and higher throughput on supported models. -::: + -:::{grid-item-card} {octicon}`server;1.5em;sd-mr-1` Multi-Node with SLURM -Add a `slurm:` section to any YAML config and launch with the `automodel` CLI. See the [Cluster guide](../launcher/slurm.md). -::: + +Add a `slurm:` section to any YAML config and launch with the `automodel` CLI. See the [Cluster guide](/job-launchers/slurm-cluster). + -:::: + --- @@ -169,7 +145,7 @@ automodel config.yaml sbatch my_cluster.sub # copy slurm.sub, edit CONFIG & SBATCH directives, then submit ``` -See the [Local Workstation](../launcher/local-workstation.md) and [Cluster](../launcher/slurm.md) guides. +See the [Run on Your Local Workstation](/job-launchers/local-workstation) and [Cluster](/job-launchers/slurm-cluster) guides. --- @@ -181,8 +157,8 @@ NeMo AutoModel writes Distributed Checkpoints (DCP) with SafeTensors shards. Che - **Reshard** when loading onto a different mesh or topology. - **Resume** training from any checkpoint without manual intervention. -See the [Checkpointing guide](../guides/checkpointing.md) for details. +See the [Checkpointing guide](/development/checkpointing) for details. ## Experiment Tracking -NeMo AutoModel integrates with MLflow and Weights & Biases for experiment tracking, metric logging, and artifact management. See the [Experiment Tracking guide](../guides/mlflow-logging.md). +NeMo AutoModel integrates with MLflow and Weights & Biases for experiment tracking, metric logging, and artifact management. See the [Experiment Tracking guide](/development/mlflow-logging). diff --git a/docs/announcements.mdx b/docs/announcements.mdx index 77310123ee..2df7a45855 100644 --- a/docs/announcements.mdx +++ b/docs/announcements.mdx @@ -1,6 +1,9 @@ -# Announcements - -See also the [Model Coverage Release Log](model-coverage/overview.md#release-log) for newly supported models across releases. +--- +title: "Announcements" +description: "" +position: 1 +--- +See also the [Model Coverage Release Log](/model-coverage/overview#release-log) for newly supported models across releases. - [Accelerating Large-Scale Mixture-of-Experts Training in PyTorch with NeMo Automodel](https://github.com/NVIDIA-NeMo/Automodel/discussions/777) - [Challenges in Enabling PyTorch Native Pipeline Parallelism for Hugging Face Transformer Models](https://github.com/NVIDIA-NeMo/Automodel/discussions/589) diff --git a/docs/breaking-changes.mdx b/docs/breaking-changes.mdx index 0c7f376731..0c80af85cc 100644 --- a/docs/breaking-changes.mdx +++ b/docs/breaking-changes.mdx @@ -1,5 +1,8 @@ -# Breaking Changes - +--- +title: "Breaking Changes" +description: "" +position: 6 +--- ## 0.4.0 · 26.04 ### CLI Signature Change diff --git a/docs/documentation.mdx b/docs/documentation.mdx index ba556497b0..b6865466b5 100644 --- a/docs/documentation.mdx +++ b/docs/documentation.mdx @@ -1,11 +1,12 @@ -# Documentation Development - +--- +title: "Documentation Development" +description: "" +--- - [Documentation Development](#documentation-development) - [Build the Documentation](#build-the-documentation) - [Live Building](#live-building) - [Documentation Version](#documentation-version) - ## Build the Documentation The following sections describe how to set up and build the NeMo Automodel documentation. diff --git a/docs/guides/audio/qwen3-omni-asr.mdx b/docs/guides/audio/qwen3-omni-asr.mdx index 196ba7f3ca..0191e7f662 100644 --- a/docs/guides/audio/qwen3-omni-asr.mdx +++ b/docs/guides/audio/qwen3-omni-asr.mdx @@ -1,4 +1,7 @@ -# Fine-Tune Qwen3-Omni for ASR +--- +title: "Fine-Tune Qwen3-Omni for ASR" +description: "End-to-end ASR fine-tuning of Qwen3-Omni-30B on Hugging Face audio datasets with NeMo AutoModel." +--- End-to-end ASR fine-tuning of `Qwen/Qwen3-Omni-30B-A3B-Instruct` on a Hugging Face audio dataset, using the NeMo AutoModel VLM training stack. The diff --git a/docs/guides/checkpointing.mdx b/docs/guides/checkpointing.mdx index a575925252..68bdb1da8f 100644 --- a/docs/guides/checkpointing.mdx +++ b/docs/guides/checkpointing.mdx @@ -1,5 +1,8 @@ -# Checkpointing - +--- +title: "Checkpointing in NeMo Automodel" +description: "" +position: 1 +--- ## Introduction During machine-learning experiments, the model-training routine regularly saves checkpoints. A checkpoint is a complete snapshot of a run that includes model weights, optimizer states, and other metadata required to resume training exactly where it left off. Writing these snapshots at regular intervals lets you recover quickly from crashes or pauses without losing progress. @@ -20,7 +23,6 @@ SFT | LLM | ✅ | ✅ | ✅ SFT | VLM | ✅ | ✅ | ✅ | PEFT | LLM / VLM | 🚧 | 🚧 | ✅ | - Changing between output formats can be done seamlessly through the recipe's `yaml` configuration file: ```yaml checkpoint: @@ -31,9 +33,10 @@ checkpoint: ``` > **Note:** For optimal compatibility with the Hugging Face ecosystem, including downstream tools such as vLLM and SGLang, we recommend using the checkpoint configuration provided above. -::: {note} + The optimizer states are _always_ saved in DCP (`.distcp` extension) format. -::: + + ## Checkpoint Symbolic Links @@ -64,10 +67,11 @@ automodel --nproc-per-node=2 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya --checkpoint.save_consolidated True ``` -::: {note} + In the above command we used the [`llama3_2_1b_squad.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/492add84a2b9d495946fe211c28973cd00051f3e/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml) config as a running example, adjust as necessary to your case. More config examples can be found in our [`examples/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples) directory. -::: + + If you're running on a single GPU, you can run: ```bash @@ -129,7 +133,6 @@ print(pipe("The key to life is")) Although this example uses the Hugging Face Transformers API, the `consolidated/` checkpoint is compatible with any Hugging Face-compatible tool, such as vLLM, SGLang, and others. - ## PEFT When training with Parameter-Efficient Fine-Tuning (PEFT) techniques, only a small subset of model weights are updated — the rest of the model remains frozen. This dramatically reduces the size of the checkpoint, often to just a few megabytes. @@ -243,7 +246,7 @@ automodel --nproc-per-node=2 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya ## Saving Checkpoints When Using Docker -When training inside a Docker container (see [Installation Guide](installation.md)), any files written to the container's filesystem are lost when the container exits (especially with `--rm`). To keep your checkpoints, you must **bind-mount a host directory** to the checkpoint path before starting the container: +When training inside a Docker container (see [Installation Guide](/get-started/installation)), any files written to the container's filesystem are lost when the container exits (especially with `--rm`). To keep your checkpoints, you must **bind-mount a host directory** to the checkpoint path before starting the container: ```bash docker run --gpus all -it --rm \ @@ -265,9 +268,10 @@ automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ When using a custom path, make sure the corresponding host directory is mounted into the container with `-v`. -::: {tip} -Mount additional host directories for datasets and the Hugging Face model cache to avoid re-downloading large models across container restarts. See the [Installation Guide](installation.md) for a complete `docker run` example with all recommended mounts. -::: + +Mount additional host directories for datasets and the Hugging Face model cache to avoid re-downloading large models across container restarts. See the [Installation Guide](/get-started/installation) for a complete `docker run` example with all recommended mounts. + + ## Asynchronous Checkpointing diff --git a/docs/guides/configuration.mdx b/docs/guides/configuration.mdx index 66ffa67fad..173de807c1 100644 --- a/docs/guides/configuration.mdx +++ b/docs/guides/configuration.mdx @@ -1,5 +1,8 @@ -# YAML Configuration - +--- +title: "YAML Configuration" +description: "" +position: 4 +--- NeMo AutoModel recipes are configured with YAML. Under the hood, YAML is parsed into a `ConfigNode` which: - Translates common scalar strings into typed Python values (e.g., `"10"` → `10`). @@ -7,7 +10,6 @@ NeMo AutoModel recipes are configured with YAML. Under the hood, YAML is parsed - Supports environment variable interpolation inside YAML strings. - Tries to make config printing safe by preserving original placeholders (to avoid leaking secrets). - ## Load Model and Dataset Configs Most recipes load the YAML using `nemo_automodel.components.config.loader.load_yaml_config()`, which returns a `ConfigNode`. @@ -29,7 +31,6 @@ Only **strings** are translated. Examples: YAML-native types (like `step_size: 10` without quotes) are already typed by the YAML parser and remain unchanged. - ## Use `_target_` for Instantiation Any mapping containing a `_target_` key can be instantiated using `ConfigNode.instantiate()`: @@ -55,8 +56,7 @@ By default, resolving targets is restricted: ## Distributed Section (Strategy-Based) -The `distributed:` section is **not** instantiated using `_target_`. Recipes parse it with a fixed schema: use `strategy: fsdp2`, `strategy: ddp`, or `strategy: megatron_fsdp`, plus optional parallelism sizes (`dp_size`, `tp_size`, `pp_size`, etc.) and strategy-specific options. When pipeline parallelism is enabled (`pp_size > 1`), add a `pipeline:` subsection with options such as `pp_schedule`, `pp_microbatch_size`, and `layers_per_stage`. See the [Pipelining](pipelining.md) guide and recipe example configs for full examples. - +The `distributed:` section is **not** instantiated using `_target_`. Recipes parse it with a fixed schema: use `strategy: fsdp2`, `strategy: ddp`, or `strategy: megatron_fsdp`, plus optional parallelism sizes (`dp_size`, `tp_size`, `pp_size`, etc.) and strategy-specific options. When pipeline parallelism is enabled (`pp_size > 1`), add a `pipeline:` subsection with options such as `pp_schedule`, `pp_microbatch_size`, and `layers_per_stage`. See the [Pipeline Parallelism with AutoPipeline](/development/pipeline-parallelism) guide and recipe example configs for full examples. ## Interpolate Environment Variables in YAML @@ -93,7 +93,6 @@ dataset: DATABRICKS_HTTP_PATH: ${DATABRICKS_HTTP_PATH} ``` - ## Prevent Secret Leakage in Logs When an env var placeholder is resolved, the config keeps the original placeholder in an internal `._orig_value` field for **safe printing**: @@ -101,10 +100,10 @@ When an env var placeholder is resolved, the config keeps the original placehold - `str(cfg)` / `repr(cfg)` prints placeholders (e.g. `${DATABRICKS_TOKEN}`), not resolved secrets. - `cfg.to_yaml_dict(use_orig_values=True, redact_sensitive=True)` is the recommended way to produce a loggable YAML dict. -:::{important} + Printing a **leaf value** (for example, `print(cfg.dataset.delta_storage_options.DATABRICKS_TOKEN)`) outputs the resolved secret. Instead, print the full config or use a redacted YAML dict. -::: + ## Configure Slurm @@ -119,5 +118,4 @@ sbatch my_cluster.sub All cluster-specific configuration (SBATCH directives, container image, mounts, secrets, environment variables) lives in your sbatch script. See -[Run on a Cluster](../launcher/slurm.md) for full examples. - +[Run on a Cluster](/job-launchers/slurm-cluster) for full examples. diff --git a/docs/guides/dataset-overview.mdx b/docs/guides/dataset-overview.mdx index 00dfed81a6..1fec91bee5 100644 --- a/docs/guides/dataset-overview.mdx +++ b/docs/guides/dataset-overview.mdx @@ -1,8 +1,11 @@ -# Dataset Overview: LLM, VLM, and Retrieval Datasets - +--- +title: "Dataset Overview: LLM, VLM, and Retrieval Datasets in NeMo AutoModel" +description: "" +position: 1 +--- This page summarizes the datasets supported in NeMo AutoModel for LLM, VLM, and retrieval training and shows how to plug in your own datasets using Python functions or the YAML `_target_` mechanism. -- See also: [LLM datasets](llm/dataset.md), [VLM datasets](vlm/dataset.md), and [Retrieval dataset](llm/retrieval-dataset.md) for deeper, task-specific guides. +- See also: [LLM datasets](/datasets/text-dataset), [VLM datasets](/datasets/multi-modal-dataset), and [Retrieval dataset](/datasets/retrieval-dataset) for deeper, task-specific guides. - If a dataset you need is missing, please open a [GitHub issue](https://github.com/NVIDIA-NeMo/Automodel/issues) with a short description and example schema so we can prioritize support. --- @@ -25,10 +28,11 @@ dataset: ### SQuAD-Style Question Answering (QA) (Instruction SFT) - Factory: `nemo_automodel.components.datasets.llm.squad.make_squad_dataset` - Use case: instruction/QA tuning with either prompt-and-answer formatting or chat-template formatting -:::{note} + - If the tokenizer has a chat template and you want answer-only loss, you must provide `start_of_turn_token`. - Optional `seq_length` can be used for padding/truncation. -::: + + - Example YAML: ```yaml dataset: @@ -60,7 +64,7 @@ dataset: answer_only_loss_mask: true start_of_turn_token: "<|assistant|>" ``` -See the detailed guide, [Column-Mapped Text Instruction Dataset](llm/column-mapped-text-instruction-dataset.md), for more information. +See the detailed guide, [Column-Mapped Text Instruction Dataset](/datasets/columnmapped-dataset), for more information. - **ChatDataset (multi-turn conversations and tool calling)** - Class: `nemo_automodel.components.datasets.llm.ChatDataset` @@ -76,7 +80,7 @@ See the detailed guide, [Column-Mapped Text Instruction Dataset](llm/column-mapp - `truncation`: truncation strategy ("do_not_truncate", "longest_first", etc.) - `start_of_turn_token`: token marking assistant response start (for answer-only loss) - `chat_template`: optional override for tokenizer's chat template - - `skip_invalid_samples`: if ``true``, skip malformed JSONL lines when reading local files (warnings log skip counts); default ``false`` fails fast on a bad line + - `skip_invalid_samples`: if `true`, skip malformed JSONL lines when reading local files (warnings log skip counts); default `false` fails fast on a bad line - Notes: - Requires a tokenizer with chat template support - Supports both single-turn and multi-turn tool calling @@ -98,8 +102,8 @@ See the detailed guide, [Column-Mapped Text Instruction Dataset](llm/column-mapp - `start_of_turn_token`: token marking assistant response start (for answer-only loss) - `chat_template`: optional override for tokenizer's chat template - `mask_reasoning_content`: optionally exclude rendered `reasoning_content` tokens from loss - - `skip_invalid_samples`: if ``true``, skip malformed JSONL lines when reading local files (warnings log skip counts); default ``false`` fails fast on a bad line -:::{note} + - `skip_invalid_samples`: if `true`, skip malformed JSONL lines when reading local files (warnings log skip counts); default `false` fails fast on a bad line + - Requires a tokenizer with chat template support - Supports both single-turn and multi-turn tool calling - Assistant messages may also include `reasoning_content` for structured reasoning traces @@ -110,7 +114,8 @@ See the detailed guide, [Column-Mapped Text Instruction Dataset](llm/column-mapp - For multi-turn tool-calling datasets, prefer chat templates that use `{% generation %}` blocks so assistant-turn loss masking is exact - Set `mask_reasoning_content: true` if you want to train on the final assistant answer while excluding rendered reasoning traces from loss - Set `skip_invalid_samples: true` for noisy local JSONL so lines that are not valid JSON are skipped instead of failing the load -::: + + - Example YAML: ```yaml dataset: @@ -234,8 +239,8 @@ dataset: ] } ``` -See the [Function Calling guide](llm/toolcalling.md) for an end-to-end example with FunctionGemma. -For a small reasoning-style chat SFT starting point, see [qwen2_5_0p5b_instruct_fineproofs_chat.yaml](../../examples/llm_finetune/qwen/qwen2_5_0p5b_instruct_fineproofs_chat.yaml). +See the [Function Calling guide](/recipes-e2e-examples/function-calling) for an end-to-end example with FunctionGemma. +For a small reasoning-style chat SFT starting point, see [qwen2_5_0p5b_instruct_fineproofs_chat.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen2_5_0p5b_instruct_fineproofs_chat.yaml). ### Retrieval (Embedding Fine-Tuning) - Factory: `nemo_automodel.components.datasets.llm.make_retrieval_dataset` @@ -256,15 +261,16 @@ collate_fn: q_max_len: 512 p_max_len: 512 ``` -See the detailed guide, [Retrieval dataset](llm/retrieval-dataset.md), for more information. +See the detailed guide, [Retrieval dataset](/datasets/retrieval-dataset), for more information. ### NanoGPT Binary Shards (Pretraining) - Class: `nemo_automodel.components.datasets.llm.nanogpt_dataset.NanogptDataset` - Use case: token-level LM pretraining over `.bin` shards produced by NanoGPT-style preprocessors (supports legacy and current formats) -:::{note} + - Streams contiguous `seq_len` slices, supports optional BOS alignment and `.bos.idx` sidecar files - Related tool: `tools/nanogpt_data_processor.py` -::: + + ### Megatron (Pretraining; Interoperable With Pre-Tokenized Megatron Data) - Class: `nemo_automodel.components.datasets.llm.megatron_dataset.MegatronPretraining` @@ -284,7 +290,7 @@ dataset: split: "0.99, 0.01, 0.00" # train, validation, test splits_to_build: "train" ``` -See the detailed [pretraining guide](llm/pretraining.md), which uses MegatronPretraining data. +See the detailed [pretraining guide](/recipes-e2e-examples/pretraining), which uses MegatronPretraining data. ## Streaming Datasets @@ -453,7 +459,6 @@ Built-in dataset makers (return lists of `conversation` dicts): - **MedPix-VQA (Medical Pixel Question Answering)**: `nemo_automodel.components.datasets.vlm.datasets.make_medpix_dataset` - **CommonVoice 17 (CV17) (audio)**: `nemo_automodel.components.datasets.vlm.datasets.make_cv17_dataset` - Each example follows the conversation schema expected by `apply_chat_template`, e.g.: ```python { @@ -500,7 +505,7 @@ dataloader: ``` If you want answer-only loss masking, provide a model-appropriate `start_of_response_token` to the collate function. -See [Gemma-3n](omni/gemma3-3n.md) and [VLM dataset](vlm/dataset.md) for end-to-end examples. +See [Gemma-3n](/recipes-e2e-examples/gemma-3-3n) and [VLM dataset](/datasets/multi-modal-dataset) for end-to-end examples. --- @@ -532,7 +537,7 @@ data: num_workers: 0 ``` -See the [Diffusion Dataset Preparation](diffusion/dataset.md) guide for full preprocessing instructions and configuration details. +See the [Diffusion Dataset Preparation](/datasets/diffusion-dataset) guide for full preprocessing instructions and configuration details. --- diff --git a/docs/guides/diffusion/dataset.mdx b/docs/guides/diffusion/dataset.mdx index 22bcd9c908..a9f911bb71 100644 --- a/docs/guides/diffusion/dataset.mdx +++ b/docs/guides/diffusion/dataset.mdx @@ -1,7 +1,8 @@ -(diffusion-dataset)= - -# Diffusion Dataset Preparation - +--- +title: "Diffusion Dataset Preparation" +description: "" +position: 7 +--- ## Introduction Diffusion model training in NeMo AutoModel requires pre-encoded `.meta` files rather than raw images or videos. During preprocessing, a VAE encodes visual data into latent representations and a text encoder produces text embeddings. These are saved as `.meta` files so that training operates entirely in latent space, avoiding the need to load heavy encoder models during training. @@ -29,7 +30,7 @@ If no caption is found for a sample, the filename (with underscores replaced by ## Preprocessing -NeMo AutoModel includes a unified preprocessing tool at [`tools/diffusion/preprocessing_multiprocess.py`](../../../tools/diffusion/preprocessing_multiprocess.py) that encodes raw images and videos into cache files compatible with the multiresolution dataloader. It uses model-specific processors from `tools/diffusion/processors/` to handle VAE encoding, text embedding, and cache data formatting for each supported model. +NeMo AutoModel includes a unified preprocessing tool at [`tools/diffusion/preprocessing_multiprocess.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/tools/diffusion/preprocessing_multiprocess.py) that encodes raw images and videos into cache files compatible with the multiresolution dataloader. It uses model-specific processors from `tools/diffusion/processors/` to handle VAE encoding, text embedding, and cache data formatting for each supported model. The tool automatically distributes work across all available GPUs using multiprocessing, with one worker per GPU. @@ -202,6 +203,7 @@ data: drop_last: false ``` -:::{tip} + Supported image resolutions for FLUX include `[256, 256]`, `[512, 512]`, and `[1024, 1024]`. While a 1:1 aspect ratio is currently used as a proxy for the closest image size, the implementation is designed to support multiple aspect ratios. -::: + + diff --git a/docs/guides/diffusion/finetune.mdx b/docs/guides/diffusion/finetune.mdx index e4a789b48b..27a8b86ab5 100644 --- a/docs/guides/diffusion/finetune.mdx +++ b/docs/guides/diffusion/finetune.mdx @@ -1,7 +1,8 @@ -(diffusion-finetune)= - -# Diffusion Model Fine-Tuning - +--- +title: "Diffusion Model Fine-Tuning with NeMo AutoModel" +description: "" +position: 16 +--- ## Introduction Diffusion models generate images and videos by learning to reverse a noise process — starting from random noise and iteratively refining it into coherent visual output guided by a text prompt. Pretrained diffusion models (like [FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev) for images or [Wan 2.1](https://huggingface.co/Wan-AI/Wan2.1-T2V-1.3B-Diffusers) for video) produce impressive general-purpose results, but they know nothing about your particular visual domain, style, or subject matter. Fine-tuning bridges that gap — you adapt the model on your own data so it produces outputs that match your requirements, without the cost of training from scratch. @@ -34,9 +35,9 @@ For model-specific configuration (FLUX.1-dev, HunyuanVideo), see [Model-Specific | Model | HF Model ID | Task | Parameters | Example Config | |-------|-------------|------|------------|----------------| -| Wan 2.1 T2V 1.3B | `Wan-AI/Wan2.1-T2V-1.3B-Diffusers` | Text-to-Video | 1.3B | [wan2_1_t2v_flow.yaml](../../../examples/diffusion/finetune/wan2_1_t2v_flow.yaml) | -| FLUX.1-dev | `black-forest-labs/FLUX.1-dev` | Text-to-Image | 12B | [flux_t2i_flow.yaml](../../../examples/diffusion/finetune/flux_t2i_flow.yaml) | -| HunyuanVideo 1.5 | `hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v` | Text-to-Video | — | [hunyuan_t2v_flow.yaml](../../../examples/diffusion/finetune/hunyuan_t2v_flow.yaml) | +| Wan 2.1 T2V 1.3B | `Wan-AI/Wan2.1-T2V-1.3B-Diffusers` | Text-to-Video | 1.3B | [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow.yaml) | +| FLUX.1-dev | `black-forest-labs/FLUX.1-dev` | Text-to-Image | 12B | [flux_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/flux_t2i_flow.yaml) | +| HunyuanVideo 1.5 | `hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v` | Text-to-Video | — | [hunyuan_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/hunyuan_t2v_flow.yaml) | All models use FSDP2 for distributed training and flow matching for loss computation. @@ -53,11 +54,12 @@ docker pull nvcr.io/nvidia/nemo-automodel:26.02.00 docker run --gpus all -it --rm --shm-size=8g nvcr.io/nvidia/nemo-automodel:26.02.00 ``` -:::{important} -**Docker users:** Checkpoints are lost when the container exits unless you bind-mount the checkpoint directory to the host. See [Install with NeMo Docker Container](../installation.md#install-with-nemo-docker-container) and [Saving Checkpoints When Using Docker](../checkpointing.md#saving-checkpoints-when-using-docker). -::: + +**Docker users:** Checkpoints are lost when the container exits unless you bind-mount the checkpoint directory to the host. See [Install with NeMo Docker Container](/get-started/installation#install-with-nemo-docker-container) and [Saving Checkpoints When Using Docker](/development/checkpointing#saving-checkpoints-when-using-docker). -For the full set of installation methods, see the [installation guide](../installation.md). + + +For the full set of installation methods, see the [installation guide](/get-started/installation). ## Prepare Your Dataset @@ -100,7 +102,7 @@ python -m tools.diffusion.preprocessing_multiprocess video \ --caption_format meta_json ``` -For the full set of arguments and input format details, see the [Diffusion Dataset Preparation](dataset.md) guide. +For the full set of arguments and input format details, see the [Diffusion Dataset Preparation](/datasets/diffusion-dataset) guide. ## Configure Your Training Recipe @@ -110,7 +112,7 @@ Fine-tuning is driven by two components: 2. A YAML configuration file — a text file in YAML format that specifies all settings the recipe uses: which model to fine-tune, where the data lives, optimizer hyperparameters, parallelism strategy, etc. You customize training by editing this file rather than modifying code, allowing you to scale from 1 to 100s of GPUs seamlessly. -Below is the annotated [wan2_1_t2v_flow.yaml](../../../examples/diffusion/finetune/wan2_1_t2v_flow.yaml), with each section explained: +Below is the annotated [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow.yaml), with each section explained: ```yaml seed: 42 @@ -212,7 +214,6 @@ checkpoint: | `checkpoint` | Recommended | Set `checkpoint_dir` to a persistent path, especially in Docker. | | `wandb` | Optional | Configure to enable Weights & Biases logging. | -(fine-tune-the-model)= ## Fine-Tune the Model Launch fine-tuning with `torchrun`: @@ -225,7 +226,6 @@ torchrun --nproc-per-node=8 \ Adjust `--nproc-per-node` to match the number of GPUs on your node, and ensure `fsdp.dp_size` in the YAML matches. -(multi-node-training)= ## Multi-Node Training When a single node doesn't provide enough GPUs or memory for your workload, you can scale training across multiple nodes. NeMo AutoModel handles multi-node distributed training through `torchrun` rendezvous and FSDP2 — the same recipe script works on one node or many. @@ -245,7 +245,7 @@ fsdp: dp_size: 16 # Total GPUs: 2 nodes × 8 GPUs ``` -A complete multi-node config is provided at [wan2_1_t2v_flow_multinode.yaml](../../../examples/diffusion/finetune/wan2_1_t2v_flow_multinode.yaml). +A complete multi-node config is provided at [wan2_1_t2v_flow_multinode.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow_multinode.yaml). ### Launch with torchrun @@ -266,7 +266,6 @@ torchrun \ -c examples/diffusion/finetune/wan2_1_t2v_flow_multinode.yaml ``` -(model-specific-notes)= ## Model-Specific Notes Use the table below to pick the right model for your use case: @@ -281,7 +280,7 @@ Use the table below to pick the right model for your use case: - **Adapter type**: `simple` - **Dataloader**: `build_video_multiresolution_dataloader` with `model_type: wan` -- **Config**: [wan2_1_t2v_flow.yaml](../../../examples/diffusion/finetune/wan2_1_t2v_flow.yaml) +- **Config**: [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow.yaml) ### FLUX.1-dev (Text-to-Image) @@ -305,7 +304,7 @@ Use the table below to pick the right model for your use case: use_guidance_embeds: true ``` - Uses `logit_normal` timestep sampling instead of `uniform` -- **Config**: [flux_t2i_flow.yaml](../../../examples/diffusion/finetune/flux_t2i_flow.yaml) +- **Config**: [flux_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/flux_t2i_flow.yaml) ### HunyuanVideo 1.5 @@ -322,7 +321,7 @@ Use the table below to pick the right model for your use case: default_image_embed_shape: [729, 1152] ``` - Uses `logit_normal` timestep sampling -- **Config**: [hunyuan_t2v_flow.yaml](../../../examples/diffusion/finetune/hunyuan_t2v_flow.yaml) +- **Config**: [hunyuan_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/hunyuan_t2v_flow.yaml) ## Generation / Inference @@ -374,13 +373,14 @@ python examples/diffusion/generate/generate.py \ | Config | Model | Output | GPUs | |--------|-------|--------|------| -| [`generate_wan.yaml`](../../../examples/diffusion/generate/configs/generate_wan.yaml) | Wan 2.1 1.3B | Video | 1 | -| [`generate_flux.yaml`](../../../examples/diffusion/generate/configs/generate_flux.yaml) | FLUX.1-dev | Image | 1 | -| [`generate_hunyuan.yaml`](../../../examples/diffusion/generate/configs/generate_hunyuan.yaml) | HunyuanVideo | Video | 1 | +| [`generate_wan.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/generate/configs/generate_wan.yaml) | Wan 2.1 1.3B | Video | 1 | +| [`generate_flux.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/generate/configs/generate_flux.yaml) | FLUX.1-dev | Image | 1 | +| [`generate_hunyuan.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/generate/configs/generate_hunyuan.yaml) | HunyuanVideo | Video | 1 | -:::{note} + You can use `--model.checkpoint ./checkpoints/LATEST` to automatically load the most recent checkpoint. -::: + + ## Hardware Requirements diff --git a/docs/guides/dllm/finetune.mdx b/docs/guides/dllm/finetune.mdx index f23d2937c7..bf0d96c7da 100644 --- a/docs/guides/dllm/finetune.mdx +++ b/docs/guides/dllm/finetune.mdx @@ -1,6 +1,8 @@ - -# Diffusion Language Model (dLLM) Fine-Tuning and Generation with NeMo AutoModel - +--- +title: "dLLM Fine-Tuning" +description: "" +position: 17 +--- ## Introduction Diffusion language models (dLLMs) generate text by iteratively denoising masked tokens, rather than generating one token at a time left-to-right like autoregressive (AR) models. Starting from a sequence of `[MASK]` tokens, the model progressively unmasks the most confident positions over multiple denoising steps until the full response is revealed. @@ -33,7 +35,7 @@ NeMo AutoModel currently supports the following dLLM model family: | Model Family | dLLM Mode | Loss | Inference | Example Config | |---|---|---|---|---| -| LLaDA | `mdlm` | MDLM cross-entropy | Block-by-block, full-forward (no KV cache) | [llada_sft.yaml](../../../examples/dllm_sft/llada_sft.yaml) | +| LLaDA | `mdlm` | MDLM cross-entropy | Block-by-block, full-forward (no KV cache) | [llada_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/dllm_sft/llada_sft.yaml) | ## Install NeMo AutoModel @@ -48,13 +50,13 @@ docker pull nvcr.io/nvidia/nemo-automodel:26.02.00 docker run --gpus all -it --rm --shm-size=8g nvcr.io/nvidia/nemo-automodel:26.02.00 ``` -For the full set of installation methods, see the [installation guide](../installation.md). +For the full set of installation methods, see the [installation guide](/get-started/installation). ## Configure Your Training Recipe dLLM fine-tuning is driven by: -1. A **recipe script** ([`train_ft.py`](../../../nemo_automodel/recipes/dllm/train_ft.py)) — orchestrates the training loop with dLLM-specific corruption, loss, and batch handling. +1. A **recipe script** ([`train_ft.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/recipes/dllm/train_ft.py)) — orchestrates the training loop with dLLM-specific corruption, loss, and batch handling. 2. A **YAML configuration file** — specifies the model, data, optimizer, dLLM-specific settings, and distributed training strategy. The recipe uses a **strategy pattern** to handle differences between model families. The `dllm.mode` field in the YAML selects the strategy: @@ -65,7 +67,7 @@ The recipe uses a **strategy pattern** to handle differences between model famil ### LLaDA Configuration -See [llada_sft.yaml](../../../examples/dllm_sft/llada_sft.yaml) for the full working config. The key dLLM-specific sections are: +See [llada_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/dllm_sft/llada_sft.yaml) for the full working config. The key dLLM-specific sections are: ```yaml model: @@ -101,7 +103,7 @@ torchrun --nproc-per-node=8 \ ## Generation / Inference -The generation script ([`generate.py`](../../../examples/dllm_generate/generate.py)) supports chat, raw, and infilling modes for LLaDA checkpoints. +The generation script ([`generate.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/dllm_generate/generate.py)) supports chat, raw, and infilling modes for LLaDA checkpoints. ### LLaDA Generation diff --git a/docs/guides/fp8-training.mdx b/docs/guides/fp8-training.mdx index 7d5e901f4d..8dedb024ea 100644 --- a/docs/guides/fp8-training.mdx +++ b/docs/guides/fp8-training.mdx @@ -1,5 +1,8 @@ -# FP8 Training - +--- +title: "FP8 Training in NeMo AutoModel" +description: "" +position: 4 +--- NeMo AutoModel supports FP8 quantization using [TorchAO](https://github.com/pytorch/ao) and `torch.compile` to accelerate training on compatible hardware. FP8 (8-bit floating point) quantization can provide substantial speedups for models where the majority of GEMMs are sufficiently large. The speedup from using FP8 tensor cores must outweigh the overhead of dynamic quantization. @@ -65,13 +68,11 @@ fp8: - Good performance, moderate accuracy - Recommended for most use cases - #### Rowwise Scaling - Scale per row for better accuracy - Slower than tensorwise - Better numerical stability - For more on scaling strategies, refer to the [TorchAO FP8 documentation](https://github.com/pytorch/ao/tree/main/torchao/float8). ## Filter Modules @@ -93,12 +94,7 @@ FP8 quantization provides measurable performance improvements while maintaining - **Convergence**: FP8 training achieves loss parity with BF16 training. - **Memory**: FP8 training achieves on par memory usage with BF16 baseline. -```{image} fp8_convergence.jpg -:alt: FP8 Convergence Comparison -:class: bg-primary -:width: 600px -:align: center -``` +![FP8 Convergence Comparison](./fp8_convergence.jpg) *Figure: Loss curves comparing FP8 tensorwise scaling + torch.compile vs. BF16 + torch.compile training on 8xH100 with 8k sequence length, demonstrating virtually identical convergence behavior with 1.24x speedup* @@ -123,7 +119,6 @@ For example, to train Llama 3.1 8B with FP8: automodel --nproc-per-node=8 examples/llm_finetune/llama3_1/llama3_1_8b_hellaswag_fp8.yaml ``` - ## Performance Considerations FP8 requires specific conditions to be effective: @@ -140,10 +135,8 @@ FP8 works best when the majority of GEMM operations are sufficiently large such - You have modern (H100+) hardware optimized for FP8 acceleration - Moderate numerical precision is acceptable and slight approximations won't affect outcomes - - ## References - [TorchAO FP8 Documentation](https://github.com/pytorch/ao/tree/main/torchao/float8) - [FP8 Performance Benchmarks](https://github.com/pytorch/ao/tree/main/torchao/float8#performance) -- [NVIDIA FP8 Primer](https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/examples/fp8_primer.html) +- [NVIDIA FP8 Primer](https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/examples/fp8_primer.html) diff --git a/docs/guides/gradient-checkpointing.mdx b/docs/guides/gradient-checkpointing.mdx index 58156b8453..c1ccb64754 100644 --- a/docs/guides/gradient-checkpointing.mdx +++ b/docs/guides/gradient-checkpointing.mdx @@ -1,5 +1,8 @@ -# Gradient (Activation) Checkpointing - +--- +title: "Gradient (Activation) Checkpointing in NeMo AutoModel" +description: "" +position: 2 +--- Gradient checkpointing, also called _activation checkpointing_, trades a little extra compute for a **large reduction in GPU memory** by recomputing intermediate activations during the backwards pass instead of storing them. It is especially powerful when combined with memory-efficient loss functions (e.g., Linear-Cut Cross-Entropy) and parameter sharding using FSDP. @@ -59,11 +62,12 @@ LC-CE and gradient checkpointing target **different memory hot-spots** (output l | + LC-CE | 7.30 | ↓ 86 % | | **FSDP + LC-CE + Checkpointing** | **7.30** | **↓ 86 %** | -:::{note} + - Measurements taken with local batch size = 8, sequence len = 2048, AdamW, PyTorch 2.8. - Peak memory reported by `torch.cuda.max_memory_allocated()` averaged across DP ranks. - Expect ±5 % variance depending on exact model, sequence length and GPU architecture. -::: + + ## Performance Considerations 1. **Extra compute**: Each checkpointed segment is recomputed once during the backward pass. In practice, the wall-clock overhead is ≈5-10% for transformer models. @@ -82,4 +86,4 @@ automodel examples/llm_finetune/llama3_2/llama_3_2_1b_my_finetune.yaml If we run with the above settings (activation ckpt = on, lc-ce = on, fsdp = on), look for a log line similar to: ``` ... | mem 7.30 GiB | ... -``` \ No newline at end of file +``` diff --git a/docs/guides/huggingface-api-compatibility.mdx b/docs/guides/huggingface-api-compatibility.mdx index 3b990a66dc..c577194b27 100644 --- a/docs/guides/huggingface-api-compatibility.mdx +++ b/docs/guides/huggingface-api-compatibility.mdx @@ -1,5 +1,8 @@ -# 🤗 Transformers API Compatibility - +--- +title: "🤗 Transformers API Compatibility" +description: "" +position: 5 +--- NeMo AutoModel is built to work with the 🤗 Hugging Face ecosystem. In practice, compatibility comes in two layers: @@ -29,9 +32,10 @@ NeMo AutoModel addresses this in two complementary ways: - **Backports where needed**: for some model families, NeMo AutoModel may vendor/backport Hugging Face code that originated in the v5 development line so users can run those models while staying on a pinned v4 dependency. - **Stable artifact format**: NeMo AutoModel checkpoints are written in Hugging Face-compatible `save_pretrained` layouts (config + tokenizer + safetensors). These artifacts are designed to be loadable by both Transformers **v4** and **v5** (and non-Transformers tools that consume HF-style model repos). -:::{note} -If you are running Transformers v5 in another environment, you can still use NeMo AutoModel-produced consolidated checkpoints with Transformers' standard loading APIs. For details on the checkpoint layouts, see [checkpointing](checkpointing.md). -::: + +If you are running Transformers v5 in another environment, you can still use NeMo AutoModel-produced consolidated checkpoints with Transformers' standard loading APIs. For details on the checkpoint layouts, see [checkpointing](/development/checkpointing). + + ## Drop-In Compatibility and Key Differences @@ -48,15 +52,15 @@ If you are running Transformers v5 in another environment, you can still use NeM - **Distributed training stack**: NeMo AutoModel's recipes/CLI are designed for multi-GPU/multi-node fine-tuning with PyTorch-native distributed features (FSDP2, pipeline parallelism, etc.). - **CUDA expectation**: NeMo AutoModel's `NeMoAutoModel*` wrappers are primarily optimized for NVIDIA GPU workflows, and offer support for CPU workflows as well. -:::{important} + `NeMoAutoModelForCausalLM.from_pretrained(...)` currently assumes CUDA is available (it uses `torch.cuda.current_device()` internally). If you need CPU-only inference, use Hugging Face `transformers` directly. -::: + + ## API Mapping (Transformers and NeMo AutoModel) ### API Name Mapping -:::{raw} html @@ -103,13 +107,11 @@ If you are running Transformers v5 in another environment, you can still use NeM
-::: ## Side-by-Side Examples ### Load a Model and Tokenizer (Transformers v4) -:::{raw} html @@ -120,7 +122,7 @@ If you are running Transformers v5 in another environment, you can still use NeM
-
import torch
+        
{`import torch
 from transformers import AutoModelForCausalLM, AutoTokenizer
 
 model_id = "gpt2"
@@ -129,10 +131,10 @@ tokenizer = AutoTokenizer.from_pretrained(model_id)
 model = AutoModelForCausalLM.from_pretrained(
     model_id,
     torch_dtype=torch.bfloat16,
-)
+)`}
-
import torch
+        
{`import torch
 from nemo_automodel import NeMoAutoModelForCausalLM, NeMoAutoTokenizer
 
 model_id = "gpt2"
@@ -141,18 +143,16 @@ tokenizer = NeMoAutoTokenizer.from_pretrained(model_id)
 model = NeMoAutoModelForCausalLM.from_pretrained(
     model_id,
     torch_dtype=torch.bfloat16,
-)
+)`}
-::: ### Text Generation This snippet assumes you already have a `model` and `tokenizer` (see the loading snippet above). -:::{raw} html @@ -163,7 +163,7 @@ This snippet assumes you already have a `model` and `tokenizer` (see the loading
-
import torch
+        
{`import torch
 
 prompt = "Write a haiku about GPU kernels."
 inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
@@ -171,10 +171,10 @@ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
 with torch.inference_mode():
     out = model.generate(**inputs, max_new_tokens=64)
 
-print(tokenizer.decode(out[0], skip_special_tokens=True))
+print(tokenizer.decode(out[0], skip_special_tokens=True))`}
-
import torch
+        
{`import torch
 
 prompt = "Write a haiku about GPU kernels."
 inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
@@ -182,19 +182,16 @@ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
 with torch.inference_mode():
     out = model.generate(**inputs, max_new_tokens=64)
 
-print(tokenizer.decode(out[0], skip_special_tokens=True))
+print(tokenizer.decode(out[0], skip_special_tokens=True))`}
-::: - ### Tokenizers (Transformers vs NeMo AutoModel) NeMo AutoModel provides `NeMoAutoTokenizer` as a Transformers-like auto-tokenizer with a small registry for specialized backends (and a safe fallback when no specialization is needed). -:::{raw} html @@ -205,25 +202,24 @@ NeMo AutoModel provides `NeMoAutoTokenizer` as a Transformers-like auto-tokenize
-
from transformers import AutoTokenizer
+        
{`from transformers import AutoTokenizer
 
-tok = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")
+tok = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")`}
-
from nemo_automodel import NeMoAutoTokenizer
+        
{`from nemo_automodel import NeMoAutoTokenizer
 
-tok = NeMoAutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")
+tok = NeMoAutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")`}
-::: ## Checkpoints: Save in NeMo AutoModel, Load Everywhere NeMo AutoModel training recipes write checkpoints in Hugging Face-compatible layouts, including consolidated safetensors that you can load directly with Transformers: -- See [checkpointing](checkpointing.md) for checkpoint formats and example directory layouts. -- See [model coverage](../model-coverage/overview.md) for notes on how model support depends on the pinned Transformers version. +- See [checkpointing](/development/checkpointing) for checkpoint formats and example directory layouts. +- See [model coverage](/model-coverage/overview) for notes on how model support depends on the pinned Transformers version. If your goal is: **train/fine-tune in NeMo AutoModel → deploy in the HF ecosystem**, the recommended workflow is to enable consolidated safetensors checkpoints and then load them with the standard HF APIs or downstream inference engines. diff --git a/docs/guides/installation.mdx b/docs/guides/installation.mdx index c8bbfad040..8a4bab22a0 100644 --- a/docs/guides/installation.mdx +++ b/docs/guides/installation.mdx @@ -1,5 +1,8 @@ -# Install NeMo AutoModel - +--- +title: "Install NeMo AutoModel" +description: "" +position: 3 +--- This guide explains how to install NeMo AutoModel for LLM, VLM, and OMNI models on various platforms and environments. Depending on your use case, there are several ways to install it: | Method | Dev Mode | Use Case | Recommended For | @@ -90,9 +93,10 @@ pip3 install nemo-automodel uv pip install nemo-automodel ``` -:::{note} + GPU training on macOS is not supported. Use macOS for CPU-based experimentation or remote cluster submission. -::: + + #### Windows @@ -149,20 +153,22 @@ For most users, the easiest way to get started is using `pip3`. ```bash pip3 install nemo-automodel ``` -:::{tip} + This installs the latest stable release of NeMo AutoModel from PyPI. To verify the install, run `python -c "import nemo_automodel; print(nemo_automodel.__version__)"`. See [nemo-automodel on PyPI](https://pypi.org/project/nemo-automodel/). -::: + + ### Install with NeMo Docker Container You can use NeMo AutoModel with the NeMo Docker container. Pull the container by running: ```bash docker pull nvcr.io/nvidia/nemo-automodel:25.11.00 ``` -:::{note} + The above `docker` command uses the [`25.11.00`](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel?version=25.11.00) container. Use the [most recent container](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel) version to ensure you get the latest version of AutoModel and its dependencies like PyTorch, Transformers, etc. -::: + + Then you can enter the container using: ```bash @@ -172,7 +178,7 @@ docker run --gpus all -it --rm \ nvcr.io/nvidia/nemo-automodel:25.11.00 ``` -:::{important} + **Persist your checkpoints.** By default, checkpoints are written to `checkpoints/` inside the container. Because `--rm` destroys the container on exit, any data stored only inside the container is lost. Always bind-mount a host directory for the checkpoint path (as shown with `-v` above) so that your trained weights survive after the container stops. You can also mount additional directories for datasets and Hugging Face cache: ```bash docker run --gpus all -it --rm \ @@ -182,11 +188,13 @@ docker run --gpus all -it --rm \ -v /path/to/your/hf_cache:/root/.cache/huggingface \ nvcr.io/nvidia/nemo-automodel:25.11.00 ``` -::: -:::{tip} + + + **Models that require CUDA-specific packages (e.g., Nemotron).** Some model families—such as Nemotron Nano and Nemotron Flash—depend on packages like `mamba-ssm` and `causal-conv1d` that must be compiled against a matching CUDA toolkit. Installing these from source on a bare-metal host can be error-prone. The NeMo Automodel Docker container ships with these dependencies pre-built, so **using the container is the recommended approach** for fine-tuning Nemotron and other models with similar requirements. -::: + + --- ## Installation Options for Developers @@ -195,24 +203,25 @@ This section provides installation options for developers, including pulling the ### Install from GitHub (Source) - If you want the **latest features** from the `main` branch or want to contribute: #### Option A – Use `pip` With Git Repo ```bash pip3 install git+https://github.com/NVIDIA-NeMo/Automodel.git ``` -:::{note} + This installs the repo as a standard Python package (not editable). -::: + + #### Option B – Use `uv` With Git Repo ```bash uv pip install git+https://github.com/NVIDIA-NeMo/Automodel.git ``` -:::{note} + `uv` handles virtual environment transparently and enables more reproducible installs. -::: + + ### Install in Developer Mode (Editable Install) @@ -224,9 +233,10 @@ cd Automodel pip3 install -e . ``` -:::{note} + This installs AutoModel in editable mode, so changes to the code are immediately reflected in Python. -::: + + ### Mount the Repo into a NeMo Docker Container @@ -250,9 +260,10 @@ docker run --gpus all -it --rm \ pip install -e . && \ # Install Automodel in editable mode automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml" # Run a usage example ``` -:::{note} + The above `docker` command mounts your local `Automodel` directory into the container at `/workspace/Automodel`. -::: + + ## Install Profiles @@ -307,9 +318,10 @@ Install everything (CUDA, VLM, NeMo-Run, etc.): pip3 install nemo-automodel[all] ``` -:::{tip} + You can combine extras: `pip3 install nemo-automodel[vlm,cuda]` -::: + + ## Summary | Goal | Command or Method | diff --git a/docs/guides/llm/column-mapped-text-instruction-dataset.mdx b/docs/guides/llm/column-mapped-text-instruction-dataset.mdx index 073b9ee5e0..46fadca317 100644 --- a/docs/guides/llm/column-mapped-text-instruction-dataset.mdx +++ b/docs/guides/llm/column-mapped-text-instruction-dataset.mdx @@ -1,5 +1,8 @@ -# Use the ColumnMappedTextInstructionDataset - +--- +title: "Use the ColumnMappedTextInstructionDataset" +description: "" +position: 4 +--- This guide explains how to use `ColumnMappedTextInstructionDataset` to quickly and flexibly load instruction-answer datasets for LLM fine-tuning, with minimal code changes and support for common tokenization strategies. The `ColumnMappedTextInstructionDataset` is a lightweight, plug-and-play helper that lets you train on instruction-answer style corpora without writing custom Python for every new schema. You simply specify which columns map to logical fields like `context`, `question`, and `answer`, and the loader handles the rest automatically. This enables: @@ -15,7 +18,7 @@ It supports two data sources out-of-the-box: 1. **Local JSON/JSONL files** - pass a single file path or a list of paths on disk. Newline-delimited JSON works great. 2. **Hugging Face Hub** - point to any dataset repo (`org/dataset`) that contains the required columns. -For **streaming** (including **Delta Lake / Databricks**), use [`ColumnMappedTextInstructionIterableDataset`](column-mapped-text-instruction-iterable-dataset.md). The iterable variant always streams by design to avoid accidentally materializing entire datasets to disk/memory. +For **streaming** (including **Delta Lake / Databricks**), use [`ColumnMappedTextInstructionIterableDataset`](/datasets/columnmapped-iterable). The iterable variant always streams by design to avoid accidentally materializing entire datasets to disk/memory. --- ## Quickstart @@ -92,7 +95,6 @@ dataset: answer_only_loss_mask: false ``` - ### Remote Dataset Example In the following section, we demonstrate how to load the instruction-tuning corpus @@ -157,13 +159,15 @@ dataset: ### Streaming / Delta Lake / Databricks -:::{note} -`ColumnMappedTextInstructionDataset` does not support streaming or Delta Lake / Databricks sources. For those, use [`ColumnMappedTextInstructionIterableDataset`](column-mapped-text-instruction-iterable-dataset.md). -::: + +`ColumnMappedTextInstructionDataset` does not support streaming or Delta Lake / Databricks sources. For those, use [`ColumnMappedTextInstructionIterableDataset`](/datasets/columnmapped-iterable). -:::{note} -Delta Lake / Databricks (including `delta_sql_query` and authentication) is supported only by `ColumnMappedTextInstructionIterableDataset`. See [`column-mapped-text-instruction-iterable-dataset.md`](column-mapped-text-instruction-iterable-dataset.md) for details. -::: + + + +Delta Lake / Databricks (including `delta_sql_query` and authentication) is supported only by `ColumnMappedTextInstructionIterableDataset`. See [`column-mapped-text-instruction-iterable-dataset.md`](/datasets/columnmapped-iterable) for details. + + ### Advanced Options | Arg | Default | Description | @@ -225,14 +229,15 @@ sbatch my_cluster.sub ``` All cluster-specific settings (nodes, GPUs, partition, container, mounts, secrets) -live in your sbatch script. See the [cluster guide](../../launcher/slurm.md) for +live in your sbatch script. See the [cluster guide](/job-launchers/slurm-cluster) for full examples (Pyxis, bare-metal, Apptainer). ### Multi-Node Slurm Configuration -:::{note} + **Multi-Node Training**: When using Hugging Face datasets in multi-node setups, you need shared storage accessible by all nodes. Set `HF_DATASETS_CACHE` to a shared directory in your sbatch script (e.g., `export HF_DATASETS_CACHE=/shared/hf_cache`) to ensure all nodes can access the cached datasets. -::: + + When using multiple nodes with Hugging Face datasets: @@ -242,7 +247,6 @@ When using multiple nodes with Hugging Face datasets: Configure all of this in your sbatch script (`my_cluster.sub`), not in the YAML. - --- ### That's It! With the mapping specified, the rest of the NeMo Automodel pipeline (pre-tokenization, packing, collate-fn, *etc.*) works as usual. diff --git a/docs/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx b/docs/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx index 748282981f..9ab915af01 100644 --- a/docs/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx +++ b/docs/guides/llm/column-mapped-text-instruction-iterable-dataset.mdx @@ -1,5 +1,8 @@ -# Use the ColumnMappedTextInstructionIterableDataset (Streaming) - +--- +title: "Use the ColumnMappedTextInstructionIterableDataset (Streaming)" +description: "" +position: 5 +--- This guide explains how to use `ColumnMappedTextInstructionIterableDataset` to **stream** instruction datasets for LLM fine-tuning, including **Delta Lake/Databricks** sources. Unlike `ColumnMappedTextInstructionDataset` (map-style, non-streaming), this class is a `torch.utils.data.IterableDataset` and **always** loads data in streaming mode. This is intentional: it helps ensure data is consumed as a stream and avoids accidentally materializing full datasets/tables to disk or memory (which is especially important for large or sensitive corpora). @@ -12,7 +15,7 @@ Use `ColumnMappedTextInstructionIterableDataset` when you need: - **Delta Lake/Databricks** (Unity Catalog, cloud lakehouse storage, DBFS, etc.) - **Very large datasets** where map-style loading/caching is undesirable -If you do *not* need streaming (and you want `len(ds)` / `ds[i]`), use [`ColumnMappedTextInstructionDataset`](column-mapped-text-instruction-dataset.md). +If you do *not* need streaming (and you want `len(ds)` / `ds[i]`), use [`ColumnMappedTextInstructionDataset`](/datasets/columnmapped-dataset). ## Key Differences vs ColumnMappedTextInstructionDataset @@ -21,7 +24,7 @@ If you do *not* need streaming (and you want `len(ds)` / `ds[i]`), use [`ColumnM - **Repeat behavior**: by default, `repeat_on_exhaustion=True` (infinite stream). Set `repeat_on_exhaustion=False` to do a single pass. - **(Optional) sharding/shuffle helpers**: use `.shard(num_shards, index)` / `.shuffle(buffer_size, seed)` when supported by the underlying backend. -The column mapping and tokenization logic are shared with `ColumnMappedTextInstructionDataset`. See [Tokenization Paths](column-mapped-text-instruction-dataset.md#tokenization-paths) for details on output fields (`input_ids`, `labels`, `attention_mask`) and masking behavior. +The column mapping and tokenization logic are shared with `ColumnMappedTextInstructionDataset`. See [Tokenization Paths](/datasets/columnmapped-dataset#tokenization-paths) for details on output fields (`input_ids`, `labels`, `attention_mask`) and masking behavior. ## Quickstart (Hugging Face Streaming) @@ -194,13 +197,15 @@ dataset: DATABRICKS_HTTP_PATH: ${oc.env:DATABRICKS_HTTP_PATH} ``` -:::{note} + **SQL engine requirement:** `delta_sql_query` is executed via Spark (Databricks runtime/pyspark) when available, otherwise via `databricks-sql-connector`. It is not supported in a deltalake-only environment. -::: -:::{note} + + + **Authentication:** The Delta Lake loader automatically picks up credentials from environment variables (`DATABRICKS_TOKEN`, `AWS_ACCESS_KEY_ID`, `AZURE_STORAGE_ACCOUNT_KEY`, etc.) if not explicitly provided in `delta_storage_options`. -::: + + ## Common Arguments @@ -218,4 +223,3 @@ dataset: | `delta_storage_options` | `None` | Storage/auth options for Delta Lake backends (Databricks, S3, Azure, GCS). | | `delta_version` | `None` | Specific Delta table version to read. | | `delta_sql_query` | `None` | SQL query to generate rows for Delta sources (Spark / Databricks SQL only). | - diff --git a/docs/guides/llm/databricks.mdx b/docs/guides/llm/databricks.mdx index 022f666e28..8485ef4cba 100644 --- a/docs/guides/llm/databricks.mdx +++ b/docs/guides/llm/databricks.mdx @@ -1,8 +1,11 @@ -# Model Training on Databricks - +--- +title: "Model Training on Databricks" +description: "" +position: 19 +--- Databricks is a widely used platform for managing data, models, applications, and compute on the cloud. This guide shows how to use AutoModel for scalable, performant model training on Databricks. -The specific example here fine-tunes a [Llama-3.2-1B](https://huggingface.co/meta-llama/Llama-3.2-1B) model using the [SQuAD dataset](https://huggingface.co/datasets/rajpurkar/squad) from Hugging Face, but any AutoModel functionality (for example, {doc}`model pre-training `, {doc}`VLMs `, {doc}`other supported models `) can also be run on Databricks. +The specific example here fine-tunes a [Llama-3.2-1B](https://huggingface.co/meta-llama/Llama-3.2-1B) model using the [SQuAD dataset](https://huggingface.co/datasets/rajpurkar/squad) from Hugging Face, but any AutoModel functionality (for example, [model pre-training](/recipes-e2e-examples/pretraining), [VLMs](/model-coverage/vision-language-models/overview), [other supported models](/model-coverage/overview)) can also be run on Databricks. ## Provision Compute @@ -87,19 +90,15 @@ To run training on a single GPU, use this command: In addition to specifying the configuration file, we also use these options: - `--step_scheduler.max_steps`: Limits the number of training steps taken. Again, this is for example purposes – adapt for your actual use case as needed. -- `--checkpoint.checkpoint_dir`: Tells AutoModel where to {doc}`save model checkpoints ` from training. We recommend saving model checkpoints in a Databricks Unity Catalog [volume](https://docs.databricks.com/aws/en/volumes/). +- `--checkpoint.checkpoint_dir`: Tells AutoModel where to [save model checkpoints](/development/checkpointing) from training. We recommend saving model checkpoints in a Databricks Unity Catalog [volume](https://docs.databricks.com/aws/en/volumes/). - `--checkpoint.staging_dir`: Specifies a temporary staging location for model checkpoints. Files will be temporarily saved to this location before being moved to the final `checkpoint_dir` location. This is needed when saving checkpoints in Unity Catalog. - `--checkpoint.is_async`: Uses asynchronous checkpointing. Looking at GPU metrics in Databricks, we see our single GPU is being well utilized (\~95% utilization). -:::{figure} ./databricks-gpu-metrics-single.png -:name: databricks-gpu-metrics-single -:alt: Single GPU utilization of ~95% during model training. -:align: center - -Single GPU utilization of ~95% during model training. -::: + + Single GPU utilization of ~95% during model training. + To utilize all four GPUs available on this `g6e.12xlarge` instance, add `--nproc-per-node=4` to the same command: @@ -113,14 +112,9 @@ To utilize all four GPUs available on this `g6e.12xlarge` instance, add `--nproc The `automodel` CLI uses PyTorch's [Elastic Launch](https://docs.pytorch.org/docs/stable/elastic/run.html) internally to spawn and coordinate multiple training processes on the VM. Each training process runs on a separate GPU, and we can now see all four GPUs are being used (~95% utilization for each GPU). -:::{figure} ./databricks-gpu-metrics-multi.png -:name: databricks-gpu-metrics-multi -:alt: Multi-GPU, single-node utilization of ~95% during model training. -:align: center - -Multi-GPU, single-node utilization of ~95% during model training. -::: - + + Multi-GPU, single-node utilization of ~95% during model training. + ### Multi-Node @@ -198,9 +192,10 @@ For Databricks, the key configuration parameters are: - `artifact_location`: Leave as `null` to use default Databricks artifact storage, or specify a Unity Catalog volume path like `/Volumes////mlflow-artifacts` - `tags`: Add custom tags to organize and filter your runs -:::{note} + Databricks automatically handles authentication when `tracking_uri` is set to `"databricks"`. No additional credentials are needed. -::: + + ### Run Training with MLflow @@ -286,10 +281,10 @@ You can override MLflow settings from the command line: --mlflow.tags.learning_rate "1e-5" ``` -For more details on MLflow configuration options and best practices, see the {doc}`MLflow logging guide `. +For more details on MLflow configuration options and best practices, see the [MLflow logging guide](/development/mlflow-logging). ## Conclusion This guide showed how to use AutoModel for model training on Databricks-managed compute. It's relatively straightforward to scale from a single-GPU to multi-GPU to multi-node training to best suit your needs. -While the example here fine-tunes a Llama-3.2-1B model using the SQuAD dataset, any supported AutoModel functionality (like model pre-training, VLMs, etc.) can also run, and scale, on Databricks. Check out {doc}`additional recipes and end-to-end examples ` to learn more. +While the example here fine-tunes a Llama-3.2-1B model using the SQuAD dataset, any supported AutoModel functionality (like model pre-training, VLMs, etc.) can also run, and scale, on Databricks. Check out [additional recipes and end-to-end examples](/recipes-e2e-examples/overview) to learn more. diff --git a/docs/guides/llm/dataset.mdx b/docs/guides/llm/dataset.mdx index 8273662213..4c657c4112 100644 --- a/docs/guides/llm/dataset.mdx +++ b/docs/guides/llm/dataset.mdx @@ -1,5 +1,8 @@ -# Integrate Your Own Text Dataset - +--- +title: "Integrate Your Own Text Dataset" +description: "" +position: 2 +--- This guide shows you how to integrate your own dataset into NeMo Automodel for training. You'll learn about two main dataset types: **completion datasets** for language modeling (like [HellaSwag](https://huggingface.co/datasets/rowan/hellaswag)) and **instruction datasets** for question-answering tasks (like [SQuAD](https://huggingface.co/datasets/rajpurkar/squad)). We'll cover how to create custom datasets by implementing the required methods and preprocessing functions, and finally show you how to specify your own data logic using YAML configuration with file paths—allowing you to define custom dataset processing without modifying the main codebase. ## Quick Start Summary @@ -46,7 +49,6 @@ NeMo Automodel provides the `SFTSingleTurnPreprocessor` class to handle completi 4. **Creates loss mask**: `-100` for context, target IDs for target. 5. **Pads** sequences to equal length. - #### Create Your Own Completion Dataset To adapt your dataset into this format, define a class like this: @@ -76,7 +78,6 @@ class MyCompletionDataset: return len(self.dataset) ``` - ### Instruction Datasets **Instruction datasets** are question-answer pairs where the model learns to respond to specific instructions or questions. These datasets are structured as context-question pairs with corresponding answers, making them ideal for teaching models to follow instructions and provide accurate responses. @@ -148,7 +149,6 @@ dataset: ``` This will call `build_my_dataset()` from the specified file with the other keys (e.g., num_blocks) as arguments. This approach allows you to integrate custom datasets via config alone—no need to alter the codebase or package structure. - ## Packed Sequence Support in NeMo AutoModel NeMo AutoModel supports **packed sequences**, a technique to optimize training with variable-length sequences (e.g., text) by minimizing padding. @@ -163,7 +163,6 @@ Instead of padding each sequence to a fixed length (wasting computation on `[PAD - Enables larger effective batch sizes leading to better GPU utilization. - Especially useful for language modeling and text datasets. - ### Enable Packed Sequences in NeMo Automodel To enable packed sequences, add these keys to your recipe's YAML config: @@ -178,7 +177,6 @@ The `packed_sequence` has two options: - **packed_sequence_size**: Defines the total token length of each packed sequence, higher values require higher GPU memory usage. - **split_across_pack**: If two will split a sequence across different packed sequences. - ## Troubleshooting Tips - **Tokenization Mismatch?** Ensure your tokenizer aligns with the model's expected inputs. diff --git a/docs/guides/llm/dsv4-flash.mdx b/docs/guides/llm/dsv4-flash.mdx index bd3872fa49..ff44e4b9dc 100644 --- a/docs/guides/llm/dsv4-flash.mdx +++ b/docs/guides/llm/dsv4-flash.mdx @@ -1,5 +1,8 @@ -# Fine-Tune DeepSeek V4 Flash - +--- +title: "DeepSeek V4 Flash" +description: "" +position: 6 +--- ## Introduction [deepseek-ai/DeepSeek-V4-Flash](https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash) is the latest fine-grained Mixture-of-Experts language model from DeepSeek. It uses a 43-layer all-MoE backbone (no dense MLP layers) with 256 routed experts plus one shared expert per block and top-6 routing. The architecture introduces a hybrid per-layer attention zoo — Sliding-Window Attention (SWA), Compressed Sparse Attention (CSA, Compressor + Indexer), and Hierarchical Compressed Attention (HCA, Compressor only) — selectable per layer through `compress_ratios`. The first `num_hash_layers` blocks use a hash-clustering gate (`DeepseekV4HashGate`) for token-to-expert routing, and every block maintains `hc_mult=4` Hyper-Connection streams mixed via a learned col-norm-first Sinkhorn router. @@ -90,5 +93,5 @@ The bringup was validated against the official DeepSeek inference reference (`ds The training loss curve below is from a 43-layer full-finetune run on HellaSwag with the full attention zoo (SWA + CSA + HCA) live.

- DeepSeek V4 Flash Training Loss Curve + DeepSeek V4 Flash Training Loss Curve

diff --git a/docs/guides/llm/finetune.mdx b/docs/guides/llm/finetune.mdx index f7adb86137..d777758ca8 100644 --- a/docs/guides/llm/finetune.mdx +++ b/docs/guides/llm/finetune.mdx @@ -1,5 +1,8 @@ -# Supervised Fine-Tuning (SFT) and Parameter-Efficient Fine-Tuning (PEFT) - +--- +title: "Supervised Fine-Tuning (SFT) and Parameter-Efficient Fine-Tuning (PEFT) with NeMo AutoModel" +description: "" +position: 2 +--- ## Introduction Pretrained language models are general-purpose: they know a lot about language but nothing about your particular domain, terminology, or task. Fine-tuning bridges that gap — you fine-tune the model on your own examples so it produces answers that are accurate and relevant for your use case, without the cost of training a model from scratch. The result is a model optimized for your data that you can evaluate, publish, and deploy. This guide walks you through that process end-to-end with NeMo AutoModel — from installation through training, evaluation, and deployment — using [Meta LLaMA 3.2 1B](https://huggingface.co/meta-llama/Llama-3.2-1B) and the [SQuAD v1.1](https://huggingface.co/datasets/rajpurkar/squad) dataset as a running example. @@ -44,21 +47,20 @@ docker pull nvcr.io/nvidia/nemo-automodel:26.02.00 docker run --gpus all -it --rm --shm-size=8g -v $(pwd)/checkpoints:/tmp/checkpoints/ nvcr.io/nvidia/nemo-automodel:26.02.00 ``` -:::{important} -Docker containers are ephemeral — files written inside the container are lost when it stops. The `-v` flag in the `docker run` command above bind-mounts a local `checkpoints/` directory into the container so that saved checkpoints persist across runs. For more details, see [Saving Checkpoints When Using Docker](../checkpointing.md#saving-checkpoints-when-using-docker). -::: + +Docker containers are ephemeral — files written inside the container are lost when it stops. The `-v` flag in the `docker run` command above bind-mounts a local `checkpoints/` directory into the container so that saved checkpoints persist across runs. For more details, see [Saving Checkpoints When Using Docker](/development/checkpointing#saving-checkpoints-when-using-docker). -For the full set of installation methods, see the [installation guide](../installation.md). + -## Configure Your Training Recipe +For the full set of installation methods, see the [installation guide](/get-started/installation). +## Configure Your Training Recipe Training is configured through a [YAML](https://en.wikipedia.org/wiki/YAML) config file with three required sections — **model**, **dataset**, and **step_scheduler** — plus an optional **peft** section. The sections below walk through each one. For the complete copy-pastable file, see [Full Config YAML](#full-config-yaml). Under the hood, both SFT and PEFT are executed by a **recipe**: a self-contained Python class that wires together model loading, dataset preparation, training, checkpointing, and logging. The fine-tuning recipe is [`TrainFinetuneRecipeForNextTokenPrediction`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/recipes/llm/train_ft.py). The config file tells the recipe *what* to build; the recipe decides *how* to build it. -:::{dropdown} How the Config System Works - + NeMo AutoModel configs use a convention borrowed from [Hydra](https://hydra.cc/): the special **`_target_`** key tells the framework *which* Python class or function to call, and **every other key** in the same YAML block is passed as a keyword argument to that call. For example: ```yaml @@ -78,9 +80,10 @@ optimizer = Adam(lr=1.0e-5, weight_decay=0) The `_target_` value is a **dotted Python import path**: the same string you would use in an `import` statement. The framework resolves it at runtime by importing the module and looking up the attribute. This means you can point `_target_` at any class constructor or factory function, and the remaining keys become its arguments. -:::{tip} + To discover which parameters a section accepts, look up the Python signature of its `_target_`. For instance, `torch.optim.Adam` accepts `lr`, `betas`, `eps`, and `weight_decay` — those are the keys you can set in the YAML. -::: + + **From YAML to running code.** Here is the path a config takes through the framework: @@ -133,7 +136,7 @@ recipe: nemo_automodel.recipes.llm.train_ft.TrainFinetuneRecipeForNextTokenPredi The short name form is a convenience — the CLI scans all recipe modules under `nemo_automodel.recipes` and matches the bare class name. If you invoke the recipe script directly with `torchrun` instead of the `automodel` CLI, the `recipe` key is not required because the script itself *is* the recipe. **Not every section uses `_target_`.** Some sections like `step_scheduler`, `distributed`, and `checkpoint` are plain key-value groups consumed directly by the recipe — they control training schedule, parallelism strategy, and checkpoint behavior without instantiating a Python object. -::: + ### Model @@ -148,20 +151,20 @@ model: | `_target_` | Points to [`NeMoAutoModelForCausalLM.from_pretrained`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/_transformers/auto_model.py) — a factory method that downloads (or loads from cache) a pretrained Hugging Face model and wraps it with NeMo distributed-training support. | | `pretrained_model_name_or_path` | A keyword argument to `from_pretrained`. Any argument that [`from_pretrained`](https://huggingface.co/docs/transformers/main_classes/model#transformers.PreTrainedModel.from_pretrained) accepts can be added here (e.g. `cache_dir`, `torch_dtype`). | -This guide uses **Meta Llama 3.2 1B** as a running example. Replace `pretrained_model_name_or_path` with any supported [Hugging Face model ID](../../model-coverage/llm/index.md). +This guide uses **Meta Llama 3.2 1B** as a running example. Replace `pretrained_model_name_or_path` with any supported [Hugging Face model ID](/model-coverage/large-language-models/overview). -:::{dropdown} About Llama 3.2 1B + Llama is a family of decoder-only transformer models developed by Meta. The 1B variant is a compact model suitable for research and edge deployment, featuring RoPE positional embeddings, grouped-query attention (GQA), and SwiGLU activations. -::: + -:::{dropdown} Accessing gated models + Some Hugging Face models are **gated**. If the model page shows a "Request access" button: 1. Log in with your Hugging Face account and accept the license. 2. Ensure the token you use (from `huggingface-cli login` or `HF_TOKEN`) belongs to the approved account. Pulling a gated model without an authorized token triggers a 403 error. -::: + ### Dataset @@ -179,12 +182,12 @@ validation_dataset: | Key | Role | |-----|------| -| `_target_` | Points to [`make_squad_dataset`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/llm/squad.py) — a factory function that downloads the SQuAD dataset, tokenizes it, and returns a `torch.utils.data.Dataset`. To use a different dataset, change `_target_` to a different factory function (see [Integrate Your Own Text Dataset](dataset.md)). | +| `_target_` | Points to [`make_squad_dataset`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/llm/squad.py) — a factory function that downloads the SQuAD dataset, tokenizes it, and returns a `torch.utils.data.Dataset`. To use a different dataset, change `_target_` to a different factory function (see [Integrate Your Own Text Dataset](/datasets/text-dataset)). | | `dataset_name`, `split` | Keyword arguments passed to `make_squad_dataset`. Each dataset factory defines its own parameters — check the function signature to see what's available. | -This guide uses **SQuAD v1.1** as a running example. Swap the dataset by changing `_target_` and the dataset arguments — see [Integrate Your Own Text Dataset](dataset.md) and [Dataset Overview](../dataset-overview.md). +This guide uses **SQuAD v1.1** as a running example. Swap the dataset by changing `_target_` and the dataset arguments — see [Integrate Your Own Text Dataset](/datasets/text-dataset) and [Dataset Overview: LLM, VLM, and Retrieval Datasets](/datasets/overview). -:::{dropdown} About SQuAD v1.1 + The Stanford Question Answering Dataset (SQuAD) is a reading comprehension dataset where each example consists of a Wikipedia passage, a question, and a span answer. SQuAD v1.1 guarantees all questions are answerable from the context, making it suitable for straightforward fine-tuning. Example: @@ -195,7 +198,7 @@ Example: "answers": { "text": ["Saint Bernadette Soubirous"], "answer_start": [515] } } ``` -::: + ### PEFT (Optional) @@ -256,7 +259,7 @@ All other settings (distributed strategy, optimizer, checkpointing, logging) use ### Full Config YAML -:::{dropdown} finetune_config.yaml (click to expand) + Save as `finetune_config.yaml`. This config runs PEFT (LoRA). To run SFT instead, remove the `peft:` section. For production-ready examples, see the hosted configs: [Llama 3.2 1B SFT](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml) and [Llama 3.2 1B PEFT](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_peft.yaml). ```yaml @@ -283,7 +286,7 @@ validation_dataset: step_scheduler: num_epochs: 1 ``` -::: + ## Fine-Tune the Model @@ -328,7 +331,7 @@ Each log line reports the current loss, gradient norm, peak GPU memory, and toke Checkpoints are saved in native Hugging Face format, so no conversion is required — they work directly with Transformers, PEFT, vLLM, lm-eval-harness, and other tools in the Hugging Face ecosystem. SFT and PEFT produce different checkpoint layouts. **SFT checkpoints** contain the full model weights at `model/consolidated/` — a single, self-contained Hugging Face model directory created by gathering distributed shards into one location — and can be loaded directly. **PEFT checkpoints** contain only the adapter weights (~MBs instead of GBs) — at inference time you must load the original base model and apply the adapter on top. This distinction affects every downstream step (inference, publishing, deployment). -:::{dropdown} Checkpoint directory structure + **SFT checkpoint:** ```bash $ tree checkpoints/epoch_0_step_10/ @@ -373,7 +376,7 @@ checkpoints/epoch_0_step_10/ 2 directories, 8 files ``` -::: + ## Run Inference @@ -471,13 +474,15 @@ lm_eval --model hf \ --batch_size auto ``` -:::{tip} + The SFT example uses the `vllm` backend for faster evaluation (requires `pip install vllm`; see [Deploy with vLLM](#deploy-with-vllm) for setup details). The PEFT example uses the `hf` backend with lm-eval's built-in PEFT support to load the adapter on top of the base model. -::: -:::{tip} + + + Run lm-eval-harness on the base model *before* fine-tuning to establish a baseline, then compare against the fine-tuned checkpoint. -::: + + ## Publish to the Hugging Face Hub @@ -543,9 +548,10 @@ model = PeftModel.from_pretrained(model, "your-username/llama3.2_1b-lora-squad") [vLLM](https://github.com/vllm-project/vllm) is an efficient inference engine for production deployment of LLMs. -:::{note} + Make sure vLLM is installed (`pip install vllm`, or use an environment that includes it). -::: + + ### SFT Checkpoint with vLLM @@ -565,12 +571,13 @@ print(f"Generated text: {outputs[0].outputs[0].text}") PEFT adapter serving uses the `vLLMHFExporter` class, which is provided by the `nemo` package — a separate dependency from `nemo-automodel`. -:::{important} + Install both packages before proceeding: ```bash pip install nemo vllm ``` -::: + + ```python from nemo.export.vllm_hf_exporter import vLLMHFExporter @@ -609,8 +616,7 @@ All other config sections remain the same for both modes. ### Full Configuration -:::{dropdown} Full Config -:open: + ```yaml # Recipe # Selects which recipe class runs the training loop. @@ -769,7 +775,7 @@ optimizer: # name: # display name for this run # save_dir: # local directory for W&B artifacts ``` -::: + ### Config Field Reference @@ -868,9 +874,10 @@ distributed: | `pp_microbatch_size` | Number of samples per micro-batch fed into the pipeline. Must satisfy: `local_batch_size ÷ pp_microbatch_size ≥ pp_size`. | | `layers_per_stage` | How many transformer layers each pipeline stage contains. If omitted, the framework splits layers evenly across `pp_size` stages. | -:::{note} + PP requires the model to define a `_pp_plan` that tells the framework how to split layers into stages. All built-in models include this plan; custom models must add one. -::: + + #### Context Parallelism @@ -884,9 +891,10 @@ distributed: cp_size: 2 ``` -:::{important} + When `cp_size > 1`, fused RoPE is automatically disabled. Some models also require the Transformer Engine (TE) attention backend for CP with packed sequences — the framework will raise an error with instructions if this applies. -::: + + #### Expert Parallelism (MoE models) @@ -928,7 +936,7 @@ When choosing a combination, keep these rules in mind: ## Next Steps -- [Integrate Your Own Text Dataset](dataset.md) — swap the SQuAD example for your own data. -- [Recipes and End-to-End Examples](../overview.md) — browse the full set of recipes available in NeMo AutoModel. See also the [`examples/llm_finetune/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_finetune) directory for ready-to-run configs. -- [Dataset Overview](../dataset-overview.md) — see all supported dataset types across LLM, VLM, and retrieval tasks. -- [Knowledge Distillation](knowledge-distillation.md) — distill a fine-tuned model into a smaller one. +- [Integrate Your Own Text Dataset](/datasets/text-dataset) — swap the SQuAD example for your own data. +- [Recipes and End-to-End Examples](/recipes-e2e-examples/overview) — browse the full set of recipes available in NeMo AutoModel. See also the [`examples/llm_finetune/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_finetune) directory for ready-to-run configs. +- [Dataset Overview: LLM, VLM, and Retrieval Datasets](/datasets/overview) — see all supported dataset types across LLM, VLM, and retrieval tasks. +- [Knowledge Distillation](/recipes-e2e-examples/knowledge-distillation) — distill a fine-tuned model into a smaller one. diff --git a/docs/guides/llm/hy3.mdx b/docs/guides/llm/hy3.mdx index 2bfa3ff519..f0458f2b08 100644 --- a/docs/guides/llm/hy3.mdx +++ b/docs/guides/llm/hy3.mdx @@ -1,5 +1,8 @@ -# Fine-Tune Hy3-preview (HunyuanLarge) - +--- +title: "Hy3-preview" +description: "" +position: 7 +--- ## Introduction [tencent/Hy3-preview](https://huggingface.co/tencent/Hy3-preview) is a 295B Mixture-of-Experts language model from Tencent. It features 80 transformer layers (layer 0 dense, layers 1–79 MoE), 192 routed experts plus one shared expert per MoE block with top-8 sigmoid routing, Grouped Query Attention (64 Q / 8 KV heads, `head_dim=128`), per-head QK RMSNorm applied before RoPE, and an `expert_bias` buffer (surfaced as `e_score_correction_bias` in the Automodel gate) for expert-load correction during inference. The model supports a 256K context window via long-context RoPE (`rope_theta=11158840`). diff --git a/docs/guides/llm/knowledge-distillation.mdx b/docs/guides/llm/knowledge-distillation.mdx index cf88e9aa2e..ca01847b5b 100644 --- a/docs/guides/llm/knowledge-distillation.mdx +++ b/docs/guides/llm/knowledge-distillation.mdx @@ -1,5 +1,8 @@ -# Knowledge Distillation - +--- +title: "Knowledge Distillation with NeMo AutoModel" +description: "" +position: 4 +--- This guide walks through fine-tuning a **student** LLM with the help of a larger **teacher** model using the `kd` (knowledge distillation) recipe. @@ -13,7 +16,6 @@ predicted distributions. The student learns from both the ground-truth labels (Cross-Entropy loss, **CE**) and the soft targets of the teacher (Kullback-Leibler loss, **KD**): - $$ \mathcal{L} = (1-\alpha) \cdot \mathcal{L}_{\textrm{CE}}(p^{s}, y) + \alpha \cdot \mathcal{KL}(p^{s}, p^{t}) $$ diff --git a/docs/guides/llm/large-moe-finetune.mdx b/docs/guides/llm/large-moe-finetune.mdx index ec9048eaef..4f858d418c 100644 --- a/docs/guides/llm/large-moe-finetune.mdx +++ b/docs/guides/llm/large-moe-finetune.mdx @@ -1,8 +1,11 @@ -# Fine-Tune Large MoE LLMs - +--- +title: "Fine-Tune Large MoE LLMs" +description: "" +position: 5 +--- ## Introduction -Mixture-of-Experts (MoE) architectures have become the dominant design for frontier language models, activating only a fraction of their total parameters per token to deliver strong performance at reduced compute cost. This guide walks through fine-tuning four example MoE LLMs with NVIDIA NeMo Automodel. For a full list of supported architectures, see the [LLM model coverage](../../model-coverage/llm/index.md) page. +Mixture-of-Experts (MoE) architectures have become the dominant design for frontier language models, activating only a fraction of their total parameters per token to deliver strong performance at reduced compute cost. This guide walks through fine-tuning four example MoE LLMs with NVIDIA NeMo Automodel. For a full list of supported architectures, see the [LLM model coverage](/model-coverage/large-language-models/overview) page. | Model | HF Checkpoint | Validated Using | |-------|--------------|-----------------| diff --git a/docs/guides/llm/nanogpt-pretraining.mdx b/docs/guides/llm/nanogpt-pretraining.mdx index 8f84dc09bc..0caadec910 100644 --- a/docs/guides/llm/nanogpt-pretraining.mdx +++ b/docs/guides/llm/nanogpt-pretraining.mdx @@ -1,10 +1,13 @@ -# LLM Pre-Training - +--- +title: "LLM Pre-Training with NeMo AutoModel" +description: "" +position: 9 +--- This guide covers **FineWeb** data preparation, **defining** a [NanoGPT‑style](https://github.com/KellerJordan/modded-nanogpt) model, and **launching and monitoring** a NeMo AutoModel pre‑training run. ## Set Up Your Environment -In this guide, we will use an interactive environment to install NeMo AutoModel from Git. You can also install NeMo AutoModel from PyPI or use our bi-monthly Docker container (see the [Installation Guide](../installation.md)). +In this guide, we will use an interactive environment to install NeMo AutoModel from Git. You can also install NeMo AutoModel from PyPI or use our bi-monthly Docker container (see the [Installation Guide](/get-started/installation)). ```bash # clone / install AutoModel (editable for local hacks) @@ -14,40 +17,43 @@ cd Automodel/ pip install -e ".[all]" # installs NeMo AutoModel + optional extras ``` -:::{note} + For this guide, we will use a single machine equipped with 8xH100 NVIDIA GPUs. -::: -:::{tip} -To run this guide on a single GPU, use the single-GPU command in the **Launch Training** section below and scale down the YAML (for example, reduce `step_scheduler.global_batch_size` / `local_batch_size`, and shrink the model using `model.n_layer` / `model.n_embd` / `model.n_head`). For more launch patterns, see [Run on Your Local Workstation](../../launcher/local-workstation.md). -::: + + + +To run this guide on a single GPU, use the single-GPU command in the **Launch Training** section below and scale down the YAML (for example, reduce `step_scheduler.global_batch_size` / `local_batch_size`, and shrink the model using `model.n_layer` / `model.n_embd` / `model.n_head`). For more launch patterns, see [Run on Your Local Workstation](/job-launchers/local-workstation). + + ## Preprocess the FineWeb Dataset -:::{warning} + **File Size Limitation**: The `nanogpt_data_processor.py` script has a **4GB file size limit** (~2^32 bytes) due to 32-bit position tracking in the BOS index. This translates to: -- **~2 billion tokens** when using uint16 (vocabularies < 65,536 tokens, e.g., GPT-2) +- **~2 billion tokens** when using uint16 (vocabularies < 65,536 tokens, e.g., GPT-2) - **~1 billion tokens** when using uint32 (larger vocabularies) Always use the `--max-tokens` flag to stay within these limits (e.g., `--max-tokens 2B` or `--max-tokens 1.5B`). -For larger datasets, please see [pretraining.md](pretraining.md) which supports sharded preprocessing without these constraints. -::: +For larger datasets, please see [pretraining.md](/recipes-e2e-examples/pretraining) which supports sharded preprocessing without these constraints. + + ### Quick Introduction to the FineWeb Dataset The [FineWeb](https://huggingface.co/datasets/HuggingFaceFW/fineweb) dataset consists of more than 18.5T tokens of cleaned and deduplicated English web data from [CommonCrawl](https://commoncrawl.org/). For this guide, we use the **`sample-10BT` subset** (10 billion tokens), from which we extract a smaller sample (e.g., 500M tokens) that fits within the preprocessing tool's limits. Briefly, FineWeb is built by extracting main text from CommonCrawl WARC HTML, keeping English pages using fastText language scoring, applying multiple quality filters (e.g., Gopher repetition/quality checks, C4-style rules, and custom heuristics for list-like or repeated/poorly formatted lines), and then MinHash-deduplicating each crawl independently (5-gram shingling with 14×8 hash functions). Basic PII normalization is applied (e.g., anonymizing emails and public IPs). The result is released per-crawl (and convenient sampled subsets), ready for high-throughput streaming. -:::{tip} -To train on more than 2B tokens from FineWeb, see [pretraining.md](pretraining.md) which uses Megatron Core's sharded dataset format without file size constraints. -::: + +To train on more than 2B tokens from FineWeb, see [pretraining.md](/recipes-e2e-examples/pretraining) which uses Megatron Core's sharded dataset format without file size constraints. + + ### Preprocessing and Tokenization For the purposes of this guide, we provide a data preprocessing tool at [`nanogpt_data_processor.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/tools/nanogpt_data_processor.py) that streams datasets from the Hugging Face Hub, tokenizes using Hugging Face's `transformers.AutoTokenizer` (default: GPT-2), and writes the output in **memory-mapped binary shards** to files. During training, we use the [`NanogptDataset`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/llm/nanogpt_dataset.py) class that can stream efficiently at training time. - ```bash # Step into repo root cd /path/to/workspace/Automodel/ @@ -354,11 +360,12 @@ model: vocab_size: 50258 ``` -:::{note} + - The `model._target_` may reference an import path or a local Python file using the `path.py:object` form. - Any nested mapping that includes `_target_` (e.g., `config:`) is instantiated first and its result is passed upward. This is how the Hugging Face `from_config` pattern works. - You can keep using the same training recipe (optimizer, data, distributed settings); only the `model:` block changes. -::: + + ## Inspect and Adjust the YAML Configuration @@ -421,9 +428,10 @@ automodel examples/llm_pretrain/nanogpt_pretrain.yaml # multi-GPU (8 GPUs) automodel --nproc-per-node 8 examples/llm_pretrain/nanogpt_pretrain.yaml ``` -:::{tip} + Adjust the `distributed` section in the YAML config to change between DDP, FSDP2, etc. -::: + + The `TrainFinetuneRecipeForNextTokenPrediction` class handles: * Distributed (FSDP2 / TP / CP) wrapping if requested in the YAML. @@ -450,6 +458,6 @@ wandb: 1. **Scaling up**: Swap the GPT-2 config for `LlamaForCausalLM`, `Qwen2`, or any Hugging Face-compatible causal model; increase `n_layer`, `n_embd`, etc. 2. **Mixed precision** - FSDP2 + `bfloat16` (`dtype: bfloat16` in distributed config) for memory savings. -3. **Sequence packing** - set `packed_sequence.packed_sequence_size` > 0 to pack variable-length contexts and boost utilization. +3. **Sequence packing** - set `packed_sequence.packed_sequence_size` >0 to pack variable-length contexts and boost utilization. 4. **Custom datasets** - implement your own `IterableDataset` or convert existing corpora to the `.bin` format using `tools/nanogpt_data_processor.py` as a template. 5. **BOS alignment** - set `align_to_bos: true` in the dataset config to ensure sequences start with BOS tokens (requires `bos_token` parameter). diff --git a/docs/guides/llm/pretraining.mdx b/docs/guides/llm/pretraining.mdx index 08153709a1..262432952c 100644 --- a/docs/guides/llm/pretraining.mdx +++ b/docs/guides/llm/pretraining.mdx @@ -1,5 +1,8 @@ -# Pretraining Megatron Core Datasets - +--- +title: "Pretraining Megatron Core Datasets with NeMo AutoModel" +description: "" +position: 8 +--- ## Introduction Pretraining builds a base large language model (LLM) by training a randomly initialized model to predict the next token across massive, unlabeled datasets. @@ -152,9 +155,10 @@ fineweb_edu/megatron_gpt2/ 1 directory, 28 files ``` -:::{tip} + Replace `--workers` with the amount of CPU cores you'd like to use to tokenize in parallel. -::: + + ## Use a Recipe for Pretraining @@ -193,7 +197,6 @@ Below is the configuration from `examples/llm_pretrain/megatron_pretrain_gpt2.ya # See the License for the specific language governing permissions and # limitations under the License. - # To run this recipe, please use the following command: # torchrun --nproc-per-node=8 examples/llm_pretrain/pretrain.py --config examples/llm_pretrain/megatron_pretrain_gpt2.yaml # Adjust --nproc-per-node to the number of GPUs available on your host machine. @@ -306,16 +309,16 @@ lr_scheduler: # save_dir: ``` -:::{tip} + If you want to add weights to the dataset blends, you can do so by passing in a list. For example, `paths: ["30", "fineweb_edu/megatron_gpt2/processed_data_0_text_document", "70", "fineweb_edu/megatron_gpt2/processed_data_1_text_document"]`. -::: + + ## Load Large Models In distributed training, the typical model-loading pipeline has each GPU load the entire model and then retain only the shard it needs. This approach becomes problematic when the model size exceeds the memory capacity of a single GPU. For instance, a 70B-parameter model requires about 140GB of memory for its parameters when using the BF16 data type (2 bytes per parameter). Since most widely used GPUs are limited to 80GB, the full model cannot be directly loaded onto a single device. In these scenarios, you can pass `is_meta_device: true` in the model config. The model will then be instantiated using [PyTorch's Meta device](https://docs.pytorch.org/docs/stable/meta.html) which loads no data, but stores all other parameter metadata necessary for sharding the model. Once the model is sharded, the model weights will be populated by only loading the weights required by the respective model shard. - ## Run the Pretraining Recipe Assuming you saved, or plan to use, the provided config at `examples/llm_pretrain/megatron_pretrain_gpt2.yaml`: @@ -741,10 +744,6 @@ For each training batch, the fine-tuning recipe logs the current loss, along wit As training progresses, you should observe the model loss beginning to converge. To verify your results, you can compare your convergence curves against the baseline benchmarks provided in the [llm.c repository](https://github.com/karpathy/llm.c/discussions/481). -:::{figure} ./gpt2_loss.png -:name: gpt2-train-loss -:alt: Example of GPT-2 training convergence on FineWeb-Edu-10B -:align: center - -Example of GPT-2 training convergence on FineWeb-Edu-10B. -::: + + Example of GPT-2 training convergence on FineWeb-Edu-10B + diff --git a/docs/guides/llm/retrieval-dataset.mdx b/docs/guides/llm/retrieval-dataset.mdx index cafd6ab950..b24fe17aed 100644 --- a/docs/guides/llm/retrieval-dataset.mdx +++ b/docs/guides/llm/retrieval-dataset.mdx @@ -1,5 +1,8 @@ -# Retrieval Dataset (Embedding Fine-tuning) - +--- +title: "Retrieval Dataset (Embedding Fine-tuning)" +description: "" +position: 3 +--- NeMo Automodel supports **retrieval model fine-tuning** using a retrieval-style dataset: each training example is a **query** paired with **one positive** document and **one or more negative** documents. This dataset is used by the retrieval recipes (see `examples/retrieval/bi_encoder/` and `examples/retrieval/cross_encoder/`) together with the `BiEncoderCollator`. @@ -50,10 +53,11 @@ Minimal example: { "class": "TextQADataset", "corpus_id": "wiki_corpus" } ``` -:::{note} + - `pos_doc` and `neg_doc` can be lists of `{"id": ...}` dicts or raw IDs (they are normalized internally). - If you set `use_dataset_instruction: true`, optional fields like `query_instruction` and `passage_instruction` in `merlin_metadata.json` are surfaced to the collator. -::: + + ### Inline-Text JSONL (No Corpus Required) @@ -66,7 +70,7 @@ This is convenient for custom fine-tuning pipelines where the documents are incl {"query":"What is Python?","pos_doc":["A programming language."],"neg_doc":"A snake."} ``` -:::{note} + - `query` is accepted (`question` is also accepted as an alias). - `pos_doc` and `neg_doc` can be either: - strings (interpreted as document text), or @@ -74,7 +78,8 @@ This is convenient for custom fine-tuning pipelines where the documents are incl - dicts with at least `text` (optionally `image`, `nr_ocr`) for multimodal use cases. - If `corpus_id` is not provided, it defaults to `__inline__`. - `use_dataset_instruction: true` has no effect for pure inline records (instructions come from corpus metadata). -::: + + ## YAML Usage (Dataset + Collator) @@ -103,4 +108,4 @@ dataloader: ## Requirements - `pos_doc` must be **non-empty**. -- If training requests negatives (e.g., `n_passages > 1`), `neg_doc` must contain **at least one** document. \ No newline at end of file +- If training requests negatives (e.g., `n_passages > 1`), `neg_doc` must contain **at least one** document. diff --git a/docs/guides/llm/sequence-classification.mdx b/docs/guides/llm/sequence-classification.mdx index 99effa7e4f..d3cbcae2a1 100644 --- a/docs/guides/llm/sequence-classification.mdx +++ b/docs/guides/llm/sequence-classification.mdx @@ -1,5 +1,8 @@ -# Sequence Classification (SFT/PEFT) - +--- +title: "Sequence Classification (SFT/PEFT) with NeMo AutoModel" +description: "" +position: 10 +--- ## Introduction Sequence classification tasks (e.g., sentiment analysis, topic classification, GLUE tasks) map input text to a discrete label. NeMo AutoModel provides a lightweight recipe specialized for this setting that integrates with popular pretrained model formats and dataset sources. Integration with Hugging Face is supported. @@ -96,7 +99,6 @@ optimizer: lr: 3.0e-4 weight_decay: 0 - ``` ## Dataset Notes @@ -116,4 +118,3 @@ optimizer: torchrun --nproc-per-node=2 examples/llm_seq_cls/seq_cls.py --config examples/llm_seq_cls/glue/mrpc_roberta_lora.yaml ``` You can adjust the number of GPUs as necessary using the `--nproc-per-node` knob. - diff --git a/docs/guides/llm/toolcalling.mdx b/docs/guides/llm/toolcalling.mdx index 29c2899998..81eaa5fcc5 100644 --- a/docs/guides/llm/toolcalling.mdx +++ b/docs/guides/llm/toolcalling.mdx @@ -1,8 +1,10 @@ -# Function Calling with FunctionGemma - +--- +title: "Function Calling with NeMo AutoModel using FunctionGemma" +description: "" +position: 3 +--- This tutorial walks through fine-tuning [FunctionGemma](https://huggingface.co/google/functiongemma-270m-it), Google's 270M function-calling model, with NeMo AutoModel on the xLAM function-calling dataset. - ## FunctionGemma Introduction FunctionGemma is a lightweight, 270M-parameter variant built on the Gemma 3 architecture with a function-calling chat format. It is intended to be fine-tuned for task-specific function calling, and its compact size makes it practical for edge or resource-constrained deployments. - Gemma 3 architecture, updated tokenizer, and function-calling chat format. @@ -12,7 +14,7 @@ FunctionGemma is a lightweight, 270M-parameter variant built on the Gemma 3 arch ## Prerequisites - Install NeMo AutoModel and its extras: `pip install nemo-automodel`. -- A FunctionGemma checkpoint available locally or using . +- A FunctionGemma checkpoint available locally or using [https://huggingface.co/google/functiongemma-270m-it](https://huggingface.co/google/functiongemma-270m-it). - Small model footprint: can be fine-tuned on a single GPU; scale batch/sequence as needed. ## xLAM Dataset @@ -48,7 +50,6 @@ Example entry: } ``` - The helper `make_xlam_dataset` converts each xLAM row into OpenAI-style tool schemas and tool calls, then renders them through the chat template so loss is applied only on the tool-call arguments: ```python @@ -82,13 +83,9 @@ def _format_example( ) ``` - - ## Run Full-Parameter SFT Use the ready-made config at [`examples/llm_finetune/gemma/functiongemma_xlam.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/functiongemma_xlam.yaml) to start fine-tuning: - - With the config in place, launch training (8 GPUs shown; adjust `--nproc-per-node` as needed): ```bash @@ -98,11 +95,11 @@ automodel --nproc-per-node=8 examples/llm_finetune/gemma/functiongemma_xlam.yaml You should be able to see a training loss curve similar to the one shown below:

- FunctionGemma SFT loss + FunctionGemma SFT loss

## Run PEFT (LoRA) -To apply LoRA (PEFT), uncomment the `peft` block in the config and tune rank/alpha/targets per the [SFT/PEFT guide](finetune.md). Example override: +To apply LoRA (PEFT), uncomment the `peft` block in the config and tune rank/alpha/targets per the [SFT/PEFT guide](/recipes-e2e-examples/sft-peft). Example override: ```yaml peft: @@ -118,5 +115,5 @@ automodel examples/llm_finetune/gemma/functiongemma_xlam.yaml ```

- FunctionGemma PEFT loss + FunctionGemma PEFT loss

diff --git a/docs/guides/mlflow-logging.mdx b/docs/guides/mlflow-logging.mdx index 7b5422c3b0..6ba0c43b19 100644 --- a/docs/guides/mlflow-logging.mdx +++ b/docs/guides/mlflow-logging.mdx @@ -1,5 +1,8 @@ -# MLflow Logging - +--- +title: "MLflow Logging in NeMo AutoModel" +description: "" +position: 5 +--- ## Introduction MLflow is an open-source platform for managing the machine learning lifecycle, including experiment tracking, model versioning, and deployment. NeMo AutoModel integrates with MLflow to log training metrics, parameters, and artifacts during model training. @@ -89,9 +92,10 @@ NeMo AutoModel automatically logs the following information to MLflow: - Model checkpoints (if configured) - Training configuration files -:::{note} + Only rank 0 in distributed training logs to MLflow to avoid duplicate entries and reduce overhead. -::: + + ## Usage Example @@ -253,4 +257,4 @@ If metrics aren't appearing in MLflow: - [MLflow Documentation](https://mlflow.org/docs/latest/index.html) - [MLflow Tracking](https://mlflow.org/docs/latest/tracking.html) - [MLflow Python API](https://mlflow.org/docs/latest/python_api/index.html) -- [NeMo AutoModel Examples](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples) \ No newline at end of file +- [NeMo AutoModel Examples](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples) diff --git a/docs/guides/omni/gemma3-3n.mdx b/docs/guides/omni/gemma3-3n.mdx index ecb81eb97d..6e658f44b9 100644 --- a/docs/guides/omni/gemma3-3n.mdx +++ b/docs/guides/omni/gemma3-3n.mdx @@ -1,5 +1,8 @@ -# Fine-Tune Gemma 3 and Gemma 3n - +--- +title: "Fine-Tune Gemma 3 and Gemma 3n" +description: "" +position: 11 +--- This document explains how to fine-tune Gemma 3 and Gemma 3n using NeMo AutoModel. It outlines key operations, including initiating SFT and PEFT-LoRA runs and managing experiment configurations using YAML. To set up your environment to run NeMo AutoModel, follow the [Installation Guide](https://github.com/NVIDIA-NeMo/Automodel#-install-nemo-automodel). @@ -131,7 +134,7 @@ NeMo AutoModel uses a flexible configuration system that combines YAML configura The simplest way to run fine-tuning is with a YAML configuration file. We provide configs for both Gemma 3 and Gemma 3n. -:::{note} + These VLM recipes require the optional `vlm` dependency set. If you see `ImportError: qwen_vl_utils is not installed`, install VLM dependencies first: ```bash @@ -139,7 +142,8 @@ uv sync --frozen --extra vlm ``` (If you're using pip: `pip3 install "nemo-automodel[vlm]"`.) -::: + + #### Run Gemma 3 Fine-Tuning @@ -225,16 +229,11 @@ peft: The training loss should look similar to the example below: -```{image} medpix_peft.jpg -:alt: Training Loss Curve -:class: bg-primary -:width: 400px -:align: center -``` +![Training Loss Curve](./medpix_peft.jpg) ### Checkpointing -We support training state checkpointing in either [Safetensors](https://huggingface.co/docs/safetensors/en/index) or [PyTorch DCP](https://docs.pytorch.org/tutorials/recipes/distributed_checkpoint_recipe.html) format. +We support training state checkpointing in either [Safetensors](https://huggingface.co/docs/safetensors/en) or [PyTorch DCP](https://docs.pytorch.org/tutorials/recipes/distributed_checkpoint_recipe.html) format. ```yaml checkpoint: @@ -268,7 +267,7 @@ After fine-tuning your Gemma 3 or Gemma 3n model, you can use it for inference o ### Generation Script -The inference functionality is provided through [`examples/vlm_generate/generate.py`](../../../examples/vlm_generate/generate.py), which supports loading fine-tuned checkpoints and performing image-text generation. +The inference functionality is provided through [`examples/vlm_generate/generate.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_generate/generate.py), which supports loading fine-tuned checkpoints and performing image-text generation. #### Basic Usage @@ -307,12 +306,7 @@ uv run examples/vlm_generate/generate.py \ Given the following image: -```{image} medpix.jpg -:alt: Sample image from the MedPix dataset -:class: bg-primary -:width: 200px -:align: center -``` +![Sample image from the MedPix dataset](./medpix.jpg) And the prompt: diff --git a/docs/guides/overview.mdx b/docs/guides/overview.mdx index 058819490d..8f44d8b9aa 100644 --- a/docs/guides/overview.mdx +++ b/docs/guides/overview.mdx @@ -1,3 +1,8 @@ +--- +title: "Recipes and End-to-End Examples" +description: "" +position: 1 +--- ## Recipes and End-to-End Examples NeMo Automodel is organized around two key concepts: recipes and components. @@ -9,7 +14,7 @@ Components are modular, plug-and-play building blocks referenced using the `_tar This page maps the ready-to-run recipes found in the `examples/` directory to their intended use cases, representative model families, and the most relevant how-to guides. - Examples root: [examples/ (GitHub)](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples) -- Getting started: [Installation](installation.md) +- Getting started: [Install NeMo AutoModel](/get-started/installation) ## Large Language Models (LLM) This section provides practical recipes and configurations for working with large language models across three core workflows: fine-tuning, pretraining, and knowledge distillation. @@ -20,7 +25,7 @@ End-to-end fine-tuning recipes for many open models. Each subfolder contains YAM - Folder: [examples/llm_finetune](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_finetune) - Representative families: Llama 3.1/3.2/3.3, Gemma 2/3, Falcon 3, Mistral/Mixtral, Nemotron, Granite, Starcoder, Qwen, Baichuan, GLM, OLMo, Phi, GPT-OSS, Moonlight -- How-to guide: [LLM finetuning](llm/finetune.md) +- How-to guide: [LLM finetuning](/recipes-e2e-examples/sft-peft) ### Pretraining @@ -29,8 +34,8 @@ Starter configurations and scripts for pretraining with datasets from different - Folder: [examples/llm_pretrain](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_pretrain) - Example models: GPT-2 baseline, NanoGPT, DeepSeek-V3, Moonlight 16B TE (Slurm) - How-to guides: - - [LLM pretraining](llm/pretraining.md) - - [Pretraining with NanoGPT](llm/nanogpt-pretraining.md) + - [LLM pretraining](/recipes-e2e-examples/pretraining) + - [Pretraining with NanoGPT](/recipes-e2e-examples/nanogpt-pretraining) ### Knowledge Distillation (KD) @@ -38,7 +43,7 @@ Recipes for distilling knowledge from a large teacher model into a smaller, more - Folder: [examples/llm_kd](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_kd) - Example model: Llama 3.2 1B -- How-to guide: [Knowledge distillation](llm/knowledge-distillation.md) +- How-to guide: [Knowledge distillation](/recipes-e2e-examples/knowledge-distillation) ### Benchmark Configurations @@ -47,7 +52,6 @@ Curated configurations for benchmarking different training stacks and settings ( - Folder: [examples/llm_benchmark](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark) - Representative configurations: DeepSeek-V3, GPT-OSS (20B/120B), Kimi K2, Moonlight 16B, Qwen3 MoE 30B - ## Vision Language Models (VLM) This section provides practical recipes and configurations for working with vision language models, covering fine-tuning and generation workflows for multimodal tasks. @@ -57,7 +61,7 @@ Fine-tuning recipes for VLMs. - Folder: [examples/vlm_finetune](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/vlm_finetune) - Representative family: Gemma 3 (various configurations) -- How-to guide: [Gemma 3n: Efficient multimodal fine-tuning](omni/gemma3-3n.md) +- How-to guide: [Gemma 3n: Efficient multimodal fine-tuning](/recipes-e2e-examples/gemma-3-3n) ### Generation @@ -75,7 +79,7 @@ End-to-end ASR fine-tuning of `Qwen3-Omni-30B-A3B-Instruct` on any HuggingFace a - Folder: [examples/audio_finetune/qwen3_omni_asr](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/audio_finetune/qwen3_omni_asr) - Representative model: Qwen3-Omni-30B-A3B-Instruct -- How-to guide: [Fine-tune Qwen3-Omni for ASR](audio/qwen3-omni-asr.md) +- How-to guide: [Fine-tune Qwen3-Omni for ASR](/recipes-e2e-examples/qwen3-omni-asr) ## Diffusion Models (Text-to-Image & Text-to-Video) @@ -89,7 +93,7 @@ Fine-tuning recipes for adapting pretrained diffusion models to your data. - Folder: [examples/diffusion/finetune](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/diffusion/finetune) - Representative models: FLUX.1-dev (T2I, 12B), Wan 2.1 T2V 1.3B, HunyuanVideo 1.5 -- How-to guide: [Diffusion fine-tuning](diffusion/finetune.md) +- How-to guide: [Diffusion fine-tuning](/recipes-e2e-examples/diffusion-fine-tuning) ### Pretraining @@ -97,7 +101,7 @@ Pretraining recipes for training diffusion models from scratch on large-scale da - Folder: [examples/diffusion/pretrain](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/diffusion/pretrain) - Representative models: Wan 2.1 T2V 1.3B, FLUX.1-dev -- How-to guide: [Diffusion fine-tuning (pretraining section)](diffusion/finetune.md#configure-your-training-recipe) +- How-to guide: [Diffusion fine-tuning (pretraining section)](/recipes-e2e-examples/diffusion-fine-tuning#configure-your-training-recipe) ### Generation @@ -105,14 +109,14 @@ Generation scripts and configs for running inference with pretrained or fine-tun - Folder: [examples/diffusion/generate](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/diffusion/generate) - Representative models: Wan 2.1 1.3B, FLUX.1-dev, HunyuanVideo -- How-to guide: [Diffusion generation](diffusion/finetune.md#generation--inference) +- How-to guide: [Diffusion generation](/recipes-e2e-examples/diffusion-fine-tuning#generation--inference) ### Dataset Preparation Preprocessing pipeline to create `.meta` files containing VAE latents and text embeddings. -- How-to guide: [Diffusion dataset preparation](diffusion/dataset.md) +- How-to guide: [Diffusion dataset preparation](/datasets/diffusion-dataset) --- -If you are new to the project, begin with the [Installation](installation.md) guide. Then, select a recipe category above and follow its linked how-to guide(s). The provided YAML configurations can serve as templates—customize them by adapting model names, datasets, and precision settings to match your specific needs. +If you are new to the project, begin with the [Install NeMo AutoModel](/get-started/installation) guide. Then, select a recipe category above and follow its linked how-to guide(s). The provided YAML configurations can serve as templates—customize them by adapting model names, datasets, and precision settings to match your specific needs. diff --git a/docs/guides/pipelining.mdx b/docs/guides/pipelining.mdx index 751f98e24f..2c4a3457c3 100644 --- a/docs/guides/pipelining.mdx +++ b/docs/guides/pipelining.mdx @@ -1,5 +1,8 @@ -# Pipeline Parallelism with AutoPipeline - +--- +title: "Pipeline Parallelism with AutoPipeline" +description: "" +position: 3 +--- ## Introduction As large language models continue to grow in size, training and fine-tuning them efficiently across multiple GPUs has become increasingly challenging. While data parallelism works well for smaller models, models with billions of parameters require more sophisticated parallelization strategies to overcome memory constraints and communication overhead. @@ -12,7 +15,6 @@ For custom models and more granular control, the functional API in `nemo_automod This guide walks you through the complete process of using AutoPipeline for Hugging Face models and the functional API for custom models. You'll learn how to configure pipeline stages, integrate with existing training workflows, optimize performance, and combine pipeline parallelism with other parallelization strategies. - **Prerequisites:** ```bash @@ -26,10 +28,11 @@ uv pip install nemo-automodel # Or install from source for the latest features uv pip install git+https://github.com/NVIDIA-NeMo/Automodel.git ``` -:::{important} + Before proceeding with this guide, please ensure that you have NeMo AutoModel installed on your machine. -For a complete guide and additional options please consult the AutoModel [Installation Guide](./installation.md). -::: +For a complete guide and additional options please consult the AutoModel [Installation Guide](/get-started/installation). + + ## Key Features diff --git a/docs/guides/quantization-aware-training.mdx b/docs/guides/quantization-aware-training.mdx index 04b91d0db6..e0caf4b497 100644 --- a/docs/guides/quantization-aware-training.mdx +++ b/docs/guides/quantization-aware-training.mdx @@ -1,5 +1,8 @@ -# Quantization-Aware Training (QAT) - +--- +title: "Quantization-Aware Training (QAT) in NeMo Automodel" +description: "" +position: 18 +--- NeMo Automodel supports Quantization-Aware Training (QAT) for Supervised Fine-Tuning (SFT) using [TorchAO](https://github.com/pytorch/ao). QAT simulates quantization effects during the training process, allowing models to adapt to lower precision representations while learning. This approach produces quantized models that maintain significantly higher accuracy compared to applying quantization after training is complete. ## What is Quantization-Aware Training? @@ -182,7 +185,7 @@ After converting to actual quantization: - **Speed**: 2-4x faster inference depending on hardware and model size - **Memory**: ~4x reduction in model size -- **Accuracy**: Minimal degradation compared to full-precision models (typically <1% difference) +- **Accuracy**: Minimal degradation compared to full-precision models (typically <1% difference) ### When to Use QAT @@ -257,8 +260,8 @@ This allows the model to learn basic patterns before introducing quantization co |---------------------|----------------------|----------------| | Full Precision (BF16) | Baseline | Baseline | | Post-Training Quantization | 1-3% | 4x | -| QAT (8da4w) | <1% | 4x | -| QAT (4w) | <1.5% | 4x (weights only) | +| QAT (8da4w) | <1% | 4x | +| QAT (4w) | <1.5% | 4x (weights only) | ### Optimization Strategies diff --git a/docs/guides/vlm/dataset.mdx b/docs/guides/vlm/dataset.mdx index 557709cab9..74cfb2c878 100644 --- a/docs/guides/vlm/dataset.mdx +++ b/docs/guides/vlm/dataset.mdx @@ -1,5 +1,8 @@ -# Integrate Your Own Multi-Modal Dataset - +--- +title: "Integrate Your Own Multi-Modal Dataset" +description: "" +position: 6 +--- This guide shows you how to integrate your own dataset into NeMo Automodel for training. You'll learn about **multi-modal datasets** that combine text with images or other modalities. We'll cover how to create custom datasets by implementing the required methods and preprocessing functions, and finally show you how to specify your own data logic using YAML configuration with file paths—allowing you to define custom dataset processing without modifying the main codebase. @@ -9,7 +12,6 @@ You'll learn about **multi-modal datasets** that combine text with images or oth | 🖼️ Multi-modal | Vision + Language | MedPix-VQA | `apply_chat_template`, collate fn | [Jump](#multi-modal-datasets) | | 🎤 Audio | Speech + Language | Common Voice 17| `apply_chat_template`, collate fn | [Jump](#audio-datasets) | - ## Multi-modal Datasets Multi-modal datasets combine text with other input types (e.g., images, audio, or video) and are essential for training Vision-Language Models (VLMs). These datasets introduce specific challenges such as aligning modalities, batching diverse data types, and formatting prompts for multi-turn, multi-modal dialogue. @@ -97,14 +99,12 @@ The example dataset preprocessing performs the following steps: For more detailed examples of how to process multi-modal datasets, see the examples in [`datasets.py`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/vlm/datasets.py). - ### Collate Functions NeMo Automodel provides specialized collate functions for different VLM processors. The collate function is responsible for batching examples and preparing them for model input. Multi-modal models require custom collate functions to batch and process each sample correctly. If your model uses a Hugging Face `AutoProcessor`, you can use it directly. Otherwise, you can define your own collate logic and point to it in your YAML config. We provide [example custom collate functions](https://github.com/NVIDIA-NeMo/Automodel/blob/main/nemo_automodel/components/datasets/vlm/collate_fns.py) that you can use as references for your implementation. After you implement your own collate function, you can specify it in your YAML config. - ## YAML-based Custom Dataset Configuration NeMo Automodel supports YAML-based dataset specification using the _target_ key. This lets you reference dataset-building classes or functions using either: @@ -135,7 +135,6 @@ dataset: ``` This will call `build_my_dataset()` from the specified file with the other keys (e.g., num_blocks) as arguments. This approach allows you to integrate custom datasets via config alone—no need to alter the codebase or package structure. - ## Custom Chat Template By default, VLM fine-tuning uses the chat template built into the model's `AutoProcessor`. To use a custom template, add `chat_template` under `dataset:` in your YAML config: diff --git a/docs/guides/vlm/gemma4.mdx b/docs/guides/vlm/gemma4.mdx index 229b13247a..7fdafb7385 100644 --- a/docs/guides/vlm/gemma4.mdx +++ b/docs/guides/vlm/gemma4.mdx @@ -1,5 +1,8 @@ -# Fine-Tuning Gemma 4 31B on CORD-v2 Receipts — End-to-End Guide - +--- +title: "Fine-Tuning Gemma 4 31B on CORD-v2 Receipts — End-to-End Guide" +description: "" +position: 12 +--- **A step-by-step guide for fine-tuning Gemma 4 31B to extract structured receipt data from scanned images using [NeMo Automodel](https://github.com/NVIDIA-NeMo/Automodel).** @@ -174,7 +177,6 @@ def compute_ned(pred: str, target: str) -> float: prev = tmp return dp[n] / max(m, n) - def run_gemma4_inference(model, processor, pil_image, prompt="Describe this image.", max_new_tokens=1024): """Run Gemma 4 inference on a single image.""" @@ -202,7 +204,6 @@ def run_gemma4_inference(model, processor, pil_image, prompt="Describe this imag prompt_length = len(processor.decode(inputs["input_ids"][0], skip_special_tokens=True)) return generated_text[prompt_length:].strip() - def evaluate_receipts(model, processor, test_dataset, n_samples=20): """Evaluate model on receipt test set, return avg NED and per-sample results.""" model.eval() @@ -498,7 +499,7 @@ Example parsed output (test sample 4): | **Average NED** | **0.0601** | | **Field-Level Accuracy** | **92.6%** | | Perfect matches (NED=0.0) | 10/20 (50%) | -| Near-perfect (NED<0.05) | 14/20 (70%) | +| Near-perfect (NED<0.05) | 14/20 (70%) | ### Field-level extraction accuracy (actual) diff --git a/docs/guides/vlm/mistral-medium-3-5.mdx b/docs/guides/vlm/mistral-medium-3-5.mdx index e9a9cd8671..76d62e5c73 100644 --- a/docs/guides/vlm/mistral-medium-3-5.mdx +++ b/docs/guides/vlm/mistral-medium-3-5.mdx @@ -1,5 +1,8 @@ -# Fine-Tune Mistral Medium 3.5 VLM - +--- +title: "Mistral Medium 3.5 VL" +description: "" +position: 15 +--- ## Introduction [Mistral Medium 3.5](https://huggingface.co/mistralai) is Mistral AI's @@ -67,7 +70,6 @@ configuration, environment variables, etc.), see the [Run on a Cluster](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/launcher/slurm.md) guide. - **Before you start**: - Hugging Face applies rate limits on downloads. We recommend cloning @@ -77,7 +79,6 @@ guide. - To enable Weights & Biases logging, set your `WANDB_API_KEY` and configure the `wandb` section in the YAML file. - ## Training Results The recipe produces a healthy initial loss aligned with the HF @@ -93,5 +94,5 @@ The training loss curves for Mistral Medium 3.5 fine-tuned on MedPix-VQA are shown below.

- Mistral Medium 3.5 Training Loss Curve + Mistral Medium 3.5 Training Loss Curve

diff --git a/docs/guides/vlm/nemotron-omni.mdx b/docs/guides/vlm/nemotron-omni.mdx index 2ca682c306..30ec1e7644 100644 --- a/docs/guides/vlm/nemotron-omni.mdx +++ b/docs/guides/vlm/nemotron-omni.mdx @@ -1,5 +1,8 @@ -# Fine-Tuning NemotronOmni on CORD-v2 Receipts — End-to-End Guide - +--- +title: "Nemotron-Omni" +description: "" +position: 14 +--- **A step-by-step guide for fine-tuning NemotronOmni (33B MoE) to extract structured receipt data from scanned images using [NeMo Automodel](https://github.com/NVIDIA-NeMo/Automodel). Covers both full SFT and LoRA PEFT.** @@ -63,9 +66,10 @@ git clone -b nemotron-omni ssh://git@gitlab-master.nvidia.com:12051/huiyingl/aut cd automodel-omni ``` -:::{note} + NemotronOmni requires `mamba_ssm`, `causal_conv1d`, and `decord` packages, which are included in the NeMo AutoModel container. -::: + + --- diff --git a/docs/guides/vlm/qwen3-5.mdx b/docs/guides/vlm/qwen3-5.mdx index 65f0088cdb..d0408f31ef 100644 --- a/docs/guides/vlm/qwen3-5.mdx +++ b/docs/guides/vlm/qwen3-5.mdx @@ -1,10 +1,13 @@ -# Fine-Tune Qwen3.5-VL - +--- +title: "Fine-Tune Qwen3.5-VL" +description: "" +position: 13 +--- ## Introduction [Qwen/Qwen3.5-397B-A17B](https://huggingface.co/Qwen/Qwen3.5-397B-A17B) is the latest vision-language model in the Qwen series developed by Alibaba. It’s a 397B-parameter (17B active) hybrid MoE model that uses a repeated layout of Gated DeltaNet and Gated Attention blocks, each paired with sparse MoE (512 experts; 10 routed + 1 shared active). Qwen3.5 is a major upgrade that unifies vision+language, boosts efficiency and multilingual coverage, delivering higher performance at lower latency/cost for developers and enterprises. Qwen3.5-397B-A17B shows competitive benchmark performance across knowledge, reasoning, coding, and agent tasks.

- Qwen3.5 benchmark + Qwen3.5 benchmark

This guide walks you through fine-tuning Qwen3.5 on a medical Visual Question Answering task using NVIDIA NeMo Automodel. You will learn how to prepare the dataset, launch training on a Slurm cluster, and inspect the results. @@ -58,5 +61,5 @@ srun --output=output.out \ The training loss curves for Qwen3.5-VL fine-tuned on MedPix-VQA are shown below.

- Qwen3.5-VL Training Loss Curve -

\ No newline at end of file + Qwen3.5-VL Training Loss Curve +

diff --git a/docs/index.mdx b/docs/index.mdx index 7c13422298..55dc2708eb 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -1,62 +1,30 @@ --- - +title: "NeMo AutoModel Documentation" description: "NeMo AutoModel is a PyTorch DTensor-native SPMD open-source training library for scalable LLM and VLM training and fine-tuning with day-0 Hugging Face model support" - -categories: - -- documentation -- home -tags: -- training -- fine-tuning -- distributed -- gpu-accelerated -- spmd -- dtensor -personas: -- Machine Learning Engineers -- Data Scientists -- Researchers -- DevOps Professionals -difficulty: beginner -content_type: index --- - -(automodel-home)= - -# NeMo AutoModel Documentation +import { Tag } from "@/components/Tag"; PyTorch-native training that scales from 1 GPU to thousands with a single config change. Load any Hugging Face model, point at your data, and start training; no checkpoint conversion and no boilerplate. -**Quick links:** [🤗 HF Compatible](guides/huggingface-api-compatibility.md) | [🚀 Performance](performance-summary.md) | [📐 Scalability](about/key-features.md) | [🎯 SFT & PEFT](guides/llm/finetune.md) | [🎨 Diffusion](guides/diffusion/finetune.md) | [👁️ VLM](guides/vlm/gemma4.md) +**Quick links:** [🤗 HF Compatible](/get-started/hf-compatibility) | [🚀 Performance](/performance/performance-summary) | [📐 Scalability](/get-started/key-features) | [🎯 SFT & PEFT](/recipes-e2e-examples/sft-peft) | [🎨 Diffusion](/recipes-e2e-examples/diffusion-fine-tuning) | [👁️ VLM](/recipes-e2e-examples/gemma-4) -::::{grid} 2 2 2 2 -:gutter: 1 1 1 2 - -:::{grid-item-card} {octicon}`book;1.5em;sd-mr-1` About -:link: about/index -:link-type: doc + + Overview of NeMo AutoModel and its capabilities. -::: + -:::{grid-item-card} {octicon}`zap;1.5em;sd-mr-1` Key Features -:link: about/key-features -:link-type: doc + Supported workflows, parallelism, recipes, and benchmarks. -::: + -:::{grid-item-card} {octicon}`hubot;1.5em;sd-mr-1` 🤗 HF Integration -:link: guides/huggingface-api-compatibility -:link-type: doc + A `transformers`-compatible library with accelerated model implementations. -::: + -:::{grid-item-card} {octicon}`checklist;1.5em;sd-mr-1` Model Coverage -:link: model-coverage/overview -:link-type: doc + Built on `transformers` for day-0 model support and OOTB compatibility. -::: + -:::: + ## Get Started @@ -66,13 +34,13 @@ uv pip install nemo-automodel automodel --nproc-per-node=2 llama3_2_1b_squad.yaml ``` -See the [installation guide](guides/installation.md) for Docker, source builds, and multi-node setup. -See the [configuration guide](guides/configuration.md) for YAML recipes and CLI overrides. -Launch on a [local workstation](launcher/local-workstation.md) or [SLURM cluster](launcher/slurm.md). +See the [installation guide](/get-started/installation) for Docker, source builds, and multi-node setup. +See the [configuration guide](/get-started/configuration) for YAML recipes and CLI overrides. +Launch on a [local workstation](/job-launchers/local-workstation) or [SLURM cluster](/job-launchers/slurm-cluster). ## Latest Model Support -New models are added regularly. Pick a model below to start fine-tuning, or see the [full release log](model-coverage/latest-models.md). +New models are added regularly. Pick a model below to start fine-tuning, or see the [full release log](/model-coverage/release-log). | Date | Modality | Model | |------|----------|-------| @@ -89,216 +57,105 @@ Find the right guide for your task: fine-tuning, pretraining, distillation, diff | I want to... | Choose this when... | Input Data | Model | Guide | | --------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------- | --------- | --------------------------------------------------------- | -| **SFT (full fine-tune)** | You need maximum accuracy and have the GPU budget to update all weights | Instruction / chat dataset | LLM | [Start fine-tuning](guides/llm/finetune.md) | -| **PEFT (LoRA)** | You want to fine-tune on limited GPU memory; updates <1 % of parameters | Instruction / chat dataset | LLM | [Start LoRA](guides/llm/finetune.md) | -| **Tool / function calling** | Your model needs to call APIs or tools with structured arguments | Function-calling dataset (queries + tool schemas) | LLM | [Add tool calling](guides/llm/toolcalling.md) | -| **Fine-tune VLM** | Your task involves both images and text (e.g., visual QA, captioning) | Image + text dataset | VLM | [Fine-tune VLM](guides/omni/gemma3-3n.md) | -| **Fine-tune Gemma 4** | You want to fine-tune Gemma 4 for structured extraction from images (e.g., receipts) | Image + text dataset | VLM | [Fine-tune Gemma 4](guides/vlm/gemma4.md) | -| **Fine-tune dLLM** | You want to fine-tune a diffusion language model (e.g., LLaDA) using masked denoising | Instruction / chat dataset | dLLM | [Fine-tune dLLM](guides/dllm/finetune.md) | -| **Fine-tune Diffusion** | You want to fine-tune a diffusion model for image or video generation | Video / Image dataset | Diffusion | [Fine-tune Diffusion](guides/diffusion/finetune.md) | -| **Fine-tune VLM-MoE** | You need large-scale vision-language training with sparse MoE efficiency | Image + text dataset | VLM (MoE) | [Fine-tune VLM-MoE](guides/vlm/qwen3-5.md) | -| **Fine-tune Audio ASR** | Adapt Qwen3-Omni for speech recognition on HF audio datasets | Audio + transcript dataset | Qwen3-Omni | [Fine-tune Qwen3-Omni ASR](guides/audio/qwen3-omni-asr.md) | -| **Embedding fine-tune** | You want to improve text similarity for search, retrieval, or RAG | Text pairs / retrieval corpus | LLM | {bdg-info}`Coming Soon` | -| **Fine-tune a large MoE** | You are adapting a large sparse MoE model (DeepSeek-V3, GLM-5, etc.) to your domain | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune MoE](guides/llm/large-moe-finetune.md) | -| **Fine-tune DeepSeek V4 Flash** | You want to fine-tune the DeepSeek V4 Flash hybrid-attention MoE (SWA / CSA / HCA + hash-routing) | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune DeepSeek V4 Flash](guides/llm/dsv4-flash.md) | -| **Fine-tune Hy3-preview** | You want to fine-tune Tencent's 295B MoE with sigmoid routing and per-head QK RMSNorm | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune Hy3-preview](guides/llm/hy3.md) | -| **Sequence classification** | You need to classify text into categories (sentiment, topic, NLI) | Text + labels (e.g., GLUE MRPC) | LLM | [Train classifier](guides/llm/sequence-classification.md) | -| **QAT fine-tune** | You want a quantized model that keeps accuracy for efficient deployment | Text dataset | LLM | [Enable QAT](guides/quantization-aware-training.md) | -| **Knowledge distillation** | You want a smaller, faster model that retains most of the teacher's quality | Instruction dataset + teacher model | LLM | [Distill a model](guides/llm/knowledge-distillation.md) | -| **Pretrain an LLM** | You are building a base model from scratch on your own corpus | Large unlabeled text corpus (e.g., FineWeb-Edu) | LLM | [Start pretraining](guides/llm/pretraining.md) | -| **Pretrain (NanoGPT)** | You want quick pretraining experiments on a single node | FineWeb / text corpus | LLM | [Try NanoGPT](guides/llm/nanogpt-pretraining.md) | +| **SFT (full fine-tune)** | You need maximum accuracy and have the GPU budget to update all weights | Instruction / chat dataset | LLM | [Start fine-tuning](/recipes-e2e-examples/sft-peft) | +| **PEFT (LoRA)** | You want to fine-tune on limited GPU memory; updates <1 % of parameters | Instruction / chat dataset | LLM | [Start LoRA](/recipes-e2e-examples/sft-peft) | +| **Tool / function calling** | Your model needs to call APIs or tools with structured arguments | Function-calling dataset (queries + tool schemas) | LLM | [Add tool calling](/recipes-e2e-examples/function-calling) | +| **Fine-tune VLM** | Your task involves both images and text (e.g., visual QA, captioning) | Image + text dataset | VLM | [Fine-tune VLM](/recipes-e2e-examples/gemma-3-3n) | +| **Fine-tune Gemma 4** | You want to fine-tune Gemma 4 for structured extraction from images (e.g., receipts) | Image + text dataset | VLM | [Fine-tune Gemma 4](/recipes-e2e-examples/gemma-4) | +| **Fine-tune dLLM** | You want to fine-tune a diffusion language model (e.g., LLaDA) using masked denoising | Instruction / chat dataset | dLLM | [Fine-tune dLLM](/recipes-e2e-examples/dllm-fine-tuning) | +| **Fine-tune Diffusion** | You want to fine-tune a diffusion model for image or video generation | Video / Image dataset | Diffusion | [Fine-tune Diffusion](/recipes-e2e-examples/diffusion-fine-tuning) | +| **Fine-tune VLM-MoE** | You need large-scale vision-language training with sparse MoE efficiency | Image + text dataset | VLM (MoE) | [Fine-tune VLM-MoE](/recipes-e2e-examples/qwen3-5-vl) | +| **Fine-tune Audio ASR** | Adapt Qwen3-Omni for speech recognition on HF audio datasets | Audio + transcript dataset | Qwen3-Omni | [Fine-tune Qwen3-Omni ASR](/recipes-e2e-examples/qwen3-omni-asr) | +| **Embedding fine-tune** | You want to improve text similarity for search, retrieval, or RAG | Text pairs / retrieval corpus | LLM | Coming Soon | +| **Fine-tune a large MoE** | You are adapting a large sparse MoE model (DeepSeek-V3, GLM-5, etc.) to your domain | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune MoE](/recipes-e2e-examples/large-moe-fine-tuning) | +| **Fine-tune DeepSeek V4 Flash** | You want to fine-tune the DeepSeek V4 Flash hybrid-attention MoE (SWA / CSA / HCA + hash-routing) | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune DeepSeek V4 Flash](/recipes-e2e-examples/deepseek-v4-flash) | +| **Fine-tune Hy3-preview** | You want to fine-tune Tencent's 295B MoE with sigmoid routing and per-head QK RMSNorm | Text dataset (e.g., HellaSwag) | LLM (MoE) | [Fine-tune Hy3-preview](/recipes-e2e-examples/hy3-preview) | +| **Sequence classification** | You need to classify text into categories (sentiment, topic, NLI) | Text + labels (e.g., GLUE MRPC) | LLM | [Train classifier](/recipes-e2e-examples/sequence-classification) | +| **QAT fine-tune** | You want a quantized model that keeps accuracy for efficient deployment | Text dataset | LLM | [Enable QAT](/recipes-e2e-examples/qat) | +| **Knowledge distillation** | You want a smaller, faster model that retains most of the teacher's quality | Instruction dataset + teacher model | LLM | [Distill a model](/recipes-e2e-examples/knowledge-distillation) | +| **Pretrain an LLM** | You are building a base model from scratch on your own corpus | Large unlabeled text corpus (e.g., FineWeb-Edu) | LLM | [Start pretraining](/recipes-e2e-examples/pretraining) | +| **Pretrain (NanoGPT)** | You want quick pretraining experiments on a single node | FineWeb / text corpus | LLM | [Try NanoGPT](/recipes-e2e-examples/nanogpt-pretraining) | ## Performance Training throughput on NVIDIA GPUs with optimized kernels for Hugging Face models. - | Model | GPUs | TFLOPs/sec/GPU | Tokens/sec/GPU | Optimizations | | ---------------- | ---- | -------------- | -------------- | ---------------------- | | DeepSeek V3 671B | 256 | 250 | 1,002 | TE + DeepEP | | GPT-OSS 20B | 8 | 279 | 13,058 | TE + DeepEP + FlexAttn | | Qwen3 MoE 30B | 8 | 277 | 12,040 | TE + DeepEP | - -See the [full benchmark results](performance-summary.md) for configuration details and more models. +See the [full benchmark results](/performance/performance-summary) for configuration details and more models. ## Advanced Topics Parallelism, precision, checkpointing strategies, and experiment tracking. -::::{grid} 1 2 2 3 -:gutter: 1 1 1 2 - -:::{grid-item-card} {octicon}`git-merge;1.5em;sd-mr-1` Pipeline Parallelism -:link: guides/pipelining -:link-type: doc + + Torch-native pipelining composable with FSDP2 and DTensor. -+++ -{bdg-secondary}`3d-parallelism` -::: + + -:::{grid-item-card} {octicon}`zap;1.5em;sd-mr-1` FP8 Training -:link: guides/fp8-training -:link-type: doc + Mixed-precision FP8 training with torchao. -+++ -{bdg-secondary}`FP8` {bdg-secondary}`mixed-precision` -::: +FP8 mixed-precision + -:::{grid-item-card} {octicon}`database;1.5em;sd-mr-1` Checkpointing -:link: guides/checkpointing -:link-type: doc + Distributed checkpoints with SafeTensors output. -+++ -{bdg-secondary}`DCP` {bdg-secondary}`safetensors` -::: +DCP safetensors + -:::{grid-item-card} {octicon}`shield-check;1.5em;sd-mr-1` Gradient Checkpointing -:link: guides/gradient-checkpointing -:link-type: doc + Trade compute for memory with activation checkpointing. -+++ -{bdg-secondary}`memory-efficiency` -::: +memory-efficiency + -:::{grid-item-card} {octicon}`meter;1.5em;sd-mr-1` Quantization-Aware Training -:link: guides/quantization-aware-training -:link-type: doc + Train with quantization for deployment-ready models. -+++ -{bdg-secondary}`QAT` -::: +QAT + -:::{grid-item-card} {octicon}`graph;1.5em;sd-mr-1` Experiment Tracking -:link: guides/mlflow-logging -:link-type: doc + Track experiments and metrics with MLflow and Wandb. -+++ -{bdg-secondary}`MLflow` {bdg-secondary}`Wandb` -::: +MLflow Wandb + -:::: + ## For Developers -::::{grid} 1 2 2 3 -:gutter: 1 1 1 2 - -:::{grid-item-card} {octicon}`file-directory;1.5em;sd-mr-1` Repo Internals -:link: repository-structure -:link-type: doc + + Components, recipes, and CLI architecture. -::: + -:::{grid-item-card} {octicon}`code;1.5em;sd-mr-1` API Reference -:link: apidocs/index -:link-type: doc + Auto-generated Python API documentation. -::: + -:::{grid-item-card} {octicon}`plug;1.5em;sd-mr-1` Use as a Library -:link: about/index -:link-type: doc + Drop-in accelerated backend for TRL, lm-eval-harness, OpenRLHF, or any code that loads Hugging Face models. -::: + -:::: + --- -::::{toctree} -:hidden: -:caption: Get Started -About -Key Features -Installation -Configuration -🤗 HF Compatibility -Repo Structure -Release Notes -:::: - -::::{toctree} -:hidden: -:caption: Announcements -announcements.md -:::: - -::::{toctree} -:hidden: -:caption: Performance -performance-summary.md -:::: - -::::{toctree} -:hidden: -:caption: Model Coverage -Overview -Release Log -Large Language Models -Vision Language Models -Omni -Diffusion -Embedding Models -Reranking Models -:::: - -::::{toctree} -:hidden: -:caption: Recipes & E2E Examples -Overview -SFT & PEFT -Function Calling -guides/llm/knowledge-distillation.md -Large MoE Fine-Tuning -DeepSeek V4 Flash -Hy3-preview -Pretraining -NanoGPT Pretraining -Sequence Classification -Gemma 3 / 3n -Gemma 4 -Qwen3.5-VL -Nemotron-Omni -Mistral Medium 3.5 VL -Qwen3-Omni ASR -Diffusion Fine-Tuning -dLLM Fine-Tuning -QAT -Databricks -:::: - -::::{toctree} -:hidden: -:caption: Datasets -Overview -Text Dataset -Retrieval Dataset -ColumnMapped Dataset -ColumnMapped Iterable -Multi-Modal Dataset -Diffusion Dataset -:::: - -::::{toctree} -:hidden: -:caption: Job Launchers -Overview -Local Workstation -SLURM Cluster -NeMo Run -SkyPilot -SkyPilot k8s -:::: - -::::{toctree} -:hidden: -:caption: Development -guides/checkpointing.md -Gradient Checkpointing -Pipeline Parallelism -guides/fp8-training.md -guides/mlflow-logging.md -API Reference -Breaking Changes -:::: +:: + +:: + +:: + +:: + +:: + +:: + +:: + +:: diff --git a/docs/launcher/local-workstation.mdx b/docs/launcher/local-workstation.mdx index cd5cf01a7d..b2fcb26b9e 100644 --- a/docs/launcher/local-workstation.mdx +++ b/docs/launcher/local-workstation.mdx @@ -1,9 +1,12 @@ -# Run on Your Local Workstation +--- +title: "Run on Your Local Workstation" +description: "" +position: 2 +--- +Use this guide for local, single-node workflows on a workstation or an interactive Slurm allocation. For setup details, refer to our [Installation Guide](/get-started/installation). +For batch multi-node jobs, see the [Run on a Cluster](/job-launchers/slurm-cluster) or [SkyPilot](/job-launchers/skypilot) guides. -Use this guide for local, single-node workflows on a workstation or an interactive Slurm allocation. For setup details, refer to our [Installation Guide](../guides/installation.md). -For batch multi-node jobs, see the [Slurm](./slurm.md) or [SkyPilot](./skypilot.md) guides. - -NeMo AutoModel uses recipes to run end-to-end workflows. If you're new to recipes, see the [Repository Structure](../repository-structure.md) guide. +NeMo AutoModel uses recipes to run end-to-end workflows. If you're new to recipes, see the [Repository Structure](/get-started/repo-structure) guide. ## Quick Start: Choose Your Job Launch Option @@ -24,7 +27,7 @@ NeMo AutoModel uses recipes to run end-to-end workflows. If you're new to recipe ## Run with AutoModel CLI (Single Node) -The AutoModel CLI is the preferred method for most users. It offers a unified interface to launch training scaling from a local workstation (this guide) to large clusters (see our [cluster guide](./slurm.md)). +The AutoModel CLI is the preferred method for most users. It offers a unified interface to launch training scaling from a local workstation (this guide) to large clusters (see our [cluster guide](/job-launchers/slurm-cluster)). ### Basic Usage @@ -64,7 +67,7 @@ automodel --nproc-per-node 2 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya If you don't specify `--nproc-per-node`, it will use all available GPUs on your system. -Looking for Slurm or cloud training? See [Slurm](./slurm.md) or [SkyPilot](./skypilot.md). +Looking for Slurm or cloud training? See [Run on a Cluster](/job-launchers/slurm-cluster) or [SkyPilot](/job-launchers/skypilot). ## Run with uv (Development Mode) @@ -110,7 +113,7 @@ python nemo_automodel/recipes/llm/train_ft.py -c examples/llm_finetune/llama3_2/ torchrun --nproc-per-node=2 nemo_automodel/recipes/llm/train_ft.py -c examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml ``` -This approach requires that you have already installed NeMo AutoModel and its dependencies in your Python environment (see the [installation guide](../guides/installation.md) for details). +This approach requires that you have already installed NeMo AutoModel and its dependencies in your Python environment (see the [installation guide](/get-started/installation) for details). ## Customize Configuration Settings @@ -147,4 +150,4 @@ For example, if you want to fine-tune `Qwen/Qwen3-0.6B` instead of `meta-llama/L - You're working in environments where uv is not available - You're integrating with existing PyTorch workflows -All approaches use the same configuration files and provide the same training capabilities on a single node. For multi-node training, see [Run on a Cluster](./slurm.md). +All approaches use the same configuration files and provide the same training capabilities on a single node. For multi-node training, see [Run on a Cluster](/job-launchers/slurm-cluster). diff --git a/docs/launcher/nemo-run.mdx b/docs/launcher/nemo-run.mdx index 1c19021c61..855ad340f9 100644 --- a/docs/launcher/nemo-run.mdx +++ b/docs/launcher/nemo-run.mdx @@ -1,6 +1,9 @@ -# Run with NeMo-Run - -In this guide, you will learn how to launch NeMo AutoModel training jobs using [NeMo-Run](https://github.com/NVIDIA-NeMo/Run). NeMo-Run supports multiple backends including Slurm, Kubernetes, Docker, and local execution. For cloud-based training, see [Run on Any Cloud with SkyPilot](./skypilot.md). For direct sbatch usage, see [Run on a Cluster (Slurm)](./slurm.md). For single-node workstation usage, see [Run on Your Local Workstation](./local-workstation.md). +--- +title: "Run with NeMo-Run" +description: "" +position: 4 +--- +In this guide, you will learn how to launch NeMo AutoModel training jobs using [NeMo-Run](https://github.com/NVIDIA-NeMo/Run). NeMo-Run supports multiple backends including Slurm, Kubernetes, Docker, and local execution. For cloud-based training, see [Run on Any Cloud with SkyPilot](/job-launchers/skypilot). For direct sbatch usage, see [Run on a Cluster (Slurm)](/job-launchers/slurm-cluster). For single-node workstation usage, see [Run on Your Local Workstation](/job-launchers/local-workstation). NeMo-Run is an open-source tool from NVIDIA that manages job submission across different execution backends. You define your compute configuration once in a Python file and reuse it across all your training jobs. diff --git a/docs/launcher/overview.mdx b/docs/launcher/overview.mdx index f4c28c4661..25dbad8fd8 100644 --- a/docs/launcher/overview.mdx +++ b/docs/launcher/overview.mdx @@ -1,15 +1,18 @@ -# Job Launchers - +--- +title: "Job Launchers" +description: "" +position: 1 +--- NeMo AutoModel provides several ways to launch training. The right choice depends on your hardware and environment. ## Which Launcher Should I Use? | Launcher | Best for | GPUs | Guide | |---|---|---|---| -| **Local Workstation** | Getting started, debugging, single-node training | 1-8 on one machine | [Local Workstation](./local-workstation.md) | -| **NeMo-Run** | Managed execution on Slurm, Kubernetes, Docker, local | 1+ | [NeMo-Run](./nemo-run.md) | -| **SkyPilot** | Cloud training or Kubernetes clusters | Any | [SkyPilot](./skypilot.md) | -| **Slurm** | Multi-node batch jobs on HPC clusters | 8+ across nodes | [Slurm](./slurm.md) | +| **Local Workstation** | Getting started, debugging, single-node training | 1-8 on one machine | [Run on Your Local Workstation](/job-launchers/local-workstation) | +| **NeMo-Run** | Managed execution on Slurm, Kubernetes, Docker, local | 1+ | [NeMo-Run](/job-launchers/nemo-run) | +| **SkyPilot** | Cloud training or Kubernetes clusters | Any | [SkyPilot](/job-launchers/skypilot) | +| **Slurm** | Multi-node batch jobs on HPC clusters | 8+ across nodes | [Run on a Cluster](/job-launchers/slurm-cluster) | ### I Have 1–2 GPUs on My Workstation @@ -19,7 +22,7 @@ Use the **interactive** launcher. No scheduler or cluster software is needed: automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml ``` -See the [Local Workstation](./local-workstation.md) guide. +See the [Run on Your Local Workstation](/job-launchers/local-workstation) guide. ### I Have Access to a Slurm Cluster @@ -29,7 +32,7 @@ Add a `slurm:` section to your YAML config and submit with the same `automodel` automodel config_with_slurm.yaml ``` -See the [Slurm](./slurm.md) guide. +See the [Run on a Cluster](/job-launchers/slurm-cluster) guide. ### I Want Managed Job Submission (Slurm, Kubernetes, Docker) @@ -39,7 +42,7 @@ Add a `nemo_run:` section to your YAML config. NeMo-Run loads a pre-configured e automodel config_with_nemo_run.yaml ``` -See the [NeMo-Run](./nemo-run.md) guide. +See the [NeMo-Run](/job-launchers/nemo-run) guide. ### I Want to Train on the Cloud @@ -49,7 +52,7 @@ Add a `skypilot:` section to your YAML config. SkyPilot provisions VMs on any ma automodel config_with_skypilot.yaml ``` -See the [SkyPilot](./skypilot.md) guide. +See the [SkyPilot](/job-launchers/skypilot) guide. ### I Want to Train on Kubernetes with SkyPilot @@ -59,7 +62,7 @@ Use the same `skypilot:` launcher, but set `cloud: kubernetes`. This is a good f automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml ``` -See the [SkyPilot + Kubernetes tutorial](./skypilot-kubernetes.md). +See the [SkyPilot + Kubernetes tutorial](/job-launchers/skypilot-k8s). ## All Launchers Use the Same Config diff --git a/docs/launcher/skypilot-kubernetes.mdx b/docs/launcher/skypilot-kubernetes.mdx index 3b8692c252..0dd5af1159 100644 --- a/docs/launcher/skypilot-kubernetes.mdx +++ b/docs/launcher/skypilot-kubernetes.mdx @@ -1,5 +1,8 @@ -# SkyPilot + Kubernetes Tutorial - +--- +title: "SkyPilot k8s" +description: "" +position: 6 +--- This tutorial shows how to run NeMo AutoModel on a Kubernetes cluster through SkyPilot. You will: @@ -23,7 +26,7 @@ You need: If you are setting up SkyPilot on Kubernetes for the first time, the official SkyPilot Kubernetes setup guide is here: -- +- [https://docs.skypilot.co/en/latest/reference/kubernetes/kubernetes-setup.html](https://docs.skypilot.co/en/latest/reference/kubernetes/kubernetes-setup.html) Install the SkyPilot Kubernetes client in your AutoModel environment: @@ -75,7 +78,7 @@ If you do not see any GPUs here, stop and fix the Kubernetes or SkyPilot setup f The easiest starting point is a one-GPU fine-tune using the existing Llama 3.2 1B SQuAD example. -This repository now includes a Kubernetes-flavored SkyPilot config at [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml`](../../examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml). +This repository now includes a Kubernetes-flavored SkyPilot config at [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml). Launch it from the repo root: @@ -138,7 +141,7 @@ torchrun --nproc_per_node=1 ~/sky_workdir/nemo_automodel/recipes/llm/train_ft.py Once the single-node job works, scaling out is just a small YAML change. -Use the two-node example at [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes_2nodes.yaml`](../../examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes_2nodes.yaml): +Use the two-node example at [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes_2nodes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes_2nodes.yaml): ```bash automodel examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes_2nodes.yaml @@ -228,7 +231,7 @@ Start with the single-node example first. If that works, check that: If you want to adapt this tutorial for your own model, the quickest path is: -1. Copy [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml`](../../examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml). +1. Copy [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot_kubernetes.yaml). 2. Change the `model` and dataset sections. 3. Keep the `skypilot:` block small until the first run succeeds. diff --git a/docs/launcher/skypilot.mdx b/docs/launcher/skypilot.mdx index 55d4061fac..90a074849b 100644 --- a/docs/launcher/skypilot.mdx +++ b/docs/launcher/skypilot.mdx @@ -1,6 +1,9 @@ -# Run with SkyPilot - -In this guide, you will learn how to launch NeMo AutoModel training jobs with [SkyPilot](https://docs.skypilot.co/en/stable/docs/). SkyPilot can target public clouds such as AWS, GCP, Azure, and Lambda, and it can also submit jobs to Kubernetes clusters. For a beginner-friendly Kubernetes walkthrough, see [SkyPilot + Kubernetes tutorial](./skypilot-kubernetes.md). For on-premises cluster usage without SkyPilot, see [Run on a Cluster (Slurm)](./slurm.md). For single-node workstation usage, see [Run on Your Local Workstation](./local-workstation.md). +--- +title: "Run on Any Cloud with SkyPilot" +description: "" +position: 5 +--- +In this guide, you will learn how to launch NeMo AutoModel training jobs with [SkyPilot](https://docs.skypilot.co/en/stable/docs/). SkyPilot can target public clouds such as AWS, GCP, Azure, and Lambda, and it can also submit jobs to Kubernetes clusters. For a beginner-friendly Kubernetes walkthrough, see [SkyPilot + Kubernetes tutorial](/job-launchers/skypilot-k8s). For on-premises cluster usage without SkyPilot, see [Run on a Cluster (Slurm)](/job-launchers/slurm-cluster). For single-node workstation usage, see [Run on Your Local Workstation](/job-launchers/local-workstation). SkyPilot is an open-source framework that abstracts cloud infrastructure so you can train on whichever cloud is cheapest or most available at launch time — including automatic spot-instance handling for significant cost savings. @@ -45,7 +48,7 @@ The CLI detects the `skypilot:` key, strips it from the training config, uploads ## Configuration Reference -Below is an annotated example for fine-tuning Llama-3.2-1B on SQuAD on a GCP spot T4. A ready-to-run copy lives at [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot.yaml`](../../examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot.yaml). +Below is an annotated example for fine-tuning Llama-3.2-1B on SQuAD on a GCP spot T4. A ready-to-run copy lives at [`examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad_skypilot.yaml). ```yaml # ── SkyPilot launcher section ───────────────────────────────────────────── @@ -178,7 +181,7 @@ automodel config_with_skypilot.yaml \ ## Kubernetes Users -If you want to run on a Kubernetes cluster, use `cloud: kubernetes` and follow the dedicated [SkyPilot + Kubernetes tutorial](./skypilot-kubernetes.md). That guide includes: +If you want to run on a Kubernetes cluster, use `cloud: kubernetes` and follow the dedicated [SkyPilot + Kubernetes tutorial](/job-launchers/skypilot-k8s). That guide includes: - a copy-paste single-node config - a two-node example diff --git a/docs/launcher/slurm.mdx b/docs/launcher/slurm.mdx index 1ac5ec65c5..1978b0c6bc 100644 --- a/docs/launcher/slurm.mdx +++ b/docs/launcher/slurm.mdx @@ -1,9 +1,11 @@ -# Run on a Cluster - -In this guide, you will learn how to submit distributed training jobs on Slurm clusters (single- or multi-node). For single-node workstation usage, see [Run on Your Local Workstation](./local-workstation.md). For setup details, refer to our [Installation Guide](../guides/installation.md). - -NeMo AutoModel uses recipes to run end-to-end workflows. If you're new to recipes, see the [Repository Structure](../repository-structure.md) guide. +--- +title: "Run on a Cluster" +description: "" +position: 3 +--- +In this guide, you will learn how to submit distributed training jobs on Slurm clusters (single- or multi-node). For single-node workstation usage, see [Run on Your Local Workstation](/job-launchers/local-workstation). For setup details, refer to our [Installation Guide](/get-started/installation). +NeMo AutoModel uses recipes to run end-to-end workflows. If you're new to recipes, see the [Repository Structure](/get-started/repo-structure) guide. ## Quickstart @@ -63,7 +65,6 @@ All cluster-specific configuration (SBATCH directives, container runtime, mounts, NCCL tuning, secrets) lives in your sbatch script where you can see and edit it directly. - ### Examples **Pyxis container (NVIDIA clusters):** @@ -160,7 +161,6 @@ srun apptainer exec --nv /shared/images/automodel.sif \ -m nemo_automodel.cli.app ${CONFIG}" ``` - ### Launch with Modified Code If the script is executed from within a Git repository accessible to Slurm @@ -189,4 +189,4 @@ You can customize training by following the steps in this section. 3. **Create custom configs**: Copy and modify existing configurations from the `examples/` directory. -For single-node workflows, see our [Run on Your Local Workstation](./local-workstation.md) guide. +For single-node workflows, see our [Run on Your Local Workstation](/job-launchers/local-workstation) guide. diff --git a/docs/model-coverage/diffusion/black-forest-labs/flux.mdx b/docs/model-coverage/diffusion/black-forest-labs/flux.mdx index 40d51cafc3..c83291307c 100644 --- a/docs/model-coverage/diffusion/black-forest-labs/flux.mdx +++ b/docs/model-coverage/diffusion/black-forest-labs/flux.mdx @@ -1,15 +1,19 @@ -# FLUX.1-dev - +--- +title: "FLUX.1-dev" +description: "" +--- [FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev) is a 12B parameter text-to-image diffusion transformer from Black Forest Labs, trained with flow matching. It produces high-fidelity images and is designed for non-commercial research and development use. -:::{card} + + | | | |---|---| | **Task** | Text-to-Image | | **Architecture** | DiT (Flow Matching) | | **Parameters** | 12B | | **HF Org** | [black-forest-labs](https://huggingface.co/black-forest-labs) | -::: + + ## Available Models @@ -29,13 +33,12 @@ | Recipe | Description | |---|---| -| {download}`flux_t2i_flow.yaml <../../../../examples/diffusion/finetune/flux_t2i_flow.yaml>` | Fine-tune — FLUX.1-dev with flow matching | -| {download}`flux_t2i_flow.yaml <../../../../examples/diffusion/pretrain/flux_t2i_flow.yaml>` | Pretrain — FLUX.1-dev with flow matching | - +| [flux_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/flux_t2i_flow.yaml) | Fine-tune — FLUX.1-dev with flow matching | +| [flux_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/pretrain/flux_t2i_flow.yaml) | Pretrain — FLUX.1-dev with flow matching | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -56,7 +59,7 @@ torchrun --nproc-per-node=8 \ -c examples/diffusion/finetune/flux_t2i_flow.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -79,13 +82,13 @@ torchrun --nproc-per-node=8 \ examples/diffusion/finetune/finetune.py \ -c examples/diffusion/finetune/flux_t2i_flow.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [Diffusion Fine-Tuning Guide](../../../guides/diffusion/finetune.md). +See the [Installation Guide](/get-started/installation) and [Diffusion Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). ## Training -See the [Diffusion Training and Fine-Tuning Guide](../../../guides/diffusion/finetune.md) and [Dataset Preparation](../../../guides/diffusion/dataset.md). +See the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning) and [Dataset Preparation](/datasets/diffusion-dataset). ## Hugging Face Model Cards diff --git a/docs/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx b/docs/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx index 4dc15df7f2..c6f1d0889a 100644 --- a/docs/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx +++ b/docs/model-coverage/diffusion/hunyuanvideo-community/hunyuanvideo.mdx @@ -1,15 +1,19 @@ -# HunyuanVideo 1.5 - +--- +title: "HunyuanVideo 1.5" +description: "" +--- [HunyuanVideo 1.5](https://huggingface.co/hunyuanvideo-community/HunyuanVideo-1.5-Diffusers-720p_t2v) is a 13B parameter text-to-video diffusion model from the Hunyuan community, supporting 720p resolution video generation with flow matching training. -:::{card} + + | | | |---|---| | **Task** | Text-to-Video | | **Architecture** | DiT (Flow Matching) | | **Parameters** | 13B | | **HF Org** | [hunyuanvideo-community](https://huggingface.co/hunyuanvideo-community) | -::: + + ## Available Models @@ -29,12 +33,11 @@ | Recipe | Description | |---|---| -| {download}`hunyuan_t2v_flow.yaml <../../../../examples/diffusion/finetune/hunyuan_t2v_flow.yaml>` | Fine-tune — HunyuanVideo 1.5 with flow matching | - +| [hunyuan_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/hunyuan_t2v_flow.yaml) | Fine-tune — HunyuanVideo 1.5 with flow matching | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -55,7 +58,7 @@ torchrun --nproc-per-node=8 \ -c examples/diffusion/finetune/hunyuan_t2v_flow.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +81,13 @@ torchrun --nproc-per-node=8 \ examples/diffusion/finetune/finetune.py \ -c examples/diffusion/finetune/hunyuan_t2v_flow.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [Diffusion Fine-Tuning Guide](../../../guides/diffusion/finetune.md). +See the [Installation Guide](/get-started/installation) and [Diffusion Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). ## Training -See the [Diffusion Training and Fine-Tuning Guide](../../../guides/diffusion/finetune.md) and [Dataset Preparation](../../../guides/diffusion/dataset.md). +See the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning) and [Dataset Preparation](/datasets/diffusion-dataset). ## Hugging Face Model Cards diff --git a/docs/model-coverage/diffusion/index.mdx b/docs/model-coverage/diffusion/index.mdx index 7b115035a6..3c3fcf0667 100644 --- a/docs/model-coverage/diffusion/index.mdx +++ b/docs/model-coverage/diffusion/index.mdx @@ -1,7 +1,8 @@ -(diffusion-models)= - -# Diffusion Models - +--- +title: "Diffusion Models" +description: "" +position: 6 +--- ## Introduction Diffusion models are a class of generative models that learn to produce images or videos by iteratively denoising samples from a noise distribution. NeMo AutoModel supports training diffusion models using **flow matching**, a framework that regresses velocity fields along straight interpolation paths between noise and data. @@ -12,10 +13,10 @@ NeMo AutoModel integrates with [Hugging Face Diffusers](https://huggingface.co/d | Owner | Model | Task | Architecture | |---|---|---|---| -| Wan AI | [Wan 2.1 T2V](wan-ai/wan2-1-t2v.md) | Text-to-Video | DiT (Flow Matching) | -| Black Forest Labs | [FLUX.1-dev](black-forest-labs/flux.md) | Text-to-Image | DiT (Flow Matching) | -| Hunyuan Community | [HunyuanVideo 1.5](hunyuanvideo-community/hunyuanvideo.md) | Text-to-Video | DiT (Flow Matching) | -| Qwen / Alibaba Cloud | [Qwen-Image](qwen/qwen-image.md) | Text-to-Image | DiT (Flow Matching) | +| Wan AI | [Wan 2.1 T2V](/model-coverage/diffusion/wan-2-1-t2v) | Text-to-Video | DiT (Flow Matching) | +| Black Forest Labs | [FLUX.1-dev](/model-coverage/diffusion/flux-1-dev) | Text-to-Image | DiT (Flow Matching) | +| Hunyuan Community | [HunyuanVideo 1.5](/model-coverage/diffusion/hunyuanvideo-1-5) | Text-to-Video | DiT (Flow Matching) | +| Qwen / Alibaba Cloud | [Qwen-Image](/model-coverage/diffusion/qwen-image) | Text-to-Image | DiT (Flow Matching) | ## Supported Workflows @@ -25,17 +26,8 @@ NeMo AutoModel integrates with [Hugging Face Diffusers](https://huggingface.co/d ## Dataset -Diffusion training requires pre-encoded `.meta` files containing VAE latents and text embeddings. Raw videos or images must be preprocessed before training. See the [Diffusion Dataset Preparation](../../guides/diffusion/dataset.md) guide. +Diffusion training requires pre-encoded `.meta` files containing VAE latents and text embeddings. Raw videos or images must be preprocessed before training. See the [Diffusion Dataset Preparation](/datasets/diffusion-dataset) guide. ## Train Diffusion Models -For a complete walkthrough of training configuration, model-specific settings, and launch commands, see the [Diffusion Training and Fine-Tuning Guide](../../guides/diffusion/finetune.md). - -```{toctree} -:hidden: - -wan-ai/wan2-1-t2v -black-forest-labs/flux -hunyuanvideo-community/hunyuanvideo -qwen/qwen-image -``` +For a complete walkthrough of training configuration, model-specific settings, and launch commands, see the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). diff --git a/docs/model-coverage/diffusion/qwen/qwen-image.mdx b/docs/model-coverage/diffusion/qwen/qwen-image.mdx index 2592e7cba8..e171db2403 100644 --- a/docs/model-coverage/diffusion/qwen/qwen-image.mdx +++ b/docs/model-coverage/diffusion/qwen/qwen-image.mdx @@ -1,14 +1,18 @@ -# Qwen-Image - +--- +title: "Qwen-Image" +description: "" +--- [Qwen-Image](https://huggingface.co/Qwen/Qwen-Image) is Alibaba Cloud's text-to-image diffusion transformer. NeMo AutoModel supports Qwen-Image training via its flow-matching pipeline with a dedicated `qwen_image` adapter, enabling FSDP2 parallelization, multiresolution bucketed dataloading and LoRA-style fine-tuning. -:::{card} + + | | | |---|---| | **Task** | Text-to-Image | | **Architecture** | DiT (Flow Matching) | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -28,13 +32,12 @@ | Recipe | Description | |---|---| -| {download}`qwen_image_t2i_flow.yaml <../../../../examples/diffusion/finetune/qwen_image_t2i_flow.yaml>` | Fine-tune — Qwen-Image with flow matching | -| {download}`qwen_image_t2i_flow.yaml <../../../../examples/diffusion/pretrain/qwen_image_t2i_flow.yaml>` | Pretrain — Qwen-Image with flow matching | - +| [qwen_image_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/qwen_image_t2i_flow.yaml) | Fine-tune — Qwen-Image with flow matching | +| [qwen_image_t2i_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/pretrain/qwen_image_t2i_flow.yaml) | Pretrain — Qwen-Image with flow matching | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -55,7 +58,7 @@ torchrun --nproc-per-node=8 \ -c examples/diffusion/finetune/qwen_image_t2i_flow.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +81,13 @@ torchrun --nproc-per-node=8 \ examples/diffusion/finetune/finetune.py \ -c examples/diffusion/finetune/qwen_image_t2i_flow.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [Diffusion Training and Fine-Tuning Guide](../../../guides/diffusion/finetune.md). +See the [Installation Guide](/get-started/installation) and [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). ## Fine-Tuning -See the [Diffusion Training and Fine-Tuning Guide](../../../guides/diffusion/finetune.md). +See the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx b/docs/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx index ff58648b6c..befb82feef 100644 --- a/docs/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx +++ b/docs/model-coverage/diffusion/wan-ai/wan2-1-t2v.mdx @@ -1,15 +1,19 @@ -# Wan 2.1 T2V - +--- +title: "Wan 2.1 T2V" +description: "" +--- [Wan 2.1](https://huggingface.co/Wan-AI/Wan2.1-T2V-1.3B-Diffusers) is a text-to-video diffusion model from Wan AI, trained with flow matching on a large-scale video dataset. It generates high-quality short video clips from text prompts. -:::{card} + + | | | |---|---| | **Task** | Text-to-Video | | **Architecture** | DiT (Flow Matching) | | **Parameters** | 1.3B | | **HF Org** | [Wan-AI](https://huggingface.co/Wan-AI) | -::: + + ## Available Models @@ -29,13 +33,12 @@ | Recipe | Description | |---|---| -| {download}`wan2_1_t2v_flow.yaml <../../../../examples/diffusion/finetune/wan2_1_t2v_flow.yaml>` | Fine-tune — Wan 2.1 T2V with flow matching | -| {download}`wan2_1_t2v_flow.yaml <../../../../examples/diffusion/pretrain/wan2_1_t2v_flow.yaml>` | Pretrain — Wan 2.1 T2V with flow matching | - +| [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/finetune/wan2_1_t2v_flow.yaml) | Fine-tune — Wan 2.1 T2V with flow matching | +| [wan2_1_t2v_flow.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/diffusion/pretrain/wan2_1_t2v_flow.yaml) | Pretrain — Wan 2.1 T2V with flow matching | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -56,7 +59,7 @@ torchrun --nproc-per-node=8 \ -c examples/diffusion/finetune/wan2_1_t2v_flow.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -79,13 +82,13 @@ torchrun --nproc-per-node=8 \ examples/diffusion/finetune/finetune.py \ -c examples/diffusion/finetune/wan2_1_t2v_flow.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [Diffusion Fine-Tuning Guide](../../../guides/diffusion/finetune.md). +See the [Installation Guide](/get-started/installation) and [Diffusion Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning). ## Training -See the [Diffusion Training and Fine-Tuning Guide](../../../guides/diffusion/finetune.md) and [Dataset Preparation](../../../guides/diffusion/dataset.md). +See the [Diffusion Training and Fine-Tuning Guide](/recipes-e2e-examples/diffusion-fine-tuning) and [Dataset Preparation](/datasets/diffusion-dataset). ## Hugging Face Model Cards diff --git a/docs/model-coverage/embedding/index.mdx b/docs/model-coverage/embedding/index.mdx index 7093ed1874..8c860cec33 100644 --- a/docs/model-coverage/embedding/index.mdx +++ b/docs/model-coverage/embedding/index.mdx @@ -1,12 +1,14 @@ -(embedding-models)= - -# Embedding Models +--- +title: "Embedding Models" +description: "" +position: 1 +--- ## Introduction Text embedding models transform text into dense vector representations that power semantic search, dense retrieval, retrieval-augmented generation (RAG), and classification tasks. NeMo AutoModel includes a training recipe for converting Llama decoder-only models into encoder architectures with bidirectional attention, and falls back to Hugging Face AutoModel for other encoder backbones. -For cross-encoder pairwise scoring, see [Reranking Models](../reranker/index.md). +For cross-encoder pairwise scoring, see [Reranking Models](/model-coverage/reranking-models/overview). Embedding models use bi-encoders to produce dense representations for queries and documents independently. They are the standard path for embedding generation and first-stage dense retrieval. @@ -14,8 +16,8 @@ Embedding models use bi-encoders to produce dense representations for queries an | Owner | Model | Architecture | Auto Class | Tasks | |---|---|---|---|---| -| NVIDIA | [Llama (Bidirectional)](nvidia/llama-bidirectional.md) | `LlamaBidirectionalModel` | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Embedding, Dense Retrieval | -| Mistral AI | [Ministral3 (Bidirectional)](mistralai/ministral3-bidirectional.md) | `Ministral3BidirectionalModel` | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Embedding, Dense Retrieval | +| NVIDIA | [Llama (Bidirectional)](/model-coverage/embedding-models/llama-bidirectional) | `LlamaBidirectionalModel` | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Embedding, Dense Retrieval | +| Mistral AI | [Ministral3 (Bidirectional)](/model-coverage/embedding-models/ministral3-bidirectional) | `Ministral3BidirectionalModel` | [`NeMoAutoModelBiEncoder`](https://github.com/NVIDIA-NeMo/Automodel/blob/8dc00dcb4a35c2413c52c6e7eb7ac8f1c24836aa/nemo_automodel/_transformers/auto_model.py#L991) | Embedding, Dense Retrieval | ### Hugging Face Auto Backbones @@ -25,9 +27,9 @@ Any Hugging Face model that can be loaded with `AutoModel` can be used as an emb | Recipe | Description | |---|---| -| {download}`llama3_2_1b.yaml <../../../examples/retrieval/bi_encoder/llama3_2_1b.yaml>` | Bi-encoder — Llama 3.2 1B embedding model | -| {download}`llama_embed_nemotron_8b.yaml <../../../examples/retrieval/bi_encoder/llama_embed_nemotron_8b/llama_embed_nemotron_8b.yaml>` | Bi-encoder — Llama-Embed-Nemotron-8B reproduction recipe | -[ [download}`ministral3_3b_instruct.yaml <../../../examples/retrieval/bi_encoder/ministral3_3b_instruct.yaml>` | Bi-encoder — Ministral3-3B recipe | +| [llama3_2_1b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama3_2_1b.yaml) | Bi-encoder — Llama 3.2 1B embedding model | +| [llama_embed_nemotron_8b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama_embed_nemotron_8b/llama_embed_nemotron_8b.yaml) | Bi-encoder — Llama-Embed-Nemotron-8B reproduction recipe | +| [ministral3_3b_instruct.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/ministral3_3b_instruct.yaml) | Bi-encoder — Ministral3-3B recipe | ## Supported Workflows @@ -37,18 +39,11 @@ Any Hugging Face model that can be loaded with `AutoModel` can be used as an emb ## Dataset -Retrieval fine-tuning requires query-document pairs: each example is a query paired with one positive document and one or more negative documents. Both inline JSONL and corpus ID-based JSON formats are supported. See the [Retrieval Dataset](../../guides/llm/retrieval-dataset.md) guide. +Retrieval fine-tuning requires query-document pairs: each example is a query paired with one positive document and one or more negative documents. Both inline JSONL and corpus ID-based JSON formats are supported. See the [Retrieval Dataset](/datasets/retrieval-dataset) guide. - - -```{toctree} -:hidden: - -nvidia/llama-bidirectional -mistralai/ministral3-bidirectional -``` +For a complete walkthrough of training configuration, model-specific settings, and launch commands, see the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune). +*/} diff --git a/docs/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx b/docs/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx index 37f85ed980..255d59bb3d 100644 --- a/docs/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx +++ b/docs/model-coverage/embedding/mistralai/ministral3-bidirectional.mdx @@ -1,17 +1,18 @@ -# Ministral3 (Bidirectional) for Embedding +--- +title: "Ministral3 (Bidirectional) for Embedding" +description: "" +--- NeMo AutoModel provides a bidirectional variant of [Mistral AI's Ministral3](https://mistral.ai/news/ministraux/) for embedding and dense retrieval tasks. Unlike the standard causal (left-to-right) Ministral3 used for text generation, this variant uses **bidirectional attention**, so each token can attend to both past and future tokens in the sequence, producing richer representations for semantic similarity and dense retrieval. The bidirectional encoder can be loaded directly from text-only checkpoints (e.g. `mistralai/Ministral-3B-Instruct`) and also automatically extracts the language model from Ministral3 VLM checkpoints (e.g. `mistralai/Ministral-3-3B-Base-2512` or `mistralai/Ministral-3-3B-Instruct-2512`). -:::{card} | | | |---|---| | **Tasks** | Embedding, Dense Retrieval | | **Architecture** | `Ministral3BidirectionalModel` | | **Parameters** | 3B | | **HF Org** | [mistralai](https://huggingface.co/mistralai) | -::: ## Available Models @@ -48,7 +49,7 @@ The bi-encoder supports multiple pooling strategies to aggregate token represent ## Try with NeMo AutoModel -**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](../../../guides/installation.md)) for information: +**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](/get-started/installation)) for information: ```bash uv pip install nemo-automodel @@ -68,13 +69,13 @@ torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config e torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/ministral3_3b_instruct.yaml ``` -See the [Installation Guide](../../../guides/installation.md). +See the [Installation Guide](/get-started/installation). - +See the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune) for bi-encoder training instructions, including LoRA and PEFT configuration. +*/} ## Hugging Face Model Cards diff --git a/docs/model-coverage/embedding/nvidia/llama-bidirectional.mdx b/docs/model-coverage/embedding/nvidia/llama-bidirectional.mdx index 3f0830ec37..dd4851039a 100644 --- a/docs/model-coverage/embedding/nvidia/llama-bidirectional.mdx +++ b/docs/model-coverage/embedding/nvidia/llama-bidirectional.mdx @@ -1,17 +1,18 @@ -# Llama (Bidirectional) for Embedding +--- +title: "Llama (Bidirectional) for Embedding" +description: "" +--- NeMo AutoModel provides a bidirectional variant of [Meta's Llama](https://www.llama.com/) for embedding and dense retrieval tasks. Unlike the standard causal (left-to-right) Llama used for text generation, this variant uses **bidirectional attention**, so each token can attend to both past and future tokens in the sequence, producing richer representations for semantic similarity and dense retrieval. -For the cross-encoder variant, see [Llama (Bidirectional) for Reranking](../../reranker/nvidia/llama-bidirectional.md). +For the cross-encoder variant, see [Llama (Bidirectional) for Reranking](/model-coverage/reranking-models/llama-bidirectional). -:::{card} | | | |---|---| | **Tasks** | Embedding, Dense Retrieval | | **Architecture** | `LlamaBidirectionalModel` | | **Parameters** | 1B – 8B | | **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | -::: ## Available Models @@ -50,12 +51,12 @@ The bi-encoder supports multiple pooling strategies to aggregate token represent | Recipe | Description | |---|---| -| {download}`llama3_2_1b.yaml <../../../../examples/retrieval/bi_encoder/llama3_2_1b.yaml>` | Bi-encoder — Llama 3.2 1B embedding model | -| {download}`llama_embed_nemotron_8b.yaml <../../../../examples/retrieval/bi_encoder/llama_embed_nemotron_8b/llama_embed_nemotron_8b.yaml>` | Bi-encoder — reproduction recipe for [`nvidia/llama-embed-nemotron-8b`](https://huggingface.co/nvidia/llama-embed-nemotron-8b) (uses [`nvidia/embed-nemotron-dataset-v1`](https://huggingface.co/datasets/nvidia/embed-nemotron-dataset-v1)) | +| [llama3_2_1b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama3_2_1b.yaml) | Bi-encoder — Llama 3.2 1B embedding model | +| [llama_embed_nemotron_8b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/bi_encoder/llama_embed_nemotron_8b/llama_embed_nemotron_8b.yaml) | Bi-encoder — reproduction recipe for [`nvidia/llama-embed-nemotron-8b`](https://huggingface.co/nvidia/llama-embed-nemotron-8b) (uses [`nvidia/embed-nemotron-dataset-v1`](https://huggingface.co/datasets/nvidia/embed-nemotron-dataset-v1)) | ## Try with NeMo AutoModel -**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](../../../guides/installation.md)) for information: +**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](/get-started/installation)) for information: ```bash uv pip install nemo-automodel @@ -74,7 +75,7 @@ cd Automodel torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/llama3_2_1b.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -95,15 +96,15 @@ cd /opt/Automodel ```bash torchrun --nproc-per-node=8 examples/retrieval/bi_encoder/finetune.py --config examples/retrieval/bi_encoder/llama3_2_1b.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md). +See the [Installation Guide](/get-started/installation). - +See the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune) for bi-encoder training instructions, including LoRA and PEFT configuration. +*/} ## Hugging Face Model Card diff --git a/docs/model-coverage/latest-models.mdx b/docs/model-coverage/latest-models.mdx index 15c2329a4b..65d22cb680 100644 --- a/docs/model-coverage/latest-models.mdx +++ b/docs/model-coverage/latest-models.mdx @@ -1,8 +1,11 @@ -# Model Release Log - +--- +title: "Model Release Log" +description: "" +position: 2 +--- A reverse-chronological log of every model added to NeMo AutoModel. The **Recipe** column links to a working example YAML you can run immediately. -See the [Model Coverage Overview](overview.md) for release summaries, and the [LLM](llm/index.md) / [VLM](vlm/index.md) / [Omni](omni/index.md) / [Diffusion](diffusion/index.md) pages for the full architecture listings. +See the [Model Coverage Overview](/model-coverage/overview) for release summaries, and the [LLM](/model-coverage/large-language-models/overview) / [VLM](/model-coverage/vision-language-models/overview) / [Omni](/model-coverage/omni/overview) / [Diffusion](/model-coverage/diffusion/overview) pages for the full architecture listings. | Date | Model | HF Model ID | Modality | Recipe | Try on Brev | |------|-------|-------------|----------|--------|------| @@ -33,7 +36,7 @@ See the [Model Coverage Overview](overview.md) for release summaries, and the [L | 2026-02-04 | Kimi-K2.5 VL | [`moonshotai/Kimi-K2.5`](https://huggingface.co/moonshotai/Kimi-K2.5) | VLM | [kimi25vl_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/kimi/kimi25vl_medpix.yaml) | 🚧 | | 2026-01-30 | Kimi-VL | [`moonshotai/Kimi-VL-A3B-Instruct`](https://huggingface.co/moonshotai/Kimi-VL-A3B-Instruct) | VLM | [kimi2vl_cordv2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/kimi/kimi2vl_cordv2.yaml) | 🚧 | | 2026-01-12 | Nemotron Flash 1B | [`nvidia/Nemotron-Flash-1B`](https://huggingface.co/nvidia/Nemotron-Flash-1B) | LLM | [nemotron_flash_1b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad.yaml) | 🚧 | -| 2026-01-12 | Nemotron Parse v1.1 | [`nvidia/NVIDIA-Nemotron-Parse-v1.1`](https://huggingface.co/nvidia/NVIDIA-Nemotron-Parse-v1.1) | VLM | [nemotron_parse_v1_1.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml) | Launch on Brev | +| 2026-01-12 | Nemotron Parse v1.1 | [`nvidia/NVIDIA-Nemotron-Parse-v1.1`](https://huggingface.co/nvidia/NVIDIA-Nemotron-Parse-v1.1) | VLM | [nemotron_parse_v1_1.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml) | Launch on Brev | | 2026-01-07 | Devstral-Small-2512 | [`mistralai/Devstral-Small-2-24B-Instruct-2512`](https://huggingface.co/mistralai/Devstral-Small-2-24B-Instruct-2512) | LLM | [devstral2_small_2512_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/devstral/devstral2_small_2512_squad.yaml) | 🚧 | | 2025-12-15 | Nemotron-3-Nano-30B-A3B | [`nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-FP8`](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-FP8) | LLM | [nemotron_nano_v3_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_v3_hellaswag.yaml) | 🚧 | | 2025-12-05 | Ministral 3 (3B / 8B / 14B) | [`mistralai/Ministral-8B-Instruct-2410`](https://huggingface.co/mistralai/Ministral-8B-Instruct-2410) | VLM | [ministral3_8b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral/ministral3_8b_medpix.yaml) | 🚧 | diff --git a/docs/model-coverage/llm/allenai/olmo.mdx b/docs/model-coverage/llm/allenai/olmo.mdx index a410ee6400..71f8f56efc 100644 --- a/docs/model-coverage/llm/allenai/olmo.mdx +++ b/docs/model-coverage/llm/allenai/olmo.mdx @@ -1,15 +1,19 @@ -# OLMo - +--- +title: "OLMo" +description: "" +--- [OLMo](https://allenai.org/olmo) (Open Language Model) is Allen AI's fully open language model — open weights, open training data, and open training code. OLMo-1B and OLMo-7B are trained on Dolma. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `OLMoForCausalLM` | | **Parameters** | 1B – 7B | | **HF Org** | [allenai](https://huggingface.co/allenai) | -::: + + ## Available Models @@ -27,12 +31,11 @@ | OLMo 1B | [`allenai/OLMo-1B-hf`](https://huggingface.co/allenai/OLMo-1B-hf) | | OLMo 7B | [`allenai/OLMo-7B-hf`](https://huggingface.co/allenai/OLMo-7B-hf) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/allenai/olmo2.mdx b/docs/model-coverage/llm/allenai/olmo2.mdx index 2a0a2f45ef..84cbacb670 100644 --- a/docs/model-coverage/llm/allenai/olmo2.mdx +++ b/docs/model-coverage/llm/allenai/olmo2.mdx @@ -1,15 +1,19 @@ -# OLMo2 - +--- +title: "OLMo2" +description: "" +--- [OLMo2](https://allenai.org/olmo) is Allen AI's second-generation open language model with improved architecture and training, including RMSNorm and rotary position embeddings. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `OLMo2ForCausalLM` | | **Parameters** | 1B – 13B | | **HF Org** | [allenai](https://huggingface.co/allenai) | -::: + + ## Available Models @@ -32,13 +36,12 @@ | Recipe | Description | |---|---| -| {download}`olmo_2_0425_1b_instruct_squad.yaml <../../../../examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad.yaml>` | SFT — OLMo2 0425 1B Instruct on SQuAD | -| {download}`olmo_2_0425_1b_instruct_squad_peft.yaml <../../../../examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad_peft.yaml>` | LoRA — OLMo2 0425 1B Instruct on SQuAD | - +| [olmo_2_0425_1b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad.yaml) | SFT — OLMo2 0425 1B Instruct on SQuAD | +| [olmo_2_0425_1b_instruct_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad_peft.yaml) | LoRA — OLMo2 0425 1B Instruct on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -57,7 +60,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +81,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/olmo/olmo_2_0425_1b_instruct_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/allenai/olmoe.mdx b/docs/model-coverage/llm/allenai/olmoe.mdx index a4dd25186f..c6d88ca379 100644 --- a/docs/model-coverage/llm/allenai/olmoe.mdx +++ b/docs/model-coverage/llm/allenai/olmoe.mdx @@ -1,15 +1,19 @@ -# OLMoE - +--- +title: "OLMoE" +description: "" +--- [OLMoE](https://allenai.org/olmo) is Allen AI's open Mixture-of-Experts language model. It activates 1B parameters per token from a 7B total parameter pool. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `OLMoEForCausalLM` | | **Parameters** | 7B total / 1B active | | **HF Org** | [allenai](https://huggingface.co/allenai) | -::: + + ## Available Models @@ -27,12 +31,11 @@ | OLMoE 1B 7B | [`allenai/OLMoE-1B-7B-0924`](https://huggingface.co/allenai/OLMoE-1B-7B-0924) | | OLMoE 1B 7B Instruct | [`allenai/OLMoE-1B-7B-0924-Instruct`](https://huggingface.co/allenai/OLMoE-1B-7B-0924-Instruct) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/baai/aquila.mdx b/docs/model-coverage/llm/baai/aquila.mdx index 570aec6010..45ad4fe6bc 100644 --- a/docs/model-coverage/llm/baai/aquila.mdx +++ b/docs/model-coverage/llm/baai/aquila.mdx @@ -1,15 +1,19 @@ -# Aquila / Aquila2 - +--- +title: "Aquila / Aquila2" +description: "" +--- [Aquila](https://huggingface.co/BAAI/Aquila-7B) is a Chinese-English bilingual language model from the Beijing Academy of Artificial Intelligence (BAAI). -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `AquilaForCausalLM` | | **Parameters** | 7B – 34B | | **HF Org** | [BAAI](https://huggingface.co/BAAI) | -::: + + ## Available Models @@ -28,12 +32,11 @@ | Aquila 7B | [`BAAI/Aquila-7B`](https://huggingface.co/BAAI/Aquila-7B) | | AquilaChat 7B | [`BAAI/AquilaChat-7B`](https://huggingface.co/BAAI/AquilaChat-7B) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -55,7 +58,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -77,13 +80,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/baichuan-inc/baichuan.mdx b/docs/model-coverage/llm/baichuan-inc/baichuan.mdx index c501d4f5db..bd2d4dcfd2 100644 --- a/docs/model-coverage/llm/baichuan-inc/baichuan.mdx +++ b/docs/model-coverage/llm/baichuan-inc/baichuan.mdx @@ -1,15 +1,19 @@ -# Baichuan / Baichuan2 - +--- +title: "Baichuan / Baichuan2" +description: "" +--- [Baichuan](https://github.com/baichuan-inc/Baichuan2) is a Chinese-English bilingual language model series from Baichuan Inc., featuring strong Chinese language performance. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `BaiChuanForCausalLM` | | **Parameters** | 7B – 13B | | **HF Org** | [baichuan-inc](https://huggingface.co/baichuan-inc) | -::: + + ## Available Models @@ -32,13 +36,12 @@ | Recipe | Description | |---|---| -| {download}`baichuan_2_7b_squad.yaml <../../../../examples/llm_finetune/baichuan/baichuan_2_7b_squad.yaml>` | SFT — Baichuan2 7B on SQuAD | -| {download}`baichuan_2_7b_squad_peft.yaml <../../../../examples/llm_finetune/baichuan/baichuan_2_7b_squad_peft.yaml>` | LoRA — Baichuan2 7B on SQuAD | - +| [baichuan_2_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/baichuan/baichuan_2_7b_squad.yaml) | SFT — Baichuan2 7B on SQuAD | +| [baichuan_2_7b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/baichuan/baichuan_2_7b_squad_peft.yaml) | LoRA — Baichuan2 7B on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -57,7 +60,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/baichuan/baichuan_2_7b_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +81,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/baichuan/baichuan_2_7b_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/baidu/ernie4-5.mdx b/docs/model-coverage/llm/baidu/ernie4-5.mdx index c31222abcb..7f9b11894d 100644 --- a/docs/model-coverage/llm/baidu/ernie4-5.mdx +++ b/docs/model-coverage/llm/baidu/ernie4-5.mdx @@ -1,8 +1,11 @@ -# ERNIE 4.5 - +--- +title: "ERNIE 4.5" +description: "" +--- [ERNIE 4.5](https://huggingface.co/baidu) is Baidu's dense and Mixture-of-Experts language model family with long-context text checkpoints on Hugging Face. -:::{card} + + | | | |---|---| | **Task** | Text Generation | @@ -10,7 +13,8 @@ | **Parameters** | 0.36B dense; 21B total / 3B active MoE | | **Context Length** | 131,072 tokens | | **HF Org** | [baidu](https://huggingface.co/baidu) | -::: + + ## Available Models @@ -33,12 +37,12 @@ | Recipe | Description | |---|---| -| {download}`ernie4_5_0p3b_hellaswag.yaml <../../../../examples/llm_finetune/ernie4_5/ernie4_5_0p3b_hellaswag.yaml>` | SFT -- ERNIE 4.5 0.3B on HellaSwag with the Hugging Face implementation | -| {download}`ernie4_5_21b_a3b_hellaswag.yaml <../../../../examples/llm_finetune/ernie4_5/ernie4_5_21b_a3b_hellaswag.yaml>` | SFT -- ERNIE 4.5 21B A3B on HellaSwag with TE attention and DeepEP | +| [ernie4_5_0p3b_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ernie4_5/ernie4_5_0p3b_hellaswag.yaml) | SFT — ERNIE 4.5 0.3B on HellaSwag with the Hugging Face implementation | +| [ernie4_5_21b_a3b_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ernie4_5/ernie4_5_21b_a3b_hellaswag.yaml) | SFT — ERNIE 4.5 21B A3B on HellaSwag with TE attention and DeepEP | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -63,7 +67,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/ernie4_5/ernie4_5_0p3b_hellas automodel --nproc-per-node=8 examples/llm_finetune/ernie4_5/ernie4_5_21b_a3b_hellaswag.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -84,9 +88,9 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/ernie4_5/ernie4_5_21b_a3b_hellaswag.yaml ``` -::: + -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) and the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/bigcode/starcoder.mdx b/docs/model-coverage/llm/bigcode/starcoder.mdx index 1c0c7a673b..0a3a0dea6f 100644 --- a/docs/model-coverage/llm/bigcode/starcoder.mdx +++ b/docs/model-coverage/llm/bigcode/starcoder.mdx @@ -1,15 +1,19 @@ -# StarCoder - +--- +title: "StarCoder" +description: "" +--- [StarCoder](https://huggingface.co/blog/starcoder) is BigCode's code language model trained on the Stack dataset. It uses Multi-Query Attention and Fill-in-the-Middle (FIM) objectives. WizardCoder also uses this architecture. -:::{card} + + | | | |---|---| | **Task** | Code Generation | | **Architecture** | `GPTBigCodeForCausalLM` | | **Parameters** | 1B – 15.5B | | **HF Org** | [bigcode](https://huggingface.co/bigcode) | -::: + + ## Available Models @@ -29,12 +33,11 @@ | SantaCoder | [`bigcode/gpt_bigcode-santacoder`](https://huggingface.co/bigcode/gpt_bigcode-santacoder) | | WizardCoder 15B | [`WizardLM/WizardCoder-15B-V1.0`](https://huggingface.co/WizardLM/WizardCoder-15B-V1.0) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -56,7 +59,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +81,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/bigcode/starcoder2.mdx b/docs/model-coverage/llm/bigcode/starcoder2.mdx index f5b796541c..954481b25b 100644 --- a/docs/model-coverage/llm/bigcode/starcoder2.mdx +++ b/docs/model-coverage/llm/bigcode/starcoder2.mdx @@ -1,15 +1,19 @@ -# StarCoder2 - +--- +title: "StarCoder2" +description: "" +--- [StarCoder2](https://huggingface.co/blog/starcoder2) is BigCode's second-generation code language model, available in 3B, 7B, and 15B sizes, trained on 600+ programming languages from The Stack v2. -:::{card} + + | | | |---|---| | **Task** | Code Generation | | **Architecture** | `Starcoder2ForCausalLM` | | **Parameters** | 3B – 15B | | **HF Org** | [bigcode](https://huggingface.co/bigcode) | -::: + + ## Available Models @@ -33,13 +37,12 @@ | Recipe | Description | |---|---| -| {download}`starcoder_2_7b_squad.yaml <../../../../examples/llm_finetune/starcoder/starcoder_2_7b_squad.yaml>` | SFT — StarCoder2 7B on SQuAD | -| {download}`starcoder_2_7b_hellaswag_fp8.yaml <../../../../examples/llm_finetune/starcoder/starcoder_2_7b_hellaswag_fp8.yaml>` | SFT — StarCoder2 7B on HellaSwag with FP8 | - +| [starcoder_2_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/starcoder/starcoder_2_7b_squad.yaml) | SFT — StarCoder2 7B on SQuAD | +| [starcoder_2_7b_hellaswag_fp8.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/starcoder/starcoder_2_7b_hellaswag_fp8.yaml) | SFT — StarCoder2 7B on HellaSwag with FP8 | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -58,7 +61,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/starcoder/starcoder_2_7b_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -79,13 +82,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/starcoder/starcoder_2_7b_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/bytedance-seed/seed.mdx b/docs/model-coverage/llm/bytedance-seed/seed.mdx index d8b6a2f1d8..0af60d0566 100644 --- a/docs/model-coverage/llm/bytedance-seed/seed.mdx +++ b/docs/model-coverage/llm/bytedance-seed/seed.mdx @@ -1,15 +1,19 @@ -# Seed (ByteDance) - +--- +title: "Seed (ByteDance)" +description: "" +--- [Seed-Coder](https://huggingface.co/ByteDance-Seed/Seed-Coder-8B-Instruct) and [Seed-OSS](https://huggingface.co/ByteDance-Seed/Seed-OSS-36B-Instruct) are open-weight models from ByteDance. Both use the `Qwen2ForCausalLM` architecture under the hood. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `Qwen2ForCausalLM` | | **Parameters** | 8B – 36B | | **HF Org** | [ByteDance-Seed](https://huggingface.co/ByteDance-Seed) | -::: + + ## Available Models @@ -31,15 +35,14 @@ | Recipe | Description | |---|---| -| {download}`seed_coder_8b_instruct_squad.yaml <../../../../examples/llm_finetune/seed/seed_coder_8b_instruct_squad.yaml>` | SFT — Seed-Coder 8B on SQuAD | -| {download}`seed_coder_8b_instruct_squad_peft.yaml <../../../../examples/llm_finetune/seed/seed_coder_8b_instruct_squad_peft.yaml>` | LoRA — Seed-Coder 8B on SQuAD | -| {download}`seed_oss_36B_hellaswag.yaml <../../../../examples/llm_finetune/seed/seed_oss_36B_hellaswag.yaml>` | SFT — Seed-OSS 36B on HellaSwag | -| {download}`seed_oss_36B_hellaswag_peft.yaml <../../../../examples/llm_finetune/seed/seed_oss_36B_hellaswag_peft.yaml>` | LoRA — Seed-OSS 36B on HellaSwag | - +| [seed_coder_8b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/seed/seed_coder_8b_instruct_squad.yaml) | SFT — Seed-Coder 8B on SQuAD | +| [seed_coder_8b_instruct_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/seed/seed_coder_8b_instruct_squad_peft.yaml) | LoRA — Seed-Coder 8B on SQuAD | +| [seed_oss_36B_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/seed/seed_oss_36B_hellaswag.yaml) | SFT — Seed-OSS 36B on HellaSwag | +| [seed_oss_36B_hellaswag_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/seed/seed_oss_36B_hellaswag_peft.yaml) | LoRA — Seed-OSS 36B on HellaSwag | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -58,7 +61,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/seed/seed_coder_8b_instruct_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -79,13 +82,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/seed/seed_coder_8b_instruct_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/cohere/command-r.mdx b/docs/model-coverage/llm/cohere/command-r.mdx index bc0e0b904c..3bfcf0f705 100644 --- a/docs/model-coverage/llm/cohere/command-r.mdx +++ b/docs/model-coverage/llm/cohere/command-r.mdx @@ -1,15 +1,19 @@ -# Command-R - +--- +title: "Command-R" +description: "" +--- [Cohere Command-R](https://cohere.com/command) is a series of enterprise-grade language models optimized for retrieval-augmented generation (RAG) and tool use. Command-R7B uses the updated `Cohere2ForCausalLM` architecture. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `CohereForCausalLM` / `Cohere2ForCausalLM` | | **Parameters** | 7B – 104B | | **HF Org** | [CohereForAI](https://huggingface.co/CohereForAI) | -::: + + ## Available Models @@ -33,13 +37,12 @@ | Recipe | Description | |---|---| -| {download}`cohere_command_r_7b_squad.yaml <../../../../examples/llm_finetune/cohere/cohere_command_r_7b_squad.yaml>` | SFT — Command-R 7B on SQuAD | -| {download}`cohere_command_r_7b_squad_peft.yaml <../../../../examples/llm_finetune/cohere/cohere_command_r_7b_squad_peft.yaml>` | LoRA — Command-R 7B on SQuAD | - +| [cohere_command_r_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/cohere/cohere_command_r_7b_squad.yaml) | SFT — Command-R 7B on SQuAD | +| [cohere_command_r_7b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/cohere/cohere_command_r_7b_squad_peft.yaml) | LoRA — Command-R 7B on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -58,7 +61,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/cohere/cohere_command_r_7b_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -79,13 +82,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/cohere/cohere_command_r_7b_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/deepseek-ai/deepseek-v3.mdx b/docs/model-coverage/llm/deepseek-ai/deepseek-v3.mdx index 2681279cfc..0438764734 100644 --- a/docs/model-coverage/llm/deepseek-ai/deepseek-v3.mdx +++ b/docs/model-coverage/llm/deepseek-ai/deepseek-v3.mdx @@ -1,17 +1,21 @@ -# DeepSeek-V3 - +--- +title: "DeepSeek-V3" +description: "" +--- [DeepSeek-V3](https://github.com/deepseek-ai/DeepSeek-V3) is a large-scale Mixture-of-Experts model with 671B total parameters and 37B activated per token. It features Multi-head Latent Attention (MLA), innovative load balancing, and Multi-Token Prediction (MTP). DeepSeek-V3.2 is an updated release with further improvements. [Moonlight](https://huggingface.co/moonshotai/Moonlight-16B-A3B) by Moonshot AI also uses this architecture with 16B total / 3B activated parameters. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `DeepseekV3ForCausalLM` / `DeepseekV32ForCausalLM` | | **Parameters** | 671B total / 37B active | | **HF Org** | [deepseek-ai](https://huggingface.co/deepseek-ai) | -::: + + ## Available Models @@ -37,14 +41,13 @@ | Recipe | Description | |---|---| -| {download}`deepseek_v32_hellaswag_pp.yaml <../../../../examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml>` | SFT — DeepSeek-V3.2 on HellaSwag with pipeline parallelism | -| {download}`moonlight_16b_te.yaml <../../../../examples/llm_finetune/moonlight/moonlight_16b_te.yaml>` | SFT — Moonlight 16B with Transformer Engine | -| {download}`moonlight_16b_te_packed_sequence.yaml <../../../../examples/llm_finetune/moonlight/moonlight_16b_te_packed_sequence.yaml>` | SFT — Moonlight 16B with packed sequences | - +| [deepseek_v32_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml) | SFT — DeepSeek-V3.2 on HellaSwag with pipeline parallelism | +| [moonlight_16b_te.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/moonlight/moonlight_16b_te.yaml) | SFT — Moonlight 16B with Transformer Engine | +| [moonlight_16b_te_packed_sequence.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/moonlight/moonlight_16b_te_packed_sequence.yaml) | SFT — Moonlight 16B with packed sequences | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -57,9 +60,10 @@ git clone https://github.com/NVIDIA-NeMo/Automodel.git cd Automodel ``` -:::{note} -This recipe was validated on **32 nodes × 8 GPUs (256 H100s)**. See the [Launcher Guide](../../../launcher/slurm.md) for multi-node setup. -::: + +This recipe was validated on **32 nodes × 8 GPUs (256 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. + + **3. Run the recipe** from inside the repo: @@ -67,7 +71,7 @@ This recipe was validated on **32 nodes × 8 GPUs (256 H100s)**. See the [Launch automodel --nproc-per-node=8 examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -88,13 +92,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/deepseek_v32/deepseek_v32_hellaswag_pp.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) and the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/deepseek-ai/deepseek.mdx b/docs/model-coverage/llm/deepseek-ai/deepseek.mdx index 1957ed2372..f88166d74c 100644 --- a/docs/model-coverage/llm/deepseek-ai/deepseek.mdx +++ b/docs/model-coverage/llm/deepseek-ai/deepseek.mdx @@ -1,15 +1,19 @@ -# DeepSeek - +--- +title: "DeepSeek" +description: "" +--- [DeepSeek](https://github.com/deepseek-ai) is a series of open-weight language models from DeepSeek AI. The first-generation models (V1/V2) use standard transformer decoder and Multi-head Latent Attention architectures. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `DeepseekForCausalLM` | | **Parameters** | 7B – 67B | | **HF Org** | [deepseek-ai](https://huggingface.co/deepseek-ai) | -::: + + ## Available Models @@ -28,12 +32,11 @@ | DeepSeek LLM 7B Chat | [`deepseek-ai/deepseek-llm-7b-chat`](https://huggingface.co/deepseek-ai/deepseek-llm-7b-chat) | | DeepSeek LLM 67B Chat | [`deepseek-ai/deepseek-llm-67b-chat`](https://huggingface.co/deepseek-ai/deepseek-llm-67b-chat) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -55,7 +58,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -77,13 +80,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/deepseek-ai/dsv4-flash.mdx b/docs/model-coverage/llm/deepseek-ai/dsv4-flash.mdx index 4b4d8aacc4..62fe3421d0 100644 --- a/docs/model-coverage/llm/deepseek-ai/dsv4-flash.mdx +++ b/docs/model-coverage/llm/deepseek-ai/dsv4-flash.mdx @@ -1,15 +1,19 @@ -# DeepSeek V4 Flash - +--- +title: "DeepSeek V4 Flash" +description: "" +--- [DeepSeek V4 Flash](https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash) is DeepSeek's latest fine-grained Mixture-of-Experts language model. It uses a 43-layer all-MoE backbone with 256 routed experts plus one shared expert per block, top-6 routing, and a hybrid per-layer attention zoo (SWA / CSA / HCA) selectable through `compress_ratios`. The first `num_hash_layers` blocks use a hash-clustering gate, and every block maintains `hc_mult=4` Hyper-Connection streams mixed via a learned col-norm-first Sinkhorn router. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `DeepseekV4ForCausalLM` | | **Parameters** | fine-grained MoE, 256 routed + 1 shared expert | | **HF Org** | [deepseek-ai](https://huggingface.co/deepseek-ai) | -::: + + ## Available Models @@ -31,10 +35,9 @@ |---|---| | [`deepseek_v4_flash_hellaswag.yaml`](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml) | SFT — DeepSeek V4 Flash on HellaSwag with pipeline parallelism | - ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -47,9 +50,10 @@ git clone https://github.com/NVIDIA-NeMo/Automodel.git cd Automodel ``` -:::{note} -The full 43-layer schedule requires a multi-node run; see the recipe yaml header for `ep_size` / `pp_size` guidance. See the [Launcher Guide](../../../launcher/slurm.md) for multi-node setup. -::: + +The full 43-layer schedule requires a multi-node run; see the recipe yaml header for `ep_size` / `pp_size` guidance. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. + + **3. Run the recipe** from inside the repo: @@ -57,7 +61,7 @@ The full 43-layer schedule requires a multi-node run; see the recipe yaml header automodel --nproc-per-node=8 examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +82,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/deepseek_v4/deepseek_v4_flash_hellaswag.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [Fine-Tune DeepSeek V4 Flash](../../../guides/llm/dsv4-flash.md) guide and the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [Fine-Tune DeepSeek V4 Flash](/recipes-e2e-examples/deepseek-v4-flash) guide and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/eleutherai/gpt-j.mdx b/docs/model-coverage/llm/eleutherai/gpt-j.mdx index 2cea2c8116..88e3995b49 100644 --- a/docs/model-coverage/llm/eleutherai/gpt-j.mdx +++ b/docs/model-coverage/llm/eleutherai/gpt-j.mdx @@ -1,15 +1,19 @@ -# GPT-J - +--- +title: "GPT-J" +description: "" +--- [GPT-J](https://github.com/kingoflolz/mesh-transformer-jax) is a 6B parameter transformer language model trained by EleutherAI on the Pile dataset. It was one of the earliest large open-weight models. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `GPTJForCausalLM` | | **Parameters** | 6B | | **HF Org** | [EleutherAI](https://huggingface.co/EleutherAI) | -::: + + ## Available Models @@ -27,12 +31,11 @@ | GPT-J 6B | [`EleutherAI/gpt-j-6b`](https://huggingface.co/EleutherAI/gpt-j-6b) | | GPT4All-J | [`nomic-ai/gpt4all-j`](https://huggingface.co/nomic-ai/gpt4all-j) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/eleutherai/gpt-neox.mdx b/docs/model-coverage/llm/eleutherai/gpt-neox.mdx index 9622f6be26..13ac558350 100644 --- a/docs/model-coverage/llm/eleutherai/gpt-neox.mdx +++ b/docs/model-coverage/llm/eleutherai/gpt-neox.mdx @@ -1,15 +1,19 @@ -# GPT-NeoX / Pythia - +--- +title: "GPT-NeoX / Pythia" +description: "" +--- [GPT-NeoX](https://github.com/EleutherAI/gpt-neox) is EleutherAI's large-scale language model architecture. The same `GPTNeoXForCausalLM` architecture is used by the Pythia scaling suite, OpenAssistant, Databricks Dolly, and StableLM models. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `GPTNeoXForCausalLM` | | **Parameters** | 1B – 20B | | **HF Org** | [EleutherAI](https://huggingface.co/EleutherAI) | -::: + + ## Available Models @@ -33,12 +37,11 @@ | Dolly v2 12B | [`databrickslabs/dolly`](https://github.com/databrickslabs/dolly) | | StableLM tuned alpha 7B | [`stabilityai/stablelm-tuned-alpha-7b`](https://huggingface.co/stabilityai/stablelm-tuned-alpha-7b) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -60,7 +63,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -82,13 +85,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/google/gemma.mdx b/docs/model-coverage/llm/google/gemma.mdx index 587efeae1e..1c22045c56 100644 --- a/docs/model-coverage/llm/google/gemma.mdx +++ b/docs/model-coverage/llm/google/gemma.mdx @@ -1,15 +1,19 @@ -# Gemma - +--- +title: "Gemma" +description: "" +--- [Google's Gemma](https://ai.google.dev/gemma) is a family of open-weight language models built on the same research and technology as Gemini. Gemma models are available in multiple sizes and versions, with improvements in each generation including local sliding window attention (Gemma 2) and interleaved global/local attention (Gemma 3). -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `GemmaForCausalLM` / `Gemma2ForCausalLM` / `Gemma3ForCausalLM` | | **Parameters** | 1B – 27B | | **HF Org** | [google](https://huggingface.co/google) | -::: + + ## Available Models @@ -39,15 +43,14 @@ | Recipe | Description | |---|---| -| {download}`gemma_2_9b_it_squad.yaml <../../../../examples/llm_finetune/gemma/gemma_2_9b_it_squad.yaml>` | SFT — Gemma 2 9B IT on SQuAD | -| {download}`gemma_2_9b_it_squad_peft.yaml <../../../../examples/llm_finetune/gemma/gemma_2_9b_it_squad_peft.yaml>` | LoRA — Gemma 2 9B IT on SQuAD | -| {download}`gemma_3_270m_squad.yaml <../../../../examples/llm_finetune/gemma/gemma_3_270m_squad.yaml>` | SFT — Gemma 3 270M on SQuAD | -| {download}`gemma_3_270m_squad_peft.yaml <../../../../examples/llm_finetune/gemma/gemma_3_270m_squad_peft.yaml>` | LoRA — Gemma 3 270M on SQuAD | - +| [gemma_2_9b_it_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/gemma_2_9b_it_squad.yaml) | SFT — Gemma 2 9B IT on SQuAD | +| [gemma_2_9b_it_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/gemma_2_9b_it_squad_peft.yaml) | LoRA — Gemma 2 9B IT on SQuAD | +| [gemma_3_270m_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/gemma_3_270m_squad.yaml) | SFT — Gemma 3 270M on SQuAD | +| [gemma_3_270m_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gemma/gemma_3_270m_squad_peft.yaml) | LoRA — Gemma 3 270M on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -66,7 +69,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/gemma/gemma_2_9b_it_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -87,13 +90,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/gemma/gemma_2_9b_it_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) for full SFT and LoRA instructions. +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) for full SFT and LoRA instructions. ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/ibm/bamba.mdx b/docs/model-coverage/llm/ibm/bamba.mdx index b17b0e8ffe..bb32a608b3 100644 --- a/docs/model-coverage/llm/ibm/bamba.mdx +++ b/docs/model-coverage/llm/ibm/bamba.mdx @@ -1,15 +1,19 @@ -# Bamba - +--- +title: "Bamba" +description: "" +--- [Bamba](https://huggingface.co/ibm-ai-platform/Bamba-9B) is a hybrid SSM-attention language model from IBM, combining Mamba-2 selective state space layers with standard transformer attention for efficient long-context processing. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `BambaForCausalLM` | | **Parameters** | 9B | | **HF Org** | [ibm-ai-platform](https://huggingface.co/ibm-ai-platform) | -::: + + ## Available Models @@ -25,12 +29,11 @@ |---|---| | Bamba 9B | [`ibm-ai-platform/Bamba-9B`](https://huggingface.co/ibm-ai-platform/Bamba-9B) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -52,7 +55,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -74,13 +77,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/ibm/granite-moe.mdx b/docs/model-coverage/llm/ibm/granite-moe.mdx index 078f703577..a11e8a7666 100644 --- a/docs/model-coverage/llm/ibm/granite-moe.mdx +++ b/docs/model-coverage/llm/ibm/granite-moe.mdx @@ -1,15 +1,19 @@ -# Granite MoE - +--- +title: "Granite MoE" +description: "" +--- IBM Granite MoE models extend the Granite architecture with Mixture-of-Experts layers for more efficient scaling. PowerMoE (IBM Research) also uses this architecture. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `GraniteMoeForCausalLM` | | **Parameters** | 1B – 3B | | **HF Org** | [ibm-granite](https://huggingface.co/ibm-granite) | -::: + + ## Available Models @@ -31,12 +35,11 @@ IBM Granite MoE models extend the Granite architecture with Mixture-of-Experts l | Granite 3.0 3B A800M Instruct | [`ibm-granite/granite-3.0-3b-a800m-instruct`](https://huggingface.co/ibm-granite/granite-3.0-3b-a800m-instruct) | | PowerMoE 3B | [`ibm/PowerMoE-3b`](https://huggingface.co/ibm/PowerMoE-3b) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -58,7 +61,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -80,13 +83,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/ibm/granite.mdx b/docs/model-coverage/llm/ibm/granite.mdx index e34e044785..bdf4565ab3 100644 --- a/docs/model-coverage/llm/ibm/granite.mdx +++ b/docs/model-coverage/llm/ibm/granite.mdx @@ -1,15 +1,19 @@ -# Granite - +--- +title: "Granite" +description: "" +--- [IBM Granite](https://www.ibm.com/granite) is IBM's family of enterprise-focused language models. Granite 3.x models are trained on a mix of code and language data and are optimized for enterprise tasks including summarization, classification, and RAG. PowerLM (IBM Research) also uses this architecture. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `GraniteForCausalLM` | | **Parameters** | 2B – 8B | | **HF Org** | [ibm-granite](https://huggingface.co/ibm-granite) | -::: + + ## Available Models @@ -34,13 +38,12 @@ | Recipe | Description | |---|---| -| {download}`granite_3_3_2b_instruct_squad.yaml <../../../../examples/llm_finetune/granite/granite_3_3_2b_instruct_squad.yaml>` | SFT — Granite 3.3 2B Instruct on SQuAD | -| {download}`granite_3_3_2b_instruct_squad_peft.yaml <../../../../examples/llm_finetune/granite/granite_3_3_2b_instruct_squad_peft.yaml>` | LoRA — Granite 3.3 2B Instruct on SQuAD | - +| [granite_3_3_2b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/granite/granite_3_3_2b_instruct_squad.yaml) | SFT — Granite 3.3 2B Instruct on SQuAD | +| [granite_3_3_2b_instruct_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/granite/granite_3_3_2b_instruct_squad_peft.yaml) | LoRA — Granite 3.3 2B Instruct on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -59,7 +62,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/granite/granite_3_3_2b_instruct_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -80,13 +83,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/granite/granite_3_3_2b_instruct_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/inceptionai/jais.mdx b/docs/model-coverage/llm/inceptionai/jais.mdx index ae2f7f3373..e8c821059a 100644 --- a/docs/model-coverage/llm/inceptionai/jais.mdx +++ b/docs/model-coverage/llm/inceptionai/jais.mdx @@ -1,15 +1,19 @@ -# Jais - +--- +title: "Jais" +description: "" +--- [Jais](https://huggingface.co/inceptionai/jais-13b) is an Arabic-English bilingual language model from Inception (formerly G42/Inception AI), trained on a large Arabic and English corpus. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `JAISLMHeadModel` | | **Parameters** | 13B – 30B | | **HF Org** | [inceptionai](https://huggingface.co/inceptionai) | -::: + + ## Available Models @@ -31,12 +35,11 @@ | Jais 30B v3 | [`inceptionai/jais-30b-v3`](https://huggingface.co/inceptionai/jais-30b-v3) | | Jais 30B Chat v3 | [`inceptionai/jais-30b-chat-v3`](https://huggingface.co/inceptionai/jais-30b-chat-v3) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -58,7 +61,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -80,13 +83,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/inclusionai/ling-2.mdx b/docs/model-coverage/llm/inclusionai/ling-2.mdx index f5ff8d409c..2b3ba8e111 100644 --- a/docs/model-coverage/llm/inclusionai/ling-2.mdx +++ b/docs/model-coverage/llm/inclusionai/ling-2.mdx @@ -1,18 +1,19 @@ -# Ling 2.0 +--- +title: "Ling 2.0" +description: "" +--- +[Ling 2.0](https://huggingface.co/collections/inclusionAI/ling-20) is the Mixture-of-Experts LLM family from inclusionAI (Ant Group), released under the `bailing_moe` HF architecture (`BailingMoeV2ForCausalLM`). The line spans a 16 B mini through a 1 T flagship while sharing the same architecture. -[Ling 2.0](https://huggingface.co/collections/inclusionAI/ling-20) is the Mixture-of-Experts -LLM family from inclusionAI (Ant Group), released under the `bailing_moe` HF -architecture (`BailingMoeV2ForCausalLM`). The line spans a 16 B mini through -a 1 T flagship while sharing the same architecture. + -:::{card} | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `BailingMoeV2ForCausalLM` | | **Parameters** | 16 B – 1 T total | | **HF Org** | [inclusionAI](https://huggingface.co/inclusionAI) | -::: + + ## Available Models @@ -21,17 +22,14 @@ a 1 T flagship while sharing the same architecture. - **Ling-1T**: 1 T total / ~50 B activated per token (80 layers, `first_k_dense_replace=4`). - **Ling-mini-base-2.0** / **Ling-flash-base-2.0**: base (pre-instruct) variants. -All variants share the same architecture: GQA + per-head QK-RMSNorm + half RoPE -(`partial_rotary_factor=0.5`) + sigmoid-routed grouped MoE with one shared -expert and a per-expert correction bias (aux-loss-free routing). +All variants share the same architecture: GQA + per-head QK-RMSNorm + half RoPE (`partial_rotary_factor=0.5`) + sigmoid-routed grouped MoE with one shared expert and a per-expert correction bias (aux-loss-free routing). ## Architecture - `BailingMoeV2ForCausalLM` (HF `model_type: "bailing_moe"`) - GQA attention; `use_qk_norm: true` - Half RoPE (`partial_rotary_factor=0.5`) -- DeepSeek-V3-style routing: sigmoid scoring, per-expert bias, grouped top-k - (`n_group=8`, `topk_group=4`) +- DeepSeek-V3-style routing: sigmoid scoring, per-expert bias, grouped top-k (`n_group=8`, `topk_group=4`) - 1 shared expert at `moe_intermediate_size` - `first_k_dense_replace` dense MLP layer(s) at the start of the stack @@ -47,17 +45,17 @@ expert and a per-expert correction bias (aux-loss-free routing). | Recipe | Description | Min HW | |---|---|---| -| {download}`ling_mini_2_0_squad.yaml <../../../../examples/llm_finetune/ling/ling_mini_2_0_squad.yaml>` | LoRA SFT — Ling-mini-2.0 on SQuAD | 2× H100 80GB | -| {download}`ling_mini_2_0_hellaswag.yaml <../../../../examples/llm_finetune/ling/ling_mini_2_0_hellaswag.yaml>` | LoRA SFT — Ling-mini-2.0 on HellaSwag | 2× H100 80GB | -| {download}`ling_mini_2_0_sft.yaml <../../../../examples/llm_finetune/ling/ling_mini_2_0_sft.yaml>` | Full SFT — Ling-mini-2.0 on HellaSwag, FSDP2 + EP=8 | 8× H100 80GB | -| {download}`ling_flash_2_0_lora.yaml <../../../../examples/llm_finetune/ling/ling_flash_2_0_lora.yaml>` | LoRA SFT — Ling-flash-2.0 on HellaSwag | 8× H100 80GB | -| {download}`ling_flash_2_0_sft.yaml <../../../../examples/llm_finetune/ling/ling_flash_2_0_sft.yaml>` | Full SFT — Ling-flash-2.0 on HellaSwag, FSDP2 + EP=32 | 32× H100 80GB (4 nodes) | -| {download}`ling_1t_lora_pp.yaml <../../../../examples/llm_finetune/ling/ling_1t_lora_pp.yaml>` | LoRA SFT — Ling-1T on HellaSwag, FSDP2 + PP=8 + EP=8 | 64× H100 80GB (8 nodes) | -| {download}`ling_1t_sft.yaml <../../../../examples/llm_finetune/ling/ling_1t_sft.yaml>` | Full SFT — Ling-1T on HellaSwag, FSDP2 + PP=4 + EP=64 | 256× H100 80GB (32 nodes) | +| [ling_mini_2_0_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_mini_2_0_squad.yaml) | LoRA SFT — Ling-mini-2.0 on SQuAD | 2× H100 80GB | +| [ling_mini_2_0_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_mini_2_0_hellaswag.yaml) | LoRA SFT — Ling-mini-2.0 on HellaSwag | 2× H100 80GB | +| [ling_mini_2_0_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_mini_2_0_sft.yaml) | Full SFT — Ling-mini-2.0 on HellaSwag, FSDP2 + EP=8 | 8× H100 80GB | +| [ling_flash_2_0_lora.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_flash_2_0_lora.yaml) | LoRA SFT — Ling-flash-2.0 on HellaSwag | 8× H100 80GB | +| [ling_flash_2_0_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_flash_2_0_sft.yaml) | Full SFT — Ling-flash-2.0 on HellaSwag, FSDP2 + EP=32 | 32× H100 80GB (4 nodes) | +| [ling_1t_lora_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_1t_lora_pp.yaml) | LoRA SFT — Ling-1T on HellaSwag, FSDP2 + PP=8 + EP=8 | 64× H100 80GB (8 nodes) | +| [ling_1t_sft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/ling/ling_1t_sft.yaml) | Full SFT — Ling-1T on HellaSwag, FSDP2 + PP=4 + EP=64 | 256× H100 80GB (32 nodes) | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)). +**1. Install** ([full instructions](/get-started/installation)). **2. Run LoRA fine-tuning:** @@ -65,6 +63,4 @@ expert and a per-expert correction bias (aux-loss-free routing). automodel examples/llm_finetune/ling/ling_mini_2_0_squad.yaml --nproc-per-node 1 ``` -A single 80 GB H100 / A100 fits Ling-mini-2.0 in bf16 with the LoRA defaults -in the example. Set `distributed.ep_size > 1` for multi-GPU expert -parallelism on the larger variants. +A single 80 GB H100 / A100 fits Ling-mini-2.0 in bf16 with the LoRA defaults in the example. Set `distributed.ep_size > 1` for multi-GPU expert parallelism on the larger variants. diff --git a/docs/model-coverage/llm/index.mdx b/docs/model-coverage/llm/index.mdx index 2a81e3cbde..4c624cc947 100644 --- a/docs/model-coverage/llm/index.mdx +++ b/docs/model-coverage/llm/index.mdx @@ -1,5 +1,8 @@ -# Large Language Models (LLMs) - +--- +title: "Large Language Models (LLMs)" +description: "" +position: 3 +--- ## Introduction Large Language Models (LLMs) power a variety of tasks such as dialogue systems, text classification, summarization, and more. NeMo AutoModel provides a simple interface for loading and fine-tuning LLMs hosted on the Hugging Face Hub. @@ -11,141 +14,81 @@ To run LLMs with NeMo AutoModel, make sure you're using NeMo container version [ pip3 install --upgrade git+git@github.com:NVIDIA-NeMo/AutoModel.git ``` -For other installation options (e.g., uv), see the [NeMo AutoModel Installation Guide](../../guides/installation.md). +For other installation options (e.g., uv), see the [NeMo AutoModel Installation Guide](/get-started/installation). ## Supported Models -NeMo AutoModel supports the [AutoModelForCausalLM](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html#automodelforcausallm) in the [Text Generation](https://huggingface.co/models?pipeline_tag=text-generation&sort=trending) category. During preprocessing, it uses `transformers.AutoTokenizer`, which is sufficient for most LLM cases. If your model requires custom text handling, override the tokenizer in your recipe YAML or provide a custom dataset `_target_`. See [LLM datasets](../../guides/llm/dataset.md) and [dataset overview](../../guides/dataset-overview.md). +NeMo AutoModel supports the [AutoModelForCausalLM](https://huggingface.co/transformers/v3.5.1/model_doc/auto.html#automodelforcausallm) in the [Text Generation](https://huggingface.co/models?pipeline_tag=text-generation&sort=trending) category. During preprocessing, it uses `transformers.AutoTokenizer`, which is sufficient for most LLM cases. If your model requires custom text handling, override the tokenizer in your recipe YAML or provide a custom dataset `_target_`. See [LLM datasets](/datasets/text-dataset) and [dataset overview](/datasets/overview). | Owner | Model Family | Architectures | |---|---|---| -| Meta | [Llama](meta/llama.md) | `LlamaForCausalLM` | -| Google | [Gemma](google/gemma.md) | `GemmaForCausalLM`, `Gemma2ForCausalLM`, `Gemma3ForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen2](qwen/qwen2.md) | `Qwen2ForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen2 MoE](qwen/qwen2-moe.md) | `Qwen2MoeForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen3](qwen/qwen3.md) | `Qwen3ForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen3 MoE](qwen/qwen3-moe.md) | `Qwen3MoeForCausalLM` | -| Qwen / Alibaba Cloud | [Qwen3-Next](qwen/qwen3-next.md) | `Qwen3NextForCausalLM` | -| Baidu | [ERNIE 4.5](baidu/ernie4-5.md) | `Ernie4_5ForCausalLM`, `Ernie4_5_MoeForCausalLM` | -| DeepSeek | [DeepSeek](deepseek-ai/deepseek.md) | `DeepseekForCausalLM` | -| DeepSeek | [DeepSeek-V3](deepseek-ai/deepseek-v3.md) | `DeepseekV3ForCausalLM`, `DeepseekV32ForCausalLM` | -| DeepSeek | [DeepSeek V4 Flash](deepseek-ai/dsv4-flash.md) | `DeepseekV4ForCausalLM` | -| Mistral AI | [Mistral](mistralai/mistral.md) | `MistralForCausalLM` | -| Mistral AI | [Mixtral](mistralai/mixtral.md) | `MixtralForCausalLM` | -| Mistral AI | [Ministral3 / Devstral](mistralai/ministral3.md) | `Mistral3ForConditionalGeneration` | -| Microsoft | [Phi](microsoft/phi.md) | `PhiForCausalLM` | -| Microsoft | [Phi-3 / Phi-4](microsoft/phi3.md) | `Phi3ForCausalLM` | -| Microsoft | [Phi-3-Small](microsoft/phi3-small.md) | `Phi3SmallForCausalLM` | -| NVIDIA | [Nemotron](nvidia/nemotron.md) | `NemotronForCausalLM` | -| NVIDIA | [Nemotron-H](nvidia/nemotron-h.md) | `NemotronHForCausalLM` | -| NVIDIA | [Nemotron-Flash](nvidia/nemotron-flash.md) | `NemotronFlashForCausalLM` | -| NVIDIA | [Nemotron-Super](nvidia/nemotron-super.md) | `DeciLMForCausalLM` | -| ZAI / Zhipu AI | [ChatGLM](thudm/chatglm.md) | `ChatGLMModel` | -| ZAI / Zhipu AI | [GLM-4](thudm/glm4.md) | `GlmForCausalLM`, `Glm4ForCausalLM` | -| ZAI / Zhipu AI | [GLM-4 MoE](thudm/glm4-moe.md) | `Glm4MoeForCausalLM`, `Glm4MoeLiteForCausalLM` | -| ZAI / Zhipu AI | [GLM-5 / GLM-5.1](thudm/glm5-moe-dsa.md) | `GlmMoeDsaForCausalLM` | -| IBM | [Granite](ibm/granite.md) | `GraniteForCausalLM` | -| IBM | [Granite MoE](ibm/granite-moe.md) | `GraniteMoeForCausalLM`, `GraniteMoeSharedForCausalLM` | -| IBM | [Bamba](ibm/bamba.md) | `BambaForCausalLM` | -| Allen AI | [OLMo](allenai/olmo.md) | `OLMoForCausalLM` | -| Allen AI | [OLMo2](allenai/olmo2.md) | `OLMo2ForCausalLM` | -| Allen AI | [OLMoE](allenai/olmoe.md) | `OLMoEForCausalLM` | -| OpenAI | [GPT-OSS](openai/gpt-oss.md) | `GptOssForCausalLM` | -| OpenAI | [GPT-2](openai/gpt2.md) | `GPT2LMHeadModel` | -| EleutherAI | [GPT-J](eleutherai/gpt-j.md) | `GPTJForCausalLM` | -| EleutherAI | [GPT-NeoX / Pythia](eleutherai/gpt-neox.md) | `GPTNeoXForCausalLM` | -| BigCode | [StarCoder](bigcode/starcoder.md) | `GPTBigCodeForCausalLM` | -| BigCode | [StarCoder2](bigcode/starcoder2.md) | `Starcoder2ForCausalLM` | -| BAAI | [Aquila](baai/aquila.md) | `AquilaForCausalLM` | -| Baichuan Inc | [Baichuan](baichuan-inc/baichuan.md) | `BaiChuanForCausalLM` | -| Cohere | [Command-R](cohere/command-r.md) | `CohereForCausalLM`, `Cohere2ForCausalLM` | -| TII | [Falcon](tiiuae/falcon.md) | `FalconForCausalLM` | -| LG AI Research | [EXAONE](lgai-exaone/exaone.md) | `ExaoneForCausalLM` | -| InternLM | [InternLM](internlm/internlm.md) | `InternLMForCausalLM`, `InternLM2ForCausalLM`, `InternLM3ForCausalLM` | -| Inception AI | [Jais](inceptionai/jais.md) | `JAISLMHeadModel` | -| MiniMax | [MiniMax-M2](minimax/minimax-m2.md) | `MiniMaxM2ForCausalLM` | -| OpenBMB | [MiniCPM](openbmb/minicpm.md) | `MiniCPMForCausalLM`, `MiniCPM3ForCausalLM` | -| Moonshot AI | [Moonlight](moonshotai/moonlight.md) | `DeepseekV3ForCausalLM` | -| ByteDance Seed | [Seed](bytedance-seed/seed.md) | `Qwen2ForCausalLM` | -| Upstage | [Solar](upstage/solar.md) | `SolarForCausalLM` | -| OrionStar | [Orion](orionstar/orion.md) | `OrionForCausalLM` | -| Stability AI | [StableLM](stabilityai/stablelm.md) | `StableLmForCausalLM` | -| Stepfun AI | [Step-3.5](stepfun-ai/step-3-5.md) | `Step3p5ForCausalLM` | -| Parasail AI | [GritLM](parasail-ai/gritlm.md) | `GritLM` | -| Tencent | [Hy3-preview](tencent/hy3.md) | `HYV3ForCausalLM` | -| Xiaomi MiMo | [MiMo-V2-Flash](xiaomimimo/mimo-v2-flash.md) | `MiMoV2FlashForCausalLM` | -| inclusionAI | [Ling 2.0](inclusionai/ling-2.md) | `BailingMoeV2ForCausalLM` | +| Meta | [Llama](/model-coverage/large-language-models/llama) | `LlamaForCausalLM` | +| Google | [Gemma](/model-coverage/large-language-models/gemma) | `GemmaForCausalLM`, `Gemma2ForCausalLM`, `Gemma3ForCausalLM` | +| Qwen / Alibaba Cloud | [Qwen2](/model-coverage/large-language-models/qwen2) | `Qwen2ForCausalLM` | +| Qwen / Alibaba Cloud | [Qwen2 MoE](/model-coverage/large-language-models/qwen2-moe) | `Qwen2MoeForCausalLM` | +| Qwen / Alibaba Cloud | [Qwen3](/model-coverage/large-language-models/qwen3) | `Qwen3ForCausalLM` | +| Qwen / Alibaba Cloud | [Qwen3 MoE](/model-coverage/large-language-models/qwen3-moe) | `Qwen3MoeForCausalLM` | +| Qwen / Alibaba Cloud | [Qwen3-Next](/model-coverage/large-language-models/qwen3-next) | `Qwen3NextForCausalLM` | +| Baidu | [ERNIE 4.5](/model-coverage/large-language-models/ernie-4-5) | `Ernie4_5ForCausalLM`, `Ernie4_5_MoeForCausalLM` | +| DeepSeek | [DeepSeek](/model-coverage/large-language-models/deepseek) | `DeepseekForCausalLM` | +| DeepSeek | [DeepSeek-V3](/model-coverage/large-language-models/deepseek-v3) | `DeepseekV3ForCausalLM`, `DeepseekV32ForCausalLM` | +| DeepSeek | [DeepSeek V4 Flash](/model-coverage/large-language-models/deepseek-v4-flash) | `DeepseekV4ForCausalLM` | +| Mistral AI | [Mistral](/model-coverage/large-language-models/mistral) | `MistralForCausalLM` | +| Mistral AI | [Mixtral](/model-coverage/large-language-models/mixtral) | `MixtralForCausalLM` | +| Mistral AI | [Ministral3 / Devstral](/model-coverage/large-language-models/ministral3-devstral) | `Mistral3ForConditionalGeneration` | +| Microsoft | [Phi](/model-coverage/large-language-models/phi) | `PhiForCausalLM` | +| Microsoft | [Phi-3 / Phi-4](/model-coverage/large-language-models/phi-3-phi-4) | `Phi3ForCausalLM` | +| Microsoft | [Phi-3-Small](/model-coverage/large-language-models/phi-3-small) | `Phi3SmallForCausalLM` | +| NVIDIA | [Nemotron / Minitron](/model-coverage/large-language-models/nemotron-minitron) | `NemotronForCausalLM` | +| NVIDIA | [Nemotron-H](/model-coverage/large-language-models/nemotron-h) | `NemotronHForCausalLM` | +| NVIDIA | [Nemotron-Flash](/model-coverage/large-language-models/nemotron-flash) | `NemotronFlashForCausalLM` | +| NVIDIA | [Nemotron-Super](/model-coverage/large-language-models/nemotron-super-llama-3-3-nemotron-super-49b) | `DeciLMForCausalLM` | +| ZAI / Zhipu AI | [ChatGLM](/model-coverage/large-language-models/chatglm) | `ChatGLMModel` | +| ZAI / Zhipu AI | [GLM-4](/model-coverage/large-language-models/glm-4) | `GlmForCausalLM`, `Glm4ForCausalLM` | +| ZAI / Zhipu AI | [GLM-4 MoE](/model-coverage/large-language-models/glm-4-moe-glm-4-5-glm-4-7) | `Glm4MoeForCausalLM`, `Glm4MoeLiteForCausalLM` | +| ZAI / Zhipu AI | [GLM-5 / GLM-5.1](/model-coverage/large-language-models/glm-5-moe-dsa) | `GlmMoeDsaForCausalLM` | +| IBM | [Granite](/model-coverage/large-language-models/granite) | `GraniteForCausalLM` | +| IBM | [Granite MoE](/model-coverage/large-language-models/granite-moe) | `GraniteMoeForCausalLM`, `GraniteMoeSharedForCausalLM` | +| IBM | [Bamba](/model-coverage/large-language-models/bamba) | `BambaForCausalLM` | +| Allen AI | [OLMo](/model-coverage/large-language-models/olmo) | `OLMoForCausalLM` | +| Allen AI | [OLMo2](/model-coverage/large-language-models/olmo2) | `OLMo2ForCausalLM` | +| Allen AI | [OLMoE](/model-coverage/large-language-models/olmoe) | `OLMoEForCausalLM` | +| OpenAI | [GPT-OSS](/model-coverage/large-language-models/gpt-oss) | `GptOssForCausalLM` | +| OpenAI | [GPT-2](/model-coverage/large-language-models/gpt-2) | `GPT2LMHeadModel` | +| EleutherAI | [GPT-J](/model-coverage/large-language-models/gpt-j) | `GPTJForCausalLM` | +| EleutherAI | [GPT-NeoX / Pythia](/model-coverage/large-language-models/gpt-neox-pythia) | `GPTNeoXForCausalLM` | +| BigCode | [StarCoder](/model-coverage/large-language-models/starcoder) | `GPTBigCodeForCausalLM` | +| BigCode | [StarCoder2](/model-coverage/large-language-models/starcoder2) | `Starcoder2ForCausalLM` | +| BAAI | [Aquila / Aquila2](/model-coverage/large-language-models/aquila-aquila2) | `AquilaForCausalLM` | +| Baichuan Inc | [Baichuan / Baichuan2](/model-coverage/large-language-models/baichuan-baichuan2) | `BaiChuanForCausalLM` | +| Cohere | [Command-R](/model-coverage/large-language-models/command-r) | `CohereForCausalLM`, `Cohere2ForCausalLM` | +| TII | [Falcon](/model-coverage/large-language-models/falcon) | `FalconForCausalLM` | +| LG AI Research | [EXAONE](/model-coverage/large-language-models/exaone) | `ExaoneForCausalLM` | +| InternLM | [InternLM](/model-coverage/large-language-models/internlm) | `InternLMForCausalLM`, `InternLM2ForCausalLM`, `InternLM3ForCausalLM` | +| Inception AI | [Jais](/model-coverage/large-language-models/jais) | `JAISLMHeadModel` | +| MiniMax | [MiniMax-M2](/model-coverage/large-language-models/minimax-m2) | `MiniMaxM2ForCausalLM` | +| OpenBMB | [MiniCPM](/model-coverage/large-language-models/minicpm) | `MiniCPMForCausalLM`, `MiniCPM3ForCausalLM` | +| Moonshot AI | [Moonlight](/model-coverage/large-language-models/moonlight) | `DeepseekV3ForCausalLM` | +| ByteDance Seed | [Seed (ByteDance)](/model-coverage/large-language-models/seed-bytedance) | `Qwen2ForCausalLM` | +| Upstage | [Solar Pro](/model-coverage/large-language-models/solar-pro) | `SolarForCausalLM` | +| OrionStar | [Orion](/model-coverage/large-language-models/orion) | `OrionForCausalLM` | +| Stability AI | [StableLM](/model-coverage/large-language-models/stablelm) | `StableLmForCausalLM` | +| Stepfun AI | [Step-3.5](/model-coverage/large-language-models/step-3-5) | `Step3p5ForCausalLM` | +| Parasail AI | [GritLM](/model-coverage/large-language-models/gritlm) | `GritLM` | +| Tencent | [Hy3-preview](/model-coverage/large-language-models/hy3-preview) | `HYV3ForCausalLM` | +| Xiaomi MiMo | [MiMo-V2-Flash](/model-coverage/large-language-models/mimo-v2-flash) | `MiMoV2FlashForCausalLM` | +| inclusionAI | [Ling 2.0](/model-coverage/large-language-models/ling-2-0) | `BailingMoeV2ForCausalLM` | ## Fine-Tuning LLMs with NeMo AutoModel The models listed above can be fine-tuned using NeMo AutoModel. We support two primary fine-tuning approaches: -1. **Parameter-Efficient Fine-Tuning (PEFT)**: Updates only a small subset of parameters (typically <1%) using techniques like Low-Rank Adaptation (LoRA). +1. **Parameter-Efficient Fine-Tuning (PEFT)**: Updates only a small subset of parameters (typically <1%) using techniques like Low-Rank Adaptation (LoRA). 2. **Supervised Fine-Tuning (SFT)**: Updates all or most model parameters for deeper adaptation. -See the [Fine-Tuning Guide](../../guides/llm/finetune.md) to learn how to apply both methods to your data. - -:::{tip} -In these guides, we use the `SQuAD v1.1` dataset for demonstration purposes, but you can use your own data. Update the recipe YAML `dataset` / `validation_dataset` sections accordingly. See [LLM datasets](../../guides/llm/dataset.md) and [dataset overview](../../guides/dataset-overview.md). -::: +See the [Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) to learn how to apply both methods to your data. -```{toctree} -:hidden: + +In these guides, we use the `SQuAD v1.1` dataset for demonstration purposes, but you can use your own data. Update the recipe YAML `dataset` / `validation_dataset` sections accordingly. See [LLM datasets](/datasets/text-dataset) and [dataset overview](/datasets/overview). -meta/llama -google/gemma -qwen/qwen2 -qwen/qwen2-moe -qwen/qwen3 -qwen/qwen3-moe -qwen/qwen3-next -baidu/ernie4-5 -deepseek-ai/deepseek -deepseek-ai/deepseek-v3 -deepseek-ai/dsv4-flash -mistralai/mistral -mistralai/mixtral -mistralai/ministral3 -microsoft/phi -microsoft/phi3 -microsoft/phi3-small -nvidia/nemotron -nvidia/nemotron-h -nvidia/nemotron-flash -nvidia/nemotron-super -thudm/chatglm -thudm/glm4 -thudm/glm4-moe -thudm/glm5-moe-dsa -ibm/granite -ibm/granite-moe -ibm/bamba -allenai/olmo -allenai/olmo2 -allenai/olmoe -openai/gpt-oss -openai/gpt2 -eleutherai/gpt-j -eleutherai/gpt-neox -bigcode/starcoder -bigcode/starcoder2 -baai/aquila -baichuan-inc/baichuan -cohere/command-r -tiiuae/falcon -lgai-exaone/exaone -internlm/internlm -inceptionai/jais -minimax/minimax-m2 -openbmb/minicpm -moonshotai/moonlight -bytedance-seed/seed -upstage/solar -orionstar/orion -stabilityai/stablelm -stepfun-ai/step-3-5 -parasail-ai/gritlm -tencent/hy3 -xiaomimimo/mimo-v2-flash -inclusionai/ling-2 -``` + diff --git a/docs/model-coverage/llm/internlm/internlm.mdx b/docs/model-coverage/llm/internlm/internlm.mdx index cb1f87ac7b..cd062bdc36 100644 --- a/docs/model-coverage/llm/internlm/internlm.mdx +++ b/docs/model-coverage/llm/internlm/internlm.mdx @@ -1,15 +1,19 @@ -# InternLM - +--- +title: "InternLM" +description: "" +--- [InternLM](https://github.com/InternLM/InternLM) is a bilingual (Chinese-English) language model series from Shanghai AI Laboratory, with versions 1, 2, and 3 each improving on reasoning, instruction following, and long-context capabilities. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `InternLMForCausalLM` / `InternLM2ForCausalLM` / `InternLM3ForCausalLM` | | **Parameters** | 7B – 8B | | **HF Org** | [internlm](https://huggingface.co/internlm) | -::: + + ## Available Models @@ -31,12 +35,11 @@ | InternLM2 7B | [`internlm/internlm2-7b`](https://huggingface.co/internlm/internlm2-7b) | | InternLM 7B | [`internlm/internlm-7b`](https://huggingface.co/internlm/internlm-7b) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -58,7 +61,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -80,13 +83,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/lgai-exaone/exaone.mdx b/docs/model-coverage/llm/lgai-exaone/exaone.mdx index eff5716d35..8f45a99ca7 100644 --- a/docs/model-coverage/llm/lgai-exaone/exaone.mdx +++ b/docs/model-coverage/llm/lgai-exaone/exaone.mdx @@ -1,15 +1,19 @@ -# EXAONE - +--- +title: "EXAONE" +description: "" +--- EXAONE is a bilingual (Korean-English) language model series from LG AI Research, with strong performance on Korean-language benchmarks. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `ExaoneForCausalLM` | | **Parameters** | 7.8B | | **HF Org** | [LGAI-EXAONE](https://huggingface.co/LGAI-EXAONE) | -::: + + ## Available Models @@ -26,12 +30,11 @@ EXAONE is a bilingual (Korean-English) language model series from LG AI Research |---|---| | EXAONE 3.0 7.8B Instruct | [`LGAI-EXAONE/EXAONE-3.0-7.8B-Instruct`](https://huggingface.co/LGAI-EXAONE/EXAONE-3.0-7.8B-Instruct) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -53,7 +56,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -75,13 +78,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/meta/llama.mdx b/docs/model-coverage/llm/meta/llama.mdx index a922b78a51..7291f5947f 100644 --- a/docs/model-coverage/llm/meta/llama.mdx +++ b/docs/model-coverage/llm/meta/llama.mdx @@ -1,15 +1,19 @@ -# Llama - +--- +title: "Llama" +description: "" +--- [Meta's Llama](https://www.llama.com/) is a family of open-weight autoregressive language models built on the transformer decoder architecture. Key design choices include pre-normalization with RMSNorm, SwiGLU activations, and Rotary Positional Embeddings (RoPE). Llama 3+ models add Grouped Query Attention (GQA) for memory-efficient inference at larger scales. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `LlamaForCausalLM` | | **Parameters** | 1B – 405B | | **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | -::: + + ## Available Models @@ -42,13 +46,12 @@ | Recipe | Description | |---|---| -| {download}`llama3_2_1b_squad.yaml <../../../../examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml>` | SFT — Llama 3.2 1B on SQuAD | -| {download}`llama_3_3_70b_instruct_squad.yaml <../../../../examples/llm_finetune/llama3_3/llama_3_3_70b_instruct_squad.yaml>` | SFT — Llama 3.3 70B Instruct on SQuAD | - +| [llama3_2_1b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml) | SFT — Llama 3.2 1B on SQuAD | +| [llama_3_3_70b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_3/llama_3_3_70b_instruct_squad.yaml) | SFT — Llama 3.3 70B Instruct on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -67,7 +70,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -88,13 +91,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) for full SFT and LoRA instructions. +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) for full SFT and LoRA instructions. ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/microsoft/phi.mdx b/docs/model-coverage/llm/microsoft/phi.mdx index 9635a6efbb..f5acdd6a7d 100644 --- a/docs/model-coverage/llm/microsoft/phi.mdx +++ b/docs/model-coverage/llm/microsoft/phi.mdx @@ -1,15 +1,19 @@ -# Phi +--- +title: "Phi" +description: "" +--- +[Microsoft's Phi](https://azure.microsoft.com/en-us/products/phi) are compact, high-capability language models designed to punch above their weight class. Phi-1.5 and Phi-2 use a standard transformer decoder architecture (`PhiForCausalLM`). For Phi-3 and Phi-4 see [Phi-3 / Phi-4](/model-coverage/large-language-models/phi-3-phi-4). -[Microsoft's Phi](https://azure.microsoft.com/en-us/products/phi) are compact, high-capability language models designed to punch above their weight class. Phi-1.5 and Phi-2 use a standard transformer decoder architecture (`PhiForCausalLM`). For Phi-3 and Phi-4 see [Phi-3 / Phi-4](phi3.md). + -:::{card} | | | |---|---| | **Task** | Text Generation | | **Architecture** | `PhiForCausalLM` | | **Parameters** | 1.3B – 2.7B | | **HF Org** | [microsoft](https://huggingface.co/microsoft) | -::: + + ## Available Models @@ -31,13 +35,12 @@ | Recipe | Description | |---|---| -| {download}`phi_2_squad.yaml <../../../../examples/llm_finetune/phi/phi_2_squad.yaml>` | SFT — Phi-2 on SQuAD | -| {download}`phi_2_squad_peft.yaml <../../../../examples/llm_finetune/phi/phi_2_squad_peft.yaml>` | LoRA — Phi-2 on SQuAD | - +| [phi_2_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_2_squad.yaml) | SFT — Phi-2 on SQuAD | +| [phi_2_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_2_squad_peft.yaml) | LoRA — Phi-2 on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -56,7 +59,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/phi/phi_2_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -77,13 +80,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/phi/phi_2_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/microsoft/phi3-small.mdx b/docs/model-coverage/llm/microsoft/phi3-small.mdx index 59a1d4b457..93e9cd24ca 100644 --- a/docs/model-coverage/llm/microsoft/phi3-small.mdx +++ b/docs/model-coverage/llm/microsoft/phi3-small.mdx @@ -1,15 +1,19 @@ -# Phi-3-Small - +--- +title: "Phi-3-Small" +description: "" +--- [Phi-3-Small](https://azure.microsoft.com/en-us/products/phi) is Microsoft's 7B model using a distinct `Phi3SmallForCausalLM` architecture with blocksparse attention, separate from the standard Phi-3 family. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `Phi3SmallForCausalLM` | | **Parameters** | 7B | | **HF Org** | [microsoft](https://huggingface.co/microsoft) | -::: + + ## Available Models @@ -27,12 +31,11 @@ | Phi-3-small-8k-instruct | [`microsoft/Phi-3-small-8k-instruct`](https://huggingface.co/microsoft/Phi-3-small-8k-instruct) | | Phi-3-small-128k-instruct | [`microsoft/Phi-3-small-128k-instruct`](https://huggingface.co/microsoft/Phi-3-small-128k-instruct) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/microsoft/phi3.mdx b/docs/model-coverage/llm/microsoft/phi3.mdx index df28ef59c5..df62afe4c9 100644 --- a/docs/model-coverage/llm/microsoft/phi3.mdx +++ b/docs/model-coverage/llm/microsoft/phi3.mdx @@ -1,15 +1,19 @@ -# Phi-3 / Phi-4 - +--- +title: "Phi-3 / Phi-4" +description: "" +--- [Phi-3](https://azure.microsoft.com/en-us/products/phi) and [Phi-4](https://azure.microsoft.com/en-us/products/phi) are Microsoft's high-capability small language models using a shared transformer decoder architecture (`Phi3ForCausalLM`). Phi-4-mini and Phi-4 achieve strong benchmark results at relatively small parameter counts. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `Phi3ForCausalLM` | | **Parameters** | 3.8B – 14B | | **HF Org** | [microsoft](https://huggingface.co/microsoft) | -::: + + ## Available Models @@ -38,15 +42,14 @@ | Recipe | Description | |---|---| -| {download}`phi_4_squad.yaml <../../../../examples/llm_finetune/phi/phi_4_squad.yaml>` | SFT — Phi-4 on SQuAD | -| {download}`phi_4_squad_peft.yaml <../../../../examples/llm_finetune/phi/phi_4_squad_peft.yaml>` | LoRA — Phi-4 on SQuAD | -| {download}`phi_3_mini_it_squad.yaml <../../../../examples/llm_finetune/phi/phi_3_mini_it_squad.yaml>` | SFT — Phi-3-mini Instruct on SQuAD | -| {download}`phi_3_mini_it_squad_peft.yaml <../../../../examples/llm_finetune/phi/phi_3_mini_it_squad_peft.yaml>` | LoRA — Phi-3-mini Instruct on SQuAD | - +| [phi_4_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_4_squad.yaml) | SFT — Phi-4 on SQuAD | +| [phi_4_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_4_squad_peft.yaml) | LoRA — Phi-4 on SQuAD | +| [phi_3_mini_it_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_3_mini_it_squad.yaml) | SFT — Phi-3-mini Instruct on SQuAD | +| [phi_3_mini_it_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/phi/phi_3_mini_it_squad_peft.yaml) | LoRA — Phi-3-mini Instruct on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -65,7 +68,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/phi/phi_4_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -86,13 +89,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/phi/phi_4_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/minimax/minimax-m2.mdx b/docs/model-coverage/llm/minimax/minimax-m2.mdx index e515cbeb66..e29af336ff 100644 --- a/docs/model-coverage/llm/minimax/minimax-m2.mdx +++ b/docs/model-coverage/llm/minimax/minimax-m2.mdx @@ -1,15 +1,19 @@ -# MiniMax-M2 - +--- +title: "MiniMax-M2" +description: "" +--- [MiniMax-M2](https://huggingface.co/MiniMaxAI) is MiniMax's large Mixture-of-Experts language model with linear attention for efficient long-context inference. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `MiniMaxM2ForCausalLM` | | **Parameters** | varies | | **HF Org** | [MiniMaxAI](https://huggingface.co/MiniMaxAI) | -::: + + ## Available Models @@ -32,14 +36,13 @@ | Recipe | Description | |---|---| -| {download}`minimax_m2.1_hellaswag_pp.yaml <../../../../examples/llm_finetune/minimax_m2/minimax_m2.1_hellaswag_pp.yaml>` | SFT — MiniMax-M2.1 on HellaSwag with pipeline parallelism | -| {download}`minimax_m2.5_hellaswag_pp.yaml <../../../../examples/llm_finetune/minimax_m2/minimax_m2.5_hellaswag_pp.yaml>` | SFT — MiniMax-M2.5 on HellaSwag with pipeline parallelism | -| {download}`minimax_m2.7_hellaswag_pp.yaml <../../../../examples/llm_finetune/minimax_m2/minimax_m2.7_hellaswag_pp.yaml>` | SFT — MiniMax-M2.7 on HellaSwag with pipeline parallelism | - +| [minimax_m2.1_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.1_hellaswag_pp.yaml) | SFT — MiniMax-M2.1 on HellaSwag with pipeline parallelism | +| [minimax_m2.5_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.5_hellaswag_pp.yaml) | SFT — MiniMax-M2.5 on HellaSwag with pipeline parallelism | +| [minimax_m2.7_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/minimax_m2/minimax_m2.7_hellaswag_pp.yaml) | SFT — MiniMax-M2.7 on HellaSwag with pipeline parallelism | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -52,9 +55,10 @@ git clone https://github.com/NVIDIA-NeMo/Automodel.git cd Automodel ``` -:::{note} -This recipe was validated on **8 nodes × 8 GPUs (64 H100s)**. See the [Launcher Guide](../../../launcher/slurm.md) for multi-node setup. -::: + +This recipe was validated on **8 nodes × 8 GPUs (64 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. + + **3. Run the recipe** from inside the repo: @@ -62,7 +66,7 @@ This recipe was validated on **8 nodes × 8 GPUs (64 H100s)**. See the [Launcher automodel --nproc-per-node=8 examples/llm_finetune/minimax_m2/minimax_m2.1_hellaswag_pp.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -83,13 +87,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/minimax_m2/minimax_m2.1_hellaswag_pp.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/mistralai/ministral3.mdx b/docs/model-coverage/llm/mistralai/ministral3.mdx index 6d9e933101..4900bfff74 100644 --- a/docs/model-coverage/llm/mistralai/ministral3.mdx +++ b/docs/model-coverage/llm/mistralai/ministral3.mdx @@ -1,17 +1,21 @@ -# Ministral3 / Devstral - +--- +title: "Ministral3 / Devstral" +description: "" +--- [Ministral](https://mistral.ai/news/ministraux/) is Mistral AI's efficient small model series optimized for on-device and edge use cases. [Devstral](https://mistral.ai/news/devstral/) is a code-focused model built on the same architecture, designed for software engineering agents. Both use the `Mistral3ForConditionalGeneration` architecture. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `Mistral3ForConditionalGeneration` | | **Parameters** | 3B – 24B | | **HF Org** | [mistralai](https://huggingface.co/mistralai) | -::: + + ## Available Models @@ -38,7 +42,7 @@ Both use the `Mistral3ForConditionalGeneration` architecture. ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -57,7 +61,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/devstral/devstral2_small_2512_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +82,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/devstral/devstral2_small_2512_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/mistralai/mistral.mdx b/docs/model-coverage/llm/mistralai/mistral.mdx index 33e24d981a..6229435f1c 100644 --- a/docs/model-coverage/llm/mistralai/mistral.mdx +++ b/docs/model-coverage/llm/mistralai/mistral.mdx @@ -1,15 +1,19 @@ -# Mistral - +--- +title: "Mistral" +description: "" +--- [Mistral AI](https://mistral.ai/) models are efficient transformer decoder models featuring sliding window attention for long context support. Mistral-Nemo is a 12B model developed jointly with NVIDIA. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `MistralForCausalLM` | | **Parameters** | 7B – 12B | | **HF Org** | [mistralai](https://huggingface.co/mistralai) | -::: + + ## Available Models @@ -33,15 +37,14 @@ | Recipe | Description | |---|---| -| {download}`mistral_7b_squad.yaml <../../../../examples/llm_finetune/mistral/mistral_7b_squad.yaml>` | SFT — Mistral 7B on SQuAD | -| {download}`mistral_7b_squad_peft.yaml <../../../../examples/llm_finetune/mistral/mistral_7b_squad_peft.yaml>` | LoRA — Mistral 7B on SQuAD | -| {download}`mistral_nemo_2407_squad.yaml <../../../../examples/llm_finetune/mistral/mistral_nemo_2407_squad.yaml>` | SFT — Mistral Nemo 2407 on SQuAD | -| {download}`mistral_nemo_2407_squad_peft.yaml <../../../../examples/llm_finetune/mistral/mistral_nemo_2407_squad_peft.yaml>` | LoRA — Mistral Nemo 2407 on SQuAD | - +| [mistral_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_7b_squad.yaml) | SFT — Mistral 7B on SQuAD | +| [mistral_7b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_7b_squad_peft.yaml) | LoRA — Mistral 7B on SQuAD | +| [mistral_nemo_2407_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_nemo_2407_squad.yaml) | SFT — Mistral Nemo 2407 on SQuAD | +| [mistral_nemo_2407_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mistral_nemo_2407_squad_peft.yaml) | LoRA — Mistral Nemo 2407 on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -60,7 +63,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/mistral/mistral_7b_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -81,13 +84,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/mistral/mistral_7b_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/mistralai/mixtral.mdx b/docs/model-coverage/llm/mistralai/mixtral.mdx index b7fca46885..4e1dfafa0b 100644 --- a/docs/model-coverage/llm/mistralai/mixtral.mdx +++ b/docs/model-coverage/llm/mistralai/mixtral.mdx @@ -1,15 +1,19 @@ -# Mixtral - +--- +title: "Mixtral" +description: "" +--- [Mixtral](https://mistral.ai/news/mixtral-of-experts/) is Mistral AI's Mixture-of-Experts model series. Each token is processed by a subset of experts, enabling a large total parameter count with efficient per-token compute. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `MixtralForCausalLM` | | **Parameters** | 47B total / 13B active | | **HF Org** | [mistralai](https://huggingface.co/mistralai) | -::: + + ## Available Models @@ -32,13 +36,12 @@ | Recipe | Description | |---|---| -| {download}`mixtral-8x7b-v0-1_squad.yaml <../../../../examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad.yaml>` | SFT — Mixtral 8x7B on SQuAD | -| {download}`mixtral-8x7b-v0-1_squad_peft.yaml <../../../../examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad_peft.yaml>` | LoRA — Mixtral 8x7B on SQuAD | - +| [mixtral-8x7b-v0-1_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad.yaml) | SFT — Mixtral 8x7B on SQuAD | +| [mixtral-8x7b-v0-1_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad_peft.yaml) | LoRA — Mixtral 8x7B on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -57,7 +60,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +81,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/mistral/mixtral-8x7b-v0-1_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) and the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/moonshotai/moonlight.mdx b/docs/model-coverage/llm/moonshotai/moonlight.mdx index c64a8d30a6..fc5f33f4a5 100644 --- a/docs/model-coverage/llm/moonshotai/moonlight.mdx +++ b/docs/model-coverage/llm/moonshotai/moonlight.mdx @@ -1,15 +1,19 @@ -# Moonlight - +--- +title: "Moonlight" +description: "" +--- [Moonlight](https://huggingface.co/moonshotai/Moonlight-16B-A3B) is a Mixture-of-Experts language model from Moonshot AI trained using Muon optimizer. It uses the `DeepseekV3ForCausalLM` architecture with 16B total parameters and 3B activated per token. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `DeepseekV3ForCausalLM` | | **Parameters** | 16B total / 3B active | | **HF Org** | [moonshotai](https://huggingface.co/moonshotai) | -::: + + ## Available Models @@ -29,13 +33,12 @@ | Recipe | Description | |---|---| -| {download}`moonlight_16b_te.yaml <../../../../examples/llm_finetune/moonlight/moonlight_16b_te.yaml>` | SFT — Moonlight 16B with Transformer Engine | -| {download}`moonlight_16b_te_packed_sequence.yaml <../../../../examples/llm_finetune/moonlight/moonlight_16b_te_packed_sequence.yaml>` | SFT — Moonlight 16B with packed sequences | - +| [moonlight_16b_te.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/moonlight/moonlight_16b_te.yaml) | SFT — Moonlight 16B with Transformer Engine | +| [moonlight_16b_te_packed_sequence.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/moonlight/moonlight_16b_te_packed_sequence.yaml) | SFT — Moonlight 16B with packed sequences | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/moonlight/moonlight_16b_te.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -75,13 +78,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/moonlight/moonlight_16b_te.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/nvidia/nemotron-flash.mdx b/docs/model-coverage/llm/nvidia/nemotron-flash.mdx index e0342c9f1f..89acdb12f2 100644 --- a/docs/model-coverage/llm/nvidia/nemotron-flash.mdx +++ b/docs/model-coverage/llm/nvidia/nemotron-flash.mdx @@ -1,19 +1,24 @@ -# Nemotron-Flash - +--- +title: "Nemotron-Flash" +description: "" +--- [NVIDIA Nemotron-Flash](https://huggingface.co/nvidia/Nemotron-Flash-1B) is a compact, fast language model designed for low-latency inference workloads. -:::{note} + This model requires `trust_remote_code: true` in your recipe YAML. -::: -:::{card} + + + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `NemotronFlashForCausalLM` | | **Parameters** | 1B | | **HF Org** | [nvidia](https://huggingface.co/nvidia) | -::: + + ## Available Models @@ -33,13 +38,12 @@ This model requires `trust_remote_code: true` in your recipe YAML. | Recipe | Description | |---|---| -| {download}`nemotron_flash_1b_squad.yaml <../../../../examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad.yaml>` | SFT — Nemotron-Flash 1B on SQuAD | -| {download}`nemotron_flash_1b_squad_peft.yaml <../../../../examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad_peft.yaml>` | LoRA — Nemotron-Flash 1B on SQuAD | - +| [nemotron_flash_1b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad.yaml) | SFT — Nemotron-Flash 1B on SQuAD | +| [nemotron_flash_1b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad_peft.yaml) | LoRA — Nemotron-Flash 1B on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -58,7 +62,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -79,13 +83,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/nemotron_flash/nemotron_flash_1b_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/nvidia/nemotron-h.mdx b/docs/model-coverage/llm/nvidia/nemotron-h.mdx index 7c87558b10..6aba76ed5e 100644 --- a/docs/model-coverage/llm/nvidia/nemotron-h.mdx +++ b/docs/model-coverage/llm/nvidia/nemotron-h.mdx @@ -1,15 +1,19 @@ -# Nemotron-H - +--- +title: "Nemotron-H" +description: "" +--- [NVIDIA Nemotron-H](https://developer.nvidia.com/blog/nemotron-h-reasoning-enabling-throughput-gains-with-no-compromises/) is a hybrid Mamba-2 / transformer architecture that interleaves selective state space layers with standard attention layers for improved efficiency on long sequences. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `NemotronHForCausalLM` | | **Parameters** | 9B – 30B | | **HF Org** | [nvidia](https://huggingface.co/nvidia) | -::: + + ## Available Models @@ -33,15 +37,14 @@ | Recipe | Description | |---|---| -| {download}`nemotron_nano_9b_squad.yaml <../../../../examples/llm_finetune/nemotron/nemotron_nano_9b_squad.yaml>` | SFT — Nemotron-Nano 9B on SQuAD | -| {download}`nemotron_nano_9b_squad_peft.yaml <../../../../examples/llm_finetune/nemotron/nemotron_nano_9b_squad_peft.yaml>` | LoRA — Nemotron-Nano 9B on SQuAD | -| {download}`nemotron_nano_v3_hellaswag.yaml <../../../../examples/llm_finetune/nemotron/nemotron_nano_v3_hellaswag.yaml>` | SFT — Nemotron-3-Nano 30B on HellaSwag | -| {download}`nemotron_nano_v3_hellaswag_peft.yaml <../../../../examples/llm_finetune/nemotron/nemotron_nano_v3_hellaswag_peft.yaml>` | LoRA — Nemotron-3-Nano 30B on HellaSwag | - +| [nemotron_nano_9b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_9b_squad.yaml) | SFT — Nemotron-Nano 9B on SQuAD | +| [nemotron_nano_9b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_9b_squad_peft.yaml) | LoRA — Nemotron-Nano 9B on SQuAD | +| [nemotron_nano_v3_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_v3_hellaswag.yaml) | SFT — Nemotron-3-Nano 30B on HellaSwag | +| [nemotron_nano_v3_hellaswag_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/nemotron/nemotron_nano_v3_hellaswag_peft.yaml) | LoRA — Nemotron-3-Nano 30B on HellaSwag | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -60,7 +63,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/nemotron/nemotron_nano_9b_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -81,13 +84,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/nemotron/nemotron_nano_9b_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/nvidia/nemotron-super.mdx b/docs/model-coverage/llm/nvidia/nemotron-super.mdx index a8cee21608..fe101f565f 100644 --- a/docs/model-coverage/llm/nvidia/nemotron-super.mdx +++ b/docs/model-coverage/llm/nvidia/nemotron-super.mdx @@ -1,15 +1,19 @@ -# Nemotron-Super (Llama-3.3-Nemotron-Super-49B) - +--- +title: "Nemotron-Super (Llama-3.3-Nemotron-Super-49B)" +description: "" +--- [Llama-3.3-Nemotron-Super-49B-v1](https://huggingface.co/nvidia/Llama-3_3-Nemotron-Super-49B-v1) is a NVIDIA model derived from Llama-3.1-70B through Neural Architecture Search (NAS)-based pruning and knowledge distillation, resulting in a 49B model with strong reasoning capabilities. It uses the `DeciLMForCausalLM` architecture. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `DeciLMForCausalLM` | | **Parameters** | 49B | | **HF Org** | [nvidia](https://huggingface.co/nvidia) | -::: + + ## Available Models @@ -25,12 +29,11 @@ |---|---| | Llama-3.3-Nemotron-Super-49B-v1 | [`nvidia/Llama-3_3-Nemotron-Super-49B-v1`](https://huggingface.co/nvidia/Llama-3_3-Nemotron-Super-49B-v1) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -52,7 +55,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -74,13 +77,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/nvidia/nemotron.mdx b/docs/model-coverage/llm/nvidia/nemotron.mdx index ff760ee75a..be57e1e7eb 100644 --- a/docs/model-coverage/llm/nvidia/nemotron.mdx +++ b/docs/model-coverage/llm/nvidia/nemotron.mdx @@ -1,15 +1,19 @@ -# Nemotron / Minitron - +--- +title: "Nemotron / Minitron" +description: "" +--- [NVIDIA Nemotron](https://www.nvidia.com/en-us/ai-data-science/foundation-models/) and [Minitron](https://developer.nvidia.com/blog/how-to-prune-and-distill-llama-3-1-8b-to-an-nvidia-llama-3-1-minitron-4b-model/) are NVIDIA's family of language models. Minitron models are produced by pruning and distilling larger Llama/Nemotron models into compact, high-performance checkpoints. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `NemotronForCausalLM` | | **Parameters** | 8B | | **HF Org** | [nvidia](https://huggingface.co/nvidia) | -::: + + ## Available Models @@ -25,12 +29,11 @@ |---|---| | Minitron 8B Base | [`nvidia/Minitron-8B-Base`](https://huggingface.co/nvidia/Minitron-8B-Base) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -52,7 +55,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -74,13 +77,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/openai/gpt-oss.mdx b/docs/model-coverage/llm/openai/gpt-oss.mdx index aca34152af..79b3cfded6 100644 --- a/docs/model-coverage/llm/openai/gpt-oss.mdx +++ b/docs/model-coverage/llm/openai/gpt-oss.mdx @@ -1,15 +1,19 @@ -# GPT-OSS - +--- +title: "GPT-OSS" +description: "" +--- [GPT-OSS](https://huggingface.co/openai/gpt-oss-20b) is OpenAI's open-weight model family featuring QuickGELU activations and activation clamping for training stability. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `GptOssForCausalLM` | | **Parameters** | 20B – 120B | | **HF Org** | [openai](https://huggingface.co/openai) | -::: + + ## Available Models @@ -31,13 +35,12 @@ | Recipe | Description | |---|---| -| {download}`gpt_oss_20b.yaml <../../../../examples/llm_finetune/gpt_oss/gpt_oss_20b.yaml>` | SFT — GPT-OSS 20B | -| {download}`gpt_oss_120b.yaml <../../../../examples/llm_finetune/gpt_oss/gpt_oss_120b.yaml>` | SFT — GPT-OSS 120B | - +| [gpt_oss_20b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gpt_oss/gpt_oss_20b.yaml) | SFT — GPT-OSS 20B | +| [gpt_oss_120b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/gpt_oss/gpt_oss_120b.yaml) | SFT — GPT-OSS 120B | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -56,7 +59,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/gpt_oss/gpt_oss_20b.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -77,13 +80,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/gpt_oss/gpt_oss_20b.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/openai/gpt2.mdx b/docs/model-coverage/llm/openai/gpt2.mdx index f5c9f17ecd..d54cc7ea53 100644 --- a/docs/model-coverage/llm/openai/gpt2.mdx +++ b/docs/model-coverage/llm/openai/gpt2.mdx @@ -1,15 +1,19 @@ -# GPT-2 - +--- +title: "GPT-2" +description: "" +--- [GPT-2](https://huggingface.co/openai-community/gpt2) is OpenAI's foundational decoder-only transformer. NeMo AutoModel uses it as a baseline for the Megatron pretraining smoke test and tutorials — its small footprint makes it a convenient target to validate data pipelines, distributed configs, and logging without needing large compute. -:::{card} + + | | | |---|---| | **Task** | Text Generation (pretraining baseline) | | **Architecture** | `GPT2LMHeadModel` | | **Parameters** | 124M – 1.5B | | **HF Org** | [openai-community](https://huggingface.co/openai-community) | -::: + + ## Available Models @@ -32,12 +36,11 @@ | Recipe | Description | |---|---| -| {download}`megatron_pretrain_gpt2.yaml <../../../../examples/llm_pretrain/megatron_pretrain_gpt2.yaml>` | Megatron pretraining smoke test — GPT-2 on FineWeb-Edu | - +| [megatron_pretrain_gpt2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_pretrain/megatron_pretrain_gpt2.yaml) | Megatron pretraining smoke test — GPT-2 on FineWeb-Edu | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -56,7 +59,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_pretrain/megatron_pretrain_gpt2.yaml ``` -See the [Installation Guide](../../../guides/installation.md) and [LLM Pretraining Guide](../../../guides/llm/pretraining.md). +See the [Installation Guide](/get-started/installation) and [LLM Pretraining Guide](/recipes-e2e-examples/pretraining). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/openbmb/minicpm.mdx b/docs/model-coverage/llm/openbmb/minicpm.mdx index 83355a8ba9..74972c4e21 100644 --- a/docs/model-coverage/llm/openbmb/minicpm.mdx +++ b/docs/model-coverage/llm/openbmb/minicpm.mdx @@ -1,15 +1,19 @@ -# MiniCPM - +--- +title: "MiniCPM" +description: "" +--- [MiniCPM](https://github.com/OpenBMB/MiniCPM) is a compact language model series from OpenBMB / Tsinghua University, designed to deliver strong performance at small parameter counts using model merging and continuous training techniques. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `MiniCPMForCausalLM` / `MiniCPM3ForCausalLM` | | **Parameters** | 2B – 4B | | **HF Org** | [openbmb](https://huggingface.co/openbmb) | -::: + + ## Available Models @@ -29,12 +33,11 @@ | MiniCPM 2B SFT | [`openbmb/MiniCPM-2B-sft-bf16`](https://huggingface.co/openbmb/MiniCPM-2B-sft-bf16) | | MiniCPM3 4B | [`openbmb/MiniCPM3-4B`](https://huggingface.co/openbmb/MiniCPM3-4B) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -56,7 +59,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +81,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/orionstar/orion.mdx b/docs/model-coverage/llm/orionstar/orion.mdx index 3345749269..a5c5751e5f 100644 --- a/docs/model-coverage/llm/orionstar/orion.mdx +++ b/docs/model-coverage/llm/orionstar/orion.mdx @@ -1,15 +1,19 @@ -# Orion - +--- +title: "Orion" +description: "" +--- [Orion](https://github.com/OrionStarAI/Orion) is a bilingual (Chinese-English) language model from OrionStar AI, with 14B parameters and strong performance on Chinese benchmarks. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `OrionForCausalLM` | | **Parameters** | 14B | | **HF Org** | [OrionStarAI](https://huggingface.co/OrionStarAI) | -::: + + ## Available Models @@ -27,12 +31,11 @@ | Orion 14B Base | [`OrionStarAI/Orion-14B-Base`](https://huggingface.co/OrionStarAI/Orion-14B-Base) | | Orion 14B Chat | [`OrionStarAI/Orion-14B-Chat`](https://huggingface.co/OrionStarAI/Orion-14B-Chat) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/parasail-ai/gritlm.mdx b/docs/model-coverage/llm/parasail-ai/gritlm.mdx index f5e067c34c..f97d52e013 100644 --- a/docs/model-coverage/llm/parasail-ai/gritlm.mdx +++ b/docs/model-coverage/llm/parasail-ai/gritlm.mdx @@ -1,15 +1,19 @@ -# GritLM - +--- +title: "GritLM" +description: "" +--- [GritLM](https://github.com/ContextualAI/gritlm) (Generative Representational Instruction Tuning) is a unified model that performs both generative language modeling and text embedding in a single model, from Parasail AI. -:::{card} + + | | | |---|---| | **Task** | Text Generation + Embedding | | **Architecture** | `GritLM` | | **Parameters** | 7B | | **HF Org** | [parasail-ai](https://huggingface.co/parasail-ai) | -::: + + ## Available Models @@ -25,12 +29,11 @@ |---|---| | GritLM 7B vllm | [`parasail-ai/GritLM-7B-vllm`](https://huggingface.co/parasail-ai/GritLM-7B-vllm) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -52,7 +55,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -74,13 +77,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/qwen/qwen2-moe.mdx b/docs/model-coverage/llm/qwen/qwen2-moe.mdx index a0b4194d57..9f27cfe793 100644 --- a/docs/model-coverage/llm/qwen/qwen2-moe.mdx +++ b/docs/model-coverage/llm/qwen/qwen2-moe.mdx @@ -1,15 +1,19 @@ -# Qwen2 MoE - +--- +title: "Qwen2 MoE" +description: "" +--- [Qwen1.5-MoE](https://qwenlm.github.io/) is a Mixture-of-Experts variant from Alibaba Cloud that activates only a fraction of parameters per token, enabling efficient training and inference at scale. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `Qwen2MoeForCausalLM` | | **Parameters** | 14.3B total / 2.7B active | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -30,12 +34,11 @@ | Recipe | Description | |---|---| -| {download}`qwen1_5_moe_a2_7b_qlora.yaml <../../../../examples/llm_finetune/qwen/qwen1_5_moe_a2_7b_qlora.yaml>` | QLoRA — Qwen1.5 MoE A2.7B | - +| [qwen1_5_moe_a2_7b_qlora.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen1_5_moe_a2_7b_qlora.yaml) | QLoRA — Qwen1.5 MoE A2.7B | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen1_5_moe_a2_7b_qlora.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -75,13 +78,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen1_5_moe_a2_7b_qlora.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) and the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/qwen/qwen2.mdx b/docs/model-coverage/llm/qwen/qwen2.mdx index 19cec6f9fb..370a8a049c 100644 --- a/docs/model-coverage/llm/qwen/qwen2.mdx +++ b/docs/model-coverage/llm/qwen/qwen2.mdx @@ -1,15 +1,19 @@ -# Qwen2 - +--- +title: "Qwen2" +description: "" +--- [Qwen2](https://qwenlm.github.io/) is Alibaba Cloud's second-generation large language model series. It features grouped query attention, YARN-based long-context extension, and dual chunk attention for long sequences. QwQ-32B-Preview, a reasoning-focused model, also uses this architecture. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `Qwen2ForCausalLM` | | **Parameters** | 0.5B – 72B | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -34,13 +38,12 @@ | Recipe | Description | |---|---| -| {download}`qwen2_5_7b_squad.yaml <../../../../examples/llm_finetune/qwen/qwen2_5_7b_squad.yaml>` | SFT — Qwen2.5 7B on SQuAD | -| {download}`qwq_32b_squad_peft.yaml <../../../../examples/llm_finetune/qwen/qwq_32b_squad_peft.yaml>` | LoRA — QwQ 32B on SQuAD | - +| [qwen2_5_7b_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen2_5_7b_squad.yaml) | SFT — Qwen2.5 7B on SQuAD | +| [qwq_32b_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwq_32b_squad_peft.yaml) | LoRA — QwQ 32B on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -59,7 +62,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen2_5_7b_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -80,13 +83,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen2_5_7b_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) for full SFT and LoRA instructions. +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) for full SFT and LoRA instructions. ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/qwen/qwen3-moe.mdx b/docs/model-coverage/llm/qwen/qwen3-moe.mdx index 977002b850..9480382536 100644 --- a/docs/model-coverage/llm/qwen/qwen3-moe.mdx +++ b/docs/model-coverage/llm/qwen/qwen3-moe.mdx @@ -1,15 +1,19 @@ -# Qwen3 MoE - +--- +title: "Qwen3 MoE" +description: "" +--- [Qwen3 MoE](https://qwenlm.github.io/blog/qwen3/) is the Mixture-of-Experts variant of the Qwen3 series from Alibaba Cloud, activating a small fraction of parameters per token for efficient large-scale training. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `Qwen3MoeForCausalLM` | | **Parameters** | 30B – 235B total | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -31,13 +35,12 @@ | Recipe | Description | |---|---| -| {download}`qwen3_moe_30b_te_deepep.yaml <../../../../examples/llm_finetune/qwen/qwen3_moe_30b_te_deepep.yaml>` | SFT — Qwen3 MoE 30B with TE + DeepEP | -| {download}`qwen3_moe_30b_lora.yaml <../../../../examples/llm_finetune/qwen/qwen3_moe_30b_lora.yaml>` | LoRA — Qwen3 MoE 30B | - +| [qwen3_moe_30b_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_moe_30b_te_deepep.yaml) | SFT — Qwen3 MoE 30B with TE + DeepEP | +| [qwen3_moe_30b_lora.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_moe_30b_lora.yaml) | LoRA — Qwen3 MoE 30B | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -56,7 +59,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_moe_30b_te_deepep.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -77,13 +80,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_moe_30b_te_deepep.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) and the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/qwen/qwen3-next.mdx b/docs/model-coverage/llm/qwen/qwen3-next.mdx index ef4676892a..5a008ea924 100644 --- a/docs/model-coverage/llm/qwen/qwen3-next.mdx +++ b/docs/model-coverage/llm/qwen/qwen3-next.mdx @@ -1,15 +1,19 @@ -# Qwen3-Next - +--- +title: "Qwen3-Next" +description: "" +--- Qwen3-Next is an advanced MoE language model from Alibaba Cloud's Qwen team designed for high-throughput inference with large total parameter counts and efficient per-token activation. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `Qwen3NextForCausalLM` | | **Parameters** | 80B total / 3B active | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -29,12 +33,11 @@ Qwen3-Next is an advanced MoE language model from Alibaba Cloud's Qwen team desi | Recipe | Description | |---|---| -| {download}`qwen3_next_te_deepep.yaml <../../../../examples/llm_finetune/qwen/qwen3_next_te_deepep.yaml>` | SFT — Qwen3-Next with TE + DeepEP | - +| [qwen3_next_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_next_te_deepep.yaml) | SFT — Qwen3-Next with TE + DeepEP | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -47,9 +50,10 @@ git clone https://github.com/NVIDIA-NeMo/Automodel.git cd Automodel ``` -:::{note} -This recipe was validated on **4 nodes × 8 GPUs (32 H100s)**. See the [Launcher Guide](../../../launcher/slurm.md) for multi-node setup. -::: + +This recipe was validated on **4 nodes × 8 GPUs (32 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. + + **3. Run the recipe** from inside the repo: @@ -57,7 +61,7 @@ This recipe was validated on **4 nodes × 8 GPUs (32 H100s)**. See the [Launcher automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_next_te_deepep.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +82,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_next_te_deepep.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/qwen/qwen3.mdx b/docs/model-coverage/llm/qwen/qwen3.mdx index a33d2ae4c5..a899d63172 100644 --- a/docs/model-coverage/llm/qwen/qwen3.mdx +++ b/docs/model-coverage/llm/qwen/qwen3.mdx @@ -1,15 +1,19 @@ -# Qwen3 - +--- +title: "Qwen3" +description: "" +--- [Qwen3](https://qwenlm.github.io/blog/qwen3/) is Alibaba Cloud's third-generation dense language model series, featuring improved reasoning, instruction following, and multilingual capabilities over Qwen2. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `Qwen3ForCausalLM` | | **Parameters** | 0.6B – 32B | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -31,13 +35,12 @@ | Recipe | Description | |---|---| -| {download}`qwen3_0p6b_hellaswag.yaml <../../../../examples/llm_finetune/qwen/qwen3_0p6b_hellaswag.yaml>` | SFT — Qwen3 0.6B on HellaSwag | -| {download}`qwen3_8b_squad_spark.yaml <../../../../examples/llm_finetune/qwen/qwen3_8b_squad_spark.yaml>` | SFT — Qwen3 8B on SQuAD (Spark) | - +| [qwen3_0p6b_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_0p6b_hellaswag.yaml) | SFT — Qwen3 0.6B on HellaSwag | +| [qwen3_8b_squad_spark.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/qwen/qwen3_8b_squad_spark.yaml) | SFT — Qwen3 8B on SQuAD (Spark) | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -56,7 +59,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_0p6b_hellaswag.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -77,13 +80,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/qwen/qwen3_0p6b_hellaswag.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) for full SFT and LoRA instructions. +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) for full SFT and LoRA instructions. ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/stabilityai/stablelm.mdx b/docs/model-coverage/llm/stabilityai/stablelm.mdx index 44adcc079d..d528cd9dd0 100644 --- a/docs/model-coverage/llm/stabilityai/stablelm.mdx +++ b/docs/model-coverage/llm/stabilityai/stablelm.mdx @@ -1,15 +1,19 @@ -# StableLM - +--- +title: "StableLM" +description: "" +--- [StableLM](https://huggingface.co/stabilityai) is Stability AI's series of open language models, available in base and instruction-tuned variants across multiple sizes. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `StableLmForCausalLM` | | **Parameters** | 3B – 7B | | **HF Org** | [stabilityai](https://huggingface.co/stabilityai) | -::: + + ## Available Models @@ -27,12 +31,11 @@ | StableLM 3B 4E1T | [`stabilityai/stablelm-3b-4e1t`](https://huggingface.co/stabilityai/stablelm-3b-4e1t) | | StableLM Base Alpha 7B v2 | [`stabilityai/stablelm-base-alpha-7b-v2`](https://huggingface.co/stabilityai/stablelm-base-alpha-7b-v2) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/stepfun-ai/step-3-5.mdx b/docs/model-coverage/llm/stepfun-ai/step-3-5.mdx index 578f782689..f896f45f09 100644 --- a/docs/model-coverage/llm/stepfun-ai/step-3-5.mdx +++ b/docs/model-coverage/llm/stepfun-ai/step-3-5.mdx @@ -1,15 +1,19 @@ -# Step-3.5 - +--- +title: "Step-3.5" +description: "" +--- [Step-3.5-Flash](https://huggingface.co/stepfun-ai/Step-3.5-Flash) is a Mixture-of-Experts language model from Stepfun AI, designed for efficient inference. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `Step3p5ForCausalLM` | | **Parameters** | varies | | **HF Org** | [stepfun-ai](https://huggingface.co/stepfun-ai) | -::: + + ## Available Models @@ -29,12 +33,11 @@ | Recipe | Description | |---|---| -| {download}`step_3.5_flash_hellaswag_pp.yaml <../../../../examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml>` | SFT — Step-3.5-Flash on HellaSwag with pipeline parallelism | - +| [step_3.5_flash_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml) | SFT — Step-3.5-Flash on HellaSwag with pipeline parallelism | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -47,9 +50,10 @@ git clone https://github.com/NVIDIA-NeMo/Automodel.git cd Automodel ``` -:::{note} -This recipe was validated on **16 nodes × 8 GPUs (128 H100s)**. See the [Launcher Guide](../../../launcher/slurm.md) for multi-node setup. -::: + +This recipe was validated on **16 nodes × 8 GPUs (128 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. + + **3. Run the recipe** from inside the repo: @@ -57,7 +61,7 @@ This recipe was validated on **16 nodes × 8 GPUs (128 H100s)**. See the [Launch automodel --nproc-per-node=8 examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +82,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/stepfun/step_3.5_flash_hellaswag_pp.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/tencent/hy3.mdx b/docs/model-coverage/llm/tencent/hy3.mdx index ea2d8be1e1..616315d3c1 100644 --- a/docs/model-coverage/llm/tencent/hy3.mdx +++ b/docs/model-coverage/llm/tencent/hy3.mdx @@ -1,15 +1,19 @@ -# Hy3 (HunyuanLarge) - +--- +title: "Hy3 (HunyuanLarge)" +description: "" +--- [Hy3-preview](https://huggingface.co/tencent/Hy3-preview) is a 295B Mixture-of-Experts language model from Tencent. It features 80 transformer layers (layer 0 dense, layers 1–79 MoE), 192 routed experts plus 1 shared expert with top-8 sigmoid routing, Grouped Query Attention (64 Q / 8 KV heads), per-head QK RMSNorm, RoPE, and an `e_score_correction_bias` gate buffer for expert-load correction. It supports a 256K context window. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `HYV3ForCausalLM` | | **Parameters** | 295B total | | **HF Org** | [tencent](https://huggingface.co/tencent) | -::: + + ## Available Models @@ -29,11 +33,11 @@ | Recipe | Description | |---|---| -| {download}`hy3_preview_deepep.yaml <../../../../examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml>` | SFT — Hy3-preview with DeepEP | +| [hy3_preview_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml) | SFT — Hy3-preview with DeepEP | ## Try with NeMo AutoModel -**1. Install** ([NeMo AutoModel](../../../guides/installation.md)): +**1. Install** ([NeMo AutoModel](/get-started/installation)): ```bash pip install nemo-automodel @@ -52,11 +56,11 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/hy_v3/hy3_preview_deepep.yaml ``` -See the [NeMo AutoModel Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [NeMo AutoModel Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) and the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/thudm/chatglm.mdx b/docs/model-coverage/llm/thudm/chatglm.mdx index 3f57f10b3a..bb45d2413b 100644 --- a/docs/model-coverage/llm/thudm/chatglm.mdx +++ b/docs/model-coverage/llm/thudm/chatglm.mdx @@ -1,15 +1,19 @@ -# ChatGLM - +--- +title: "ChatGLM" +description: "" +--- [ChatGLM](https://github.com/zai-org/ChatGLM-6B) is a bilingual (Chinese-English) conversational language model from Zhipu AI. ChatGLM2 and ChatGLM3 extend the original with improved performance, longer context, and more efficient attention. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `ChatGLMModel` | | **Parameters** | 6B | | **HF Org** | [zai-org](https://huggingface.co/zai-org) | -::: + + ## Available Models @@ -27,12 +31,11 @@ | ChatGLM3 6B | [`zai-org/chatglm3-6b`](https://huggingface.co/zai-org/chatglm3-6b) | | ChatGLM2 6B | [`zai-org/chatglm2-6b`](https://huggingface.co/zai-org/chatglm2-6b) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/thudm/glm4-moe.mdx b/docs/model-coverage/llm/thudm/glm4-moe.mdx index 2348078168..35278c7b5d 100644 --- a/docs/model-coverage/llm/thudm/glm4-moe.mdx +++ b/docs/model-coverage/llm/thudm/glm4-moe.mdx @@ -1,15 +1,19 @@ -# GLM-4 MoE (GLM-4.5 / GLM-4.7) - +--- +title: "GLM-4 MoE (GLM-4.5 / GLM-4.7)" +description: "" +--- [GLM-4.5 and GLM-4.7](https://huggingface.co/zai-org) are Mixture-of-Experts variants of the GLM family released under the `zai-org` HuggingFace organization. GLM-4.7-Flash is a lighter variant with fewer active parameters. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `Glm4MoeForCausalLM` / `Glm4MoeLiteForCausalLM` | | **Parameters** | varies | | **HF Org** | [zai-org](https://huggingface.co/zai-org) | -::: + + ## Available Models @@ -34,15 +38,14 @@ | Recipe | Description | |---|---| -| {download}`glm_4.5_air_te_deepep.yaml <../../../../examples/llm_finetune/glm/glm_4.5_air_te_deepep.yaml>` | SFT — GLM-4.5-Air with TE + DeepEP | -| {download}`glm_4.7_te_deepep.yaml <../../../../examples/llm_finetune/glm/glm_4.7_te_deepep.yaml>` | SFT — GLM-4.7 with TE + DeepEP | -| {download}`glm_4.7_flash_te_deepep.yaml <../../../../examples/llm_finetune/glm/glm_4.7_flash_te_deepep.yaml>` | SFT — GLM-4.7-Flash with TE + DeepEP | -| {download}`glm_4.7_flash_te_packed_sequence.yaml <../../../../examples/llm_finetune/glm/glm_4.7_flash_te_packed_sequence.yaml>` | SFT — GLM-4.7-Flash with packed sequences | - +| [glm_4.5_air_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.5_air_te_deepep.yaml) | SFT — GLM-4.5-Air with TE + DeepEP | +| [glm_4.7_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.7_te_deepep.yaml) | SFT — GLM-4.7 with TE + DeepEP | +| [glm_4.7_flash_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.7_flash_te_deepep.yaml) | SFT — GLM-4.7-Flash with TE + DeepEP | +| [glm_4.7_flash_te_packed_sequence.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4.7_flash_te_packed_sequence.yaml) | SFT — GLM-4.7-Flash with packed sequences | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -55,9 +58,10 @@ git clone https://github.com/NVIDIA-NeMo/Automodel.git cd Automodel ``` -:::{note} -This recipe was validated on **8 nodes × 8 GPUs (64 H100s)**. See the [Launcher Guide](../../../launcher/slurm.md) for multi-node setup. -::: + +This recipe was validated on **8 nodes × 8 GPUs (64 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. + + **3. Run the recipe** from inside the repo: @@ -65,7 +69,7 @@ This recipe was validated on **8 nodes × 8 GPUs (64 H100s)**. See the [Launcher automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_4.5_air_te_deepep.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -86,13 +90,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_4.5_air_te_deepep.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) and the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/thudm/glm4.mdx b/docs/model-coverage/llm/thudm/glm4.mdx index 8cf0ee2e18..7fbc9e4560 100644 --- a/docs/model-coverage/llm/thudm/glm4.mdx +++ b/docs/model-coverage/llm/thudm/glm4.mdx @@ -1,15 +1,19 @@ -# GLM-4 - +--- +title: "GLM-4" +description: "" +--- [GLM-4](https://github.com/zai-org/GLM-4) is Zhipu AI's fourth-generation General Language Model, featuring strong multilingual capabilities and tool-use support. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `GlmForCausalLM` / `Glm4ForCausalLM` | | **Parameters** | 9B – 32B | | **HF Org** | [zai-org](https://huggingface.co/zai-org) | -::: + + ## Available Models @@ -32,13 +36,12 @@ | Recipe | Description | |---|---| -| {download}`glm_4_9b_chat_hf_squad.yaml <../../../../examples/llm_finetune/glm/glm_4_9b_chat_hf_squad.yaml>` | SFT — GLM-4 9B on SQuAD | -| {download}`glm_4_9b_chat_hf_hellaswag_fp8.yaml <../../../../examples/llm_finetune/glm/glm_4_9b_chat_hf_hellaswag_fp8.yaml>` | SFT — GLM-4 9B on HellaSwag with FP8 | - +| [glm_4_9b_chat_hf_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4_9b_chat_hf_squad.yaml) | SFT — GLM-4 9B on SQuAD | +| [glm_4_9b_chat_hf_hellaswag_fp8.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_4_9b_chat_hf_hellaswag_fp8.yaml) | SFT — GLM-4 9B on HellaSwag with FP8 | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -57,7 +60,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_4_9b_chat_hf_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +81,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_4_9b_chat_hf_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/thudm/glm5-moe-dsa.mdx b/docs/model-coverage/llm/thudm/glm5-moe-dsa.mdx index f7869f18a0..abdd960c41 100644 --- a/docs/model-coverage/llm/thudm/glm5-moe-dsa.mdx +++ b/docs/model-coverage/llm/thudm/glm5-moe-dsa.mdx @@ -1,15 +1,19 @@ -# GLM-5 / GLM-5.1 (MoE + DSA) - +--- +title: "GLM-5 / GLM-5.1 (MoE + DSA)" +description: "" +--- [GLM-5](https://huggingface.co/zai-org/GLM-5) and [GLM-5.1](https://huggingface.co/zai-org/GLM-5.1) are Zhipu AI's latest open-source large Mixture-of-Experts models featuring a DeepSeek-style MLA (Multi-head Latent Attention) + DSA (Dynamic Sparse Attention) architecture. GLM-5.1 shares the `glm_moe_dsa` architecture with GLM-5, with updated weights. -:::{card} + + | | | |---|---| | **Task** | Text Generation (MoE) | | **Architecture** | `GlmMoeDsaForCausalLM` | | **Parameters** | 256 routed experts, 8 active per token | | **HF Org** | [zai-org](https://huggingface.co/zai-org) | -::: + + ## Key Features @@ -34,8 +38,8 @@ | Recipe | Description | |---|---| -| {download}`glm_5_hellaswag_pp.yaml <../../../../examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml>` | SFT — GLM-5 with EP=64, PP=4 on 32 nodes | -| {download}`glm_5.1_hellaswag_pp.yaml <../../../../examples/llm_finetune/glm/glm_5.1_hellaswag_pp.yaml>` | SFT — GLM-5.1 with EP=64, PP=4 on 32 nodes | +| [glm_5_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml) | SFT — GLM-5 with EP=64, PP=4 on 32 nodes | +| [glm_5.1_hellaswag_pp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/glm/glm_5.1_hellaswag_pp.yaml) | SFT — GLM-5.1 with EP=64, PP=4 on 32 nodes | ## Parallel Setup @@ -65,7 +69,7 @@ distributed: ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -78,9 +82,10 @@ git clone https://github.com/NVIDIA-NeMo/Automodel.git cd Automodel ``` -:::{note} -This recipe was validated on **32 nodes × 8 GPUs (256 H100s)**. See the [Launcher Guide](../../../launcher/slurm.md) for multi-node setup. -::: + +This recipe was validated on **32 nodes × 8 GPUs (256 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. + + **3. Run the recipe** from inside the repo: @@ -88,7 +93,7 @@ This recipe was validated on **32 nodes × 8 GPUs (256 H100s)**. See the [Launch automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -109,13 +114,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/glm/glm_5_hellaswag_pp.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md) and the [Large MoE Fine-Tuning Guide](../../../guides/llm/large-moe-finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft) and the [Large MoE Fine-Tuning Guide](/recipes-e2e-examples/large-moe-fine-tuning). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/tiiuae/falcon.mdx b/docs/model-coverage/llm/tiiuae/falcon.mdx index 0f9d0b679b..64a8b33266 100644 --- a/docs/model-coverage/llm/tiiuae/falcon.mdx +++ b/docs/model-coverage/llm/tiiuae/falcon.mdx @@ -1,15 +1,19 @@ -# Falcon - +--- +title: "Falcon" +description: "" +--- [Falcon](https://falconllm.tii.ae/) is a series of open language models from the Technology Innovation Institute (TII) in Abu Dhabi, known for being trained on a high-quality curated web corpus (RefinedWeb). -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `FalconForCausalLM` | | **Parameters** | 7B – 40B | | **HF Org** | [tiiuae](https://huggingface.co/tiiuae) | -::: + + ## Available Models @@ -34,13 +38,12 @@ | Recipe | Description | |---|---| -| {download}`falcon3_7b_instruct_squad.yaml <../../../../examples/llm_finetune/falcon/falcon3_7b_instruct_squad.yaml>` | SFT — Falcon3 7B Instruct on SQuAD | -| {download}`falcon3_7b_instruct_squad_peft.yaml <../../../../examples/llm_finetune/falcon/falcon3_7b_instruct_squad_peft.yaml>` | LoRA — Falcon3 7B Instruct on SQuAD | - +| [falcon3_7b_instruct_squad.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/falcon/falcon3_7b_instruct_squad.yaml) | SFT — Falcon3 7B Instruct on SQuAD | +| [falcon3_7b_instruct_squad_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/falcon/falcon3_7b_instruct_squad_peft.yaml) | LoRA — Falcon3 7B Instruct on SQuAD | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -59,7 +62,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/falcon/falcon3_7b_instruct_squad.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -80,13 +83,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/falcon/falcon3_7b_instruct_squad.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/upstage/solar.mdx b/docs/model-coverage/llm/upstage/solar.mdx index bcde2fcddc..5e93657c25 100644 --- a/docs/model-coverage/llm/upstage/solar.mdx +++ b/docs/model-coverage/llm/upstage/solar.mdx @@ -1,15 +1,19 @@ -# Solar Pro - +--- +title: "Solar Pro" +description: "" +--- [Solar Pro](https://huggingface.co/upstage/solar-pro-preview-instruct) is an enterprise language model from Upstage, built on a depth up-scaling technique applied to Llama-based architectures. -:::{card} + + | | | |---|---| | **Task** | Text Generation | | **Architecture** | `SolarForCausalLM` | | **Parameters** | 22B | | **HF Org** | [upstage](https://huggingface.co/upstage) | -::: + + ## Available Models @@ -25,12 +29,11 @@ |---|---| | Solar Pro Preview Instruct | [`upstage/solar-pro-preview-instruct`](https://huggingface.co/upstage/solar-pro-preview-instruct) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -52,7 +55,7 @@ automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.ya Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -74,13 +77,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx b/docs/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx index 58b18944b3..6158e436ac 100644 --- a/docs/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx +++ b/docs/model-coverage/llm/xiaomimimo/mimo-v2-flash.mdx @@ -1,18 +1,19 @@ -# MiMo-V2-Flash +--- +title: "MiMo-V2-Flash" +description: "" +--- +[MiMo-V2-Flash](https://huggingface.co/XiaomiMiMo/MiMo-V2-Flash) is Xiaomi's hybrid attention Mixture-of-Experts language model. It alternates full and sliding-window attention layers, uses a `sigmoid_with_bias` router with group-limited expert routing, and ships as an FP8 HF checkpoint. -[MiMo-V2-Flash](https://huggingface.co/XiaomiMiMo/MiMo-V2-Flash) is Xiaomi's -hybrid attention Mixture-of-Experts language model. It alternates full and -sliding-window attention layers, uses a `sigmoid_with_bias` router with -group-limited expert routing, and ships as an FP8 HF checkpoint. + -:::{card} | | | |---|---| | **Task** | Text Generation (MoE, hybrid attention) | | **Architecture** | `MiMoV2FlashForCausalLM` | | **Parameters** | Approx. several hundred B total / much smaller active | | **HF Org** | [XiaomiMiMo](https://huggingface.co/XiaomiMiMo) | -::: + + ## Available Models @@ -22,12 +23,8 @@ group-limited expert routing, and ships as an FP8 HF checkpoint. - `MiMoV2FlashForCausalLM` - Sliding-window attention via the `MiMoV2FlashAttention(is_swa=True)` path. -- MoE blocks use the shared `nemo_automodel.components.moe.layers.MoE` - with `score_func="sigmoid_with_bias"` and `gate_precision=fp32` so - routing decisions stay numerically stable when activations are bf16. -- FP8 round-trip in `MiMoV2FlashStateDictAdapter` covers the bulk of - attention/expert weights; layer norms, the gate, `lm_head`, and - `embed_tokens` stay in bf16 per `NON_QUANTIZED_KEY_PATTERNS`. +- MoE blocks use the shared `nemo_automodel.components.moe.layers.MoE` with `score_func="sigmoid_with_bias"` and `gate_precision=fp32` so routing decisions stay numerically stable when activations are bf16. +- FP8 round-trip in `MiMoV2FlashStateDictAdapter` covers the bulk of attention/expert weights; layer norms, the gate, `lm_head`, and `embed_tokens` stay in bf16 per `NON_QUANTIZED_KEY_PATTERNS`. ## Example HF Models @@ -39,12 +36,11 @@ group-limited expert routing, and ships as an FP8 HF checkpoint. | Recipe | Description | |---|---| -| {download}`mimo_v2_flash_hellaswag.yaml <../../../../examples/llm_finetune/mimo_v2_flash/mimo_v2_flash_hellaswag.yaml>` | SFT — MiMo-V2-Flash on HellaSwag | - +| [mimo_v2_flash_hellaswag.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/mimo_v2_flash/mimo_v2_flash_hellaswag.yaml) | SFT — MiMo-V2-Flash on HellaSwag | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -63,7 +59,7 @@ cd Automodel automodel --nproc-per-node=8 examples/llm_finetune/mimo_v2_flash/mimo_v2_flash_hellaswag.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -84,13 +80,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/llm_finetune/mimo_v2_flash/mimo_v2_flash_hellaswag.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [Installation Guide](/get-started/installation) and [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Fine-Tuning -See the [LLM Fine-Tuning Guide](../../../guides/llm/finetune.md). +See the [LLM Fine-Tuning Guide](/recipes-e2e-examples/sft-peft). ## Hugging Face Model Cards diff --git a/docs/model-coverage/omni/index.mdx b/docs/model-coverage/omni/index.mdx index d494632840..342cddfe02 100644 --- a/docs/model-coverage/omni/index.mdx +++ b/docs/model-coverage/omni/index.mdx @@ -1,5 +1,8 @@ -# Omni Models - +--- +title: "Omni Models" +description: "" +position: 5 +--- Omni models go beyond image-text understanding to support additional modalities such as audio, video, or a combination of all — text, image, audio, and video in a single unified model. ## Run Omni Models with NeMo AutoModel @@ -10,24 +13,16 @@ To run omni models with NeMo AutoModel, use NeMo container version [`25.11.00`]( pip3 install --upgrade git+git@github.com:NVIDIA-NeMo/AutoModel.git ``` -For other installation options, see our [NeMo AutoModel Installation Guide](../../guides/installation.md). +For other installation options, see our [NeMo AutoModel Installation Guide](/get-started/installation). ## Supported Models | Owner | Model | Modalities | Architecture | |---|---|---|---| -| Qwen / Alibaba Cloud | [Qwen3-Omni](qwen/qwen3-omni.md) | Text · Image · Audio · Video | `Qwen3OmniForConditionalGeneration` | -| Microsoft | [Phi-4-multimodal](microsoft/phi4-multimodal.md) | Text · Image · Audio | `Phi4MultimodalForCausalLM` | -| NVIDIA | [Nemotron-3-Nano-Omni](nvidia/nemotron-omni.md) | Text · Image · Audio | `NemotronH_Nano_Omni_Reasoning_V3` | +| Qwen / Alibaba Cloud | [Qwen3-Omni](/model-coverage/omni/qwen3-omni) | Text · Image · Audio · Video | `Qwen3OmniForConditionalGeneration` | +| Microsoft | [Phi-4-multimodal](/model-coverage/omni/phi-4-multimodal) | Text · Image · Audio | `Phi4MultimodalForCausalLM` | +| NVIDIA | [Nemotron-3-Nano-Omni](/model-coverage/omni/nemotron-omni) | Text · Image · Audio | `NemotronH_Nano_Omni_Reasoning_V3` | ## Fine-Tune Omni Models -All supported omni models can be fine-tuned using full SFT or PEFT (LoRA) approaches. See the [VLM Fine-Tuning Guide](../../guides/omni/gemma3-3n.md) for general setup instructions. - -```{toctree} -:hidden: - -qwen/qwen3-omni -microsoft/phi4-multimodal -nvidia/nemotron-omni -``` +All supported omni models can be fine-tuned using full SFT or PEFT (LoRA) approaches. See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n) for general setup instructions. diff --git a/docs/model-coverage/omni/microsoft/phi4-multimodal.mdx b/docs/model-coverage/omni/microsoft/phi4-multimodal.mdx index 6b3a27178d..d40fe05796 100644 --- a/docs/model-coverage/omni/microsoft/phi4-multimodal.mdx +++ b/docs/model-coverage/omni/microsoft/phi4-multimodal.mdx @@ -1,15 +1,19 @@ -# Phi-4-multimodal - +--- +title: "Phi-4-multimodal" +description: "" +--- [Phi-4-multimodal-instruct](https://huggingface.co/microsoft/Phi-4-multimodal-instruct) is Microsoft's multimodal extension of Phi-4, supporting text, image, and audio inputs — making it suitable for speech, vision, and combined multimodal tasks. -:::{card} + + | | | |---|---| | **Task** | Omnimodal (Text·Image·Audio) | | **Architecture** | `Phi4MultimodalForCausalLM` | | **Parameters** | 5.6B | | **HF Org** | [microsoft](https://huggingface.co/microsoft) | -::: + + ## Available Models @@ -29,12 +33,11 @@ | Recipe | Dataset | Description | |---|---|---| -| {download}`phi4_mm_cv17.yaml <../../../../examples/vlm_finetune/phi4/phi4_mm_cv17.yaml>` | CommonVoice 17 | SFT — Phi-4-multimodal on CommonVoice (audio-text) | - +| [phi4_mm_cv17.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/phi4/phi4_mm_cv17.yaml) | CommonVoice 17 | SFT — Phi-4-multimodal on CommonVoice (audio-text) | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -53,7 +56,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/phi4/phi4_mm_cv17.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -74,13 +77,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/phi4/phi4_mm_cv17.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [Omni Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [Omni Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM / Omni Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM / Omni Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/omni/nvidia/nemotron-omni.mdx b/docs/model-coverage/omni/nvidia/nemotron-omni.mdx index a77c917f0e..003e979a7b 100644 --- a/docs/model-coverage/omni/nvidia/nemotron-omni.mdx +++ b/docs/model-coverage/omni/nvidia/nemotron-omni.mdx @@ -1,18 +1,22 @@ -# Nemotron-3-Nano-Omni - +--- +title: "Nemotron-3-Nano-Omni" +description: "" +--- [Nemotron-3-Nano-Omni-30B-A3B-Reasoning](https://huggingface.co/nvidia) is NVIDIA's omnimodal reasoning model. It pairs a NemotronH (hybrid Mamba-2 + Attention) MoE language backbone with a RADIO v2.5-H vision encoder and a Parakeet (FastConformer) sound encoder, supporting interleaved text, image, and audio inputs. -:::{card} + + | | | |---|---| | **Task** | Omnimodal (Text·Image·Audio) | | **Architecture** | `NemotronH_Nano_Omni_Reasoning_V3` | | **Parameters** | 30B total / 3B active | | **HF Org** | [nvidia](https://huggingface.co/nvidia) | -::: + + ## Available Models @@ -26,12 +30,12 @@ sound encoder, supporting interleaved text, image, and audio inputs. | Recipe | Dataset | Description | |---|---|---| -| {download}`nemotron_omni_cord_v2.yaml <../../../../examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2.yaml>` | CORD-v2 | Full SFT — receipt parsing | -| {download}`nemotron_omni_cord_v2_peft.yaml <../../../../examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2_peft.yaml>` | CORD-v2 | LoRA PEFT — receipt parsing | +| [nemotron_omni_cord_v2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2.yaml) | CORD-v2 | Full SFT — receipt parsing | +| [nemotron_omni_cord_v2_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2_peft.yaml) | CORD-v2 | LoRA PEFT — receipt parsing | ## Try with NeMo AutoModel -**1. Install** ([NeMo AutoModel](../../../guides/installation.md)): +**1. Install** ([NeMo AutoModel](/get-started/installation)): ```bash pip install nemo-automodel @@ -52,4 +56,4 @@ automodel examples/vlm_finetune/nemotron_omni/nemotron_omni_cord_v2.yaml --nproc For a full walkthrough — dataset preparation, SFT vs. LoRA configs, and post-training inference — see the -[Nemotron-Omni guide](../../../guides/vlm/nemotron-omni.md). +[Nemotron-Omni guide](/recipes-e2e-examples/nemotron-omni). diff --git a/docs/model-coverage/omni/qwen/qwen3-omni.mdx b/docs/model-coverage/omni/qwen/qwen3-omni.mdx index 456a74d4d7..d273479964 100644 --- a/docs/model-coverage/omni/qwen/qwen3-omni.mdx +++ b/docs/model-coverage/omni/qwen/qwen3-omni.mdx @@ -1,15 +1,19 @@ -# Qwen3-Omni - +--- +title: "Qwen3-Omni" +description: "" +--- [Qwen3-Omni](https://qwenlm.github.io/blog/qwen3/) is Alibaba Cloud's omnimodal model supporting text, image, audio, and video inputs in a single unified architecture with a MoE language backbone. -:::{card} + + | | | |---|---| | **Task** | Omnimodal (Text·Image·Audio·Video) | | **Architecture** | `Qwen3OmniForConditionalGeneration` | | **Parameters** | 30B total / 3B active | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -29,12 +33,11 @@ | Recipe | Dataset | Description | |---|---|---| -| {download}`qwen3_omni_moe_30b_te_deepep.yaml <../../../../examples/vlm_finetune/qwen3/qwen3_omni_moe_30b_te_deepep.yaml>` | MedPix-VQA | SFT — Qwen3-Omni 30B with TE + DeepEP | - +| [qwen3_omni_moe_30b_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_omni_moe_30b_te_deepep.yaml) | MedPix-VQA | SFT — Qwen3-Omni 30B with TE + DeepEP | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -53,7 +56,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/qwen3/qwen3_omni_moe_30b_te_deepep.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -74,13 +77,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/qwen3/qwen3_omni_moe_30b_te_deepep.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [Omni Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [Omni Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM / Omni Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM / Omni Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/overview.mdx b/docs/model-coverage/overview.mdx index f0efd2c64a..fa7f939008 100644 --- a/docs/model-coverage/overview.mdx +++ b/docs/model-coverage/overview.mdx @@ -1,21 +1,24 @@ -# Model Coverage Overview - +--- +title: "Model Coverage Overview" +description: "" +position: 1 +--- NeMo AutoModel integrates with Hugging Face `transformers`. Any LLM or VLM that can be instantiated through `transformers` can also be used using NeMo AutoModel, subject to runtime, third-party software dependencies, and feature compatibility. ## Supported Hugging Face Auto Classes | Auto Class | Task | Status | Details | |------------|------|--------|---------| -| `AutoModelForCausalLM` | Text Generation (LLM) | Supported | See [LLM model list](llm/index.md). | -| `AutoModelForImageTextToText` | Image-Text-to-Text (VLM) | Supported | See [VLM model list](vlm/index.md). | +| `AutoModelForCausalLM` | Text Generation (LLM) | Supported | See [LLM model list](/model-coverage/large-language-models/overview). | +| `AutoModelForImageTextToText` | Image-Text-to-Text (VLM) | Supported | See [VLM model list](/model-coverage/vision-language-models/overview). | | `AutoModelForSequenceClassification` | Sequence Classification | WIP | Early support; interfaces may change. | -| Diffusers Pipelines | Diffusion Generation (T2I, T2V) | Supported | See [Diffusion model list](diffusion/index.md). | -| `NeMoAutoModelBiEncoder` | Embedding Models | Supported | See [Embedding model list](embedding/index.md). | -| `NeMoAutoModelCrossEncoder` | Reranking Models | Supported | See [Reranking model list](reranker/index.md). | +| Diffusers Pipelines | Diffusion Generation (T2I, T2V) | Supported | See [Diffusion model list](/model-coverage/diffusion/overview). | +| `NeMoAutoModelBiEncoder` | Embedding Models | Supported | See [Embedding model list](/model-coverage/embedding-models/overview). | +| `NeMoAutoModelCrossEncoder` | Reranking Models | Supported | See [Reranking model list](/model-coverage/reranking-models/overview). | ## Release Log -The table below tracks when model support and key features were added across NeMo AutoModel releases. For the full list of tested architectures and example configs, see the [LLM](llm/index.md) and [VLM](vlm/index.md) pages. +The table below tracks when model support and key features were added across NeMo AutoModel releases. For the full list of tested architectures and example configs, see the [LLM](/model-coverage/large-language-models/overview) and [VLM](/model-coverage/vision-language-models/overview) pages. | Release | Date | New Models | Key Features | |---------|------|------------|--------------| @@ -24,7 +27,6 @@ The table below tracks when model support and key features were added across NeM | **0.1.0** | Oct 2025 | DeepSeek V3/V3.2, 40+ LLM architectures, Gemma 3 VLM | Pretraining, knowledge distillation, FP8 (torchao), pipeline parallelism, HSDP, auto pipelining, ColumnMapped dataset | | **0.1.0a0** | Sep 2025 | Initial LLM and VLM support (Llama, Mistral, Qwen2, Gemma, Phi, and more) | MegatronFSDP, packed sequences, Triton LoRA kernels | - ## Day-0 Support - NeMo AutoModel closely tracks the latest `transformers` version and updates its dependency regularly. @@ -41,4 +43,4 @@ NeMo AutoModel includes a custom model registry that allows teams to: ## Having Issues? -If a model from the Hub doesn't work as expected, see the [Troubleshooting Guide](troubleshooting.md) for common issues and solutions. +If a model from the Hub doesn't work as expected, see the [Troubleshooting Unsupported Models](/model-coverage/overview) guide for common issues and solutions. diff --git a/docs/model-coverage/reranker/index.mdx b/docs/model-coverage/reranker/index.mdx index 3a663e095d..fc22d03f88 100644 --- a/docs/model-coverage/reranker/index.mdx +++ b/docs/model-coverage/reranker/index.mdx @@ -1,18 +1,20 @@ -(reranking-models)= - -# Reranking Models +--- +title: "Reranking Models" +description: "" +position: 1 +--- ## Introduction Reranking models use cross-encoders to score a query-document pair jointly. They are typically used after an embedding model has produced an initial candidate set. NeMo AutoModel supports optimized bidirectional Llama rerankers and falls back to Hugging Face `AutoModelForSequenceClassification` for other architectures. -For first-stage dense retrieval, see [Embedding Models](../embedding/index.md). +For first-stage dense retrieval, see [Embedding Models](/model-coverage/embedding-models/overview). ## Optimized Backbones (Bidirectional Attention) | Owner | Model | Architecture | Wrapper Class | Tasks | |---|---|---|---|---| -| NVIDIA | [llama-nemotron-rerank-1b-v2](nvidia/llama-bidirectional.md) | `LlamaBidirectionalForSequenceClassification` | `NeMoAutoModelCrossEncoder` | Reranking | +| NVIDIA | [llama-nemotron-rerank-1b-v2](/model-coverage/reranking-models/llama-bidirectional) | `LlamaBidirectionalForSequenceClassification` | `NeMoAutoModelCrossEncoder` | Reranking | ## Hugging Face Auto Backbones @@ -25,16 +27,10 @@ Any Hugging Face model loadable using `AutoModelForSequenceClassification` can b ## Dataset -Retrieval fine-tuning requires query-document pairs: each example is a query paired with one positive document and one or more negative documents. Both inline JSONL and corpus ID-based JSON formats are supported. See the [Retrieval Dataset](../../guides/llm/retrieval-dataset.md) guide. +Retrieval fine-tuning requires query-document pairs: each example is a query paired with one positive document and one or more negative documents. Both inline JSONL and corpus ID-based JSON formats are supported. See the [Retrieval Dataset](/datasets/retrieval-dataset) guide. - - -```{toctree} -:hidden: - -nvidia/llama-bidirectional -``` +For a complete walkthrough of training configuration, model-specific settings, and launch commands, see the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune). +*/} diff --git a/docs/model-coverage/reranker/nvidia/llama-bidirectional.mdx b/docs/model-coverage/reranker/nvidia/llama-bidirectional.mdx index 7ae40d502a..110b811236 100644 --- a/docs/model-coverage/reranker/nvidia/llama-bidirectional.mdx +++ b/docs/model-coverage/reranker/nvidia/llama-bidirectional.mdx @@ -1,17 +1,18 @@ -# Llama (Bidirectional) for Reranking +--- +title: "Llama (Bidirectional) for Reranking" +description: "" +--- NeMo AutoModel provides a bidirectional variant of [Meta's Llama](https://www.llama.com/) for reranking tasks. Unlike the standard causal (left-to-right) Llama used for text generation, this variant uses **bidirectional attention**, allowing the query and document to interact across the full sequence before a classification head produces a relevance score. -For the bi-encoder variant, see [Llama (Bidirectional) for Embedding](../../embedding/nvidia/llama-bidirectional.md). +For the bi-encoder variant, see [Llama (Bidirectional) for Embedding](/model-coverage/embedding-models/llama-bidirectional). -:::{card} | | | |---|---| | **Tasks** | Reranking | | **Architecture** | `LlamaBidirectionalForSequenceClassification` | | **Parameters** | 1B – 8B | | **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | -::: ## Available Models @@ -39,11 +40,11 @@ The cross-encoder path is used for pairwise relevance scoring and reranking. | Recipe | Description | |---|---| -| {download}`llama3_2_1b.yaml <../../../../examples/retrieval/cross_encoder/llama3_2_1b.yaml>` | Cross-encoder — Llama 3.2 1B reranker | +| [llama3_2_1b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/retrieval/cross_encoder/llama3_2_1b.yaml) | Cross-encoder — Llama 3.2 1B reranker | ## Try with NeMo AutoModel -**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](../../../guides/installation.md)) for information: +**1. Install NeMo AutoModel**. Refer to the ([Installation Guide](/get-started/installation)) for information: ```bash uv pip install nemo-automodel @@ -62,7 +63,7 @@ cd Automodel torchrun --nproc-per-node=8 examples/retrieval/cross_encoder/finetune.py --config examples/retrieval/cross_encoder/llama3_2_1b.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -83,15 +84,15 @@ cd /opt/Automodel ```bash torchrun --nproc-per-node=8 examples/retrieval/cross_encoder/finetune.py --config examples/retrieval/cross_encoder/llama3_2_1b.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md). +See the [Installation Guide](/get-started/installation). - +See the [Embedding and Reranking Fine-Tuning Guide](/recipes-e2e-examples/retrieval-finetune) for cross-encoder training instructions, including LoRA/PEFT configuration. +*/} ## Hugging Face Model Cards diff --git a/docs/model-coverage/troubleshooting.mdx b/docs/model-coverage/troubleshooting.mdx index cbaf8fc08b..635bda4511 100644 --- a/docs/model-coverage/troubleshooting.mdx +++ b/docs/model-coverage/troubleshooting.mdx @@ -1,7 +1,7 @@ -:orphan: - -# Troubleshooting Unsupported Models - +--- +title: "Troubleshooting Unsupported Models" +description: "" +--- Sometimes a model listed on the Hugging Face Hub may not work with NeMo AutoModel. If you encounter any such model, please open a [GitHub issue](https://github.com/NVIDIA-NeMo/Automodel/issues) with the model ID and any stack trace you see. @@ -18,6 +18,6 @@ These cases typically stem from upstream packaging or dependency constraints. Yo ## Steps to Try -1. **Upgrade NeMo AutoModel** to a release that supports the required `transformers` version. See [Installation](../guides/installation.md). -2. **Enable remote code** — if the model uses custom code, set `trust_remote_code: true` in your `model:` config. See [Hugging Face API Compatibility](../guides/huggingface-api-compatibility.md). +1. **Upgrade NeMo AutoModel** to a release that supports the required `transformers` version. See [Install NeMo AutoModel](/get-started/installation). +2. **Enable remote code** — if the model uses custom code, set `trust_remote_code: true` in your `model:` config. See [Hugging Face API Compatibility](/get-started/hf-compatibility). 3. **Open a GitHub issue** with the model ID and error so we can prioritize support or add a registry-backed implementation. diff --git a/docs/model-coverage/vlm/google/gemma3-vl.mdx b/docs/model-coverage/vlm/google/gemma3-vl.mdx index 16b357b7d3..4f24b7e3d3 100644 --- a/docs/model-coverage/vlm/google/gemma3-vl.mdx +++ b/docs/model-coverage/vlm/google/gemma3-vl.mdx @@ -1,15 +1,19 @@ -# Gemma 3 VL / Gemma 3n - +--- +title: "Gemma 3 VL / Gemma 3n" +description: "" +--- [Gemma 3 VL](https://ai.google.dev/gemma/docs/core) is Google's multimodal extension of Gemma 3, supporting image-text inputs for tasks like image captioning and visual question answering. Gemma 3n is a next-generation efficiency-focused variant. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `Gemma3ForConditionalGeneration` | | **Parameters** | 4B – 27B | | **HF Org** | [google](https://huggingface.co/google) | -::: + + ## Available Models @@ -32,17 +36,16 @@ | Recipe | Dataset | Description | |---|---|---| -| {download}`gemma3_vl_4b_cord_v2.yaml <../../../../examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml>` | cord-v2 | SFT — Gemma 3 4B VL on CORD-v2 | -| {download}`gemma3_vl_4b_cord_v2_peft.yaml <../../../../examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2_peft.yaml>` | cord-v2 | LoRA — Gemma 3 4B VL on CORD-v2 | -| {download}`gemma3_vl_4b_cord_v2_megatron_fsdp.yaml <../../../../examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2_megatron_fsdp.yaml>` | cord-v2 | SFT — Gemma 3 4B VL with MegatronFSDP | -| {download}`gemma3_vl_4b_medpix.yaml <../../../../examples/vlm_finetune/gemma3/gemma3_vl_4b_medpix.yaml>` | MedPix-VQA | SFT — Gemma 3 4B VL on MedPix | -| {download}`gemma3n_vl_4b_medpix.yaml <../../../../examples/vlm_finetune/gemma3n/gemma3n_vl_4b_medpix.yaml>` | MedPix-VQA | SFT — Gemma 3n 4B VL on MedPix | -| {download}`gemma3n_vl_4b_medpix_peft.yaml <../../../../examples/vlm_finetune/gemma3n/gemma3n_vl_4b_medpix_peft.yaml>` | MedPix-VQA | LoRA — Gemma 3n 4B VL on MedPix | - +| [gemma3_vl_4b_cord_v2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml) | cord-v2 | SFT — Gemma 3 4B VL on CORD-v2 | +| [gemma3_vl_4b_cord_v2_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2_peft.yaml) | cord-v2 | LoRA — Gemma 3 4B VL on CORD-v2 | +| [gemma3_vl_4b_cord_v2_megatron_fsdp.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2_megatron_fsdp.yaml) | cord-v2 | SFT — Gemma 3 4B VL with MegatronFSDP | +| [gemma3_vl_4b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3/gemma3_vl_4b_medpix.yaml) | MedPix-VQA | SFT — Gemma 3 4B VL on MedPix | +| [gemma3n_vl_4b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3n/gemma3n_vl_4b_medpix.yaml) | MedPix-VQA | SFT — Gemma 3n 4B VL on MedPix | +| [gemma3n_vl_4b_medpix_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma3n/gemma3n_vl_4b_medpix_peft.yaml) | MedPix-VQA | LoRA — Gemma 3n 4B VL on MedPix | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -61,7 +64,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -82,13 +85,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [Gemma 3 & Gemma 3n Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md) for detailed instructions on dataset preparation, configuration, and multi-GPU training. +See the [Gemma 3 & Gemma 3n Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n) for detailed instructions on dataset preparation, configuration, and multi-GPU training. ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/google/gemma4.mdx b/docs/model-coverage/vlm/google/gemma4.mdx index 27597692d1..e6a72033f8 100644 --- a/docs/model-coverage/vlm/google/gemma4.mdx +++ b/docs/model-coverage/vlm/google/gemma4.mdx @@ -1,15 +1,19 @@ -# Gemma 4 - +--- +title: "Gemma 4" +description: "" +--- [Gemma 4](https://ai.google.dev/gemma) is Google's next-generation multimodal Gemma family, supporting image-text inputs with a Mixture-of-Experts (MoE) language backbone at larger scales. NeMo AutoModel replaces the HF-native dense matmul over experts with the NeMo `GroupedExperts` backend, enabling Expert Parallelism (EP) via the standard MoE parallelizer. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `Gemma4ForConditionalGeneration` | | **Parameters** | 2B – 31B (dense) · 26B-A4B (MoE) | | **HF Org** | [google](https://huggingface.co/google) | -::: + + ## Available Models @@ -35,22 +39,21 @@ | Recipe | Description | |---|---| -| {download}`gemma4_2b.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_2b.yaml>` | SFT — Gemma 4 E2B on MedPix | -| {download}`gemma4_2b_peft.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_2b_peft.yaml>` | LoRA — Gemma 4 E2B on MedPix | -| {download}`gemma4_4b.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_4b.yaml>` | SFT — Gemma 4 E4B on MedPix | -| {download}`gemma4_4b_peft.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_4b_peft.yaml>` | LoRA — Gemma 4 E4B on MedPix | -| {download}`gemma4_31b.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_31b.yaml>` | SFT — Gemma 4 31B on MedPix | -| {download}`gemma4_31b_peft.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_31b_peft.yaml>` | LoRA — Gemma 4 31B on MedPix | -| {download}`gemma4_31b_tp4.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_31b_tp4.yaml>` | SFT — Gemma 4 31B with TP=4 | -| {download}`gemma4_31b_tp4_pp2.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_31b_tp4_pp2.yaml>` | SFT — Gemma 4 31B with TP=4, PP=2 | -| {download}`gemma4_31b_tp4_pp4.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_31b_tp4_pp4.yaml>` | SFT — Gemma 4 31B with TP=4, PP=4 (multi-node) | -| {download}`gemma4_26b_a4b_moe.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_26b_a4b_moe.yaml>` | SFT — Gemma 4 26B-A4B MoE on MedPix | -| {download}`gemma4_26b_a4b_moe_peft.yaml <../../../../examples/vlm_finetune/gemma4/gemma4_26b_a4b_moe_peft.yaml>` | LoRA — Gemma 4 26B-A4B MoE on MedPix | - +| [gemma4_2b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_2b.yaml) | SFT — Gemma 4 E2B on MedPix | +| [gemma4_2b_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_2b_peft.yaml) | LoRA — Gemma 4 E2B on MedPix | +| [gemma4_4b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_4b.yaml) | SFT — Gemma 4 E4B on MedPix | +| [gemma4_4b_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_4b_peft.yaml) | LoRA — Gemma 4 E4B on MedPix | +| [gemma4_31b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b.yaml) | SFT — Gemma 4 31B on MedPix | +| [gemma4_31b_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b_peft.yaml) | LoRA — Gemma 4 31B on MedPix | +| [gemma4_31b_tp4.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b_tp4.yaml) | SFT — Gemma 4 31B with TP=4 | +| [gemma4_31b_tp4_pp2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b_tp4_pp2.yaml) | SFT — Gemma 4 31B with TP=4, PP=2 | +| [gemma4_31b_tp4_pp4.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_31b_tp4_pp4.yaml) | SFT — Gemma 4 31B with TP=4, PP=4 (multi-node) | +| [gemma4_26b_a4b_moe.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_26b_a4b_moe.yaml) | SFT — Gemma 4 26B-A4B MoE on MedPix | +| [gemma4_26b_a4b_moe_peft.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/gemma4/gemma4_26b_a4b_moe_peft.yaml) | LoRA — Gemma 4 26B-A4B MoE on MedPix | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -69,7 +72,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/gemma4/gemma4_4b.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -90,13 +93,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/gemma4/gemma4_4b.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/huggingface/smolvlm.mdx b/docs/model-coverage/vlm/huggingface/smolvlm.mdx index 90397a5a02..285b40b41e 100644 --- a/docs/model-coverage/vlm/huggingface/smolvlm.mdx +++ b/docs/model-coverage/vlm/huggingface/smolvlm.mdx @@ -1,15 +1,19 @@ -# SmolVLM - +--- +title: "SmolVLM" +description: "" +--- [SmolVLM](https://huggingface.co/blog/smolvlm) is HuggingFace's compact vision language model designed for on-device and memory-constrained deployment, featuring an efficient image token compression strategy. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `SmolVLMForConditionalGeneration` | | **Parameters** | 256M – 2B | | **HF Org** | [HuggingFaceTB](https://huggingface.co/HuggingFaceTB) | -::: + + ## Available Models @@ -27,12 +31,11 @@ | SmolVLM Instruct | [`HuggingFaceTB/SmolVLM-Instruct`](https://huggingface.co/HuggingFaceTB/SmolVLM-Instruct) | | SmolVLM 256M Instruct | [`HuggingFaceTB/SmolVLM-256M-Instruct`](https://huggingface.co/HuggingFaceTB/SmolVLM-256M-Instruct) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.y Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/index.mdx b/docs/model-coverage/vlm/index.mdx index 54157cf8a8..2ff5a830c9 100644 --- a/docs/model-coverage/vlm/index.mdx +++ b/docs/model-coverage/vlm/index.mdx @@ -1,5 +1,8 @@ -# Vision Language Models (VLMs) - +--- +title: "Vision Language Models (VLMs)" +description: "" +position: 4 +--- ## Introduction Vision Language Models (VLMs) integrate vision and language processing capabilities, enabling models to understand images and generate text descriptions, answer visual questions, and perform multimodal reasoning. @@ -14,7 +17,7 @@ To run VLMs with NeMo AutoModel, use NeMo container version [`25.11.00`](https:/ pip3 install --upgrade git+git@github.com:NVIDIA-NeMo/AutoModel.git ``` -For other installation options, see our [Installation Guide](../../guides/installation.md). +For other installation options, see our [Installation Guide](/get-started/installation). ## Supported Models @@ -22,46 +25,27 @@ NeMo AutoModel supports [AutoModelForImageTextToText](https://huggingface.co/doc | Owner | Model | Architectures | |---|---|---| -| Moonshot AI | [Kimi-VL](moonshotai/kimi-vl.md) | `KimiVLForConditionalGeneration` | -| Google | [Gemma 3 VL / Gemma 3n](google/gemma3-vl.md) | `Gemma3ForConditionalGeneration` | -| Google | [Gemma 4](google/gemma4.md) | `Gemma4ForConditionalGeneration` | -| Qwen / Alibaba Cloud | [Qwen2.5-VL](qwen/qwen2-5-vl.md) | `Qwen2VLForConditionalGeneration`, `Qwen2_5VLForConditionalGeneration` | -| Qwen / Alibaba Cloud | [Qwen3-VL / Qwen3-VL-MoE](qwen/qwen3-vl.md) | `Qwen3VLForConditionalGeneration` | -| Qwen / Alibaba Cloud | [Qwen3.5-VL](qwen/qwen3-5-vl.md) | `Qwen3_5VLForConditionalGeneration`, `Qwen3_5MoeVLForConditionalGeneration` | -| NVIDIA | [Nemotron-Parse](nvidia/nemotron-parse.md) | `NemotronParseForConditionalGeneration` | -| Mistral AI | [Ministral3 VL](mistralai/ministral3-vl.md) | `Mistral3ForConditionalGeneration` | -| Mistral AI | [Mistral-Small-4](mistralai/mistral-small-4.md) | `MistralForConditionalGeneration` | -| Mistral AI | [Mistral Medium 3.5](mistralai/mistral-medium-3-5.md) | `Mistral3ForConditionalGeneration` (FP8) | -| InternLM / Shanghai AI Lab | [InternVL](internlm/internvl.md) | `InternVLForConditionalGeneration` | -| Meta | [Llama 4](meta/llama4.md) | `Llama4ForConditionalGeneration` | -| HuggingFace | [SmolVLM](huggingface/smolvlm.md) | `SmolVLMForConditionalGeneration` | -| LLaVA | [LLaVA](llava-hf/llava.md) | `LlavaForConditionalGeneration`, `LlavaNextForConditionalGeneration`, `LlavaNextVideoForConditionalGeneration`, `LlavaOnevisionForConditionalGeneration` | -| lmms-lab | [LLaVA-OneVision 1.5](lmms-lab/llava-onevision.md) | `LlavaOneVisionForConditionalGeneration` | +| Moonshot AI | [Kimi-VL](/model-coverage/vision-language-models/kimi-vl) | `KimiVLForConditionalGeneration` | +| Google | [Gemma 3 VL / Gemma 3n](/model-coverage/vision-language-models/gemma-3-vl-gemma-3n) | `Gemma3ForConditionalGeneration` | +| Google | [Gemma 4](/model-coverage/vision-language-models/gemma-4) | `Gemma4ForConditionalGeneration` | +| Qwen / Alibaba Cloud | [Qwen2.5-VL](/model-coverage/vision-language-models/qwen2-5-vl) | `Qwen2VLForConditionalGeneration`, `Qwen2_5VLForConditionalGeneration` | +| Qwen / Alibaba Cloud | [Qwen3-VL / Qwen3-VL-MoE](/model-coverage/vision-language-models/qwen3-vl-qwen3-vl-moe) | `Qwen3VLForConditionalGeneration` | +| Qwen / Alibaba Cloud | [Qwen3.5-VL](/model-coverage/vision-language-models/qwen3-5-vl) | `Qwen3_5VLForConditionalGeneration`, `Qwen3_5MoeVLForConditionalGeneration` | +| NVIDIA | [Nemotron-Parse](/model-coverage/vision-language-models/nemotron-parse) | `NemotronParseForConditionalGeneration` | +| Mistral AI | [Ministral3 VL](/model-coverage/vision-language-models/ministral3-vl) | `Mistral3ForConditionalGeneration` | +| Mistral AI | [Mistral-Small-4](/model-coverage/vision-language-models/mistral-small-4) | `MistralForConditionalGeneration` | +| Mistral AI | [Mistral Medium 3.5](/model-coverage/vision-language-models/mistral-medium-3-5) | `Mistral3ForConditionalGeneration` (FP8) | +| InternLM / Shanghai AI Lab | [InternVL](/model-coverage/vision-language-models/internvl) | `InternVLForConditionalGeneration` | +| Meta | [Llama 4](/model-coverage/vision-language-models/llama-4) | `Llama4ForConditionalGeneration` | +| HuggingFace | [SmolVLM](/model-coverage/vision-language-models/smolvlm) | `SmolVLMForConditionalGeneration` | +| LLaVA | [LLaVA](/model-coverage/vision-language-models/llava) | `LlavaForConditionalGeneration`, `LlavaNextForConditionalGeneration`, `LlavaNextVideoForConditionalGeneration`, `LlavaOnevisionForConditionalGeneration` | +| lmms-lab | [LLaVA-OneVision 1.5](/model-coverage/vision-language-models/llava-onevision) | `LlavaOneVisionForConditionalGeneration` | ## Fine-Tuning -All supported models can be fine-tuned using either full SFT or PEFT (LoRA) approaches. See the [Gemma 3 Fine-Tuning Guide](../../guides/omni/gemma3-3n.md) for a complete walkthrough covering dataset preparation, configuration, and multi-GPU training. - -:::{tip} -In these guides, we use the `quintend/rdr-items` and `naver-clova-ix/cord-v2` datasets for demonstration purposes. Update the recipe YAML `dataset` section to use your own data. See [VLM datasets](../../guides/vlm/dataset.md) and [dataset overview](../../guides/dataset-overview.md). -::: +All supported models can be fine-tuned using either full SFT or PEFT (LoRA) approaches. See the [Gemma 3 Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n) for a complete walkthrough covering dataset preparation, configuration, and multi-GPU training. -```{toctree} -:hidden: + +In these guides, we use the `quintend/rdr-items` and `naver-clova-ix/cord-v2` datasets for demonstration purposes. Update the recipe YAML `dataset` section to use your own data. See [VLM datasets](/datasets/multi-modal-dataset) and [dataset overview](/datasets/overview). -moonshotai/kimi-vl -google/gemma3-vl -google/gemma4 -qwen/qwen2-5-vl -qwen/qwen3-vl -qwen/qwen3-5-vl -nvidia/nemotron-parse -mistralai/ministral3-vl -mistralai/mistral-small-4 -mistralai/mistral-medium-3-5 -internlm/internvl -meta/llama4 -huggingface/smolvlm -llava-hf/llava -lmms-lab/llava-onevision -``` + diff --git a/docs/model-coverage/vlm/internlm/internvl.mdx b/docs/model-coverage/vlm/internlm/internvl.mdx index 0f6da2ae0f..73df1ee41c 100644 --- a/docs/model-coverage/vlm/internlm/internvl.mdx +++ b/docs/model-coverage/vlm/internlm/internvl.mdx @@ -1,15 +1,19 @@ -# InternVL - +--- +title: "InternVL" +description: "" +--- [InternVL](https://github.com/OpenGVLab/InternVL) is a vision language model from Shanghai AI Laboratory (OpenGVLab), combining a large vision encoder with an InternLM language backbone for strong multimodal performance. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `InternVLForConditionalGeneration` | | **Parameters** | 4B – 8B | | **HF Org** | [OpenGVLab](https://huggingface.co/OpenGVLab) | -::: + + ## Available Models @@ -30,12 +34,11 @@ | Recipe | Dataset | Description | |---|---|---| -| {download}`internvl_3_5_4b.yaml <../../../../examples/vlm_finetune/internvl/internvl_3_5_4b.yaml>` | MedPix-VQA | SFT — InternVL3.5 4B on MedPix | - +| [internvl_3_5_4b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/internvl/internvl_3_5_4b.yaml) | MedPix-VQA | SFT — InternVL3.5 4B on MedPix | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/internvl/internvl_3_5_4b.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -75,13 +78,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/internvl/internvl_3_5_4b.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/llava-hf/llava.mdx b/docs/model-coverage/vlm/llava-hf/llava.mdx index 3c9cc28e0c..bae42c4029 100644 --- a/docs/model-coverage/vlm/llava-hf/llava.mdx +++ b/docs/model-coverage/vlm/llava-hf/llava.mdx @@ -1,15 +1,19 @@ -# LLaVA - +--- +title: "LLaVA" +description: "" +--- [LLaVA](https://llava-vl.github.io/) (Large Language and Vision Assistant) is a pioneering open-source multimodal model connecting a vision encoder to a language model via a projection layer. Multiple versions and variants are supported via the `llava-hf` organization on Hugging Face. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `LlavaForConditionalGeneration` / `LlavaNextForConditionalGeneration` | | **Parameters** | 7B – 34B | | **HF Org** | [llava-hf](https://huggingface.co/llava-hf) | -::: + + ## Available Models @@ -36,12 +40,11 @@ | LLaVA-NeXT-Video 7B | [`llava-hf/LLaVA-NeXT-Video-7B-hf`](https://huggingface.co/llava-hf/LLaVA-NeXT-Video-7B-hf) | | LLaVA-OneVision 7B | [`llava-hf/llava-onevision-qwen2-7b-ov-hf`](https://huggingface.co/llava-hf/llava-onevision-qwen2-7b-ov-hf) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -63,7 +66,7 @@ automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.y Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -85,13 +88,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/lmms-lab/llava-onevision.mdx b/docs/model-coverage/vlm/lmms-lab/llava-onevision.mdx index 9d7031232d..186e0d669a 100644 --- a/docs/model-coverage/vlm/lmms-lab/llava-onevision.mdx +++ b/docs/model-coverage/vlm/lmms-lab/llava-onevision.mdx @@ -1,15 +1,19 @@ -# LLaVA-OneVision 1.5 - +--- +title: "LLaVA-OneVision 1.5" +description: "" +--- [LLaVA-OneVision 1.5](https://github.com/EvolvingLMMs-Lab/LLaVA-OneVision-2) is a vision-language model combining a **Rice ViT** encoder with a **Qwen3** language backbone, capable of handling both image and video understanding. NeMo AutoModel ships a custom NVIDIA implementation (`LlavaOneVisionForConditionalGeneration`) with FSDP2/HSDP support, LoRA fine-tuning and distributed training. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `LlavaOneVisionForConditionalGeneration` | | **Parameters** | 4B · 8B | | **HF Org** | [lmms-lab](https://huggingface.co/lmms-lab) | -::: + + ## Available Models @@ -33,13 +37,12 @@ Vision tower is the **Rice Transformer**: 14×14 patch embed with 2D RoPE, stand | Recipe | Description | |---|---| -| {download}`llava_ov_1_5_4b_finetune.yaml <../../../../examples/vlm_finetune/llava_onevision/llava_ov_1_5_4b_finetune.yaml>` | SFT — LLaVA-OneVision-1.5 4B on LLaVA-Instruct-150K | -| {download}`llava_ov_1_5_8b_lora.yaml <../../../../examples/vlm_finetune/llava_onevision/llava_ov_1_5_8b_lora.yaml>` | LoRA — LLaVA-OneVision-1.5 8B on LLaVA-Instruct-150K | - +| [llava_ov_1_5_4b_finetune.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/llava_onevision/llava_ov_1_5_4b_finetune.yaml) | SFT — LLaVA-OneVision-1.5 4B on LLaVA-Instruct-150K | +| [llava_ov_1_5_8b_lora.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/llava_onevision/llava_ov_1_5_8b_lora.yaml) | LoRA — LLaVA-OneVision-1.5 8B on LLaVA-Instruct-150K | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -58,7 +61,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/llava_onevision/llava_ov_1_5_4b_finetune.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -79,13 +82,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/llava_onevision/llava_ov_1_5_4b_finetune.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/meta/llama4.mdx b/docs/model-coverage/vlm/meta/llama4.mdx index 9a3293e5e2..f677e0ce2c 100644 --- a/docs/model-coverage/vlm/meta/llama4.mdx +++ b/docs/model-coverage/vlm/meta/llama4.mdx @@ -1,15 +1,19 @@ -# Llama 4 - +--- +title: "Llama 4" +description: "" +--- [Llama 4](https://ai.meta.com/blog/llama-4-multimodal-intelligence/) is Meta's first natively multimodal model family. Llama 4 Scout and Maverick are MoE models supporting interleaved image and text inputs. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `Llama4ForConditionalGeneration` | | **Parameters** | 17B active (MoE) | | **HF Org** | [meta-llama](https://huggingface.co/meta-llama) | -::: + + ## Available Models @@ -27,12 +31,11 @@ | Llama-4-Scout-17B-16E-Instruct | [`meta-llama/Llama-4-Scout-17B-16E-Instruct`](https://huggingface.co/meta-llama/Llama-4-Scout-17B-16E-Instruct) | | Llama-4-Maverick-17B-128E-Instruct | [`meta-llama/Llama-4-Maverick-17B-128E-Instruct`](https://huggingface.co/meta-llama/Llama-4-Maverick-17B-128E-Instruct) | - ## Try with NeMo AutoModel Install NeMo AutoModel and follow the fine-tuning guide to configure a recipe for this model. -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -54,7 +57,7 @@ automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.y Replace `` with the model ID from **Example HF Models** above. -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel automodel --nproc-per-node=8 examples/vlm_finetune/gemma3/gemma3_vl_4b_cord_v2.yaml \ --model.pretrained_model_name_or_path ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/mistralai/ministral3-vl.mdx b/docs/model-coverage/vlm/mistralai/ministral3-vl.mdx index 15d9581eb1..10fa50ab2f 100644 --- a/docs/model-coverage/vlm/mistralai/ministral3-vl.mdx +++ b/docs/model-coverage/vlm/mistralai/ministral3-vl.mdx @@ -1,15 +1,19 @@ -# Ministral3 VL - +--- +title: "Ministral3 VL" +description: "" +--- [Ministral3](https://mistral.ai/news/ministraux/) is Mistral AI's efficient small model series. The vision-capable variants support image-text inputs for multimodal tasks. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `Mistral3ForConditionalGeneration` | | **Parameters** | 3B – 14B | | **HF Org** | [mistralai](https://huggingface.co/mistralai) | -::: + + ## Available Models @@ -33,14 +37,13 @@ | Recipe | Dataset | Description | |---|---|---| -| {download}`ministral3_3b_medpix.yaml <../../../../examples/vlm_finetune/mistral/ministral3_3b_medpix.yaml>` | MedPix-VQA | SFT — Ministral3 3B on MedPix | -| {download}`ministral3_8b_medpix.yaml <../../../../examples/vlm_finetune/mistral/ministral3_8b_medpix.yaml>` | MedPix-VQA | SFT — Ministral3 8B on MedPix | -| {download}`ministral3_14b_medpix.yaml <../../../../examples/vlm_finetune/mistral/ministral3_14b_medpix.yaml>` | MedPix-VQA | SFT — Ministral3 14B on MedPix | - +| [ministral3_3b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral/ministral3_3b_medpix.yaml) | MedPix-VQA | SFT — Ministral3 3B on MedPix | +| [ministral3_8b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral/ministral3_8b_medpix.yaml) | MedPix-VQA | SFT — Ministral3 8B on MedPix | +| [ministral3_14b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral/ministral3_14b_medpix.yaml) | MedPix-VQA | SFT — Ministral3 14B on MedPix | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -59,7 +62,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/mistral/ministral3_3b_medpix.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -80,13 +83,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/mistral/ministral3_3b_medpix.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx b/docs/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx index 1650d2a4a0..13a6a57d7e 100644 --- a/docs/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx +++ b/docs/model-coverage/vlm/mistralai/mistral-medium-3-5.mdx @@ -1,5 +1,7 @@ -# Mistral Medium 3.5 - +--- +title: "Mistral Medium 3.5" +description: "" +--- [Mistral Medium 3.5](https://huggingface.co/mistralai) is Mistral AI's flagship **128B dense** model that merges instruction-following, reasoning, and coding into a single checkpoint with a configurable reasoning mode. @@ -9,7 +11,8 @@ It unifies the lineage of *Mistral Medium 3.1*, *Magistral Medium*, and H100 nodes — a notable footprint advantage over comparably-capable Mixture-of-Experts (MoE) systems. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | @@ -19,7 +22,8 @@ Mixture-of-Experts (MoE) systems. | **Languages** | 40+ (English, French, Spanish, German, Russian, Chinese, Japanese, Italian, Portuguese, Arabic, Hindi, Korean, plus Indic / Nordic / Eastern European tail) | | **License** | Modified MIT (open-weights, ≤ $20M annual revenue threshold) | | **HF Org** | [mistralai](https://huggingface.co/mistralai) | -::: + + ## Architecture @@ -89,12 +93,11 @@ training to fit on H100-80GB. | Recipe | Dataset | Description | |---|---|---| -| {download}`mistral3p5_128b_medpix.yaml <../../../../examples/vlm_finetune/mistral3p5/mistral3p5_128b_medpix.yaml>` | MedPix-VQA | SFT — Mistral Medium 3.5 128B on MedPix, 8 nodes × 8 GPUs (TP=8 PP=8) | - +| [mistral3p5_128b_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral3p5/mistral3p5_128b_medpix.yaml) | MedPix-VQA | SFT — Mistral Medium 3.5 128B on MedPix, 8 nodes × 8 GPUs (TP=8 PP=8) | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -107,22 +110,23 @@ git clone https://github.com/NVIDIA-NeMo/Automodel.git cd Automodel ``` -:::{note} + This recipe was validated on **8 nodes × 8 GPUs (64 H100s)** with -TP=8 PP=8 DP=1. See the [Launcher Guide](../../../launcher/slurm.md) +TP=8 PP=8 DP=1. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. Inference / single-node fine-tune fits in **1 × H200** or **2 × H100** nodes thanks to the dense + FP8 layout. -::: + + **3. Run the recipe** via Slurm (see the -[fine-tuning guide](../../../guides/vlm/mistral-medium-3-5.md) for a +[fine-tuning guide](/recipes-e2e-examples/mistral-medium-3-5) for a complete launch script): ```bash sbatch your_slurm_script.sub ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -143,14 +147,14 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/mistral3p5/mistral3p5_128b_medpix.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and the -[Mistral Medium 3.5 Fine-Tuning Guide](../../../guides/vlm/mistral-medium-3-5.md). +See the [Installation Guide](/get-started/installation) and the +[Mistral Medium 3.5 Fine-Tuning Guide](/recipes-e2e-examples/mistral-medium-3-5). ## Fine-Tuning -See the [Mistral Medium 3.5 Fine-Tuning Guide](../../../guides/vlm/mistral-medium-3-5.md). +See the [Mistral Medium 3.5 Fine-Tuning Guide](/recipes-e2e-examples/mistral-medium-3-5). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/mistralai/mistral-small-4.mdx b/docs/model-coverage/vlm/mistralai/mistral-small-4.mdx index 86dc86de18..cf6820c599 100644 --- a/docs/model-coverage/vlm/mistralai/mistral-small-4.mdx +++ b/docs/model-coverage/vlm/mistralai/mistral-small-4.mdx @@ -1,15 +1,19 @@ -# Mistral-Small-4 - +--- +title: "Mistral-Small-4" +description: "" +--- [Mistral-Small-4-119B](https://huggingface.co/mistralai/Mistral-Small-4-119B-2603) is Mistral AI's multimodal MoE model supporting both text and image inputs at scale. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `MistralForConditionalGeneration` | | **Parameters** | 119B (MoE) | | **HF Org** | [mistralai](https://huggingface.co/mistralai) | -::: + + ## Available Models @@ -29,12 +33,11 @@ | Recipe | Dataset | Description | |---|---|---| -| {download}`mistral4_medpix.yaml <../../../../examples/vlm_finetune/mistral4/mistral4_medpix.yaml>` | MedPix-VQA | SFT — Mistral-Small-4 on MedPix | - +| [mistral4_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/mistral4/mistral4_medpix.yaml) | MedPix-VQA | SFT — Mistral-Small-4 on MedPix | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -47,9 +50,10 @@ git clone https://github.com/NVIDIA-NeMo/Automodel.git cd Automodel ``` -:::{note} -This recipe was validated on **4 nodes × 8 GPUs (32 H100s)**. See the [Launcher Guide](../../../launcher/slurm.md) for multi-node setup. -::: + +This recipe was validated on **4 nodes × 8 GPUs (32 H100s)**. See the [Launcher Guide](/job-launchers/slurm-cluster) for multi-node setup. + + **3. Run the recipe** from inside the repo: @@ -57,7 +61,7 @@ This recipe was validated on **4 nodes × 8 GPUs (32 H100s)**. See the [Launcher automodel --nproc-per-node=8 examples/vlm_finetune/mistral4/mistral4_medpix.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +82,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/mistral4/mistral4_medpix.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/moonshotai/kimi-vl.mdx b/docs/model-coverage/vlm/moonshotai/kimi-vl.mdx index f8344a9936..e23bbf80b1 100644 --- a/docs/model-coverage/vlm/moonshotai/kimi-vl.mdx +++ b/docs/model-coverage/vlm/moonshotai/kimi-vl.mdx @@ -1,15 +1,19 @@ -# Kimi-VL - +--- +title: "Kimi-VL" +description: "" +--- [Kimi-VL](https://huggingface.co/moonshotai/Kimi-VL-A3B-Instruct) and Kimi-K25-VL are vision language models from Moonshot AI. Kimi-VL-A3B uses a MoE language backbone (3B active parameters) with a vision encoder, supporting image understanding and multimodal reasoning. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `KimiVLForConditionalGeneration` | | **Parameters** | ~3B active (MoE) | | **HF Org** | [moonshotai](https://huggingface.co/moonshotai) | -::: + + ## Available Models @@ -30,13 +34,12 @@ | Recipe | Dataset | Description | |---|---|---| -| {download}`kimi2vl_cordv2.yaml <../../../../examples/vlm_finetune/kimi/kimi2vl_cordv2.yaml>` | cord-v2 | SFT — Kimi-VL on CORD-v2 | -| {download}`kimi25vl_medpix.yaml <../../../../examples/vlm_finetune/kimi/kimi25vl_medpix.yaml>` | MedPix-VQA | SFT — Kimi-K25-VL on MedPix | - +| [kimi2vl_cordv2.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/kimi/kimi2vl_cordv2.yaml) | cord-v2 | SFT — Kimi-VL on CORD-v2 | +| [kimi25vl_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/kimi/kimi25vl_medpix.yaml) | MedPix-VQA | SFT — Kimi-K25-VL on MedPix | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -55,7 +58,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/kimi/kimi2vl_cordv2.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -76,13 +79,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/kimi/kimi2vl_cordv2.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/nvidia/nemotron-parse.mdx b/docs/model-coverage/vlm/nvidia/nemotron-parse.mdx index a579a3e9f5..272be22e76 100644 --- a/docs/model-coverage/vlm/nvidia/nemotron-parse.mdx +++ b/docs/model-coverage/vlm/nvidia/nemotron-parse.mdx @@ -1,15 +1,19 @@ -# Nemotron-Parse - +--- +title: "Nemotron-Parse" +description: "" +--- [Nemotron-Parse-v1.1](https://huggingface.co/nvidia/NVIDIA-Nemotron-Parse-v1.1) is NVIDIA's document parsing VLM, specializing in extracting structured information from complex documents including tables, forms, and mixed-content PDFs. -:::{card} + + | | | |---|---| | **Task** | Document Parsing | | **Architecture** | `NemotronParseForConditionalGeneration` | | **Parameters** | varies | | **HF Org** | [nvidia](https://huggingface.co/nvidia) | -::: + + ## Available Models @@ -29,12 +33,11 @@ | Recipe | Dataset | Description | Try on Brev | |---|---|---|---| -| {download}`nemotron_parse_v1_1.yaml <../../../../examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml>` | cord-v2 | SFT — Nemotron-Parse on CORD-v2 | [![Launch on Brev](https://brev-assets.s3.us-west-1.amazonaws.com/nv-lb-dark.svg)](https://brev.nvidia.com/launchable/deploy/now?launchableID=env-3C6LDKU2DfOvpVTFhjw3YQ4djPM) | - +| [nemotron_parse_v1_1.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml) | cord-v2 | SFT — Nemotron-Parse on CORD-v2 | [![Launch on Brev](https://brev-assets.s3.us-west-1.amazonaws.com/nv-lb-dark.svg)](https://brev.nvidia.com/launchable/deploy/now?launchableID=env-3C6LDKU2DfOvpVTFhjw3YQ4djPM) | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -53,7 +56,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -74,9 +77,9 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/nemotron/nemotron_parse_v1_1.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning Tutorial on Brev @@ -84,7 +87,7 @@ Launch the end-to-end Nemotron Parse fine-tuning tutorial on Brev with a single [![Launch on Brev](https://brev-assets.s3.us-west-1.amazonaws.com/nv-lb-dark.svg)](https://brev.nvidia.com/launchable/deploy/now?launchableID=env-3C6LDKU2DfOvpVTFhjw3YQ4djPM) -See also the [tutorial notebook](https://github.com/NVIDIA-NeMo/Automodel/blob/main/tutorials/nemotron-parse/finetune.ipynb) and the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See also the [tutorial notebook](https://github.com/NVIDIA-NeMo/Automodel/blob/main/tutorials/nemotron-parse/finetune.ipynb) and the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/qwen/qwen2-5-vl.mdx b/docs/model-coverage/vlm/qwen/qwen2-5-vl.mdx index fad741e688..d7e09efa5c 100644 --- a/docs/model-coverage/vlm/qwen/qwen2-5-vl.mdx +++ b/docs/model-coverage/vlm/qwen/qwen2-5-vl.mdx @@ -1,15 +1,19 @@ -# Qwen2.5-VL - +--- +title: "Qwen2.5-VL" +description: "" +--- [Qwen2.5-VL](https://qwenlm.github.io/blog/qwen2.5-vl/) is Alibaba Cloud's vision language model series supporting image and video understanding. It features dynamic resolution processing and integrates with the Qwen2.5 language backbone. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `Qwen2_5VLForConditionalGeneration` | | **Parameters** | 2B – 72B | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -36,12 +40,11 @@ | Recipe | Dataset | Description | |---|---|---| -| {download}`qwen2_5_vl_3b_rdr.yaml <../../../../examples/vlm_finetune/qwen2_5/qwen2_5_vl_3b_rdr.yaml>` | rdr-items | SFT — Qwen2.5-VL 3B on RDR Items | - +| [qwen2_5_vl_3b_rdr.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen2_5/qwen2_5_vl_3b_rdr.yaml) | rdr-items | SFT — Qwen2.5-VL 3B on RDR Items | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -60,7 +63,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/qwen2_5/qwen2_5_vl_3b_rdr.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -81,13 +84,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/qwen2_5/qwen2_5_vl_3b_rdr.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/qwen/qwen3-5-vl.mdx b/docs/model-coverage/vlm/qwen/qwen3-5-vl.mdx index 50890fb5fe..37408a0939 100644 --- a/docs/model-coverage/vlm/qwen/qwen3-5-vl.mdx +++ b/docs/model-coverage/vlm/qwen/qwen3-5-vl.mdx @@ -1,15 +1,19 @@ -# Qwen3.5-VL - +--- +title: "Qwen3.5-VL" +description: "" +--- Qwen3.5-VL is Alibaba Cloud's next-generation vision language model series, including dense and MoE variants for image and multimodal understanding tasks. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `Qwen3_5VLForConditionalGeneration` | | **Parameters** | 4B – 35B+ | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -28,17 +32,16 @@ Qwen3.5-VL is Alibaba Cloud's next-generation vision language model series, incl | Recipe | Dataset | Description | |---|---|---| -| {download}`qwen3_5_4b.yaml <../../../../examples/vlm_finetune/qwen3_5/qwen3_5_4b.yaml>` | MedPix-VQA | SFT — Qwen3.5-VL 4B on MedPix | -| {download}`qwen3_5_9b.yaml <../../../../examples/vlm_finetune/qwen3_5/qwen3_5_9b.yaml>` | MedPix-VQA | SFT — Qwen3.5-VL 9B on MedPix | -| {download}`qwen3_5_moe_medpix.yaml <../../../../examples/vlm_finetune/qwen3_5_moe/qwen3_5_moe_medpix.yaml>` | MedPix-VQA | SFT — Qwen3.5-MoE on MedPix | -| {download}`qwen3_5_35b.yaml <../../../../examples/vlm_finetune/qwen3_5_moe/qwen3_5_35b.yaml>` | MedPix-VQA | SFT — Qwen3.5 35B on MedPix | -| {download}`qwen3_6_27b.yaml <../../../../examples/vlm_finetune/qwen3_5/qwen3_6_27b.yaml>` | MedPix-VQA | SFT — Qwen3.6-27B on MedPix | -| {download}`qwen3_6_35b.yaml <../../../../examples/vlm_finetune/qwen3_5_moe/qwen3_6_35b.yaml>` | MedPix-VQA | SFT — Qwen3.6 35B-A3B on MedPix | - +| [qwen3_5_4b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5/qwen3_5_4b.yaml) | MedPix-VQA | SFT — Qwen3.5-VL 4B on MedPix | +| [qwen3_5_9b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5/qwen3_5_9b.yaml) | MedPix-VQA | SFT — Qwen3.5-VL 9B on MedPix | +| [qwen3_5_moe_medpix.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5_moe/qwen3_5_moe_medpix.yaml) | MedPix-VQA | SFT — Qwen3.5-MoE on MedPix | +| [qwen3_5_35b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5_moe/qwen3_5_35b.yaml) | MedPix-VQA | SFT — Qwen3.5 35B on MedPix | +| [qwen3_6_27b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5/qwen3_6_27b.yaml) | MedPix-VQA | SFT — Qwen3.6-27B on MedPix | +| [qwen3_6_35b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3_5_moe/qwen3_6_35b.yaml) | MedPix-VQA | SFT — Qwen3.6 35B-A3B on MedPix | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -57,7 +60,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/qwen3_5/qwen3_5_4b.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -78,13 +81,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/qwen3_5/qwen3_5_4b.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/model-coverage/vlm/qwen/qwen3-vl.mdx b/docs/model-coverage/vlm/qwen/qwen3-vl.mdx index db9ef2d4bb..2762e81426 100644 --- a/docs/model-coverage/vlm/qwen/qwen3-vl.mdx +++ b/docs/model-coverage/vlm/qwen/qwen3-vl.mdx @@ -1,15 +1,19 @@ -# Qwen3-VL / Qwen3-VL-MoE - +--- +title: "Qwen3-VL / Qwen3-VL-MoE" +description: "" +--- [Qwen3-VL](https://qwenlm.github.io/blog/qwen3/) is Alibaba Cloud's third-generation vision language model series. The MoE variant activates a fraction of parameters per token for efficient large-scale inference. -:::{card} + + | | | |---|---| | **Task** | Image-Text-to-Text | | **Architecture** | `Qwen3VLForConditionalGeneration` | | **Parameters** | 4B – 235B | | **HF Org** | [Qwen](https://huggingface.co/Qwen) | -::: + + ## Available Models @@ -33,15 +37,14 @@ | Recipe | Dataset | Description | |---|---|---| -| {download}`qwen3_vl_4b_instruct_rdr.yaml <../../../../examples/vlm_finetune/qwen3/qwen3_vl_4b_instruct_rdr.yaml>` | rdr-items | SFT — Qwen3-VL 4B on RDR Items | -| {download}`qwen3_vl_8b_instruct_rdr.yaml <../../../../examples/vlm_finetune/qwen3/qwen3_vl_8b_instruct_rdr.yaml>` | rdr-items | SFT — Qwen3-VL 8B on RDR Items | -| {download}`qwen3_vl_moe_30b_te_deepep.yaml <../../../../examples/vlm_finetune/qwen3/qwen3_vl_moe_30b_te_deepep.yaml>` | MedPix-VQA | SFT — Qwen3-VL-MoE 30B with TE + DeepEP | -| {download}`qwen3_vl_moe_235b.yaml <../../../../examples/vlm_finetune/qwen3/qwen3_vl_moe_235b.yaml>` | MedPix-VQA | SFT — Qwen3-VL-MoE 235B | - +| [qwen3_vl_4b_instruct_rdr.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_4b_instruct_rdr.yaml) | rdr-items | SFT — Qwen3-VL 4B on RDR Items | +| [qwen3_vl_8b_instruct_rdr.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_8b_instruct_rdr.yaml) | rdr-items | SFT — Qwen3-VL 8B on RDR Items | +| [qwen3_vl_moe_30b_te_deepep.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_moe_30b_te_deepep.yaml) | MedPix-VQA | SFT — Qwen3-VL-MoE 30B with TE + DeepEP | +| [qwen3_vl_moe_235b.yaml](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/vlm_finetune/qwen3/qwen3_vl_moe_235b.yaml) | MedPix-VQA | SFT — Qwen3-VL-MoE 235B | ## Try with NeMo AutoModel -**1. Install** ([full instructions](../../../guides/installation.md)): +**1. Install** ([full instructions](/get-started/installation)): ```bash pip install nemo-automodel @@ -60,7 +63,7 @@ cd Automodel automodel --nproc-per-node=8 examples/vlm_finetune/qwen3/qwen3_vl_4b_instruct_rdr.yaml ``` -:::{dropdown} Run with Docker + **1. Pull the container** and mount a checkpoint directory: ```bash @@ -81,13 +84,13 @@ cd /opt/Automodel ```bash automodel --nproc-per-node=8 examples/vlm_finetune/qwen3/qwen3_vl_4b_instruct_rdr.yaml ``` -::: + -See the [Installation Guide](../../../guides/installation.md) and [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [Installation Guide](/get-started/installation) and [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Fine-Tuning -See the [VLM Fine-Tuning Guide](../../../guides/omni/gemma3-3n.md). +See the [VLM Fine-Tuning Guide](/recipes-e2e-examples/gemma-3-3n). ## Hugging Face Model Cards diff --git a/docs/performance-summary.mdx b/docs/performance-summary.mdx index 622612cac9..be080d534b 100644 --- a/docs/performance-summary.mdx +++ b/docs/performance-summary.mdx @@ -1,5 +1,8 @@ -# Performance Summary - +--- +title: "Performance Summary" +description: "" +position: 1 +--- This document provides performance benchmarks for various large language models using NeMo AutoModel with the PyTorch backend. ## Pre-Training Performance @@ -20,7 +23,6 @@ The table below shows training performance for full sequences with no padding ac | GPT-OSS 120B | 64 | 512 | 2 | 2 | 4 | 4096 | 1 | 1 | 1 | - | - | 64 | TE + DeepEP + FlexAttn | 4.30 | 231 | 7,626 | | Llama3 70B | 64 | 128 | 1 | 1 | 4 | 8192 | 1 | 1 | 2 | - | - | 32 | TE + fsdp2_prefetch | 18.90 | 389 | 866.77 | - ## Fine-Tuning (LoRA) Performance The table below shows fine-tuning (LoRA) performance for full sequences with no padding across different model architectures and scales. @@ -69,14 +71,14 @@ Pre-training and fine-tuning (LoRA) benchmark configurations are available in [` - [`custom_llama3_3_70b_instruct_peft_benchmark_2nodes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/llama3_3/custom_llama3_3_70b_instruct_peft_benchmark_2nodes.yaml) - Llama-70B fine-tuning (LoRA) optimized on 2 nodes - [`custom_qwen2_5_32b_peft_benchmark_2nodes.yaml`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/examples/llm_benchmark/qwen/custom_qwen2_5_32b_peft_benchmark_2nodes.yaml) - Qwen2.5-32B fine-tuning (LoRA) optimized on 2 nodes -:::{note} + - All benchmarks use mock data for consistent performance measurement. - Fake balanced gate is enabled to simulate ideal expert routing. - No gradient clipping applied for pure performance measurement. - MFU calculated using peak TFLOPs for the system (989 for BF16 H100). - Step times include forward and backward passes + optimizer step for the global batch. -::: + ## Version Information - **Last Updated**: 2025-10-02 diff --git a/docs/release-notes.mdx b/docs/release-notes.mdx index 7cbefe5b43..2c33c9fb47 100644 --- a/docs/release-notes.mdx +++ b/docs/release-notes.mdx @@ -1,5 +1,7 @@ -# Release Notes - +--- +title: "Release Notes" +description: "" +--- ## 0.4.0 · 26.04 (2026-04-28) · [PyPI](https://pypi.org/project/nemo-automodel/0.4.0/) · [GH](https://github.com/NVIDIA-NeMo/Automodel/releases/tag/v0.4.0) · [NGC Docker](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/nemo-automodel/tags?version=26.04.00) ### Highlights @@ -83,7 +85,7 @@ A migration guide for the new CLI, the `recipe` YAML section, the SLURM `sbatch`-script workflow, and the `nemo-automodel[cli]` install profile is in -[Breaking Changes](breaking-changes.md). +[Breaking Changes](/development/breaking-changes). --- @@ -253,4 +255,4 @@ Initial public release of NeMo AutoModel. --- For the list of newly supported models per release, see the -[Model Coverage Release Log](model-coverage/latest-models.md). +[Model Coverage Release Log](/model-coverage/release-log). diff --git a/docs/repository-structure.mdx b/docs/repository-structure.mdx index 72cb311fad..d4679fd299 100644 --- a/docs/repository-structure.mdx +++ b/docs/repository-structure.mdx @@ -1,16 +1,18 @@ -# Repository Structure - +--- +title: "Repository Structure" +description: "" +position: 6 +--- This introductory guide presents the structure of the NeMo AutoModel repository, provides a brief overview of its parts, introduces concepts such as components and recipes, and explains how everything fits together. ## What is NeMo AutoModel? NeMo AutoModel is a PyTorch library for fine-tuning and pretraining large-scale models. In particular, it provides: - **Optimized implementations** for training efficiency, including fused kernels and memory-saving techniques. -- [**Day-0 support**](model-coverage/overview.md) for LLMs and VLMs available on the Hugging Face Hub. +- [**Day-0 support**](/model-coverage/overview) for LLMs and VLMs available on the Hugging Face Hub. - **Seamless integration** with Hugging Face datasets, tokenizers, and related tools. - **Distributed training strategies** using FSDP2 and MegatronFSDP across multi-GPU and multi-node environments. - **End-to-end workflows** with recipes for data preparation, training, and evaluation. - ## Repository Structure The AutoModel source code is available under the [`nemo_automodel`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/nemo_automodel) directory. It is organized into three directories: - [`components/`](https://github.com/NVIDIA-NeMo/Automodel/tree/main/nemo_automodel/components) - Self-contained modules @@ -82,7 +84,7 @@ The recipe/components structure enables you to: - Decouple individual components and replace them with custom implementations when needed. - Avoid rigid, class-based trainer structures by using linear scripts that expose training logic for maximum flexibility and control. - +{/* For an in-depth explanation of the LLM recipe please also see the [LLM recipe deep-dive guide](https://github.com/NVIDIA-NeMo/Automodel/blob/main/docs/llm_recipe_deep_dive). */} #### Configure a Recipe An example YAML configuration is shown below. The complete config is available [here](https://github.com/NVIDIA-NeMo/Automodel/blob/main/examples/llm_finetune/llama3_2/llama3_2_1b_squad.yaml): @@ -111,9 +113,8 @@ single-GPU interactive sessions to batch multi-node runs. It supports interactiv SkyPilot, and NeMo-Run launchers. The CLI lives at the repository root in the `cli/` package, separate from the core `nemo_automodel` library. - ## Next Steps Learn how to train models with NeMo AutoModel on: -- **Your local workstation**: See [`docs/launcher/local-workstation.md`](launcher/local-workstation.md). -- **A cluster**: See [`docs/launcher/slurm.md`](launcher/slurm.md). +- **Your local workstation**: See [`docs/launcher/local-workstation.md`](/job-launchers/local-workstation). +- **A cluster**: See [`docs/launcher/slurm.md`](/job-launchers/slurm-cluster). From 066794fc7126349c28d4b144883dc738e8e0c7bb Mon Sep 17 00:00:00 2001 From: Lawrence Lane Date: Thu, 21 May 2026 17:15:15 -0400 Subject: [PATCH 5/7] docs(fern): refresh README, SKILL.md, AGENTS.md for docs/ + docs/fern/ layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the human- and agent-facing orientation docs so they describe the post-migration layout: docs/ ← nightly MDX (top level) docs/fern/ ← infra (config, theme, components, frozen v0.4) Files touched: * docs/fern/Makefile run-from-here comments * docs/fern/README.md full layout + versioning + CI section refresh * docs/fern/components/Tag.tsx comment path * docs/fern/components/CustomFooter.tsx comment path * AGENTS.md skill-table one-liner * skills/README.md skill-table one-liner * skills/fern-docs/SKILL.md full rewrite: scope rule, add/update/move/remove ops now target docs/.mdx with path: ../../.mdx in nightly.yml; dropped the obsolete latest.yml alias-sync step (latest now mounts v0.4 only); cutting-a-version recipe uses rsync from docs/ into versions/v0.5/pages/. Signed-off-by: Lawrence Lane --- AGENTS.md | 2 +- docs/fern/Makefile | 10 +- docs/fern/README.md | 71 ++++++------ docs/fern/components/CustomFooter.tsx | 2 +- docs/fern/components/Tag.tsx | 2 +- skills/README.md | 2 +- skills/fern-docs/SKILL.md | 148 +++++++++++++------------- 7 files changed, 121 insertions(+), 116 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 210643377e..688dc7272e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -218,7 +218,7 @@ file gives step-by-step instructions an AI agent can follow. | 7 | build-and-dependency | `build-and-dependency` | Container setup, uv package management, environment variables, CLI usage | | 8 | cicd | `cicd` | Commit/PR workflow, CI trigger mechanism, failure investigation | | 9 | testing | `testing` | Unit and functional test layout, tier semantics (L0/L1/L2), adding tests | -| 10 | fern-docs | `fern-docs` | Maintain the Fern docs site under `fern/` — pages, slugs, redirects, version aliases, library reference | +| 10 | fern-docs | `fern-docs` | Maintain the Fern docs site under `docs/` (MDX content) + `docs/fern/` (infra) — pages, slugs, redirects, version aliases, library reference | **Always read the relevant `SKILL.md` before starting any task it covers — skills are mandatory context, not optional background reading.** diff --git a/docs/fern/Makefile b/docs/fern/Makefile index e2dfbb57c3..21a19361d3 100644 --- a/docs/fern/Makefile +++ b/docs/fern/Makefile @@ -1,9 +1,9 @@ # NeMo AutoModel — Fern docs convenience targets. -# Runs from this directory (fern/). Invoke as: +# Runs from this directory (docs/fern/). Invoke as: # -# cd fern && make docs +# cd docs/fern && make docs # # or from anywhere in the repo: -# make -C fern docs +# make -C docs/fern docs # # CI workflows under `.github/workflows/fern-docs-*.yml` are the source of # truth for the published pipeline; these targets just mirror the @@ -24,8 +24,8 @@ help: @echo "NeMo AutoModel — Fern docs Make targets" @echo "========================================" @echo "" - @echo "Run from this directory ('cd fern && make ')" - @echo "or from anywhere in the repo ('make -C fern ')." + @echo "Run from this directory ('cd docs/fern && make ')" + @echo "or from anywhere in the repo ('make -C docs/fern ')." @echo "" @echo " make docs-login FIRST-TIME SETUP — provision Fern account + CLI auth" @echo " make docs Generate library reference and start Fern dev server" diff --git a/docs/fern/README.md b/docs/fern/README.md index 51426de57f..b5c03769ab 100644 --- a/docs/fern/README.md +++ b/docs/fern/README.md @@ -1,8 +1,8 @@ # NeMo AutoModel — Fern Docs -This directory holds the Fern MDX source for the NeMo AutoModel documentation site at **[docs.nvidia.com/nemo/automodel](https://docs.nvidia.com/nemo/automodel)**. +This directory holds the Fern build infrastructure (config, theme, components, frozen version snapshots) for the NeMo AutoModel documentation site at **[docs.nvidia.com/nemo/automodel](https://docs.nvidia.com/nemo/automodel)**. -The legacy Sphinx tree under `../docs/` remains in place for reference until the Fern site is fully validated; new pages and edits should land here. +**The MDX content lives one level up, in `docs/` itself** — every nightly page is a top-level sibling of this `docs/fern/` directory (e.g. `docs/index.mdx`, `docs/guides/llm/finetune.mdx`). Fern reads those files via relative `path: ../../<...>.mdx` entries in `docs/fern/versions/nightly.yml`. ## Quick links @@ -10,8 +10,8 @@ The legacy Sphinx tree under `../docs/` remains in place for reference until the |---|---| | Published site | https://docs.nvidia.com/nemo/automodel | | Fern dashboard | https://dashboard.buildwithfern.com (NVIDIA org) | -| Skill for agents | [`../skills/fern-docs/SKILL.md`](../skills/fern-docs/SKILL.md) | -| CI workflows | [`../.github/workflows/fern-docs-*.yml`](../.github/workflows/) | +| Skill for agents | [`../../skills/fern-docs/SKILL.md`](../../skills/fern-docs/SKILL.md) | +| CI workflows | [`../../.github/workflows/fern-docs-*.yml`](../../.github/workflows/) | | Make targets | [`./Makefile`](./Makefile) | ## Quickstart @@ -19,8 +19,8 @@ The legacy Sphinx tree under `../docs/` remains in place for reference until the First time on this machine: ```bash -# All Make targets live in fern/Makefile — run them from this directory -# (`cd fern && make `) or from anywhere with `make -C fern `. +# All Make targets live in docs/fern/Makefile — run them from this directory +# (`cd docs/fern && make `) or from anywhere with `make -C docs/fern `. # 1. Install the Fern CLI globally (one-time) npm install -g fern-api @@ -28,7 +28,7 @@ npm install -g fern-api # 2. Provision your Fern account + CLI auth (one-time per machine). # Walks you through the dashboard sign-in step before running `fern login`. -cd fern && make docs-login +cd docs/fern && make docs-login # 3. Build the API library reference and start the local dev server make docs # http://localhost:3002 @@ -55,34 +55,37 @@ make docs-check ## Layout ``` -fern/ -├── fern.config.json # Fern CLI pin (4.62.4+) and org slug -├── docs.yml # Site config: instances, versions, redirects, libraries, theme -├── main.css # NVIDIA-green theme overrides -├── assets/ # Logos and shared SVGs -├── components/ # BadgeLinks.tsx, Tag.tsx, CustomFooter.tsx -├── versions/ -│ ├── nightly.yml # Nav for the bleeding-edge tree — paths point at ./nightly/pages/ -│ ├── nightly/pages/ # Bleeding-edge MDX content (edited on every PR) -│ ├── v0.4.yml # Nav for the frozen 0.4.0 GA snapshot — paths point at ./v0.4/pages/ -│ ├── v0.4/pages/ # Frozen 0.4.0 content (back-ports only) -│ └── latest.yml # GA alias — paths point at ./v0.4/pages/; bumps to ./v0.5/pages/ at next GA cut -└── product-docs/ # GENERATED Python API reference (gitignored — `make docs` regenerates) +docs/ ← nightly MDX lives here (sibling of fern/) +├── index.mdx, breaking-changes.mdx, release-notes.mdx, ... +├── about/, guides/, model-coverage/, launcher/, api-reference/ +├── *.png / *.jpg ← page-scoped images +└── fern/ ← THIS DIRECTORY + ├── fern.config.json # Fern CLI pin (4.62.4+) and org slug + ├── docs.yml # Site config: instances, versions, redirects, libraries, theme + ├── main.css # NVIDIA-green theme overrides + ├── assets/ # Logos and shared SVGs + ├── components/ # BadgeLinks.tsx, Tag.tsx, CustomFooter.tsx + ├── versions/ + │ ├── nightly.yml # Nav for nightly — paths point at ../../.mdx (up into docs/) + │ ├── v0.4.yml # Nav for the frozen 0.4.0 GA snapshot — paths at ./v0.4/pages/ + │ ├── v0.4/pages/ # Frozen 0.4.0 content (back-ports only; never edited from nightly) + │ └── latest.yml # GA alias — paths at ./v0.4/pages/ today; repointed at next GA cut + └── product-docs/ # GENERATED Python API reference (gitignored — `make docs` regenerates) ``` ``` File path Published URL ───────────────────────────────────────────────────────── ───────────────────────────────────────────────── -fern/versions/nightly/pages/get-started/installation.mdx docs.nvidia.com/nemo/automodel/nightly/get-started/installation -fern/versions/v0.4/pages/get-started/installation.mdx docs.nvidia.com/nemo/automodel/v0.4/get-started/installation +docs/get-started/installation.mdx docs.nvidia.com/nemo/automodel/nightly/get-started/installation +docs/fern/versions/v0.4/pages/get-started/installation.mdx docs.nvidia.com/nemo/automodel/v0.4/get-started/installation docs.nvidia.com/nemo/automodel/latest/get-started/installation (latest mounts v0.4 content) ``` -`nightly/pages/` and `v0.4/pages/` are **separate, independent content trees**. `nightly/` is the bleeding-edge tree edited on every PR; `v0.4/` is the frozen 0.4.0 release snapshot, only changed via deliberate back-port. `latest.yml` mounts `./v0.4/pages/` so `/latest/...` URLs serve the current GA — at the next GA cut, `latest.yml` repoints at the new train. Today the two trees are byte-for-byte identical (we just shipped 0.4.0); they'll diverge as nightly accumulates post-release edits. +The **`docs/` top-level tree IS the nightly tree** — every PR lands there. The **`docs/fern/versions/v0.4/pages/` tree is a frozen 0.4.0 release snapshot**, only changed via deliberate back-port. `latest.yml` mounts `./v0.4/pages/` so `/latest/...` URLs serve the current GA — at the next GA cut, `latest.yml` repoints at the new train. Today the two trees are byte-for-byte identical (we just shipped 0.4.0); they'll diverge as nightly accumulates post-release edits. ## Local development -From this directory (`cd fern` first, or use `make -C fern ` from anywhere): +From this directory (`cd docs/fern` first, or use `make -C docs/fern ` from anywhere): ```bash make docs # `fern docs md generate` + `fern docs dev` → http://localhost:3002 @@ -93,7 +96,7 @@ make docs-publish # trigger the `Publish Fern Docs` workflow on origin/main For first-time-on-this-machine setup, see the [Quickstart](#quickstart) above — `make docs-login` walks through dashboard provisioning + `fern login` together. -`fern docs md generate` (run by `make docs`) populates `fern/product-docs/` from the `nemo_automodel` package source declared in the `libraries:` block of `docs.yml`. Without it, a cold `fern docs dev` will fail with `Folder not found: ./product-docs/...`. Re-run only when the upstream Python source changes — for prose-only iteration, `cd fern && fern docs dev` alone is enough. +`fern docs md generate` (run by `make docs`) populates `docs/fern/product-docs/` from the `nemo_automodel` package source declared in the `libraries:` block of `docs.yml`. Without it, a cold `fern docs dev` will fail with `Folder not found: ./product-docs/...`. Re-run only when the upstream Python source changes — for prose-only iteration, `cd docs/fern && fern docs dev` alone is enough. ## Sidebar fidelity rule @@ -156,28 +159,28 @@ Repository source paths like `examples/llm_finetune/foo.yaml` or `nemo_automodel | `Latest` | `latest` | `stable` | `./versions/latest.yml` | | `0.4.0 · 26.04` | `v0.4` | `stable` | `./versions/v0.4.yml` | -**`nightly` is the bleeding-edge tree** — every PR lands here, and (once wired up) the daily build publishes from here. **`v0.4` is the frozen 0.4.0 GA snapshot** with its own copy of every page; it only changes via deliberate back-ports from nightly. `latest.yml` mounts the current GA's content (today: `./v0.4/pages/...`). +**`nightly` reads the MDX directly from `docs/`** (via `path: ../../<...>.mdx` in `nightly.yml`) — every PR lands there, and (once wired up) the daily build publishes from that tree. **`v0.4` is the frozen 0.4.0 GA snapshot** with its own copy of every page under `docs/fern/versions/v0.4/pages/`; it only changes via deliberate back-ports from nightly. `latest.yml` mounts the current GA's content (today: `./v0.4/pages/...`). When the next GA cuts (e.g. `v0.5`): -1. `cp -r versions/nightly versions/v0.5` — fresh frozen snapshot of nightly at release time -2. `cp versions/nightly.yml versions/v0.5.yml`, then sed `./nightly/` → `./v0.5/` in the new file +1. `cp -r ../* versions/v0.5/pages/` (excluding `docs/fern/`) — fresh frozen snapshot of nightly at release time +2. `cp versions/nightly.yml versions/v0.5.yml`, then sed `../../` → `./v0.5/pages/` in the new file 3. Repoint `versions/latest.yml` at the new GA: `cp versions/v0.5.yml versions/latest.yml` 4. Add the new frozen-pin entry to `docs.yml` `versions:` (`display-name: "0.5.0"`, `slug: v0.5`, `availability: stable`); keep `v0.4` per support policy -5. `versions/nightly/pages/` keeps moving forward as the bleeding-edge tree; `versions/v0.4/pages/` and `versions/v0.5/pages/` are now both frozen +5. `docs/` keeps moving forward as the nightly tree; `versions/v0.4/pages/` and `versions/v0.5/pages/` are both frozen ## CI and publishing | Workflow | Trigger | Purpose | |---|---|---| | `fern-docs-ci.yml` | `push: pull-request/[0-9]+` (FW-CI mirror) | `fern check` on PRs | -| `fern-docs-preview-build.yml` | `pull_request` | Untrusted half: collect `fern/` artifact (no secrets) | +| `fern-docs-preview-build.yml` | `pull_request` | Untrusted half: collect `docs/fern/` artifact (no secrets) | | `fern-docs-preview-comment.yml` | `workflow_run` after build | Trusted half: build preview with `DOCS_FERN_TOKEN`, post 🌿 comment | -| `publish-fern-docs.yml` | push to `main` (`fern/**`), `docs/v*` tag, or manual | Publish to docs.nvidia.com/nemo/automodel | +| `publish-fern-docs.yml` | push to `main` (`docs/**`), `docs/v*` tag, or manual | Publish to docs.nvidia.com/nemo/automodel | Required org secret: **`DOCS_FERN_TOKEN`** (already wired for the existing `build-docs.yml`). -PRs that touch `fern/**` get an automatic preview URL posted as a 🌿 comment. +PRs that touch `docs/**` get an automatic preview URL posted as a 🌿 comment. ## Commits @@ -187,13 +190,13 @@ DCO sign-off is required: git commit -s -m "docs: " ``` -PR titles follow Conventional Commits (e.g. `docs(fern): add gemma4 fine-tuning guide`) — see [`AGENTS.md`](../AGENTS.md) for the full convention. +PR titles follow Conventional Commits (e.g. `docs(fern): add gemma4 fine-tuning guide`) — see [`AGENTS.md`](../../AGENTS.md) for the full convention. ## Troubleshooting | Symptom | Fix | |---|---| -| `fern check` YAML error | 2-space indent; `- page:` inside `contents:`; `path:` is relative to the version YAML | +| `fern check` YAML error | 2-space indent; `- page:` inside `contents:`; `path:` is relative to the version YAML (so nightly paths reach back up via `../../`) | | Page 404 in preview | `slug:` collision in the same section, or missing `slug:` override (default slugifies the long display title) | | `Folder not found: ./product-docs/...` in `fern docs dev` | Run `make docs` once; library generation populates `product-docs/` | | `[ERR_PNPM_IGNORED_BUILDS]` on first `fern docs dev` | pnpm 10+ blocks esbuild's postinstall — `pnpm config set onlyBuiltDependencies '["esbuild"]' --location global`, then `rm -rf ~/.fern/app-preview` and retry | diff --git a/docs/fern/components/CustomFooter.tsx b/docs/fern/components/CustomFooter.tsx index db2d9da6b0..91111549e5 100644 --- a/docs/fern/components/CustomFooter.tsx +++ b/docs/fern/components/CustomFooter.tsx @@ -6,7 +6,7 @@ /** * Custom footer for NVIDIA docs (Fern native header/footer). * Markup and class names match the original custom-app footer 1:1 so that - * fern/main.css (footer + Built with Fern styles) applies correctly: + * docs/fern/main.css (footer + Built with Fern styles) applies correctly: * dark mode logo, responsive layout, and Built with Fern tooltip. */ export default function CustomFooter() { diff --git a/docs/fern/components/Tag.tsx b/docs/fern/components/Tag.tsx index d7c7b5d78e..1bface0b58 100644 --- a/docs/fern/components/Tag.tsx +++ b/docs/fern/components/Tag.tsx @@ -10,7 +10,7 @@ * their visual cues after migration. Used by `convert_myst_to_fern.py` when * converting `{bdg-primary}\`text\`` to `text`. * - * Copy to your repo's `fern/components/` together with `BadgeLinks.tsx`. + * Copy to your repo's `docs/fern/components/` together with `BadgeLinks.tsx`. */ export type TagVariant = | "primary" diff --git a/skills/README.md b/skills/README.md index eebb5f1a4e..76b7aeea17 100644 --- a/skills/README.md +++ b/skills/README.md @@ -26,4 +26,4 @@ To invoke a skill manually, use `/` in your Claude Code session. | `cicd` | Commit/PR workflow, CI trigger mechanism, failure investigation | | `build-and-dependency` | Container setup, uv package management, environment variables, CLI usage | | `testing` | Unit and functional test layout, tier semantics (L0/L1/L2), adding tests | -| `fern-docs` | Maintain the Fern docs site under `fern/` — pages, slugs, redirects, version aliases, library reference | \ No newline at end of file +| `fern-docs` | Maintain the Fern docs site under `docs/` (MDX content) + `docs/fern/` (infra) — pages, slugs, redirects, version aliases, library reference | \ No newline at end of file diff --git a/skills/fern-docs/SKILL.md b/skills/fern-docs/SKILL.md index 21ecb731bd..839cfd315c 100644 --- a/skills/fern-docs/SKILL.md +++ b/skills/fern-docs/SKILL.md @@ -1,6 +1,6 @@ --- name: fern-docs -description: Maintain the NeMo AutoModel Fern docs site under fern/ — add, update, move, or remove pages; manage redirects, slugs, navigation, and version aliases; run validation and previews. +description: Maintain the NeMo AutoModel Fern docs site under docs/ (MDX content) + docs/fern/ (infra) — add, update, move, or remove pages; manage redirects, slugs, navigation, and version aliases; run validation and previews. when_to_use: Editing or adding documentation pages, fixing broken links, renaming a slug, updating the sidebar, adding a redirect, regenerating the API library reference, debugging fern check / broken-link errors, cutting a new version train, 'edit docs', 'add doc page', 'fern check failing', 'preview fails locally'. --- @@ -10,50 +10,53 @@ Unified skill for adding, updating, moving, and removing pages on the NeMo AutoM ## Scope rule -**ALL docs edits happen under `fern/`.** The legacy Sphinx tree at `docs/` is read-only reference; do not add new pages there. New pages, release notes, migration guides — everything belongs under `fern/versions/nightly/pages/`. +**Nightly MDX content lives at the top level of `docs/`** (e.g. `docs/index.mdx`, `docs/guides/llm/finetune.mdx`). **`docs/fern/` holds only Fern build infrastructure** — config, theme, components, and the frozen v0.4 snapshot. New pages, release notes, migration guides → add as a top-level `.mdx` under `docs/`. **Two real content trees, plus a GA alias YAML.** -- `fern/versions/nightly/pages/` — bleeding-edge tree. Every PR lands here. Mounted at the `nightly` URL slug via `nightly.yml`. -- `fern/versions/v0.4/pages/` — frozen 0.4.0 GA snapshot. Independent copy of every page. Only changes via deliberate back-port. Mounted at the `v0.4` URL slug via `v0.4.yml`. -- `fern/versions/latest.yml` — GA alias. Its `path:` lines mount the current GA's content (today: `./v0.4/pages/...`). Repointed at the next GA's tree when one is cut. +- `docs/` — bleeding-edge (nightly) tree. Every PR lands here. Mounted at the `nightly` URL slug via `docs/fern/versions/nightly.yml` (paths reach back up via `../../.mdx`). +- `docs/fern/versions/v0.4/pages/` — frozen 0.4.0 GA snapshot. Independent copy of every page. Only changes via deliberate back-port. Mounted at the `v0.4` URL slug via `v0.4.yml`. +- `docs/fern/versions/latest.yml` — GA alias. Its `path:` lines mount the current GA's content (today: `./v0.4/pages/...`). Repointed at the next GA's tree when one is cut. -The two trees were byte-for-byte identical at the moment 0.4.0 shipped (today, just after the migration), but they will diverge as nightly accumulates post-release edits and v0.4 stays frozen. **Default editing target is `nightly/`.** Only touch `v0.4/` for explicit back-ports — call out the divergence in the PR description. +The two trees were byte-for-byte identical at the moment 0.4.0 shipped, but they will diverge as nightly accumulates post-release edits and v0.4 stays frozen. **Default editing target is `docs/` top-level.** Only touch `docs/fern/versions/v0.4/pages/` for explicit back-ports — call out the divergence in the PR description. **Sidebar fidelity rule.** Section captions, page titles, and Model Coverage child ordering must match the **published v0.4.0 sidebar at docs.nvidia.com/nemo/automodel/latest** verbatim. Don't silently shorten a title or reorder siblings — the docs PM and content engineers diff against the published site and any drift is treated as a regression. If you want a shorter sidebar label, change the toctree-derived display name in the source — never just retitle in the MDX. ## Layout at a glance ``` -fern/ -├── fern.config.json # Org slug + Fern CLI pin (4.62.4+) -├── docs.yml # Site config: instances, versions, redirects, libraries, theme -├── main.css # NVIDIA-green theme overrides -├── assets/ # Logos and shared SVGs (NVIDIA_dark/light/symbol) -├── components/ # BadgeLinks.tsx, Tag.tsx, CustomFooter.tsx -├── versions/ -│ ├── nightly.yml # Nav for bleeding-edge — paths → ./nightly/pages/ -│ ├── nightly/pages/ # Bleeding-edge MDX (edited every PR) -│ ├── v0.4.yml # Nav for frozen 0.4.0 — paths → ./v0.4/pages/ -│ ├── v0.4/pages/ # Frozen 0.4.0 MDX (back-ports only) -│ └── latest.yml # GA alias — paths → ./v0.4/pages/ today; repointed at next GA cut -└── product-docs/ # GENERATED Python API reference (gitignored) +docs/ ← nightly MDX (top level) +├── index.mdx, breaking-changes.mdx, release-notes.mdx, ... +├── about/, guides/, model-coverage/, launcher/, api-reference/ +├── *.png / *.jpg ← page-scoped images +└── fern/ ← infra only + ├── fern.config.json # Org slug + Fern CLI pin (4.62.4+) + ├── docs.yml # Site config: instances, versions, redirects, libraries, theme + ├── main.css # NVIDIA-green theme overrides + ├── assets/ # Logos and shared SVGs (NVIDIA_dark/light/symbol) + ├── components/ # BadgeLinks.tsx, Tag.tsx, CustomFooter.tsx + ├── versions/ + │ ├── nightly.yml # Nav for nightly — paths → ../../.mdx (up into docs/) + │ ├── v0.4.yml # Nav for frozen 0.4.0 — paths → ./v0.4/pages/ + │ ├── v0.4/pages/ # Frozen 0.4.0 MDX (back-ports only) + │ └── latest.yml # GA alias — paths → ./v0.4/pages/ today; repointed at next GA cut + └── product-docs/ # GENERATED Python API reference (gitignored) ``` ``` -File URL -───────────────────────────────────────────────────────── ──────────────────────────────────────────── -fern/versions/nightly/pages/get-started/installation.mdx /latest/get-started/installation - /v0.4/get-started/installation - /nightly/get-started/installation +File URL +───────────────────────────────────────────────────────────── ──────────────────────────────────────────── +docs/get-started/installation.mdx /nightly/get-started/installation +docs/fern/versions/v0.4/pages/get-started/installation.mdx /latest/get-started/installation + /v0.4/get-started/installation ``` ## Operations ### Add a page -1. Gather: title, target section, filename (kebab-case `.mdx`), subdirectory under `fern/versions/nightly/pages/`. -2. Create the MDX with frontmatter: +1. Gather: title, target section, filename (kebab-case `.mdx`), subdirectory under `docs/`. +2. Create the MDX at `docs//.mdx` with frontmatter: ```mdx --- @@ -65,28 +68,27 @@ fern/versions/nightly/pages/get-started/installation.mdx /latest/get-started ``` -3. Add a `- page:` entry to `fern/versions/nightly.yml` under the right `section:`, with an explicit `slug:` if the desired URL differs from the slugified title: +3. Add a `- page:` entry to `docs/fern/versions/nightly.yml` under the right `section:`, with `path:` reaching up into `docs/` via `../../`: ```yaml - page: "" - path: ./nightly/pages//.mdx + path: ../..//.mdx slug: ``` -4. **Sync the aliases:** `cp fern/versions/nightly.yml fern/versions/latest.yml && sed -i '' 's|./nightly/pages/|./v0.4/pages/|g' fern/versions/latest.yml`. -5. `make docs-check` (runs `fern check`) and verify URL resolves on `make docs` preview. +4. `make docs-check` (runs `fern check`) and verify URL resolves on `make docs` preview. There is no `nightly.yml` ↔ `latest.yml` alias-sync step under this layout — `latest.yml` mounts the frozen v0.4 tree, not nightly, so it's intentionally out of sync. ### Update a page -1. Locate by path, title, or keyword: `grep -rn "" fern/versions/nightly/pages/ --include="*.mdx"`. -2. **Content only** — edit the single MDX file. There is no mirror to maintain (latest/nightly serve the same content). -3. **Title change** — update the frontmatter `title:` and (if the page is in `versions/nightly.yml`) update the `- page:` entry's display label. Re-sync `latest.yml` and `v0.4.yml`. -4. **Section move** — `git mv` the file, update `path:` in `versions/nightly.yml`, fix incoming links, re-sync aliases. -5. **Slug change** — change `slug:` in the YAML (or rename the file and let the default slug update). Add a `redirects:` entry in `docs.yml` so the old URL keeps working. +1. Locate by path, title, or keyword: `grep -rn "" docs/ --include="*.mdx" --exclude-dir=fern`. +2. **Content only** — edit the single MDX file at `docs/<...>.mdx`. +3. **Title change** — update the frontmatter `title:` and update the `- page:` entry's display label in `docs/fern/versions/nightly.yml`. +4. **Section move** — `git mv` the file within `docs/`, update `path:` in `nightly.yml`, fix incoming links. +5. **Slug change** — change `slug:` in the YAML (or rename the file and let the default slug update). Add a `redirects:` entry in `docs/fern/docs.yml` so the old URL keeps working. ### Redirect quirks -Four things to watch when editing `redirects:` in `fern/docs.yml`: +Four things to watch when editing `redirects:` in `docs/fern/docs.yml`: 1. **`:path*` does NOT match the empty-path case.** `//v0.4/:path*/index.html` will *not* match `//v0.4/index.html` (where `:path*` would have to be empty). Each version-root `index.html` needs its own explicit rule. NeMo Curator (NVIDIA-NeMo/Curator#1938) discovered this when their version-root URLs 404'd. AutoModel ships explicit rules for `latest`, `v0.4`, `nightly`, and the legacy `0.4` form — when you add a new version slug, add four new explicit rules: `/index.html`, `/index`, plus the same two for any legacy form (e.g. `0.5` → `v0.5`). 2. **Older un-migrated versions need a fallback.** Whatever versions the published Sphinx site exposed (check the version-switcher dropdown on `docs.nvidia.com/nemo//latest/`) but you didn't migrate into Fern still need to resolve. The pattern: redirect each old slug's URLs to the equivalent path under `/latest/` so external bookmarks and search results land on the closest current page instead of 404ing. Five rules per old version: `/index.html`, `/index`, `/:path*/index.html`, `/:path*`, `/:path*.html` — all destinations `/latest/...`. AutoModel ships these for `0.3.0`, `0.2.0`, `0.1.0`. @@ -95,17 +97,17 @@ Four things to watch when editing `redirects:` in `fern/docs.yml`: ### Remove a page -1. Find incoming links: `grep -rn "" fern/versions/nightly/pages/ --include="*.mdx"`. -2. `git rm fern/versions/nightly/pages/.mdx`. -3. Remove the `- page:` block from `versions/nightly.yml` (and re-sync `latest.yml` / `nightly.yml`). +1. Find incoming links: `grep -rn "" docs/ --include="*.mdx" --exclude-dir=fern`. +2. `git rm docs/<...>.mdx`. +3. Remove the `- page:` block from `docs/fern/versions/nightly.yml`. 4. Fix or delete incoming links. -5. Add a redirect in `docs.yml` if the URL was public. +5. Add a redirect in `docs/fern/docs.yml` if the URL was public. ### Worked example: add a guide Request: *"Add a fine-tuning guide for Qwen3.6 under Recipes & E2E Examples."* -1. Create `fern/versions/nightly/pages/guides/llm/qwen3-6-finetune.mdx`: +1. Create `docs/guides/llm/qwen3-6-finetune.mdx`: ```mdx --- @@ -116,23 +118,22 @@ Request: *"Add a fine-tuning guide for Qwen3.6 under Recipes & E2E Examples."* This guide walks through fine-tuning Qwen3.6 with NeMo AutoModel... ``` -2. Add to `fern/versions/nightly.yml` under the `Recipes & E2E Examples` section, slotted in publication-order with the other fine-tune entries: +2. Add to `docs/fern/versions/nightly.yml` under the `Recipes & E2E Examples` section, slotted in publication-order with the other fine-tune entries: ```yaml - page: "Fine-Tune Qwen3.6" - path: ./nightly/pages/guides/llm/qwen3-6-finetune.mdx + path: ../../guides/llm/qwen3-6-finetune.mdx slug: qwen3-6-finetune ``` -3. `cp fern/versions/nightly.yml fern/versions/latest.yml && sed -i '' 's|./nightly/pages/|./v0.4/pages/|g' fern/versions/latest.yml`. -4. `make docs-check` then `make docs` to preview at `http://localhost:3002/latest/recipes-e2e-examples/qwen3-6-finetune`. +3. `make docs-check` then `make docs` to preview at `http://localhost:3002/nightly/recipes-e2e-examples/qwen3-6-finetune`. ### Worked example: rename a slug with a redirect Request: *"Rename `/recipes-e2e-examples/sft-peft` to `/recipes-e2e-examples/fine-tuning`."* -1. Edit `versions/nightly.yml`, change the `slug:` on the SFT & PEFT entry from `sft-peft` to `fine-tuning`. -2. Add a redirect to `fern/docs.yml`: +1. Edit `docs/fern/versions/nightly.yml`, change the `slug:` on the SFT & PEFT entry from `sft-peft` to `fine-tuning`. +2. Add a redirect to `docs/fern/docs.yml`: ```yaml redirects: @@ -140,8 +141,7 @@ Request: *"Rename `/recipes-e2e-examples/sft-peft` to `/recipes-e2e-examples/fin destination: "/:version/recipes-e2e-examples/fine-tuning" ``` -3. `grep -rn "/recipes-e2e-examples/sft-peft" fern/versions/nightly/pages/` and update incoming body links. -4. Re-sync `latest.yml` and `v0.4.yml`. +3. `grep -rn "/recipes-e2e-examples/sft-peft" docs/ --include="*.mdx" --exclude-dir=fern` and update incoming body links. ## Content guidelines @@ -167,7 +167,7 @@ import { BadgeLinks } from "@/components/BadgeLinks"; `` accepts: `primary`, `secondary`, `success`, `warning`, `danger`, `info`, `light`, `dark` (1:1 with sphinx-design `{bdg-*}` variants). -Images live in `fern/assets/` (shared across all pages) or alongside the MDX file (page-scoped). Reference page-scoped images with relative paths (`./image.png`), not absolute (`/image.png`) — Fern's path resolver doesn't normalize root-relative image paths the same way as link targets. +Images live in `docs/fern/assets/` (shared across all pages) or alongside the MDX file (page-scoped). Reference page-scoped images with relative paths (`./image.png`), not absolute (`/image.png`) — Fern's path resolver doesn't normalize root-relative image paths the same way as link targets. ## Frontmatter @@ -204,15 +204,17 @@ For cross-repo references (yaml configs, Python source), use absolute GitHub URL make docs-check # `fern check` — config + MDX validation ``` +Run from `docs/fern/` (`cd docs/fern && make docs-check`) or anywhere with `make -C docs/fern docs-check`. + `fern check` must pass before commit. The dev server's broken-link warnings for version-prefixed routes (e.g. `/latest/get-started/installation` from MDX that uses `/get-started/installation`) are **false positives** — Fern's strict validator doesn't resolve version-agnostic links. The published site renders them correctly. The URLMap-based `validate_fern_internal_links.py` (under the convert-to-fern toolkit) is authoritative. -To regenerate the autodoc library reference (gitignored under `product-docs/`): +To regenerate the autodoc library reference (gitignored under `docs/fern/product-docs/`): ```bash make docs # runs `fern docs md generate` then `fern docs dev` ``` -`fern docs md generate` populates `product-docs/` from the `nemo_automodel` package source declared in `docs.yml` `libraries:` block. Without this step, a cold `fern docs dev` fails with `Folder not found: ./product-docs/...`. +`fern docs md generate` populates `docs/fern/product-docs/` from the `nemo_automodel` package source declared in `docs.yml` `libraries:` block. Without this step, a cold `fern docs dev` fails with `Folder not found: ./product-docs/...`. ## Preview and publish @@ -223,14 +225,14 @@ make docs # runs `fern docs md generate` then `fern docs dev` | Shared preview URL on `*.docs.buildwithfern.com` (needs `DOCS_FERN_TOKEN`) | `make docs-preview` | | Trigger production publish workflow on `origin/main` | `make docs-publish` | -PRs that touch `fern/**` get an automatic Fern preview URL posted as a 🌿 comment by `fern-docs-preview-comment.yml`. No manual step. +PRs that touch `docs/**` get an automatic Fern preview URL posted as a 🌿 comment by `fern-docs-preview-comment.yml`. No manual step. ``` ┌─ fern-docs-ci.yml → fern check (push to pull-request/) -PR (touches fern/) ─┼─ fern-docs-preview-build.yml → upload fern/ artifact (no secrets) +PR (touches docs/) ─┼─ fern-docs-preview-build.yml → upload docs/fern/ artifact (no secrets) └─ fern-docs-preview-comment.yml → 🌿 preview URL comment -Push to main (touches fern/) → publish-fern-docs.yml → docs.nvidia.com/nemo/automodel +Push to main (touches docs/) → publish-fern-docs.yml → docs.nvidia.com/nemo/automodel Tag push (docs/v*) → publish-fern-docs.yml → docs.nvidia.com/nemo/automodel Manual dispatch → publish-fern-docs.yml → docs.nvidia.com/nemo/automodel ``` @@ -241,11 +243,11 @@ The preview-comment + publish jobs require the `DOCS_FERN_TOKEN` org secret (alr When NeMo AutoModel ships a new GA (e.g. `v0.5`): -1. `cp -r fern/versions/nightly fern/versions/v0.5` — frozen snapshot of the bleeding-edge tree at release. -2. `cp fern/versions/nightly.yml fern/versions/v0.5.yml` and rewrite `./nightly/` path prefixes to `./v0.5/`. -3. Update `fern/versions/latest.yml` to point at the new train: `cp fern/versions/v0.5.yml fern/versions/latest.yml`. (`latest` is the auto-bumping GA alias.) -4. In `fern/docs.yml` `versions:`, add a new frozen-pin entry (`display-name: "0.5.0 · 26.07"`, `slug: v0.5`, `availability: stable`) and keep the previous pin (`v0.4`) for permalink stability. -5. `fern/versions/nightly/pages/` keeps moving forward as the bleeding-edge tree; the new `fern/versions/v0.5/pages/` is the frozen GA snapshot and only changes via deliberate back-port. +1. `mkdir -p docs/fern/versions/v0.5/pages && rsync -a --exclude='fern' docs/ docs/fern/versions/v0.5/pages/` — fresh frozen snapshot of nightly at release time. +2. `cp docs/fern/versions/nightly.yml docs/fern/versions/v0.5.yml` and rewrite `../../` path prefixes to `./v0.5/pages/`. +3. Update `docs/fern/versions/latest.yml` to point at the new train: `cp docs/fern/versions/v0.5.yml docs/fern/versions/latest.yml`. (`latest` is the auto-bumping GA alias.) +4. In `docs/fern/docs.yml` `versions:`, add a new frozen-pin entry (`display-name: "0.5.0 · 26.07"`, `slug: v0.5`, `availability: stable`) and keep the previous pin (`v0.4`) for permalink stability. +5. `docs/` keeps moving forward as the bleeding-edge tree; the new `docs/fern/versions/v0.5/pages/` is the frozen GA snapshot and only changes via deliberate back-port. 6. Promote `nightly` to `availability: stable` if and when its content tree gets cut over. 7. Tag `docs/v0.5.0` and push to publish. @@ -263,29 +265,29 @@ If sign-off is missing on a recent commit, amend with `git commit --amend -s`. P | Symptom | Fix | |---|---| -| `fern check` YAML error | 2-space indent; `- page:` inside `contents:`; `path:` is relative to the version YAML; `slug:` must not collide with siblings | +| `fern check` YAML error | 2-space indent; `- page:` inside `contents:`; `path:` is relative to `nightly.yml`'s location (so nightly entries reach back up via `../../`); `slug:` must not collide with siblings | | Page 404 in preview | Missing `slug:` override (default slugifies the long display title) or `position:` collision in an auto-discovered folder | | `Folder not found: ./product-docs/...` on `fern docs dev` | Run `make docs` once to populate the library reference | | `[ERR_PNPM_IGNORED_BUILDS]` on first `fern docs dev` | pnpm 10+ blocks esbuild's postinstall — `pnpm config set onlyBuiltDependencies '["esbuild"]' --location global`, then `rm -rf ~/.fern/app-preview` and retry | | Broken-link warning on version-agnostic path | `fern docs broken-links` false-positives; URLMap-based validator is authoritative | | `JSX expressions must have one parent element` | Wrap multi-element JSX in `<>...` or a `
` | -| Old Sphinx URL breaks | Add a `redirects:` entry in `fern/docs.yml`; the redirect generator already handles `/index.html` and `.html` legacy forms | +| Old Sphinx URL breaks | Add a `redirects:` entry in `docs/fern/docs.yml`; the redirect generator already handles `/index.html` and `.html` legacy forms | | Image not rendering | Use relative path (`./image.png`) for page-scoped images, not root-relative (`/image.png`) | -| Sidebar caption looks shortened vs published site | Compare against `docs.nvidia.com/nemo/automodel/latest` and restore the verbatim title in `versions/nightly.yml` | -| `latest.yml` or `v0.4.yml` drift from `nightly.yml` | Re-sync: `cp fern/versions/nightly.yml fern/versions/latest.yml && sed -i '' 's|./nightly/pages/|./v0.4/pages/|g' fern/versions/latest.yml` | +| Sidebar caption looks shortened vs published site | Compare against `docs.nvidia.com/nemo/automodel/latest` and restore the verbatim title in `docs/fern/versions/nightly.yml` | +| `path: ../../foo.mdx` doesn't resolve | Confirm the MDX file is at `docs/foo.mdx` (top level), not still under `docs/fern/versions/nightly/pages/` — that legacy tree no longer exists | ## Key references | File | Purpose | |---|---| -| `fern/docs.yml` | Site config — `instances`, `versions`, `redirects`, `libraries`, theme | -| `fern/versions/nightly.yml` | Canonical nav tree | -| `fern/versions/{latest,v0.4}.yml` | Aliases — content copies of `nightly.yml` | -| `fern/versions/nightly/pages/` | MDX content (130+ pages) | -| `fern/components/` | `BadgeLinks.tsx`, `Tag.tsx`, `CustomFooter.tsx` | -| `fern/main.css` | Theme overrides — NVIDIA green, badge spacing | -| `fern/README.md` | Human-facing orientation | -| `fern/Makefile` | `make docs / docs-check / docs-preview / docs-publish` (run from `fern/` or via `make -C fern`) | +| `docs/fern/docs.yml` | Site config — `instances`, `versions`, `redirects`, `libraries`, theme | +| `docs/fern/versions/nightly.yml` | Canonical nav tree — paths reach up into `docs/` via `../../` | +| `docs/fern/versions/{latest,v0.4}.yml` | Frozen GA nav (mount `./v0.4/pages/...`) | +| `docs/` (top-level *.mdx) | Nightly MDX content (~140 pages + page-scoped images) | +| `docs/fern/versions/v0.4/pages/` | Frozen 0.4.0 snapshot (back-ports only) | +| `docs/fern/components/` | `BadgeLinks.tsx`, `Tag.tsx`, `CustomFooter.tsx` | +| `docs/fern/main.css` | Theme overrides — NVIDIA green, badge spacing | +| `docs/fern/README.md` | Human-facing orientation | +| `docs/fern/Makefile` | `make docs / docs-check / docs-preview / docs-publish` (run from `docs/fern/` or via `make -C docs/fern`) | | `.github/workflows/fern-docs-*.yml` | CI: check, preview build, preview comment | | `.github/workflows/publish-fern-docs.yml` | CI: publish to docs.nvidia.com/nemo/automodel | -| `docs/` | **Legacy** Sphinx source — read-only reference for fidelity checks | From 6fff668dddb0994461494bd81eb37a1426a4fe08 Mon Sep 17 00:00:00 2001 From: Lawrence Lane Date: Thu, 21 May 2026 17:29:17 -0400 Subject: [PATCH 6/7] docs(fern): remove Sphinx-era holdovers from docs/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops four files that only existed for the old Sphinx build and have no Fern equivalent: D docs/conf.py (Sphinx config — Fern uses docs.yml) D docs/autodoc2_docstrings_parser.py (sphinx-autodoc2 plugin — Fern's `libraries:` block handles autodoc) D docs/project.json (Sphinx project metadata) D docs/versions1.json (Sphinx version-switcher dropdown — Fern reads versions from docs.yml) `.github/workflows/release-freeze.yml`: the `bump-docs-versions` job existed solely to bump these three Sphinx files (versions1.json, project.json, conf.py) on code freeze. With the files gone, the job has no work to do, so it's removed and replaced with a short comment pointing at the Fern equivalent (add a new version pin in docs/fern/docs.yml + docs/fern/versions/*.yml and tag docs/v..0). fern check still passes. Signed-off-by: Lawrence Lane --- .github/workflows/release-freeze.yml | 77 ++-------------- docs/autodoc2_docstrings_parser.py | 32 ------- docs/conf.py | 133 --------------------------- docs/project.json | 1 - docs/versions1.json | 26 ------ 5 files changed, 6 insertions(+), 263 deletions(-) delete mode 100644 docs/autodoc2_docstrings_parser.py delete mode 100644 docs/conf.py delete mode 100644 docs/project.json delete mode 100644 docs/versions1.json diff --git a/.github/workflows/release-freeze.yml b/.github/workflows/release-freeze.yml index c4c70a872e..3fc0287468 100644 --- a/.github/workflows/release-freeze.yml +++ b/.github/workflows/release-freeze.yml @@ -49,74 +49,9 @@ jobs: SLACK_WEBHOOK_ADMIN: ${{ secrets.SLACK_WEBHOOK_ADMIN }} PAT: ${{ secrets.PAT }} - bump-docs-versions: - needs: [code-freeze] - runs-on: ubuntu-latest - env: - VERSION: ${{ needs.code-freeze.outputs.release-branch }} - DRY_RUN: ${{ inputs.dry-run }} - steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - ref: main - token: ${{ secrets.PAT }} - - - name: Configure git - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - - name: Update versions1.json - run: | - version_number=$(echo ${VERSION} | sed 's/^r//') - - # Remove (latest) tag from previous latest entry, insert new version after nightly - jq --arg ver "$version_number" ' - map(if .name then del(.name) else . end) - | [.[0]] + [{"name": ($ver + " (latest)"), "version": $ver, "url": "https://docs.nvidia.com/nemo/automodel/latest/"}] + .[1:] - ' docs/versions1.json > tmp.json && mv tmp.json docs/versions1.json - - - name: Commit changes - id: commit-versions1 - run: | - git add docs/versions1.json - git commit -m "[bot]: Update docs-versions after code-freeze for ${VERSION}" - commit_hash=$(git rev-parse HEAD) - echo "commit_hash=${commit_hash}" | tee -a $GITHUB_OUTPUT - - if [[ "$DRY_RUN" != "true" ]]; then - git push - fi - - - name: Switch to release branch - run: | - git fetch origin ${{ needs.code-freeze.outputs.release-branch }} - git checkout ${{ needs.code-freeze.outputs.release-branch }} - - - name: Cherry-pick docs-versions commit - run: | - git cherry-pick ${{ steps.commit-versions1.outputs.commit_hash }} - - - name: Update project.json - run: | - version_number=$(echo ${VERSION} | sed 's/^r//') - - jq --arg ver "$version_number" \ - '. = {"version": $ver, "name": "nemo-automodel"}' \ - docs/project.json > tmp.json && mv tmp.json docs/project.json - - - name: Update conf.py - run: | - version_number=$(echo ${VERSION} | sed 's/^r//') - sed -i "s/release = .*/release = \"${version_number}\"/" docs/conf.py - - - name: Commit changes - run: | - git add docs/project.json - git add docs/conf.py - git commit -m "Bump docs version to ${VERSION}" - - if [[ "$DRY_RUN" != "true" ]]; then - git push - fi + # bump-docs-versions: the Sphinx-era docs/versions1.json, docs/project.json, + # and docs/conf.py no longer exist; Fern manages version metadata via + # docs/fern/docs.yml `versions:` and docs/fern/versions/*.yml. The + # equivalent step under Fern is to add a new version pin in those files + # and tag docs/v..0 to trigger publish-fern-docs.yml — done by hand + # at release cut time, not on every code freeze. diff --git a/docs/autodoc2_docstrings_parser.py b/docs/autodoc2_docstrings_parser.py deleted file mode 100644 index 1f8e1bdbfd..0000000000 --- a/docs/autodoc2_docstrings_parser.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# flake8: noqa -# pylint: skip-file -from docutils import nodes -from myst_parser.parsers.sphinx_ import MystParser -from sphinx.ext.napoleon.docstring import GoogleDocstring - - -class NapoleonParser(MystParser): - def parse(self, input_string: str, document: nodes.document) -> None: - # Get the Sphinx configuration - config = document.settings.env.config - - # Process with Google style - google_parsed = str(GoogleDocstring(input_string, config)) - - return super().parse(google_parsed, document) - - -Parser = NapoleonParser diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index ad9e002958..0000000000 --- a/docs/conf.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -import datetime -import os -import sys - -# flake8: noqa -# pylint: skip-file - -# Embed a build timestamp so every docs build produces unique content, -# ensuring Akamai ECCU revalidate detects changed ETags on S3. -build_timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") - -project = "NeMo-AutoModel" -copyright = "2026, NVIDIA Corporation" -author = "NVIDIA Corporation" -release = "nightly" - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = [ - "myst_parser", # For our markdown docs - "autodoc2", # Generates API docs - "sphinx.ext.viewcode", # For adding a link to view source code in docs - "sphinx.ext.doctest", # Allows testing in docstrings - "sphinx.ext.napoleon", # For google style docstrings - "sphinx_copybutton", # For copy button in code blocks - "sphinx_design", # For grid layout and card components -] - -templates_path = ["_templates"] -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "documentation.md"] - -# -- Options for MyST Parser (Markdown) -------------------------------------- -# MyST Parser settings -myst_enable_extensions = [ - "dollarmath", # Enables dollar math for inline math - "amsmath", # Enables LaTeX math for display mode - "colon_fence", # Enables code blocks using ::: delimiters instead of ``` - "deflist", # Supports definition lists with term: definition format - "fieldlist", # Enables field lists for metadata like :author: Name - "tasklist", # Adds support for GitHub-style task lists with [ ] and [x] -] -myst_heading_anchors = 5 # Generates anchor links for headings up to level 5 - -# -- Options for Autodoc2 --------------------------------------------------- -sys.path.insert(0, os.path.abspath("..")) - -autodoc2_packages = [ - "../nemo_automodel", # Path to your package relative to conf.py -] -autodoc2_render_plugin = "myst" # Use MyST for rendering docstrings -autodoc2_output_dir = "apidocs" # Output directory for autodoc2 (relative to docs/) -# This is a workaround that uses the parser located in autodoc2_docstrings_parser.py to allow autodoc2 to -# render google style docstrings. -# Related Issue: https://github.com/sphinx-extensions2/sphinx-autodoc2/issues/33 -autodoc2_docstring_parser_regexes = [ - (r".*", "docs.autodoc2_docstrings_parser"), -] -# Exclude specific modules from autodoc2 generation -autodoc2_skip_module_regexes = [ - r"nemo_automodel\.package_info", # Exclude top-level package info file -] - -# Suppress build warnings that arise from generated files (harmless) -suppress_warnings = [ - "myst.header", # Skip warnings about heading level starting at H2 in generated docs - "autodoc2.dup_item", # Skip duplicate item warnings from autodoc2 analysis -] - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_theme = "nvidia_sphinx_theme" -# Add the docs render/build date to the footer on every page. -# The NVIDIA theme includes a "last-updated" footer component that shows -# Sphinx's `last_updated` value when this is set. -html_last_updated_fmt = "%Y-%m-%d" -html_theme_options = { - "icon_links": [ - { - "name": "GitHub", - "url": "https://github.com/NVIDIA-NeMo/Automodel/", - "icon": "fa-brands fa-github", - } - ], - "switcher": { - "json_url": "../versions1.json", - "version_match": release, - }, - "extra_head": { - f""" - - - """ - }, - "extra_footer": { - """ - - """ - }, -} -html_extra_path = ["project.json", "versions1.json"] - -# Github links are now getting rate limited from the Github Actions -linkcheck_ignore = [ - ".*github\\.com.*", - ".*githubusercontent\\.com.*", - ".*huggingface\\.co.*", # Gated model pages require authentication; non-checkable from CI - ".*llama\\.com.*", # Returns 400 to automated crawlers - ".*ai\\.meta\\.com.*", # Returns 400 to automated crawlers -] diff --git a/docs/project.json b/docs/project.json deleted file mode 100644 index 103b1f387b..0000000000 --- a/docs/project.json +++ /dev/null @@ -1 +0,0 @@ -{"name": "nemo-automodel", "version": "nightly"} diff --git a/docs/versions1.json b/docs/versions1.json deleted file mode 100644 index a2f2d46129..0000000000 --- a/docs/versions1.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "version": "nightly", - "url": "https://docs.nvidia.com/nemo/automodel/nightly/" - }, - { - "name": "0.4.0 (latest) · 26.04", - "version": "0.4.0", - "url": "https://docs.nvidia.com/nemo/automodel/latest/" - }, - { - "name": "0.3.0 · 26.02", - "version": "0.3.0", - "url": "https://docs.nvidia.com/nemo/automodel/0.3.0/" - }, - { - "name": "0.2.0 · 25.11", - "version": "0.2.0", - "url": "https://docs.nvidia.com/nemo/automodel/0.2.0/" - }, - { - "name": "0.1.0", - "version": "0.1.0", - "url": "https://docs.nvidia.com/nemo/automodel/0.1.0/" - } -] From 3f861f8c4d11c7c41df049652f1516fb58deca2b Mon Sep 17 00:00:00 2001 From: Lawrence Lane Date: Thu, 21 May 2026 17:56:14 -0400 Subject: [PATCH 7/7] docs(fern): switch to global-theme: nvidia (drop inline NVIDIA assets) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adopts the central NVIDIA Fern theme from https://github.com/NVIDIA/fern-components via `global-theme: nvidia` in docs.yml. At publish time Fern fetches the registered theme, merges it on top of this repo's docs.yml, and applies NVIDIA branding without us vendoring any of it locally. Removed (now inherited from the global theme): D docs/fern/main.css (NVIDIA-green CSS overrides) D docs/fern/assets/NVIDIA_{dark,light,symbol}.svg (logos + favicon) D docs/fern/components/CustomFooter.tsx (privacy / Do Not Sell / etc.) Kept locally (repo-specific, not in the global theme): docs/fern/components/BadgeLinks.tsx docs/fern/components/Tag.tsx docs.yml changes: - Add `global-theme: nvidia` - Drop `footer:` / `layout:` / `colors:` / `theme:` / `favicon:` / `js:` / `css:` (all inherited) - Keep only `logo: right-text: NeMo AutoModel` to override the theme's default right-text slot (same pattern as NeMo Curator) - Keep `instances:`, `redirects:`, `title:`, `navbar-links:`, `libraries:`, `experimental:`, `versions:` (all child-owned) fern.config.json: - Bump CLI pin 4.62.4 -> 5.29.0 (matches NeMo Curator; required for `global-theme:` support — pre-5.x CLIs reject the field). Validates clean: `fern check` -> All checks passed. README + SKILL.md updated to describe the new wiring (global-theme inheritance, kept-vs-removed components, CLI version bump). Signed-off-by: Lawrence Lane --- docs/fern/README.md | 18 +- docs/fern/assets/NVIDIA_dark.svg | 37 -- docs/fern/assets/NVIDIA_light.svg | 36 -- docs/fern/assets/NVIDIA_symbol.svg | 24 - docs/fern/components/CustomFooter.tsx | 96 --- docs/fern/docs.yml | 40 +- docs/fern/fern.config.json | 2 +- docs/fern/main.css | 872 -------------------------- skills/fern-docs/SKILL.md | 16 +- 9 files changed, 31 insertions(+), 1110 deletions(-) delete mode 100644 docs/fern/assets/NVIDIA_dark.svg delete mode 100644 docs/fern/assets/NVIDIA_light.svg delete mode 100644 docs/fern/assets/NVIDIA_symbol.svg delete mode 100644 docs/fern/components/CustomFooter.tsx delete mode 100644 docs/fern/main.css diff --git a/docs/fern/README.md b/docs/fern/README.md index b5c03769ab..ff3bfe9271 100644 --- a/docs/fern/README.md +++ b/docs/fern/README.md @@ -1,9 +1,11 @@ # NeMo AutoModel — Fern Docs -This directory holds the Fern build infrastructure (config, theme, components, frozen version snapshots) for the NeMo AutoModel documentation site at **[docs.nvidia.com/nemo/automodel](https://docs.nvidia.com/nemo/automodel)**. +This directory holds the Fern build infrastructure (config, repo-specific components, frozen version snapshots) for the NeMo AutoModel documentation site at **[docs.nvidia.com/nemo/automodel](https://docs.nvidia.com/nemo/automodel)**. **The MDX content lives one level up, in `docs/` itself** — every nightly page is a top-level sibling of this `docs/fern/` directory (e.g. `docs/index.mdx`, `docs/guides/llm/finetune.mdx`). Fern reads those files via relative `path: ../../<...>.mdx` entries in `docs/fern/versions/nightly.yml`. +NVIDIA branding (logos, favicon, footer, fonts, NVIDIA-green CSS, OneTrust JS) comes from the central control repo at **[NVIDIA/fern-components](https://github.com/NVIDIA/fern-components)** via `global-theme: nvidia` in `docs.yml` — no logos or theme CSS are vendored locally. + ## Quick links | What | Where | @@ -60,11 +62,10 @@ docs/ ← nightly MDX lives here (sibling of fern/) ├── about/, guides/, model-coverage/, launcher/, api-reference/ ├── *.png / *.jpg ← page-scoped images └── fern/ ← THIS DIRECTORY - ├── fern.config.json # Fern CLI pin (4.62.4+) and org slug - ├── docs.yml # Site config: instances, versions, redirects, libraries, theme - ├── main.css # NVIDIA-green theme overrides - ├── assets/ # Logos and shared SVGs - ├── components/ # BadgeLinks.tsx, Tag.tsx, CustomFooter.tsx + ├── fern.config.json # Fern CLI pin (5.29.0+) and org slug + ├── docs.yml # Site config: instances, versions, redirects, libraries, global-theme: nvidia + ├── components/ # BadgeLinks.tsx, Tag.tsx (repo-specific only; + │ # NVIDIA-branded footer/logo/CSS ship via global-theme) ├── versions/ │ ├── nightly.yml # Nav for nightly — paths point at ../../.mdx (up into docs/) │ ├── v0.4.yml # Nav for the frozen 0.4.0 GA snapshot — paths at ./v0.4/pages/ @@ -126,7 +127,8 @@ Use the bundled custom components in `components/`: |---|---|---| | `` | Header badge rows on landing pages (PyPI, license, GitHub, …) | `import { BadgeLinks } from "@/components/BadgeLinks";` | | `label` | Card chips ("start here", "5 min", etc.) | `import { Tag } from "@/components/Tag";` | -| `` | Wired in `docs.yml` `footer:`; **required** for NVIDIA legal/privacy compliance | (auto) | + +The shared NVIDIA `` (privacy / Do Not Sell / etc.) ships from the `nvidia` global theme — wired automatically, **not** authored in this repo. Standard Fern components are also available — ``, ``, ``, ``, `` / ``, etc. Don't use GitHub `> [!NOTE]` syntax — it does not render in MDX. @@ -202,7 +204,7 @@ PR titles follow Conventional Commits (e.g. `docs(fern): add gemma4 fine-tuning | `[ERR_PNPM_IGNORED_BUILDS]` on first `fern docs dev` | pnpm 10+ blocks esbuild's postinstall — `pnpm config set onlyBuiltDependencies '["esbuild"]' --location global`, then `rm -rf ~/.fern/app-preview` and retry | | Broken-link warning for version-agnostic path | `fern docs broken-links` false-positives on links without a version slug; the URLMap-based `validate_fern_internal_links.py` is authoritative | | `JSX expressions must have one parent element` | Wrap multi-element JSX in `<>...` or a `
` | -| Card badges have no spacing | Use `` (NeMo AutoModel landing pattern), not raw HTML; spacing is in `main.css` | +| Card badges have no spacing | Use `` (NeMo AutoModel landing pattern), not raw HTML; spacing comes from the `nvidia` global theme's CSS | | Old Sphinx URL breaks | Add a `redirects:` entry in `docs.yml` | | `//index.html` 404s but deep paths work | `:path*` does not match the empty-path case ([NVIDIA-NeMo/Curator#1938](https://github.com/NVIDIA-NeMo/Curator/pull/1938)). Each version-root `index.html` needs its own explicit redirect rule — slot before the `:path*/index.html` catch-all | diff --git a/docs/fern/assets/NVIDIA_dark.svg b/docs/fern/assets/NVIDIA_dark.svg deleted file mode 100644 index fe67b898bf..0000000000 --- a/docs/fern/assets/NVIDIA_dark.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/fern/assets/NVIDIA_light.svg b/docs/fern/assets/NVIDIA_light.svg deleted file mode 100644 index 568ee177ba..0000000000 --- a/docs/fern/assets/NVIDIA_light.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/fern/assets/NVIDIA_symbol.svg b/docs/fern/assets/NVIDIA_symbol.svg deleted file mode 100644 index fd57037f32..0000000000 --- a/docs/fern/assets/NVIDIA_symbol.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/docs/fern/components/CustomFooter.tsx b/docs/fern/components/CustomFooter.tsx deleted file mode 100644 index 91111549e5..0000000000 --- a/docs/fern/components/CustomFooter.tsx +++ /dev/null @@ -1,96 +0,0 @@ -/** - * SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: LicenseRef-NvidiaProprietary - */ - -/** - * Custom footer for NVIDIA docs (Fern native header/footer). - * Markup and class names match the original custom-app footer 1:1 so that - * docs/fern/main.css (footer + Built with Fern styles) applies correctly: - * dark mode logo, responsive layout, and Built with Fern tooltip. - */ -export default function CustomFooter() { - const currentYear = new Date().getFullYear(); - const logoUrl = - "https://fern-image-hosting.s3.us-east-1.amazonaws.com/nvidia/NVIDIA_Logo_0.svg"; - - return ( - - ); -} diff --git a/docs/fern/docs.yml b/docs/fern/docs.yml index 0480240298..ea0784e18f 100644 --- a/docs/fern/docs.yml +++ b/docs/fern/docs.yml @@ -2,36 +2,20 @@ instances: - url: https://nemo-automodel.docs.buildwithfern.com/nemo/automodel custom-domain: docs.nvidia.com/nemo/automodel title: NVIDIA NeMo AutoModel -footer: ./components/CustomFooter.tsx -layout: - searchbar-placement: header - page-width: 1376px - sidebar-width: 248px - content-width: 812px - tabs-placement: header - hide-feedback: true -colors: - accentPrimary: - dark: '#76B900' - light: '#76B900' - background: - light: '#FFFFFF' - dark: '#000000' -theme: - page-actions: toolbar - footer-nav: minimal + +# Inherit NVIDIA branding (footer, colors, layout, fonts, NVIDIA logos+favicon, +# OneTrust JS, theme CSS) from the central control repo at +# https://github.com/NVIDIA/fern-components. At publish time Fern fetches the +# `nvidia` theme from the registry and merges it on top of this file, so the +# theme-owned fields (footer / layout / colors / theme / logo SVGs / favicon / +# js / css) intentionally do NOT appear below. +global-theme: nvidia + +# Override only the `right-text` slot of the theme's logo; SVG paths, height, +# href stay inherited from the global theme. Same pattern as NeMo Curator. logo: - dark: ./assets/NVIDIA_dark.svg - light: ./assets/NVIDIA_light.svg - height: 20 - href: / right-text: NeMo AutoModel -favicon: ./assets/NVIDIA_symbol.svg -js: -- url: https://assets.adobedtm.com/5d4962a43b79/c1061d2c5e7b/launch-191c2462b890.min.js - strategy: beforeInteractive -css: -- ./main.css + navbar-links: - type: github value: https://github.com/NVIDIA-NeMo/Automodel diff --git a/docs/fern/fern.config.json b/docs/fern/fern.config.json index 3d47d15e31..aacfdddc82 100644 --- a/docs/fern/fern.config.json +++ b/docs/fern/fern.config.json @@ -1,4 +1,4 @@ { "organization": "nvidia", - "version": "4.62.4" + "version": "5.29.0" } diff --git a/docs/fern/main.css b/docs/fern/main.css deleted file mode 100644 index 936c895aaa..0000000000 --- a/docs/fern/main.css +++ /dev/null @@ -1,872 +0,0 @@ -/*! - * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: LicenseRef-NvidiaProprietary - * - * NVIDIA CORPORATION, its affiliates and licensors retain all intellectual - * property and proprietary rights in and to this material, related - * documentation and any modifications thereto. Any use, reproduction, - * disclosure or distribution of this material and related documentation - * without an express license agreement from NVIDIA CORPORATION or - * its affiliates is strictly prohibited. - */ - -/* Color themes for light and dark modes */ -:root { - /* Brand Colors */ - --nv-color-green: #74B900; - --nv-color-green-2: #004B31; - --nv-color-black: #000000; - --nv-color-white: #FFFFFF; - - /* Grey Scale - Light */ - --nv-light-grey-1: #f7f7f7; - --nv-light-grey-2: #EEEEEE; - --nv-light-grey-3: #DDDDDD; - --nv-light-grey-4: #CCCCCC; - --nv-light-grey-5: #999999; - - /* Grey Scale - Dark */ - --nv-dark-grey-1: #111111; - --nv-dark-grey-2: #1A1A1A; - --nv-dark-grey-3: #222222; - --nv-dark-grey-4: #333333; - --nv-dark-grey-5: #666666; - - /* Colors by Usage */ - --nv-color-text: #000000; - --nv-color-bg-default: #FFFFFF; - --nv-color-bg-alt: #f7f7f7; - --nv-color-success: #76B900; - --nv-color-error: #f44336; - - /* Theme-independent settings */ - --rounded: 999px; -} -main { - min-height: calc(100vh - 200px); - } -/* Typography - Headers */ -h1 { - font-size: 36px; - font-weight: 700; - line-height: 1.25em; /* 45px */ -} - -h2 { - font-size: 28px; - font-weight: 700; - line-height: 1.25em; /* 35px */ -} - -h3 { - font-size: 24px; - font-weight: 700; - line-height: 1.25em; /* 30px */ -} - -h4 { - font-size: 20px; - font-weight: 700; - line-height: 1.25em; /* 25px */ -} - -/* Typography - Paragraphs */ -.prose{ - color: var(--nv-dark-grey-2) !important; -} -.dark .prose{ - color: var(--nv-light-grey-2) !important; -} -p { - text-decoration-thickness: 3px; -} -.fern-mdx-link { - color: var(--tw-prose-body); - text-decoration-color: var(--accent); - font-weight: var(--font-weight-normal); -} - -/* Badge links: hide redundant external-link icon (badges already indicate links) */ -.badge-links .fern-mdx-link svg { - display: none; -} - -/* Light theme (default) */ -html:not([data-theme]),html[data-theme=light] { - --pst-color-background: #fff; - --pst-color-on-background: #fff; - --pst-color-shadow: #ccc; - --pst-color-heading: #000; - --pst-color-text-base: #1a1a1a; - --pst-color-text-muted: #666; - --pst-color-surface: #f7f7f7; - --pst-color-on-surface: #333; - --pst-color-primary: var(--nv-color-green-2); - --pst-color-table-row-hover-bg: var(--nv-color-green); - --pst-color-link: var(--pst-color-text-base); - --pst-color-link-hover: var(--pst-color-text-base); - --pst-color-inline-code: var(--pst-color-primary); - --pst-color-inline-code-links: var(--pst-color-primary); - --pst-color-secondary: var(--pst-color-primary); - --pst-color-secondary-bg: var(--nv-color-green); - --pst-color-accent: var(--nv-color-green); -} - -/* Dark theme */ -html[data-theme=dark] { - --pst-color-background: #111; - --pst-color-on-background: #000; - --pst-color-shadow: #000; - --pst-color-heading: #fff; - --pst-color-text-base: #eee; - --pst-color-text-muted: #999; - --pst-color-surface: #1a1a1a; - --pst-color-on-surface: #ddd; - --pst-color-primary: var(--nv-color-green); - --pst-color-table-row-hover-bg: var(--nv-color-green-2); - --pst-color-link: var(--pst-color-text-base); - --pst-color-link-hover: var(--pst-color-text-base); - --pst-color-inline-code: var(--pst-color-primary); - --pst-color-inline-code-links: var(--pst-color-primary); - --pst-color-secondary: var(--pst-color-primary); - --pst-color-secondary-bg: var(--nv-color-green-2); - --pst-color-accent: var(--nv-color-green); -} - -/* Product and verion selector styling */ - -.fern-product-selector { - border-radius: 8px; - pointer-events: none !important; - padding-right: 2px; -} - -.product-dropdown-trigger svg{ - display: none !important; -} - -.fern-product-selector .product-dropdown-trigger p{ - font-weight: bold !important; -} -.fern-product-selector-radio-group { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 8px; - max-width: 1000px; -} - -@media (max-width: 768px) { - .fern-product-selector-radio-group { - grid-template-columns: repeat(2, 1fr); - } -} -.fern-version-selector { - transform: translateY(-1px); -} - -.fern-version-selector .version-dropdown-trigger{ - outline: 1px solid var(--border, var(--grayscale-a5)) !important; - border-radius: 5px; - transition: box-shadow 0.3s ease, outline 0.3s ease; -} -.product-dropdown-trigger{ - padding-left: 0px !important; -} - -.product-dropdown-trigger, .version-dropdown-trigger{ - background-color: transparent !important; -} -.product-dropdown-trigger svg:hover{ - stroke: var(--nv-color-green) !important; -} -.version-dropdown-trigger:hover{ - box-shadow: 0 0 0 1px var(--nv-color-green) !important; -} -.version-dropdown-trigger svg:hover{ - stroke: var(--nv-color-green) !important; -} -/* Sidebar styling */ -#fern-sidebar { - border-right: 1px solid var(--border, var(--grayscale-a5)) !important; - height: 100vh !important; -} -.fern-sidebar-link:not(:hover){ - background-color: transparent !important; -} -.fern-sidebar-link { - padding-left: 1rem !important; - padding-right: 1rem !important; - padding-top: 0.5rem !important; - padding-bottom: 0.5rem !important; - border-radius: 0px !important; - &.nested { - padding-left: 1rem !important; - } -} -/* Section-level sidebar links (pages that have children) should match sidebar heading padding */ -.fern-sidebar-group > li > .fern-sidebar-link:has(+ .fern-sidebar-group) { - padding-left: 0.25rem !important; -} -.fern-sidebar-group{ - padding: 0 !important -} -#fern-sidebar-scroll-area{ - padding-right: 0 !important -} - -/* header styling */ -.fern-header-content{ - padding-left: 18.5px; - margin-top: -5px; - margin-bottom: -5px; -} -#fern-header { - border-color: var(--border, var(--grayscale-a5)) !important; -} -@keyframes header-background-fade { - 0% { - background-color: transparent; - } - 100% { - background-color: var(--header-background); - } - } - -[data-theme=default]#fern-header { -animation: header-background-fade linear; -animation-timeline: scroll(); -animation-range: 0 50px; -} -.fern-header-navbar-links .fern-button{ - background-color: transparent !important; -} -.fern-header-navbar-links > button{ - background-color: transparent !important; -} -.fern-header-logo-container > div > div > a > img{ - padding-right: 0.5rem; -} -.fern-header-logo-container .font-heading{ - font-size: 16px !important; - font-weight: bold !important; - color: var(--grayscale-a12) !important; - border-inline: 1px solid var(--border, var(--grayscale-a5)); - padding: 15px 1rem; - margin: -20px 0.5rem; -} -@media (max-width: 1024px) { - .fern-header-logo-container .font-heading{ - display: none !important; - } -} -/* Search bar styling */ -#fern-search-button{ - background-color: transparent !important; - border-radius: var(--rounded); - transition: box-shadow 0.3s ease, outline 0.3s ease; -} -#fern-search-button:hover{ - box-shadow: 0 0 0 1px var(--nv-color-green) !important; -} -#fern-search-button .fern-kbd{ - display: none; -} - -.fern-layout-footer-toolbar button{ - background-color: transparent !important; - border-color: transparent !important; - padding-inline: 0px !important; -} - -/* ========== Custom footer (native React component) – 1:1 with original ========== */ -.bd-footer { - border-top: 1px solid var(--border, var(--grayscale-a5)) !important; - font-family: NVIDIA, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; - font-size: 0.875rem; - padding: 2rem 0; - width: 100%; -} -.bd-footer * { - font-family: inherit; -} -.bd-footer__inner { - padding: 0 2rem; -} -.footer-items__start { - display: flex; - flex-direction: column; - gap: 1.5rem; -} -.footer-logos-container { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - gap: 1rem; -} -.footer-brand { - display: inline-block; - text-decoration: none; -} -.footer-brand .logo__image { - height: 24px; - width: auto; - transition: opacity 0.2s ease; -} -.footer-brand:hover .logo__image { - opacity: 0.8; -} -.footer-brand-fern { - display: flex; - align-items: center; - margin-left: auto; -} -/* Logo theme visibility – .dark is on ancestor in Fern */ -.only-light { - display: block; - filter: invert(1); -} -.only-dark { - display: none; -} -.dark .only-light { - display: none; -} -.dark .only-dark { - display: block; - filter: none; -} -.footer-links { - display: flex; - flex-wrap: wrap; - gap: 0.25rem 0.5rem; - line-height: 1.65; - margin: 0; - padding: 0; -} -.footer-links a { - color: var(--grayscale-a11); - text-decoration: none; - transition: color 0.2s ease; - white-space: nowrap; -} -.pipe-separator { - color: var(--grayscale-a11); - white-space: nowrap; -} -.copyright { - color: var(--grayscale-a11); - font-size: 0.875rem; - line-height: 1.65; - margin: 0; -} -@media (max-width: 768px) { - .bd-footer { padding: 1.5rem 0; } - .bd-footer__inner { padding: 0 1.5rem; } - .footer-items__start { gap: 1rem; } - .footer-links { flex-direction: row; gap: 0.5rem 0.75rem; } - .footer-links a { white-space: normal; word-break: break-word; } -} -@media (max-width: 480px) { - .footer-links { gap: 0.5rem; } - .footer-links a { font-size: 0.8125rem; } - .copyright { font-size: 0.8125rem; } -} -/* Built with Fern link + tooltip */ -.built-with-fern-link { - display: flex; - align-items: baseline; - gap: 0.25rem; - text-decoration: none; - position: relative; -} -.built-with-fern-logo { - height: 1rem; - margin: 0; - transition: filter 150ms ease; -} -.built-with-fern-logo path { fill: var(--grayscale-a12); } -.built-with-fern-link:hover .built-with-fern-logo { filter: saturate(1) opacity(1); } -.built-with-fern-link:hover .built-with-fern-logo path:nth-child(2) { fill: #51C233; } -.built-with-fern-tooltip { - position: absolute; - top: 50%; - right: calc(100%); - bottom: auto; - left: auto; - transform: translateY(-50%); - margin: 0; - margin-right: 0.5rem; - padding: 0.5rem 0.75rem; - background-color: #FFFFFF; - color: #000000; - font-size: 0.85rem; - border-radius: 0.375rem; - border: 1px solid var(--grayscale-a5); - white-space: nowrap; - pointer-events: none; - opacity: 0; - transition: opacity 150ms ease; - transition-delay: 0s; - z-index: 50; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - width: max-content; -} -.built-with-fern-link:hover .built-with-fern-tooltip { - opacity: 1; - transition-delay: 0.75s; -} -.dark .built-with-fern-tooltip { - background-color: #000000; - color: #FFFFFF; -} -.built-with-fern-logo-dark { display: none; } -.dark .built-with-fern-logo-light { display: none; } -.dark .built-with-fern-logo-dark { display: block; } -@media (prefers-color-scheme: dark) { - .built-with-fern-logo-light { display: none; } - .built-with-fern-logo-dark { display: block; } -} - -/* Footer styling */ -.fern-footer-nav{ - border-radius: var(--rounded); - background-color: transparent !important; - transition: box-shadow 0.3s ease, outline 0.3s ease; -} -/* Hide line numbers */ -.code-block-line-gutter { - display: none !important; -} -.fern-footer-prev h4, .fern-footer-next h4{ - font-size: inherit !important; -} -.fern-sidebar-link.nested[data-state="active"]:before { - left: -0px !important; - bottom: -0px !important; - top: -0px !important; - width: 2px !important; -} -.fern-sidebar-link[data-state="active"] { - color: unset !important; -} - -.fern-selection-item .fern-selection-item-icon{ - border-color: transparent !important; -} -/* Button styling */ -.fern-button{ - border-radius: var(--rounded); - font-weight: bold; -} -.fern-button.filled.primary{ - color: var(--nv-color-black); -} -.dark .fern-button.filled.primary{ - background-color: var(--nv-color-white); -} -.dark .fern-button.filled.primary:hover{ - background-color: var(--nv-light-grey-2); -} -.fern-button.outlined.normal{ - background-color: transparent; - --tw-ring-color: transparent; - color: var(--nv-color-black); -} -.fern-button.outlined.normal:hover{ - color: var(--nv-color-green) -} -.dark .fern-button.outlined.normal{ - color: var(--nv-color-white); -} -.dark .fern-button.outlined.normal:hover{ - color: var(--nv-color-green); -} -/* Card styling */ -.fern-card{ - transition: box-shadow 0.3s ease, outline 0.3s ease; -} -svg.card-icon{ - height: 24px !important; - width: 24px !important; -} -.card-icon{ - background-color: transparent !important; -} -.fern-card:hover{ - box-shadow: 0 0 0 1px var(--nv-color-green) !important; -} -.fern-docs-badge{ - border-radius: var(--rounded); -} -.fern-page-actions button:hover{ - background-color: transparent !important; -} -.fern-page-actions a:hover{ - background-color: transparent !important; -} -/* Moving logo to footer */ -#builtwithfern, #builtwithfern * { - display: none !important; -} - -/* Landing Page Gradients */ -/* Top: Simple radial gradient (no mask, responsive) */ -.landing-gradient-top { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 800px; - background: radial-gradient(ellipse 100% 100% at 50% 10%, - rgba(191, 242, 48, 0.15) 0%, - rgba(158, 228, 179, 0.12) 30%, - rgba(124, 215, 254, 0.12) 50%, - rgba(124, 215, 254, 0.06) 75%, - transparent 100%); - pointer-events: none; - z-index: 0; -} - -/* Bottom: Masked gradient for organic transition */ -.landing-gradient-bottom { - position: absolute; - bottom: -282px; - left: 0; - right: 0; - height: 1232px; - background: linear-gradient(85deg, #BFF230 41.98%, #7CD7FE 99.52%); - opacity: 0.05; - pointer-events: none; - z-index: 5; - mask-image: url('https://www.figma.com/api/mcp/asset/27509afa-9c16-46bb-8415-4395e2e5a347'); - mask-repeat: no-repeat; - mask-position: 0% -17px; - mask-size: 100% auto; - -webkit-mask-image: url('https://www.figma.com/api/mcp/asset/27509afa-9c16-46bb-8415-4395e2e5a347'); - -webkit-mask-repeat: no-repeat; - -webkit-mask-position: 0% -17px; - -webkit-mask-size: 100% auto; -} - -/* Landing Page Gradients Wrapper */ -.landing-page-gradients { - position: relative; - width: 100%; - margin-top: -100px; - padding-top: 100px; - overflow: visible; - background: #181818; -} - -/* Hero Section (Landing page only) */ -.hero-section { - position: relative; - width: 100%; - padding: 3rem 6rem; - margin: 0 auto; - overflow: visible; - display: flex; - flex-direction: column; - align-items: center; - z-index: 10; -} - -/* Hero Section Content - constrain width */ -.hero-section > * { - position: relative; - z-index: 100; - max-width: 1440px; - width: 100%; -} - -/* Tablet and Mobile: fix spacing and layout */ -@media (max-width: 1024px) { - /* Extend dark background behind header */ - .landing-page body, .landing-page html, .landing-page main { - background: #181818 !important; - } - - .landing-page-gradients { - margin-top: -100px; - padding-top: 100px; - } - - .hero-section { - padding: 2rem 2rem; - } - - .hero-section > * { - max-width: none; - } - - .hero-content-grid { - grid-template-columns: 1fr; - gap: 2rem; - } - - .hero-heading { - font-size: 36px; - } - - .hero-subtitle { - font-size: 16px; - } - - .hero-title-section { - margin-bottom: 2rem; - } -} - -/* Small mobile only */ -@media (max-width: 600px) { - .hero-heading { - font-size: 28px; - } - - .hero-section { - padding: 1.5rem 1.5rem; - } -} - -.hero-section h1, -.hero-section h2, -.hero-section h3, -.hero-section h4, -.hero-section h5, -.hero-section h6 { - pointer-events: none !important; -} -/* Hero Title Section */ -.hero-title-section { - text-align: center; - margin-bottom: 4rem; - position: relative; - z-index: 100; -} - -.hero-heading { - font-size: 48px; - font-weight: 700; - line-height: 1.2; - margin: 0 0 1rem 0; - color: var(--nv-color-white); -} - -.hero-subtitle { - font-size: 18px; - line-height: 1.5; - margin: 0; - color: var(--nv-color-white); -} - -/* Hero Content Grid */ -.hero-content-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 3rem; - align-items: start; - position: relative; - z-index: 100; -} - -.hero-column { - display: flex; - flex-direction: column; - gap: 1rem; -} - -.hero-column-title { - font-size: 24px; - font-weight: 700; - margin: 0; - color: var(--nv-color-white); -} - -.hero-column-subtitle { - font-size: 16px; - margin: 0 0 1rem 0; - color: var(--nv-color-white); -} - -/* Hero Card Container (Left Column) */ -.hero-card-container { - display: flex; - flex-direction: column; - border-radius: 8px; - overflow: hidden; - border: 1px solid var(--border, var(--grayscale-a5)); - margin-top: 1.5rem !important; - background: rgba(26, 26, 26, 0.2); - backdrop-filter: blur(6px); -} - -.hero-card-image { - width: 100%; - height: auto; - display: block; -} - -.hero-card-content { - padding: 1.5rem; - display: flex; - flex-direction: row; - gap: 1rem; - align-items: center; - justify-content: space-between; - background: rgba(26, 26, 26, 0.2); - backdrop-filter: blur(6px); -} - -.hero-card-text-wrapper { - flex: 1; -} - -.hero-card-text { - margin: 0; - font-size: 14px; - line-height: 1.5; - color: var(--nv-color-white); -} - -.hero-card-button-wrapper { - flex-shrink: 0; -} -.hero-card-button-wrapper .fern-mdx-link{ - text-decoration: none !important; -} - -.hero-card-button { - white-space: nowrap; -} - -/* Hero Cards */ - -.hero-column .fern-card { - padding: 9px 17px; - background-color: rgba(26, 26, 26, 0.2) !important; - backdrop-filter: blur(6px); -} - -.hero-section .fern-card{ - color: white !important; -} - -.hero-column .card-icon { - font-size: 64px !important; - width: 64px !important; - height: 64px !important; -} - -.hero-column .card-icon svg, -.hero-column .card-icon i { - font-size: 64px !important; - width: 64px !important; - height: 64px !important; -} - -.hero-column .fern-card-title { - font-size: 16px; - font-weight: 500; - line-height: 24px; -} - -.hero-column .fern-card p { - font-size: 14px; - line-height: 20px; - color: white !important; -} - -/* Body Section */ -.body-section { - display: flex; - padding: 4rem 16rem; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 4rem; - align-self: stretch; - position: relative; - z-index: 1; - background: #181818; -} - -/* Body Section Content - constrain width */ -.body-section > * { - max-width: 1440px; - width: 100%; - position: relative; - z-index: 10; -} - -.code-block .fern-code-link{ - text-decoration: underline !important; - text-decoration-color: var(--accent) !important; - text-underline-offset: 1px !important; - text-decoration-style: underline !important; -} - -/* Mobile Styles */ -@media (max-width: 768px) { - .hero-section { - padding: 2rem 1.5rem; - } - - .hero-title-section { - margin-bottom: 2rem; - } - - .hero-heading { - font-size: 32px; - } - - .hero-subtitle { - font-size: 16px; - } - - .hero-content-grid { - grid-template-columns: 1fr; - gap: 2rem; - } - - .hero-column-title { - font-size: 20px; - } - - .hero-column-subtitle { - font-size: 14px; - } - - .hero-card-content { - flex-direction: column; - align-items: flex-start; - } - - .hero-card-button-wrapper { - align-self: flex-start; - } - - .hero-column .card-icon, - .hero-column .card-icon svg, - .hero-column .card-icon i { - font-size: 40px !important; - width: 40px !important; - height: 40px !important; - } - - .hero-column .fern-card-title { - font-size: 14px; - } - - .hero-column .fern-card p { - font-size: 11px; - } - - .body-section { - padding: 2rem 1.5rem; - } - - .fern-selection-item-icon.use-icon { - display: none !important; - } -} \ No newline at end of file diff --git a/skills/fern-docs/SKILL.md b/skills/fern-docs/SKILL.md index 839cfd315c..cc5c07bd11 100644 --- a/skills/fern-docs/SKILL.md +++ b/skills/fern-docs/SKILL.md @@ -30,11 +30,12 @@ docs/ ← nightly MDX (top level) ├── about/, guides/, model-coverage/, launcher/, api-reference/ ├── *.png / *.jpg ← page-scoped images └── fern/ ← infra only - ├── fern.config.json # Org slug + Fern CLI pin (4.62.4+) - ├── docs.yml # Site config: instances, versions, redirects, libraries, theme - ├── main.css # NVIDIA-green theme overrides - ├── assets/ # Logos and shared SVGs (NVIDIA_dark/light/symbol) - ├── components/ # BadgeLinks.tsx, Tag.tsx, CustomFooter.tsx + ├── fern.config.json # Org slug + Fern CLI pin (5.29.0+) + ├── docs.yml # Site config + global-theme: nvidia (inherits + │ # logos / footer / theme CSS / fonts / OneTrust JS + │ # from NVIDIA/fern-components) + ├── components/ # BadgeLinks.tsx, Tag.tsx + │ # (repo-specific; NVIDIA footer ships in global theme) ├── versions/ │ ├── nightly.yml # Nav for nightly — paths → ../../.mdx (up into docs/) │ ├── v0.4.yml # Nav for frozen 0.4.0 — paths → ./v0.4/pages/ @@ -167,7 +168,7 @@ import { BadgeLinks } from "@/components/BadgeLinks"; `` accepts: `primary`, `secondary`, `success`, `warning`, `danger`, `info`, `light`, `dark` (1:1 with sphinx-design `{bdg-*}` variants). -Images live in `docs/fern/assets/` (shared across all pages) or alongside the MDX file (page-scoped). Reference page-scoped images with relative paths (`./image.png`), not absolute (`/image.png`) — Fern's path resolver doesn't normalize root-relative image paths the same way as link targets. +Page-scoped images live alongside the MDX file (e.g. `docs/guides/audio/qwen_omni_asr.png`). Reference them with relative paths (`./image.png`), not absolute (`/image.png`) — Fern's path resolver doesn't normalize root-relative image paths the same way as link targets. The NVIDIA logos and favicon come from the `nvidia` global theme; do not add them locally. ## Frontmatter @@ -285,8 +286,7 @@ If sign-off is missing on a recent commit, amend with `git commit --amend -s`. P | `docs/fern/versions/{latest,v0.4}.yml` | Frozen GA nav (mount `./v0.4/pages/...`) | | `docs/` (top-level *.mdx) | Nightly MDX content (~140 pages + page-scoped images) | | `docs/fern/versions/v0.4/pages/` | Frozen 0.4.0 snapshot (back-ports only) | -| `docs/fern/components/` | `BadgeLinks.tsx`, `Tag.tsx`, `CustomFooter.tsx` | -| `docs/fern/main.css` | Theme overrides — NVIDIA green, badge spacing | +| `docs/fern/components/` | `BadgeLinks.tsx`, `Tag.tsx` (repo-specific; NVIDIA footer ships via `global-theme: nvidia`) | | `docs/fern/README.md` | Human-facing orientation | | `docs/fern/Makefile` | `make docs / docs-check / docs-preview / docs-publish` (run from `docs/fern/` or via `make -C docs/fern`) | | `.github/workflows/fern-docs-*.yml` | CI: check, preview build, preview comment |

5|e4fEVE>|yf3kuM+#^m0rC&X@>~RB@=hX2 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⁡3)ul_W)=yTl$A@AuNk$?X7pBA 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