Docs · Everyday use

Bring your own model

Give Nodeau a GGUF file of your own. It reads the header to work out what the model needs, hashes the bytes so the file is its own identity, and then measures and probes it on a real card before saying what it can do.

The whole flow#

Terminal
nodeau model import ./my-model.gguf --alias finance-model
nodeau model qualify finance-model
nodeau run finance-model

Or in one step:

Terminal
nodeau model import ./my-model.gguf --alias finance-model --qualify

Import#

Terminal
nodeau model import PATH --alias NAME [flags]

Import reads the file's header to work out what the model is — its architecture, the shape its KV cache depends on, its quantisation, whether it carries a chat template — hashes the bytes, copies them into the model cache, and registers the result under the name you choose.

What the bytes are is the identity#

A model is identified by the SHA-256 of its contents, not by its filename, the alias you give it, or where it came from.

  • Importing the same bytes twice costs no extra disk.
  • Importing different bytes under a name you have used before creates a **new artifact and says so**. It never silently repoints the old one, and the previous qualification evidence does not carry across — because it was evidence about different bytes.
Output
NOTE: "finance-model" previously pointed at different bytes. This is a NEW
artifact with its own identity; the previous qualification evidence no
longer applies and is not carried across.

Nothing in the file is executed#

A GGUF is data. Nodeau reads the header and stops, and the model runs on Nodeau's own pinned runtime. There is no trust_remote_code, no publisher script and no download hook. The tensor offset is discarded so nothing can be tempted to seek there, and every length declared in the file is treated as hostile until bounded.

Importing is not qualifying#

After an import, Nodeau knows what your file says about itself. It does not yet know what the model can actually do on your hardware. That is what qualification is for.

What you get back#

Output
alias         finance-model
digest        9f2c4e…
architecture  llama
quantisation  Q4_K_M
parameters    7.6B
max context   32768
chat template yes

What the file suggests it can do — these are HINTS, not proof:
  chat              the file carries a chat template
  embed             the architecture is an encoder

Hints come from metadata and are never evidence. Tools and structured output are never hinted at all: no key distinguishes a tool-trained model, and the runtime will apply a grammar to anything and produce valid nonsense.

Nothing is inferred from a model's name, family or id.

Flags#

FlagDefaultMeaning
--alias <name>requiredThe name you will type to run this model
--namespace, -nnodeau-devWhere to register it. Must be where its workloads run
--sha256 <digest>—The digest you expect. A mismatch refuses the import and copies nothing
--qualifyoffRun qualification immediately after importing
--probe <list>—Capabilities to try during qualification, beyond what the file suggests
--no-registeroffPlace and verify the weights on this machine only, without registering a model — for a worker that should be able to run a model the control plane registered
--cache-dir <path>/var/lib/nodeau/modelsModel cache directory
--jsonoffMachine-readable

--alias and --no-register cannot be used together.

What import cannot do#

GGUF onlyNo Safetensors, no PyTorch, no ONNX. There is no conversion step
One fileA split multi-part GGUF is not supported. Nodeau fetches and verifies one file against one SHA-256
No visionA vision model is two files — the weights and a multimodal projector — and Nodeau imports one. The model registers and serves text; image input is refused up front rather than started and broken later
No licence reviewNodeau did not choose your file and has not reviewed its licence. Custom models are listed separately from curated ones for exactly that reason
Nothing is uploadedYour file is copied from one directory to another on your own machine. It is not sent to Nodeau Cloud, its name is not reported, and Nodeau will never tell you to "re-download" it — because it never downloaded it

Import failure cases#

What happenedWhat Nodeau does
The file is not a GGUFRefused: magic mismatch, naming what it found instead
An unsupported GGUF container versionRefused, stating which versions this reader accepts
The header is truncated, or declares a length past the endRefused. Every length in the file is bounded before it is trusted
A metadata key appears twiceRefused
The path is not a regular fileRefused
--sha256 was given and does not matchRefused, and nothing is copied
Not enough free diskRefused before copying, with a margin
The file declares no shape Nodeau can sizeImported and intact. Admission will refuse to schedule it rather than invent a memory figure — a guess that is too low is an out-of-memory kill
A valid GGUF whose architecture the runtime does not implementImports cleanly, phase Unsupported. Your file is fine, and a later Nodeau with a newer runtime may well run it

The last two are worth reading twice. Unknown is not unsupported, and unsupported is not corrupt.


Qualification#

Terminal
nodeau model qualify finance-model [flags]

