Overview
Off Grid leverages platform-specific hardware accelerators to achieve real-time on-device AI inference:- Android: OpenCL (GPU) for LLMs, Qualcomm QNN (NPU) for image generation
- iOS: Metal (GPU) for LLMs, Apple Neural Engine (ANE) for image generation
LLM Inference Acceleration
OpenCL GPU Offloading (Android)
Llama.cpp supports GPU acceleration via OpenCL on Qualcomm Adreno GPUs. Architecture:- Configuration
- Performance
- Memory Safety
- First
nGpuLayerslayers → GPU via OpenCL - Remaining layers → CPU via ARM NEON
Known Issues:
Flash Attention Conflict:
Metal GPU Acceleration (iOS)
Llama.cpp uses Metal Performance Shaders (MPS) for GPU acceleration on Apple Silicon. Architecture:- Configuration
- Performance
- Memory Safety
nGpuLayers: 99) typically provides best performance since Metal backend is stable.- Zero-copy tensor transfers (no CPU↔GPU memcpy)
- Lower latency for small batches
- Higher effective memory bandwidth
M1 iPad Air throttling: Sustained generation (>2 minutes) may trigger thermal throttling, reducing GPU clocks by 20-30%. Performance degrades to ~70% of initial speed.
Image Generation Acceleration
Qualcomm QNN NPU (Android)
Qualcomm AI Engine Direct (QNN) accelerates Stable Diffusion on the Hexagon DSP (Neural Processing Unit). Architecture:- Snapdragon 8 Gen 1
- Snapdragon 8 Gen 2
- Snapdragon 8 Gen 3
- Snapdragon 8 Gen 4/5
SoC: SM8450
HTP Version: V68
Performance: ~8-12s for 512×512 @ 20 steps
Models:
HTP Version: V68
Performance: ~8-12s for 512×512 @ 20 steps
Models:
qnn-min variant (conservative optimizations)unet.bin— UNet denoising network (HTP-optimized)vae_decoder.bin— VAE decoder (HTP-optimized)clip.binorclip.mnn— Text encoder (CPU or MNN)
xororz/sd-qnn-* HuggingFace repos.
Runtime Library Selection:
libQnnHtp.so automatically loads chipset-specific variant:
- Detects HTP version via
/sys/devices/soc0/soc_id - Loads corresponding
libQnnHtpV73.so,libQnnHtpV75.so, etc. - Falls back to oldest compatible version if exact match unavailable
DSP_LIBRARY_PATH— Hexagon DSP firmware locationADSP_LIBRARY_PATH— Audio DSP library path (required for some SoCs)
QNN provides 2-3x speedup with 40% lower power consumption.
Known Issues:
Cache Warmup:
First generation after model load takes 60-120s for QNN to:
- Analyze compute graph
- Compile ops for HTP
- Cache compiled binaries to
/data/local/tmp/qnn_cache/
Apple Neural Engine (iOS)
Apple’s dedicated AI accelerator for Core ML inference. Architecture:- A17 Pro
- A18 Pro
- M2
- M4
TOPs: 16 (trillion ops/sec)
Architecture: 3rd-gen ANE
Performance: ~10-12s for SD 1.5 fp16 @ 20 steps
Found in: iPhone 15 Pro, iPhone 15 Pro Max
Architecture: 3rd-gen ANE
Performance: ~10-12s for SD 1.5 fp16 @ 20 steps
Found in: iPhone 15 Pro, iPhone 15 Pro Max
- Op is convolution, matrix multiply, or supported activation
- Tensor shapes are ANE-compatible (batch size 1, certain dimension alignments)
- Precision is fp16 or int8
- Custom ops (e.g., some schedulers)
- Unsupported tensor shapes
- Dynamic shapes (rare in Stable Diffusion)
Full-precision models run faster because ANE doesn’t need to dequantize weights.
Power Efficiency:
ANE power consumption: ~1-2W during inference (vs. 5-8W for GPU). iPhone 15 Pro generates 10 images on a full charge with screen off.
RAM-Based Limitations
Off Grid enforces RAM-based safety limits to prevent OS-level kills and crashes.Pre-Load Memory Checks
Warning Thresholds:
- 50% (Yellow Warning)
- 60% (Red Error)
Runtime Context Caps
abort() during KV cache allocation).
Auto-Scaling Context:
Overload Prevention in ARCHITECTURE.md
From source docs:RAM-Aware Runtime Safeguards: On low-RAM devices (e.g. iPhone XS with 4GB), llama.cpp and CLIP can callImplementation:abort()during Metal GPU allocation, which is a POSIX signal that bypasses JavaScript try/catch and kills the app instantly. To prevent this,initWithAutoContext()applies device-RAM-based caps before any native call:
initContextWithFallback(), so the dangerous Metal allocation is never attempted.
Performance Benchmarks
Text Generation (Tokens/Sec)
Android (Snapdragon 8 Gen 3):
iOS (A17 Pro):
Image Generation (Seconds)
Android:
iOS:
Vision Inference (Seconds)
Best Practices
For LLM Inference
- Start conservative: Begin with 0 GPU layers, incrementally increase by 8-10 layers while monitoring stability
- Monitor temperature: Sustained generation can trigger thermal throttling on mobile devices
- Reduce context on ≤4GB devices: Use 2048 max context to prevent OOM
- Disable flash attention with GPU: Auto-disabled on Android, but verify on custom builds
For Image Generation
- Prefer NPU/ANE over CPU: 2-3x faster with lower power consumption
- Use fp16 models on iOS: Palettized models are 2x slower due to dequantization overhead
- Cache warmup on first run: Warn users first generation will be slow (QNN cache building)
- Unload text model before image generation: Prevents RAM contention on 4-6GB devices
For Memory Management
- Respect 60% RAM budget: Prevents OS kills
- Warn at 50%: Give users option to close background apps
- Unload before switching models: Releases GPU/ANE resources
- Monitor with DeviceInfoScreen: Real-time RAM usage in settings
Debugging Acceleration Issues
OpenCL (Android)
CL_OUT_OF_HOST_MEMORY— Reduce GPU layersCL_DEVICE_NOT_FOUND— GPU not detected, use CPU- SIGSEGV during
clBuildProgram— OpenCL compiler crash, disable GPU
Metal (iOS)
MTLBuffer allocation failed— Reduce context size or GPU layersabort() in mtl_backend_init— ≤4GB device, GPU layers should be 0
QNN (Android)
Failed to create backend— SELinux blocking DSP, use MNN fallbacklibQnnHtp.so not found— Runtime libs not extracted, checkprepareRuntimeDir()
ANE (iOS)
Use Xcode Instruments → Core ML:- Profile → Core ML
- Run image generation
- Check “ANE Utilization” track
- Should be over 80% during UNet inference
References
- llama.cpp Backends:
https://github.com/ggerganov/llama.cpp/tree/master/docs/backend - Qualcomm AI Engine:
https://www.qualcomm.com/developer/software/qualcomm-ai-engine-direct - Apple Neural Engine:
https://github.com/hollance/neural-engine(reverse engineering) - Core ML Performance:
https://developer.apple.com/documentation/coreml/optimizing_your_model_for_the_neural_engine - Metal Performance Shaders:
https://developer.apple.com/documentation/metalperformanceshaders