feat: prioritize proven GPU framework combinations

This commit is contained in:
CoolBoy
2026-08-05 18:21:59 +08:00
parent 882479e43e
commit 5e47d9e695
11 changed files with 431 additions and 86 deletions

View File

@@ -17,13 +17,12 @@ DEFAULT_GPU_STRATEGY_PATH = Path(".modelhub_state/gpu_strategy.json")
DEFAULT_REFRESH_SUBMISSIONS = 200
DEFAULT_RECENT_TERMINAL_WINDOW = 1000
DEFAULT_LONG_TERM_MIN_SAMPLES = 100
STRATEGY_STATE_VERSION = 2
STRATEGY_STATE_VERSION = 3
LONG_TERM = "long_term"
ALL_SUPPORTED = "all_supported"
RECENT = "recent"
CATEGORIES = (LONG_TERM, ALL_SUPPORTED, RECENT)
CATEGORY_WEIGHTS = {LONG_TERM: 5, ALL_SUPPORTED: 3, RECENT: 2}
CATEGORIES = (LONG_TERM, RECENT)
CATEGORY_WEIGHTS = {LONG_TERM: 7, RECENT: 3}
def _empty_category_counts() -> dict[str, int]:
return {category: 0 for category in CATEGORIES}
@@ -354,7 +353,7 @@ class GPUStrategyManager:
self.log(
f"[strategy] {action} generation={self.state.get('generation', 0)} "
f"accepted={self.state.get('acceptedSinceRefresh', 0)}/{self.state.get('refreshSubmissions', self.refresh_submissions)} "
f"categories={counts.get(LONG_TERM, 0)},{counts.get(ALL_SUPPORTED, 0)},{counts.get(RECENT, 0)} "
f"categories={counts.get(LONG_TERM, 0)},{counts.get(RECENT, 0)} "
f"long={','.join(self.state.get('longTermGpus') or [])} recent={self.state.get('recentGpu') or 'n/a'}"
)
@@ -377,20 +376,25 @@ class GPUStrategyManager:
recent = [recent_gpu]
if category == LONG_TERM:
eligible = long_term
eligible = list(long_term)
base_pattern = (5.0, 3.0, 2.0)
elif category == RECENT:
eligible = recent
base_pattern = (6.0, 3.0, 1.0)
else:
eligible = supported
base_pattern = tuple(1.0 for _ in eligible)
eligible = list(recent)
base_pattern = (6.0, 3.0, 1.0)
if self.market_intelligence is not None:
try:
vetted = self.market_intelligence.eligible_gpus(supported)
except Exception:
vetted = supported
eligible = [gpu for gpu in eligible if gpu in vetted]
eligible.extend(gpu for gpu in vetted if gpu not in eligible)
if not eligible:
return []
weights: dict[str, float] = {}
for index, gpu in enumerate(eligible):
base = base_pattern[min(index, len(base_pattern) - 1)]
base = base_pattern[index] if index < len(base_pattern) else 0.5
market_weight = 1.0
if self.market_intelligence is not None:
try:
@@ -460,9 +464,13 @@ class GPUStrategyManager:
break
if selected is None:
# With market intelligence enabled, an empty vetted pool means
# stop instead of silently turning fallback into exploration.
if self.market_intelligence is not None:
break
# Unknown/custom GPUs can only appear when callers bypass the normal resolver.
selected = next((candidate for candidate in candidates if candidate_key(candidate) not in used), None)
actual_category = ALL_SUPPORTED
actual_category = planned_category
if selected is None:
break
@@ -508,9 +516,9 @@ class GPUStrategyManager:
for category in CATEGORIES
}
for candidate in candidates:
category = str(candidate.get("strategyCategory") or ALL_SUPPORTED)
category = str(candidate.get("strategyCategory") or LONG_TERM)
if category not in category_counts:
category = ALL_SUPPORTED
category = LONG_TERM
category_counts[category] += 1
gpu = str(candidate.get("targetGpu") or "")
if gpu in gpu_category_counts[category]: