MNN icon indicating copy to clipboard operation
MNN copied to clipboard

[Bug] llm_bench 在 ARM CPU 上测试 gemma-3-1b-it 模型时出现异常高的解码速度(1500 toks/s)

Open jialilve opened this issue 2 months ago • 2 comments

我最近在使用 llm_bench 工具对端侧大模型进行性能测试。在测试 gemma-3-1b-it-qat-q4_0-gguf-MNN 模型时,我发现了一些异常高且可能不正确的解码速度。特别地,目前只有在这个模型上才会出现这个情况

问题描述

llm_bench 工具在特定条件下(例如 prompt=128, decode=128)报告 Gemma 模型的解码速度超过了 1500 tokens/秒。这个数值远高于预期,也比 llama.cpp 等类似框架(在相同模型上,llama.cpp 的速度约为 52 tok/s)快得不合常理。同时,这个速度会随着输入长度、参数(-c[precison 1:High,2:Low])的变化而发生剧烈的、不符合逻辑的波动。 与此对比,使用本项目(MNN)的llm_demo 工具交互式聊天也并没有体现出1500 tokens/秒 左右的decode,目测应该是50 tok/s左右(大概)?

不合理点一:Decode 速度异常高且剧烈波动

  • 现象:

    • 在高精度、8线程、输入128的条件下,Decode 速度达到了 1684.20 tok/s
    • 在高精度、8线程测试中,输入从128变为256,Decode速度就从 1684.20 暴跌到 307.38
    • 在输入512时速度又回升到 748.56,在1024时又跌回 317.14

不合理点二:低精度(Low)模式下decode速度骤降

  • 现象:

    • 在8线程、输入512的条件下,高精度 Decode 速度为 748.56 tok/s,而低精度骤降至 32.10 tok/s
    • 在4线程、输入512的条件下,也出现了同样的情况,低精度速度为 35.14 tok/s

如何复现

  1. 环境
  • MNN 版本: main branch
  • 操作系统: Android 15
  • 设备型号: One Plus13-9Elite
  1. 模型: gemma-3-1b-it-qat-q4_0-gguf-MNN
  2. 复现指令: 运行 llm_bench,使用如下参数:
    LD_LIBRARY_PATH=. ./llm_bench -m /path/to/gemma-3-1b-it-qat-q4_0-gguf-MNN/config.json -a cpu -c 1 -p 128,256,512,1024 -n 128 -t 8 -kv true
    

截图

Image
# High Precision, 8 Threads
| model                         | modelSize  | backend | threads | precision | llm_demo                 | speed(tok/s)          |
| ----------------------------- | ---------- | ------- | ------- | --------- | ------------------------ | --------------------- |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 8       | High      | prompt=128<br>decode=128 | 295.09 ± 7.41<br>1684.20 ± 33.36 |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 8       | High      | prompt=256<br>decode=128 | 258.10 ± 10.33<br>307.38 ± 3.74 |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 8       | High      | prompt=512<br>decode=128 | 233.18 ± 3.77<br>748.56 ± 42.66 |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 8       | High      | prompt=1024<br>decode=128| 206.89 ± 6.09<br>317.14 ± 3.65 |

# Low Precision, 8 Threads
| model                         | modelSize  | backend | threads | precision | llm_demo                 | speed(tok/s)          |
| ----------------------------- | ---------- | ------- | ------- | --------- | ------------------------ | --------------------- |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 8       | Low       | prompt=128<br>decode=128 | 291.25 ± 12.48<br>1549.26 ± 62.67 |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 8       | Low       | prompt=256<br>decode=128 | 301.29 ± 14.12<br>1086.25 ± 19.91|
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 8       | Low       | prompt=512<br>decode=128 | 282.61 ± 17.78<br>32.10 ± 0.41   |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 8       | Low       | prompt=1024<br>decode=128| 223.93 ± 1.03<br>30.26 ± 0.18   |

