Executable programs and extensions

What is Crane? Run LLM, OCR and audio models behind a local Rust API

A chat model in one Python environment, OCR in another set of libraries, and speech recognition with yet another install can turn environment upkeep into the project. Crane is a Rust inference project built on Hugging Face Candle. It keeps text models and OCR, ASR and TTS examples in one repository, then exposes them through the local crane-serve API. Start by checking the chat path with a small Qwen3.5 model, then add the model tasks you need. This guide builds a pinned repository version, keeps the server on your machine, and connects an app to the same API.

Key takeaways

01
Crane is a Candle-based Rust project that connects text, image and audio tasks to applications and HTTP APIs.
02
First check the chat server with the official Qwen/Qwen3.5-0.8B files, then set the client base URL to http://127.0.0.1:8080/v1 and model name to crane-local.
03
The Bonsai 2 Prism GGUF path is documented for CPU and NVIDIA CUDA. Metal support elsewhere in the project does not establish support for every model.

When every model task needs its own Python setup

Imagine a chat server working in its virtual environment until an OCR package conflicts with a dependency, while a speech demo wants another Python version. The friction is not the models themselves, but the separate execution environments. Crane takes a different approach: manage text inference, image input, OCR and audio code within one project built around Rust and Candle.

Rust catches many errors during compilation and packages programs as executable binaries. Candle supplies tensor operations and model components in Rust, letting Crane keep application code and inference in the same language ecosystem. That is an implementation and deployment advantage, not a promise that every model will run faster automatically.

A small computer showing a chat screen, with a microphone and a photo beside it
Text, image and audio inputs appear in one local workflow.

Crane, Ollama and MLX serve different roles

Ollama simplifies downloading a model and using its local API. MLX is a machine-learning framework for Apple silicon, used by applications such as oMLX. Crane brings Candle's Rust model implementations together with several device backends. It is worth considering for inference inside a Rust app or for running the same server program with different models. The basic setup loads one model per process. To use chat and speech together, run the required servers separately on different ports.

You point Crane's crane-serve at a model, then send OpenAI-shaped chat requests from an existing program. This is less about replacing the convenience features of a desktop app and more about adding a server layer you can control between an application and its model. The project's Metal support on Mac does not imply every model uses Metal; specific checkpoints have their own device support, as with Bonsai 2 below.

Pin the repository revision and build the server

The steps below target the Crane revision reviewed on September 23, 2026. Cloning the repository and checking out that commit makes the commands and model support less likely to shift under later main changes. Prepare the Rust toolchain, Xcode Command Line Tools on macOS, and a compatible CUDA toolkit on Linux when compiling for NVIDIA CUDA.

Run only one of the three build commands below: Metal and Accelerate for Mac, CUDA for Linux with an NVIDIA GPU, or CPU for a test without GPU acceleration. Model weights are not part of the build; download them in the next step. The official install.sh helps choose these features, but explicit Cargo commands make the selected configuration visible.

Clone and pin the revision
git clone https://github.com/lucasjinreal/Crane.git
cd Crane
git checkout --detach 99a60887bdca16b4852b7bc953ca03c1df374e88
Start from the revision reviewed for this guide.
Build for Apple silicon
cargo build --release -p crane-serve --features "metal,accelerate"
Choose this build command on Mac.
Build for NVIDIA CUDA
cargo build --release -p crane-serve --features cuda
For Linux with a compatible CUDA toolkit installed.
Build for CPU
cargo build --release -p crane-serve
Choose this to start without a GPU.
Concept illustration of differently shaped wooden blocks and a fitting jig, with a laptop and graphics card behind them
Choose an execution path that fits the model format; device support varies by model.

Check the chat path first with a small model

For the first run, use the official Hugging Face repository Qwen/Qwen3.5-0.8B. Crane's README lists Qwen 3.5 0.8B as supported, and the model card provides the safetensors repository and license. This checkpoint includes a vision encoder, so pass crane-serve's --text-only option when testing text chat without the vision component.

Download the model using the Hugging Face CLI. If uv is already installed, use uvx hf below; uv manages the tool's isolated environment, so you do not need to create one yourself. Otherwise choose a suitable installation method in the CLI guide linked below. Once the download finishes, check that the model directory contains its configuration, tokenizer and weight files.

