Download docs/architecture-and-operation.zh-CN.md from shadowtec/Audio8-ASR-0.1B-RK3576-RKNN: direct link, hf CLI and curl.
- Browser
- Download file 3.71 kB
-
https://huggingface.co/shadowtec/Audio8-ASR-0.1B-RK3576-RKNN/resolve/main/docs/architecture-and-operation.zh-CN.md
- Command line
-
hf download hf://shadowtec/Audio8-ASR-0.1B-RK3576-RKNN/docs/architecture-and-operation.zh-CN.md
-
curl -L -o architecture-and-operation.zh-CN.md https://huggingface.co/shadowtec/Audio8-ASR-0.1B-RK3576-RKNN/resolve/main/docs/architecture-and-operation.zh-CN.md
RK3576 / RKNN KV-cache 策略调研
结论
RK3576 NPU 可以执行带有 cache 输入、Concat、Gather/Slice、Attention 的静态图;因此不能说硬件“完全不支持 KV cache”。但 RKNN Lite 普通 inference() 是无状态函数接口,没有一个通用的、跨调用自动持久化的 KV-cache 对象。所谓“由 NPU 自己更新 cache”必须在图中显式实现写回(Concat、ScatterND、预分配 buffer + position 等),并不等同于 runtime 自动保存状态。
当前项目第一版用了 Transformers DynamicCache.update() 导出路径。该路径把 cache 更新/Concat trace 进 ONNX,再由 RKNN 重写 layout。它在 ONNX Runtime 上正确,但 RK3576 上第 0 层的 projection 正常、Concat 后即出现约 140% L2 偏差,说明当前问题是编译后 cache layout/reorder/Gather/Concat 语义,而非 RK3576 缺少 attention 算力。
本地 TTS RK3576 研究也记录了同类事实:完整 AR FP16 图曾在实板 rs-gather submit 失败;问题收敛到 compiler 为 attention / ScatterND 生成的固定重排 Gather 路径。另一个 Fast AR 图在 position 1 分叉;无状态 FFN 子图则稳定。这些记录支持“状态写回/重排路径是风险中心”的判断。
三种实现路线
1. NPU 图内动态 Concat/ScatterND
NPU 读取旧 cache → NPU 计算新 K/V → NPU Concat/Scatter 写回 → Attention
优点:理论上减少 CPU 拼接,数据路径短。
风险:当前已经失败;容易触发 RKNN 的 -rs-gather、layout 重排、ScatterND 和静态轴问题。即使 compiler 能生成 .rknn,也必须逐位置验证,不能以首轮能运行作为通过标准。
2. CPU 管理 cache,NPU 读只读历史 cache(推荐第一修复路线)
CPU 保存 old K/V
NPU 计算当前 token 的 attention、FFN、logits 和 new K/V
CPU concat(old, new_delta)
优点:跨调用状态明确,CPU concat 只有约 3.63 ms;失败时边界清楚,可按 token 调试。缺点:每步需要搬运历史 K/V,且 decoder 图需要避免再次调用 DynamicCache.update() 的内部 Concat。
3. 固定最大 cache + NPU 位置写入
预分配 [B,H,Smax,D],用 cache_position 写入当前位置
优点:固定 shape,有机会实现 zero-copy/少搬运。
风险:仍依赖 Scatter/Masked assignment、position 和 layout;应在路线 2 证明数学递归正确后再尝试。
当前推荐顺序
先修正 decoder 图,去除 DynamicCache.update() 的图内写回/Concat;
让 CPU 跨步保存并追加 K/V,NPU 图只消费明确的只读历史 cache;
先做第 0 层和 token 1 的逐中间量比较;
通过后扩展 8 层与 token 0/1/2/3/16/EOS;
最后再试固定最大 cache 的 NPU 写入。
验收门槛
KV cache 是递归状态,门槛比一次性 encoder 更严格:
每层 K/V delta normalized L2 <= 0.5%:候选通过
0.5%~1%:警告,不能直接部署
>1%:不通过
decode logits normalized L2 <= 0.5%,且 top-1 token 不变
token 0/1/2/3/16/EOS 全部一致
最终 CER/WER 不出现稳定退化
当前图:logits L2 113.16%、K/V delta 最大 L2 143.56%、token 13→3711,属于明确失败。
时间解释
当前 97.68 ms 是普通 rknn.inference() 混合总时间,包含输入准备、runtime/layout、driver submit、NPU 计算、输出回收和同步;不能称为纯搬运。单独可测的 CPU concat 是 3.63 ms,历史 K/V 输入约 3.44 MiB,delta 输出 32 KiB。后续应继续使用 runtime layer table 报告 NPU operator time 和 CPU boundary time,把剩余量称为 runtime/data-boundary overhead,而不是 DMA 纯时间。