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

5 阅读10分钟

写在前面: 这一章我们不谈复杂的公式,不堆砌晦涩的术语。我希望用最通俗的“白话”,带你钻进 AI 的大脑里,看看它是如何把一段文字变成数学坐标,又是只有什么样的“身体构造”才能在手机这种寸土寸金的地方,既跑得快又能自我进化。

在开始编写代码之前,我们需要先建立一套共同的认知框架。这将决定我们后续所有工程决策的合理性。

本章核心任务

  1. 理解端侧训练与云端训练的本质区别。
  2. 掌握 Token、Embedding、Attention 三大基石。
  3. 理解“扇出架构”如何解决手机算力不足的问题。

0 引言

最近个人开发了一款目标记录 app,目前已经上架 App Store。主要使用 Bert_base 进行蒸馏得到学生模型,设置支持在 iOS 端进行调整训练提供周期数据洞察。本系列七篇文章简单介绍整体流程,以及后续的指导意义。

1.1 基础中的基础:什么是“端侧训练”?

在深入技术之前,我们先搞清楚一个物理概念:你的手机到底在干什么?

通常我们用 AI(比如 ChatGPT),流程是这样的:

  1. 你输入“你好”。

  2. 这句话飞到美国的服务器。

  3. 服务器算出回复,飞回你的手机。

  4. 你的手机全程只是个“显示器”

端侧训练 (On-Device Training) 是完全不同的:

  1. 你告诉 AI:“这句话你理解错了,应该是工作类。”

  2. 你的手机 CPU/NPU 瞬间全速运转

  3. 它打开了存储在 App 里的模型文件(那个几百 MB 的大脑)。

  4. 真的修改了模型里的某几个数字(权重)。

  5. 下一秒,这个脑子就长出了新的神经突触,永远记住了你的教诲。

  6. 全程没有一个字节的数据飞出你的手机。

云端训练 vs 端侧训练:一张表看懂

特性云端训练 (Cloud Training)端侧训练 (On-Device Training)
数据去向必须上传服务器 (隐私有风险)永远不出手机 (绝对隐私)
算力来源昂贵的英伟达显卡集群手机芯片 (利用闲置算力)
变强逻辑喂海量数据,学通用规律 (博学)喂个人数据,学个人习惯 (专精)
更新频率几周/几月更一次 (慢)每秒都能进化 (实时)
比喻读万卷书的教授24小时贴身服务的管家

1.2 语言的原子:从“切菜”开始 (Tokenization)

在让计算机理解“我爱你”之前,我们得先解决一个更基础的问题:计算机连字都不认识。

计算机的底层只有 0 和 1,它不知道什么是“我”,什么是“爱”。

所以,第一步是翻译。但在翻译之前,我们需要先切分

为什么不能直接查字典?

你可能会想,给每个汉字编个号不就行了?

  • “我” = 1

  • “爱” = 2

  • “你” = 3

这在简单的中文里行得通,但在英语或复杂的语境里就崩了。比如 "apple" 和 "apples","run" 和 "running",它们意思相近,但如果只是简单编号,计算机就会把它们当成两个完全不相关的数字。

Token(词元):AI 的乐高积木

现代 AI(比如 BERT、GPT)使用一种叫 Tokenization 的技术。它不按“字”切,也不完全按“词”切,而是按“语义碎片”切。

这就好比玩乐高,我们不关心最终拼出的是城堡还是飞船,我们只关心最基础的积木块

  • 输入unhappiness (不快乐)

  • 切分un (不) + happi (快乐) + ness (名词后缀)

  • 编号[2013, 8921, 105]

关键点:AI 读到的不是文字,而是一串数字列表 (IDs)

当你输入一句“帮我记账”,AI 真正看到的是类似 [101, 243, 982, 102] 这样的序列。


1.2 听懂人话的数学原理:从“字典”到“地图” (Embedding)

有了数字列表,计算机还是不懂意思。243982 对它来说只是两个数。

人类教会计算机理解语言的方式,经历了一次从“查字典”到“看地图”的认知飞跃。

阶段一:词袋模型 (Bag of Words) —— 只是数数

早期的 AI 像个只会数数的傻瓜。

