Conversation
|
For ggml-related changes, please submit a PR to ggml-org/ggml or ggml-org/llama.cpp first. If the changes are merged upstream, I will sync them here. As for the FP8-related changes, I previously submitted a PR to ggml-org/llama.cpp, but it has not been merged yet. |
|
Yes, getting first-class FP8 support merged into
Our Hexagon work also includes FP8 GEMM, flash attention, fused operations, VAE kernels, runtime integration, and tests. Upstreaming the complete stack incrementally will likely take weeks or even months. Meanwhile, there is clear demand from Qualcomm users who want to run diffusion models on their devices:
Our Local Dream users also want to run newer DiT models beyond SDXL on-device. This is intended to be a Qualcomm-wide optimization branch, covering both the Hexagon NPU and the Adreno OpenCL GPU path. We will also integrate the existing and follow-up Adreno OpenCL work, including #22755, #26085, #26331, and #28446, as those changes land upstream. For this reason, I believe it would be practical to create a temporary |
You may wish to reach out to the GenieX team at Qualcomm. An earlier (pre-acquisition) version of what is now GenieX included stable-diffusion.cpp and they have regular meetings with the llama.cpp maintainer responsible for Hexagon. |
9341d9d to
422d937
Compare
|
@happyyzy, hello, maybe you could try to contact @rmatif, he attempted to use Hexagon (#670, comment) in rmatif/Local-Diffusion (but did't publish releases with QNN support). |
Motivation
We are building high-performance DiT inference on Qualcomm devices, covering both Adreno GPUs and Hexagon NPUs, for Local Dream.
Our Adreno work is already being contributed to llama.cpp: #22755, #26085, and #26331 are merged; Fused QKNorm-RoPE #28446 is currently open.
This PR provides the integrated Hexagon NPU path for stable-diffusion.cpp.
Implementation
The v79+ path includes standard
F8_E4M3safetensor loading; HMX 32x32set_tensorrepacking; FP8 W8A16 GEMM; non-causal HMX FA; fused Q/K RMSNorm-RoPE; segmented-K Kleinlinear2; FP16 VAE activations; direct implicit-GEMM convolution; fused GroupNorm-affine-SiLU; and fused upscale-convolution. Qwen3-4B uses the existing generic Hexagon Q4 kernels. This path supports end-to-end image generation at resolutions from 1K up to 2K, amazing for a phone!The FP8 GEMM uses the v79
activation.hf/weight.f8HMX path with FP32 accumulation. HMXcvt.hf = acc(2)applies the architectural 1/256 conversion; the HVX output epilogue compensates by 256 and folds the model's FP32 weight scale and any graph scalar scale into the same store pass.Temporary integration
The FP8 plumbing required for full llama.cpp integration has not yet been accepted into llama.cpp's embedded ggml, for reasons that remain unclear to us. This PR temporarily uses happyyzy/ggml, branch
work/qualcomm-hexagon-optimizations, commit8121decc678bfb9f02a0f7190bce143bfb1599fa.The generic pieces are being upstreamed into llama.cpp incrementally. This is a temporary integration vehicle for Local Dream until that work is complete.
End-to-end results
Device: Snapdragon 8 Elite / SM8750 / HTP v79. TE, DiT, and VAE all run on HTP. Prompt is
a lovely cat, Euler, CFG 1, seed 42. ``E2Eisgenerate_image completed`, including live TE, all sampling steps, and VAE decode. None of these runs uses tiled VAE.During the long 1536 runs, Z-Image iterations 5-8 rose to 36.16-38.37 s/it and the final Klein iteration rose to 25.24 s/it. The E2E numbers above include that thermal throttling.
This puts phone-class Snapdragon inference close to mainstream NVIDIA RTX GPU latency for these distilled pipelines.
Commands
Images
Z-Image 1024, 8 steps
Klein 1024, 4 steps
Z-Image 1536, 8 steps
Klein 1536, 4 steps
FP8 vs Upstream Q4_0/Q8_0
Compared with upstream Hexagon using standard Q4_0/Q8_0 GGUF weights, FP8 is 8.87x faster for Z-Image and 9.30x faster for FLUX.2/Klein at 1K, while also delivering visibly better image quality.
Q4_0 + Q8_0
F8_E4M3