Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/customizer/about.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ SFT and LoRA both learn from examples of the right answer. Reinforcement learnin

DPO trains on preference pairs. Each example is a prompt with a **chosen** response and a **rejected** one, and training pushes the model toward the chosen style without needing a separate reward model. Use it when you have human or model-generated preference data and want to shape tone, formatting, or helpfulness.

The main control is `ref_policy_kl_penalty` (β), which sets how far the policy may drift from the model it started as.
The main control is `ref_policy_kl_penalty` (β), which sets how far the policy may drift from the model it started as. See [DPO Customization](/documentation/customizer-reference/tutorials/dpo-customization-job).

### Group Relative Policy Optimization

Expand Down
4 changes: 2 additions & 2 deletions docs/customizer/grpo-training.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ A full-weight GRPO job instead registers a new model entity, which does need its

## Key hyperparameters

All GRPO knobs live under `training`, except `policy_backend`, which is under `training.parallelism`.
All GRPO knobs live under `training`, including `policy_backend` (a sibling of `parallelism`, not a field on it).

| Field | Default | Notes |
| --- | --- | --- |
Expand All @@ -384,7 +384,7 @@ All GRPO knobs live under `training`, except `policy_backend`, which is under `t
| `overlong_filtering` | `false` | Zero the loss contribution of responses truncated at the generation cap. |
| `ref_policy_kl_penalty` | `0.0` | KL coefficient against the reference policy. |
| `val_at_start` | `false` | Run validation before the first step, so baseline and result come from one job. |
| `parallelism.policy_backend` | `automodel` | The NeMo-RL worker that trains the model, chosen explicitly and never inferred. `automodel` supports LoRA, `expert_parallel_size` above 1, and `automodel_kwargs`, and needs Transformer Engine (Hopper or newer). `dtensor` runs stock HuggingFace modules on PyTorch FSDP2 for pre-Hopper GPUs, and supports none of those three. Requesting an `automodel`-only feature under `dtensor` is rejected at submit, with every conflict reported at once. |
| `policy_backend` | `automodel` | The NeMo-RL worker that trains the model, chosen explicitly and never inferred. Set it on `training` (for example `training.policy_backend`), not under `training.parallelism`. `automodel` supports LoRA, `expert_parallel_size` above 1, and `automodel_kwargs`, and needs Transformer Engine (Hopper or newer). `dtensor` runs stock HuggingFace modules on PyTorch FSDP2 for pre-Hopper GPUs, and supports none of those three. Requesting an `automodel`-only feature under `dtensor` is rejected at submit, with every conflict reported at once. |
| `batching_strategy` | `dynamic` | How rollouts are grouped into training micro-batches. `dynamic` fills each micro-batch to a token budget, so short rollouts share a batch instead of each paying for a full-length pad. `static` puts one rollout per slot. `sequence_packing` concatenates rollouts, and is rejected for VLM, multimodal, and context-parallel runs. |
| `train_mb_tokens` | Derived | Token budget per micro-batch, read by `dynamic` and `sequence_packing`. Defaults to `max_seq_length × micro_batch_size`. |
| `sequence_length_round` | `64` | Round bucketed sequence lengths up to a multiple of this. Read only by `dynamic`. |
Expand Down
7 changes: 7 additions & 0 deletions docs/customizer/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ Learn how to start a SFT customization job using a custom dataset.

<small><span class="md-tag">nemo-customizer</span></small>

</Card>
<Card title="Start a DPO Customization Job" href="/documentation/customizer-reference/tutorials/dpo-customization-job">

Learn how to start a DPO customization job using preference data.

<small><span class="md-tag">nemo-customizer</span> <span class="md-tag">dpo</span></small>

</Card>
<Card title="Distill a Model with Knowledge Distillation" href="/documentation/customizer-reference/tutorials/distillation-customization-job">

Expand Down
2 changes: 1 addition & 1 deletion docs/customizer/manage-customization-jobs/cancel-job.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ print(f"Updated at: {cancelled_job.updated_at}")
"name": "automodel-a1b2c3d4e5f6",
"workspace": "default",
"id": "platform-job-2k8i3i1HqJHHPVB5M6Bk9Z",
"source": "automodel",
"source": "customization",
"status": "cancelled",
"spec": {
"model": "default/qwen3-1.7b",
Expand Down
9 changes: 9 additions & 0 deletions docs/customizer/manage-customization-jobs/create-job.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,15 @@ print(f"Submitted job: {job.job.name}")
Knowledge distillation is an Automodel feature. Set `training.training_type` to `"distillation"` and provide a `teacher_model` that references a second Model Entity. The `model` field is the student model being trained.

```python
import os
from nemo_platform import NeMoPlatform
from nemo_automodel_plugin.schema import AutomodelJobInput

