一份个人开发者的部署记录:Termux、llama.cpp、Qwen3,以及 DeepSeek Harness 的上下文开销。
我在做 AI 科技资讯聚合时,需要先判断采集到的内容是否与 AI 有关,再决定哪些新闻值得继续处理。新闻的抓取、去重和入库放在服务器上,模型只负责分类。这样一个任务不需要模型长篇回答,理想情况下,输入一条新闻,返回一段 JSON 就够了。
我手上正好有一台闲置的一加 9R:骁龙 870、8GB 内存。与其让它放在抽屉里,不如试试能否把它当成一个独立的模型 API 节点。
最后确实跑通了:Windows 可以通过局域网向手机发送请求,Qwen3 在手机上完成推理,再把结果返回电脑。随后我又把它接入 DeepSeek Harness,过程比预期曲折得多。
这篇主要记录实测结果、能复现的配置,以及遇到的问题。目前跑通的是本地推理和局域网 API,不是已经稳定运行的 24 小时服务。
01|先确认:这些旧设备到底能跑多大的模型
正式部署一加 9R 前,我用另外两台设备做了对照测试,推理工具是 PocketPal AI,模型主要采用 GGUF 的 Q4_K_M 量化版本。
| 设备 | 模型 | Prompt 处理 | Token 生成 |
|---|---|---|---|
| iPad mini 4(A8 / 2GB) | SmolLM2-360M Q4 | 26.34 t/s | 8.00 t/s |
| iPad mini 4 | Qwen2.5-0.5B Q4 | 23.66 t/s | 7.84 t/s |
| iPad mini 4 | Qwen2.5-1.5B Q4 | — | 约 0.4 t/s(单次) |
| iPhone 14 Pro | Qwen3-4B-Instruct-2507 Q4 | 89.78 t/s | 8.54 t/s |
| 一加 9R | Qwen3-1.7B Q4 | 约 61 t/s | 约 17.3 t/s |
这些数据来自不同设备、不同测试任务,不能当作严格横向跑分,但足够帮我选择部署方案。
iPad mini 4 的 0.5B 模型至少还能完成简单中文问答。换到 1.5B 后,一次基准测试只有约 0.4 t/s。它不是完全跑不动,而是速度已经不适合交互。具体是不是内存或缓存压力导致了额外下降,这次没有单独定位。
iPhone 14 Pro 成功运行了 4B Q4。它在一条复杂的虚构新闻测试中,能识别夸大的跑分条件,也没有照着正文里伪装成“系统备注”的指令直接返回 HIGH。但这只是一条样本,不能拿来证明模型的整体准确率。
真正准备放在一加 9R 上常驻的,我还是选择 Qwen3-1.7B Q4_K_M。理由很实际:比 4B 轻,初测生成速度达到约 17.3 t/s;对于输出几行 JSON 的分类任务,这比追求更大参数量更合适。
02|在 ColorOS 上部署 llama.cpp
一加 9R 使用官方 ColorOS,没有 Root,也没有刷第三方系统。我只需要它负责推理,不打算把采集器、数据库、网站一并塞进手机。
运行结构很简单:
Windows / 新闻采集服务
│ HTTP 请求
▼
一加 9R · Termux
│
llama-server
│
Qwen3-1.7B GGUF
│
JSON 响应
这里有两个工具容易混淆:Termux 提供 Android 上的命令行环境;llama.cpp 才是加载 GGUF 和执行推理的程序,其中 llama-server 负责提供 HTTP API。
部署时,第一个障碍竟然不是编译,而是安装软件包。Termux 一直报:
Error: None of the mirrors are accessible
E: Unable to locate package git
E: Unable to locate package clang
最初我反复尝试 pkg install,始终找不到包。后来确认是软件源和索引的问题,手动改用清华 Termux 镜像,执行 apt update 后才恢复正常。
printf '%s\n' 'deb https://mirrors.tuna.tsinghua.edu.cn/termux/apt/termux-main stable main' > "$PREFIX/etc/apt/sources.list"
apt update
apt upgrade -y
apt install -y git clang cmake ninja curl libandroid-spawn
编译 llama.cpp 则没有额外折腾手机 GPU 驱动,先走 CPU 路线:
cd ~
git clone --depth 1 https://github.com/ggml-org/llama.cpp.git
cd llama.cpp
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DGGML_OPENMP=OFF -DLLAMA_CURL=OFF
cmake --build build -j 2
最后那条命令里的 -j 2 只限制编译时的并行任务,避免手机编译时内存压力过大;它不是推理线程数。模型跑起来后,我没有再固定 CPU 推理线程,让 llama.cpp 使用默认配置。
把 Qwen3-1.7B-Q4_K_M.gguf 放入 ~/models/ 后,先通过 llama-cli 做短文本测试,记录到约 61 t/s 的 Prompt 处理速度和 17.3 t/s 的生成速度。这个速度是手机前台的短任务数据,不代表持续运行或锁屏性能。
03|把聊天模型变成局域网 API
接下来启动 llama-server。API 密钥在 Termux 会话中设置,电脑侧使用相同的密钥;不需要将端口暴露到公网。
# 先在 Termux 中设置 API_KEY 环境变量
~/llama.cpp/build/bin/llama-server \
-m ~/models/Qwen3-1.7B-Q4_K_M.gguf \
-c 4096 \
--host 0.0.0.0 \
--port 8080 \
--api-key "$API_KEY"
第一次从 Windows 调用失败,PowerShell 一直提示无法连接。排查后发现,我把示例地址 192.168.1.50 当成了手机 IP。改成手机实际的局域网地址,Test-NetConnection 返回 TcpTestSucceeded: True,再访问 /health,得到 status: ok。
真正要测试的还不是 /health,而是:
POST http://<手机IP>:8080/v1/chat/completions
我从 Windows 发出一条“机械键盘上市”的新闻,让手机判断它的 AI 新闻价值。API 正常返回了 JSON,但第一次给出了 HIGH,理由甚至把 RGB 灯效和普通硬件控制解释成 AI 技术。
这很能说明问题:接口能用,不等于模型判断靠谱。
后来我把规则改为先判断新闻是否有明确的 AI 相关内容,再判断价值等级,同一类新闻最终返回:
{
"level": "LOW",
"reason": "未提及AI相关技术或功能"
}
之前在 iPhone 上测试 4B 时,类似的机械键盘新闻也被正确判为 LOW。
API 调试期间还有个容易踩的坑:我曾将 max_tokens 设为 80。请求完成后 content 是空的,finish_reason 却是 length。检查完整响应才发现,Qwen3 把生成额度用在 reasoning_content 中,最终 JSON 还没输出就被截断了。
这之后我移除了该请求的人为低额度限制。对 Qwen3 这样的带思考能力的模型,只检查 message.content,可能会把“输出被截断”误诊成“模型没回答”。
到这里,Windows 通过局域网调用手机模型的完整链路已经可用。新闻评分是否能用于实际筛选,还需要按固定样本测误报和漏报,不能凭几次正确回答就投入自动化。
04|锁屏是比跑分更现实的问题
手机作为临时推理节点没有问题;要长期当服务器,ColorOS 的后台行为就绕不过去。
我给 Termux 开了后台运行权限,锁定最近任务,并执行 termux-wake-lock。锁屏五分钟后,电脑访问 /health 依然能得到 ok。当时我以为后台问题解决了。
随后发起实际的聊天补全请求,情况完全不同:锁屏时请求长时间不结束,有一次直接连接异常;另一次请求在我中途解锁手机后才拿到了结果,端到端耗时约 215 秒。
这 215 秒不是正常的模型生成用时,也不能直接拿来计算锁屏时的 tokens/s。我没有做完 CPU 频率、休眠状态及网络日志的对照采集,因此现在只能说锁屏与推理阻塞存在明显关联,具体是哪一层暂停了执行尚未定位。
从这里学到一个很实用的检查顺序:
端口可连接 ≠ /health 正常 ≠ 锁屏状态能完成推理
若要把手机作为长期节点,必须在不解锁的前提下连续发出真实请求,并记录完成率、耗时、温度以及失败后的恢复行为。目前我还没有完成这个验证。
05|接入 DeepSeek Harness,才发现真正贵的是上下文
llama-server 提供 OpenAI 兼容接口,所以我又在 Windows 版 DeepSeek Harness(DSH)里添加了自定义模型服务商。API 地址、协议和模型 ID 配好后,开始测试最简单的一句话:
你好
结果先收到:
CONTEXT_WINDOW_EXCEEDED
request (11526 tokens) exceeds the available context size (4096 tokens)
我实际只输入了两个汉字,但 Harness 不是普通聊天客户端。它会把系统规则、工具定义、技能等内容一起放进模型请求。安装 dsh-context 后,我看到了这次约 11.6K Token 的构成:
| 内容 | 约占用 | 比例 |
|---|---|---|
| 工具定义(29 项) | 6.4K | 55.2% |
| 技能注入 | 2.6K | 22.3% |
| 系统提示词 | 2.4K | 20.5% |
| 用户输入及其他 | 0.2K | 约 2% |
最大的开销不是我输入了多少字,而是模型在开始回答前就需要了解约 29 项工具。仅工具定义和技能注入,就占了约 9K Token。把模型的上下文窗口从 4096 提到更大,只解决“装不下”,不解决“处理这些内容很费时间”。
最后 Harness 确实给出了回复:
你好!有什么我可以帮助你的吗?
整轮用时 7 分 51 秒。 这是包含错误重试和等待的会话耗时,不是纯生成两个句子的用时。诊断页面显示,模型等待约 7 分 18 秒,占绝大多数;但“等待”具体包含多少 Prompt 处理、排队或重试,不能直接从这个统计中拆出来。
这也改变了我的优化方向。继续堆更大的模型没有意义,我准备先做一个只保留聊天、指定文件读取和少量 PowerShell 查询命令的精简 Agent。目标不是缩短一段预设文字,而是减少实际发送给模型的工具 Schema 和自动注入内容。
目前这还是下一步计划,我没有把它写成已经完成的功能。
06|这次实验到底得到了什么
一加 9R 已经做到三件事:在官方 ColorOS 上运行 GGUF 模型;通过局域网提供 OpenAI 兼容 API;被 Windows 和 DeepSeek Harness 调用。
尚未解决的也很明确:锁屏后真实推理不稳定;1.7B 的新闻分类会误判;Harness 的默认 Agent 请求太重,难以匹配这台手机的算力。
对我的资讯项目而言,比较合理的下一步是让手机先承担短文本相关性预筛,只返回少量结构化字段;不确定或可能重要的内容交给更强的模型复核。先做固定样本评估,重点看漏掉多少真正有价值的新闻,而不是只看几条分类成功的例子。
至于让旧手机承担完整编程 Agent,我暂时不会继续硬推。现在最值得优化的是任务规模、上下文开销和后台稳定性,而不是把能加载的最大模型当作目标。
相关项目: Termux · llama.cpp · PocketPal AI · DeepSeek Harness
说明:文中性能值均为当时截图与命令行的实测记录;不同设备测试条件并不完全一致。截图中的项目标题、新闻内容有部分为实验样例,不代表现实产品发布。
Conversation
评论