Back to Llmfit

How llmfit Works

docs/how-it-works.md

1.1.27.4 KB
Original Source

How llmfit Works

The scoring model, speed estimation, and the model database.

← Back to README

How it works

  1. Hardware detection -- Reads total/available RAM via sysinfo, counts CPU cores, and probes for GPUs:

    • NVIDIA -- Multi-GPU support via nvidia-smi. Aggregates VRAM across all detected GPUs. Falls back to VRAM estimation from GPU model name if reporting fails.
    • AMD -- Detected via rocm-smi.
    • Intel Arc -- Discrete VRAM via sysfs, integrated via lspci.
    • Apple Silicon -- Unified memory via system_profiler. VRAM = system RAM.
    • Ascend -- Detected via npu-smi.
    • Backend detection -- Automatically identifies the acceleration backend (CUDA, Metal, ROCm, SYCL, CPU ARM, CPU x86, Ascend) for speed estimation.
  2. Model database -- Hundreds models sourced from the HuggingFace API, stored in llmfit-core/data/hf_models.json and embedded at compile time. Memory requirements are computed from parameter counts across a quantization hierarchy (Q8_0 through Q2_K). VRAM is the primary constraint for GPU inference; system RAM is the fallback for CPU-only execution.

    MoE support -- Models with Mixture-of-Experts architectures (Mixtral, DeepSeek-V2/V3) are detected automatically. Only a subset of experts is active per token, so the effective VRAM requirement is much lower than total parameter count suggests. For example, Mixtral 8x7B has 46.7B total parameters but only activates ~12.9B per token, reducing VRAM from 23.9 GB to ~6.6 GB with expert offloading.

  3. Dynamic quantization -- Instead of assuming a fixed quantization, llmfit tries the best quality quantization that fits your hardware. It walks a hierarchy from Q8_0 (best quality) down to Q2_K (most compressed), picking the highest quality that fits in available memory. If nothing fits at full context, it tries again at half context.

  4. Multi-dimensional scoring -- Each model is scored across four dimensions (0–100 each):

    DimensionWhat it measures
    QualityParameter count, model family reputation, quantization penalty, task alignment
    SpeedEstimated tokens/sec based on backend, params, and quantization
    FitMemory utilization efficiency (sweet spot: 50–80% of available memory)
    ContextContext window capability vs target for the use case

    Dimensions are combined into a weighted composite score. Weights vary by use-case category (General, Coding, Reasoning, Chat, Multimodal, Embedding). For example, Chat weights Speed higher (0.35) while Reasoning weights Quality higher (0.55). Models are ranked by composite score, with unrunnable models (Too Tight) always at the bottom.

    Task alignment within the Quality dimension uses a curated per-family benchmark table (llmfit-core/data/use_case_benchmarks.json, aggregated from public coding/reasoning/chat leaderboards), so a strong coding model outranks a larger generalist for --use-case coding even at fewer parameters. Families without an entry fall back to name-based heuristics; corrections to the table are welcome PRs.

  5. Speed estimation -- Token generation in LLM inference is memory-bandwidth-bound: each token requires reading the full model weights once from VRAM. When the GPU model is recognized, llmfit uses its actual memory bandwidth to estimate throughput:

    Formula: (bandwidth_GB_s / model_size_GB) × efficiency_factor

    The efficiency factor (0.55) and per-mode speed multipliers are tunable via the Advanced Configuration popup (A in the TUI). The defaults account for kernel overhead, KV-cache reads, and memory controller effects. This approach is validated against published benchmarks from llama.cpp (Apple Silicon, NVIDIA T4) and real-world measurements.

    The bandwidth lookup table covers ~80 GPUs across NVIDIA (consumer + datacenter), AMD (RDNA + CDNA), and Apple Silicon families.

    For unrecognized GPUs, llmfit falls back to per-backend speed constants:

    BackendSpeed constant
    CUDA220
    Metal160
    ROCm180
    SYCL100
    CPU (ARM)90
    CPU (x86)70
    NPU (Ascend)390

    Fallback formula: K / params_b × quant_speed_multiplier, with per-mode penalties tunable via the Advanced Configuration popup (A in the TUI).

  6. Fit analysis -- Each model is evaluated for memory compatibility:

    Run modes:

    • GPU -- Model fits in VRAM. Fast inference.
    • MoE -- Mixture-of-Experts with expert offloading. Active experts in VRAM, inactive in RAM.
    • CPU+GPU -- VRAM insufficient, spills to system RAM with partial GPU offload.
    • CPU -- No GPU. Model loaded entirely into system RAM.

    Fit levels:

    • Perfect -- Recommended memory met on GPU. Requires GPU acceleration.
    • Good -- Fits with headroom. Best achievable for MoE offload or CPU+GPU.
    • Marginal -- Tight fit, or CPU-only (CPU-only always caps here).
    • Too Tight -- Not enough VRAM or system RAM anywhere.

Model database

The model list is generated by scripts/scrape_hf_models.py, a standalone Python script (stdlib only, no pip dependencies) that queries the HuggingFace REST API. Hundreds models & providers including Meta Llama, Mistral, Qwen, Google Gemma, Microsoft Phi, DeepSeek, IBM Granite, Allen Institute OLMo, xAI Grok, Cohere, BigCode, 01.ai, Upstage, TII Falcon, HuggingFace, Zhipu GLM, Moonshot Kimi, Baidu ERNIE, and more. The scraper automatically detects MoE architectures via model config (num_local_experts, num_experts_per_tok) and known architecture mappings.

Model categories span general purpose, coding (CodeLlama, StarCoder2, WizardCoder, Qwen2.5-Coder, Qwen3-Coder), reasoning (DeepSeek-R1, Orca-2), multimodal/vision (Llama 3.2 Vision, Llama 4 Scout/Maverick, Qwen2.5-VL), chat, enterprise (IBM Granite), and embedding (nomic-embed, bge).

See MODELS.md for the full list.

The model database is embedded at compile time, so end users get updates by upgrading llmfit itself (brew upgrade llmfit, scoop update llmfit, or downloading a newer release). The commands below are for contributors refreshing the database from source:

To refresh the model database:

sh
# Automated update (recommended)
make update-models

# Or run the script directly
./scripts/update_models.sh

# Or manually
python3 scripts/scrape_hf_models.py
cargo build --release

The scraper writes llmfit-core/data/hf_models.json, which is baked into the binary via include_str!. The automated update script backs up existing data, validates JSON output, and rebuilds the binary.

By default, the scraper enriches models with known GGUF download sources from providers like unsloth and bartowski. Results are cached in data/gguf_sources_cache.json (7-day TTL) to avoid repeated API calls. Use --no-gguf-sources to skip enrichment for a faster scrape.