当前位置: 首页 > news >正文

小模型回到本地:NPU、端侧推理和开发者的新耐心

我对端侧小模型的兴趣,不是来自“把大模型塞进手机”这类口号,而是来自一个很具体的需求:做一个离线会议助手。它要在笔记本和手机上工作,能在没有网络的会议室里生成本地摘要,能先把敏感信息在设备上处理掉,必要时再把脱敏后的材料交给云端兜底。

这个需求听起来不大,却能把端侧 AI 的难点都翻出来:模型下载、冷启动、NPU 和 CPU fallback、音频转写后的本地摘要、隐私缓存、云端兜底开关、设备碎片化、发布灰度、回滚和验收。端侧小模型不是云端大模型的迷你版,它更像一个必须长期住在用户设备里的功能模块。

下面我用这个离线会议助手做主线,记录一套可以复制的工程方案。它不是某个真实产品的内部实现,所有名称、URL、token 和客户信息都用公开示例替代。

先把产品边界写窄

离线会议助手第一版只承诺四件事。

它能在本地处理一段会议音频转写文本,生成 5 到 8 条要点。它能识别并遮蔽明显的手机号、邮箱、身份证样式字段、合同号样式字段。它能在用户同意后,把脱敏摘要和片段索引发给云端,让云端生成更完整的纪要。它能在没有网络时保存草稿,等用户确认后再同步。

它不承诺自动识别所有发言人,不承诺做法律级事实核验,不承诺离线回答最新政策,也不承诺把两小时会议完整压进一个小模型上下文。边界写窄不是保守,而是端侧产品必须对资源和信任负责。

第一版的本地链路是这样的:

音频文件或实时转写文本 -> 本地分段器 -> 隐私预处理器 -> 小模型摘要器 -> 本地草稿和片段索引 -> 用户确认 -> 可选云端兜底

这里的小模型不是唯一主角。分段、脱敏、缓存、权限和兜底一样重要。端侧 AI 做得好,常常不是因为模型特别聪明,而是每一步都知道自己该做多少。

一个请求长什么样

本地接口没有必要模仿云端 OpenAI API,但保留结构化请求会让调试和回放方便很多。会议助手内部给本地推理服务发这样的请求:

{ "request_id": "local_meeting_20260615_001", "mode": "offline_summary", "device_context": { "platform": "macos", "power": "battery", "network": "offline", "accelerator": "ane", "memory_pressure": "normal" }, "privacy_policy": { "redact_before_cache": true, "allow_cloud_fallback": false, "retention_hours": 24 }, "input": { "meeting_title": "产品周会", "language": "zh-CN", "segments": [ { "start_ms": 12000, "end_ms": 42600, "speaker": "S1", "text": "我们本周先把离线摘要做成 beta,不要默认上传音频。" }, { "start_ms": 43100, "end_ms": 86500, "speaker": "S2", "text": "如果用户打开云端增强,只上传脱敏后的摘要和片段索引。" } ] }, "output": { "max_bullets": 8, "include_actions": true, "include_risks": true } }

返回也要能解释本地做了什么:

{ "request_id": "local_meeting_20260615_001", "status": "ok", "summary": [ "离线摘要 beta 阶段不默认上传音频。", "云端增强需要用户主动开启,并且只接收脱敏后的摘要和片段索引。" ], "actions": [ { "owner": "未识别", "text": "补充云端增强的授权弹窗文案。", "evidence_segment_ids": [2] } ], "redactions": [ { "type": "email", "count": 1, "replacement": "[EMAIL_1]" } ], "runtime": { "model": "meeting-summarizer-1.8b-q4", "backend": "ane", "input_tokens": 1462, "output_tokens": 214, "prefill_ms": 382, "decode_ms": 1040, "peak_memory_mb": 1180, "cloud_fallback_used": false } }

这类结构化返回有两个好处。产品可以把“云端未使用”“已脱敏”“本地草稿保存 24 小时”清楚地展示给用户;工程也可以在不记录原文的情况下知道模型是否跑在加速器上、耗时多少、是否触发 fallback。

设备能力探测比模型榜单更早

端侧项目最容易犯的错,是先挑一个看起来分数不错的模型,再想办法让它跑起来。会议助手反过来做。先定义设备矩阵,再选模型。

第一版只覆盖三类设备:

设备档位目标允许策略
高端笔记本10 分钟会议 15 秒内出草稿本地摘要、脱敏、可选云端增强
普通手机10 分钟会议 30 秒内出草稿本地短摘要、低电量降级
低端或旧设备只做隐私预处理和片段索引不强行本地生成长摘要

