Pure Rust multimodal inference engine based on Qwen3.5-4B. No Python, no CUDA, no external ML frameworks. Single executable + model weights = portable AI that runs on any machine.
GPU accelerated — auto-detects Vulkan (Windows/Linux) or Metal (macOS) GPU and runs inference on it. Falls back to CPU if no GPU available. Smart system awareness — detects RAM and CPU at startup and adjusts generation limits automatically.
License
This project is licensed under Apache 2.0. The base model Qwen3.5-4B is released by the Qwen team under Apache 2.0.
What It Does
QORA-4B is a 4-billion parameter language model with built-in vision. It can:
Text generation — answer questions, write code, reason through problems
Image understanding — describe photos, answer questions about images
Video understanding — analyze frame sequences, describe motion and temporal changes
Thinking mode — extended chain-of-thought reasoning with configurable budget
Architecture
QORA-4B uses a hybrid architecture combining two attention mechanisms:
Component
Details
Parameters
4B total
Hidden dim
2560
Layers
32 (24 DeltaNet + 8 Full Attention)
Layer pattern
3x DeltaNet + 1x Full Attention, repeated 8 times
Vocabulary
248,320 tokens
Context
262K tokens natively
DeltaNet Layers (24 of 32)
Gated linear attention with delta rule state updates
16 QK heads + 32 V heads, head_dim=128
Causal Conv1d (kernel=4) + SiLU activation
O(1) memory per token (recurrent state, no KV cache needed)
Images: single frame duplicated along temporal axis
Video: actual Conv3d over consecutive frame pairs (N frames → N/2 temporal patches)
GPU Support
QORA-4B automatically detects and uses your GPU via the Burn framework's wgpu backend:
Windows/Linux: Vulkan
macOS: Metal (Apple Silicon and Intel)
Attempting GPU inference...
GPU initialized successfully
VRAM probe: 256MB OK
Weights loaded to GPU in 5.9s
Prefill: 97 tokens in 21.8s (4.5 tok/s)
Decode: 96 tokens in 29.3s (3.27 tok/s)
Mode
Decode Speed
Prefill Speed
GPU
~3.3 tok/s
~4.5 tok/s
CPU
~1.3 tok/s
~1.9 tok/s
GPU gives a ~2.5x speedup over CPU. Use --cpu to force CPU-only inference.
VRAM requirements: ~2 GB for Q4 weights + cache. Fits in 4+ GB GPUs. Embedding and lm_head stay on CPU (vocab=248K is too large for VRAM).
GPU prefill optimization: DeltaNet layers use a hybrid approach — batch all matrix projections on GPU, then run the lightweight sequential state update on CPU. This avoids per-token GPU round-trips and achieves near-optimal throughput.
Smart System Awareness
QORA-4B detects your system at startup and automatically adjusts generation limits:
1# Text generation (auto-detects GPU)2qor4b --prompt "Explain quantum computing" --max-tokens 50034# Force CPU-only5qor4b --prompt "Hello" --cpu
67# Image understanding8qor4b --prompt "What's in this image?" --image photo.jpg
910# Video understanding (directory of frame images)11qor4b --prompt "What happens in this video?" --video frames_dir/
1213# Thinking mode (default, extended reasoning)14qor4b --prompt "Solve: integral of x^2 * e^x dx" --think-budget 20481516# No-think mode (faster, direct answers)17qor4b --prompt "What is 2+2?" --no-think
1819# Greedy decoding (deterministic output)20qor4b --prompt "Hello" --greedy
CLI Flags
Flag
Description
--prompt TEXT
Input prompt (default: "Hello, how are you?")
--image PATH
Path to an image file (PNG/JPG)
--video PATH
Path to directory of frame images (PNG/JPG, sorted by name)
--max-tokens N
Max tokens to generate (default: 1024)
--think-budget N
Max thinking tokens before forcing answer (default: 1024)
--no-think
Disable thinking mode (direct answers)
--show-think
Display thinking tokens on stderr
--greedy
Greedy decoding (temperature=0, not recommended with thinking mode)
--cpu
Force CPU inference (skip GPU auto-detection)
Sampling Defaults
Parameter
Think mode
No-think mode
temperature
1.0
0.7
top_k
20
20
top_p
0.95
0.95
presence_penalty
1.5
1.5
Video Input
Video is provided as a directory of frame images (not a video file). Extract frames however you like:
bash
1# Example: extract 4 frames from a video with ffmpeg2ffmpeg -i video.mp4 -vf "select=not(mod(n\,30))" -frames:v 4 frames/frame_%02d.png
34# Then run5qor4b --prompt "Describe what happens" --video frames/
Frames are loaded in alphabetical order, resized to uniform dimensions (max 768px, divisible by 32), and processed as temporal pairs via Conv3d. Odd frame counts are padded by duplicating the last frame.