Share models on Hugging Face¶
A Hugging Face model repository can publish Loom programs, model cards, and a
catalog together. Users select a model with loom-fetch, then pass the installed
card to loom-serve. The publisher needs the installed SDK and ordinary files;
there is no required build system, native extension, or server rebuild.
This guide uses a tiny text model to prove the whole path before introducing large checkpoints. It performs deterministic arithmetic through real JIT kernels and the text service. It is not a trained chatbot.
The published example contains the same files as the downloadable template below.
Start from a working publication¶
Install the Loom SDK, including the
hf extra for Hugging Face acquisition. The example's smoke test requires
loom-serve with the x86 CPU JIT and task device enabled.
Download the ready-to-copy template and extract it:
curl --fail --location https://rocm.github.io/hrx-system/loom/generated/examples/serving/model-publication.zip --output=model-publication.zip
python -m zipfile -e model-publication.zip .
cd model-publication
python smoke.py
In Windows PowerShell, use curl.exe to select curl instead of a shell alias.
The Python commands are the same. The final JSON reports "status": "ok" and
includes the checked completion. Diagnostics and fetch progress use stderr.
The script starts a private CPU server on an automatically selected loopback
port, submits a request, then stops that disposable server.
The downloaded folder contains only the publication:
README.md this model's behavior and requirements
AGENTS.md links to the authoritative Loom guides
LICENSE
catalog.json discovery index
refresh.py explicit metadata refresh
smoke.py acquisition and expected-output check
model/tiny-text/
model.json portable model definition
model.json.lock asset identities
tokenizer.json
program/*.loom preparation, control, storage, and kernels
There are no build files or checkout-relative dependencies. The example embeds its 76-byte safetensors checkpoint in the card; fetch materializes it as an ordinary parameter file. Larger checkpoints can be local files or references to another Hugging Face repository, as shown below.
Edit the model; refresh metadata explicitly¶
The portable model card connects programs, services, parameter variants, tokenizers, and presets. Its paths are relative to the card, not the repository root. Device placement belongs to the user's deployment, not the published model definition.
| File | Maintained by | Changes that require attention |
|---|---|---|
model/*/model.json |
Model author | Program roles, checkpoint sources, service contracts, and presets. |
model.json.lock |
refresh.py / loom-fetch |
Asset contents, origins, or the set of selected dependencies. |
catalog.json |
refresh.py / catalog generator |
Model IDs, names, descriptions, services, variants, and presets. |
smoke.py |
Model author | The expected response and device requirements of the published example. |
One command refreshes all cards in this template's model/*/ layout:
Refresh deliberately replaces asset commitments. Review its diff alongside the authored change. Smoke consumes the existing locks: changed assets fail rather than having their new hashes accepted. It also compares the local catalog to the cards, so stale discovery metadata fails before serving. The smoke's expected text and token counts belong to this arithmetic model; a learned port supplies its own numerical or behavioral checks.
An asset-scoped lock leaves .loom, .loombc, and auxiliary program files
editable. A kernel edit alone needs no asset-lock refresh. A complete publication
lock can also seal program bytes using --lock-scope=all; the
acquisition reference
defines both scopes. Portable bytecode still JITs for the selected target;
linking and packaging explains how to
produce it.
Both scripts have --help and accept --cache for reusing acquired assets.
They wrap existing installed commands, which agents can also invoke directly:
loom-fetch model/tiny-text/model.json --update-lock --all-variants --no-input
python -m loom.model.catalog --output=catalog.json --card=model/tiny-text/model.json=model/tiny-text/model.json
--all-variants refreshes one lock covering every declared selection without
creating an installation. The catalog command accepts repeated --card options.
Additional models can live in sibling directories; each owns its own card and
lock. The template's smoke checks example/tiny-text, not every future model
added to a catalog.
Upload and check the published copy¶
Replace YOUR_NAME/loom-models with a repository you own. Authenticate and
create the repository using the Hugging Face CLI:
hf auth login
hf repos create YOUR_NAME/loom-models
hf upload YOUR_NAME/loom-models . . --include="model/*" --include="catalog.json" --include="README.md" --include="AGENTS.md" --include="LICENSE" --include=".gitignore" --include="refresh.py" --include="smoke.py" --exclude="*/.loom-fetch.lock" --exclude="*/__pycache__/*"
The allowlist publishes the model and author tools without an installed model,
cache, virtual environment, or local log directory. The excluded file is a
local acquisition mutex, not model.json.lock. Large folder uploads can span
several commits, so share the catalog only after the upload and smoke check
complete. For updates to an already shared publication, upload and check a new
branch before sharing its release tag or commit.
Now exercise acquisition from the uploaded catalog:
This uses the same result check as the local smoke, but fetches the published
files through Hugging Face. It does not substitute local model files. Access
approval and credentials are handled by loom-fetch; --no-input keeps the
script from waiting for an interactive prompt.
For releases, use a tag or full repository commit in place of main in the
catalog URL. Fetch resolves a branch or tag once, then acquires relative cards,
locks, and programs at that commit. A branch changing during acquisition cannot
mix publication revisions. An offline fetch uses the cached snapshot; it does
not discover newer uploads.
Give users a catalog URL¶
Users can list the catalog without downloading model payloads:
loom-fetch --catalog=https://huggingface.co/YOUR_NAME/loom-models/resolve/main/catalog.json --list --json
Or select and install a specific preset without terminal interaction:
loom-fetch --catalog=https://huggingface.co/YOUR_NAME/loom-models/resolve/main/catalog.json --model=example/tiny-text --preset=default --output=./installed --no-input --json
loom-serve --device=task --pool_backing=fixed --model=./installed/model.json --listen=127.0.0.1:8080
The fetch result includes the installed card path and selected catalog
revision. Scripts use its exit status for success and its JSON for the result
or access/error diagnostic. A direct model.json URL also works when discovery
is unnecessary. The fetch-and-serve workflow
covers caches, materialization, gated checkpoints, and diagnosing failures.
Serving uses the acquired local files and needs no Hugging Face credential. Model programs are executable code; hashes identify bytes, not publisher trust. The sandboxing guide covers isolation.
Publish your own model¶
Replace the example's programs, tokenizer, and parameters with a working
model package, and give the card its own model ID.
Its README describes the model, supported devices, presets, provenance,
license, and output checks. AGENTS.md can continue routing agents to the Loom
website rather than copying these instructions into each repository.
A parameter file stored beside a card needs only its relative path. To reuse
an upstream checkpoint without uploading another copy, a card can name an
origin and refer to it from its parameter scope. These fragments belong in
origins and the selected variant's service respectively:
"parameters": {
"model": {
"files": [{
"path": "parameter/model.safetensors",
"origin": "@checkpoint/model.safetensors"
}]
}
}
Refresh resolves the upstream revision and records the acquired asset's identity. Fetch later uses that lock; it does not silently accept newer weights. The authored parameter keys, encodings, and layouts must match the preparation and kernel programs. Referencing a checkpoint does not port its architecture. Upstream licensing and access requirements still apply.