# Low Precision, 4 Threads
| model                         | modelSize  | backend | threads | precision | llm_demo                 | speed(tok/s)          |
| ----------------------------- | ---------- | ------- | ------- | --------- | ------------------------ | --------------------- |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 4       | Low       | prompt=128<br>decode=128 | 141.08 ± 0.47<br>1459.18 ± 20.27 |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 4       | Low       | prompt=256<br>decode=128 | 164.22 ± 12.45<br>1084.68 ± 7.46 |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 4       | Low       | prompt=512<br>decode=128 | 150.31 ± 1.24<br>35.14 ± 0.26   |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU     | 4       | Low       | prompt=1024<br>decode=128| 147.38 ± 0.34<br>32.54 ± 0.09   |

# High Precision, 8 Threads(第二次测)
| model                          |  modelSize | backend    | threads | precision  | llm_demo   | speed(tok/s) |
| ------------------------------ | ---------: | ---------- | ----: | ---------- | ---------- | ------------ |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU        |     8 | High       | prompt=128<br>decode=128 | 192.81 ± 15.27<br>1441.38 ± 101.12 |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU        |     8 | High       | prompt=256<br>decode=128 | 197.49 ± 3.67<br>284.73 ± 5.64 |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU        |     8 | High       | prompt=512<br>decode=128 | 188.80 ± 2.44<br>706.67 ± 17.71 |
| gemma-3-1b-it-qat-q4_0-gguf-MNN | 994.65 MiB | CPU        |     8 | High       | prompt=1024<br>decode=128 | 174.25 ± 1.52<br>298.71 ± 6.05 |

希望团队能帮忙调查一下这个问题。非常感谢!

jialilve avatar Oct 16 '25 07:10 jialilve

原因

原因是 gemma3 输出终止 token(stop_token) 非常快,实际只输出了 3~4 个 token 就结束了,而 llm_bench 中却根据输出 128 个 token 计算 decoding tps 指标,二者出现了偏差。

fix

修复的代码如下,计算 TPS 的 nGenerate 从 llm 中获取:

diff --git a/transformers/llm/engine/demo/llm_bench.cpp b/transformers/llm/engine/demo/llm_bench.cpp
index 029077f5..f32c8e36 100644
--- a/transformers/llm/engine/demo/llm_bench.cpp
+++ b/transformers/llm/engine/demo/llm_bench.cpp
@@ -892,6 +892,7 @@ int main(int argc, char ** argv) {
         if (instance.mCmdParam.kvCache == "true") {
             std::vector<int> tokens(prompt_tokens, 16);
             
+            t.nGenerate = 0;
             for (int i = 0; i < instance.mCmdParam.nRepeat + 1; ++i) {
                 llm->response(tokens, nullptr, nullptr, decodeTokens);
                 auto prefillTime = context->prefill_us;
@@ -899,6 +900,7 @@ int main(int argc, char ** argv) {
                 if (i > 0) { // Exclude the first performance value.
                     t.prefillUs.push_back(prefillTime);
                     t.decodeUs.push_back(decodeTime);
+                    t.nGenerate += llm->getCurrentHistory() - tokens.size();
                 }
             }
             if (printHeader) {

修改后打印的结果如下:

model modelSize backend threads precision llm_demo speed(tok/s)
gemma-3-1b-it-qat-q4_0-gguf-MNN 994.65 MiB CPU 4 Low prompt=128
decode=20
45.16 ± 0.19
50.01 ± 0.78
gemma-3-1b-it-qat-q4_0-gguf-MNN 994.65 MiB CPU 4 Low prompt=256
decode=20
44.89 ± 0.52
48.47 ± 0.21
gemma-3-1b-it-qat-q4_0-gguf-MNN 994.65 MiB CPU 4 Low prompt=512
decode=512
44.30 ± 0.17
48.58 ± 0.16
gemma-3-1b-it-qat-q4_0-gguf-MNN 994.65 MiB CPU 4 Low prompt=1024
decode=20
43.50 ± 0.11
46.38 ± 0.33

hebangwen avatar Oct 16 '25 11:10 hebangwen

上一份评论中的代码有误,修复后的代码见 PR #3954

hebangwen avatar Oct 17 '25 06:10 hebangwen

Marking as stale. No activity in 60 days.

github-actions[bot] avatar Dec 16 '25 09:12 github-actions[bot]