---
title: "Prepare your model template"
description: "Write the ARX model template that lists your model in AI Model Center: the collection and variant layout, the model block that declares what the model is, its download sources, and the engines that serve it"
canonical_url: "https://developer.ardge.com/en/guide/model-provider/prepare-model-template"
---
# Prepare your model template

> Write the ARX model template that lists your model in AI Model Center: the collection and variant layout, the model block that declares what the model is, its download sources, and the engines that serve it

## Overview

The model template is what makes your model deployable on ARX. It is a directory of YAML that declares what the model is, where its weights are downloaded from, what it needs to run, and which inference engines can serve it.

A model template is always a **collection** of variants, even when there is only one variant. The collection is the marketplace entry; each variant is a separately deployable build of the same model family.

This page covers the layout of that directory and, above all, the `model` block where you declare the model itself.

## What you'll learn

- Lay out a collection and its variant directories, and pick ids that agree with each other
- Declare what the model is in the `model` block: parameters, format, precision, tasks, and inputs and outputs
- Point at the weights with `sources`, and at the engines that serve them with `deployment.engines`

## Applies to

- ARX OS 1.0 and later

## Before you begin

- Your model is published where ARX can download it — a Hugging Face or ModelScope repository, or another source you can name
- You know the exact file names to download when the model is a GGUF build

<note>

