pure rust · one binary · apple silicon + nvidia · anthropic + openai apis
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
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
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
Qwen3.5-0.8B decode
318tok/s
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
35B-A3B MoE · c=1
149.3tok/s
vs SGLang 0.5.13 · decode
−2.8% per token
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
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
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
Support matrix
Two backends, one runtime contract. Authoritative truth lives in docs/support-matrix.md.
| backend | stability | os / hardware | models | quants | api |
cuda | stable | Linux + NVIDIA Ampere+ · 1–8 GPUs (TP / EP) | Qwen3.5 / 3.6 / 3.8 · DeepSeek-V4-Flash · GLM-5.2 | BF16 · FP8 · NVFP4 · W4AFP8 · INT8/FP8 paged KV | Anthropic + OpenAI |
metal | beta | Apple Silicon (M1+) | Qwen3.5 / 3.6 MoE (canonical) · Qwen3 dense · DeepSeek-OCR | MLX 4-bit · BF16 | Anthropic + OpenAI |
cpu | dev only | portable smoke | Qwen3.5 (small) | BF16 | Anthropic + 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.
- P1 · active Multi-turn TTFT on the 35BThe per-turn table ships on Qwen3.5-0.8B. The canonical Qwen3.6-35B-A3B row needs a MacBook without swap pressure; the script and the method are in the repo scripts/bench_multiturn_ttft.py · benchmarks/
- P1 · active Batched speculative verifySpeculative decode is inert from c=4 until the verify step is batched; the measured top lever on the NVFP4 27B, projected −32% decode latency at c=16 infer-cuda · docs/plans/2026-08-21-batched-mtp-verify.md
- P2 · active Prefill parity with SGLangDecode is 2.8% faster than SGLang on the same kernel; prefill of a 33K prompt is 19% slower (25.0 s vs 21.0 s) infer-cuda · docs/baselines.md
- P2 · queued Cold page-read latency of the KV tiersPrefix pages demote to host RAM and disk under pressure; a decode step stalling on a cold page is the design risk, and its latency is unmeasured infer-core · kv-native-sys
- open Distill your agent tracesOn-Policy Distillation from a DeepSeek-V4-Flash teacher into a 35B student on the serving engine; today the teacher runs on CUDA only train · autograd
- open Third backends: HIP / VulkanHIP substrate and a coherent Vulkan forward (gfx1151) landed; the license is performance parity, not a boot infer-hip · infer-vulkan · #71
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.