一台没刷机的 K30 Pro,让我彻底对「原版MIUI K30 Pro GPU 推理」死心。
〇、前情提要 & 勘误
先道个歉: 第一篇里我把 POCO F2 Pro / K30 Pro 的 SoC 写成了「Snapdragon 855」,实际上是 Snapdragon 865(Kryo 585)。这里正式更正,后面所有数据都以本篇文章为准。
前两篇的剧情回顾:
第一篇: 刷了 LineageOS 的 K30 Pro,Adreno 650 的 Turnip 开源驱动不支持 8-bit storage buffer 直读,GPU 加速走不通。最后靠 CPU dotprod 优化跑到 13.23 t/s。
第二篇: 换了台没 root 的 vivo X100 Pro(Dimensity 9300 + Mali-G720),装上 vulkan-loader-android 后 Vulkan 开箱即用。同款 Qwen3.5-2B 模型跑到 17.64 t/s,全面超越 K30 Pro。
两台手机,两个结局。但总觉得对比不公平——一个刷了 LineageOS,一个是天玑旗舰。那 同款 K30 Pro,如果没刷机、用原厂 MIUI,Adreno 650 能不能支棱起来?
于是搞了第三台手机。
一、新(旧)装备
| 项目 | 值 |
|---|---|
| 手机 | Redmi K30 Pro |
| SoC | Snapdragon 865 (Kryo 585, kona) |
| GPU | Adreno 650 |
| 内存 | 8 GB |
| Root | 没有 |
| 系统 | 原厂 MIUI(Android 12) |
和第一篇那台的区别就一个:没刷过机。 这意味着 Adreno 650 用的是 Qualcomm 原厂闭源驱动,不是 LineageOS 上那个功能残缺的 Turnip。
原厂驱动 + 完整 Vulkan——这总该能跑了吧?
二、第一个意外:Vulkan 版本不对
装好 Termux,编译完带 -DGGML_VULKAN=ON 的 llama.cpp,一跑——
ggml_vulkan: Error: Vulkan 1.2 required.
什么情况?查一下:
$ vulkaninfo
apiVersion = 1.1.128
deviceName = Adreno (TM) 650
Vulkan 1.1.128。 新版 llama.cpp 的 Vulkan 后端要求 Vulkan 1.2(因为用了一些 1.2 的特性如 timeline semaphore 等)。而 Adreno 650 在 MIUI 上的官方驱动只支持 1.1。
等等——这个 Vulkan 加载器对吗?
$ dpkg -l | grep vulkan-loader
ii vulkan-loader-generic 1.4.356
又是 vulkan-loader-generic!和第二篇一样的问题。切到 vulkan-loader-android 试试:
apt-get remove vulkan-loader-generic -y
apt-get install vulkan-loader-android -y
再查:
$ vulkaninfo
apiVersion = 1.1.128
deviceName = Adreno (TM) 650
加载器对了,但 版本还是 1.1.128。这就不是加载器的问题了——是 Qualcomm 给 Adreno 650 的官方驱动本身就只实现到 Vulkan 1.1。
查了一下,Adreno 650 的硬件本身支持 Vulkan 1.2 的大部分功能,但 Qualcomm 在 MIUI 上提供的闭源驱动止步于 1.1。而 LineageOS 的 Turnip 开源驱动虽然版本新(1.4+),却又缺了 StorageBuffer8BitAccess——两边各缺一角,怎么都拼不完整。
所以,Adreno 650 用新版 llama.cpp 做 GPU 推理,无论刷没刷机,都走不通。
三、老老实实 CPU 调优
既然 GPU 没戏,那就把 CPU 压榨到极致。
3.1 编译优化:dotprod 指令集
Snapdragon 865(Kryo 585)支持 ARMv8.2-A + Dot Product 指令集。和第一篇一样,用最激进的编译参数:
cmake -B build -DGGML_VULKAN=OFF \
-DCMAKE_C_FLAGS="-march=armv8.2-a+dotprod+fp16+rcpc -O3" \
-DCMAKE_CXX_FLAGS="-march=armv8.2-a+dotprod+fp16+rcpc -O3"
cmake --build build -j4
不过实测发现,新版 cmake 已经自动检测了 -mcpu=native+dotprod,手动加 march 标志的提升不到 3%。
3.2 线程数扫描
Kryo 585 的核心布局是 1 + 3 + 4——1 个 2.84GHz 超大核、3 个 2.42GHz 大核、4 个 1.8GHz 小核。上次的经验是「最佳线程数 = 大核数」,这次验证一下:
线程数扫描结果(Qwen3.5-2B, pp128 + tg32):
─────────────────────────────────────
t=1 ████░░░░░░░░░░░░░░░░░ 1.91 t/s
t=2 ██████████████████░░░ 9.03 t/s
t=3 █████████████████████ 11.99 t/s ← 🏆 文本生成最优
t=4 ████████████████████░ 10.81 t/s
t=6 █████████████████░░░░ 9.58 t/s
─────────────────────────────────────
结论和上次一致:
- t=3 是甜点值——只用 3 个 2.42GHz 同频大核,调度无干扰
- t=4 时第 4 个线程可能被分配到 2.84GHz prime 核或挤到小核,反而产生调度开销
- Prompt 处理(pp)t=6 最快(37 t/s),但文本生成掉到 9.58——多线程对并行计算有利,但串行生成时是累赘
四、三台设备终极大横评
控制变量: 同一模型(Qwen3.5-2B-Q4_K_M),同一 benchmark 工具(llama-bench),同一测试参数(pp128 + tg32)。
| 项目 | K30 Pro A(LineageOS) | K30 Pro B(MIUI 原厂) | vivo X100 Pro |
|---|---|---|---|
| SoC | Snapdragon 865 | Snapdragon 865 | Dimensity 9300 |
| GPU | Adreno 650 | Adreno 650 | Mali-G720 MC12 |
| 系统 | LineageOS 23 | MIUI (Android 12) | 原厂 Funtouch OS |
| 内存 | 8 GB | 8 GB | 16 GB |
| 加速方式 | CPU dotprod + OpenMP | CPU dotprod | Vulkan GPU 🏆 |
| GPU 状态 | Turnip 缺 StorageBuffer8Bit ❌ | Qualcomm 驱动仅 Vulkan 1.1 ❌ | 官方驱动 Vulkan 1.3 ✅ |
| pp128 | 26.28 t/s | 34.43 t/s 🏆 | 43.89 t/s 🏆 |
| tg32 | 13.23 t/s 🏆 | 11.99 t/s | 17.64 t/s 🏆 |
| 最优线程 | t=4 | t=3 | t=4 |
| 编译时间 | ~10 分钟 | ~50 分钟(含 GPU 后端) | ~50 分钟 |
几个有意思的发现
1. 线程数策略要区分场景
Prompt 处理是并行计算(一次性算完所有 token),t=6 最快;文本生成是串行(逐个 token),t=3 最优。如果日常使用场景偏重对话(短 prompt + 长生成),用 t=3;如果偏重文档分析(长 prompt + 短生成),用 t=6。
2. 三台设备的差异不止是系统
同款 SoC、同一模型,两台 K30 Pro 的数据也不同。这很正常——编译参数、llama.cpp 版本、CMake 的自动检测、后台进程、散热状态……任何变量都会影响最终数字。所以 benchmark 数字的价值不在「精确对比」,而在于判断量级和趋势:10 t/s 和 13 t/s 都是可用的,17 t/s 确实更快。
3. 同款 SoC 的 GPU 加速,不同系统都是死路
这是我折腾完三台手机后最大的感叹:
Adreno 650 GPU 推理可行性:
┌─ LineageOS ──────────────────────────┐
│ 驱动:Turnip(开源逆向) │
│ 版本:Vulkan 1.4+ │
│ 问题:缺 StorageBuffer8BitAccess │
│ → 带宽翻倍,GPU 比 CPU 慢 ❌ │
└──────────────────────────────────────┘
┌─ MIUI(原厂)─────────────────────────┐
│ 驱动:Qualcomm 官方闭源 │
│ 版本:Vulkan 1.1.128 │
│ 问题:llama.cpp 要求 Vulkan 1.2 │
│ → 初始化失败,无法使用 ❌ │
└──────────────────────────────────────┘
一边是驱动功能不全,一边是驱动版本太旧。这台 2020 年的旗舰 SoC,在 2026 年的 LLM 推理赛道上,无论你用什么系统,GPU 这条路就是走不通。
五、所以结论是什么?
1. 不是所有 Mali 都比 Adreno 好,但这局 Mali 赢了
Mali-G720(天玑 9300)在 GPU 推理上全面碾压 Adreno 650,根本原因是 MediaTek 跟进了 Vulkan 1.3,而 Qualcomm 对 Adreno 650 这个老旗舰的驱动支持停在了 1.1。
不止是硬件不行,更是驱动断了。
2. 手机 GPU 推理的「入场券」是 Vulkan 1.2+
如果你也想在手机上跑 llama.cpp 的 Vulkan 后端,先确认你的 GPU 支持 Vulkan 1.2 以上:
| GPU | 最高 Vulkan | llama.cpp 可用? |
|---|---|---|
| Adreno 650 (MIUI) | 1.1 | ❌ |
| Adreno 650 (Turnip) | ~1.4(但不完整) | ⚠️ 功能残缺 |
| Mali-G720 (原厂) | 1.3 | ✅ |
| Adreno 7xx (原厂) | 1.2+ | ✅ 理论可行(待验证) |
3. CPU dotprod 优化是最后的防线
Adreno 650 的 GPU 走不通,但它的 CPU 确实被低估了。Kryo 585 的 dotprod 指令集让 2B 模型跑到 11-13 t/s——作为一台三四年前的旧手机,这个成绩其实相当不错。
虽然比不上 GPU 的 17 t/s,但别忘了:这只是一台闲置的旧手机。 插电挂在那当个本地 AI 助手,不占地方、不费电、不需要云服务——对于探索本地大模型部署的人来说,它是完全可用的。
不要高估手机 GPU 的能力,但也不要低估 CPU 优化的潜力。
——这个结论从第一篇到第三篇,一直没变过。
六、所以这些折腾说明了什么?
三篇文章,三台手机,前后折腾了将近一周:
- K30 Pro + LineageOS → GPU 功能残缺,CPU dotprod 优化 → 13 t/s
- vivo X100 Pro + 原厂系统 → Mali GPU 开箱即用 → 17 t/s
- K30 Pro + MIUI 原厂 → Adreno 驱动版本太旧 → 12 t/s
一路折腾下来,最大的收获不是「谁快谁慢」,而是搞清楚了手机本地 LLM 的可行边界:
关于旧手机:
- 三四年前的旗舰(骁龙 865/855)跑 2B 级别模型完全可行,10-13 t/s 够日常对话
- 不用追求 GPU 加速,CPU dotprod 优化就能达到可用水平
- 闲置手机 + Termux + llama.cpp = 零成本的本地 AI 服务器
关于 GPU 加速:
- 天玑 9300/9400 这类新平台的 Mali GPU Vulkan 支持完整,开箱即用
- 老平台 Adreno 遇到的两重障碍(Turnip 功能缺失 vs 原厂驱动版本太旧)短期内无解
- 新版 llama.cpp 要求 Vulkan 1.2+,这是目前手机 GPU 推理的实际门槛
还不死心? 在网络上看到有人把K30 pro刷了魔改之后的Hyper OS,不知道那个版本的驱动能不能成功,后期有空刷机可以试试。
2026-07-07 · 三台手机 / 三篇笔记 / 一个结论
系列文章:
手机跑大模型GPU加速折腾记.md手机跑大模型GPU加速折腾记·续——主力机vivoX100Pro无root上Vulkan.md手机跑大模型GPU加速折腾记·再续——回归MIUI的K30Pro,Adreno终究是错付了.md← 本文