**Download the skills:** the bundle is [arx-isv-skills-v0.6.4.zip](https://developer.ardge.com/skills/arx-isv-skills-v0.6.4.zip) (about 185 KB) — unzip it and copy the folders inside into your project's `.claude/skills/`.

</note>

<tip>

**Let an AI agent write it for you:** point your AI agent at the skills bundle and have it generate the template from your model's source page.

</tip>

## Directory layout

Templates sit directly under `templates/`. A collection's directory name is its id, and each variant lives in its own subdirectory:

```text
templates/
- publisher.yaml
- models.your-model/
  - collection.yaml         # the collection root
  - icon.svg                # optional
  - localization.yaml       # collection-level translations (optional)
  - 0.6b-gguf/              # one directory per variant
    - manifest.yaml
    - localization.yaml     # optional
  - 8b-instruct/
    - manifest.yaml
```

Name a variant directory after size and build — `0.6b-gguf`, `4b`, `8b-instruct`, `270m` — because that name becomes the `@variant` suffix of the variant's id.

Three values state the same family three times, and validation fails when they disagree:

```yaml
# collection.yaml
id: models.your-model

# 0.6b-gguf/manifest.yaml
id: models.your-model@0.6b-gguf   # left of '@' is the collection id
model:
  collection: your-model          # the id's last segment, with no prefix
```

<warning>

**Two documents, two version constants:** `collection.yaml` takes `version: "1"`, a variant manifest takes `version: "1.0"`. Writing `"1.0"` in a collection is the most common first error in the whole format.

</warning>

## What goes in collection.yaml

The collection is the marketplace entry for the family. Everything below is required except `icon`.

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      What it carries
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        metadata.id
      </code>
      
       / <code>
        name
      </code>
    </td>
    
    <td>
      The family id, matching the directory, with no <code>
        @variant
      </code>
      
      , and its display name
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        metadata.description
      </code>
    </td>
    
    <td>
      What the family is and what it is good at — either the prose itself, or the name of a file beside <code>
        collection.yaml
      </code>
      
       that holds it
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        metadata.categories
      </code>
    </td>
    
    <td>
      Closed enum, at least one: <code>
        llm
      </code>
      
      , <code>
        embedding-model
      </code>
      
      , <code>
        reranker-model
      </code>
      
      , <code>
        image-model
      </code>
      
      , <code>
        audio-model
      </code>
      
      , <code>
        video-model
      </code>
      
      , <code>
        multimodal
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        metadata.tasks
      </code>
      
       / <code>
        inputTypes
      </code>
      
       / <code>
        outputTypes
      </code>
    </td>
    
    <td>
      The same three closed enums a variant declares — see <a href="#the-model-block">
        the model block
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        metadata.tags
      </code>
      
       / <code>
        license
      </code>
      
       / <code>
        developer
      </code>
      
       / <code>
        updateDate
      </code>
    </td>
    
    <td>
      Free tags, the licence, the upstream developer's name and URL, and the date the entry was last updated
    </td>
  </tr>
</tbody>
</table>

There is no `subtitle` in a collection — variants have one, collections do not.

## What goes in a variant manifest.yaml

<table>
<thead>
  <tr>
    <th>
      Block
    </th>
    
    <th>
      What it carries
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        metadata
      </code>
    </td>
    
    <td>
      Id, name, version, release date, <code>
        type: models
      </code>
      
      , categories, subtitle, developer, supported languages, and tags. <code>
        subtitle
      </code>
      
       is required here, unlike in an app manifest
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        metadata.model
      </code>
    </td>
    
    <td>
      What the model actually is — the block this page is about
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        resources
      </code>
    </td>
    
    <td>
      CPU, memory, storage, GPU count, and VRAM the variant needs to serve
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        deployment
      </code>
    </td>
    
    <td>
      <code>
        type: model
      </code>
      
       plus the engines that can serve it
    </td>
  </tr>
</tbody>
</table>

`metadata.releaseDate` is the model's real release date, taken from its source page rather than from the day you write the manifest. `metadata.supportedLanguages` is what the model itself handles, not the languages the template is translated into.

## The model block

Required inside it: `collection`, `params`, `format`, and `sources`. Everything else is optional but usually worth declaring, because an application's dependency conditions filter on these fields — a variant that omits them cannot be matched.

```yaml
model:
  collection: your-model           # collection name, no prefix
  params: "0.6b"                   # ^[0-9]+(\.[0-9]+)?(b|m)$
  variant: reranker
  quantization: "Q8_0"
  format: gguf
  tasks:
    - text-ranking
  inputTypes:
    - text
  outputTypes:
    - score
  sources:
    - provider: huggingface
      modelId: ggml-org/Qwen3-Reranker-0.6B-Q8_0-GGUF
      files:
        - "qwen3-reranker-0.6b-q8_0.gguf"
```

### params

The pure parameter count: digits, an optional decimal point, and a lowercase `b` for billion or `m` for million. `"0.6b"` and `"270m"` are correct; `"8B"` and `"8b-gguf"` are not — build information belongs in the variant id. For a mixture-of-experts model, write the **total** count and mention the active parameters in the subtitle or tags.

### format

A closed enum, and it decides which engines can serve the model:

<table>
<thead>
  <tr>
    <th>
      Value
    </th>
    
    <th>
      Served by
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        gguf
      </code>
    </td>
    
    <td>
      llama.cpp
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        safetensors
      </code>
    </td>
    
    <td>
      vLLM and other Hugging Face Transformers–style runtimes
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ct2
      </code>
    </td>
    
    <td>
      CTranslate2 (faster-whisper)
    </td>
  </tr>
</tbody>
</table>

### variant, precision, quantization

- `variant` — `base`, `instruct`, `instruction-tuned`, `chat`, `embedding`, `reranker`, or `transcription`
- `precision` — `fp32`, `fp16`, `bf16`, `fp8`, `int8`, or `int4`. Omit it for GGUF builds, where the quantization already says it; set it for safetensors and ct2
- `quantization` — a free string such as `"Q8_0"`, `"Q4_K_M"` or `"awq"`, or `null`

### tasks, inputTypes, outputTypes

Three closed enums, the same three the collection declares:

<table>
<thead>
  <tr>
    <th>
      Kind
    </th>
    
    <th>
      <code>
        tasks
      </code>
    </th>
    
    <th>
      <code>
        inputTypes
      </code>
    </th>
    
    <th>
      <code>
        outputTypes
      </code>
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      LLM
    </td>
    
    <td>
      <code>
        text-generation
      </code>
    </td>
    
    <td>
      <code>
        text
      </code>
    </td>
    
    <td>
      <code>
        text
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Embedding
    </td>
    
    <td>
      <code>
        text-embedding
      </code>
    </td>
    
    <td>
      <code>
        text
      </code>
    </td>
    
    <td>
      <code>
        vector
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Reranker
    </td>
    
    <td>
      <code>
        text-ranking
      </code>
    </td>
    
    <td>
      <code>
        text
      </code>
    </td>
    
    <td>
      <code>
        score
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Transcription
    </td>
    
    <td>
      <code>
        audio-to-text
      </code>
    </td>
    
    <td>
      <code>
        audio
      </code>
    </td>
    
    <td>
      <code>
        text
      </code>
    </td>
  </tr>
</tbody>
</table>

### sources

Download sources in priority order. Each entry needs a `provider` — `huggingface`, `modelscope`, `ollama`, or `custom` — and a `modelId`. Add `files` to narrow the download to specific files, which is required for a GGUF build served by llama.cpp.

File names must match the provider's listing exactly, so fetch them rather than guessing. Note that `ollama` here is a download provider, not an inference engine.

## deployment.engines

At least one engine, each with a `name` and the `apiEndpoints` this model serves on it:

```yaml
deployment:
  type: model
  engines:
    - name: llama.cpp
      version: ">=0.11.0"          # optional
      apiEndpoints:
        - /v1/chat/completions
      contextWindow: 32768
```

Engine names resolve against the inference-engine catalog the validator compiles in: `llamacpp` (aliases `llama.cpp`, `llama_cpp`) for GGUF, `vllm` and `nvidia-vllm` for safetensors, and `whisper` (alias `faster-whisper`) for ct2 speech-to-text. Anything else fails validation.

Declare `contextWindow` on the first engine at minimum — that is the value an application's dependency conditions compare against.

## resources

Estimate from the real files and the measured serving footprint: `storage` is the size of what is actually downloaded, and `vram` is the weights plus the KV cache at the declared context window, with headroom. A CPU-only model takes `gpu: 0` and `vram: null`.

## Optional files

`icon.svg` is the icon AI Model Center lists the collection under — square, 256×256 or larger, on a transparent background, SVG preferred.

`localization.yaml` translates the user-facing strings, and a model carries it at two levels: one beside `collection.yaml`, one inside each variant directory. The model's name is not translated — a model number reads the same in every language.

## Next step

<card-group>
<card icon="i-lucide-handshake" title="Ship through the official channel" to="https://developer.ardge.com/en/guide/model-provider/shipping-channel">

Move from a template you deploy yourself to shipping your model to customers as an ARDGE partner

</card>
</card-group>


## Sitemap

See the full [sitemap](https://developer.ardge.com/sitemap.md) for all pages.
