Repository navigation
[job] AMD launchers: one thinking switch and a serve-flag cleanup #146
Description
Status (2026-10-01 03:40Z)
- Kill switch verified on the 27B, strix (main be43587, DFlash2 gamma 8; jobs 123/125). With
--disable-thinking, these all return no reasoning:- OpenAI
enable_thinking:true; - OpenAI
reasoning_effort:"high"; - Anthropic
thinking:{type:enabled}.
The positive control on the same server without the switch returned 399 / 593 reasoning chars for those requests.
- OpenAI
- Linux switch done (local branch
launch/thinking-switch-linux@0bb0bedce, not pushed):THINKING=off|on ./serve-amd.sh. Verified on strix:off: no reasoning for any request.on: a silent request reasons; a per-requestenable_thinking:falsestill wins.- unset: unchanged.
- Windows switch implemented (local
launch/thinking-switch@ce4253a8d, on top of Strix Halo Windows: Flash-Next port on main + MoE prefill transpose (2k TTFT ~2x) (supersedes #54) #80's run-mode commits):serve-amd.ps1 -Thinking default|off|on, recorded in each recipe's fingerprint.- JSON quoting is picked per host: Windows PowerShell 5.1 / pwsh < 7.3 vs pwsh 7.3+ Standard argument passing.
- Windows smoke runs after the Strix Halo Windows: Flash-Next port on main + MoE prefill transpose (2k TTFT ~2x) (supersedes #54) #80 legs free winbox.
ssm-state-poisoning-gate: PASS, 12/12 replays byte-identical with prefix caching on (strix DFlash2 recipe, SSM 4 @ 512). The Windows recipes' larger SSM settings (24 @ 128, 64 @ 16) don't fit strix's 60 GB; they get tested on winbox.- Flag inventory posted below (step 3).
Why (Windows tester, 2026-09-30):
1. "Is there any way to disable thinking completely?"
The engine already has a kill switch: spark serve --disable-thinking forces thinking off for every request. It outranks per-request enable_thinking and reasoning_effort (crates/spark-server/src/api/chat/thinking.rs, test kill_switch_overrides_everything). The launchers don't agree on it:
| launcher mode | thinking today |
|---|---|
Windows 27B + MTP (first_run.ps1 -Phase serve) |
--disable-thinking hard-coded, so it can't be turned on |
Windows 27B + DFlash2 (win_serve_dflash2_nvfp4.ps1) |
--disable-thinking hard-coded |
Windows Flash-Next + MTP (win_serve_flashnext_nvfp4.ps1, #80) |
checkpoint default; DISABLE_THINKING=1 turns it off |
Linux serve-amd.sh |
requestable per request (MODEL.toml default off); --disable-thinking only as a pass-through arg |
Thinking also changes speed, not just quality: speculative decoding is gated off inside <think>.
2. Recipe flags users end up hand-editing.
The tester started from the DFlash2 recipe's command line and changed --gpu-memory-utilization 0.548 and --max-seq-len 65536 to get past OOM. They scored 80 on their Hermes-20 run, with thinking on and with it off, against 94 on ours. Nobody knows yet whether those edits explain the gap: the 94's serve fingerprint wasn't recorded.
The three Windows recipes disagree, with no measured reason:
--gpu-memory-utilization: 0.90 / 0.95 / 0.90;--ssm-cache-slots/--ssm-checkpoint-interval: 24 / 128 (DFlash2), 64 / 16 (MTP), 0 (Flash-Next);- prefix caching: on, on, off.
They also carry speed and dtype toggles (--kv-cache-dtype, --lm-head-dtype, --no-fast-load, --dflash-window-size 0, --max-prefill-tokens). The engine on top of that has ~500 ATLAS_* variables (#117).
Done bar:
- One thinking switch with the same meaning in every mode:
serve-amd.ps1 -Thinking on|offandserve-amd.shTHINKING=on|off. Off maps to--disable-thinking, and the setting goes into the serve fingerprint. Pick one default for all modes by measurement, and record it with the ST-995 run under it. - "Completely off" verified: OpenAI requests (
enable_thinking,reasoning_effort) and Anthropic requests (thinking.enabled) return no reasoning with the switch off. A positive control returns reasoning with it on. - No hand-tuned memory: the launcher derives
--gpu-memory-utilizationfrom the memory the GPU exposes and the recipe's measured pre-KV footprint. It refuses, printing the numbers, any configuration whose KV pool can't hold--max-seq-len, rather than booting a pool that starves long sessions. - Every speed/dtype/cache toggle in the recipes ends up in one of two places: the measured per-model default in MODEL.toml (the SSOT), or a documented diagnostic. Values that differ between the recipes without a measurement are unified.
- The tester gap reproduced on winbox: the tester's exact command vs the recipe, one flag at a time (util and seq first), on ST-995 and the agentic leg. Our 94 gets fingerprinted.
- Out of scope: lower-bit (2–3 bit) quants.
Plan:
- Strix job 122 (queued): the kill switch on both API surfaces, plus a positive control. Also the
ssm-state-poisoning-gateunder the DFlash2 recipe's SSM settings (24 @ 128) and the MTP recipe's (64 @ 16). - Launcher switch plus fingerprint field. Land it with or right after Strix Halo Windows: Flash-Next port on main + MoE prefill transpose (2k TTFT ~2x) (supersedes #54) #80.
- A flag inventory: a table of every recipe flag, what it changes, its measured evidence, and the proposed home. Then fold it into MODEL.toml or the launcher, one PR per class.
- Memory auto-sizing in the launchers, plus the refuse-with-numbers check.
- The tester-gap A/B on winbox once the Strix Halo Windows: Flash-Next port on main + MoE prefill transpose (2k TTFT ~2x) (supersedes #54) #80 perf leg frees it.
Activity
AzeezIsh commentedon Oct 1, 2026
Flag inventory for step 3 (research only; nothing changed yet). Sources: the three Windows recipes on #80's run-mode branch,
serve-amd.shon main plus the thinking switch, the tester's command line, and engine defaults fromserve_args.rs. Rows marked "launcher-derived" are platform sizing; "MODEL.toml default" rows are per-model behaviour to freeze; "diagnostic-only" rows stay flags and never defaults.MODEL(positional)$ModelDir$ModelDir$ModelDirnvidia/Qwen3.8-27B-NVFP4or$1--model-name$ModelName(envATLAS_MODEL_NAME)nvidia/Qwen3.8-27B-NVFP4nvidia/Qwen3.8-Flash-Next-NVFP4MODEL_NAMEenv if set_name_or_path(serve_args.rs:118-121)--host/--bind$BindHost(envATLAS_BIND, default 127.0.0.1; wildcard 0.0.0.0 refused)$BindHostparam/ATLAS_BIND(127.0.0.1)$BindHost(127.0.0.1, wildcard refused)HOSTenv (default 0.0.0.0)--port$Port/ATLAS_PORT(8081)$Port/ATLAS_PORT(8096)$Port(8095)PORTenv (8081)--no-fast-load--no-tui--max-seq-lenATLAS_MAX_SEQ_LEN(4096)SeqLen49152SEQ_LENenv (8192)MAX_SEQ_LENenv (4096)--max-prefill-tokensATLAS_MAX_PREFILL_TOKENSPREFILL_TOKENSenv (2048)MAX_PREFILL_TOKENSenv (2048)--gpu-memory-utilizationATLAS_GPU_UTIL(0.95)Util0.90 on main (0.80 in #80's pre-merge copy)ATLAS_UTILenv (0.90, 0.86 serial)GPU_UTILenv (0.88, 0.80 under DFLASH)--kv-cache-dtypeDEFAULT_KV_CACHE_DTYPE, serve_args.rs:25); MODEL.toml may override--lm-head-dtypedefault)LM_HEADenv (nvfp4; bf16 for unsloth)--max-batch-sizeMAX_BATCHenv (1)--max-num-seqs--vision-max-pixels--speculative+--num-draftsNUM_DRAFTSenv (3)--speculativeoff (:510); num_drafts MODEL.toml/engine fallback 1 (:16-21)--mtp-quantization--mtp-vocab--dflash+--draft-model$DraftDirDFLASH=1+DRAFT_MODELenv--dflash-gammaGamma8DFLASH_GAMMAenv (16 default)--dflash-window-size--disable-tool-grammartrue--ssm-cache-slotsSsmSlots24SSM_SLOTSenv (0)SSM_SLOTSenv (0)--ssm-checkpoint-intervalSsmInterval128SSM_CKPT_INTERVALenv (16)--enable-prefix-cachingPREFIX_CACHE=1--disable-thinking/--stupifyATLAS_THINKING)DISABLE_THINKING=1→ conditionalTHINKING=offopt-Thinking/THINKING) ✓ done--default-chat-template-kwargsononly)ononly)ononly)THINKING=on--request-timeout--dangerously-allow-unresolved-kernel-lookupsALLOW_FALLBACKSalways on--check-kernels--scheduling-policy--swap-space-gb,--tbt-deadline-ms,--oom-guard-mbATLAS_W4A16_VARIANT=v1ATLAS_W4A16_DP4A:-1exportATLAS_SSM_TAIL_MIDCHUNK=1ATLAS_MTP_GATE_REPROBE=64ATLAS_DFLASH_OPTION_B=1:-1ATLAS_DFLASH_CTX_WINDOW=$SeqLenATLAS_MTP_ACCEPT_DEBUG=1ATLAS_KV_EXTERNAL_RESERVE_GB=0ATLAS_QSA_VERIFY_ACTIVE:-1default onATLAS_NO_MTP_DRAFTER_CONTEXTFP8_DEQUANT/ATLAS_FP8_DEQUANT_*/ATLAS_GDN_BF16_WEIGHTSDFLASH/DRAFT_MODEL/DFLASH_GAMMA(env)GPU_UTIL/MAX_SEQ_LEN/MAX_PREFILL_TOKENS/SSM_SLOTS/SSM_CKPT_INTERVAL/LM_HEAD/HOST/PORT/MODEL_NAME/MAX_BATCH/NUM_DRAFTS(env)ATLAS_PORT/ATLAS_BIND/ATLAS_THINKING/ATLAS_UTIL/SEQ_LEN/PREFILL_TOKENS/SSM_SLOTS/SERIAL/PREFIX_CACHE/DISABLE_THINKING(env, Windows)Reading
sizing (memory, bind, port, slots) — belongs in the launcher scripts.
declared default for this model×quant (kv bf16, lm-head dtype, dflash
gamma/window, ssm ckpt interval, prefill tokens, request-timeout).
accept-debug, MTP ctx toggles.
--mtp-quantization bf16,--mtp-vocab 100000—passed explicitly but equal to engine defaults on every recipe.
AzeezIsh commentedon Oct 1, 2026
Why configurations crash the host instead of failing at startup (investigation for the memory item; two strix OOMs on 2026-10-01).
The KV budget is computed once, in
crates/spark-model/src/factory/build.rs:391-465:total × util − used_so_far − inference_reserve. Hereused_so_faris a self-relative measurement taken at that instant (build.rs:355-389), so anything allocated after it falls outside--gpu-memory-utilization.The 02:57Z strix boot (27B + DFlash2, ctx window 32768, 24 Marconi slots @ 128, util 0.80) logged 48.0 GB budget = 45.2 GB pre-KV + 2.8 GB KV. These allocations then landed outside that budget:
dflash_head/from_weights.rs:238-284load_dflash_weightsceil(ctx/16)+1blocks × 5 layersdflash_head/from_weights.rspaged_implimpl_a1_initmax_seq_len × 5 × hidden × 2dflash_head.rs:463-468(at request admission)That's roughly 6–7 GB on a box with nothing left, and the kernel OOM-killer rebooted it. On unified memory these allocations take physical RAM, so the util math never gets a chance to refuse.
Separately, the Marconi snapshot pool is about 151.5 MB per slot (
ssm_snapshot.rs:117-203). The checkpoint interval only sets how often a state is saved, not the slot size. The recipe comment saying the engine raises slots to covermax_seq_lenis stale:--ssm-cache-slotsflows through unmodified.preflight.rs:169reserves the pool on paper, which shrinks KV, but the allocation itself still runs against whatever physical memory is left.Proposed fix (smallest correct):
used_so_faris sampled. That's the same pattern the ctx-acc priming already uses atbuild.rs:254. The self-relative measurement then counts them, with no second copy of size formulas to drift.max_batch_sizesequences inpreflight.rs, next tossm_snapshot_bytes.kv_budget == 0bail (build.rs:437) fires with real numbers for any configuration that doesn't fit.total × util.AzeezIsh commentedon Oct 2, 2026
Memory item: Devin's KV-budget fix passed its strix validation (job 140, 2026-10-02 00:16–00:19Z). Posting from the job log because it hadn't been reported.
Branch
fix/kv-budget-uma-headroom@215e3e534(stacked onfix/kv-budget-counts-drafter; still local), strix-hip qwen3.8-27b nvfp4, bin3cc011eb:DFlash drafter does not fit: 47.0 GB used + 6.6 GB drafter (weights + KV pool + ctx-window …)So the class of host crash this issue describes (allocations landing outside
--gpu-memory-utilization) now becomes a startup refusal on the config that rebooted strix. Theteardown_errors=1 / sweep_fails=282in U-074/U-076 is #122's SSM-pool half; this branch doesn't include #148.Still open before it ships:
AzeezIsh commentedon Oct 2, 2026
#146 memory fix: the AMD Linux platform gate passed. That's ST-995 plus the 1007-turn replay, the full AGENTS.md suite this fix still owed.
Run: strix job 142, 2026-10-02 06:02–13:05Z, run dir
~/dp4a-ab/out/kvbudget-gate-20261002T0602Z. Branchfix/kv-budget-uma-headroom@215e3e534(mainbe435875c+ 6 commits, still local), bin3cc011eb,nvidia/Qwen3.8-27B-NVFP4, DFlash2 γ8. The recipes and references are the same ones the #156 gate used.run-1790935156817722493.json), 994/995 responses byte-identical to 073KV cache exhausted, 0 prefill errors, 0 faults, 0 OOM kills, clean teardowns.Still owed before this ships:
win_serve_dflash2_nvfp4.ps1.AzeezIsh commentedon Oct 5, 2026
GB10 boots of the KV-budget fix: outputs identical, but KV collapses on GB10. Do not merge as-is. Reiner job 695, 2026-10-04: main 4405bce vs main + this branch rebased (
eb493f3c4, local), job 659's recipes, util 0.88.--dflash --dflash-gamma 8)Next: fix the GB10 path (likely the headroom/drafter term should key on the platform's memory model, not on
unified memoryalone). Re-boot the three arms before this goes anywhere.Merge pull request #185 from Atlas-Inf/launch/thinking-switch-linux
AzeezIsh commentedon Oct 18, 2026
Status update (2026-10-18):
serve-amd.sh THINKING=off|onmerged via serve-amd.sh: THINKING=off|on switch (issue #146) #185 (0bb0bedce→ main). Both launcher families now have the same off|on meaning; engine kill switch verified across OpenAI/Anthropic/Responses surfaces.--disable-thinkingscored 76.28 overall / 69.76 normalized vs 83.92 / 82.93 default — ~7.6/~13 pt cliff on tool workloads → measured default for tool-facing recipes = thinking on (checkpoint default); off is a throughput-leg setting.Still open: flag-inventory fold into MODEL.toml, and the winbox legs (tester-gap A/B, Windows smoke) — winbox has been offline ~4 days.
serve-amd.sh: THINKING=off|on switch (issue Atlas-Inf#146)