${ctxSel}
diff --git a/xtts/llm-adapter/adapter.py b/xtts/llm-adapter/adapter.py
index 47e1d9b..5dc6cf3 100644
--- a/xtts/llm-adapter/adapter.py
+++ b/xtts/llm-adapter/adapter.py
@@ -771,6 +771,13 @@ def _ctx_profile(key: str) -> dict:
weights, mmproj = _model_files(key)
if not weights:
return {}
+ return _profile_of_files(weights, mmproj, lambda: _model_cpu_moe(key))
+
+
+def _profile_of_files(weights: str, mmproj, cpu_moe_of=lambda: 0) -> dict:
+ """Wie _ctx_profile, aber fuer beliebige Dateien — auch heruntergeladene
+ Modelle, die (noch) auf keiner Karte liegen. cpu_moe_of: Aufteilung der
+ Experten (0 = Schaetzung "alles auf der Karte")."""
meta = _gguf_meta(weights)
arch = meta.get("general.architecture")
if not arch:
@@ -784,7 +791,7 @@ def _ctx_profile(key: str) -> dict:
ctx_max = int(g("context_length", 0) or 0)
exp_by_layer = meta.get("_expert_bytes_by_layer") or {}
moe = bool(exp_by_layer) or int(g("expert_count", 0) or 0) > 0
- cpu_moe = _model_cpu_moe(key) if moe else 0
+ cpu_moe = cpu_moe_of() if moe else 0
if cpu_moe:
layers = sorted(exp_by_layer) if cpu_moe < 0 else sorted(exp_by_layer)[:cpu_moe]
ram_mb = sum(exp_by_layer[l] for l in layers) / 1048576
@@ -1364,6 +1371,25 @@ async def _prefetch(ws, key: str, repo: str, files: list, card: str, cancel: thr
return err
+def _disk_profiles(repo_dir: str) -> list:
+ """Kontext-Profil (Maximum + GB je Stufe, Annahme: alles auf der Karte) je
+ heruntergeladener Quantisierung — damit die Diagnostic auch fuer Modelle,
+ die auf keiner Karte liegen, zeigen kann, was sie koennen und kosten."""
+ import glob
+ files = [p for p in glob.glob(os.path.join(repo_dir, "snapshots", "*", "**", "*.gguf"), recursive=True)
+ if os.path.isfile(p)]
+ mmproj = next((p for p in files if "mmproj" in os.path.basename(p).lower()), None)
+ out = []
+ for w in files:
+ if not _is_main_gguf(w) or _SPLIT_RE.search(w):
+ continue # gesplittete Modelle: Groesse waere nur die des ersten Teils
+ prof = _profile_of_files(w, mmproj)
+ if prof:
+ out.append({"quant": _quant_of(w), **{k: prof[k] for k in ("ctxMax", "options", "moe") if k in prof},
+ **({"expertsMB": prof["expertsMB"]} if "expertsMB" in prof else {})})
+ return out
+
+
def _disk_info() -> dict:
"""Freier Platz + fertig heruntergeladene Modelle (je Repo) fuer die Diagnostic."""
out = {"freeBytes": 0, "models": []}
@@ -1381,7 +1407,8 @@ def _disk_info() -> dict:
except OSError:
pass
if size:
- out["models"].append({"repo": name[len("models--"):].replace("--", "/", 1), "bytes": size})
+ out["models"].append({"repo": name[len("models--"):].replace("--", "/", 1), "bytes": size,
+ "profiles": _disk_profiles(os.path.join(MODELS_DIR, name))})
except OSError as e:
logger.info("Plattenbelegung nicht lesbar: %s", e)
return out