diff --git a/studio/backend/utils/models/model_config.py b/studio/backend/utils/models/model_config.py index 72cbc40cd3..8df53a28c9 100644 --- a/studio/backend/utils/models/model_config.py +++ b/studio/backend/utils/models/model_config.py @@ -962,18 +962,10 @@ def list_gguf_variants( ) ) - # Sort: recommended first, then UD variants by size, then non-UD by size. - best_file = _pick_best_gguf([v.filename for v in variants]) - best_quant = _extract_quant_label(best_file) if best_file else None - - def _sort_key(v: GgufVariantInfo) -> tuple: - is_recommended = v.quant == best_quant - is_ud = v.quant.startswith("UD-") - # (0, ...) recommended | (1, 0, -size) other UD | (1, 1, -size) non-UD - # Negative size so largest (best quality) appears first. - return (0 if is_recommended else 1, 0 if is_ud else 1, -v.size_bytes) - - variants.sort(key = _sort_key) + # Sort by size descending (largest = best quality first). + # Recommended pinning and OOM demotion are handled client-side + # where GPU VRAM info is available. + variants.sort(key = lambda v: -v.size_bytes) return variants, has_vision diff --git a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx index 1ce7f40cca..cc399c39c5 100644 --- a/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx +++ b/studio/frontend/src/components/assistant-ui/model-selector/pickers.tsx @@ -206,7 +206,24 @@ function GgufVariantExpander({ ); } - if (!variants || variants.length === 0) { + const sortedVariants = useMemo(() => { + if (!variants) return variants; + return [...variants].sort((a, b) => { + const aIsRec = a.quant === defaultVariant; + const bIsRec = b.quant === defaultVariant; + if (aIsRec !== bIsRec) return aIsRec ? -1 : 1; + + const aGb = a.size_bytes / (1024 ** 3); + const bGb = b.size_bytes / (1024 ** 3); + const aOom = gpuGb != null && gpuGb > 0 && aGb > 0 && checkVramFit(aGb, gpuGb) === "exceeds"; + const bOom = gpuGb != null && gpuGb > 0 && bGb > 0 && checkVramFit(bGb, gpuGb) === "exceeds"; + if (aOom !== bOom) return aOom ? 1 : -1; + + return b.size_bytes - a.size_bytes; + }); + }, [variants, defaultVariant, gpuGb]); + + if (!sortedVariants || sortedVariants.length === 0) { return (
No GGUF variants found. @@ -224,7 +241,7 @@ function GgufVariantExpander({ Vision )}
- {variants.map((v) => { + {sortedVariants.map((v) => { const sizeGb = v.size_bytes / (1024 ** 3); const fitStatus = gpuGb != null && gpuGb > 0 && sizeGb > 0 ? checkVramFit(sizeGb, gpuGb)