---
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

title: "Create a Model Entity"
description: ""
---

Create a Model Entity that references your FileSet to enable customization jobs.

## Prerequisites

- Created a FileSet containing your model checkpoint (refer to [Create a Model FileSet](/documentation/customizer-reference/manage-model-entities/create-a-model-file-set)).
- Set the `NMP_BASE_URL` environment variable.

```bash
export NMP_BASE_URL="https://your-nemo-platform-url"
```

---

## Create the Model Entity

```python
import os
from nemo_platform import NeMoPlatform
from nemo_platform._exceptions import ConflictError

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

try:
    model = client.models.create(
        workspace="default",
        name="qwen3-1.7b",
        fileset="default/qwen3-1.7b",  # Reference: workspace/fileset-name
        description="Qwen3 1.7B base model for customization",
    )
    print(f"Created Model Entity: {model.name}")
except ConflictError:
    print("Model Entity already exists")
    model = client.models.retrieve(workspace="default", name="qwen3-1.7b")
```

<Accordion title="Example Response">

```json
{
  "id": "model-abc123def456",
  "name": "qwen3-1.7b",
  "workspace": "default",
  "description": "Qwen3 1.7B base model for customization",
  "fileset": "default/qwen3-1.7b",
  "spec": null,
  "adapters": [],
  "created_at": "2026-02-09T10:30:00Z",
  "updated_at": "2026-02-09T10:30:00Z"
}
```

Note: `spec` is initially `null` and will be auto-populated by the Models Controller.

</Accordion>
---

## Wait for Model Spec Auto-Population

The platform's **Models Controller** automatically analyzes your model files and populates the `spec` field with metadata like architecture, parameter count, and layer information. This is required before running customization jobs.

```python
import time

# Poll until spec is populated
print("Waiting for model spec to be auto-populated...")
while True:
    model = client.models.retrieve(workspace="default", name="qwen3-1.7b")
    if model.spec:
        break
    print(" Still waiting...")
    time.sleep(5)

print(f"\nModel ready for customization!")
print(f" Family: {model.spec.family}")
print(f" Parameters: {model.spec.base_num_parameters:,}")
print(f" Hidden Size: {model.spec.hidden_size}")
print(f" Layers: {model.spec.num_layers}")
print(f" Attention Heads: {model.spec.num_attention_heads}")
```

<Accordion title="Example Model Spec">

```json
{
  "spec": {
    "family": "qwen",
    "base_num_parameters": 1720574976,
    "hidden_size": 2048,
    "num_layers": 28,
    "num_attention_heads": 16,
    "num_kv_heads": 8,
    "vocab_size": 151936,
    "context_size": 40960
  }
}
```

</Accordion>
---

## Verify the Model Entity

Before using in a customization job, verify everything is set up correctly:

```python
model = client.models.retrieve(workspace="default", name="qwen3-1.7b")

# Verification checks
assert model.spec is not None, "Model spec not yet populated - wait longer"
assert model.fileset, "FileSet reference missing"

print("Model Entity is ready for customization.")
print(f"\nUse in customization jobs as:")
print(f' model: "{model.workspace}/{model.name}"')
```

---

## Using the Model Entity in Customization Jobs

After your Model Entity is ready (has a populated `spec`), reference it in a customization job. Jobs are submitted to a backend (`automodel` shown here; `unsloth` is also available):

```python
from nemo_automodel_plugin.schema import AutomodelJobInput

# Create a customization job using the Model Entity
spec = AutomodelJobInput(
    model="default/qwen3-1.7b",  # Created above
    dataset={"training": "default/my-training-dataset"},
    training={"training_type": "sft", "finetuning_type": "lora"},
    schedule={"epochs": 1},
)
job = client.customization.automodel.jobs.create(spec=spec, workspace="default", name="my-lora-job")
```

Refer to [create-job](/documentation/customizer-reference/manage-customization-jobs/create-a-customization-job) for complete job creation details.

---

## Post-Training Output

After a customization job completes, the output depends on the fine-tuning regime (`training.finetuning_type`):

- **LoRA training** (`finetuning_type: "lora"`): An **adapter** is attached to this Model Entity. The adapter contains only the trained LoRA weights.
- **Full-weight training** (`finetuning_type: "all_weights"`): A **new Model Entity** is created containing the complete fine-tuned model weights. This new entity has a `base_model` field linking back to the original.

For LoRA jobs, you can list adapters attached to a model:

```python
model = client.models.retrieve(workspace="default", name="qwen3-1.7b")

if model.adapters:
    print(f"Adapters attached to {model.name}:")
    for adapter in model.adapters:
        print(f" - {adapter.name} (enabled: {adapter.enabled})")
else:
    print("No adapters attached yet")
```

---

## Next Steps

- [Create a customization job](/documentation/customizer-reference/manage-customization-jobs/create-a-customization-job)
- [Understand hyperparameters](/documentation/customizer-reference/manage-customization-jobs/training-configuration)
