arle(1)
pure rust · one binary · apple silicon + nvidia · anthropic + openai apis
rle

Point your coding agent
at a local model.

Claude Code, opencode, aider: every turn re-sends the whole conversation. ARLE keeps the KV cache alive across turns and prefills only what the turn added — turn 20 starts as fast as turn 2.

api anthropic /v1/messages · openai v1 metal beta · apple silicon cuda stable · ampere+ kv prefix cache survives turns spec mtp · dspark · bit-identical release v0.5.8 · 2026-08-21
arle — zsh ~/code
$ arle serve --backend metal --model-path mlx-community/Qwen3.6-35B-A3B-4bitserving on http://127.0.0.1:8000  · /v1/messages · /v1/chat/completions $ ANTHROPIC_BASE_URL=http://localhost:8000 ANTHROPIC_API_KEY=local claude# turn 1: cold prefill of the system promptprefix-lookup  prompt=4850 licensed_blocks=0# turn 2 … turn 12: only the new tokens prefillprefix-attach  matched=8640 restored=8640 committed=8651

Why this exists

Most local servers are built around one prompt. An agent session is a loop: the same system prompt and a growing tool history, twenty times over. ARLE is built around the loop.

reason · 01Turns stay fast.

A coding agent re-sends the whole conversation every turn. ARLE keeps the prior turn's KV on the accelerator, shares prefix pages across requests through a radix cache, and prefills only the tokens the turn added. 12 agent-shaped turns on a MacBook: 180 ms per turn against mlx-lm's 249 ms on the same weights — measured, not projected.

reason · 02Speaks both agent dialects.

Anthropic /v1/messages with streaming events, tool_use and extended-thinking blocks, and OpenAI /v1/chat/completions with streaming and tools. Claude Code needs one environment variable; any model string is routed to the served model.

reason · 03One binary, no Python.

Pure Rust from the HTTP layer to the scheduler and the KV cache. Metal runs through an MLX C++ bridge, NVIDIA through FlashMLA, DeepGEMM and DeepEP with CUDA graphs. brew install, one curl line, or a Docker image — clone to first token in minutes.

reason · 04Numbers are dated.

Every figure on this page resolves to a dated snapshot in docs/experience/wins/ with the command, the environment, and the arm it beat. Speculative decode is verified bit-identical to greedy; restored prefixes are gated against cold prefill with a needle ladder.

Architecture

One runtime, three surfaces, two backends. Serving, the local agent, and OPD training run the same Rust and model code; dependencies flow strictly downward and infer-core carries no backend dependency. Canonical topology lives in docs/codebase-map.md.

bin
arle the only binary the workspace builds · src/main.rs
control plane
cliagentchattools REPL · session loop · protocol · sandboxed tools
front door
infer-api InferenceEngine · LoadedInferenceEngine · backends plug in here
server · core
infer-serverinfer-core Anthropic + OpenAI facade (axum) · Engine<E,K> · scheduler · radix prefix cache
seam · ir
infer-seaminfer-plan BackendExecutor + KvPool seam · ForwardPlan IR — host-only
backends
infer-cudainfer-metal feature-gated · metal’s host KV pool doubles as the cpu smoke path
kernels
cuda-kernelsmlx-syskv-native-sys CUDA C / TileLang · MLX C++ bridge · KV persistence
pure leaves · infer-topo · infer-moe · infer-utilspecs · qwen3 · qwen35 · deepseekffi · deepep-sys · xgrammar-systrain · autograd + train — OPD only; the teacher is the serving engine

Install and connect

One runnable line per platform, then one environment variable for your agent. Pre-built tarballs and SHAs on each GitHub Release; the curl installer verifies SHA256 before extracting.

Apple Silicon · Homebrew zsh / bash
$ brew install cklxx/tap/arle
$ arle serve --backend metal --model-path mlx-community/Qwen3.6-35B-A3B-4bit
Linux x86_64 / macOS · curl sh-compatible
$ curl -fsSL https://github.com/acupof-ai/arle/releases/latest/download/install.sh \
    | sh
$ arle --doctor
CUDA · GPU container docker / nvidia
$ docker run --rm --gpus all -p 8000:8000 \
    -v $PWD/models:/models:ro ghcr.io/acupof-ai/arle:latest \
    serve --backend cuda --model-path /models/Qwen3.6-27B