Nodeau starts the model, watches how much memory it really takes, exercises each capability with a probe designed to fail if the model cannot do it, cleans up, and records what it proved.

Loading is not qualifying, and HTTP 200 is not a capability#

Every probe asserts something a model without the capability would fail:

CapabilityWhat the probe asserts
chatNon-empty content first, then a coherent answer. A 200 with nothing in it is the failure this exists for
toolsA tool call whose arguments parse and reflect the question — it names the city you asked about
embedRelated texts really do score closer than unrelated ones: repeatable, finite, and not a constant vector
rerankThe ordering responds to the query
structured-outputA json_schema reply checked against the schema, because the runtime constrains sampling and does not post-validate
vision-inputTwo different images under a byte-identical prompt must give different answers

It will not waive safety on your behalf#

If the model does not fit under the ordinary arithmetic, the run reports that and stops. It will never quietly reduce Nodeau's safety margin to make a model fit — a qualifier that spent the margin would always succeed and prove nothing.

Accepting that risk is a decision only you can make, with --accept-estimate-risk or --spend-safety-reserve, spelled exactly as they are on nodeau run. A qualification run that used either records the fact permanently, and prediction, waived amount, which waivers were used and observed peak are four separate fields — so a number you chose is never printed as something Nodeau measured.

It uses free capacity#

Qualification never evicts a healthy workload. If your cards are busy, admission refuses and the run reports it rather than waiting for ever.

Flags#

FlagDefaultMeaning
--probe <list>what the model declaresWhich capabilities to probe
--task <task>chat, or the model's ownTask to qualify
--context-size <n>4096Context window to qualify at
--parallel <n>1Concurrent sequences to qualify at
--gpus <n>1Accelerators for this one workload
--dry-runoffPrint the plan and stop, without touching a GPU
--ready-timeout <d>8mBound on how long the runtime may take to start
--timeout <d>20mBound on the whole run
--namespace, -nnodeau-devNamespace the qualification workload runs in
--jsonoffMachine-readable

Outcomes#

Each model ends in one phase, and each capability gets its own result.

PhaseMeaning
ImportedThe bytes are verified and registered. Nothing is known about what they can do
InspectedThe header was read and a profile synthesised. Admission arithmetic is possible; the model has not been proven to run
QualifyingA qualification run owns this model right now
QualifiedEvery capability that was probed passed
PartialThe model runs, some probed capabilities passed and others did not. A first-class outcome
UnsupportedA valid artifact this build cannot serve. Not an error — your file is fine
FailedQualification ran and the model could not serve
DisabledTaken out of service by its owner. Evidence is kept
Capability resultMeaning
PassProbed, and the probe's own assertions held
FailProbed, and they did not
UntestedNot probed. The zero-information state, and never rendered as a pass
NotApplicableThe question does not arise for this model
UnsupportedThe runtime or platform cannot do it here

The evidence is keyed to an execution, not to a model#

A qualification record names the bytes, the runtime digest, the task, the context size, the parallelism, the cards and the schema version. Change any of those and the record stops describing what would happen.

Concretely: 4K-context evidence never claims 128K. Qualify again at the configuration you intend to run.

You should re-qualify when:

  • you change the context size or parallelism you intend to serve at;
  • you change the hardware — a different card, or a card moved between machines;
  • you re-import different bytes under the same alias (the evidence is dropped automatically, and Nodeau says so);
  • Nodeau's runtime changes in a release.

If a run is interrupted#

The model stays in whatever phase it had reached, and the workload is cleaned up. Run nodeau model qualify again — nothing is left holding a card.


Running an imported model#

Terminal
nodeau run finance-model
nodeau run finance-model --task embed --port 8081

Exactly like a curated model, and through the same admission engine. It is refused the same way and for the same reasons.

Terminal
nodeau model list             # your own models are listed separately
nodeau model info finance-model

A custom model is custom qualified, never "Nodeau curated". Different trust classes, listed separately, and the origin is stamped by the loader rather than declared by the file — so the claim cannot be forged, and a forgotten stamp reads as unknown rather than as curated.

Where a diagnosis points#

If Nodeau cannot run your model, the message says whose gap it is. "A gap in Nodeau's catalog" is true for a curated model and wrong for a file you supplied, and a remedy that sends you to fix the wrong thing costs you an afternoon.

Documentation for the current published build, the beta channel. Something here wrong or missing? Tell us — a report from a machine we have never seen is the most useful thing we get.