drafting.CLASS_DEFAULTS: one removable entry per set, read from the signals the confidence already reads (a CUDA card whose engine slots are under the last-but-one CONF_STEPS step).
IQ3_S: on P2003 the file cache makes the MTP faster than DFlash2 by 12-44% (RTX2 t4b). UD-IQ4_XS-v31: DFlash2 beats the MTP by about 6.5% (t8, 3 starts; DF-VAL forced-fast tuned 0.8 x1.037).
The v31 entry DEPENDS ON RTX2's FILE-TIER FIX (unbuffered reads) BEING IN THE SAME RELEASE; without it remove that entry.
Anything chosen by name wins. Resident CUDA, Strix, gfx1201, Arc and Metal entries and the conf tables are unchanged. The sm_86 support line reads the set: UD-IQ4_XS-v31 gets the existing
'faster on some kinds of text and slower on others' line, every other model keeps 'slower'.
(cherry picked from commit 42412d42ff835d6a66a78fbf6d119911908eda1b)
The SYCL 0.2.11 engine reads only bf16 selector codebooks, so Arc gets its own tuned file (qwen3.8-flash-next-dflash2.strata1.q4_0-bf16sel.pack, 522,458,112 bytes, own SHA-256 pin) through
SetDefault.pack. Only IQ3_XXS, the set measured on the A750 (tuned 0.6 x1.054, 3 of 3 rounds); other Arc sets keep the stock pack. SYCL never gets the selq4 file, CUDA / HIP / Metal never the
bf16sel one. NOTICE names the second file and no longer overclaims about the text.
(cherry picked from commit 6111c583b70e3c88a3d54039e13d76b19f15742d)
SET_DEFAULTS entries carry a card condition (tuned_applies: the CONF_STEPS first-step slots or the Spark's shared memory for CUDA, gfx1151 for HIP); no entry names a conf, so
conf_for / CONF_STEPS / BACKEND_CONF run as before and only the pack changes. Enabled only for the cells measured at the shipped conf (CUDA-resident IQ3_S and UD-IQ4_XS-v31, Strix IQ3_S, UD-Q4_K_XL, UD-IQ4_XS).
12 GB and 24 GB cards, several cards, gfx1201, other AMD and SYCL never fetch or use it. Fetch keeps tuned, then stock, then MTP; silent offline; feed backends are asked per start's backend.
(cherry picked from commit f096dcd750b5928ace6f9eca1e2936b9e35578d4)
SET_DEFAULTS is the one per-(backend, set) table (Metal only; IQ3_S stays on the MTP). Setup, strata launch and strata drafting fetch fetch the tuned pack through the signed feed
(pinned size and SHA-256, resumable, silent offline, the standard drafter and then the MTP as fallbacks). Apache-2.0 licence and the modified-by-Strata notice ship in
data/dflash2-tuned and are copied beside the file. The Metal 'not tested' line is replaced for these sets.
Conflicts in strata_cli/bench_facts.py (the redactor), three hunks: kept every side. The patterns stay QATUI's (the key and the names are matched as whole tokens, a hyphen next to the key does not hide it, the names are not touched inside a label the function wrote), each entry carries SECURE's third field (is a login or host name) for redact_document, and the host names come from socket.gethostname() and sysinfo.node() (LIFE), both marked as names.
On a PC whose login is an ordinary word ("user", "test", "admin") the whole-document pass turned status reasons and field names into <user>, and the report failed its own validation. Paths, addresses and the key are still replaced everywhere; the name rules apply to hardware, model and configuration text, error messages, engine options and request checks.
Conflict in strata_cli/bench_facts.py (the redaction helper): kept both sides' intent. The host name comes from sysinfo.node() (LIFE) and the key is redacted with usable_key(key), word=True, exact=True (SECURE).
'N settings could not be tried: not enough free memory' is the result message (and the Terminal's tuning line) only when some candidates were skipped for memory
in a result that otherwise keeps the current settings; the structured outcome is unchanged and values.not_tried carries the count. Owner decision 11-04.
limit.output, CLAUDE_CODE_MAX_OUTPUT_TOKENS and maxTokens are max(4096, context/8): 16384 at 128K, so OpenCode's compaction summary has room (the tested 32K server keeps
4096). The input limit and compaction point stay as tested. Rewriting a config keeps an output cap other than the 4096 older versions wrote. #4528: the documented
provider block is still accepted by OpenCode's schema (deprecated in favour of 'providers'); no change. Idea as in PR #4230, written here.
The engine's flag schema picks which options are valueless: on DeepSeek --mmap-experts on|off|auto keeps its word through derive_config, the one argument
precedence (arg_layers) and a second launch. Approach as in PR #5028, written here.
_drm_vendor_backend skips a make whose every card reports a small own memory (the 512 MiB carve-out of an APU) while another make has a card;
intel_arc_cards reads each entry on its own, takes card10 and up, and counts an unlisted Battlemage/Alchemist id as an Arc of the family's smallest memory.
The launcher's merge of the Arc beside other makes was already in place. Backend half as in PR #5184, written here.
Explicit launch values, then persisted overrides (user_args and hand edits to the launch config), then calibrated values (recorded by
engine calibrate --apply-result with the model and context they were measured for), then Auto. derive_config builds the argv once through
strata_control/arg_layers.py; explicit values go to user_args so the DFlash2 policy keeps them, and are not remembered when left out next time.
Failed stops are counted apart from stopped ones; the empty-list line is for zero targets only. No wording changes: the existing lines are reused.
Approach as in PR #4568.
running_launches binds prof before the try so a failed load uses this row's defaults; kept_key skips list rows that carry only an error
and keeps looking for a valid key. Approach as in PR #4562 and #4563; tests use real temporary profiles in both orders.
Approach from PRs #4500 (one redact_object call before validation) and #4599 (none is no key, whole word, own case). tools/strata_bench.py gets the same none rule and key matching.
The 8-character floor of #4599 is not taken: a short key is still removed where it stands alone.
- gpu_roles.describe(card_numbers=True) prints "GPU <n+1> (--gpu <n>)"; the two test_launch.py assertions are back on the old digits plus the hint. The Terminal has no translation catalog for this line.
- split_engine: the refusal sentence ends "has 7 GiB free)" when the free memory was read (the size, as before, when it was not).
- the desktop app asked `drafting plan` / `drafting fetch` before it unloads the running model, so its own engine counted as busy memory on a model switch and the plan could pick DFlash2 and fetch the 1.2 GB drafter. New flag --engines-unloading (hidden from --help), sent by native-control.mjs for a load that unloads the running instances (not for a model added beside them); same effect as Runner.card_probe. Logic only, no text.
- tests: python (drafting plan with and without the flag), node split-app.test.mjs (flag on the argv, a 2-card model switch, a model added beside).
- discovery.prepared_beside(gguf, data_dirs): after the models-folder walk it also looks in --data-dir and the remembered data folder for mtp/rt, the pack and the picture reader (setup writes them there); plan, download_plan and the own-files preview pass them. A model folder outside the data folder no longer asks for the 5.2 GB layer a second time.
- split_engine: Card.free_mib from the same nvidia-smi call (memory.free; AMD: the render node's vram_used), fit = min(size, free) - 700 MiB; busy cards get the layer split with DFlash2 and no draft-layer part. Runner.card_probe leaves free memory out while a server of this launch (same profile or port) is about to be stopped. Free cards decide as before.
- plan: the cards line prints the numbers --gpu takes and leaves out cards CUDA_VISIBLE_DEVICES (AMD: ROCR/HIP_VISIBLE_DEVICES) hides; the split probe respects the same variables when no card is named. Digits only.
- tests/terminal/test_fix3_0212.py (41 tests); launch_support.Home clears the visibility variables.
- drafting.blocked_by(named=True): only --pipeline-windows still blocks; Metal keeps the old rule (no per-request drafters there)
- apply/launcher/plan pass the choice; the all-cards split engine runs --draft dflash2 --draft-model PACK only for DFlash2 by name AND --split-engine on
- the split engine's own DFlash2 start line counts as "DFlash2 on"; a split run config with --draft dflash2 is left as it is
- app Drafting hint and Terminal --drafting help say it (owner-approved wording, English only)
- tests: terminal drafting/single/split-parallel, split engine, serve parallel, node parallel-default
`strata split-engine apply --config IN --out OUT` turns the run config the app built into the split engine's (same steps as strata launch: rule, strata-split-N beside the
engine, draft layer on disk, lanes 1..8 from "parallel"); nothing is written on a no. Shared helpers in split_engine.py (exe_finder, draft_layer_present, apply_run_config,
split_plan_line), used by the launcher too. `strata drafting plan` asks the rule with the choice in hand (a saved DFlash2 under an Auto on the screen is Auto), says split for
an explicit MTP as the Terminal does, and uses the Terminal's plan line; expected() refuses a conversation memory other than int8 as the start does. --no-split stays.
Tests: AppPlanEqualsTerminalPlan, AppStartsTheSplit replace AppDoesNotSplit; docs/SPLIT_ENGINE.md describes the app.
App: `strata drafting plan/fetch` gain --no-split, and every drafting call the host makes (control-runtime.mjs draftingPlan, draftingFetch) carries it, so Auto in the app on
2 NVIDIA / 4 R9700 cards is the layer split with DFlash2 alone, no draft layer is planned or fetched for the split, and the Models screen label and fit say DFlash2 again
(capabilities.dflash2Split stays false). The Terminal's plan is unchanged (split + MTP). The gguf_dir fix of installMtpLayer and the explicit-MTP path stay.
Lanes: split_config cuts the lanes to 1..8 (the engine refuses "--batch must be 1..8"): the AMD four-card default PARALLEL 32, a layer config's own --batch (IQ3_S on 4 R9700
gave 32 and fell back to the layer split) and a profile parallel above 8; serve/server.py parallel_args' split branch cuts the same.
Tests: tests/terminal/test_split_parallel.py (AppDoesNotSplit, LaneClamp), apps/host/tests/drafting.test.mjs.
App (apps/host): a plain Auto load (no choice carried, none saved but Auto) fetches the draft layer when `strata drafting plan` says mtp_needed and split,
the same as the Terminal; a Load that carries a choice is as before. probeDrafting reads the plan's split word (capabilities.dflash2Split); the install's drafter
(resolveDrafter) takes it too, so a new install on 2 cards leaves DFlash2 out and gets the MTP layer. drafting.ts / native-settings.mjs
resolveDrafter(choice, family, served, split): Auto is the MTP where the split takes the start, a DFlash2 the person chose stays; NativeModels.tsx passes it, so the
label and the fit use the MTP. `strata drafting plan` gains "split".
Launcher: when the server starts the normal layer split because the all-cards split engine would not come up (metrics engine.split_fallback), the final summary
replaces "Using the all-cards split engine on N cards" with "The all-cards split engine could not start (<the engine's own reason>); running the normal layer split."
Tests: apps/host/tests/drafting.test.mjs; tests/terminal/test_split_parallel.py (PlanTellsTheApp, SummaryTellsWhatRuns).
The split runs the model's draft layer (--mtp) and exits at start without it ("sfnx: --native and --mtp are required"). The plan and the fetch for Auto
resolved to DFlash2 (drafter 1.2 GB, no draft layer), so on 2 x sm_86/sm_120 or 4 x gfx1201 the split was chosen at start, failed, and the server fell back
to the layer split after "Using the all-cards split engine on 2 cards".
(B) strata_control/split_engine.expected(): the rule apply_to_config uses, asked before anything is on disk (model assumed when its file is not there yet).
Runner.split_expected / resolved_drafting and drafting_inputs: Auto where the split will take the start is the MTP, so download_plan and the fetch include the
draft layer (5.2 GB) and not DFlash2's drafter, setup gets --mtp on without --drafter dflash2, and the plan says "Drafting: MTP (the all-cards split engine uses
the MTP draft layer, 5.2 GB)". The app's `strata drafting plan/fetch` (drafting_cmd._inputs) follows the same rule. A person's own DFlash2 / off, --split-engine
off, one card, other cards, three cards keep what they had.
(A) Runner.apply_split_engine: when the --mtp folder is missing or empty at start the split is not picked (Auto: silently, the layer split with DFlash2 starts as
the plan said; "on": one line saying to add --drafting mtp). _auto_gates() is the Auto-only part of the rule, shared by apply_to_config and expected().
Tests: tests/terminal/test_split_parallel.py (Terminal and app plan paths, AMD 4 x gfx1201 and 2, one card, sm_89, own DFlash2, off, missing draft layer).
The split runs the model's draft layer (--mtp) and exits at start without it ("sfnx: --native and --mtp are required"). The plan and the fetch for Auto
resolved to DFlash2 (drafter 1.2 GB, no draft layer), so on 2 x sm_86/sm_120 or 4 x gfx1201 the split was chosen at start, failed, and the server fell back
to the layer split after "Using the all-cards split engine on 2 cards".
(B) strata_control/split_engine.expected(): the rule apply_to_config uses, asked before anything is on disk (model assumed when its file is not there yet).
Runner.split_expected / resolved_drafting and drafting_inputs: Auto where the split will take the start is the MTP, so download_plan and the fetch include the
draft layer (5.2 GB) and not DFlash2's drafter, setup gets --mtp on without --drafter dflash2, and the plan says "Drafting: MTP (the all-cards split engine uses
the MTP draft layer, 5.2 GB)". The app's `strata drafting plan/fetch` (drafting_cmd._inputs) follows the same rule. A person's own DFlash2 / off, --split-engine
off, one card, other cards, three cards keep what they had.
(A) Runner.apply_split_engine: when the --mtp folder is missing or empty at start the split is not picked (Auto: silently, the layer split with DFlash2 starts as
the plan said; "on": one line saying to add --drafting mtp). _auto_gates() is the Auto-only part of the rule, shared by apply_to_config and expected().
Tests: tests/terminal/test_split_parallel.py (Terminal and app plan paths, AMD 4 x gfx1201 and 2, one card, sm_89, own DFlash2, off, missing draft layer).
The split's run config always carries --batch N. ensure_profile still wrote the launch profile's parallel=<card fit> (4 on 32 GB or more) beside
it, and strata serve --profile (cli._effective) refuses a parallel override next to --batch: every 2-card NVIDIA start with the split on Auto
stopped with "parallel override conflicts with --batch/--slots in run config args" before the engine ran. Same for the AMD four-card default.
- runner.ensure_profile: no parallel override when the run config already names its slots (run_config_owns_slots)
- runner.apply_split_engine: the person's --parallel N is the split's lane count (cfg["parallel"] for the rule; taken out again on a refusal)
- cli._effective: a parallel override on the split's run config (split_engine_note) is not a conflict (the app's Concurrent requests); other configs keep the check
- server.parallel_args: "parallel" on the split's run config sets its --batch
- tests/terminal/test_split_parallel.py: Terminal path, app path, AMD four-card, lanes from the flag, the check kept for other configs