mirror of
https://github.com/Heretek-AI/Strata.git
synced 2026-11-09 17:16:49 -10:00
100 lines
5.1 KiB
Python
100 lines
5.1 KiB
Python
"""``strata drafting plan|fetch``: the DFlash2 drafter file (strata_control/drafting_fetch.py). The app calls it with ``--output jsonl``.
|
|
|
|
With ``--config`` (a model's run config) and ``--mode`` (the choice, default: the config's own ``drafting``) the command decides what this
|
|
model needs: ``needed`` is true only when the choice would use the drafter and its file is not here yet. ``fetch --if-needed`` then downloads
|
|
only in that case, so the app can call it before every load without asking twice.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from strata_control import acquisition, drafting
|
|
|
|
|
|
def add_parser(sp) -> None:
|
|
drafting_p = sp.add_parser("drafting", help="the DFlash2 drafter file: what it would download, and fetch it")
|
|
d_sp = drafting_p.add_subparsers(dest="drafting_command", required=True)
|
|
for name, text in (("plan", "say what fetching would download; nothing is changed"),
|
|
("fetch", "download the drafter (pinned, checked) and pack it for the engine")):
|
|
one = d_sp.add_parser(name, help=text)
|
|
one.add_argument("--data-dir", metavar="DIR", help="the model data folder (default: the one Strata uses)")
|
|
one.add_argument("--config", metavar="FILE", help="a model's run config: its data folder, model and drafting choice decide what is needed")
|
|
one.add_argument("--family", metavar="NAME", help="the model family when there is no run config yet (qwen, gyro, coder, ...)")
|
|
one.add_argument("--mode", choices=drafting.MODES, help="the choice to decide for (default: the run config's own)")
|
|
if name == "fetch":
|
|
one.add_argument("--if-needed", action="store_true", help="download only when the choice would use the drafter and it is not here")
|
|
one.add_argument("--output", choices=("human", "json", "jsonl"), default="human")
|
|
|
|
|
|
def _card_class() -> str:
|
|
try:
|
|
from strata_control import engine_component
|
|
return drafting.card_class(list(engine_component.cuda_archs_present()) + list(engine_component.hip_archs_present()))
|
|
except Exception: # noqa: BLE001 - an unknown card is the "other" class
|
|
return "other"
|
|
|
|
|
|
def _inputs(a) -> dict:
|
|
cfg: dict = {}
|
|
if a.config:
|
|
try:
|
|
cfg = json.loads(Path(a.config).read_text(encoding="utf-8-sig"))
|
|
except (OSError, ValueError):
|
|
cfg = {}
|
|
if a.data_dir:
|
|
data = Path(a.data_dir)
|
|
else:
|
|
data = drafting.data_dir_of(cfg.get("args") or [])
|
|
if data is None:
|
|
from strata_cli.launch.catalog import Catalog
|
|
data = Catalog().data_dir()
|
|
return {"mode": a.mode if a.mode else cfg.get("drafting"), "klass": _card_class(), "model_name": cfg.get("model_name"), "family": a.family, "data_dir": data}
|
|
|
|
|
|
def run(a) -> int:
|
|
from strata_control import drafting_fetch # here, not at the top: it pulls in the network code, which a started engine's command line must not load
|
|
machine = a.output in ("json", "jsonl")
|
|
want = _inputs(a)
|
|
folder = want["data_dir"]
|
|
needed = drafting.needs_pack(**want)
|
|
if a.drafting_command == "plan":
|
|
decision = drafting.decide(want["mode"], klass=want["klass"], model_name=want["model_name"], family=want["family"], data_dir=folder)
|
|
result = {**drafting_fetch.plan(folder), "needed": needed, "serves": drafting.ENGINE_SERVES_DFLASH2, "drafter": decision.drafter, "note": decision.note,
|
|
"line": drafting.summary_line(decision)}
|
|
if (a.config or a.mode) and not needed: # asked about a model: nothing to download unless the choice uses the drafter
|
|
result["gb"] = 0.0
|
|
if machine:
|
|
print(json.dumps({"schema_version": 1, "ok": True, **result}, ensure_ascii=False))
|
|
else:
|
|
print(result["text"] if needed or not decision.note else result["line"])
|
|
return 0
|
|
if getattr(a, "if_needed", False) and not needed:
|
|
if machine:
|
|
print(json.dumps({"schema_version": 1, "ok": True, "event": "result", "pack": None, "skipped": True}, ensure_ascii=False))
|
|
else:
|
|
print("Nothing to download.")
|
|
return 0
|
|
|
|
def show(step: str, done: int, total: int) -> None:
|
|
if a.output == "jsonl":
|
|
print(json.dumps({"event": "progress", "step": step, "done": done, "total": total}, ensure_ascii=False), flush=True)
|
|
elif not machine and total:
|
|
print(f"\r{step} {done / 1e9:.2f} of {total / 1e9:.2f} GB", end="", flush=True)
|
|
|
|
try:
|
|
out = drafting_fetch.ensure(folder, progress=show)
|
|
except (drafting_fetch.DraftingError, acquisition.AcquisitionRefused) as exc:
|
|
if machine:
|
|
print(json.dumps({"schema_version": 1, "ok": False, "error": {"code": "drafting_failed", "message": str(exc)}}, ensure_ascii=False))
|
|
else:
|
|
print(f"\nstrata: {exc}", file=sys.stderr)
|
|
return 5
|
|
if machine:
|
|
print(json.dumps({"schema_version": 1, "ok": True, "event": "result", "pack": str(out)}, ensure_ascii=False))
|
|
else:
|
|
print(f"\nThe DFlash2 drafter is ready: {out}")
|
|
return 0
|