Model Planner Documentation
Model Planner Documentation
Overview
The ModelPlanner is the single source of truth for all llama-server launch parameter calculations. It reads GGUF model metadata and system hardware information to compute optimal launch parameters that fit available resources.
Purpose
The ModelPlanner determines the best llama-server launch configuration for a given model and system, ensuring:
- The model fits in available RAM and VRAM
- Context size is appropriate for the mode and hardware
- GPU offloading is maximized without overflow
- Batch sizes are optimal for performance
- CPU allocation is efficient
Responsibilities
- Read GGUF metadata - Parse model architecture, quantization, and size
- Detect system hardware - RAM, CPU cores, GPU backend and VRAM
- Compute launch parameters - ctx_size, gpu_layers, batch sizes, threads, flash_attn
- Validate feasibility - Ensure parameters fit in available memory
- Generate estimates - RAM/VRAM usage, tokens per second
- Provide warnings - When requested parameters must be reduced
Dependencies
gguf- GGUF metadata parsingpsutil- System informationcpuinfo- CPU feature detectionllama_tools/planner/types.py- Dataclasses for results
Constraints
- Single source of truth - All calculations must go through ModelPlanner
- No duplicate calculations - Doctor, interfaces must use Planner results
- Fail-safe - If model won't fit, return can_run=false with suggestions
- Overrides validation - User overrides are validated and degraded when needed
- Minimum context - Never allow ctx_size below MIN_CTX (512 tokens)
Extension Points
Adding a New Model Type
If supporting a new model format:
- Add parsing logic to
GgufMetadataReader - Update
ModelMetadatadataclass if needed - Ensure GGUF format is maintained (llama.cpp standard)
Adding a New Optimization Mode
- Add to
OptimizationModeenum intypes.py - Add batch defaults in
MODE_DEFAULTSinestimator.py - Add target context fraction in
mode_target_ctx_fraction() - Add flash_attn logic in
flash_attn_for_mode()
Adding Hardware Detection
- Add detection function in
SystemProbe - Update
SystemInfodataclass if needed - Use detection results in
max_gpu_layers()orfits_in_memory()
Module Details
llama_tools/planner/planner.py - ModelPlanner
The main orchestration class that:
- Reads or uses provided metadata
- Detects system (or uses provided)
- Applies user overrides with validation
- Computes optimal parameters
- Validates memory fit
- Returns PlanResult
Key methods:
plan()- Main planning method
llama_tools/planner/gguf_reader.py - GgufMetadataReader
Reads GGUF metadata from model files:
- Architecture, layers, parameters
- Embedding length, context length
- Quantization type
- File size (handles sharded models)
llama_tools/planner/system_probe.py - SystemProbe
Detects system hardware:
- RAM available/total
- CPU physical and logical cores
- AVX2/AVX-512 support
- Accelerator backend (CUDA, ROCm/HIP on Linux and Windows, Vulkan, Metal) through provider probes
- GPU VRAM total/free
- All detected accelerators plus whether memory availability is measured or estimated
- GPU name
llama_tools/planner/storage_probe.py - StorageProbe
Path-scoped probe for the volume that holds the model GGUF (Windows / macOS / Linux):
- Whether the volume is an SSD (
is_ssd; unknown → fail-closed, no budget expand) - Free / total disk space on that volume
- OS swap / pagefile totals via
psutil.swap_memory()
Attached onto SystemInfo.model_volume during ModelPlanner.plan().
llama_tools/planner/estimator.py - Estimator
Contains all calculation formulas:
split_memory()/split_memory_detailed()- Calculate RAM/VRAM split (and CPU pinned vs weights)fits_in_memory()- Check if parameters fit (physical RAM + optional SSD virtual RAM)effective_ram_budget_mb()/ssd_virtual_ram_mb()- SSD-backed budget helpersmax_ctx_that_fits()- Find max contextmax_gpu_layers()- Find max GPU layersestimate_speed()- Estimate tokens/secbuild_estimate()- Build PlanEstimatebuild_minimum_resources()- Minimum requirements
llama_tools/planner/types.py - Dataclasses
Type definitions:
ModelMetadata- GGUF model metadataModelVolumeInfo- Model path volume (SSD / free space / swap)SystemInfo- System hardware infoLaunchParams- Launch parametersLaunchOverrides- User overridesPlanEstimate- Resource estimatesPlanWarning- Parameter warningsRecommendation- Advice messagesPlanResult- Complete planning resultMinimumResources- Minimum requirements
Calculation Details
Memory Split
The model and KV cache are split between RAM and GPU:
GPU:
- GPU layers weights
- Proportional KV cache (same ratio as layers)
- GPU buffers for computation
RAM:
- CPU layers weights
- Remaining KV cache
- CPU buffers
SSD-backed virtual RAM
When the model path is on an SSD, free disk space can expand the effective RAM budget so models larger than physical RAM may still plan as runnable:
physical_budget = ram_available_mb - os_reserve_mb
virtual_budget = max(0, volume_free_mb - disk_reserve_mb) # SSD only; else 0
effective_budget = physical_budget + virtual_budget
Rules:
- Non-SSD / unknown media → no expansion (fail-closed).
- CPU-side KV + compute buffers must fit in
physical_budget; only CPU-resident weights may spill to SSD (mmap / paging). - VRAM accounting is unchanged.
- Config:
llama.disk_reserve_mb(default 4096), same spirit asos_reserve_mb. - When virtual RAM is required, planner emits a
PlanWarningon fieldram_budget.
GPU Layers Calculation
Uses binary search to find maximum GPU layers that fit:
- Start with requested or full offload
- Test if parameters fit
- Binary search for maximum
- Respect VRAM safety margin (90%)
Context Size Calculation
- Mode target (25%/50%/100% of model context)
- Maximum that fits in memory
- User override (if provided)
- Round down to power of 2
- Minimum MIN_CTX (512 tokens)
Batch Sizes
Mode-dependent defaults:
- SPEED: n_batch=2048, n_ubatch=512
- BALANCED: n_batch=1024, n_ubatch=256
- QUALITY: n_batch=512, n_ubatch=128
Adjusted to fit memory, halved if needed.
Speed Estimation
Based on:
- Quantization (Q4_K fastest, F32 slowest)
- GPU offload ratio
- AVX2/AVX-512 support
- Context size penalty (sqrt scaling)
- Flash attention (if available)
Usage Examples
Basic Planning
from core.planner import ModelPlanner
planner = ModelPlanner()
plan = planner.plan(
model_path="C:/llama/model.gguf",
mode="balanced",
)
With Overrides
from core.planner import LaunchOverrides
overrides = LaunchOverrides(ctx_size=4096, threads=8)
plan = planner.plan(
model_path="C:/llama/model.gguf",
mode="quality",
overrides=overrides,
)
Programmatic Planning
from core.planner import ModelPlanner, LaunchOverrides
planner = ModelPlanner(os_reserve_mb=4096)
# Plan for model
plan = planner.plan(
model_path="C:/llama/model.gguf",
mode="balanced",
overrides=LaunchOverrides(threads=12),
)
if plan.can_run:
print(f"Recommended: ctx={plan.recommended.ctx_size}, "
f"gpu={plan.recommended.gpu_layers}")
else:
print(f"Cannot run: {plan.reason}")
for suggestion in plan.minimum_required.suggestions:
print(f" - {suggestion}")
Launch Parameters
ctx_size
Context window size (tokens). Must be power of 2, minimum 512.
gpu_layers
Number of layers to offload to GPU. Maximum is model block_count.
n_batch
Batch size for processing. Affects throughput and memory.
n_ubatch
Micro-batch size for flash attention. Must be ≤ n_batch.
threads
Number of CPU threads for inference.
threads_batch
Threads for batched requests (same as threads by default).
flash_attn
Flash attention setting: "on", "off", or "auto".
cache_type_k / cache_type_v
KV cache data type: f16, q8_0, q4_0, etc.
Performance Estimates
PlanEstimate provides:
ram_mb- Estimated RAM usagevram_mb- Estimated VRAM usagekv_cache_mb- KV cache memorytokens_per_second_min/max- Generation speed range
Warnings
PlanWarning is generated when:
- Requested parameter exceeds available resources
- GPU layers must be reduced
- Context size must be reduced
- Batch sizes must be reduced
- Plan relies on SSD-backed virtual RAM / mmap for CPU weights
Example:
PlanWarning(
field="gpu_layers",
message="Requested gpu_layers=35 exceeds VRAM; reduced to 28",
requested=35,
resolved=28,
)
Recommendations
Recommendation provides advice:
code- Machine-readable identifiermessage- Human-readable messageseverity- "info", "suggestion", "warning", "error"field- Optional link to specific parameter
Integration Points
App Context
The planner is used in app.py to compute resolved model config:
planner = ModelPlanner(os_reserve_mb=config.llama.os_reserve_mb)
plan = planner.plan(...)
recommended = plan.recommended
model_config = ResolvedLlamaModelConfig(
ctx_size=recommended.ctx_size,
gpu_layers=recommended.gpu_layers,
# ...
)
Doctor Interface
Doctor uses Planner (not its own calculations):
planner = create_planner()
doctor = Doctor(planner)
result = doctor.check_model(metadata, system, mode)
Plan Interface
Plan preview uses Planner directly:
planner = ModelPlanner(os_reserve_mb=config.llama.os_reserve_mb)
plan = planner.plan(...)
Testing
Key test cases:
- Model fits with various configurations
- Model doesn't fit (RAM/VRAM insufficient)
- Override validation and degradation
- GPU detection (with/without GPU)
- Context size optimization
- Batch size fitting
- Speed estimation accuracy
Run: python -m pytest packages/llama-tools/tests/test_model_planner.py -v
MTP (Multi-Token Prediction)
When LaunchOverrides.mtp_enabled=True (from llama.models.main.mtp.enabled):
- Planner adds MTP warnings and
MTP_ENABLEDrecommendation - Embedded MTP (no
draft_path): addsMTP_VRAM_OVERHEAD_MB(2500 MB heuristic) to VRAM estimate - Separate draft (
draft_path): reads draft GGUF, computesmtp_spec_draft_nglviadraft_ngl_for_remaining_vram() - If combined VRAM exceeds budget →
can_run=False
Config keys: mtp.enabled, mtp.spec_draft_n_max (2 or 3), mtp.draft_path (optional).
Shared parsing lives in llama_tools/llama_config_parse.py.
Architecture Rules for Planner
- Single Source of Truth - All calculations must be in Planner
- No duplicate calculations - Doctor, interfaces must use Planner results
- Fail-fast - If model won't fit, return can_run=false immediately
- Graceful degradation - Reduce parameters when requested values don't fit
- Document assumptions - All formulas and heuristics should be documented
- Test-driven - Add tests for new calculations