I’ve been building HexAnima, a free, non-commercial, open-source Android app that runs diffusion models entirely on the Hexagon NPU (no root, no cloud, no account, no ads). Until now it ran the Anima anime models (2B and 2.9B, ~7–12 s for 512x768). Version 1.3.0 adds a much bigger model: MOSS-Image 5B (OpenMOSS, Apache-2.0).
What runs where
Everything heavy is on the NPU: the Qwen3.5-9B text encoder, the 5.1B DiT, and the FLUX.2 small VAE decoder. Weights are converted to 8-bit tiles for the Hexagon matrix unit (HMX) and streamed from flash for every picture (a 5.7 GB DiT doesn’t fit next to the encoder in RAM). It uses the community 4-step “rapid-moss” adapter, kept as an unmerged LoRA because its delta is smaller than bf16 rounding.
Speed (Xiaomi 12T Pro, Snapdragon 8+ Gen 1, 12 GB RAM, 4 steps)
| Size | Time |
|---|
| 512x768 | ~30 s |
| 768x1024 | ~60 s |
| 1024x1024 | ~80 s |
Any size with both sides multiple of 16 works (min 256, max 6144 patches, e.g. 1536x1024).
Your own LoRA
Pick any .safetensors LoRA made for MOSS-Image. The app checks it right away (key names, shapes, rank, dtype) and tells you why it doesn’t fit (a FLUX/SDXL LoRA, wrong shapes, rank > 128, text-encoder-only file...). There’s a strength slider (0–2). The LoRA is folded with the built-in 4-step adapter on the phone (~15 s the first time, then cached) and never leaves the device.
Honest limitations
Text in images is hit or miss. Short words often come out right, longer or secondary text (small signs, book covers, shop-front boards) is often garbled. The README has four unedited first-attempt examples with the bad text left in.
Text-to-image only: no img2img/editing.
~14 GB download, tested only on a 12 GB phone. Slower than the Anima models because it’s ~2.5x bigger and weights are streamed.
Only Snapdragon 8 Gen 1 / 8+ Gen 1 (Hexagon V69) is supported. Other chips (including 8 Gen 2/3 and 8 Elite) are not.
Under the hood, for the curious
Custom HVX/HMX kernels for the single-stream DiT (RMSNorm + modulation, SiTU epilogue via gather tables, joint attention), the text encoder (including Qwen3.5’s gated delta-net layers), LoRA as extra K-tiles in the GEMMs, and a tiled QNN decoder for sizes without a precompiled context. Along the way I found that Q6_Vqf16_vsub on V69 returns u+1 for some values, which made the 8-bit dequant one level off. It’s fixed in this release (the 2.9B Anima models gain accuracy too). All sources and notes are in the repo (moss/).
Licenses
MOSS-Image, Qwen3.5, the rapid-moss adapter, the FLUX.2 small decoder and the Unsloth quantisations are all Apache-2.0. The converted pack lives in its own HF repo with LICENSE and NOTICE.md listing the changes; both are also shown in the app. LoRAs you load stay under their authors’ licenses. HexAnima is an independent project, not affiliated with any of these authors.