我逆向工程了 NPU 厂商的引擎格式(int8 权重存储为两个半字节平面)以运行 GGUF 而无需模型转换——现在比厂商自己的运行时快 1.5 倍
摘要
逆向工程了 Axera AX8850 NPU 的 int8 权重格式,以在 llama.cpp 中实现直接 GGUF 推理,在 Raspberry Pi 5 上实现了高达 24.5 t/s 的解码和 716 t/s 的预填充,性能比厂商的运行时高出 1.5 倍。
我一直在 Raspberry Pi 5 上运行 Qwen3-0.6B,使用 M5Stack LLM-8850 卡(Axera AX8850 NPU,24 TOPS,8GB LPDDR4x)作为 llama.cpp 后端。问题在于:厂商的软件栈要求通过他们的编译器转换每个模型,而他们的封闭运行时只能达到 13.5–14.5 t/s。我想要 llama.cpp 直接工作:输入 GGUF,输出 tokens。我最终做了什么:逆向工程了引擎格式。厂商编译的引擎(.axmodel)将权重存储在一个名为 npu_params 的 blob 中。我解码了它:int8 权重存储为两个半字节平面——一个粗糙的字节对每个元素对保存两个高位半字节,一个精细的字节在18个位置之前保存两个低位半字节。为了破解这个布局,我构建了大约10个“标记”检查点,其中每个权重编码自己的(行,列)坐标,通过厂商工具链编译它们,并比较输出差异。所有每层的7个矩阵的完整布局,加上缩放表。在加载时直接将 GGUF 权重修补到预编译的引擎中。无需转换步骤,无需为每个模型编译。GGUF 反量化 → 根据引擎自身的缩放重新量化 → 只有真正不同的字节被写入。与同一 GGUF 的 CPU 参考相比,token 一致性达到 96%。发现“损坏”的批量预填充路径从未损坏。厂商提供了预填充形状组,但自己的主机运行时从未调用;每个人都假设它们不工作。它们工作正常——bug 出现在每个人(包括厂商的示例)如何绑定输出缓冲区的方式上。修复后:预填充达到 716 t/s,输出字节一致。在 Pi 5 上的当前数字(贪婪,单流):在 int4 引擎上,解码达到 24.5 t/s @ 2k 上下文(使用 1k 上下文构建时为 29.9 t/s)使用裁剪的词汇表头部达到 26.8 t/s提示处理达到 716 t/s Pi CPU:空闲。卡片完成所有工作。在此过程中,我测量了“24 TOPS”实际去向:在批量1解码时,这类芯片是一个内存带宽问题(有效流式传输约 25 GB/s,达到 LPDDR4x 峰值的 73%),而 MAC 利用率约为 1%——即使一个完美供给的 Transformer GEMM 在此数据流上也仅能达到约 2.6 有效 TOPS。解码速度 = 每个 token 的字节数 × 每个权重通道的 tokens 数。这个框架预测了我们所有的改进(int4 = 1.5×,批量预填充 = 39×,词汇表裁剪 = +10%)。链接:项目仓库(README:快速开始,完整的优化故事,布局破解工具包,在线测试工具):https://github.com/woolcoxm/LLMTest 带有后端的 llama.cpp 分支(单个约4.5k行文件,ggml/src/ggml-axcl/ggml-axcl.cpp):https://github.com/woolcoxm/llama.cpp 演示图像(24 t/s 流式传输,Pi CPU 约1%,来自实际捕获的运行):https://raw.githubusercontent.com/woolcoxm/LLMTest/main/docs/demo.png 所有内容都可以从 README 快速开始重现:在任何带有 AXCL 驱动程序的 aarch64 主机上构建 llama.cpp 时使用 -DGGML_AXCL=ON,指向引擎集,喂入 GGUF。我很乐意在评论中深入讨论半字节平面布局、标记构建方法论或 AX8850 的实际性能范围。
相似文章
Reddit r/LocalLLaMA
一位社区开发者发布了 Ninfer 4080,这是一个优化的本地推理运行时,可在 16GB 的 RTX 4080 上以 100k 上下文运行 Qwen 3.8 27B GSQ 模型,通过 DFlash2 投机解码实现了最高约 2720 tok/s 的预填充速度和 262 tok/s 的解码速度——比 llama.cpp 或 vLLM 等通用引擎快得多。
Reddit r/LocalLLaMA
一位开发者发布了 open_rknpu2_lm_infer,这是一个用 Rust 和 C++ 编写、面向 Rockchip RK3588 NPU 的开源 LLM 推理引擎,它绕过了专有厂商库,运行 Qwen3.5-4B 的速度约为 Rockchip RKLLM SDK 的两倍,并支持多模态输入和投机解码。
Reddit r/LocalLLaMA
逆向工程了RK3588 NPU并构建了一个开放编译器和运行时,以从PyTorch、ONNX和JAX运行GPT-2和SigLIP,无需供应商SDK。
Reddit r/LocalLLaMA
LoRA over GGUF 系列更新:Qwen3.8-Flash-Next(125B-A6B + 51B engram)现在可以在 40 GiB 显存中进行 LoRA 训练,无需 CPU 卸载,在 Strix Halo 上达到 200 token/s 的速度,transformers 5.18 已合并初步的 GGUF 支持,更多内核优化(GGTensile)也即将到来。
Reddit r/LocalLLaMA
本文介绍了将AI9Stars G9v3-39A5B混合专家模型非官方量化至GGUF格式的过程,以及为支持BF16与Q4_K_M变体本地推理而创建的llama.cpp专用分支。