Squeeze-Evolve
Multi-model orchestration for verifier-free evolutionary test-time scaling.
Squeeze-Evolve routes each step of an evolutionary inference loop to the most cost-effective model. Expensive models handle the hardest groups; cheap models handle the rest. The result: equivalent or better accuracy at a fraction of the cost.
Use it in Claude Code
Run Squeeze-Evolve on any query directly in Claude Code via the bundled plugin — no setup, no API keys (it uses your own Claude session):
/plugin marketplace add squeeze-evolve/squeeze-evolve
/plugin install squeeze-evolve@squeeze-evolve
/squeeze-evolve:ask <your question>
It samples candidate answers from a strong model, then evolves them — clustering by answer-diversity and routing recombination to cheap vs. expensive models (consensus → free, low → haiku, medium → sonnet, high → opus) — and returns a synthesized answer with a routing trace. Details in plugins/squeeze-evolve/.
Install
# Clone with the vllm submodule
git clone --recurse-submodules [email protected]:squeeze-evolve/squeeze-evolve.git
cd squeeze-evolve
# Recommended (uv)
uv sync --dev
# Or with pip
pip install -e ".[dev]"
Optional extras:
# Forked vllm with custom confidence engine
VLLM_USE_PRECOMPILED=1 uv pip install --editable external/vllm
# Cloud storage for checkpoints
uv sync --dev --extra aws # Amazon S3
uv sync --dev --extra gcs # Google Cloud Storage
Quick start
# Run the evolutionary loop on a dataset
squeeze-evolve-client \
--config benchmarks/aime25/configs/example.yaml \
--input data/aime25/test.parquet \
--n-problems 5
# Save results to a file
squeeze-evolve-client \
--config benchmarks/aime25/configs/example.yaml \
--input data/aime25/test.parquet \
--output results.json
# Start the HTTP server
squeeze-evolve-server --host 0.0.0.0 --port 8080
How it works
Squeeze-Evolve runs an evolutionary loop over a population of candidate solutions. Each loop refines the population by scoring, grouping, and recombining candidates, with the key innovation being fitness-based routing: each group is sent to the model best suited for its difficulty.
Loop 0 (initialization). The most expensive model generates an initial population of N candidate solutions per problem. Initialization quality is the single strongest predictor of final accuracy, so this step uses the best model available.
Loops 1..T (evolution). Each subsequent loop runs five stages:
-
Score. A fitness signal (group confidence or answer diversity) is computed for each candidate. Confidence uses token log-probabilities already produced during inference; diversity counts unique answers. Both are zero- or near-zero-cost proxies for group difficulty.
-
Select. Candidates are grouped into subsets of size K. Groups can be formed uniformly at random or via fitness-weighted sampling.
-
Route. Each group's fitness determines which model recombines it. Per-problem adaptive thresholds at configurable percentiles split groups into N tiers:
- Low fitness (hard, uncertain) → most expensive model
- High fitness (easy, consensus) → cheapest model
- Full consensus → lightweight non-LLM aggregation (majority vote)
-
Recombine. Each model receives its assigned groups in parallel and generates a single refined candidate per group. The N model batches and the lite aggregation all execute concurrently.
-
Update. New candidates replace or accumulate into the population for the next loop.
Configuration
Configs load from YAML, JSON, or Python files via load_run_config().
run_name: my_run