iOS 端侧模型训练及应用入门(二)

5 阅读4分钟

模块二:不仅是分门别类——构建用户的“全息影像”

写在前面: 如果说模块一里的 BERT 是我们的“眼睛”,帮我们看清了文字的坐标。那这一章我们要讲的就是“大脑”里的分类格。 很多时候,我们觉得 AI 笨,不是因为它“看不懂”,而是我们教它的分类方式太单一了。


2.1 拒绝“贴标签”,我们要的是“全息影像”

以前做 App,我们喜欢给用户贴一个标签。比如用户说“我要去跑步”,我们贴个标签 运动,完事。

但这远远不够。

想象一下,你是个私人管家。当主人说“我要去跑步”时,如果你只知道这是运动,你是不合格的。

你需要瞬间捕捉到以下信息:

  • 什么事? 跑步(Topic)

  • 心情咋样? 挺积极的,不是被迫营业(Sentiment)

  • 急吗? 不急,随时能去(Urgency)

  • 多难? 对主人来说是小菜一碟(Difficulty)

  • 是去为了啥? 是为了健康维系(ActionType: Lifestyle)

看,本来扁平的一句话,通过这就变成了立体的全息影像

我们在系统设计中引入了 5 个新维度(紧急度、时间视窗、行动类型、难度、具体度),就是为了让手机能像这个老管家一样,通过一句话,通过这 7 个维度的交叉定位,彻底读懂用户当下的状态。


2.2 举一反三:把这套逻辑搬到别的地方 (Domain Transfer)

这套“全息”的思路,不仅仅能用来做目标管理。如果你是做其他 App 的,完全可以照猫画虎。

关键在于:你要把你那个领域的“专家直觉”,拆解成几个独立的判断维度。

案例 A:如果你是做“记账软件”的

别只分“餐饮、交通”了,试试加上这几个维度:

  1. 必要性 (Necessity)
  • 分类:生存必须 vs 提升生活 vs 奢侈浪费

  • 价值:帮用户分析“钱都花哪了”。

  1. 消费情绪 (Mood)
  • 分类:冲动解压 vs 理智规划 vs 社交被迫

  • 价值:如果发现用户都在心情不好时乱花钱,可以弹窗提醒。

  1. 预算归属 (Budget Type)
  • 分类:个人 vs 家庭 vs 工作垫付

案例 B:如果你是做“医疗问诊”的

别只分科室,试试加上:

  1. 疼痛程度 (Severity)
  • 分类:微痛 vs 剧痛 vs 隐痛
  1. 持续时间 (Duration)
  • 分类:突发 vs 间歇 vs 长期
  1. 情绪状态 (Anxiety)
  • 分类:极度恐慌 vs 平静咨询

核心心法不要试图训练一个巨大的模型一次性输出所有结果。把任务拆得越细,每一个小分类器(Head)就越准,训练也越容易。


2.3 老师,我想加个“新分类”怎么办?(Data Updates & Retraining)

这是大家最关心的问题。

“我现在只有工作生活,要是明天我想加个滑雪怎么办?”

或者“我觉得现在的分类不够准,我想重新教它,怎么操作?”

这里必须明确一个概念:所有的训练都在响应用户的交互

不是只有点了“训练”按钮才叫训练。用户的每一次修正、每一次确认,甚至每一次不修改(默认认可),都是在为 AI 喂数据。

在我们的扇出架构里,这事儿变得特别简单,这就像换灯泡,不用拆房子。

第一步:准备“课本” (Data Preparation)

你不需要去搞那种几百万条的大数据。对于端侧微调,你只需要准备“小而精”的数据。

比如你想教它识别“滑雪”,你只需要在表格里填上:

文本内容标签 (Label)
“周末去崇礼滑雪”滑雪
“买了新的单板”滑雪
“在这个雪道摔惨了”滑雪
......

注意:为了防止它“为了学滑雪忘了跑步”,你最好再一次性把之前的“跑步”、“游泳”数据也带上,混合在一起。

第二步:重新训练“小脑瓜” (Retrain the Head)

2.3.1 什么是“纠错数据”?

当用户把一条本来被识别为“工作”的任务,手动改成了“滑雪”,这一瞬间,一条黄金数据诞生了。

在代码中,它长这样:


struct TrainingSample {

let id: UUID

let text: String // "周末去崇礼滑雪"

let embedding: [Float] // [0.12, -0.55, ... 768维坐标]

let correctLabel: String // "滑雪" (用户修正后的真实意图)

let timestamp: Date

}

这些 TrainingSample 会被悄悄保存在手机的一个安全角落(Core Data 或 SQLite),等待着夜深人静时被用来“特训”模型。

2.3.2 训练过程
  1. 不动大脑袋:那个几百兆的 BERT (Feature Extractor) 完全不用动!不用重新下载,不用重新部署。

  2. 只换灯泡

  • 把上面的数据喂给训练脚本。

  • 脚本会只训练那个负责 Topic 的小分类器。

  • 因为这个小分类器极小(几十 KB),在电脑上可能几秒钟就训练完了。

第三步:热更新 (Hot Update)

训练好了一个新的 TopicClassifier.mlmodel 文件后,你把它放到服务器上。

App 启动时检测到更新,下载这个几十 KB 的小文件,替换掉本地旧的。

用户完全无感,但下一秒,他的 App 就突然能听懂“滑雪”了。

这就是模块化扇出架构带来的最大红利:灵活、低成本、随时进化。