Merge f-0214-strixplan 0c0b7b875 (Strix plan fix) into f-0214-int

This commit is contained in:
Niko1221 committed 2026-11-05 12:53:44 +01:00
commit d7f5c6dd11
2 files changed
+105 -12

No files matched your search

+28 -9
View File
@@ -487,26 +487,26 @@ MODELS = {
# download_gb / arena_gb: the pinned shard sizes and the routed experts' bytes (tests/fixtures/unsloth_v31); ram_gb: the RAM-budget floor of UD-Q4_K_XL.
"UD-IQ1_M": {"about": "~1-bit (Unsloth Dynamic v3.1), the smallest download", "download_gb": 68.0, "ram_gb": 48, "arena_gb": 34.8, "families": ("unsloth",), "budget": True,
"shards": 3, "file": "Qwen3.8-Flash-Next-{q}-0000{i}-of-00003.gguf", "quant": "UD-IQ1_M",
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True},
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True, "uma_pool_auto": True},
"UD-Q2_0": {"about": "2-bit (Unsloth Dynamic v3.1)", "download_gb": 70.5, "ram_gb": 48, "arena_gb": 37.4, "families": ("unsloth",), "budget": True,
"shards": 3, "file": "Qwen3.8-Flash-Next-{q}-0000{i}-of-00003.gguf", "quant": "UD-Q2_0",
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True},
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True, "uma_pool_auto": True},
"UD-IQ2_XS": {"about": "2-bit i-quant (Unsloth Dynamic v3.1)", "download_gb": 75.8, "ram_gb": 48, "arena_gb": 42.3, "families": ("unsloth",), "budget": True,
"shards": 3, "file": "Qwen3.8-Flash-Next-{q}-0000{i}-of-00003.gguf", "quant": "UD-IQ2_XS",
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True},
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True, "uma_pool_auto": True},
"UD-Q2_K_XL": {"about": "2-bit (Unsloth Dynamic v3.1) with some 3-bit experts", "download_gb": 79.6, "ram_gb": 48, "arena_gb": 46.0, "families": ("unsloth",), "budget": True,
"shards": 4, "file": "Qwen3.8-Flash-Next-{q}-0000{i}-of-00004.gguf", "quant": "UD-Q2_K_XL",
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True},
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True, "uma_pool_auto": True},
"UD-IQ3_XXS": {"about": "3-bit i-quant (Unsloth Dynamic v3.1)", "download_gb": 83.6, "ram_gb": 48, "arena_gb": 50.3, "families": ("unsloth",), "budget": True,
"shards": 4, "file": "Qwen3.8-Flash-Next-{q}-0000{i}-of-00004.gguf", "quant": "UD-IQ3_XXS",
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True},
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True, "uma_pool_auto": True},
"UD-Q3_K_XL": {"about": "3-bit (Unsloth Dynamic v3.1) with some 4-bit experts", "download_gb": 89.5, "ram_gb": 48, "arena_gb": 56.2, "families": ("unsloth",), "budget": True,
"shards": 4, "file": "Qwen3.8-Flash-Next-{q}-0000{i}-of-00004.gguf", "quant": "UD-Q3_K_XL",
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True},
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True, "uma_pool_auto": True},
# the v3.1 UD-IQ4_XS is another file from the pinned UD-IQ4_XS (345 of 1224 tensors changed type; four shards): its own name
UNSLOTH_V31_IQ4_XS: {"about": "~4-bit i-quant (Unsloth Dynamic v3.1), a newer file than UD-IQ4_XS with other tensor types", "download_gb": 93.7, "ram_gb": 48, "arena_gb": 60.4, "families": ("unsloth",), "budget": True,
"shards": 4, "file": "Qwen3.8-Flash-Next-{q}-0000{i}-of-00004.gguf", "quant": "UD-IQ4_XS",
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True},
"revision": UNSLOTH_V31_REVISION, "engine": UNSLOTH_V31_ENGINE, "vision": True, "uma_pool_auto": True},
# MODEL-UPDATE Phase 4: NVFP4 experts, ready-made packs (NVFP4_REPOS). 63.3 GiB (68.0 GB) of experts in the
# pack's experts.bin; the low-RAM mode reads them from there on a PC whose RAM does not hold them. NVIDIA only
# (the HIP and SYCL engines have no NVFP4 kernels). Images: both packs keep Qwen's vision tower unquantized, so the
@@ -3667,11 +3667,30 @@ def unsloth_budget(model, ram, gpu=None, asked=None) -> bool:
"""Does setup write the RAM-budget mode (--resident-budget-gib) for this Unsloth file: asked for (--resident-budget-gib
N), a unified-memory APU (#1715: there the budget and the GPU's cache are the same RAM, and the all-in-RAM mode was
measured on discrete cards only), or its experts with UNSLOTH_RESIDENT_BESIDE_GB beside them do not fit this PC's RAM
(GiB, ram_gb()). Else every expert is kept in RAM, as for ISTA's files."""
return asked is not None or bool((gpu or {}).get("uma")) or \
(GiB, ram_gb()). Else every expert is kept in RAM, as for ISTA's files.
Round 0214: a unified-memory APU keeps the budget mode (above) except for a set that says "uma_pool_auto" (Unsloth's v3.1 sets) whose experts fit
the GPU's shared pool whole (uma_holds_experts): there every expert is in the pool, the cache is `auto` and nothing is pinned. The fixed cache and
the pinned RAM part the budget mode wrote for them (367 slots + 35 GiB on a 64 GB Strix Halo) failed the first launch of UD-IQ2_XS three times of three
("prefill: the token id buffer (unspecified launch failure)" right after pinning); `--expert-cache auto` with nothing pinned passed (ENG-AMD)."""
return asked is not None or (bool((gpu or {}).get("uma")) and not uma_holds_experts(model, ram, gpu)) or \
ram < MODELS[model]["arena_gb"] / 1.073741824 + UNSLOTH_RESIDENT_BESIDE_GB
def uma_holds_experts(model, ram, gpu) -> bool:
"""A unified-memory GPU whose shared pool holds every expert of `model` beside everything else the engine keeps there (strata_control/uma_pool.py: the
measured fixed part, the experts, a margin) and whose RAM holds them with UNSLOTH_RESIDENT_BESIDE_GB more. Only for a set that asks ("uma_pool_auto"):
the sets measured under the budget mode (UD-IQ4_XS, UD-Q4_K_XL, ...) keep their plans."""
if sys.platform == "darwin" or not MODELS.get(model, {}).get("uma_pool_auto") or not (gpu or {}).get("uma"):
return False # (a Mac never reaches this: metal/setup_mac.py and mac_control_setup have their own plans; the check keeps it so)
shared = float((gpu or {}).get("vram_gb") or 0.0)
if shared <= 0:
return False
from strata_control import uma_pool
arena_gib = MODELS[model]["arena_gb"] / 1.073741824
return (uma_pool.FIXED_GIB + arena_gib + uma_pool.MARGIN_GIB <= uma_pool.pool_gib(shared)
and ram >= arena_gib + UNSLOTH_RESIDENT_BESIDE_GB)
def images_default(model, family, ram, gpu=None) -> bool:
"""Is "images on" setup's default answer (the question's Enter, and --yes) for this choice? Owner rule 2026-10-18: pictures are on
wherever the model can read them - the original Flash-Next, Swift and Coder files, Unsloth's, NVFP4 - on every make of card; which
+77 -3
View File
@@ -587,10 +587,10 @@ class StrixHaloCache(Base):
HALO = [{"index": 0, "name": "AMD Radeon 8060S", "vram_gb": 114.0, "arch": "gfx1151", "driver": "amdgpu",
"uma": True, "dedicated_gb": 2.0, "shared_gb": 112.0}]
def run_halo(self, ram, argv=("--context", "8192"), amd=None):
def run_halo(self, ram, argv=("--context", "8192"), amd=None, m="UD-IQ4_XS", version="0.1.41"):
with mock.patch.object(setup, "get_prebuilt_hip", lambda *a, **k: self.t / "engine"), mock.patch.object(setup, "WIN", False), mock.patch.object(setup, "build_engine_hip", lambda *a, **k: self.t / "engine"):
return self.main([*argv, "--backend", "hip"], version="0.1.41", amd=self.HALO if amd is None else amd,
ram=ram, m="UD-IQ4_XS")
return self.main([*argv, "--backend", "hip"], version=version, amd=self.HALO if amd is None else amd,
ram=ram, m=m)
def test_cache_is_a_number_that_leaves_room(self):
code, out, cfg = self.run_halo(124.0)
@@ -614,6 +614,80 @@ class StrixHaloCache(Base):
self.assertEqual(args[args.index("--expert-cache") + 1], "auto")
self.assertIn("leaves almost none for the expert cache", out)
# Round 0214 (the release blocker): a 64 GB Strix Halo gave UD-IQ2_XS a fixed 367-slot cache and a 35 GiB pinned part, and its first launch failed 3 of 3;
# `--expert-cache auto` with nothing pinned passed. A v3.1 set whose experts fit the shared pool whole gets that plan; every other set keeps its plan.
HALO64 = [{"index": 0, "name": "AMD Radeon 8060S", "vram_gb": 64.0, "arch": "gfx1151", "driver": "amdgpu",
"uma": True, "dedicated_gb": 32.0, "shared_gb": 32.0}]
def plan(self, model, ram, amd=None):
code, out, cfg = self.run_halo(ram, amd=amd or self.HALO64, m=model, version="0.1.57")
self.assertEqual(code, 0, out)
a = cfg["args"]
return a[a.index("--expert-cache") + 1], (a[a.index("--resident-budget-gib") + 1] if "--resident-budget-gib" in a else None)
def test_the_v31_sets_that_fit_the_pool_get_cache_auto_and_nothing_pinned(self):
for model in ("UD-IQ1_M", "UD-Q2_0", "UD-IQ2_XS"):
with self.subTest(model=model):
self.assertTrue(setup.uma_holds_experts(model, 63.7, self.HALO64[0]))
self.assertFalse(setup.unsloth_budget(model, 63.7, self.HALO64[0]))
self.assertEqual(self.plan(model, 63.7), ("auto", None))
def test_the_sets_too_big_for_the_pool_keep_the_budget_plan(self):
for model in ("UD-Q2_K_XL", "UD-IQ3_XXS", "UD-Q3_K_XL", "UD-IQ4_XS-v31"):
with self.subTest(model=model):
self.assertFalse(setup.uma_holds_experts(model, 63.7, self.HALO64[0]))
self.assertTrue(setup.unsloth_budget(model, 63.7, self.HALO64[0]))
cache, budget = self.plan(model, 63.7)
self.assertEqual(budget, "40") # as UD-IQ4_XS's: the RAM less 24
def test_a_bigger_pool_holds_more_of_the_v31_sets(self):
big = [{**self.HALO[0], "vram_gb": 114.0}]
for model in ("UD-IQ3_XXS", "UD-Q3_K_XL", "UD-IQ4_XS-v31"):
with self.subTest(model=model):
self.assertEqual(self.plan(model, 124.0, amd=big), ("auto", None))
def test_the_pinned_sets_keep_exactly_their_plans(self):
"""UD-IQ4_XS / UD-Q4_K_XL / UD-Q5_K_XL / UD-Q6_K_XL / Q8_0: not marked, so the rule never touches them, on Strix at 64 and 124 GB."""
for model in ("UD-IQ4_XS", "UD-Q4_K_XL", "UD-Q5_K_XL", "UD-Q6_K_XL", "Q8_0"):
self.assertNotIn("uma_pool_auto", setup.MODELS[model])
for ram, halo in ((63.7, self.HALO64[0]), (124.0, self.HALO[0])):
self.assertFalse(setup.uma_holds_experts(model, ram, halo))
self.assertTrue(setup.unsloth_budget(model, ram, halo), (model, ram))
self.assertEqual(self.plan("UD-IQ4_XS", 63.7), ("auto", "40")) # no room for a number: auto, with the budget (it passes on the box)
code, out, cfg = self.run_halo(124.0)
a = cfg["args"]
self.assertEqual((a[a.index("--resident-budget-gib") + 1], a[a.index("--expert-cache") + 1]), ("55", str(int(45 / (59.5e9 / setup.UMA_EXPERTS * 1.1 / 2**30)))))
def test_other_cards_and_a_person_s_budget_are_unchanged(self):
r9700 = {"vram_gb": 31.9, "uma": False}
nvidia = {"vram_gb": 12.0}
for gpu in (r9700, nvidia, None):
self.assertFalse(setup.uma_holds_experts("UD-IQ2_XS", 63.7, gpu))
self.assertFalse(setup.unsloth_budget("UD-IQ2_XS", 63.7, gpu), gpu) # (63.7 GB holds its 39 GiB of experts and 16 more: all in RAM, as before)
self.assertTrue(setup.unsloth_budget("UD-IQ2_XS", 40.0, gpu)) # too little RAM: the budget, as before
self.assertTrue(setup.unsloth_budget("UD-IQ2_XS", 63.7, self.HALO64[0], asked=24.0)) # --resident-budget-gib N is still honoured
asked = self.run_halo(63.7, ("--context", "8192", "--resident-budget-gib", "24"), amd=self.HALO64, m="UD-IQ2_XS", version="0.1.57")[2]["args"]
self.assertIn("--resident-budget-gib", asked) # the budget the person asked for is written (setup's own pool check may lower it, as before)
def test_a_mac_is_never_touched(self):
with mock.patch.object(setup.sys, "platform", "darwin"):
self.assertFalse(setup.uma_holds_experts("UD-IQ2_XS", 63.7, self.HALO64[0]))
self.assertTrue(setup.unsloth_budget("UD-IQ2_XS", 63.7, self.HALO64[0])) # the answer it gave before round 0214
def test_the_spark_profile(self):
"""A DGX Spark (GB10, unified memory, 128 GB): the old sets keep the budget plan, a v3.1 set that fits the pool has all of its experts in it."""
spark = {"vram_gb": 119.0, "uma": True, "arch": "121"}
for model in ("UD-IQ4_XS", "UD-Q4_K_XL", "UD-Q5_K_XL", "UD-Q6_K_XL", "Q8_0"):
self.assertTrue(setup.unsloth_budget(model, 121.0, spark), model)
for model in ("UD-IQ1_M", "UD-IQ2_XS", "UD-IQ3_XXS", "UD-Q3_K_XL", "UD-IQ4_XS-v31"):
self.assertFalse(setup.unsloth_budget(model, 121.0, spark), model)
def test_nvidia_plans_are_the_same_for_every_set(self):
for model in ("UD-IQ4_XS", "UD-Q4_K_XL", "UD-IQ1_M", "UD-IQ4_XS-v31"):
for ram in (47.0, 63.7, 124.0):
want = ram < setup.MODELS[model]["arena_gb"] / 1.073741824 + setup.UNSLOTH_RESIDENT_BESIDE_GB
self.assertEqual(setup.unsloth_budget(model, ram, {"vram_gb": 12.0}), want, (model, ram))
def test_a_discrete_card_keeps_auto(self):
r9700 = [{"index": 0, "name": "AMD Radeon AI PRO R9700", "vram_gb": 31.9, "arch": "gfx1201",
"driver": "amdgpu"}]