Connect · Claude Code / OpenAI clients any shell
$ ANTHROPIC_BASE_URL=http://localhost:8000 ANTHROPIC_API_KEY=local claude
$ export OPENAI_BASE_URL=http://localhost:8000/v1 OPENAI_API_KEY=local
# opencode, aider, the openai SDK — anything that speaks the OpenAI API

Bench

Dated, reproducible snapshots straight from docs/experience/wins/ and benchmarks/. Decode and prefill are reported separately; nothing is an end-to-end blend.

2026-09-02 beta · default-on

metal · M4 Pro 48 GB · Qwen3.5-0.8B-MLX-4bit · 12-turn agent conversation, 4.8K-token system prompt, +~350 tokens per turn · same weights and request bytes for both servers

TTFT · turns 2–12 median
180ms
mlx-lm 0.31.2 · same
249ms
TTFT · turn 12
202ms · 8.6K tokens
restored vs cold
18/18needle exact · DET
scripts/bench_multiturn_ttft.py --turns 12 --warmup snapshot ↗
2026-06-14 beta · snapshot

metal · M4 Pro 48 GB · Qwen3.6-35B-A3B-4bit (MoE, ~3B active) · 512-in / 128-out · single stream · median of 6

decode
85.3tok/s
time per token
11.7ms
TTFT · 512 tokens
1.23s
Qwen3.5-0.8B decode
318tok/s
arle serve --backend metal --model-path mlx-community/Qwen3.6-35B-A3B-4bit snapshot ↗
2026-08-14 stable · anchor

cuda · 1×H20 · Qwen3.6-27B-FP8 + block-drafter speculative decode (DSpark) · 32K-token multi-turn agent prompts · per-request decode

decode · c=1
91.8tok/s
decode · c=8
20.5tok/s
35B-A3B MoE · c=1
149.3tok/s
vs SGLang 0.5.13 · decode
−2.8% per token
arle serve --backend cuda --spec-type dspark · bench-agent-32k snapshot ↗
2026-08-20 beta · default-on

cuda · 1×H20 · Qwen3.8-27B-NVFP4 vs Qwen3.6-27B-FP8 · same binary, both arms back to back · nothing resident twice

decode · c=1
+21.3% vs FP8
end-to-end · c=4
+15.3% vs FP8
resident
22.4GB · FP8 29.4
GSM8K-shaped
188/200FP8 189/200
arle serve --backend cuda --model-path unsloth/Qwen3.8-27B-NVFP4 snapshot ↗
2026-08-23 beta · default-on

cuda · 4×H20 TP=4 · DeepSeek-V4-Flash · c=1 decode body captured into one CUDA graph per slot · 32K agent prompts

decode · NVFP4 experts
44.2tok/s · was 40.8
decode · FP8 experts
59.5tok/s · was 52.4
ITL p50
22.2ms · was 24.1
MMLU · 200 items
0per-item diffs
arle serve --backend cuda --tensor-parallel-size 4 snapshot ↗
2026-06-20 beta · multi-seed

train · On-Policy Distillation · the teacher is the serving engine, the student trains on its own rollouts · Qwen3.5-4B and Qwen3.5-27B

MATH-500 · 4B
+27pp · 0.518 → 0.792
Terminal-Bench · 27B
+5.1pp pass@1
BFCL-live abstention
1.00from 0.60
python on the hot path
0processes
arle train opd snapshot ↗

Support matrix

Two backends, one runtime contract. Authoritative truth lives in docs/support-matrix.md.

backendstabilityos / hardwaremodelsquantsapi
cudastableLinux + NVIDIA Ampere+ · 1–8 GPUs (TP / EP)Qwen3.5 / 3.6 / 3.8 · DeepSeek-V4-Flash · GLM-5.2BF16 · FP8 · NVFP4 · W4AFP8 · INT8/FP8 paged KVAnthropic + OpenAI
metalbetaApple Silicon (M1+)Qwen3.5 / 3.6 MoE (canonical) · Qwen3 dense · DeepSeek-OCRMLX 4-bit · BF16Anthropic + OpenAI
cpudev onlyportable smokeQwen3.5 (small)BF16Anthropic + OpenAI

Where a contribution lands

No queue, no committee — a weekend PR here can move a headline number, and the fronts are public. Start with CONTRIBUTING.md.

Stars are the only metric a small project has. If ARLE made your agent loop faster than what you had, leave one. It decides how much time this gets.

★ Star acupof-ai/arle

Files

The repo at a glance. Everything links back to canonical paths in acupof-ai/arle.