比如你给它两句话:

  1. 苹果 也是 水果

  2. 苹果 手机 很 好用”

在它眼里,这两句话里都有“苹果”这个词。它会认为这两句话非常相似。

这就像做菜:它只看到桌上有“面粉”和“鸡蛋”,却分不清这到底是用来做“蛋糕”还是“面条”。它丢失了语境

阶段二:向量 (Vector) / Embedding —— 经纬度坐标

现在的 LLM(大语言模型)之所以聪明,是因为它学会了画地图

想象一个巨大的、几千维的宇宙空间。每一个词(Token),在这个空间里都有一个固定的坐标点

训练 LLM 的过程,就是让它把意思相近的词,在空间里摆得更近一点。

  • 神奇的现象:在这个空间里,如果你找到“国王”的坐标,减去“男人”的坐标,再加上“女人”的坐标,你会惊讶地发现,结果落在了“女王”的坐标附近!

  • King - Man + Woman ≈ Queen

这就是 Embedding(嵌入)。

当你输入“我今天很累”,BERT(768维) 这样的模型并没有“读”这句话,而是把它转化为了一个包含 768 个数字的坐标数组(比如 [0.12, -0.98, ...])。这个坐标精确地锁定了你这句话在“语义宇宙”中的位置——它靠近“疲惫”,远离“兴奋”。

总结LLM 对文本的操作,本质上就是把“文字”变成“高维空间里的坐标”。


1.3 AI 的“注意力”:为什么它能读懂潜台词? (Transformer & Attention)

有了坐标,AI 知道了每个词的意思。但一句话不仅仅是词的堆砌。

“我一把把把把住了。” —— 这句话里有四个“把”,意思完全不同。AI 怎么区分?

这就轮到 Transformer 架构和它的核心武器 Self-Attention (自注意力机制) 登场了。

聚光灯效应

想象你在一个嘈杂的鸡尾酒会上。虽然周围都在说话,但你只注意听你朋友的声音,忽略背景噪音。

Attention 机制就是让 AI 拥有这种能力。

当 AI 读到“苹果”这个词时,它会立刻向四周发射“聚光灯”:

  1. 如果周围出现了“好吃”、“水果”,它就明白:哦,这是吃的苹果

  2. 如果周围出现了“手机”、“屏幕”,它就明白:哦,这是科技公司苹果

BERT (Bidirectional Encoder Representations from Transformers) 的强大之处在于它是双向的。它不仅看前面,也看后面。它能像人类一样,通读全句,综合上下文来确定每个词在当前语境下的精确含义(动态坐标)。


1.4 学习的两个阶段:通识教育 vs 专业特训

明白了 AI 的大脑构造,我们就能理解为什么我们在手机上要采用特殊的训练策略。

AI 的变强之路分为两步:

第一步:Pre-training (预训练) —— 通识教育

  • 做什么:让模型阅读维基百科、几亿本电子书。

  • 学到了什么:它学会了语法,学会了常识,知道“巴黎是法国的首都”,知道“苹果”有两种含义。

  • 代价:这需要几千张显卡,跑几个月。这是在云端完成的。

  • 产物:一个博学的、通用的“基座模型” (Backbone),比如 BERT-Base, Llama, GPT-4。

第二步:Fine-tuning (微调) —— 专业特训

  • 做什么:给这个博学的模型看几百条你的个人日记。

  • 学到了什么:它学会了你的个人习惯。比如它本来认为“加班”是中性词,但看了你的日记后,它知道对你来说,“加班”意味着“痛苦”和“压力”。

  • 代价:只需要很少的算力,几分钟就能完成。这可以在手机上完成!


1.5 端侧架构:扇出 (Fan-out) —— 带着“外挂”大脑跑马拉松

既然 BERT 这么厉害,为什么不能直接在手机上从头训练它?

拦路虎:计算量与内存 (End-side Constraints)

BERT 像一个读过万卷书的老教授。为了改掉它对你这一小点个人习惯的认知,让你直接修改它的 1.1 亿个脑细胞(参数),这在手机上是不可能的任务。

  • 内存墙:训练需要的内存是推理的 4 倍。

  • 发热:手机 5 分钟就会烫手降频。