Download the official model files
uvx hf download Qwen/Qwen3.5-0.8B --local-dir models/Qwen3.5-0.8B
Run inside the Crane directory and wait for the model download to finish.

Bind the server to 127.0.0.1

After downloading the model, start crane-serve. --model-name crane-local sets the name used in API requests, and --context 4096 sets the context limit for this test. Passing --host 127.0.0.1 restricts access to clients on the same computer. Crane's default host is 0.0.0.0, so keep this option in the command.

When the server starts, check the address in the terminal. If the built-in page does not open automatically, visit http://127.0.0.1:8080/ in your browser. --ui serves Crane's built-in browser interface. With the text-only model loaded, start with a short prompt and make sure the response completes.

Qwen3.5 text chat server
./target/release/crane-serve --model-path models/Qwen3.5-0.8B --model-type qwen3_5_vl --text-only --model-name crane-local --host 127.0.0.1 --port 8080 --context 4096 --ui
Point to the downloaded directory. --text-only skips the vision tower.

Point an API client at the same server

A direct HTTP request lets you inspect the connection between the server and an app. curl -N displays streamed output without buffering, and the request's model value must match the crane-local name from the launch command. For supported Qwen templates, chat_template_kwargs.enable_thinking turns thinking mode off.

In an OpenAI-compatible app, set the base URL to http://127.0.0.1:8080/v1 and model name to crane-local. The example above is local-only with API authentication disabled. If the app requires an API-key field, a placeholder such as local can be used; it does not secure the server. Once connected, try an everyday question in your language or a short code explanation.

Request a streaming response
curl -N http://127.0.0.1:8080/v1/chat/completions -H 'Content-Type: application/json' -d '{"model":"crane-local","messages":[{"role":"user","content":"Say hello in one short sentence."}],"stream":true,"max_tokens":256,"temperature":0,"chat_template_kwargs":{"enable_thinking":false}}'
Leave the server running and use another terminal. The reply arrives in chunks.

Add OCR, ASR or TTS after chat works

Once chat works, restart the server with the model type for your next task. Crane's repository lists PaddleOCR variants, Qwen3-ASR and Qwen3-TTS, while the crane-serve docs describe audio transcription and speech-generation paths. Audio servers use different model types and inputs from chat, so take the options and request format from the corresponding README section and test with one sample.

Before sending real files or work material, try short, non-sensitive inputs. For OCR, see whether text in a photo is captured; for ASR, whether Korean speech is transcribed; for TTS, whether it speaks the language you need. Even when each task uses a different model, you can reuse the same server pattern in your app.

What changes when switching to Bonsai 2

Bonsai 2's Prism release is a GGUF file containing PTQ1_0 or PQ2_0 ternary weights. Crane was updated to recognize those dedicated GGUF types and use its TernaryLinear execution path for the affected weights. When downloading, choose the specified Bonsai 2 Prism file rather than a generic Q4 GGUF.

The official support note names CPU and NVIDIA CUDA for this model. That differs from Qwen3.5's Metal path, so building Crane with Metal on a Mac does not mean Bonsai 2 receives the same GPU acceleration. Do not estimate memory from the 27B parameter label alone; check the selected Prism file size and available memory with the 4096-token context setting.

Switch to a downloaded Bonsai 2 GGUF
./target/release/crane-serve \
  --model-path /absolute/path/Ternary-Bonsai-2-27B-PTQ1_0.gguf \
  --model-name bonsai-local --host 127.0.0.1 --port 8080 \
  --context 4096 --ui
Stop the previous server with Ctrl+C first. Replace the file path and change the client model name to bonsai-local. This example targets CPU or CUDA.

Compare fairly with your current runtime

This guide does not include a direct Crane benchmark. On your machine, separate model loading and warm-up from measurement, then record the median of three matching requests. Track time to first token, subsequent generation speed and total completion time to see whether input processing or answer generation changed.

An identical question is not a fair comparison if only one engine enables thinking or uses a different output limit. Match the model, quantization, context and output cap; separate fresh requests from cached follow-ups. Record format differences such as MLX versus GGUF. A faster answer that omits important content is not sufficient reason to switch. The useful outcome is less environment upkeep while reliably completing your everyday task.

A laptop and computer linked by a cable, beside a log notebook and stopwatch
Log the same request and compare its wait time and answer quality.