mirror of
https://github.com/Heretek-AI/Strata.git
synced 2026-11-07 10:05:58 -10:00
Merge f-038-ds-unsloth (final 4148c5125)
This commit is contained in:
commit
7851a8dab6
8 files changed
+128
-26
No files matched your search
@@ -8416,13 +8416,12 @@ def install_dsv41(a, family, gpu, hip, amd, cuda_tk, multi, port, ram, adopted,
|
||||
except Exception: # noqa: BLE001 - the disk is only a hint here
|
||||
room = None
|
||||
rec = dsv41_fit.recommend(ram, room) # the best version this computer's memory and disk suit; warn-never-refuse
|
||||
if mac: # the Unsloth 1-bit sets have no Metal kernel yet: not in a Mac's menu
|
||||
names = [m for m in names if m not in dsv41_fit.MAC_NOT_YET]
|
||||
names = [m for m in names if not dsv41_fit.not_here(m)] # the Unsloth 1-bit sets: no Metal kernel yet on a Mac, untested on a DGX Spark
|
||||
for i, m in enumerate(names, 1):
|
||||
say(f" {i}) {fam['models'][m].get('label', m)}: {fam['models'][m]['about']}" + (" (recommended)" if m == rec else ""))
|
||||
model = names[int(ask("Which version?", [str(i) for i in range(1, len(names) + 1)], str(names.index(rec) + 1), a.yes)) - 1]
|
||||
if mac and model in dsv41_fit.MAC_NOT_YET: # IQ1_S experts: no Metal kernel yet (strata_control/dsv41_fit.MAC_NOT_YET); said before anything is fetched or packed
|
||||
fail(dsv41_fit.MAC_NOT_YET_LINE, "choose --model IST-DAS-2.00bpw or --model IST-DAS-2.25bpw (their files work with --gguf-dir too); nothing has been downloaded")
|
||||
if dsv41_fit.not_here(model): # Mac: IQ1_S experts have no Metal kernel yet; DGX Spark: never run (strata_control/dsv41_fit.not_here); said before anything is fetched or packed
|
||||
fail(dsv41_fit.not_here(model), "choose --model IST-DAS-2.00bpw or --model IST-DAS-2.25bpw (their files work with --gguf-dir too); nothing has been downloaded")
|
||||
ok(f"size: {model}")
|
||||
md = fam["models"][model]
|
||||
say(" Its GGUF files: " + ("IST-DAS / ISTA-DASLab (huggingface.co/ISTA-DASLab/DeepSeek-V4.1-Flash-1017-GSQ-RCO-GGUF), with the DSpark drafter and a small metadata file from Unsloth"
|
||||
|
||||
@@ -383,8 +383,10 @@ class Catalog:
|
||||
near = S.closest(family, list(families))
|
||||
raise ValueError(f"There is no model family called '{family}'." + (f" Did you mean '{near}'?" if near else "")
|
||||
+ " Families: " + ", ".join(families) + ".")
|
||||
if match in self.strata.dsv41_not_on_mac() and self._mac_hardware():
|
||||
raise ValueError(self.strata.dsv41_not_on_mac_line() + " Use ist-das-2.00bpw or ist-das-2.25bpw.")
|
||||
from strata_control import dsv41_fit
|
||||
line = dsv41_fit.not_here(match) or (dsv41_fit.MAC_NOT_YET_LINE if match in dsv41_fit.MAC_NOT_YET and self._mac_hardware() else None)
|
||||
if line:
|
||||
raise ValueError(line + " Use ist-das-2.00bpw or ist-das-2.25bpw.")
|
||||
offered = [f for f in families if match in self.strata.sizes_of(models, f)]
|
||||
if family is not None:
|
||||
if family not in offered:
|
||||
|
||||
@@ -1309,8 +1309,9 @@ class Runner:
|
||||
if found is None:
|
||||
return False
|
||||
model, d, folder = found
|
||||
if sys.platform == "darwin" and model in self.catalog.strata.dsv41_not_on_mac(): # IQ1_S experts: no Metal kernel yet; said before an engine or a download is touched
|
||||
raise LaunchError(self.catalog.strata.dsv41_not_on_mac_line(),
|
||||
from strata_control import dsv41_fit
|
||||
if dsv41_fit.not_here(model): # Mac: no Metal IQ1_S kernel yet; DGX Spark: never run; said before an engine or a download is touched
|
||||
raise LaunchError(dsv41_fit.not_here(model),
|
||||
"Use the 2.00 or 2.25 files (--model ist-das-2.00bpw or --model ist-das-2.25bpw, or --model-path to those files). "
|
||||
"Nothing was downloaded or changed.", 2)
|
||||
if s.family and s.family != "deepseek41":
|
||||
|
||||
@@ -560,8 +560,9 @@ class ModelScreen(Base):
|
||||
if found is None:
|
||||
return False
|
||||
model, d, folder = found
|
||||
if sys.platform == "darwin" and model in self.ctx.catalog.strata.dsv41_not_on_mac():
|
||||
self.say(self.ctx.catalog.strata.dsv41_not_on_mac_line() + " Pick the 2.00 or 2.25 version from the list, or point to those files.", True)
|
||||
from strata_control import dsv41_fit
|
||||
if dsv41_fit.not_here(model):
|
||||
self.say(dsv41_fit.not_here(model) + " Pick the 2.00 or 2.25 version from the list, or point to those files.", True)
|
||||
return True
|
||||
_layout, names, missing = mod.dsv41_parts(d, lambda n: (folder / n).exists()) # the pinned four-shard layout, or ISTA's six-shard one (0.2.8.1)
|
||||
if missing:
|
||||
|
||||
@@ -19,6 +19,8 @@ setup.py, tools/strata_mcp.py and strata_cli/launch import it. Recommend, never
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import platform
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
from strata_control import gpu_fit
|
||||
@@ -612,6 +614,19 @@ MAC_SET_PACK = {"IST-DAS-2.00bpw": "IQ2_XXS", "IST-DAS-2.25bpw": "IQ2_XS"}
|
||||
# launch and the "I already have the model" check, with this one line. Remove a name here when its Metal kernel lands.
|
||||
MAC_NOT_YET = ("UD-IQ1_S", "UD-IQ1_M")
|
||||
MAC_NOT_YET_LINE = "Unsloth's 1-bit DeepSeek sets don't run on a Mac yet; the 2.00 and 2.25 sets do."
|
||||
# The same two sets were never run on a DGX Spark (linux-aarch64, GB10) either: kept off it the same way until a Spark run passes (remove the names then).
|
||||
AARCH64_NOT_YET = ("UD-IQ1_S", "UD-IQ1_M")
|
||||
AARCH64_NOT_YET_LINE = "Unsloth's 1-bit DeepSeek sets were not tested on a DGX Spark yet; the 2.00 and 2.25 sets were."
|
||||
|
||||
|
||||
def not_here(model: str | None) -> str | None:
|
||||
"""The plain line when `model` is not offered on THIS computer (a Mac: MAC_NOT_YET; linux-aarch64, the DGX Spark: AARCH64_NOT_YET), else None.
|
||||
Read at call time from sys.platform and platform.machine(), so one rule serves the model lists, setup, `strata launch` and the app's file check."""
|
||||
if sys.platform == "darwin" and model in MAC_NOT_YET:
|
||||
return MAC_NOT_YET_LINE
|
||||
if sys.platform.startswith("linux") and platform.machine().lower() in ("aarch64", "arm64") and model in AARCH64_NOT_YET:
|
||||
return AARCH64_NOT_YET_LINE
|
||||
return None
|
||||
MAC_SMALL_RAM_GB = 64.0 # below this the measured M5 Max numbers do not apply (nothing smaller than 32 GB was ever started)
|
||||
|
||||
|
||||
|
||||
@@ -338,6 +338,7 @@ def _already_set_up(shards: list[Path], candidate: dict | None) -> dict | None:
|
||||
|
||||
ISSUE_WORDS = {
|
||||
"not_on_this_mac": "Unsloth's 1-bit DeepSeek sets don't run on a Mac yet; the 2.00 and 2.25 sets do",
|
||||
"not_on_this_spark": "Unsloth's 1-bit DeepSeek sets were not tested on a DGX Spark yet; the 2.00 and 2.25 sets were",
|
||||
"multiple_model_groups": "the folder holds more than one model",
|
||||
"incomplete_or_invalid_shard_set": "some parts of the model are missing",
|
||||
"unrecognized_or_unsupported_model_variant": "this is not a model size Strata knows",
|
||||
@@ -368,18 +369,9 @@ _REASON_WORDS = (
|
||||
)
|
||||
|
||||
|
||||
def _on_mac() -> bool:
|
||||
return sys.platform == "darwin"
|
||||
|
||||
|
||||
def _mac_not_yet() -> tuple:
|
||||
def _not_here(model: str) -> str | None:
|
||||
from strata_control import dsv41_fit
|
||||
return dsv41_fit.MAC_NOT_YET
|
||||
|
||||
|
||||
def _mac_not_yet_line() -> str:
|
||||
from strata_control import dsv41_fit
|
||||
return dsv41_fit.MAC_NOT_YET_LINE
|
||||
return dsv41_fit.not_here(model)
|
||||
|
||||
|
||||
def plain_issue(code: str) -> str:
|
||||
@@ -683,10 +675,11 @@ def _dsv41_plan(path: Path, details) -> dict | None:
|
||||
candidate = {"family": dsv41_sets.FAMILY, "model": row["model"], "basis": "known_names_and_sizes", "expected_expert_types": [],
|
||||
"expected_tensor_count": None,
|
||||
"setup_args_hint": ["--family", dsv41_sets.FAMILY, "--model", row["model"], "--gguf-dir", str(place)]}
|
||||
if _on_mac() and row["model"] in _mac_not_yet(): # recommend, never force: say what does work and stop before anything is copied or packed
|
||||
issues.append("not_on_this_mac")
|
||||
line = _not_here(row["model"])
|
||||
if line: # recommend, never force: say what does work and stop before anything is copied or packed (Mac: no Metal IQ1_S kernel; DGX Spark: never run)
|
||||
issues.append("not_on_this_mac" if sys.platform == "darwin" else "not_on_this_spark")
|
||||
candidate = None
|
||||
messages.append(_mac_not_yet_line())
|
||||
messages.append(line)
|
||||
messages.append(f"This is DeepSeek-V4.1-Flash, {row['label']}: all {len(row['present'])} model files are here"
|
||||
+ (", and the n-gram table." if row["engram"] else "."))
|
||||
if not row["engram"]:
|
||||
|
||||
@@ -135,9 +135,12 @@ class AppCheck(unittest.TestCase):
|
||||
|
||||
|
||||
class Setup(unittest.TestCase):
|
||||
def runTest(self): # (SparkGate borrows run_setup)
|
||||
pass
|
||||
|
||||
"""setup.py is the last stop: the line, before an engine, a download or a pack is touched."""
|
||||
|
||||
def run_setup(self, model, platform):
|
||||
def run_setup(self, model, platform, machine=None):
|
||||
import contextlib
|
||||
import importlib.util
|
||||
import io
|
||||
@@ -148,7 +151,7 @@ class Setup(unittest.TestCase):
|
||||
spec.loader.exec_module(setup)
|
||||
a = types.SimpleNamespace(model=model, models_dir="/nonexistent/models", yes=True, gguf_dir=None)
|
||||
out = io.StringIO()
|
||||
with mock.patch.object(sys, "platform", platform), contextlib.redirect_stdout(out), contextlib.redirect_stderr(out):
|
||||
with mock.patch.object(sys, "platform", platform), mock.patch("platform.machine", return_value=machine or "x86_64"), contextlib.redirect_stdout(out), contextlib.redirect_stderr(out):
|
||||
try:
|
||||
setup.install_dsv41(a, "deepseek41", {}, False, False, 13, True, 8080, 128.0, False)
|
||||
except BaseException as exc: # noqa: BLE001 - fail() exits; anything after the check would raise something else
|
||||
@@ -164,5 +167,85 @@ class Setup(unittest.TestCase):
|
||||
self.assertIn("nothing has been downloaded", text)
|
||||
|
||||
|
||||
SPARK_LINE = "Unsloth's 1-bit DeepSeek sets were not tested on a DGX Spark yet; the 2.00 and 2.25 sets were."
|
||||
|
||||
|
||||
def spark():
|
||||
"""A DGX Spark: linux-aarch64 (the two patches the one rule reads)."""
|
||||
from contextlib import ExitStack
|
||||
stack = ExitStack()
|
||||
stack.enter_context(mock.patch.object(sys, "platform", "linux"))
|
||||
stack.enter_context(mock.patch("platform.machine", return_value="aarch64"))
|
||||
return stack
|
||||
|
||||
|
||||
class SparkGate(unittest.TestCase):
|
||||
"""The same gate for the DGX Spark (dsv41_fit.AARCH64_NOT_YET): the sets were never run there. Removing the names from the tuple lifts it."""
|
||||
|
||||
def setUp(self):
|
||||
self.home = Home().__enter__()
|
||||
self.addCleanup(self.home.__exit__, None, None, None)
|
||||
self.hw = {**PC, "engine_vendor": "nvidia"}
|
||||
p = mock.patch.object(Catalog, "hardware", lambda s, fresh=False: dict(self.hw))
|
||||
p.start()
|
||||
self.addCleanup(p.stop)
|
||||
|
||||
def test_the_rule(self):
|
||||
self.assertEqual(dsv41_fit.AARCH64_NOT_YET, UD)
|
||||
self.assertEqual(dsv41_fit.AARCH64_NOT_YET_LINE, SPARK_LINE)
|
||||
with spark():
|
||||
for m in UD:
|
||||
self.assertEqual(dsv41_fit.not_here(m), SPARK_LINE)
|
||||
self.assertIsNone(dsv41_fit.not_here("IST-DAS-2.25bpw"))
|
||||
with mock.patch.object(sys, "platform", "linux"), mock.patch("platform.machine", return_value="x86_64"):
|
||||
self.assertIsNone(dsv41_fit.not_here("UD-IQ1_S"))
|
||||
with mock.patch.object(sys, "platform", "darwin"):
|
||||
self.assertEqual(dsv41_fit.not_here("UD-IQ1_S"), LINE)
|
||||
|
||||
def test_not_in_the_list_on_a_spark_but_on_a_pc(self):
|
||||
with spark():
|
||||
got = [r.model for r in catalog(self.hw).rows() if r.family == "deepseek41"]
|
||||
for m in UD:
|
||||
self.assertNotIn(m, got)
|
||||
self.assertIn("IST-DAS-2.25bpw", got)
|
||||
pc = [r.model for r in catalog(self.hw).rows() if r.family == "deepseek41"]
|
||||
for m in UD:
|
||||
self.assertIn(m, pc)
|
||||
|
||||
def test_model_flag_on_a_spark_says_what_works(self):
|
||||
with spark():
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
catalog(self.hw).resolve("ud-iq1_s", None)
|
||||
self.assertIn(SPARK_LINE, str(cm.exception))
|
||||
self.assertIn("ist-das-2.25bpw", str(cm.exception))
|
||||
|
||||
def test_model_path_of_a_ud_folder_on_a_spark_stops(self):
|
||||
folder = Path(os.environ["STRATA_INSTALL_DIR"]) / "UD-IQ1_M"
|
||||
folder.mkdir(parents=True, exist_ok=True)
|
||||
for name in dsv41_sets.tables()["sets"]["UD-IQ1_M"]["shards"]:
|
||||
(folder / name).write_bytes(b"GGUF")
|
||||
with spark():
|
||||
with self.assertRaises(LaunchError) as cm:
|
||||
Runner(S.LaunchSettings(model_path=str(folder)), catalog=catalog(self.hw)).check_own_files()
|
||||
self.assertIn(SPARK_LINE, cm.exception.text)
|
||||
|
||||
def test_app_check_on_a_spark(self):
|
||||
import tempfile
|
||||
for model in UD:
|
||||
with mock.patch.object(models, "_dsv41_files", return_value=ud_files(model)), tempfile.TemporaryDirectory() as tmp, spark():
|
||||
plan = models.plan_import(tmp)
|
||||
self.assertIn(SPARK_LINE, plan["messages"])
|
||||
self.assertIn("not_on_this_spark", plan["issues"])
|
||||
self.assertIsNone(plan["candidate_selection"])
|
||||
self.assertIn(SPARK_LINE.rstrip("."), plan["plain_issues"])
|
||||
|
||||
def test_setup_stops_on_a_spark(self):
|
||||
for model in UD:
|
||||
exc, text = Setup().run_setup(model, "linux", machine="aarch64")
|
||||
self.assertEqual(exc, "SystemExit", (model, text[-300:]))
|
||||
self.assertIn(SPARK_LINE, text)
|
||||
self.assertIn("nothing has been downloaded", text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1288,6 +1288,8 @@ class Strata:
|
||||
for f, fd in families.items():
|
||||
sizes = []
|
||||
for m in self.sizes_of(models, f):
|
||||
if f == "deepseek41" and self.dsv41_not_here(m): # the Unsloth 1-bit sets on a DGX Spark: not offered until a Spark run passes
|
||||
continue
|
||||
own = self.own_size(f, m)
|
||||
d = own or models[m]
|
||||
tag = (fd.get("tag", "") + m).lower()
|
||||
@@ -1346,6 +1348,12 @@ class Strata:
|
||||
from strata_control import dsv41_fit
|
||||
return dsv41_fit.MAC_NOT_YET
|
||||
|
||||
@staticmethod
|
||||
def dsv41_not_here(model: str) -> str | None:
|
||||
"""The plain line when this computer (a Mac, a DGX Spark) is not offered `model`, else None: strata_control/dsv41_fit.not_here."""
|
||||
from strata_control import dsv41_fit
|
||||
return dsv41_fit.not_here(model)
|
||||
|
||||
@staticmethod
|
||||
def dsv41_not_on_mac_line() -> str:
|
||||
from strata_control import dsv41_fit
|
||||
|
||||
Reference in new issue
Block a user