破局之道:扇出架构 (Fan-out)

为了解决这个问题,我们设计了一种“章鱼架构”(也叫 Fan-out):

视觉化想象:

  • 章鱼的大脑袋 (Backbone):很大,很重,装着所有的通用知识。

  • 状态冻结 (Frozen)。像琥珀一样封存起来,平时负责看东西,但绝不改变

  • 章鱼的小触手 (Heads):很小,很灵活,专门负责抓具体的东西。

  • 状态活跃 (Trainable)。这些触手是可以“生长”和“改变”的。


graph TD

UserInput["用户其实想说:'去滑雪'"] --> Tokenizer["分词器 (Tokenizer)"]

Tokenizer --> InputIDs["数字序列 (IDs)"]

InputIDs --> BERT["大脑袋 (BERT Backbone)\n[冻结 Frozen]"]

BERT --> Embedding["语义坐标 (Embedding)"]

subgraph FanOut["小触手 (Fan-out Heads)"]

Embedding --> Head1["分类头 1: Topic\n[可训练 Trainable]"]

Embedding --> Head2["分类头 2: Sentiment\n[可训练 Trainable]"]

Embedding --> Head3["分类头 3: Urgency\n[可训练 Trainable]"]

end

Head1 --> Result1["运动"]

Head2 --> Result2["开心"]

Head3 --> Result3["不急"]

style BERT fill:#eee,stroke:#333,stroke-width:2px

style FanOut fill:#e1f5fe,stroke:#039be5,stroke-width:2px,stroke-dasharray: 5, 5

具体分工:

  1. 大脑袋 (BERT - Static MLProgram)
  • 任务:它只负责把用户说的话,翻译成“语义坐标” (Embedding)。

  • 优势:因为它不动,所以我们可以利用苹果的 ANE (神经网络引擎) 对它进行极致的加速。

  1. 灵活的触手 (Classifiers - Dynamic NeuralNetwork)
  • 在老教授后面,我们接了几个特别小的、刚刚出生的小脑瓜(分类器)。

  • 任务:它们从老教授那里拿到“坐标”,然后判断这是“工作”还是“生活”。

  • 优势:只有几十 KB,我们在手机上只训练这部分!哪怕每分钟训练一次,手机也不会烫。

为什么要这么做?

这就好比,你不需要教一个成年人(BERT)怎么“看”世界(基本的语法、常识),你只需要训练几个实习生(Heads)怎么根据看到的画面做具体的决策(你的个人习惯)。


1.6 另一种可能:不用“学”,直接“找” —— k-NN 聚类法

除了上面说的“教徒弟”(训练神经网络头部),其实还有一种更简单的流派,我们称之为直觉派,也是目前 Apple 正在支持的方式。

怎么做?(Embedding + k-NN)

还是那个不变的静态大脑袋 (MLProgram),我们把用户说过的每一句话,都算出坐标(Embedding),然后存起来

当用户说了一句新话时:

  1. 算坐标:算出新话的 Embedding。

  2. 找邻居:在存好的坐标库里,找离在这个点最近的 K 个(比如 5 个)邻居。

  3. 随大流:如果这 5 个邻居里,有 4 个都是“工作”类,那这句新话大约也就是“工作”类。

对比:“训练派” vs “直觉派”

  • 训练派 (Neural Network)

  • 原理:总结规律。像学霸,做完题后总结出公式,下次直接套公式。

  • 优点:存的模型很小(公式很短),推理速度极快。

  • 缺点:需要训练过程(消耗算力)。

  • 直觉派 (k-NN)

  • 原理:翻阅历史。像记性好的人,遇到新题就翻以前的错题本,看哪道题最像。

  • 优点完全不需要训练!存下数据即训练完成 (Lazy Learning)。

  • 缺点:随着存的数据越来越多,找邻居会变慢(检索耗时);需要存下所有历史数据的坐标(占空间)。

结论:在我们的设计中,为了极致的响应速度和对未来复杂逻辑的支持,我们首选训练派。但在数据极少(比如冷启动)阶段,直觉派也是一个极佳的备选方案。