A from-scratch LLM inference runtime for iOS/Android, targeting phones with under 512MB RAM. It's research-grade, not a wrapper around llama.cpp or a port of vLLM.
9
stars
0
commits
Rust
primary language
Aug 8, 2026
updated
A ground-up LLM inference engine for iOS and Android, written in Rust. Brings server-grade serving concepts — paged KV cache, continuous decode scheduling, multi-session concurrency — to phones running under 512MB RAM.
Not a wrapper around llama.cpp. Not a port of vLLM. A new runtime designed for mobile constraints from scratch.
[!NOTE] Status. The CPU and Metal backends, the iOS bindings, and the text models listed under Supported Models are stable and in active use. Metal coverage varies by model; CPU runs everything. The Android AAR and Compose demo build and package the native library, but haven't been validated or tuned on-device. Vulkan sets up the device and pipelines but still runs every op on CPU. The native
.cellmVLM path and the Docker image are experimental or not yet wired up; vision via ONNX is stable. See Feature Status.

| Resource | Path |
|---|---|
| Getting Started | Quick Start below |
| Architecture & Design | docs/project_architecture.md |
| Paged KV Cache Deep Dive | docs/paged-kv-cache-foundation.md |
| Benchmarks | docs/benchmarks/README.md |
| Model Conversion | docs/convert-quantized-models.md |
| VLM (Vision) Guide | docs/vlm-smolvlm-onnx.md (ONNX path; native .cellm is experimental) |
| iOS Demo App | bindings/ios/CellmDemo |
| Android Bindings | bindings/kotlin (builds; not yet device-validated) |
| WASM & WebGPU | docs/wasm-backend.md |
| Live WASM Demo | cellm-wasm ( (Research Preview) |
| Git Commit Messages | Local LLM commit messages below |
| Docker (CPU tooling) | Docker below (planned, not yet wired up) |
cargo build --release
cargo run --release --bin infer -- \
--model models/smollm2-135m.cellm \
--tokenizer models/hf/smollm2-135m/tokenizer.json \
--prompt "Hello, how are you?" \
--chat \
--gen 32
cargo run --release --bin infer -- \
--model models/smollm2-135m-int8.cellm \
--tokenizer models/hf/smollm2-135m/tokenizer.json \
--prompt "Hello" \
--chat \
--gen 16 \
--backend metal
Tip: Use
--chatfor ChatML-style formatting. Without it, many base models behave like text-completion engines and may not answer directly.
cargo run --release --bin metal-smoke
flowchart LR
U["User Prompt"] --> API["App/UI Request Layer"]
API --> ORCH["CPU Orchestrator"]
ORCH --> TOK[Tokenizer]
TOK --> FMT["Prompt Formatter"]
FMT --> SCH["Decode Scheduler / Batcher"]
SCH -->|"prefill/decode jobs"| ENG["Engine Dispatcher"]
ENG -->|backend=CPU| CPUPATH["CPU Kernels"]
ENG -->|backend=Metal| METAL["Metal Kernels"]
METAL --> MATMUL["QKV / MLP MatMul"]
METAL --> ATTN["Attention + GroupKV Cache"]
METAL --> NORM["RMSNorm / RoPE / Logits"]
MATMUL --> SAMPLER
ATTN --> SAMPLER
NORM --> SAMPLER
CPUPATH --> SAMPLER["Sampler + Stop Rules"]
SAMPLER --> DETOK[Detokenizer]
DETOK --> STREAM["Streaming Output"]
STREAM --> API
API --> U
subgraph ModelAssets["Local Model Assets"]
W[".cellm / .cellmd mmap Weights"]
T["tokenizer.json + config"]
end
W --> ENG
T --> TOK
subgraph SessionState["Per-Session State"]
KV["KV Cache (GroupKV layout)"]
PT["Page Table / Sequence Cursor"]
TH["Thermal + QoS Policy"]
end
SCH --> KV
SCH --> PT
ORCH --> TH
TH --> SCH
| Feature | llama.cpp | MLX | ExecuTorch | cellm |
|---|---|---|---|---|
| Language | C++ | C++/Python | C++ | Rust |
| KV Cache | Contiguous | Contiguous | Contiguous | Paged (Block-based) |
| Focus | Portability | Apple Native | Model Export | Mobile Multi-session |
| Scheduling | Static Batch | Mostly Single | N/A | Round-Robin Interleaved |
| Memory | Manual/Static | Managed Buffer | Static Graph | Dynamic Block Allocator |
cellm/
├── crates/
│ ├── cellm-core/ # Memory arena, tensor layout, op dispatch
│ ├── cellm-model/ # Model format, configuration, weight management
│ ├── cellm-cache/ # Paged KV cache: BlockAllocator, PageTable, physical storage
│ ├── cellm-kernels/ # CPU, Metal, WASM & WebGPU compute kernels
│ ├── cellm-scheduler/ # Decode scheduler & batching logic
│ ├── cellm-wasm/ # WebAssembly bindings & JavaScript API
│ └── cellm-sdk/ # Public C FFI + high-level API for mobile consumers
├── bindings/
│ ├── ios/CellmDemo/ # SwiftUI demo app (LLM + VLM stub)
│ ├── kotlin/ # Android Kotlin/JNI bindings
│ └── swift/ # Swift Package + XCFramework build scripts
├── tools/
│ ├── infer/ # CLI inference runner (debug & validation)
│ ├── vlm-onnx-infer/ # VLM runner for SmolVLM ONNX exports
│ ├── vlm-smoke/ # SDK FFI VLM smoke test
│ ├── convert/ # HF Safetensors/GGUF/PyTorch -> .cellm converter
│ ├── bench/ # Latency & throughput benchmark harness
│ └── metal-smoke/ # Minimal Metal kernel compile + dispatch test
├── docs/ # Architecture deep-dives, benchmarks, model guides
└── models/ # Sample .cellm checkpoints (Git LFS)
Convert HuggingFace Safetensors or GGUF to .cellm:
cargo run --bin convert -- \
--input ./models/hf/smollm2-135m \
--output ./models/smollm2-135m.cellm \
--dtype f16
Quantize during conversion:
cargo run --bin convert -- \
--input ./models/hf/smollm2-135m \
--output ./models/smollm2-135m-int8.cellm \
--dtype f16 \
--quantize-int8-symmetric
See docs/convert-quantized-models.md for GGUF, PyTorch, and 4-bit affine workflows.
# Quick smoke benchmark
cargo run --release --bin bench -- --model tiny
# Full LLM backend matrix (CPU vs Metal)
tools/bench/run_llm_backend_matrix.sh
Detailed benchmark reports live in docs/benchmarks/.
# ONNX vision + ONNX decoder (recommended)
cargo build --release -p cellm-vlm-onnx-infer
./target/release/vlm-infer \
--model-dir models/hf/smolvlm-256m-instruct \
--onnx-variant fp16 \
--image models/test_images/rococo.jpg \
--prompt "Describe this image." \
--split-image \
--max-new-tokens 96
Native .cellm vision + decoder is experimental:
./target/release/vlm-infer \
--model-dir models/hf/smolvlm-256m-instruct \
--cellm-model models/smolvlm-256m.cellm \
--vision-backend cellm \
--decoder-backend cellm \
--image models/test_images/rococo.jpg \
--prompt "Describe this image." \
--max-new-tokens 12
See docs/vlm-smolvlm-onnx.md for full VLM docs.
Build the XCFramework:
./scripts/build_xcframework.sh
Then open bindings/ios/CellmDemo in Xcode.
Build and run the WASM engine with WebGPU acceleration:
# Build the WASM module
./scripts/build-wasm.sh --release
# Serve the demo page
python3 -m http.server 8080 --directory crates/cellm-wasm/www/
Then open http://localhost:8080 and use engine.try_init_webgpu() to enable hardware acceleration.
cellm's whole point is phone deployment (iOS/Android via Metal/Vulkan), so Docker can't run the actual mobile targets — there's no GPU passthrough for Apple's Metal API in a Linux container. Where Docker does help is the CPU-backend and tooling side of the repo: CI, headless benchmarking, model conversion pipelines, and testing without owning a Mac.
| Image | Backend | Status | Use case |
|---|---|---|---|
cellm:cpu | CPU kernels | Planned | CI, headless benchmarking, model conversion, testing without a Mac |
cellm:vulkan | Vulkan compute | Research | Once the Vulkan backend stabilizes (see Feature Status) |
cellm:metal | Metal | Not possible | No Metal GPU passthrough on Linux containers — Metal only runs on real macOS/iOS hardware |
Unlike llama.cpp's Docker matrix (CUDA/ROCm/Vulkan/SYCL variants for full/light/server), cellm doesn't need a wide backend matrix — this is a mobile-first inference engine, not a server deployment target. A single CPU image covers the actual need for reproducible tooling.
Example Dockerfile shape:
FROM rust:1.75 AS build
WORKDIR /app
COPY . .
RUN cargo build --release --bin infer --bin convert --bin bench
FROM debian:bookworm-slim AS cpu
COPY --from=build /app/target/release/infer /app/target/release/convert /app/target/release/bench /usr/local/bin/
ENTRYPOINT ["infer"]
Usage once built:
docker run -v /path/to/models:/models cellm:cpu \
--model /models/smollm2-135m.cellm \
--tokenizer /models/hf/smollm2-135m/tokenizer.json \
--prompt "Hello" --chat --gen 32
Not wired up yet — tracked as a follow-up. If you want to help, a
Dockerfile+ GitHub Actions workflow (mirroring.github/workflows/docker.yml-style multi-arch builds) for thecpuvariant is the right first PR.
Use cellm's local LLM to generate git commit messages from staged changes. All inference runs locally on CPU — no API keys, no data leaves your machine.
.cellm format (e.g., Qwen2.5 0.5B int8)tokenizer.json./target/release/infer built (cargo build --release)# Stage your changes first
git add -A
# Generate a commit message from staged diff
./tools/git-cellm-commit.sh
# Or pipe any diff
git diff HEAD~1 | ./tools/git-cellm-commit.sh
git diff --cached captures your staged changesSet these environment variables to use a different model:
| Env var | Default | Description |
|---|---|---|
CELLM_COMMIT_MODEL | models/to-huggingface/qwen2.5-0.5b-int8-v1/qwen2.5-0.5b-int8-v1.cellm | Path to .cellm model |
CELLM_COMMIT_TOKENIZER | models/to-huggingface/qwen2.5-0.5b-int8-v1/tokenizer.json | Path to tokenizer.json |
CELLM_COMMIT_INFER | ./target/release/infer | Path to the infer binary |
Example with the LFM model:
CELLM_COMMIT_MODEL=models/LFM2.5-230M-int4-v2.cellm \
CELLM_COMMIT_TOKENIZER=models/to-huggingface/LFM2.5-230M/tokenizer.json \
./tools/git-cellm-commit.sh
| Model | Size | Best For | Notes |
|---|---|---|---|
| SmolLM2 | 135M-360M | Fast smoke tests, small devices | Best LLM starter model |
| LFM2.5 | 350M | Long-context, efficient inference | Linear attention, up to 256K context |
| Qwen2.5 / Qwen3.0 / Qwen3.5 | 0.5B-0.8B | Multilingual, reasoning | DeltaNet layers supported (CPU ref) |
| Gemma-3 | 1B | Quality vs size tradeoff | Metal path active, CPU-safe fallback |
| Bonsai | 1.7B | High-quality local chat | 1-bit quantized; see docs/bonsai_1bit_analysis.md |
| Gemma-4 | 2B-4B | Larger mobile workloads | Experimental; see docs/gemma4_* |
| SmolVLM | 256M | Vision-language (ONNX) | Native .cellm VLM path in progress |
| FunctionGemma | 270M | Mobile actions / tool use | Experimental quality; see docs/function-calling-gemma.md and HF builds |
Recommended first download: SmolLM2-135M
Sample checkpoints bundled in this repo (via Git LFS):
models/smollm2-135m-int8.cellmmodels/smolvlm-256m-int8.cellmmodels/qwen3.5-0.8b-int4-textonly.cellmBlockAllocator & PageTabledocs/vlm-smolvlm-onnx.md.cellm VLM path - ViT/SigLIP encoder + linear projector (experimental, see docs/vlm-smolvlm-onnx.md)wasm-bindgentools/git-cellm-commit.sh.so; on-device validation and tuning still openinfer/convert/bench (see Docker)| Topic | Doc |
|---|---|
| Architecture & crate design | docs/project_architecture.md |
| Paged KV cache internals | docs/paged-kv-cache-foundation.md |
| Scheduler & continuous batching | docs/phase4-continuous-batching.md |
| Model conversion & quantization | docs/convert-quantized-models.md |
| On-device function calling | docs/function-calling-gemma.md |
| TurboQuant KV compression | docs/turboquant_dataflow.md |
| VLM / SmolVLM ONNX guide | docs/vlm-smolvlm-onnx.md |
| VLM sequence tracking | docs/cellm-vlm-sequence.md |
| Qwen3.5 / DeltaNet | docs/qwen3_5-deltanet.md |
| Metal acceleration notes | docs/LFM_Metal_Acceleration.md |
| Benchmark history & raw runs | docs/benchmarks/ |
| Data flow diagrams | docs/data_flow.md |
| Format specification | docs/format.md |
| Inference graph | docs/inference_graph.md |
| WASM & WebGPU Backend | docs/wasm-backend.md |
# 1. Verify Metal device access
cargo run --release --bin metal-smoke
# 2. Verify infer picks Metal
./target/release/infer \
--model models/smollm2-135m-int8.cellm \
--tokenizer models/hf/smollm2-135m/tokenizer.json \
--prompt "hello" --gen 8 --backend metal
In restricted/sandboxed shells, Metal device discovery can fail. infer --backend metal now errors instead of silently falling back to CPU.
CELLM_LLAMA_ROPE_INTERLEAVED=0 ./target/release/infer ...
Default keeps norm/RoPE/logits on CPU-safe path for quality parity. Opt-in Metal paths:
CELLM_GEMMA_USE_METAL_NORM=1 # enable Metal RMSNorm
CELLM_GEMMA_USE_METAL_ROPE=1 # enable Metal RoPE
CELLM_GEMMA_USE_METAL_LOGITS=1 # enable Metal final logits matvec
CELLM_LLAMA_ENABLE_GRAPH=1 ./target/release/infer ...
| Model | Flag | Purpose |
|---|---|---|
| SmolLM2 360M | CELLM_LLAMA_ROPE_INTERLEAVED=0 | Correct RoPE layout |
| Llama | CELLM_LLAMA_USE_METAL_NORM=1 | Force Metal norm |
| Llama | CELLM_LLAMA_USE_METAL_ROPE=1 | Force Metal RoPE |
| Qwen VLM | CELLM_VLM_TOKENIZER=... | Set tokenizer path for vlm-smoke |
For more debug flags and backend-specific notes, see the per-model docs in docs/.
If you use cellm in your research, please cite:
@software{asante2026cellm,
author = {Asante, Jeffrey},
title = {cellm: A Mobile-Native LLM Serving Engine},
year = {2026},
url = {https://github.com/jeffasante/cellm},
note = {Rust inference engine with paged KV cache and multi-session scheduling}
}
Apache License, Version 2.0 (LICENSE-APACHE)
Rust
75.5%
Swift
10.6%
Python
5.9%
HTML
2.6%
Kotlin
2.4%
C
1.3%
Shell
1.1%
A from-scratch LLM inference runtime for iOS/Android, targeting phones with under 512MB RAM. It's research-grade, not a wrapper around llama.cpp or a port of vLLM.
9
stars
0
commits
Rust
primary language
Aug 8, 2026
updated
A ground-up LLM inference engine for iOS and Android, written in Rust. Brings server-grade serving concepts — paged KV cache, continuous decode scheduling, multi-session concurrency — to phones running under 512MB RAM.
Not a wrapper around llama.cpp. Not a port of vLLM. A new runtime designed for mobile constraints from scratch.
[!NOTE] Status. The CPU and Metal backends, the iOS bindings, and the text models listed under Supported Models are stable and in active use. Metal coverage varies by model; CPU runs everything. The Android AAR and Compose demo build and package the native library, but haven't been validated or tuned on-device. Vulkan sets up the device and pipelines but still runs every op on CPU. The native
.cellmVLM path and the Docker image are experimental or not yet wired up; vision via ONNX is stable. See Feature Status.

| Resource | Path |
|---|---|
| Getting Started | Quick Start below |
| Architecture & Design | docs/project_architecture.md |
| Paged KV Cache Deep Dive | docs/paged-kv-cache-foundation.md |
| Benchmarks | docs/benchmarks/README.md |
| Model Conversion | docs/convert-quantized-models.md |
| VLM (Vision) Guide | docs/vlm-smolvlm-onnx.md (ONNX path; native .cellm is experimental) |
| iOS Demo App | bindings/ios/CellmDemo |
| Android Bindings | bindings/kotlin (builds; not yet device-validated) |
| WASM & WebGPU | docs/wasm-backend.md |
| Live WASM Demo | cellm-wasm ( (Research Preview) |
| Git Commit Messages | Local LLM commit messages below |
| Docker (CPU tooling) | Docker below (planned, not yet wired up) |
cargo build --release
cargo run --release --bin infer -- \
--model models/smollm2-135m.cellm \
--tokenizer models/hf/smollm2-135m/tokenizer.json \
--prompt "Hello, how are you?" \
--chat \
--gen 32
cargo run --release --bin infer -- \
--model models/smollm2-135m-int8.cellm \
--tokenizer models/hf/smollm2-135m/tokenizer.json \
--prompt "Hello" \
--chat \
--gen 16 \
--backend metal
Tip: Use
--chatfor ChatML-style formatting. Without it, many base models behave like text-completion engines and may not answer directly.
cargo run --release --bin metal-smoke
flowchart LR
U["User Prompt"] --> API["App/UI Request Layer"]
API --> ORCH["CPU Orchestrator"]
ORCH --> TOK[Tokenizer]
TOK --> FMT["Prompt Formatter"]
FMT --> SCH["Decode Scheduler / Batcher"]
SCH -->|"prefill/decode jobs"| ENG["Engine Dispatcher"]
ENG -->|backend=CPU| CPUPATH["CPU Kernels"]
ENG -->|backend=Metal| METAL["Metal Kernels"]
METAL --> MATMUL["QKV / MLP MatMul"]
METAL --> ATTN["Attention + GroupKV Cache"]
METAL --> NORM["RMSNorm / RoPE / Logits"]
MATMUL --> SAMPLER
ATTN --> SAMPLER
NORM --> SAMPLER
CPUPATH --> SAMPLER["Sampler + Stop Rules"]
SAMPLER --> DETOK[Detokenizer]
DETOK --> STREAM["Streaming Output"]
STREAM --> API
API --> U
subgraph ModelAssets["Local Model Assets"]
W[".cellm / .cellmd mmap Weights"]
T["tokenizer.json + config"]
end
W --> ENG
T --> TOK
subgraph SessionState["Per-Session State"]
KV["KV Cache (GroupKV layout)"]
PT["Page Table / Sequence Cursor"]
TH["Thermal + QoS Policy"]
end
SCH --> KV
SCH --> PT
ORCH --> TH
TH --> SCH
| Feature | llama.cpp | MLX | ExecuTorch | cellm |
|---|---|---|---|---|
| Language | C++ | C++/Python | C++ | Rust |
| KV Cache | Contiguous | Contiguous | Contiguous | Paged (Block-based) |
| Focus | Portability | Apple Native | Model Export | Mobile Multi-session |
| Scheduling | Static Batch | Mostly Single | N/A | Round-Robin Interleaved |
| Memory | Manual/Static | Managed Buffer | Static Graph | Dynamic Block Allocator |
cellm/
├── crates/
│ ├── cellm-core/ # Memory arena, tensor layout, op dispatch
│ ├── cellm-model/ # Model format, configuration, weight management
│ ├── cellm-cache/ # Paged KV cache: BlockAllocator, PageTable, physical storage
│ ├── cellm-kernels/ # CPU, Metal, WASM & WebGPU compute kernels
│ ├── cellm-scheduler/ # Decode scheduler & batching logic
│ ├── cellm-wasm/ # WebAssembly bindings & JavaScript API
│ └── cellm-sdk/ # Public C FFI + high-level API for mobile consumers
├── bindings/
│ ├── ios/CellmDemo/ # SwiftUI demo app (LLM + VLM stub)
│ ├── kotlin/ # Android Kotlin/JNI bindings
│ └── swift/ # Swift Package + XCFramework build scripts
├── tools/
│ ├── infer/ # CLI inference runner (debug & validation)
│ ├── vlm-onnx-infer/ # VLM runner for SmolVLM ONNX exports
│ ├── vlm-smoke/ # SDK FFI VLM smoke test
│ ├── convert/ # HF Safetensors/GGUF/PyTorch -> .cellm converter
│ ├── bench/ # Latency & throughput benchmark harness
│ └── metal-smoke/ # Minimal Metal kernel compile + dispatch test
├── docs/ # Architecture deep-dives, benchmarks, model guides
└── models/ # Sample .cellm checkpoints (Git LFS)
Convert HuggingFace Safetensors or GGUF to .cellm:
cargo run --bin convert -- \
--input ./models/hf/smollm2-135m \
--output ./models/smollm2-135m.cellm \
--dtype f16
Quantize during conversion:
cargo run --bin convert -- \
--input ./models/hf/smollm2-135m \
--output ./models/smollm2-135m-int8.cellm \
--dtype f16 \
--quantize-int8-symmetric
See docs/convert-quantized-models.md for GGUF, PyTorch, and 4-bit affine workflows.
# Quick smoke benchmark
cargo run --release --bin bench -- --model tiny
# Full LLM backend matrix (CPU vs Metal)
tools/bench/run_llm_backend_matrix.sh
Detailed benchmark reports live in docs/benchmarks/.
# ONNX vision + ONNX decoder (recommended)
cargo build --release -p cellm-vlm-onnx-infer
./target/release/vlm-infer \
--model-dir models/hf/smolvlm-256m-instruct \
--onnx-variant fp16 \
--image models/test_images/rococo.jpg \
--prompt "Describe this image." \
--split-image \
--max-new-tokens 96
Native .cellm vision + decoder is experimental:
./target/release/vlm-infer \
--model-dir models/hf/smolvlm-256m-instruct \
--cellm-model models/smolvlm-256m.cellm \
--vision-backend cellm \
--decoder-backend cellm \
--image models/test_images/rococo.jpg \
--prompt "Describe this image." \
--max-new-tokens 12
See docs/vlm-smolvlm-onnx.md for full VLM docs.
Build the XCFramework:
./scripts/build_xcframework.sh
Then open bindings/ios/CellmDemo in Xcode.
Build and run the WASM engine with WebGPU acceleration:
# Build the WASM module
./scripts/build-wasm.sh --release
# Serve the demo page
python3 -m http.server 8080 --directory crates/cellm-wasm/www/
Then open http://localhost:8080 and use engine.try_init_webgpu() to enable hardware acceleration.
cellm's whole point is phone deployment (iOS/Android via Metal/Vulkan), so Docker can't run the actual mobile targets — there's no GPU passthrough for Apple's Metal API in a Linux container. Where Docker does help is the CPU-backend and tooling side of the repo: CI, headless benchmarking, model conversion pipelines, and testing without owning a Mac.
| Image | Backend | Status | Use case |
|---|---|---|---|
cellm:cpu | CPU kernels | Planned | CI, headless benchmarking, model conversion, testing without a Mac |
cellm:vulkan | Vulkan compute | Research | Once the Vulkan backend stabilizes (see Feature Status) |
cellm:metal | Metal | Not possible | No Metal GPU passthrough on Linux containers — Metal only runs on real macOS/iOS hardware |
Unlike llama.cpp's Docker matrix (CUDA/ROCm/Vulkan/SYCL variants for full/light/server), cellm doesn't need a wide backend matrix — this is a mobile-first inference engine, not a server deployment target. A single CPU image covers the actual need for reproducible tooling.
Example Dockerfile shape:
FROM rust:1.75 AS build
WORKDIR /app
COPY . .
RUN cargo build --release --bin infer --bin convert --bin bench
FROM debian:bookworm-slim AS cpu
COPY --from=build /app/target/release/infer /app/target/release/convert /app/target/release/bench /usr/local/bin/
ENTRYPOINT ["infer"]
Usage once built:
docker run -v /path/to/models:/models cellm:cpu \
--model /models/smollm2-135m.cellm \
--tokenizer /models/hf/smollm2-135m/tokenizer.json \
--prompt "Hello" --chat --gen 32
Not wired up yet — tracked as a follow-up. If you want to help, a
Dockerfile+ GitHub Actions workflow (mirroring.github/workflows/docker.yml-style multi-arch builds) for thecpuvariant is the right first PR.
Use cellm's local LLM to generate git commit messages from staged changes. All inference runs locally on CPU — no API keys, no data leaves your machine.
.cellm format (e.g., Qwen2.5 0.5B int8)tokenizer.json./target/release/infer built (cargo build --release)# Stage your changes first
git add -A
# Generate a commit message from staged diff
./tools/git-cellm-commit.sh
# Or pipe any diff
git diff HEAD~1 | ./tools/git-cellm-commit.sh
git diff --cached captures your staged changesSet these environment variables to use a different model:
| Env var | Default | Description |
|---|---|---|
CELLM_COMMIT_MODEL | models/to-huggingface/qwen2.5-0.5b-int8-v1/qwen2.5-0.5b-int8-v1.cellm | Path to .cellm model |
CELLM_COMMIT_TOKENIZER | models/to-huggingface/qwen2.5-0.5b-int8-v1/tokenizer.json | Path to tokenizer.json |
CELLM_COMMIT_INFER | ./target/release/infer | Path to the infer binary |
Example with the LFM model:
CELLM_COMMIT_MODEL=models/LFM2.5-230M-int4-v2.cellm \
CELLM_COMMIT_TOKENIZER=models/to-huggingface/LFM2.5-230M/tokenizer.json \
./tools/git-cellm-commit.sh
| Model | Size | Best For | Notes |
|---|---|---|---|
| SmolLM2 | 135M-360M | Fast smoke tests, small devices | Best LLM starter model |
| LFM2.5 | 350M | Long-context, efficient inference | Linear attention, up to 256K context |
| Qwen2.5 / Qwen3.0 / Qwen3.5 | 0.5B-0.8B | Multilingual, reasoning | DeltaNet layers supported (CPU ref) |
| Gemma-3 | 1B | Quality vs size tradeoff | Metal path active, CPU-safe fallback |
| Bonsai | 1.7B | High-quality local chat | 1-bit quantized; see docs/bonsai_1bit_analysis.md |
| Gemma-4 | 2B-4B | Larger mobile workloads | Experimental; see docs/gemma4_* |
| SmolVLM | 256M | Vision-language (ONNX) | Native .cellm VLM path in progress |
| FunctionGemma | 270M | Mobile actions / tool use | Experimental quality; see docs/function-calling-gemma.md and HF builds |
Recommended first download: SmolLM2-135M
Sample checkpoints bundled in this repo (via Git LFS):
models/smollm2-135m-int8.cellmmodels/smolvlm-256m-int8.cellmmodels/qwen3.5-0.8b-int4-textonly.cellmBlockAllocator & PageTabledocs/vlm-smolvlm-onnx.md.cellm VLM path - ViT/SigLIP encoder + linear projector (experimental, see docs/vlm-smolvlm-onnx.md)wasm-bindgentools/git-cellm-commit.sh.so; on-device validation and tuning still openinfer/convert/bench (see Docker)| Topic | Doc |
|---|---|
| Architecture & crate design | docs/project_architecture.md |
| Paged KV cache internals | docs/paged-kv-cache-foundation.md |
| Scheduler & continuous batching | docs/phase4-continuous-batching.md |
| Model conversion & quantization | docs/convert-quantized-models.md |
| On-device function calling | docs/function-calling-gemma.md |
| TurboQuant KV compression | docs/turboquant_dataflow.md |
| VLM / SmolVLM ONNX guide | docs/vlm-smolvlm-onnx.md |
| VLM sequence tracking | docs/cellm-vlm-sequence.md |
| Qwen3.5 / DeltaNet | docs/qwen3_5-deltanet.md |
| Metal acceleration notes | docs/LFM_Metal_Acceleration.md |
| Benchmark history & raw runs | docs/benchmarks/ |
| Data flow diagrams | docs/data_flow.md |
| Format specification | docs/format.md |
| Inference graph | docs/inference_graph.md |
| WASM & WebGPU Backend | docs/wasm-backend.md |
# 1. Verify Metal device access
cargo run --release --bin metal-smoke
# 2. Verify infer picks Metal
./target/release/infer \
--model models/smollm2-135m-int8.cellm \
--tokenizer models/hf/smollm2-135m/tokenizer.json \
--prompt "hello" --gen 8 --backend metal
In restricted/sandboxed shells, Metal device discovery can fail. infer --backend metal now errors instead of silently falling back to CPU.
CELLM_LLAMA_ROPE_INTERLEAVED=0 ./target/release/infer ...
Default keeps norm/RoPE/logits on CPU-safe path for quality parity. Opt-in Metal paths:
CELLM_GEMMA_USE_METAL_NORM=1 # enable Metal RMSNorm
CELLM_GEMMA_USE_METAL_ROPE=1 # enable Metal RoPE
CELLM_GEMMA_USE_METAL_LOGITS=1 # enable Metal final logits matvec
CELLM_LLAMA_ENABLE_GRAPH=1 ./target/release/infer ...
| Model | Flag | Purpose |
|---|---|---|
| SmolLM2 360M | CELLM_LLAMA_ROPE_INTERLEAVED=0 | Correct RoPE layout |
| Llama | CELLM_LLAMA_USE_METAL_NORM=1 | Force Metal norm |
| Llama | CELLM_LLAMA_USE_METAL_ROPE=1 | Force Metal RoPE |
| Qwen VLM | CELLM_VLM_TOKENIZER=... | Set tokenizer path for vlm-smoke |
For more debug flags and backend-specific notes, see the per-model docs in docs/.
If you use cellm in your research, please cite:
@software{asante2026cellm,
author = {Asante, Jeffrey},
title = {cellm: A Mobile-Native LLM Serving Engine},
year = {2026},
url = {https://github.com/jeffasante/cellm},
note = {Rust inference engine with paged KV cache and multi-session scheduling}
}
Apache License, Version 2.0 (LICENSE-APACHE)
Rust
75.5%
Swift
10.6%
Python
5.9%
HTML
2.6%
Kotlin
2.4%
C
1.3%
Shell
1.1%