把会议纪要交给手机上的小语言模型,还是送到服务器处理?设想一款应用从纪要中提取三类行动项信息:负责人、具体事项和截止日期。没有写明日期时,不能编造日期。这比让助手研究会议议题窄得多。本地推理可以免于上传纪要,但最终选择取决于真实应用、受支持设备和网络策略,而不是模型卡上的参数量。
先界定任务,再选模型
先定输出格式和停止规则:缺少负责人或截止日期时标为“未注明”;未经确认不得发送日历邀请。用同一批留出的纪要比较规则提取器、本地小模型、服务器模型和混合路由。对这样受约束的任务,规则方案也可能胜出。Meta 的 Llama 3.2 发布说明介绍了面向摘要和改写等边缘任务的 1B、3B 文本模型;这证明模型可用,不证明它适合这项工作。平台可用性也要核对:Google 的 LLM Inference 指南明确标示 Android 和 iOS 实现已弃用,Web 实现未弃用,并建议移动端项目迁移至 LiteRT-LM;不能把这项状态扩大到 Web。确定运行时和模型版本,不要只按“端侧 AI”标签设计。
只有包括离线场景在内的所有硬性门槛都通过,才选本地。只有允许数据外发,且端到端测得的收益足以支持,才考虑服务器。混合方案并非免费的折中:路由判断、用户同意和离线失败行为都属于产品设计。若纪要涉及受监管或格外敏感的信息,先请法务和安全团队审查;本文不能替代合规判断。
让其他团队也能复测的流程
- 冻结测试集。从目标工作流程收集经同意、去标识化的纪要,覆盖普通、冗长、多语言、OCR 错乱、含糊、前后矛盾和对抗性输入。单独留出测试集、记录版本,预先规定各类样本的质量标准,包括何时正确拒答。由两名审阅者对照原纪要裁定分歧,不能被模型流畅的措辞带偏。
- 保持比较条件一致。记录应用版本、操作系统、设备档位(包括受支持的最低配置)、运行时与后端、模型和量化文件哈希、提示词与输出格式、分词器、输入输出长度、服务器区域、网络类型和并发量。在至少两种电量和温度状态下重复测试,随机化候选方案的测试顺序;报告分布和置信区间,不挑最快的一次。一项端侧推理研究比较了多种模型、量化方式和设备配置:它说明配置会影响结果,但其数字不能当作你手机上的基准。
- 量完整体验。分别在新启动进程和预热会话中记录首次有用输出及任务完成耗时(p50/p95)、各类样本质量、拒答和错误率、与其他应用共存时的峰值内存占用、存储及下载大小、每个完成任务增加的电池能耗。计入预处理、模型加载、排队、上传、路由和后处理,并与现有流程比较。Apple 的 电池分析指南介绍 Xcode、MetricKit 与 Instruments,并提醒温度造成的限制;应使用平台测量工具和受控基线,不能拿每秒 token 数充当能耗。
- 主动破坏路由。测试飞行模式、强制登录的公共 Wi-Fi、慢速或断续网络、服务器超时、模型下载不可用、存储不足、内存压力、撤回同意、旧版系统以及模型更新。记录每种情况下结果是正确、延迟、拒绝还是悄悄改走另一条路。检查网络遥测和崩溃报告载荷,确认哪些原始字段实际离开设备。
保留每个方案的逐条结果与故障类别。如果没有一条路线全部达标,就不要靠平均分硬选赢家:缩小任务、加入人工复核或维持现有流程。量化、提示词或运行时更改后重跑同一组测试。冷启动可能颠倒预热演示的排名;离线要求也可能淘汰其他方面更好的远程方案。
一个刻意采用合成数据的决策门禁
下面的 Python 3 标准库程序不需要模型或网络。表格中的每个数值和门槛都是为检验决策规则而虚构的示意值,不是设备跑分或推荐阈值。将代码保存为 decision_harness.py,依次运行 python decision_harness.py 和 python decision_harness.py --allow-egress --no-offline。实际决策时须用自己应用的测量结果替换示例数据,并在查看结果前商定门槛。“每月费用”只是虚构的可比运营成本估值,并非完整的总拥有成本;设备能耗不包含服务器耗电。
#!/usr/bin/env python
"""Illustrative decision gate, NOT a model or device benchmark. Python 3 stdlib.
Usage: python decision_harness.py [--allow-egress] [--no-offline]
Replace ROWS with measured values from your own application and devices.
"""
import argparse
# Each row represents one workload stratum, with cold/warm application completion
# latency (seconds), measured peak working set (MiB), incremental device energy
# (joules/request), independently adjudicated task success fraction, and flags.
# All numbers below are fabricated to exercise the policy; do not quote them as
# hardware performance or infer server-side energy from device energy.
ROWS = [
dict(route="local", stratum="routine", quality=.97, cold=2.8, warm=.8,
memory=740, energy=3.2, raw_exits=False, offline=True, monthly=95),
dict(route="local", stratum="hard", quality=.77, cold=4.6, warm=1.8,
memory=790, energy=5.1, raw_exits=False, offline=True, monthly=95),
dict(route="hybrid", stratum="routine", quality=.97, cold=3.0, warm=.9,
memory=760, energy=3.4, raw_exits=False, offline=True, monthly=110),
dict(route="hybrid", stratum="hard", quality=.94, cold=5.1, warm=2.4,
memory=760, energy=4.6, raw_exits=True, offline=False, monthly=110),
dict(route="server", stratum="routine", quality=.98, cold=2.1, warm=1.2,
memory=130, energy=1.0, raw_exits=True, offline=False, monthly=140),
dict(route="server", stratum="hard", quality=.96, cold=3.8, warm=2.7,
memory=130, energy=1.5, raw_exits=True, offline=False, monthly=140),
]
# Example policy only: substitute thresholds, strata and costs before a real decision.
QUALITY_FLOOR = {"routine": .90, "hard": .90}
MAX_COLD_S, MAX_WARM_S = 6.0, 3.0
MAX_MEMORY_MIB, MAX_DEVICE_ENERGY_J = 900, 6.0
def assess(rows, allow_egress=False, require_offline=True):
by_route = {}
for row in rows:
by_route.setdefault(row["route"], []).append(row)
results = {}
for route, entries in sorted(by_route.items()):
issues = []
strata = [r["stratum"] for r in entries]
if sorted(strata) != sorted(QUALITY_FLOOR):
issues.append("missing/duplicate strata")
if len({r["monthly"] for r in entries}) != 1:
issues.append("inconsistent monthly cost")
for r in entries:
label = r["stratum"]
if label not in QUALITY_FLOOR or r["quality"] < QUALITY_FLOOR.get(label, 1):
issues.append(label + ": quality")
if r["cold"] > MAX_COLD_S or r["warm"] > MAX_WARM_S:
issues.append(label + ": latency")
if r["memory"] > MAX_MEMORY_MIB:
issues.append(label + ": memory")
if r["energy"] > MAX_DEVICE_ENERGY_J:
issues.append(label + ": device energy")
if r["raw_exits"] and not allow_egress:
issues.append(label + ": raw data egress")
if not r["offline"] and require_offline:
issues.append(label + ": offline failure")
results[route] = (entries[0]["monthly"], issues)
eligible = [(cost, route) for route, (cost, issues) in results.items() if not issues]
return results, min(eligible)[1] if eligible else None
def main():
p = argparse.ArgumentParser(description=__doc__)
p.add_argument("--allow-egress", action="store_true")
p.add_argument("--no-offline", action="store_true")
args = p.parse_args()
results, winner = assess(ROWS, args.allow_egress, not args.no_offline)
for route, (cost, issues) in sorted(results.items()):
print(f"{route}: ${cost}/month; " + ("PASS" if not issues else "FAIL: " + ", ".join(issues)))
print("Decision:", winner or "no eligible route; redesign, relax policy explicitly, or stop")
if __name__ == "__main__":
main()
默认示例中,本地方案未通过困难样本的质量门槛;混合方案未通过离线和原始数据外发门槛;服务器方案也未通过后两项。因此结论是没有合格路线。如果明确允许外发且不要求离线,混合方案通过,并且示意月费用低于服务器方案。这是条件性的结果,不能据此擅自取消任何要求。此简化门禁每类样本只有一个汇总质量比例,每种温度状态只有一个观测值;实际决策还需不确定性区间、p95 尾部表现、隐私审计证据、明确的样本占比,以及成本和阈值的敏感性分析。
算清手机与团队各自承担的成本
模型文件大小不等于应用峰值内存:分词器、KV 缓存、运行时缓冲区、输入长度以及其他应用都会占用资源。下载、存储和首次加载应与稳定运行分开预算。量化可能同时改变体积和答案质量。服务器的单次请求成本应计入输入输出量、重试、区域、数据保留和支持;混合方案增加路由器开发、验证与监控,本地方案则增加跨设备 QA、分发、更新和用户电池开销。按预期请求结构及高使用量场景比较,不要把手机耗电当作整个系统的能耗。
本地路线可能编造一个看似可信的截止日期;远程路线可能泄露私密纪要;混合路线若把困难纪要误判为简单任务,或超时后悄悄切换,也可能同时发生两类故障。为各路线定义停止状态。界面应清晰区分“在设备上处理”和“发送以增强处理”;如果产品承诺本地处理,后者必须先获得明确同意。离线意味着不尝试远程请求,而不是让回退流程一直转圈。Meydo Journal 关于手机硬件约束的文章讨论更广的端侧问题;这里聚焦一个边界明确的工作流程。
安全边界随数据流转
本地推理减少了一条传输路径,却不能让共用、丢失或被入侵的设备自动变安全。盘点本地纪要缓存、模型包、日志、遥测、备份和崩溃报告;尽量少留敏感信息,并规定保留期限与删除方式。混合路由必须在上传文本之前作判断;日志要能表明使用了哪条路线,又不必无谓保存纪要。平台的隐私承诺只能按适用范围引用:Google 的 AICore 文档描述其自身处理中的请求隔离和不保留输入输出,并不保证别的应用的分析统计或服务器回退同样如此。
固定模型与运行时文件版本并校验完整性,通过可信更新渠道分发、分阶段上线、保留经测试的回滚方案;每次改动后重跑质量与隐私检查。即使不调用云端,被篡改的模型包或带提示注入的纪要仍可能突破边界。提取出的行动项只能作为未受信任的建议;发送日历邀请或执行其他对外动作前须经人工确认。最终上线取决于实际运营条件:最低配置设备上的测量体验及离线拒绝行为均通过约定门槛,才上线本地方案;否则仅在允许并获得明确同意时选择混合或服务器方案,不然就放弃自动化这项任务。
