inference/models) is a view over the self-hosted
model registry. The registry is a desired-configuration store: each record
is a model spec that describes how FirstByte serves one model.
Afterburner serves only clutch-layers models, on model servers that
FirstByte runs. A write to the registry does not start a pod. The serving
fabric reads the spec on its next hydrate.
Four procedures back the screen:
What the registry holds
Each registry record carries the deploy configuration and nothing that requires live Kubernetes or engine truth. The screen renders these fields:
The stat strip above the table counts models, sums requested GPUs and
replicas, and lists the distinct engines present. Rescan registry
re-runs
models.local. The search box filters client-side over
name, served/weights path, engine and namespace; the stat strip
always reflects the full list, not the filtered one.
The model spec field by field
The Deploy model drawer builds the payload sent tomodels.deploy.
Validation errors stay hidden until the first Deploy click, then
update live. Leaving
gpu, replicas or port blank is allowed — the
payload then falls back to the deployer’s defaults shown above — but a
non-empty value must parse as a usable number.
If models.deploy rejects the write, the drawer renders the mutation’s
error message inline and stays open. On success the drawer closes and
the registry list refetches.
Engines and serving images
The registry serves clutch-layers models only. These are FirstByte’s own model servers. The form starts withengine: clutch-layers, and an empty
engine field falls back to clutch-layers.
image has no default. You must enter the serving image of your
clutch-layers model server, for example
registry.example.com/clutch-layers:latest. The form shows an error until you
do. engine and image are independent fields. The spec does not derive one
from the other.
Set engine on every model. The router scrapes a model with the metric
profile of its engine. A model with no engine set is scraped with the built-in
default profile of mod_inference. That profile does not read the
clutch-layers metric names. See
Runtime and routing.
The engine value shows as a colour-coded tag in the table, the drawer and the
“Engines” stat card.
Sourcing weights from HuggingFace
The drawer’s Source toggle picks between two sourcing modes:- HuggingFace Hub — the server pulls the repo directly from
huggingface.co.modelis the repo id inorg/modelform, for examplemeta-llama/Llama-3.1-8B-Instruct. - Custom path — the model is served from a weights path already
present on the node or baked into the image, for example
/models/llama-3-8b.
hfToken and revision only appear, and only travel in the payload,
when sourcing from the Hub. Set revision to pin a Hub commit or branch;
leave it blank to track the repo’s default. The table shows the pinned
revision per model, or — when nothing is pinned.
Tenant sealing for HuggingFace tokens
Supply an HF token for gated or private repos. A token is sealed per tenant, so the drawer requires a tenant / org id as soon as the token field is non-empty; submitting without one raises “Enter a tenant to seal the HF token under”. The sealing path:- The token is submitted with
tenantIdtomodels.deploy. - The BFF seals it with
cred_seal(AES-256-GCM, keyed per tenant) before the value reaches Redis. - The sealed value is decrypted only inside the serving pod, at deploy time.
sealed creds tag in its drawer
(driven by a non-empty sealedEnv). The token itself is never read back
into the console.
Namespaces, GPUs, replicas and ports
namespaceselects the Kubernetes namespace that the deployment lands in; blank meansdefault.gpuis the GPU request per replica, accepted in the range 0–8. Zero is valid, for a model that runs on CPU.replicasis the desired replica count, accepted in the range 1–64.portis the service port exposed by the serving container; blank means8000.
gpu and replicas across every registered model,
which is the quickest read on how much capacity the registry is asking
for in aggregate.
Status and what the registry does not track
Each row and drawer shows astatus pill derived from the spec’s
status field. This value comes from the registry record, so it tracks
the spec’s own lifecycle — it is not a live readback from Kubernetes or
from the engine.
The registry deliberately carries no live serving truth. Ready replica
counts and throughput are not part of a registry record and are not
displayed; the drawer states that they appear only once the deployment is
live and serving traffic. To reason about a running deployment, use the
serving-side signals, not this screen.
The table also has an Upstream column. It is a separate fact from
Status. Status describes the registry entry. Upstream says whether the address
that the entry routes to answered on its last turn. The pill reads up,
down, or untried. The verdict comes from real turns, so a model that
nobody has called reads untried. The same pill reads untried for a model
with no static route, because k8s discovery may serve that model. The screen
adds a note in three cases:
- No engine is reporting. Every model reads
untried. This does not mean that the models fail to serve. - The engine reports routing but not upstream health. Routing works. This build of the engine does not measure upstream health.
- The engine routes a name that the registry does not list, or some endpoints answered nothing on their last turn.
When a registry write takes effect
models.deploy saves desired configuration. It does not restart or
reload anything on its own:
- The spec is written into the registry that
mod_inferencereads on its next hydrate. - The change applies on the next deployment restart.
- Running requests are not reloaded. In-flight traffic continues against the previously loaded configuration.
image, revision, gpu,
replicas or port: the registry reflects them immediately, the serving
fabric does not until it next hydrates.
Enabling and disabling registry writes
Writes are gated on the BFF by theINFERENCE_DEPLOY_ENABLED environment
variable, set to 1 to enable them. The console reads the resulting flag
through models.deployStatus, which returns { enabled }.
When writes are disabled:
- A warning banner appears under the page header: “Registry writes are disabled on this deployment — models can be viewed but not deployed or removed.”
- Deploy model is disabled, with the tooltip “Registry writes are disabled on this deployment”.
- Every Remove button, in both the table and the drawer, is disabled.
models.localstill runs, so the registry remains fully readable and Rescan registry still works.
Removing a model
models.remove takes a single argument, { name }, and deletes the
matching registry record. Two controls call it:
- The Remove button on each table row. Its click handler stops propagation, so it removes the model without opening the drawer.
- Remove from registry in the model drawer’s footer.
Related
- Telemetry — metrics and traces for serving traffic
- Authentication — API keys and per-tenant credential scope