feat: research MoE activated parameter metadata

This commit is contained in:
Hermes Agent
2026-08-26 00:36:12 +10:00
parent 29fe832929
commit 57c8b841f2
6 changed files with 87 additions and 12 deletions
+77 -7
View File
@@ -884,9 +884,50 @@ def _infer_capabilities(name: str, family: str, details: dict[str, Any], adverti
return [cap for cap in order if cap in set(caps)]
def _architecture(name: str, family: str, details: dict[str, Any]) -> tuple[str, bool]:
text = f"{name} {family} {details.get('parent_model', '')}".lower()
moe = any(token in text for token in ("moe", "mixture", "_h_", "a3b"))
def _page_description(html: str) -> str:
patterns = [
r'<meta[^>]+name=["\']description["\'][^>]+content=["\']([^"\']*)',
r'<meta[^>]+property=["\']og:description["\'][^>]+content=["\']([^"\']*)',
r'<meta[^>]+content=["\']([^"\']*)["\'][^>]+(?:name|property)=["\'](?:description|og:description)["\']',
]
for pattern in patterns:
match = re.search(pattern, html, re.I)
if match:
return unescape(re.sub(r"\s+", " ", match.group(1))).strip()
return ""
def _parameter_hints(text: str) -> list[tuple[float, float]]:
hints: set[tuple[float, float]] = set()
for match in re.finditer(r"\b([0-9]+(?:\.[0-9]+)?)\s*B\s*[-_]\s*A\s*([0-9]+(?:\.[0-9]+)?)\s*B\b", text, re.I):
hints.add((float(match.group(1)), float(match.group(2))))
for match in re.finditer(r"\b([0-9]+(?:\.[0-9]+)?)\s*B\b[^.]{0,100}?\b([0-9]+(?:\.[0-9]+)?)\s*B\s+activated\b", text, re.I):
hints.add((float(match.group(1)), float(match.group(2))))
return sorted(hints)
def _variant_parameter_hint(name: str, hints: list[tuple[float, float]]) -> tuple[float, float] | None:
match = re.search(r"(?:[:_-])([0-9]+(?:\.[0-9]+)?)\s*b(?:$|[-_:])", name, re.I)
total = float(match.group(1)) if match else None
active_match = re.search(r"(?:^|[-_:])([0-9]+(?:\.[0-9]+)?)\s*b\s*[-_]?\s*a\s*([0-9]+(?:\.[0-9]+)?)\s*b(?:$|[-_:])", name, re.I)
if active_match:
return float(active_match.group(1)), float(active_match.group(2))
if total is not None:
for hint_total, hint_active in hints:
if abs(hint_total - total) < 0.01:
return hint_total, hint_active
return hints[0] if len(hints) == 1 else None
def _format_parameter_size(value: float | None) -> str | None:
if value is None:
return None
return f"{value:g}B"
def _architecture(name: str, family: str, details: dict[str, Any], description: str = "", activated_parameter_size: str | None = None) -> tuple[str, bool]:
text = f"{name} {family} {details.get('parent_model', '')} {description}".lower()
moe = any(token in text for token in ("moe", "mixture of experts", "mixture-of-experts", "a3b", "activated parameter")) or bool(activated_parameter_size)
label = "Mixture of Experts (MoE)" if moe else "Dense / single-expert"
if family:
label += f" · {family}"
@@ -917,7 +958,14 @@ def _model_view(raw: dict[str, Any], loaded: dict[str, Any] | None = None, sourc
family = str(details.get("family") or (details.get("families") or [""])[0] or "")
capabilities = _infer_capabilities(name, family, details, raw.get("capabilities"))
context_length = details.get("context_length") or raw.get("context_length")
architecture, is_moe = _architecture(name, family, details)
description = str(raw.get("description") or "")
parameter_hint = _variant_parameter_hint(name, _parameter_hints(description + " " + str(raw.get("parameter_text") or "")))
total_parameter_size = str(raw.get("parameter_size") or details.get("parameter_size") or "")
activated_parameter_size = str(raw.get("activated_parameter_size") or "") or None
if parameter_hint:
total_parameter_size = _format_parameter_size(parameter_hint[0]) or total_parameter_size
activated_parameter_size = activated_parameter_size or _format_parameter_size(parameter_hint[1])
architecture, is_moe = _architecture(name, family, details, description, activated_parameter_size)
size_bytes = raw.get("size") or 0
ram_gb, ram_basis = _ram_estimate(size_bytes, details.get("parameter_size"), details.get("quantization_level"), context_length)
loaded = loaded or {}
@@ -937,7 +985,10 @@ def _model_view(raw: dict[str, Any], loaded: dict[str, Any] | None = None, sourc
"family": family or "unknown",
"architecture": architecture,
"is_moe": is_moe,
"parameter_size": details.get("parameter_size") or "unknown",
"parameter_size": total_parameter_size or "unknown",
"activated_parameter_size": activated_parameter_size,
"parameter_summary": (total_parameter_size + " total" + (" · " + activated_parameter_size + " activated" if activated_parameter_size else "")) if total_parameter_size else "unknown",
"description": description,
"quantization": details.get("quantization_level") or "unknown",
"format": details.get("format") or "unknown",
"context_length": context_length,
@@ -1055,8 +1106,22 @@ def _fetch_library_families() -> list[str]:
def _fetch_family_variants(family: str) -> list[dict[str, Any]]:
try:
html = _text_request(f"{REMOTE_OLLAMA}/library/{family}/tags", timeout=30)
return _parse_variant_page(html, family)
tags_html = _text_request(f"{REMOTE_OLLAMA}/library/{family}/tags", timeout=30)
try:
family_html = _text_request(f"{REMOTE_OLLAMA}/library/{family}", timeout=30)
except (HTTPError, URLError, OSError, ValueError):
family_html = tags_html
description = _page_description(family_html) or _page_description(tags_html)
parameter_text = family_html + " " + tags_html
hints = _parameter_hints(parameter_text)
rows = _parse_variant_page(tags_html, family)
for row in rows:
row["description"] = description
hint = _variant_parameter_hint(str(row.get("name") or ""), hints)
if hint:
row["parameter_size"] = _format_parameter_size(hint[0])
row["activated_parameter_size"] = _format_parameter_size(hint[1])
return rows
except (HTTPError, URLError, OSError, ValueError):
return []
@@ -1764,6 +1829,11 @@ def status() -> dict[str, Any]:
def catalog_view(raw: dict[str, Any], source: str) -> dict[str, Any]:
name = str(raw.get("name") or raw.get("model"))
if not raw.get("description"):
family_candidates = family_rows.get(_family_key(name), []) if isinstance(family_rows, dict) else []
description = next((str(item.get("description") or "") for item in family_candidates if item.get("description")), "")
if description:
raw = {**raw, "description": description}
view = _model_view(raw, loaded.get(name), source=source)
view["installed"] = name in installed_names
view["loaded"] = name in loaded