|
Download docs/VISION_OFFLOAD.md from elyanlabs/open-xdna: direct link, hf CLI and curl.
- Browser
- Download file 3.4 kB
-
https://huggingface.co/elyanlabs/open-xdna/resolve/main/docs/VISION_OFFLOAD.md
- Command line
-
hf download hf://elyanlabs/open-xdna/docs/VISION_OFFLOAD.md
-
curl -L -o VISION_OFFLOAD.md https://huggingface.co/elyanlabs/open-xdna/resolve/main/docs/VISION_OFFLOAD.md
3.4 kB
| # NPU vision offload β the multimodal front-end belongs on the NPU | |
| **Thesis:** for a multimodal model (image + text), put the **vision front-end on the XDNA1 | |
| NPU** and keep text generation on the CPU/iGPU. This is the NPU's *designed* purpose β Ryzen AI | |
| NPUs exist for edge vision/CNN inference β so unlike text decode (memory-bound, where the NPU | |
| loses), the vision path is **compute-bound conv work the AIE array is built for.** | |
| ## Why vision, not text | |
| | | text decode | vision front-end | | |
| |---|---|---| | |
| | bottleneck | memory bandwidth | compute (convs/matmuls) | | |
| | NPU fit | poor (M0/M0.5: NPU loses) | **strong** (AIE = CNN engine) | | |
| | parallelism | low (gemv) | high (patches/channels) | | |
| | concurrency | β | runs while CPU/iGPU do the LLM | | |
| | power | β | ~6.6 W | | |
| The NPU stops being a reluctant matmul unit and becomes what it was made for. | |
| ## Proven on silicon (this repo) | |
| A full image-processing pipeline runs on the gen-1 NPU today β `programming_examples/vision/ | |
| edge_detect` (`rgba2gray β 3Γ3 Laplacian filter2d β threshold`), verified vs an OpenCV reference: | |
| ``` | |
| $ python3 edge_detect.py -W 512 -H 512 | |
| Number of differences: 1942, average L1 error: 0.96 | |
| PASS! | |
| ``` | |
| IRON ships the vision/CNN kernel set the front-end needs: `conv2dk1`, `conv2dk3` (incl | |
| depthwise + ReLU + pooling variants), `conv2dk1_i8`, `filter2d`, `rgba2gray`, `gray2rgba`, | |
| `rgba2hue`, plus `softmax`/`gelu`/`silu` for the encoder blocks. These are exactly the ops a | |
| ViT/CNN image tower (patch-embed conv, conv stem, channel projections) is made of. | |
| ## The hook (proposed integration) | |
| For a multimodal model with a vision encoder (PaliGemma / Gemma-vision / LLaVA-style towers): | |
| 1. **Image preprocessing + patch-embed conv β NPU** (`conv2dk1`/`conv2dk3`/`filter2d`). | |
| 2. **Vision-encoder early conv/projection stages β NPU**, streaming patch tiles. | |
| 3. Hand off the image embeddings to the text path: **decode β Radeon 780M, prefill β CPU.** | |
| 4. The NPU also runs the **prune/collapse coprocessor** on attention/FFN (see TIER3_DESIGN.md). | |
| Net: a 4-way split on the integrated SoC β **NPU = vision + prune, 780M = decode, CPU = | |
| prefill** β all over the 96 GB unified pool, no discrete GPU. | |
| ## Honest status | |
| - β **Proven**: conv / 2D-filter / colorspace vision kernels run on the NPU (edge_detect PASS). | |
| These are the building blocks of a vision tower. | |
| - β **SigLIP/ViT patch-embed wired + measured** (`examples/npu_patch_embed.py`): the patch-projection | |
| matmul ([256Γ768]@[768Γ768], SigLIP-base/16) runs on the NPU, **bit-exact**. HONEST measurement: at | |
| base size the NPU (int16, 6.6 ms / 46 GFLOP/s, dispatch-bound) is **~3.2Γ SLOWER than fair CPU f32 | |
| BLAS** (2.0 ms / 148 GFLOP/s). The win is **offload + ~6.6 W + scaling** (frees CPU/iGPU for the LLM, | |
| gap closes at larger image/batch), **not raw latency** at SigLIP-base. Don't quote int32-numpy as the | |
| CPU baseline β it's unoptimized (~1.5 GFLOP/s) and makes the NPU look 34Γ faster, which is false. | |
| - π§ **Not yet done**: full multi-stage encoder (conv stem + transformer blocks) + a batched/larger-image | |
| regime where the NPU's offload+power actually nets ahead; measure end-to-end encoder latency & SoC power. | |
| - The "boost" is expected to be real *because* this is the NPU's native workload β but it is a | |
| projection from the proven primitives until a full vision tower is wired and measured. | |