设备探测在功能入口就发生,而不是推理失败后才补救:

{ "device_id_hash": "dev_anon_7f2a", "platform": "android", "os_version": "15", "app_version": "1.4.0", "accelerators": ["nnapi", "cpu"], "recommended_backend": "nnapi", "available_memory_mb": 3260, "battery_level": 0.42, "thermal_state": "nominal", "model_profile": "meeting-lite" }

如果设备只能稳定跑meeting-lite,界面就不要给用户承诺“完整纪要”。可以给“本地要点”和“云端增强”两个清晰选择。端侧 AI 的体验很大一部分来自诚实,不是来自把所有能力都塞进一个按钮。

模型包不只是一个文件

会议助手用了两个本地模型包。一个很小,负责隐私预处理和意图分类;一个稍大,负责会议摘要草稿。它们和 tokenizer、prompt 模板、后处理规则绑定发布。

模型清单像这样:

models: - id: privacy-filter-280m-q8 role: privacy_preprocess size_mb: 210 min_app_version: "1.4.0" backends: ["ane", "nnapi", "cpu"] checksum: "sha256:example-privacy-filter" retention: bundled - id: meeting-summarizer-1.8b-q4 role: offline_summary size_mb: 1260 min_app_version: "1.4.0" backends: ["ane", "nnapi", "directml", "cpu"] checksum: "sha256:example-meeting-summarizer" download: wifi_only: true resume: true keep_previous_version: true prompts: summary_template_version: "summary-v6" action_template_version: "action-v3" postprocess: schema_version: "meeting-note-v2"

这里最容易被低估的是版本绑定。新模型可能要求新的 tokenizer,也可能改变输出格式。只替换权重文件,不更新 prompt 和后处理,很容易让客户端解析失败。端侧发布比服务端更麻烦,因为坏版本已经到了用户设备上,不是重启一个 Pod 就能消失。

所以模型包必须有签名、校验、最小 App 版本、可回滚的上一版本。下载也要可恢复,不能让用户在会议前卡在一个 1GB 文件上。

本地摘要不是把整场会议塞进去

小模型上下文有限,移动设备更有限。会议助手不把整场会议一次性喂给模型,而是先做分段,再做局部摘要,最后合并。一个 45 分钟会议可能被拆成 20 到 40 个片段。

分段器用简单规则和轻量模型混合:静音超过一定时间、话题关键词变化、发言人变化、片段 token 超过上限。每段生成一个局部草稿:

{ "segment_id": 12, "time_range": "00:18:22-00:21:05", "input_tokens": 1180, "local_summary": "团队决定 beta 阶段默认只保存本地草稿,云端增强需要用户主动确认。", "actions": [ "补充授权弹窗", "把云端增强的上传字段写入隐私说明" ], "risk_flags": ["privacy_notice_required"] }

全局摘要只读取这些局部草稿和少量证据片段,而不是读取完整原文。这样做牺牲了一部分跨段推理能力,但换来稳定的内存、可解释的证据和更低的隐私风险。

端侧小模型适合做“足够好的草稿”,不是替人拍板。会议纪要这种场景尤其要保留证据片段,让用户能点回去看原话。没有证据的漂亮总结,在线上看起来聪明,在实际工作里很危险。

隐私预处理在缓存之前

“数据不出设备”不等于隐私问题自动解决。会议助手会在本地缓存草稿、片段索引和模型中间结果。如果缓存里保留了手机号、邮箱、合同号,风险仍然在设备上长期存在。

所以我们把隐私预处理放在缓存之前。原始转写文本只保存在受保护的临时区,默认 24 小时过期。进入持久缓存的内容必须先脱敏。

privacy: raw_transcript: storage: protected_tmp ttl_hours: 24 sync: false redacted_segments: storage: encrypted_local_db ttl_days: 30 sync: optional cloud_payload: allowed_fields: - redacted_summary - action_items - evidence_segment_ids - language denied_fields: - raw_audio - raw_transcript - speaker_voiceprint

脱敏规则不要只靠大模型。确定性规则负责邮箱、手机号、证件号样式、银行卡样式;小模型负责识别“这可能是客户名称、内部项目代号、合同编号”这类上下文信息。两者都不完美,所以界面上要允许用户查看将要上传的内容。

云端兜底的请求因此长这样:

{ "request_id": "cloud_enhance_20260615_001", "consent_id": "consent_local_9a21", "source": "offline_meeting_assistant", "payload": { "language": "zh-CN", "redacted_summary": [ "团队决定 beta 阶段默认只保存本地草稿。", "[PROJECT_1] 需要补充授权弹窗和隐私说明。" ], "action_items": [ "补充授权弹窗", "确认云端增强上传字段" ], "evidence_segment_ids": [3, 12, 18] } }

注意这里没有原始音频、没有完整转写、没有真实人名邮箱。云端拿到的是本地预处理后的材料。这个链路不如“全量上云”聪明,但它更容易被用户和企业安全团队接受。

云端兜底是正常路径,不是失败路径

很多端侧方案把云端兜底写成“本地失败才调用云端”。会议助手里不这么设计。云端增强是一条用户可见的正常路径:本地先出草稿,用户看过脱敏内容后,选择是否增强。

本地模式下,用户得到的是要点、待办和风险提示。云端增强模式下,用户可以得到更完整的章节、决策背景、冲突点整理和格式化纪要。二者不是谁替代谁,而是成本、隐私和质量的不同选择。

工程上也不能做双倍浪费。云端增强不从零处理会议,而是接收本地摘要、待办、片段索引和少量已脱敏证据。这样云端上下文更短,费用更低,用户也知道上传了什么。

如果企业策略禁止云端,功能仍然可用,只是不展示增强入口:

{ "policy": "local_only", "features": { "offline_summary": true, "privacy_preprocess": true, "cloud_enhance": false, "share_redacted_note": true }, "message_code": "cloud_disabled_by_policy" }

这个错误语义比“网络不可用”重要。用户需要知道是离线、策略禁止、低电量降级,还是设备不支持。

指标只记录运行状态,不记录会议内容

端侧 AI 也需要观测,否则线上问题会变成客服截图。难点是不能把用户会议内容传回去。会议助手只上报匿名运行指标和失败原因。

第一版指标字段如下:

字段用途
eventmodel_loadedsummary_completedfallback_used
app_version排查客户端版本问题
model_id模型版本和量化版本
backendanennapidirectmlcpu
device_tier高端、中端、低端的匿名档位
network_state在线、离线、弱网
battery_state插电、电池、低电量
thermal_state正常、温热、过热降级
input_token_bucket只记录分桶,不记录文本
latency_ms端到端耗时
prefill_ms输入处理耗时
decode_ms生成耗时
peak_memory_mb峰值内存
fallback_reasonCPU 回退、模型缺失、策略禁止等
redaction_count_bucket脱敏数量分桶,不含具体值

一条上报像这样:

{ "event": "summary_completed", "app_version": "1.4.0", "model_id": "meeting-summarizer-1.8b-q4", "backend": "nnapi", "device_tier": "mid", "network_state": "offline", "battery_state": "battery", "thermal_state": "nominal", "input_token_bucket": "8k-16k", "latency_ms": 23840, "prefill_ms": 6920, "decode_ms": 11860, "peak_memory_mb": 1420, "fallback_reason": "none", "cloud_fallback_used": false }

这里故意不上传会议标题、发言人、摘要文本、具体脱敏值。端侧功能的观测要克制,宁可少一点,也不要把信任优势毁掉。

排障记录:为什么一台手机突然慢了三倍

试点时遇到过一个典型问题:同一个 10 分钟会议样本,高端笔记本 11 秒出草稿,中端手机有时 24 秒,有时接近 70 秒。模型没变,输入也没变。

排查不是从模型质量开始,而是从指标分桶开始。慢请求有三个共同点:backend=cputhermal_state=warmfallback_reason=accelerator_compile_failed。也就是说,NNAPI 编译失败后回退到了 CPU,手机又处于温热状态,频率下降,延迟自然翻倍。

继续查本地日志,发现失败集中在一个算子组合上。模型里有一段动态 shape,对某个驱动版本不稳定。解决方式不是让用户重试,而是给这类设备下发meeting-lite配置,限制片段长度,并禁用触发问题的图优化。

配置像这样:

device_overrides: - match: platform: android accelerator: nnapi driver_family: "example-driver-31" model_profile: meeting-lite max_segment_tokens: 900 graph_optimizations: dynamic_shape_fusion: false fallback: allow_cpu: true max_latency_ms: 45000

这个问题说明端侧排障有自己的节奏。服务端慢了,可以看 Pod、看 GPU、看队列。端侧慢了,要看设备温度、驱动、后端、内存压力、是否插电、是否刚下载完模型。没有匿名指标,团队只能在少数测试机上猜。

发布:模型灰度要像客户端灰度

会议助手的发布不是把模型文件放到 CDN 就结束。第一版发布分成四层:客户端代码、模型清单、模型文件、远程策略。任何一层都可能需要回滚。

一个可执行的发布步骤如下。

先发布客户端1.4.0,只带隐私过滤小模型,摘要模型按需下载。功能入口默认对 5% beta 用户开放。

rollout: app_min_version: "1.4.0" audience: beta percent: 5 default_mode: local_summary cloud_enhance_default: off

再下发模型清单,但不自动下载大模型。用户进入会议助手时,如果设备符合条件且在 Wi-Fi 下,才提示下载。

download_policy: meeting-summarizer-1.8b-q4: wifi_only: true require_battery_level_gte: 0.3 allow_metered_network: false keep_previous_version: true

接着扩大到 20%,观察模型加载成功率、下载失败率、摘要完成率、CPU fallback 比例、低电量降级比例。这里的核心不是 DAU,而是端侧运行健康。

最后才开放云端增强。云端增强必须单独灰度,因为它牵涉授权文案、脱敏 payload、服务端成本和企业策略。

cloud_enhance: percent: 10 require_user_consent: true upload_payload: redacted_only max_payload_tokens: 6000 blocked_when: - enterprise_policy_local_only - redaction_confidence_low

这个节奏慢一些,但端侧功能需要这种耐心。坏模型一旦下载到大量设备,回收成本比服务端高得多。

回滚:用户设备上的坏版本不会自动消失

端侧回滚分四种情况。

如果只是策略问题,比如云端增强授权文案不够清楚,关闭远程开关即可:

features: cloud_enhance: enabled: false reason: "consent_copy_revision"

如果是模型质量问题,把模型清单指回上一版,并保留已下载的新模型但不再选择它。不要立刻删除,避免用户在弱网下反复下载。

models: meeting_summary_active: meeting-summarizer-1.8b-q4-20260610 meeting_summary_blocked: - id: meeting-summarizer-1.8b-q4-20260615 reason: "action_item_regression"

如果是某类设备的运行时问题,只对该设备族降级到 lite 模型或 CPU 路径。不要全量回滚,否则会牺牲其他设备上已经稳定的体验。

device_overrides: - match: device_tier: mid backend: nnapi os_version_lte: "15" force_model: meeting-summarizer-lite-900m-q4

如果是客户端解析崩溃,才需要紧急发版,并通过远程策略关闭相关模型能力。端侧系统要默认假设“有一部分用户暂时不会升级”,所以旧客户端兼容性要保留一段时间。

回滚演练也要做。验收不是写一段文档,而是在测试设备上真的把模型从新版本切回旧版本,确认草稿还能打开,缓存不会损坏,用户不会丢会议记录。

验收:端侧 AI 要看体验,也要看不打扰

会议助手第一版的验收线写得很具体。

指标验收标准
高端笔记本 10 分钟会议草稿P95 小于 15 秒
中端手机 10 分钟会议草稿P95 小于 30 秒
本地隐私预处理邮箱、手机号样式召回率大于 99%
云端 payload不包含原始音频和完整原文
模型冷启动热启动小于 2 秒,冷启动小于 8 秒
CPU fallback 比例支持设备上小于 5%
低电量降级电量低于 20% 时不启动大模型
崩溃率beta 用户不高于基线 0.1 个百分点
回滚耗时远程策略 5 分钟内生效
用户可见控制能查看本地保存、上传内容和清除缓存

质量验收也不能只看自动分数。我们准备了一组会议样本:短站会、产品评审、客户访谈、技术排障、带大量数字的项目同步。每个样本都有人类参考摘要,检查三类问题:关键决策有没有漏,待办有没有编造,敏感字段有没有外泄。

端侧还有一个特殊验收:不打扰。模型下载不能抢用户流量,低电量时不能硬跑,手机发热时不能继续生成长摘要,用户关闭云端增强后不能偷偷上传。很多 AI 功能失败在太积极,而端侧功能尤其要学会克制。

这套方案真正改变了什么

做完这个离线会议助手,我对端侧小模型的判断更朴素了。

它不是云端大模型的替代品。它更适合做第一层:离数据近、响应快、隐私敏感、可以离线、成本稳定。它负责把原始材料变成更干净、更短、更有结构的中间结果。云端负责更复杂的推理和更完整的表达,但前提是用户知道并同意哪些数据会离开设备。

开发上也要换心态。服务端 AI 项目常常围绕吞吐、队列和 GPU 成本转;端侧 AI 项目则绕不开电量、温度、包体、下载、驱动、缓存、权限和回滚。NPU 不是自动加速按钮,小模型也不是随便放进 App 就能用。