client = NeMoPlatform(
base_url=os.environ.get("NMP_BASE_URL", "http://localhost:8080"),
workspace="default",
)

spec = AutomodelJobInput(
model="default/qwen3-1.7b", # Student model
dataset={"training": "default/my-training-dataset"},
Expand Down
14 changes: 7 additions & 7 deletions docs/customizer/manage-customization-jobs/list-active-jobs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: "List Active Jobs"
description: ""
---
<a id="ft-list-active-customization-jobs"></a>
List active customization jobs and their high-level status. Customization jobs run on the platform's Jobs service, so you list them through that service and filter by `source` and `status`. The `source` scopes results to a backend (`automodel` or `unsloth`), while `status="active"` excludes completed, failed, and cancelled jobs. Each entry includes the job definition (model, dataset, training configuration) and overall status.
List active customization jobs and their high-level status. Customization jobs run on the platform's Jobs service, so you list them through that service and filter by `source` and `status`. Platform job records use `source="customization"` for Automodel, Unsloth, and RL (the Jobs service does not store the training backend as `source`). `status="active"` excludes completed, failed, and cancelled jobs. Tell backends apart from the job name prefix (`automodel-…`, `unsloth-…`, `rl-…`) or from the backend you submitted to. Each entry includes the job definition (model, dataset, training configuration) and overall status.

<Tip>

Expand All @@ -28,7 +28,7 @@ export NMP_BASE_URL="https://your-nmp-base-url"

## To List Active Customization Jobs

Use the SDK to list jobs, filtering by `source` to scope the results to a customization backend and by `status` to return only active jobs:
Use the SDK to list jobs, filtering by `source="customization"` and by `status` to return only active customization jobs:

```python
import os
Expand All @@ -40,11 +40,11 @@ client = NeMoPlatform(
workspace="default",
)

# List active automodel customization jobs
# List active customization jobs
jobs = client.jobs.list(
workspace="default",
filter={
"source": "automodel", # Use "unsloth" for the Unsloth backend
"source": "customization",
"status": "active",
},
page=1,
Expand All @@ -61,7 +61,7 @@ for job in jobs.data:
filtered_jobs = client.jobs.list(
workspace="default",
filter={
"source": "automodel",
"source": "customization",
"status": "active",
"project": "my-finetuning-project",
},
Expand All @@ -84,7 +84,7 @@ for job in filtered_jobs.data:
"id": "platform-job-QtyhRY5ub4t4tTLPY4sTkz",
"name": "automodel-99da3f7c1b2e",
"workspace": "default",
"source": "automodel",
"source": "customization",
"created_at": "2026-02-09T22:12:45",
"updated_at": "2026-02-09T22:12:45",
"status": "active",
Expand Down Expand Up @@ -126,7 +126,7 @@ for job in filtered_jobs.data:
},
"sort": "created_at",
"filter": {
"source": "automodel",
"source": "customization",
"status": "active"
},
"search": {}
Expand Down
29 changes: 1 addition & 28 deletions docs/customizer/models/data-format.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -175,31 +175,4 @@ Each line in your JSONL file must contain a JSON object with these required fiel
}
```

### SFT Legacy Conversational

#### Required Schema

Each line in your JSONL file must contain a JSON object with these required fields:

- **`system`** (string): The system message that defines the assistant's role or behavior.
- **`conversations`** (array of objects): The conversation turns between user and assistant.
- **`from`** (string): The role of the message sender (`User` or `Assistant`).
- **`value`** (string): The content of the message.

#### Example Dataset Entry

```json
{
"system": "You are a helpful assistant.",
"conversations": [
{
"from": "User",
"value": "Choose a number that is greater than 0 and less than 2."
},
{
"from": "Assistant",
"value": "1"
}
]
}
```
The `system` plus `conversations: [{from, value}]` layout is **not** a supported SFT schema. Automodel detects chat data from a `messages` array (`role` / `content`), prompt/completion pairs, embedding triplets, or a custom two-column `prompt_template`. Convert conversational examples to [OpenAI Chat Model](#openai-chat-model) format before training; otherwise the job fails at start with `DatasetFormatError`.
Loading
Loading