feat: prioritize proven GPU framework combinations
This commit is contained in:
@@ -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]:
|
||||
|
||||
Reference in New Issue
Block a user