narwhal-profile¶
narwhal-profile --fleet PATH measures live engines into the fleet's profiles.path, refits TTFT from retained samples, or merges separately measured role mixes. Every mode writes a profile store and a sidecar at the same path with its suffix replaced by .samples.json.
Live sweeps bind each fit to the verified engine attestation when engine_contract is configured, or to the live process identity otherwise, and retain that evidence with the raw observations in the .samples.json sidecar.
Live sweeps replace existing outputs when --overwrite is supplied. Refits and merges require fresh output paths, and every mode rejects symlink destinations.
Selection, refitting, and output¶
| Option | Default | Contract |
|---|---|---|
--version |
Print the installed distribution version. | |
--format |
text |
Select json for versioned command results. |
--fleet PATH |
required | Fleet config JSON; defines engine membership for all three modes. |
--only IID |
all engines | Repeatable engine selector for live sweeps. |
--refit-samples PATH |
omitted | Refit TTFT from saved generation-bound samples while retaining decode fits. Requires --out and samples covering every fleet engine; exclusive with --only and --merge. |
--merge PATH |
omitted | Repeat at least twice to combine measured profile stores and their matching sidecars. Requires --out; exclusive with --refit-samples, --only and --overwrite. |
--out PATH |
omitted | Fresh profile destination required for --refit-samples and --merge, with a matching .samples.json sidecar. Live sweeps use profiles.path. |
--limits PATH |
requested concurrency points | Generated per-engine max_num_seqs limits applied to live decode cohorts. |
--overwrite |
false | Replace live profile and sample files when the first engine completes; with --only, the new store contains the selected profiles. Refits always require fresh outputs. |
Refits retain the raw samples and process-generation evidence in the new sidecar. Merges require matching measurement evidence for every input profile and coverage of every configured engine; each engine, GPU group, role split and target-role variant must occur once. The merged sidecar records the source profile and sample paths with their SHA-256 hashes, so retain those source files.
narwhal-profile --fleet fleet.json
narwhal-profile --fleet fleet.json --refit-samples profiles.samples.json --out refitted.json
narwhal-profile --fleet fleet.json --merge split-1.json --merge split-2.json --out combined.json
Prefill and decode sweeps¶
These options apply to live measurement. The command validates supplied sweep values before selecting a mode; refits use the retained samples and merges use the source stores.
| Option | Default | Contract |
|---|---|---|
--prefill-lens LIST |
256,512,1024,2048,4096,8192,12288,16384 |
Comma-separated candidate lengths. The profiler keeps points within each engine's live max_model_len and requires at least three distinct usable values. |
--decode-input-lens LIST |
512,4096,8192 |
Comma-separated prompt lengths for the decode sweep. Requires at least two distinct values. |
--decode-concurrency LIST |
1,4,16,48 |
Candidate stream counts. With --limits, the profiler keeps points within each engine's limit and adds that limit as a point when a candidate exceeds it. At least two distinct usable values are required. |
--decode-tokens N |
64 |
Tokens per decode stream. Minimum 3. Larger cohorts may require more tokens to overlap. |
--prefill-repeats N |
3 |
Repetitions per prefill length. The fit uses each length's median and retains every raw timing. Minimum 3. |
--decode-repeats N |
1 |
Repetitions per decode input-length/concurrency point. Minimum 1. |
Shared-GPU neighbour traffic¶
--colocated loads the other engines in each target's shared_device.group according to their configured roles. Supply all five neighbour options with finite positive rates and positive integer token counts. Each neighbour's tokenised input plus output must fit its live max_model_len.
| Option | Default | Contract |
|---|---|---|
--colocated |
false | Measure each target with traffic on peers in its shared GPU group; requires all five neighbour options. |
--neighbour-prefill-rps RATE |
required with --colocated |
Offered requests per second per prefill neighbour. |
--neighbour-decode-rps RATE |
required with --colocated |
Offered requests per second per decode neighbour. |
--neighbour-prefill-tokens N |
required with --colocated |
Input tokens per prefill neighbour request; each requests one output token. |
--neighbour-decode-input-tokens N |
required with --colocated |
Input tokens per decode neighbour request. |
--neighbour-decode-output-tokens N |
required with --colocated |
Output tokens per decode neighbour request. |
narwhal-profile --fleet fleet.json --colocated \
--neighbour-prefill-rps 0.5 --neighbour-decode-rps 0.25 \
--neighbour-prefill-tokens 512 --neighbour-decode-input-tokens 128 \
--neighbour-decode-output-tokens 32
Profiling sweep stop conditions¶
Before each completion, the profiler verifies that the actual tokenised input plus the requested output fits the engine.
With --colocated, every neighbour must complete requests during the target's
measurement interval. The sample sidecar records each neighbour's role,
completion count, achieved rate and errors. A stalled or failed neighbour
rejects that profile's measured role mix.
A profiling run aborts when any of these conditions occurs:
- the
--onlyselection matches zero configured engines; /healthfails its HTTP 200 check;- the
/tokenizeresponse failsmax_model_lenvalidation; - engine limits leave fewer than three prefill lengths, two decode input lengths, or two decode concurrency levels;
- the representative prefill fit exceeds 20% mean error;
- the representative prefill fit exceeds 50% worst-point error.
A completed sweep prints wrote N profile(s) to PATH; a refit prints refitted N profile(s) to PATH; a merge prints merged N measured profiles to PATH.