Foundation Models 自定义适配器:何时需要训练
Apple 的适配器文档对该路径有明确而狭义的定义:大多数提示工程、引导生成和工具调用应使用基础系统模型,仅当任务需要模型权重特化且团队能熟练进行 Python 模型训练时,才训练自定义 Adapter。14
Apple 自己关于该类型的文档原文写道:”适配器会占用大量存储空间,不建议大多数应用使用。”1 本系列的前一篇文章 Foundation Models Use Cases 介绍了大多数应用应当遵循的常规路径。本文则聚焦于第三条路径:训练、打包和发布自定义适配器的运维生命周期,以及 Apple 关于何时不应使用此路径的明确指引。
TL;DR
- Apple 的工具包将训练方法定为 LoRA:基础权重保持冻结,仅训练适配器权重。2
- 每个适配器都绑定到单一的系统模型版本。当 Apple 更新基础模型时,您需要重新训练适配器。3
- Apple 的建议原文:”大多数提示工程、引导生成和工具调用应使用基础系统模型。如果需要让模型专门化,则训练自定义 Adapter……仅当您能熟练在 Python 中训练基础模型时,才使用自定义适配器。”1
- 适配器文件体积较大,不应随主应用包一起发布,而应通过托管资源包和 Background Assets 按需交付。23
- Apple 表示,仅在提示工程或工具调用无法满足任务需求时,或当现有的微调服务器 LLM、领域专业知识、风格/格式/策略遵循或延迟目标足以证明其成本合理时,才考虑使用适配器。2
适配器究竟是什么
SystemLanguageModel.Adapter 是一个 struct,可在 iOS、iPadOS、Mac Catalyst、macOS 和 visionOS 上使用,全部为 26.0+。4 Apple 对该类型的描述:
“大多数提示工程、引导生成和工具调用应使用基础系统模型。如果需要让模型专门化,则训练自定义 Adapter 来改变系统模型权重,并针对您的自定义任务进行优化。仅当您能熟练在 Python 中训练基础模型时,才使用自定义适配器。”4
该机制有明确的文档说明。Apple 的适配器训练指南直接指出:2
“系统模型采用一种称为 LoRA(Low-Rank Adaptation)的参数高效微调(PEFT)方法。在 LoRA 中,原始模型权重被冻结,称为’适配器’的小型可训练权重矩阵被嵌入到模型网络中。在训练期间,仅更新适配器权重,从而显著减少需要训练的参数数量。”
LoRA 是一项公开技术,有已发表的论文渊源。5 Apple 文档化的接口包括工具包、.fmadapter 导出、资源包打包、Background Assets 交付,以及通过 SystemLanguageModel.Adapter 的运行时加载。234
该类型的 API 接口
Apple 列出了如下 Adapter 接口:4
init(fileURL: URL) throws:”从文件 URL 创建适配器。”init(name: String) throws:”创建从 background assets 框架下载的适配器。”func compile() async throws:”在与 LanguageModelSession 一起使用之前准备适配器。如果您的适配器有草稿模型,应调用此方法。”var creatorDefinedMetadata: [String : Any]:”从适配器元数据的创建者定义字段读取的值。”static func removeObsoleteAdapters() throws:”移除所有与当前系统模型不兼容的过时适配器。”static func compatibleAdapterIdentifiers(name: String) -> [String]:”获取与当前系统模型兼容的所有适配器标识符。”enum AssetError:与资源相关失败的错误类型。
SystemLanguageModel 提供了一个配套的适配器初始化器:convenience init(adapter: SystemLanguageModel.Adapter, guardrails: SystemLanguageModel.Guardrails),描述为”使用适配器创建模型的基础版本。”6
仅在部署阶段所需的授权键是 com.apple.developer.foundation-model-adapter:”一个布尔值,指示应用是否可以为 Foundation Models 框架启用自定义适配器。”6 训练或本地 Xcode 测试不需要它;但在发布到 App Store 之前必须获得它。3
Apple 的”何时考虑使用适配器”准则
工具包页面列出了具体的采用信号:2
- “您拥有适合用于 LLM 的数据集”,或您已经使用基于服务器的微调 LLM 并希望在设备端实现等效能力。
- “您需要让模型成为某个领域的专家。”
- “您需要让模型遵循特定的风格、格式或策略。”
- “提示工程无法实现任务所需的准确性或一致性。”
- “您希望降低推理延迟。如果您的提示工程方案需要每次调用都附带冗长的示例提示,那么针对该任务专门化的适配器只需极少的提示。”
同一指南也列出了您需要承担的成本:2
- 包含展示目标技能的提示和响应配对的数据集。
- 评估适配器质量的流程。
- 从服务器将适配器加载到您应用中的流程。
以及存储成本:”每个适配器将占用您应用约 160 MB 的存储空间。和其他大型资源一样,适配器不应成为应用主包的一部分,因为有多个适配器版本时,您的应用会变得过大,让人们难以安装。”2
该框架的建议——Apple 在两处分别重申——是默认采用提示工程加工具调用,仅当上述准则满足时才使用适配器。
Apple 描述下的训练流程
Apple 表示,工具包包含 Python 示例代码、特定系统模型版本的模型资源、.fmadapter 导出工具,以及资源包打包工具。2
数据集要求是 jsonl 格式的提示/响应配对,基础任务大约需要 100-1,000 个样本,复杂任务需要 5,000+ 个。Schema.md 涵盖引导生成和 AI 安全字段。2
硬件要求:”配备 Apple 芯片且至少 32GB 内存的 Mac,或 Linux GPU 机器。” Python 3.11 或更高版本。2
Apple 的数据质量原则很简单:质量胜过数量。2
训练通过工具包的 train_adapter 入口点调用:
python -m examples.train_adapter \
--train-data /path/to/train.jsonl \
--eval-data /path/to/valid.jsonl \
--epochs 5 \
--learning-rate 1e-3 \
--batch-size 4 \
--checkpoint-dir /path/to/my_checkpoints/
可选地,在训练完适配器之后,您可以训练一个匹配的草稿模型。2 草稿模型是系统基础模型的一个较小版本,可启用推测解码——这是一项已发表的推理加速技术。7 Apple 的表述:”如果您选择不训练草稿模型,则无法在您适配器的使用场景中启用推测解码。”2
单版本约束
适配器最具运维影响的事实是其与特定系统模型版本的绑定:3
“每个适配器仅与单一的特定系统模型版本兼容。每发布一个新的基础模型版本,您都必须训练一个新的适配器。如果您的应用在没有兼容适配器的情况下运行在用户设备上,将出现运行时错误。”
截至 2026 年 5 月 4 日检索,Apple 的工具包表格将 Beta 0.1.0 和 Beta 0.2.0 列为已移除,26.0.0 是首个完整工具包版本。Apple 的节奏规则是每次系统模型更新对应一个工具包版本。2 完整表述:”每次系统模型更新都会发布一个新的工具包。系统模型在 iOS、macOS 和 visionOS 之间共享,系统模型更新将作为这些平台 OS 更新的一部分进行(尽管并非每次 OS 更新都会有模型更新)。”2
运维含义在于:发布适配器的应用团队订阅了一个由 Apple 节奏驱动的模型更新生命周期。每次基础模型升级都成为重新训练、重新评估和重新发布的强制触发点。
作为资源包打包
Apple 的规则是:适配器文件对于应用包来说太大;应通过 App Store Connect 或您自己的服务器托管,然后按需下载与设备兼容的适配器。3
工具包生成 .fmadapter 包,工具包还会将其打包为 Background Assets 资源包。Xcode 16 或更高版本中的 ba-package 命令行工具完成打包工作;工具包会调用它。3
托管选项:3
- Apple 托管,受管理。 Apple 托管资源;OS 管理下载生命周期。
- 自托管,受管理。 您托管在自己的服务器上;OS 管理下载生命周期。
- 自托管,不受管理。 您自己托管并管理生命周期。
所需的 Info.plist 键根据托管选项而不同:3 Apple 托管受管理需要 BAHasManagedAssetPacks、BAAppGroupID 和 BAUsesAppleHosting;自托管受管理需要前两项;自托管不受管理则不需要任何键。每条路径还有一个由 Xcode 生成的资源下载器扩展目标。
在运行时选择正确的适配器
当资源下载器扩展的 BackgroundDownloadHandler.swift 生成时,Xcode 会接入一个 shouldDownload(_:) 回调。Apple 关于适配器资源的示例代码:3
func shouldDownload(_ assetPack: AssetPack) -> Bool {
if assetPack.id.hasPrefix("mygameshader") {
return true
}
return SystemLanguageModel.Adapter.isCompatible(assetPack)
}
Apple 的示例是唯一文档化的运行时检查方式。表达式 SystemLanguageModel.Adapter.isCompatible(assetPack) 是示例为适配器资源包返回的内容;除示例所示外,请将该调用视为不透明。3
加载和跟踪下载
资源到达设备后,加载路径如下:3
SystemLanguageModel.Adapter.removeObsoleteAdapters()
let adapter = try SystemLanguageModel.Adapter(name: "myAdapter")
如果设备上没有缓存兼容的适配器,构造将触发下载。Apple 关于 UX 的说明:”由于适配器数据量较大,下载可能需要一些时间,特别是在 Wi-Fi 或蜂窝网络上。如果用户没有网络连接,他们将无法立即使用您的适配器。”3
状态序列来自 AssetPackManager:3
let assetpackIDList = SystemLanguageModel.Adapter.compatibleAdapterIdentifiers(name: name)
if let assetPackID = assetpackIDList.first {
let statusUpdates = AssetPackManager.shared.statusUpdates(forAssetPackWithID: assetPackID)
for await status in statusUpdates {
switch status {
case .began(let assetPack): ...
case .paused(let assetPack): ...
case .downloading(let assetPack, let progress): ...
case .finished(let assetPack): ...
case .failed(let assetPack, let error): ...
@unknown default: ...
}
}
}
文档化的五个 DownloadStatusUpdate 案例:.began、.paused、.downloading、.finished、.failed。3 框架的 @unknown default 分支是必需的,因为 Apple 可能在未来的 SDK 版本中添加新案例。
状态达到 .finished 后,适配器即可接入会话:
let adaptedModel = SystemLanguageModel(adapter: adapter)
let session = LanguageModelSession(model: adaptedModel)
草稿模型及其速率限制
如果您的适配器附带了草稿模型,调用 adapter.compile() 会准备草稿模型以供使用。Apple 的文档将其称为一个独立的、计算开销较大的步骤:3
“设备首次下载新版本的适配器时,调用
compile()会完整编译您的草稿模型并保存到设备上。在应用的后续启动中,调用compile()会检查已保存的已编译草稿模型,如果存在则立即返回。”
存在已公布的速率限制:3
“速率限制保护着所有应用和进程共享的设备资源。如果框架判断需要进行新的编译,则会在 macOS 之外的所有平台上对编译过程进行速率限制,每个应用每天最多三次草稿模型编译。”
速率限制不包括 macOS;在其他平台上,新的草稿模型编译每个应用每天限制三次。3 Apple 建议在 Background Tasks 调度的任务内运行编译,这样工作就不会阻塞应用启动。3
Apple 关于 Xcode 测试的警告:通过 Xcode 启动会更改应用 UUID,因此每次启动都会运行完整编译,可能触发速率限制。3
测试与模拟器约束
适配器测试需要物理设备。Apple 明确指出:”测试适配器需要物理设备,不支持在模拟器上进行。”3
为在 Xcode 中进行本地测试,您应通过文件 URL 而非名称进行初始化:3
let localURL = URL(filePath: "absolute/path/to/my_adapter.fmadapter")
let adapter = try SystemLanguageModel.Adapter(fileURL: localURL)
发布时,Apple 表示仅出于本地测试目的导入适配器文件,然后在发布前移除它们,并按需下载适配器。3
该路径在运维层面的成本
将整个生命周期串联起来,发布自定义适配器的应用承担以下事项:
- Python 训练基础设施。 至少配备 Apple 芯片和 32 GB 内存的 Mac,或 Linux GPU 机器。2
- 跟随 Apple 节奏的重新训练周期。 每次系统模型更新都意味着新的适配器和新的工具包版本。3
- 服务堆栈。 通过 App Store Connect 的 Apple 托管资源包,或运行资源下载器集成的您自己的服务器。3
- 存储中的逐版本适配器。 现网中存在多个基础模型版本意味着需要托管多个适配器,设备拉取与之匹配的版本。3
- 授权关卡。 您 Apple Developer Program 会员资格的账户持有者需提交申请;未获批准则无法发布。2
- 每个适配器版本 160 MB 的存储成本。 不在应用包中,但下载后会占用用户设备空间。2
- 物理设备测试。 模拟器无法运行适配器。3
这就是清楚明白的运维成本。当采用信号清晰时,所获得的收益是:设备端模型针对该任务实现了专门化,所需提示极少,延迟更低。对于已经为微调的服务器端推理付费、并希望在设备端实现等效能力的应用而言,这就是简洁明了的取舍。
要点回顾
- 按 Apple 文档化的技术,适配器即 LoRA。 基础权重冻结,模型网络中嵌入小型可训练矩阵,训练期间只更新适配器权重。2
- 每个系统模型版本对应一个适配器,无例外。 规划与 OS 发布绑定的重新训练。3
.fmadapter流程是端到端的。 在 Python 中训练,使用工具包打包,作为 Background Assets 资源包托管,在应用中按名称加载,在后台任务中编译草稿模型。- Apple 自己建议大多数应用不要走这条路。 两处不同的 Apple 文档页面都不鼓励大多数用例使用此路径。1 阅读工具包页面上的准则;默认答案是”不用”。
- 在硬件上测试。 模拟器无法运行适配器。围绕物理设备会话和
Background Tasks框架的编译时段构建测试方案。
完整的 Apple Ecosystem 集群:内置专门化的决策准则;位于框架核心的 Tool 协议;应用内与工具 LLM 之间的 代理工作流划分;针对更宏观路由问题的 App Intents 与 MCP 对比。集群入口位于 Apple Ecosystem Series。如需更广泛的 iOS 与 AI 代理上下文,请参阅 iOS Agent Development guide。
FAQ
我如何判断我的应用是否真的需要自定义适配器?
Apple 建议大多数提示工程、引导生成和工具调用使用基础模型,工具包指南也表示适配器有较高的训练和重新训练要求。除非 Apple 关于适配器的信号都明确成立,否则默认答案是不需要。24
该授权实际上控制什么?
Apple 文档说明该授权在部署适配器时是必需的,但训练或本地测试不需要。23
适配器有多大,存放在哪里?
Apple 文档化的数字:”每个适配器将占用您应用约 160 MB 的存储空间。”2 适配器不存放在应用包中。Apple 通过 Background Assets 路由它们,托管在 Apple 服务器(受管理)或您自己的服务器(受管理或不受管理)上,设备会下载与其当前系统模型匹配的版本。3
当 Apple 更新基础模型时会发生什么?
当 Apple 更新基础模型时,请为该模型版本训练兼容的适配器;否则应用在没有兼容适配器的设备上可能触发运行时错误。23
适配器与 .contentTagging 之间是什么关系?
.contentTagging 由 Apple 管理并内置于框架中:是一个内部专门化的用例,而非开发者训练的正式 Adapter 类型。本文涵盖的是正式类型;用例则在 配套文章 中介绍。
我必须训练草稿模型吗?
Apple 仅记录了跳过草稿模型训练的这一后果:该适配器用例无法使用推测解码。2
References
-
Apple Developer, “SystemLanguageModel.Adapter”。类型描述、关于大多数应用不建议使用的建议,以及”仅当您能熟练在 Python 中训练基础模型时,才使用自定义适配器。”检索于 2026-05-04。 ↩↩↩↩
-
Apple Developer, “Get started with Foundation Models adapter training”。工具包概述、LoRA 机制、硬件要求、数据集形式、训练 CLI、草稿模型选项、工具包版本表、授权申请流程。检索于 2026-05-04。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
Apple Developer, “Loading and using a custom adapter with Foundation Models”。资源包托管、Info.plist 键、
shouldDownload(_:)示例、状态序列、速率限制、模拟器排除、单版本兼容性约束。检索于 2026-05-04。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple Developer, “SystemLanguageModel.Adapter”。Struct API 接口:
init(fileURL:)、init(name:)、compile()、creatorDefinedMetadata、removeObsoleteAdapters()、compatibleAdapterIdentifiers(name:)、AssetError。检索于 2026-05-04。 ↩↩↩↩↩↩ -
Hu et al., “LoRA: Low-Rank Adaptation of Large Language Models”, arXiv:2106.09685。Apple 所使用的技术参考的原始 LoRA 论文。 ↩
-
Apple Developer, “SystemLanguageModel”。
init(adapter:guardrails:)便利初始化器和com.apple.developer.foundation-model-adapter授权描述。检索于 2026-05-04。 ↩↩ -
Leviathan et al., “Fast Inference from Transformers via Speculative Decoding”, arXiv:2211.17192,以及 Chen et al., “Accelerating Large Language Model Decoding with Speculative Sampling”, arXiv:2302.01318。Apple 草稿模型所使用的推测解码技术,适配器训练指南直接引用。 ↩