How to Handle Configuration in Colibri: A Complete Guide to Model JSON Setup
Colibri uses a mandatory config.json file and an optional *_meta.json file parsed by the C engine at startup, with strict validation in validate_cfg() to ensure memory safety before model loading.
The JustVugg/colibri engine relies on a JSON-driven configuration system that defines model architecture and runtime parameters. When you handle configuration in Colibri, you are working with a strict schema enforced by the C engine to prevent out-of-bounds memory access and ensure consistent model loading across both Python and CLI interfaces.
Core Configuration Files
Mandatory config.json
Every model directory must contain a config.json file. The C engine parses this file in load_cfg() (located in c/qwen36.c, lines 65-78) to extract fundamental hyperparameters including hidden_size, num_hidden_layers, vocab_size, rms_norm_eps, and the optional rope_theta. If config.json is missing, unreadable, or exceeds 256 MiB, the engine aborts immediately with a clear error message at line 69.
Optional Meta Files for MoE Models
For Qwen-3-MoE architectures, Colibri supports companion meta files (e.g., qwen36_meta.json). The load_meta() function (lines 68-84 in c/qwen36.c) reads these files to overwrite default dimensions derived from config.json. These meta files supply authoritative values for attention heads (q_heads, kv_heads), dimensions (head_dim), and expert-related settings (n_experts, topk), eliminating the need for the engine to infer them.
Configuration Validation and Safety
Hard Limits and Consistency Checks
After loading JSON sources, the engine executes validate_cfg() (lines 120-166 in c/qwen36.c). This function uses the CFG_NEED macro to enforce strict safety limits: n_layers must be between 1 and 512, hidden_size cannot exceed 65536, and topk is capped at 256. The validation also checks consistency between config.json and the meta file, ensuring layer counts match and preventing out-of-bounds memory writes. Any violation triggers an immediate abort with a descriptive error.
Default Fallback Behavior
If the meta file is absent, Colibri falls back to deterministic patterns (specifically i%4==3 for attention layer detection) and hard-coded defaults (lines 81-95 in c/qwen36.c). This ensures minimal stub models load safely even without complete metadata.
Layer Types and Active Count
The optional layer_types array allows explicit per-layer attention type specification (e.g., "full_attention"). Parsed within load_meta() at lines 118-126, this array overwrites the default is_attn pattern and updates the n_active counter to reflect the actual number of active layers.
Runtime Configuration Exposure
The parsed configuration populates the Cfg struct, making parameters available throughout the engine for attention heads, rotary dimensions, and expert counts. Python entry points in colibri/cli.py ultimately invoke the C binary, ensuring identical validation logic regardless of frontend.
Loading Configuration Programmatically
The following Python example mirrors the C engine's validation logic to safely load and verify Colibri configurations:
import json
from pathlib import Path
def load_colibri_config(model_dir: Path) -> dict:
"""Read Colibri's config.json and optional meta file, performing the same checks
the C engine does."""
cfg_path = model_dir / "config.json"
with cfg_path.open("r", encoding="utf-8") as f:
cfg = json.load(f)
# Basic required keys (mirrors load_cfg())
required = ["hidden_size", "num_hidden_layers", "vocab_size", "rms_norm_eps"]
for key in required:
if key not in cfg or not isinstance(cfg[key], (int, float)):
raise ValueError(f"config.json: missing or non‑numeric '{key}'")
# Optional meta overrides
meta_path = next(model_dir.glob("*_meta.json"), None)
if meta_path:
with meta_path.open("r", encoding="utf-8") as f:
meta = json.load(f)
# Override only the fields that exist in the meta file
for k in ("hidden_size", "num_hidden_layers", "q_heads",
"kv_heads", "head_dim", "n_experts", "topk"):
if k in meta:
cfg[k] = meta[k]
# Simple validation (mirrors validate_cfg())
if not (0 < cfg["num_hidden_layers"] <= 512):
raise ValueError("n_layers out of range 1..512")
if cfg["hidden_size"] <= 0 or cfg["hidden_size"] > 65536:
raise ValueError("hidden size out of range")
if cfg["vocab_size"] <= 0:
raise ValueError("vocab must be positive")
# …add further checks as needed…
return cfg
# Example usage
model_dir = Path("/path/to/qwen36_small")
config = load_colibri_config(model_dir)
print("Loaded config:", config)
CLI Configuration Handling
When using the command-line interface, the coli command forwards to the C engine while preserving all configuration handling:
# Install the Python package (editable) and ensure the C engine is built
pip install -e .
# Launch a model located in ./models/qwen36_small
coli run --model-dir ./models/qwen36_small --prompt "Hello, world!"
The coli entry point locates the C engine under c/ and executes the binary, guaranteeing that load_cfg(), load_meta(), and validate_cfg() process your JSON files exactly as described.
Summary
- Colibri requires a mandatory
config.jsonparsed byload_cfg()inc/qwen36.c(lines 65-78) - Optional
*_meta.jsonfiles for MoE models override defaults viaload_meta()(lines 68-84) - The
validate_cfg()function enforces hard limits using theCFG_NEEDmacro: maximum 512 layers, 65536 hidden size, and 256 topk experts - Missing meta files trigger safe defaults using the
i%4==3attention pattern (lines 81-95) - Generation configuration files are handled by
c/tools/repack_fp8_passthrough.pybut not validated by the engine - Both Python and CLI interfaces ultimately rely on the same C-level validation in
c/qwen36.c
Frequently Asked Questions
What happens if config.json is missing or corrupted?
The engine aborts immediately with a descriptive error. At line 69 of c/qwen36.c, load_cfg() checks for file presence, readability, and size limits (256 MiB maximum), terminating if any check fails.
Can I use Colibri without a meta file for MoE models?
Yes, but the engine falls back to hard-coded defaults and deterministic layer patterns (i%4==3). While functional, providing a *_meta.json ensures accurate expert counts and dimensions via load_meta().
How do I validate my configuration before running the model?
The engine automatically runs validate_cfg() (lines 120-166) at startup. For manual validation, mirror these checks in Python: verify num_hidden_layers is between 1-512, hidden_size is positive and ≤ 65536, and vocab_size is positive.
Where does the CLI store generation configuration?
The generation_config.json file is copied by the repack_fp8_passthrough tool (lines 112-119 in c/tools/repack_fp8_passthrough.py) but is not validated by the C engine. Defaults are applied at runtime if this optional file is missing.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →