← 返回文章列表

回归 MIUI 的 K30 Pro,我对 Adreno 650 死心了

一台没刷机的 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
SoCSnapdragon 865 (Kryo 585, kona)
GPUAdreno 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
SoCSnapdragon 865Snapdragon 865Dimensity 9300
GPUAdreno 650Adreno 650Mali-G720 MC12
系统LineageOS 23MIUI (Android 12)原厂 Funtouch OS
内存8 GB8 GB16 GB
加速方式CPU dotprod + OpenMPCPU dotprodVulkan GPU 🏆
GPU 状态Turnip 缺 StorageBuffer8BitQualcomm 驱动仅 Vulkan 1.1 ❌官方驱动 Vulkan 1.3 ✅
pp12826.28 t/s34.43 t/s 🏆43.89 t/s 🏆
tg3213.23 t/s 🏆11.99 t/s17.64 t/s 🏆
最优线程t=4t=3t=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最高 Vulkanllama.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 优化的潜力。

——这个结论从第一篇到第三篇,一直没变过。


六、所以这些折腾说明了什么?

三篇文章,三台手机,前后折腾了将近一周:

  1. K30 Pro + LineageOS → GPU 功能残缺,CPU dotprod 优化 → 13 t/s
  2. vivo X100 Pro + 原厂系统 → Mali GPU 开箱即用 → 17 t/s
  3. 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 · 三台手机 / 三篇笔记 / 一个结论

系列文章:

  1. 手机跑大模型GPU加速折腾记.md
  2. 手机跑大模型GPU加速折腾记·续——主力机vivoX100Pro无root上Vulkan.md
  3. 手机跑大模型GPU加速折腾记·再续——回归MIUI的K30Pro,Adreno终究是错付了.md ← 本文