概括
在 K3 Pico-ITX 上用 ONNX Runtime 跑 EmbeddingGemma-2 文本嵌入,CPUExecutionProvider 可用(单条 182 ms,与本机 fp32 结果逐位一致);SpaceMITExecutionProvider 跑得动但结果错(cosine 0.6956),检索不可用。我用 EP 自带的张量导出功能把误差定位到了具体的算子:/model/layers.0/attn/MatMul_qk(注意力 Q·Kᵀ),而紧邻的 /model/layers.0/attn/qkv_proj/MatMul 是正常的。
社区的其他类似问题贴
- [bug]SpaceMITExecutionProvider推理bug
- SpaceMIT Execution Provider 进行AI加速的问题
- 使用SpaceMITExecutionProvider发生错误,以及加载模型和推理时间增加的问题
- 发现K3的一个致命bug: SpacemiT EP 库(libspacemit_ep.so)在 K3 的 Bianbu 系统上存在兼容性问题
- K3 上 llama.cpp-spacemit 与 ONNX SpaceMITExecutionProvider 并发运行时出现 TCM buffer 冲突
- K1使用SpaceMIT Execution Provider出现tcm buffer acquire failed报错
- ORT推理时打印alloc failed(131072)
- Execution providers for onnxruntime
- reshape的维度(官方 bug 报告模板 + xslim 指引)
- 进迭时空双周报-(20250822-0921)
- SpacemiT EP 2.0.5 的 INT8 回归问题(仓库唯一 issue)
- spacemit-com/onnxruntime Releases
一、环境
| 项 | 值 |
|---|---|
| 硬件 | K3 Pico-ITX,16 GB LPDDR5;8 核 X100(cpu0-7 @2.2GHz)+ 8 个 AI 核(cpu8-15 @1.8GHz) |
| 系统 | Bianbu 4.0.1(codename resolute),kernel 6.18.3,riscv64 RVA23 |
| ONNX Runtime | onnxruntime 1.24.0+spacemit.a3(apt python3-spacemit-ort) |
| EP 库 | apt spacemit-ort 2.0.7;另试官方 release spacemit-ort.riscv64.2.0.7 |
| 模型 | EmbeddingGemma-2 文本骨干 ONNX fp32(1.08 GB,ai.onnx opset 21 + com.microsoft 1) |
| 量化版 | 社区转换 int8(314 MB,onnx-community/embeddinggemma-2-ONNX) |
| Python 依赖 | tokenizers(PyPI 的 riscv64 wheel,用 pip install --target 装入,未动系统 Python) |
术语说明:K3 上没有 GPU,加速单元是 8 个 AI 核,EP 指的是 SpaceMITExecutionProvider。
二、复现步骤
- 把模型与 tokenizer 放到板子的
/root/models/eg2/。 - 按
ort.InferenceSession(path, providers=["CPUExecutionProvider"])建会话并跑,得到参考向量。 - 把
providers换成["SpaceMITExecutionProvider"],其余不动。 - 用同一个句子的输入,比较两次输出的 cosine 相似度。
三、实测数据
| 配置 | 单条耗时 | cosine vs fp32 参考 | top-3 检索结果 |
|---|---|---|---|
| fp32 + CPU EP | 182 ms | 1.00000 | 正确 |
| int8 + CPU EP | 298 ms | 0.99995 | 与 fp32 完全一致 |
| fp32 + SpaceMIT EP | 132 ms | 0.69561 | 全错 |
| int8 + SpaceMIT EP | 编不过 | — | — |
板子上的其它基准:模型装载 1.4 s;64 个文本块按 4 批建索引 119.36 s(1865 ms/块);峰值内存 1505 MB。
四、定位过程
EP 提供了两个导出开关,我把中间结果全部导出后与本机 CPU EP 逐张量对拍。
SPACEMIT_EP_DUMP_SUBGRAPHS=1导出 EP 编译出的子图:145 个。SPACEMIT_EP_DUMP_TENSORS=<dir>导出每层张量:533 个。- 用一个只对齐输出名的探针模型,把两边同名的张量逐个比较。
- 每个张量同时算两个指标:顺序敏感误差与顺序无关误差(后者用于排除转置造成的布局假象)。
- 按图序找第一处真分歧。
结果:
| 图序 | 张量 | 顺序敏感误差 | 顺序无关误差 | 判定 |
|---|---|---|---|---|
| #57 | /model/embedding_projection/MatMul |
5.6e-7 | 5.6e-7 | 正常 |
| #67 | /model/layers.0/attn/qkv_proj/MatMul |
6.7e-7 | 6.7e-7 | 正常 |
| #112 | /model/layers.0/attn/MatMul_qk |
1.00 | 0.33 | 算错 |
误差再逐层放大:layer 0 最大 1.5,layer 8 达 3.1,layer 16–20 的 MLP 到 5–17 倍。
为了排除 com.microsoft::RotaryEmbedding 的干扰,我还把它拆成 Slice/Mul/Add/Concat 等基础算子(拆完在 CPU EP 上与原图 cosine = 1.00000,即逐位一致)。拆完后 EP 不再报编译错、能跑整图,但 cosine 仍是 0.69561,与本机逐位相同 —— 说明误差不来自 RotaryEmbedding。
五、已排除的做法
| 做法 | 结果 |
|---|---|
SPACEMIT_EP_DENSE_ACCURACY_LEVEL = 0/1/2/3(int8/FP16/FP32 档) |
输出逐位相同 |
SPACEMIT_EP_DISABLE_FLOAT16_EPILOGUE 开/关 |
逐位相同 |
| 换 int8 量化模型 | EP 报同一个 RotaryEmbedding 错;CPU 上反而更慢(298 ms) |
| 拆 RotaryEmbedding 图手术 | 见上,cos 不变 |
SPACEMIT_EP_DISABLE_PASSES_FILTER 关掉 MatMulTransposeFusion、PackedAttentionFusion、_FusePackedAttention |
毫无效果,耗时与结果逐位相同(该旋钮看来未实现,也不在文档的 ProviderOption 列表里) |
SPACEMIT_EP_DISABLE_OP_TYPE_FILTER="Attention" |
无效果 |
SPACEMIT_EP_DISABLE_OP_NAME_FILTER 把 24 个 QKᵀ 踢回 CPU |
生效(142→136 ms),但 cosine 仍 0.6815,精度不恢复 |
xslim fp32 精简后再跑 |
EP 仍报同一个 RotaryEmbedding 错;关掉 rotary 后 cosine 仍 0.69561 |
xslim --fp16 后再跑 |
xslim 产出的模型装不进 ORT(见下面第六节) |
六、附带发现的三个小问题
- apt 的 EP 库与官方 release 不是同一份:apt 版
libspacemit_ep.so.2.0.7的 md5 是ac949dde…,官方 release 是a16afbce…。apt 版加载即报Attempt to use DefaultLogger but none has been registered.,反过来建 session 又直接段错误(官方自己的resnet18.q.onnx也是这样)。换成 release 版后 resnet18 int8 单条 2.95 ms,正好对上 modelzoo 标称的 2.90 ms。 xslim 2.1.1的两个问题:(a) 对 ai.onnx opset 21 的模型,默认的版本转换会崩(IndexError: invalid unordered_map key),要显式加--opset 21才能跑;(b)--fp16产出的模型 ORT 装不进,报/model/attention_bias/sliding/Where与/model/pooling/count/Max的类型不匹配(fp32 与 fp16 混用),清掉 value_info 后还会在下一个节点复发。- TCM 节点缺失:板子已经装了
spacemit-tcm 3.0.1,/dev/tcm存在,但没有/dev/tcm_sync_mem。llama.cpp 侧会报open(/dev/tcm_sync_mem) failed并退化到堆内存。
七、希望得到的答复
- SpaceMIT EP 在这类结构(24 层、rank-5 注意力、Q/K/V 由 Transpose + MatMul 组成)上是否已知有精度问题?有没有已修复的版本?
- 官方验证流程一般是先过
xslim再上板。我已按这个流程做过,问题依旧 —— 还有没有其它必须的前置步骤? - 是否考虑开源部分算子接口来提升社区解决方案的操作空间?