最可靠的路径是从一个窄场景开始。比如会议助手只先做好本地摘要、隐私预处理和云端增强确认。把请求样例、配置、指标、排障、发布、回滚和验收都跑通以后,再谈更多能力。端侧 AI 最后拼的不是一句“本地运行”,而是它在用户设备上长期、稳定、可解释地运行。

当一个功能能在断网时给出可用草稿,在联网时清楚说明上传内容,在低电量时主动降级,在出问题时能回滚到旧模型,我才会觉得它真的进入了产品阶段。否则它只是一次演示。

参考资料

  • W3C Web Neural Network API
  • WebNN 介绍
  • Microsoft WebNN Overview
http://www.jsqmd.com/news/1030286/

相关文章:

  • ZigBee OTA升级与诊断集群开发实践指南
  • 常德防水补漏哪家好?2026 本地正规防水商家 TOP5 深度横评,精准排查暗管渗水,厨卫、屋顶、飘窗、阳台、外墙渗漏、瓷砖空鼓修补一站式治理方案推荐 - 泛家庭维修
  • 2026上海静安区黄金回收市场调研白皮书,多维度测评优质回收机构排行 - 奢品小当家
  • Mole终极指南:用命令行工具彻底优化你的Mac性能
  • 2026石家庄中检认证黄金回收白银回收铂金回收,旧黄金首饰投资金条高价变现 - 信誉隆金银铂奢回收
  • 亨得利腕表服务网点现场探访正本清源:2026亨得利官方服务体系全公示与消费者权益保护声明 - 亨得利官方维修中心
  • 2026通化本地正规黄金回收白银回收铂金回收老店|CCIC中检鉴定,全城免费上门收金 - 中业金奢再生回收中心
  • 异形灯箱生产厂家有零售的吗?2026零售定制选型参考 - 资讯快报
  • 沈阳 K 金 / 婚嫁黄金变现干货|实体门店无套路,大盘价透明结算 - 奢侈品回收评测
  • 2026银川本地正规黄金回收白银回收铂金回收老店|CCIC中检鉴定,全城免费上门收金 - 中业金奢再生回收中心
  • 2026盐城中检认证黄金回收白银回收铂金回收,旧黄金首饰投资金条高价变现 - 信誉隆金银铂奢回收
  • 2026海南公司注册代办哪家强?零差评本土代理记账服务商优选榜单 - GrowthUME
  • 2026济南LV/古驰/香奈儿避坑指南:七家包包回收正规门店 - 薛定谔的梨花猫
  • 2026 广州高空车升降车租赁公司 实测 TOP5 测评 - LYL仔仔
  • Claude账号信任机制与可持续使用指南
  • 80+专业Illustrator脚本:设计师效率革命的终极解决方案
  • 2026新乡本地正规黄金回收白银回收铂金回收老店|CCIC中检鉴定,全城免费上门收金 - 中业金奢再生回收中心
  • 阳江阳东黄金回收:2026老牌持证商家透明变现攻略 - 行行星
  • 2026广州吊车租赁公司实测 TOP5 测评 - LYL仔仔
  • 2026磁悬浮压缩机厂家深度测评:如何为工业生产匹配最佳方案? - 速递信息
  • 苏州闲置翡翠变现指南,本地靠谱回收门店全面盘点 - 讯息早知道
  • 2026无锡中检认证黄金回收白银回收铂金回收,旧黄金首饰投资金条高价变现 - 信誉隆金银铂奢回收
  • ms-swift 大模型微调完整实战指南:从环境搭建到SFT/GRPO/OPD全流程
  • 个人出售腕表全过程分享,合肥靠谱收表实体店详细测评 - 讯息早知道
  • 2026清远中检认证黄金回收白银回收铂金回收,旧黄金首饰投资金条高价变现 - 信誉隆金银铂奢回收
  • 2026天津公安备案黄金回收白银回收铂金回收老店,中检授权上门回收无套路 - 中安检金银铂钻回收
  • 2026绍兴公安备案黄金回收白银回收铂金回收老店,中检授权上门回收无套路 - 中安检金银铂钻回收
  • 2026盐城本地正规黄金回收白银回收铂金回收老店|CCIC中检鉴定,全城免费上门收金 - 中业金奢再生回收中心
  • 天津本地二手包包回收实测,筛选五家资质齐全,口碑稳定回收机构 - 讯息早知道
  • 3步破解百度网盘Mac版下载限制:告别龟速的实用指南