Skip to content

ui : add model compatibility estimation - #27957

Open
allozaur wants to merge 2 commits into
allozaur/ui/hf-data-layerfrom
allozaur/ui/model-compatibility
Open

ui : add model compatibility estimation#27957
allozaur wants to merge 2 commits into
allozaur/ui/hf-data-layerfrom
allozaur/ui/model-compatibility

Conversation

@allozaur

@allozaur allozaur commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Overview

Adds model hardware-compatibility estimation for the web UI:

  • New model-compatibility.ts util (ported from llama-macos): color-codes each GGUF in a repo as full (green, fits at native context), limited (yellow, fits at reduced context) or none (red)
  • Device memory budget mirrors llama.cpp's --fit-target logic: ~75% of RAM for the GPU working set minus 1 GB slack, clamped by a 4 GB OS floor
  • Memory estimate = file size + 5% overhead + KV cache (~0.1 MB / 1k tokens)
  • Main quants, their shards, mmproj and draft sidecars are grouped and share a tier; sidecars pair with the closest-quant main, mirroring find_best_sibling
  • Device RAM from user settings, falling back to navigator.deviceMemory; unknown memory = no badges
  • New detectToolUseSupport() util: infers tool-calling support from the chat template (no server flag exists)
  • Exports detectOs for reuse

Additional information

Requirements

@allozaur
allozaur force-pushed the allozaur/ui/model-compatibility branch 2 times, most recently from 25e0e56 to e9d6f6d Compare August 31, 2026 10:56
@allozaur
allozaur marked this pull request as ready for review August 31, 2026 10:56
@allozaur
allozaur requested a review from a team as a code owner August 31, 2026 10:56
Copilot AI lite review requested due to automatic review settings August 31, 2026 10:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds client-side utilities in the UI to (1) estimate whether a GGUF quant “fits” into a device’s memory budget and (2) infer tool-calling support by inspecting a model’s chat template. This supports richer model browsing/selection UX without requiring new server flags.

Changes:

  • Add a model hardware-compatibility estimation module that tiers GGUF files (full / limited / none) based on estimated memory use.
  • Add a chat-template heuristic to detect tool-use capability.
  • Export the new utilities from the UI utils barrel, and expose detectOs from browser-info.ts.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
tools/ui/src/lib/utils/model-compatibility.ts New compatibility estimator (memory budget + shard/sidecar grouping + tiering).
tools/ui/src/lib/utils/chat-template-tool-detector.ts New heuristic detector for tool-calling support via template inspection.
tools/ui/src/lib/utils/index.ts Re-export new utility APIs from the utils barrel.
tools/ui/src/lib/utils/browser-info.ts Make detectOs an exported helper (previously file-local).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +39 to +60
const MB = 1024 * 1024;
/** Hardcoded device RAM (GB) for testing the compatibility UI; 0 disables it. */
const TEST_DEVICE_MEMORY_GB = 128;

/**
* Resolve the device memory in GB: the user's settings override when set,
* else the browser's `navigator.deviceMemory` (Chrome/Edge only, capped at 8).
* Returns 0 when neither is available, which callers treat as "unknown".
*/
export function resolveDeviceMemoryGb(configuredGb: number): number {
// Hardcoded device RAM for testing the compatibility UI; 0 disables the
// override. TODO: remove once the device-memory source is trusted.
if (TEST_DEVICE_MEMORY_GB > 0) return TEST_DEVICE_MEMORY_GB;

if (configuredGb > 0) return configuredGb;

if (!browser) return 0;

const nav = navigator as Navigator & { deviceMemory?: number };

return typeof nav.deviceMemory === 'number' && nav.deviceMemory > 0 ? nav.deviceMemory : 0;
}
Comment on lines +198 to +222
const ctxBytesPer1k = ctxBytesPer1kTokens(nativeCtxTokens);
const fits = (ctxTokens: number) =>
weightMb + (ctxBytesPer1k * (ctxTokens / 1000)) / MB <= budgetMb;

if (nativeCtxTokens < MIN_CTX_TOKENS) return 'none';

if (fits(nativeCtxTokens)) return 'full';

// Find the largest standard tier that still fits within the native window.
const largestFitting = [...CTX_TIERS]
.filter((t) => t <= nativeCtxTokens)
.reverse()
.find((t) => fits(t));

return largestFitting !== undefined ? 'limited' : 'none';
}

/**
* Approximate KV-cache bytes per 1k tokens. Without a MemProfile probe (which
* only exists post-launch in llama-macos) we estimate from the native context
* window; ~0.1 MB per 1k tokens is a conservative mid-range for modern models.
*/
function ctxBytesPer1kTokens(_nativeCtxTokens: number): number {
return 0.1 * MB;
}
Comment on lines +22 to +28
export function detectToolUseSupport(t: string): boolean {
if (!t) return false;

if (JINJA_TOOLS_VAR.test(t)) return true;

return TOOL_CALL_TOKENS.some((token) => t.includes(token));
}
Comment on lines +81 to +90
export function computeFileCompatibilityTiers(
files: HfModelSibling[],
nativeCtxTokens: number,
deviceMemoryGb: number
): Map<string, CompatibilityTier> {
const tiers = new Map<string, CompatibilityTier>();

// Unknown device memory: leave every file untiered (neutral) rather than
// guessing a fit we cannot back up.
if (deviceMemoryGb <= 0) return tiers;
@allozaur
allozaur force-pushed the allozaur/ui/model-compatibility branch from e9d6f6d to 3259c9c Compare August 31, 2026 12:49
@allozaur
allozaur force-pushed the allozaur/ui/model-compatibility branch 2 times, most recently from 7e6bc67 to 58677fe Compare August 31, 2026 21:46
Port the hardware-compatibility estimator from ggml-org/llama-macos:
map every GGUF file in a repo to a full/limited/none tier based on
the device memory budget (GPU working set approximated from RAM, less
fit slack and an OS floor) and the estimated weight + context memory.

Main quants are tiered individually; shards, mmproj and quant-matched
draft sidecars inherit their main quant's tier. Sidecar picking
mirrors the server's find_best_sibling ranking (deepest directory,
exact quant tag, closest bit depth).

Also port detectToolUseSupport (infers tool-calling support from a
chat template) and the browser get_info fallback helper.

Assisted-by: pi
Replace the device-memory tier machinery with a plain file-size
estimate: required runtime memory is the model file size with
headroom for KV cache and allocator overhead (estimateModelMemoryBytes).
Callers present the requirement; there is no device detection and no
fit-versus-budget verdict.

Drops resolveDeviceMemoryGb, deviceMemoryBudgetMb,
computeFileCompatibilityTiers and the CompatibilityTier type, and the
barrel keeps only the new estimator.

Assisted-by: pi
@allozaur
allozaur force-pushed the allozaur/ui/model-compatibility branch from 58677fe to a07359e Compare August 31, 2026 22:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants