darkmaniac7's picture
Add SDXL-Turbo W8A16 Hexagon NPU bundle (V75-native, fwd-compat V79/V81) + manifest
39ae3a9 verified
|
Raw
History Blame
5.31 kB
---
license: other
license_name: stabilityai-ai-community
license_link: https://huggingface.co/stabilityai/sdxl-turbo/blob/main/LICENSE.md
tags:
- stable-diffusion-xl
- sdxl-turbo
- qnn
- hexagon
- npu
- w8a16
- text-to-image
- tokforge
pipeline_tag: text-to-image
library_name: qnn
inference: false
---
# TokForge SDXL-Turbo Β· Hexagon NPU (W8A16)
**PRIVATE** model bundle for the **TokForge** Android app (`dev.tokforge`). This repo hosts the
**SDXL-Turbo** image-generation pipeline compiled to **QNN context binaries** for the
**Qualcomm Hexagon DSP (HTP)**, so TokForge can fetch the SDXL-NPU "Faithful" backend from scratch
(previously hand-staged on devices only).
Sibling of [`darkmaniac7/TokForge-SD15-QNN-NPU`](https://huggingface.co/darkmaniac7/TokForge-SD15-QNN-NPU)
(SD1.5). Same non-root `untrusted_app` cDSP recipe; this is the higher-quality 1024px tier.
## What this is
- **Model:** SDXL-Turbo (few-step distilled SDXL), native **1024Γ—1024** (128Γ—128 latent).
- **Quantization:** **W8A16** (8-bit weights, 16-bit activations) on the Hexagon HTP.
- **Runtime:** **QAIRT 2.40**. Bin set is **V75-native** (`libQnnHtpV75Skel.so`).
- **Variant:** **fp16 text encoders + TAESDXL** tiny-VAE (see below).
- **Footprint:** **~4.3 GB** on disk (the on-device fresh download is this big).
## Pipeline / variant
This bundle is the **fp16-encoders + TAESDXL** variant the `libsdxl_qnn_driver` runs end-to-end
(no host orchestration beyond the emb-MLP):
| Stage | File | Where it runs |
|-------|------|---------------|
| CLIP-L text encoder | `text_encoder_1_fp16.bin` | DSP (fp16) β†’ `last_hidden [1,77,768]` |
| OpenCLIP-bigG text encoder (+proj) | `text_encoder_2_fp16.bin` | DSP (fp16) β†’ `last_hidden [1,77,1280]` + `pooled [1,1280]` |
| text_embedding | concat β†’ `[1,77,2048]` | driver |
| combined-emb MLP | `sdxl_emb_mlp.bin` | **host CPU** β†’ `emb [1,1280]` per step |
| UNet (EulerAncestral, 4 steps, guidance 0) | `unet.bin` (2.6 GB) | DSP |
| VAE decode (1024px) | `taesdxl_decoder.mnn` (2.4 MB) | **CPU** (MNN tiny-VAE) |
**Why the host emb-MLP:** qairt-converter 2.40 constant-folds SDXL's two sinusoidal paths
(`time_proj` and `add_time_proj`). The driver dodges both by precomputing the **combined**
`emb = time_embedding(time_proj(t)) + add_embedding(cat(pooled, add_time_proj(time_ids)))` on host
(weights in `sdxl_emb_mlp.bin`) and feeding it as ONE float UNet input, so no foldable path remains.
**Why TAESDXL CPU VAE:** it is the **only validated** VAE path. The DSP VAE is blocked at 1024px on
V75 (unsigned-PD HTP cap) and the OpenCL/Vulkan VAE SIGSEGVs Adreno in `Session::resize`. The driver
always selects `--vae_mnn` + `SDXL_VAE_BACKEND=cpu`.
**SDXL-Turbo is guidance-free** (`guidance_scale 0`): NO CFG β†’ one UNet pass per step. EulerAncestral,
4 steps native (6 for quality), VAE scaling factor **0.13025**.
## Arch coverage & verification
| Set | dsp_arch | Skel | Verified |
|-----|----------|------|----------|
| `ours/v75` | 75 (V75) | `libQnnHtpV75Skel.so` | **YES** β€” device-verified coherent+crisp on Lenovo **SM8650/V75** (.69) |
**Forward-compat:** a lower-arch bin runs on a higher-arch DSP. The **V75-native** set is the
shipping set for **V73 β†’ V81**, and was **verified by forward-compat on V81** (RedMagic **SM8850**
handsets .82 and .80, coherent+crisp). **Native V81/V79 SDXL bins are NOT separately built** β€” V75-native
is the single own-built set today.
| SoC class | Hexagon | Status |
|-----------|---------|--------|
| 8 Gen 2 / 8s Gen 3 (SM8550/SM8635) | V73 | covered by V75-native forward-compat (untested on device) |
| 8 Gen 3 (SM8650) | V75 | **device-verified** |
| 8 Elite (SM8750) | V79 | forward-compat (untested on V79 silicon) |
| 8 Elite Gen 5 (SM8850) | V81 | **forward-compat verified** (.82, .80) |
## Provenance
Clean-room conversion, our own pipeline (no third-party NPU bins):
1. **Base:** `stabilityai/sdxl-turbo` (fp16 safetensors) β†’ ONNX export (UNet emb-input/fold-proofed
graph, dual CLIP encoders, TAESDXL decoder).
2. **Quantize:** **W8A16** via QAIRT (calibration set), graph name `model`.
3. **Compile:** `qnn-context-binary-generator` β†’ V75 HTP context binaries (**QAIRT 2.40**).
4. **VAE:** TAESDXL exported to a CPU MNN model (`taesdxl_decoder.mnn`).
## License
**SDXL-Turbo β€” Stability AI Community License** (`stabilityai/sdxl-turbo`).
- Commercial use **permitted** for organizations/individuals with **< $1M USD annual revenue**.
- Above $1M revenue requires a **Stability AI Enterprise license**.
- **Attribution + license text must be retained** with the model.
- This is **NOT** OpenRAIL-M (that covers the sibling SD1.5 bundle).
Text encoder bases: OpenCLIP bigG (MIT-class), OpenAI CLIP-L (MIT).
## Files
See `manifest.json` for the authoritative file set with per-file md5 + size. The app reads
`manifest.json`, resolves the device Hexagon arch, downloads the matching set into
`filesDir/image_models/SDXL-QNN-NPU/`, and the `libsdxl_qnn_driver` loads the bins flat from there.
**Driver-required files** (every one must be present + non-empty for a usable bundle):
`unet.bin`, `text_encoder_1_fp16.bin`, `text_encoder_2_fp16.bin`, `sdxl_emb_mlp.bin`,
`taesdxl_decoder.mnn`, `tokenizer/{vocab.json,merges.txt}`, `tokenizer_2/{vocab.json,merges.txt}`.