mirror of
https://github.com/Niko1221/Strata.git
synced 2026-11-07 14:21:06 -10:00
Auto picks DFlash2 for Unsloth's quantizations of Qwen3.8-Flash-Next
DF2-METAL found that SUPPORTED_FAMILIES and the model-name pattern left Unsloth out, so UD-Q4_K_XL and UD-IQ4_XS (the same Qwen3.8-Flash-Next weights, and the case the
DFlash2 numbers on Strix, R9700 and M5 Max were measured on) started the MTP everywhere.
- strata_control/drafting.py: "unsloth" is a supported family; the name pattern also matches qwen3.8-flash-next-unsloth-<model> (what setup.py and metal/setup_mac.py write:
f"{family name}-{model.lower()}"). Swift (UkisAI's fine-tune), Coder (ISTA-DASLab's coding version) and NVFP4 stay on the MTP. The stale "Unsloth" in the "another model"
comment is gone.
- The app's two copies of the rule follow (apps/host/server/native-settings.mjs, src/lib/drafting.ts): the Drafting dropdown and the memory estimate treat Unsloth like Qwen.
- Tests: Unsloth names on cuda, hip, metal and sycl resolve to DFlash2 alone with the vocabulary; Swift, Coder and NVFP4 names stay MTP with their arguments untouched; the names
are read from setup.py and metal/setup_mac.py; the terminal flow gets the Drafting step for Unsloth; tests/drafting.test.mjs.
This commit is contained in:
1 parent
3342e06444
commit
d55138e95a
6 files changed
+122
-18
No files matched your search
@@ -87,9 +87,9 @@ export function setSpeedSwitch(env,id,on){
|
||||
export function speedSwitchRows(env,context){return SPEED_SWITCHES.filter(s=>speedSwitchApplies(s.id,context)).map(s=>({...s,on:speedSwitchIsOn(env,s.id)}));}
|
||||
/** Settings the app itself applies when it starts a model (they are not read from the engine's source, so the engine's text never says it supports them). */
|
||||
export const APP_OWNED_FIELDS=['mtp','batchMtp','drafting','ds_experts'];
|
||||
/** The families that have a Drafting choice and the model names the DFlash2 drafter was made for (strata_control/drafting.py SUPPORTED_FAMILIES, _SUPPORTED_NAME). */
|
||||
export const DRAFTING_FAMILIES=['qwen','gyro'];
|
||||
const DFLASH2_MODEL=/^qwen3\.8-flash-next(-gyro-[a-z0-9._-]+|-(q|iq|tq)\d[a-z0-9_.]*)?$/i;
|
||||
/** The families that have a Drafting choice and the model names the DFlash2 drafter was made for (strata_control/drafting.py SUPPORTED_FAMILIES, _SUPPORTED_NAME): Qwen3.8-Flash-Next, Gyro and Unsloth's quantizations of the same weights; not Swift, Coder or NVFP4. */
|
||||
export const DRAFTING_FAMILIES=['qwen','gyro','unsloth'];
|
||||
const DFLASH2_MODEL=/^qwen3\.8-flash-next(-gyro-[a-z0-9._-]+|-unsloth-[a-z0-9._-]+|-(q|iq|tq)\d[a-z0-9_.]*)?$/i;
|
||||
/** The drafter a choice means (one per run; strata_control/drafting.py choice_of): Auto is DFlash2 where the engine has it (`served`, Control's word) and the model is one it was made for, else the MTP; off and mtp are what they say. `model` is a run config's model name or a family. */
|
||||
export function resolveDrafter(choice,model,served){
|
||||
const c=String(choice??'auto').toLowerCase();if(c==='off'||c==='mtp')return c;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* The Drafting choice the Models screen offers for a model. It exists only where there is something to choose: DFlash2 is for Qwen3.8-Flash-Next
|
||||
* only (the qwen and gyro families), and only while this computer's engine can run it: strata_control/drafting.py hardware_support (Control reports it as
|
||||
* only (the qwen, gyro and unsloth families: Qwen3.8-Flash-Next, its Gyro build and Unsloth's quantizations of the same weights), and only while this computer's engine can run it: strata_control/drafting.py hardware_support (Control reports it as
|
||||
* `capabilities.dflash2`; Metal and Intel engines and PCs without a supported card have none). Every other model has no dropdown at all: DeepSeek has no
|
||||
* MTP (its own DSpark drafter is chosen by the engine), and the other families have the MTP and nothing to pick against it (Settings > Draft layer turns it off).
|
||||
*/
|
||||
export const DRAFTING_FAMILIES = ['qwen', 'gyro'];
|
||||
export const DRAFTING_FAMILIES = ['qwen', 'gyro', 'unsloth'];
|
||||
|
||||
/** The drafter a choice means for a family (one per run; strata_control/drafting.py choice_of): Auto is DFlash2 where the engine has it (`served`) and the family is one it was made for, else the MTP. */
|
||||
export function resolveDrafter(choice: string | null | undefined, family: string | null | undefined, served: boolean | null | undefined): 'dflash2' | 'mtp' | 'off' {
|
||||
|
||||
@@ -109,13 +109,13 @@ test('every sentence of the Drafting choice is in the catalog in all nine langua
|
||||
}
|
||||
});
|
||||
|
||||
test('the Drafting dropdown exists only where there is something to choose: Qwen3.8-Flash-Next (qwen, gyro) on a computer whose engine can run DFlash2', async () => {
|
||||
test('the Drafting dropdown exists only where there is something to choose: Qwen3.8-Flash-Next (qwen, gyro, unsloth) on a computer whose engine can run DFlash2', async () => {
|
||||
const { transform } = await import('esbuild');
|
||||
const code = (await transform(read('../src/lib/drafting.ts'), { loader: 'ts', format: 'esm' })).code;
|
||||
const { draftingChoices } = await import(`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`);
|
||||
const all = ['auto', 'mtp', 'dflash2', 'off'];
|
||||
// the engine here cannot run it (Metal, Intel, no card), or Control has not answered yet: no dropdown for anyone
|
||||
for (const family of ['qwen', 'gyro', 'coder', 'swift', 'deepseek41', undefined]) {
|
||||
for (const family of ['qwen', 'gyro', 'unsloth', 'coder', 'swift', 'deepseek41', undefined]) {
|
||||
assert.equal(draftingChoices(family, false), null, `${family}, not served`);
|
||||
assert.equal(draftingChoices(family, undefined), null, `${family}, Control has not answered`);
|
||||
assert.equal(draftingChoices(family, null), null);
|
||||
@@ -123,7 +123,8 @@ test('the Drafting dropdown exists only where there is something to choose: Qwen
|
||||
// it can: only the models it is for. DeepSeek has no MTP (its DSpark drafter is chosen by the engine); the other families have the MTP and nothing to pick against it.
|
||||
assert.deepEqual(draftingChoices('qwen', true), all);
|
||||
assert.deepEqual(draftingChoices('gyro', true), all);
|
||||
for (const family of ['coder', 'swift', 'unsloth', 'nvfp4', 'qwen36', 'deepseek41', undefined]) assert.equal(draftingChoices(family, true), null, `${family}, served`);
|
||||
assert.deepEqual(draftingChoices('unsloth', true), all, "Unsloth's quantizations are the same weights (DFlash2 measured on UD-Q4_K_XL)");
|
||||
for (const family of ['coder', 'swift', 'nvfp4', 'qwen36', 'deepseek41', undefined]) assert.equal(draftingChoices(family, true), null, `${family}, served`);
|
||||
// the app learns it from Control, once, and false until Control answers
|
||||
const host = read('../server/native-control.mjs');
|
||||
assert.match(host, /dflash2:dflash2Served===true,dflash2Support\}/);
|
||||
@@ -163,12 +164,17 @@ test('one drafter per run: Auto is DFlash2 where the engine has it, the same wor
|
||||
const code = (await transform(read('../src/lib/drafting.ts'), { loader: 'ts', format: 'esm' })).code;
|
||||
const ts = await import(`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`);
|
||||
const host = await import('../server/native-settings.mjs');
|
||||
for (const [choice, family, served] of [['auto', 'qwen', true], [undefined, 'gyro', true], ['auto', 'qwen', false], ['auto', 'coder', true], ['mtp', 'qwen', true], ['dflash2', 'qwen', true], ['off', 'qwen', true], ['dflash2', 'coder', true]]) {
|
||||
for (const [choice, family, served] of [['auto', 'qwen', true], [undefined, 'gyro', true], ['auto', 'unsloth', true], ['auto', 'swift', true], ['auto', 'nvfp4', true], ['auto', 'qwen', false], ['auto', 'coder', true], ['mtp', 'qwen', true], ['dflash2', 'qwen', true], ['off', 'qwen', true], ['dflash2', 'coder', true]]) {
|
||||
assert.equal(ts.resolveDrafter(choice, family, served), host.resolveDrafter(choice, family, served), `${choice} ${family} ${served}`);
|
||||
}
|
||||
assert.equal(ts.resolveDrafter('auto', 'qwen', true), 'dflash2');
|
||||
assert.equal(ts.resolveDrafter('auto', 'qwen', null), 'mtp', 'Control has not answered: the MTP');
|
||||
assert.equal(host.resolveDrafter('auto', 'Qwen3.8-Flash-Next-iq3_s', true), 'dflash2', 'a run config model name works too');
|
||||
// the names setup.py writes (f"{family name}-{model.lower()}"): Unsloth's quantizations are DFlash2's; Swift, Coder and NVFP4 are not
|
||||
for (const name of ['qwen3.8-flash-next-unsloth-ud-q4_k_xl', 'qwen3.8-flash-next-unsloth-ud-iq4_xs', 'qwen3.8-flash-next-unsloth-q8_0', 'qwen3.8-flash-next-gyro-gyro-s']) assert.equal(host.resolveDrafter('auto', name, true), 'dflash2', name);
|
||||
for (const name of ['qwen3.8-flash-next-coder-iq1_m', 'qwen3.8-flash-next-nvfp4-nvfp4', 'swift-1.5-iq2_xs', 'qwen3.8-flash-next-unsloth', 'qwen3.6-35b-a3b-ud-q4_k_xl']) assert.equal(host.resolveDrafter('auto', name, true), 'mtp', name);
|
||||
assert.equal(ts.resolveDrafter('auto', 'unsloth', true), 'dflash2');
|
||||
assert.equal(host.resolveDrafter('auto', 'unsloth', true), 'dflash2');
|
||||
});
|
||||
|
||||
test('a new install fetches only the drafter it will use; the fit and the slot estimates use the drafter chosen', async () => {
|
||||
|
||||
@@ -9,11 +9,11 @@ strata_control/draft_layer.py), so a setup run that rewrites the engine argument
|
||||
``--draft dflash2``) starts with the one chosen.
|
||||
|
||||
dflash2 ``--draft dflash2 --draft-model <pack> --draft-fallback none --mtp-draft-vocab <file> --spec 6 --draft-conf 0.35`` and no ``--mtp``: the DFlash2
|
||||
block drafter (incoai/Qwen3.8-Flash-Next-DFlash2, Q4_0 pack) for Qwen3.8-Flash-Next and Gyro, with the window and confidence that measured best
|
||||
block drafter (incoai/Qwen3.8-Flash-Next-DFlash2, Q4_0 pack) for Qwen3.8-Flash-Next, Gyro and Unsloth's quantizations, with the window and confidence that measured best
|
||||
(RESULTS-DRAFT.md section 4); a ``--spec`` or ``--draft-conf`` the person set by hand (``user_args``) stays
|
||||
mtp the model's own draft layer (``--mtp <folder>``) and none of the DFlash2 flags
|
||||
off no draft layer and no DFlash2 (the same as ``"mtp": false``: the engine still looks ahead in the text with ``--spec``)
|
||||
auto DFlash2 wherever the engine has it (DFLASH2_BACKENDS) and the model is Qwen3.8-Flash-Next or Gyro, the MTP everywhere else
|
||||
auto DFlash2 wherever the engine has it (DFLASH2_BACKENDS) and the model is Qwen3.8-Flash-Next, Gyro or an Unsloth quantization, the MTP everywhere else
|
||||
|
||||
Recommend, never force: a choice that cannot be applied (DFlash2 in a layer split or with several requests at once, no drafter file yet) does not stop the
|
||||
start. The other drafter runs if it is on this computer, else none, and ``Decision.note`` says why in one short line. Nothing is loaded twice and the
|
||||
@@ -227,9 +227,14 @@ SLOT_BASE_MIB = 3800 # dense weights and the engine's fixed buffers beyo
|
||||
SLOT_RESERVE_MIB = 700 # the engine's default --vram-reserve-mib
|
||||
DEFAULT_CONTEXT = 131072 # --max-context when the arguments name none (the 128K default)
|
||||
|
||||
#: model families (strata launch --family) the drafter was trained for and measured on: Qwen3.8-Flash-Next and its Gyro build.
|
||||
SUPPORTED_FAMILIES = ("qwen", "gyro")
|
||||
_SUPPORTED_NAME = re.compile(r"^qwen3\.8-flash-next(-gyro-[a-z0-9._-]+|-(q|iq|tq)\d[a-z0-9_.]*)?$", re.IGNORECASE)
|
||||
#: model families (strata launch --family) the drafter was trained for and measured on: Qwen3.8-Flash-Next, its Gyro build and Unsloth's quantizations of the same weights
|
||||
#: (UD-IQ4_XS, UD-Q4_K_XL...; DFlash2 numbers measured on UD-Q4_K_XL on Strix, R9700 and M5 Max). Not Swift (UkisAI's fine-tune), Coder (ISTA-DASLab's coding version) or NVFP4:
|
||||
#: no DFlash2 acceptance numbers for them, they start the MTP.
|
||||
SUPPORTED_FAMILIES = ("qwen", "gyro", "unsloth")
|
||||
#: The model_name setup.py (and metal/setup_mac.py) write: f"{family name}-{model.lower()}": qwen3.8-flash-next-iq3_s, qwen3.8-flash-next-gyro-gyro-s,
|
||||
#: qwen3.8-flash-next-unsloth-ud-q4_k_xl. (Coder is qwen3.8-flash-next-coder-iq1_m, NVFP4 qwen3.8-flash-next-nvfp4-nvfp4: neither matches.) Mirrored in
|
||||
#: apps/host/server/native-settings.mjs; tests/drafting.test.mjs keeps the two the same.
|
||||
_SUPPORTED_NAME = re.compile(r"^qwen3\.8-flash-next(-gyro-[a-z0-9._-]+|-unsloth-[a-z0-9._-]+|-(q|iq|tq)\d[a-z0-9_.]*)?$", re.IGNORECASE)
|
||||
|
||||
|
||||
def supported_model(model_name: str | None = None, family: str | None = None) -> bool:
|
||||
@@ -621,7 +626,7 @@ def apply(cfg: dict[str, Any], *, klass: str = "other", data_dir: str | Path | N
|
||||
`engine` is the engine program that will start (None: not known, the usual flags): an engine that only takes `--mtp DIR` for the vocabulary gets that
|
||||
(still without the MTP layer), and an engine without `--draft-fallback` gets no DFlash2 flag at all (the MTP, said in one line)."""
|
||||
args = [str(a) for a in cfg.get("args") or []]
|
||||
if not supported_model(cfg.get("model_name"), family): # another model: its drafting is not this choice's business (DeepSeek, Swift, Coder, Qwen3.6, Unsloth...)
|
||||
if not supported_model(cfg.get("model_name"), family): # another model: its drafting is not this choice's business (DeepSeek, Swift, Coder, NVFP4, Qwen3.6...)
|
||||
asked = normalize(cfg.get("drafting"))
|
||||
if asked == "dflash2":
|
||||
cfg["args"] = strip_draft_flags(args)
|
||||
|
||||
@@ -43,11 +43,11 @@ class AutoAndTheBackends(unittest.TestCase):
|
||||
"""Owner 2026-11-02: DFlash2 is the primary drafter on every system whose engine has it (CUDA, HIP, Metal, Intel SYCL since the DF2-SYCL engine)."""
|
||||
self.assertEqual(drafting.DFLASH2_BACKENDS, ("cuda", "hip", "metal", "sycl"))
|
||||
for backend in ("cuda", "hip", "metal", "sycl"):
|
||||
for family in ("qwen", "gyro"):
|
||||
for family in ("qwen", "gyro", "unsloth"):
|
||||
self.assertEqual(drafting.choice_of("auto", family=family, backend=backend), "dflash2", (backend, family))
|
||||
self.assertEqual(drafting.choice_of("auto", family="qwen", backend=None), "mtp", "an unknown computer is the MTP")
|
||||
self.assertEqual(drafting.choice_of("auto", family="qwen", backend="cpu"), "mtp", "an engine without the code is the MTP")
|
||||
for family in ("coder", "swift", "unsloth", "nvfp4", "deepseek41"):
|
||||
for family in ("coder", "swift", "nvfp4", "deepseek41"):
|
||||
self.assertEqual(drafting.choice_of("auto", family=family, backend="cuda"), "mtp", family)
|
||||
|
||||
def test_intel_runs_dflash2_and_a_build_without_the_code_does_not(self):
|
||||
@@ -369,6 +369,98 @@ class EngineArguments(unittest.TestCase):
|
||||
self.assertIn('o.draft_fallback != "mtp"', src)
|
||||
|
||||
|
||||
class UnslothAndTheOtherFlashNextFiles(unittest.TestCase):
|
||||
"""DF2-METAL found that Auto never picked DFlash2 for Unsloth's quantizations: they are the same Qwen3.8-Flash-Next weights and the DFlash2 numbers (Strix, R9700,
|
||||
M5 Max) were measured on UD-Q4_K_XL. Swift (UkisAI's fine-tune) and Coder (ISTA-DASLab's coding version) are fine-tunes with no acceptance numbers: the MTP.
|
||||
The names are the ones setup.py and metal/setup_mac.py write: f"{family name}-{model.lower()}"."""
|
||||
|
||||
UNSLOTH = ("qwen3.8-flash-next-unsloth-ud-q4_k_xl", "qwen3.8-flash-next-unsloth-ud-iq4_xs", "qwen3.8-flash-next-unsloth-ud-q5_k_xl",
|
||||
"qwen3.8-flash-next-unsloth-ud-q6_k_xl", "qwen3.8-flash-next-unsloth-q8_0")
|
||||
FLASH_NEXT = ("qwen3.8-flash-next", "qwen3.8-flash-next-q2_0", "qwen3.8-flash-next-iq2_xs", "qwen3.8-flash-next-iq3_xxs", "qwen3.8-flash-next-iq3_s",
|
||||
"qwen3.8-flash-next-gyro-gyro-s", "qwen3.8-flash-next-gyro-gyro-m")
|
||||
OTHERS = ("qwen3.8-flash-next-coder-iq1_m", "qwen3.8-flash-next-nvfp4-nvfp4", "qwen3.8-flash-next-nvfp4-nvfp4-nvidia", "qwen3.8-flash-next-nvfp4-nvfp4-qad",
|
||||
"swift-1.5-iq2_xs", "swift-1.5-q4_0", "qwen3.6-35b-a3b-ud-q4_k_xl", "deepseek-v4.1-flash", "qwen3.8-flash-next-unsloth", "qwen3.8-flash-next-unslothx-q8_0")
|
||||
HARDWARE = (("cuda", ["sm_120"]), ("hip", ["gfx1151"]), ("metal", None), ("sycl", ["8086"]))
|
||||
|
||||
def test_the_names_the_setups_write(self):
|
||||
for name in self.UNSLOTH + self.FLASH_NEXT:
|
||||
self.assertTrue(drafting.supported_model(name), name)
|
||||
self.assertTrue(drafting.supported_model(name.upper()), name.upper())
|
||||
for name in self.OTHERS:
|
||||
self.assertFalse(drafting.supported_model(name), name)
|
||||
self.assertTrue(drafting.supported_model(None, "unsloth"))
|
||||
for family in ("swift", "coder", "nvfp4", "qwen36", "deepseek41"):
|
||||
self.assertFalse(drafting.supported_model(None, family), family)
|
||||
self.assertEqual(drafting.SUPPORTED_FAMILIES, ("qwen", "gyro", "unsloth"))
|
||||
|
||||
def test_the_names_are_the_ones_setup_writes(self):
|
||||
"""Read from the code, not from memory: the family names and the way setup.py and metal/setup_mac.py make the run config's model_name."""
|
||||
setup = (ROOT / "setup.py").read_text(encoding="utf-8")
|
||||
mac = (ROOT / "metal" / "setup_mac.py").read_text(encoding="utf-8")
|
||||
self.assertIn('"name": "qwen3.8-flash-next-unsloth"', setup)
|
||||
self.assertIn('"name": "qwen3.8-flash-next-coder"', setup)
|
||||
self.assertIn('"name": "qwen3.8-flash-next-nvfp4"', setup)
|
||||
self.assertGreaterEqual(setup.count("\"model_name\": f\"{fam['name']}-{model.lower()}\""), 3)
|
||||
self.assertIn("f\"{fam['name']}-{model.lower()}\"", mac)
|
||||
for model in ("UD-IQ4_XS", "UD-Q4_K_XL", "UD-Q5_K_XL", "UD-Q6_K_XL", "Q8_0"):
|
||||
self.assertIn(f'"{model}": {{"about"', setup)
|
||||
self.assertTrue(drafting.supported_model(f"qwen3.8-flash-next-unsloth-{model.lower()}"), model)
|
||||
|
||||
def run_config(self, name, tmp, mode=None):
|
||||
data = Path(tmp)
|
||||
mtp = data / "mtp" / "rt"
|
||||
mtp.mkdir(parents=True)
|
||||
(mtp / "experts.bin").write_bytes(b"e")
|
||||
(mtp / "draft_vocab.bin").write_bytes(b"v")
|
||||
pack = drafting.pack_path(data)
|
||||
pack.parent.mkdir(parents=True)
|
||||
pack.write_bytes(b"x" * (2 << 20))
|
||||
args = ["--pack", str(data / "packs" / "x"), "--native", "/d/m.gguf", "--mtp", str(mtp), "--spec", "4", "--spec-min-p", "0.5"]
|
||||
cfg = {"model_name": name, "args": args, **({} if mode is None else {"drafting": mode})}
|
||||
return cfg, data, mtp
|
||||
|
||||
def test_unsloth_resolves_to_dflash2_alone_with_the_vocabulary_on_every_backend(self):
|
||||
for backend, archs in self.HARDWARE:
|
||||
for name in self.UNSLOTH:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
cfg, data, mtp = self.run_config(name, tmp)
|
||||
decision = drafting.apply(cfg, data_dir=data, backend=backend, archs=archs)
|
||||
args = cfg["args"]
|
||||
self.assertEqual((decision.drafter, decision.note), ("dflash2", ""), (backend, name))
|
||||
self.assertEqual(args[args.index("--draft") + 1], "dflash2")
|
||||
self.assertEqual(args[args.index("--draft-fallback") + 1], "none")
|
||||
self.assertEqual(args[args.index("--mtp-draft-vocab") + 1], str(mtp / "draft_vocab.bin"), "the vocabulary the engine needs")
|
||||
for flag in ("--mtp", "--spec-min-p"):
|
||||
self.assertNotIn(flag, args, (backend, name, flag))
|
||||
self.assertEqual(args[args.index("--spec") + 1], "6")
|
||||
|
||||
def test_swift_coder_and_nvfp4_stay_on_the_mtp(self):
|
||||
for backend, archs in self.HARDWARE:
|
||||
for name in ("qwen3.8-flash-next-coder-iq1_m", "qwen3.8-flash-next-nvfp4-nvfp4", "swift-1.5-iq2_xs"):
|
||||
for mode in (None, "auto", "dflash2"):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
cfg, data, mtp = self.run_config(name, tmp, mode)
|
||||
original = list(cfg["args"])
|
||||
decision = drafting.apply(cfg, data_dir=data, backend=backend, archs=archs)
|
||||
self.assertEqual(decision.drafter, "mtp", (backend, name, mode))
|
||||
self.assertEqual(cfg["args"], original, "its own MTP arguments, untouched")
|
||||
self.assertNotIn("--draft", cfg["args"])
|
||||
if mode == "dflash2":
|
||||
self.assertEqual(decision.note, drafting.NOT_SUPPORTED)
|
||||
|
||||
def test_by_family_the_terminal_and_the_app_agree(self):
|
||||
for backend, _ in self.HARDWARE:
|
||||
self.assertEqual(drafting.choice_of("auto", family="unsloth", backend=backend), "dflash2", backend)
|
||||
for family in ("swift", "coder", "nvfp4"):
|
||||
self.assertEqual(drafting.choice_of("auto", family=family, backend=backend), "mtp", (backend, family))
|
||||
# the app's own copies of the rule (the host and the page) name the same families and the same names
|
||||
host = (ROOT / "apps" / "host" / "server" / "native-settings.mjs").read_text(encoding="utf-8")
|
||||
page = (ROOT / "apps" / "host" / "src" / "lib" / "drafting.ts").read_text(encoding="utf-8")
|
||||
self.assertIn("DRAFTING_FAMILIES=['qwen','gyro','unsloth']", host)
|
||||
self.assertIn("DRAFTING_FAMILIES = ['qwen', 'gyro', 'unsloth']", page)
|
||||
self.assertIn(r"-unsloth-[a-z0-9._-]+", host)
|
||||
|
||||
|
||||
class TheInstalledEngineDecidesTheFlags(unittest.TestCase):
|
||||
"""GUI-FB3 item 2. Gyro-S with Auto sent `--mtp-draft-vocab FILE` and no `--mtp` to the engine 0.1.55.2 (f-0291-r5070-df2), which only takes `--mtp DIR` for the
|
||||
vocabulary and ended with exit code 2. The app reads what the engine program takes (it is never started for this) and sends only that."""
|
||||
|
||||
@@ -364,7 +364,8 @@ class TheTerminalStep(unittest.TestCase):
|
||||
self.assertIn("drafting", flow)
|
||||
self.assertEqual(flow.index("drafting"), flow.index("pictures") + 1)
|
||||
self.assertIn("drafting", self.flow("gyro", ("hip", ["gfx1151"])))
|
||||
for family in ("deepseek41", "swift", "coder", "unsloth", "nvfp4", "qwen36", None):
|
||||
self.assertIn("drafting", self.flow("unsloth", ("cuda", ["sm_120"])))
|
||||
for family in ("deepseek41", "swift", "coder", "nvfp4", "qwen36", None):
|
||||
self.assertNotIn("drafting", self.flow(family, ("cuda", ["sm_120"])), family)
|
||||
self.assertIn("drafting", self.flow("qwen", ("sycl", [])))
|
||||
for hardware in (("cpu", []), (None, [])):
|
||||
|
||||
Reference in new issue
Block a user