Skip to main content

Model YAML schema

hosts/<host>/<engine>/models/<slug>.yml is the contract. One file drives the compose service, the LiteLLM routing table, and the VRAM budget check. There is no second place to register a model.

make validate enforces everything below, offline, before Ansible connects to anything.

Common fields

FieldTypeMeaning
slugstringMust equal the filename stem. It is also the primary LiteLLM alias.
enginevllm | llamacppSelects which extra fields are required, and must match the host's engine.
imagestringContainer image for the engine process.
portintHost-side port. Unique within a host, and rendered as 127.0.0.1:<port>:<internal>.
vram_estimate_gibintWhat this model occupies. Summed across active_models and checked against vram_budget_gib.
tier8g | 24g | 48gThe card size this entry is sized for. A model may not exceed its tier's ceiling.
mandatoryboolWhether the recommender fits this one before anything else.
virtual_modelslistExtra LiteLLM aliases. Globally unique per host.
extra_argslistPassed to the engine verbatim, one list item per argv element.
notesstringWhy. See below.

vLLM-only

FieldMeaning
hf_modelThe HuggingFace repo id vLLM loads.
max_model_lenContext length.
gpu_memory_utilizationFraction of total card memory, weights included.
max_num_seqsConcurrent sequences.
dtypeauto, bfloat16, …

llama.cpp-only

FieldMeaning
hf_repoThe GGUF repository.
hf_fileThe exact GGUF filename to download.
contextContext length, passed as -c.
n_gpu_layersLayers to offload. 999 means all; llama.cpp clamps to the real count.
parallel_slotsConcurrent slots, passed as -np.

Rules the validator enforces

  • slug equals the filename stem.
  • Ports are unique within a host, and never collide with the gateway port.
  • sum(vram_estimate_gib) over active_models fits vram_budget_gib.
  • No model exceeds its declared tier's ceiling.
  • Aliases are unique per host. LiteLLM silently shadows a duplicate model_name rather than erroring, so a collision would otherwise cost you an afternoon.
  • Every slug in active_models names a file that exists.
  • chat_template_file, if set, points at a file that exists.
  • The host serves every alias in required_common_aliases.
  • Anything a pi extension advertises is an alias some host actually serves.

extra_args is a list of argv elements, not a command line

extra_args:
- --flash-attn
- "on" # its own element, not "--flash-attn on"

The template renders one YAML item per argument. Writing --flash-attn on as a single string passes it as one argv element, which the engine rejects.

The notes block is not decoration

Every model file carries prose explaining the quantization choice, the sizing arithmetic, and what breaks. That is why these are YAML-with-prose rather than rows in a table:

Q4_K_M (~4.7 GiB weights) plus ~1.3 GiB of KV cache at 16384 context fits inside an 8 GiB budget with a little headroom. On unified-memory APUs the relevant limit is the GTT allocation, not a dedicated VRAM pool […]

Quantization and tool calling interact. The source deployment this was ported from found Q4_K_M improvising tool-call wrappers that llama.cpp's chat parser does not recognise […] Q6_K restored adherence.

Six months later, that paragraph is the difference between a ten-minute fix and rediscovering the problem from scratch.