其他
在 Apple 设备上选择与部署端侧 AI 模型时如何选型…
为 iPhone、iPad、Mac 构建本地私有 AI 功能时,在 Foundation Models、Core ML、MLX Swift、llama.cpp 之间选型并正确落地。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 38/100 ×0.15
适用场景
在 Apple 设备上选择与部署端侧 A特定
解决思路
- 按场景选择框架:Apple Intelligence 设备(iOS 26+/macOS 26+)上的文本生成、摘要、实体抽取、结构化输出、短对话用 Foundation Models;图像分类、目标检测、分割、自定义 NLP/音频模型、需要 Neural Engine 优化或量化/调色板化/剪枝的模型用 Core ML;在 Apple Silicon 上跑 Llama、Mistral、Qwen、Gemma 等开源 LLM 追求最高吞吐或做研究/微调用 MLX Swift;需要 GGUF 格式、跨平台(iOS+Android+桌面)或最大开源生态兼容性用 llama.cpp。
- 其他任务交给对应框架:OCR/文字识别用 Vision,情感分析/NER/分词用 Natural Language,设备端训练自定义分类器用 Create ML。
- 使用 Foundation Models 前先做可用性门控:用 switch 检查 SystemLanguageModel.default.availability,分别处理 .available、.unavailable(.appleIntelligenceNotEnabled)、.unavailable(.modelNotReady)、.unavailable(.deviceNotEligible) 及未知原因,并在 .available 时用 supportsLocale(Locale.current) 校验区域,不要直接匹配语言列表。
- 创建 LanguageModelSession 时用闭包传入简短指令(如“You are a helpful cooking assistant.”),调用 session.prewarm() 预热,再用 try await session.respond(to:) 获取响应。
- 遵守 Foundation Models 会话约束:会话有状态且一次只接受一个请求,需串行化访问并在再次请求前检查 isResponding;指令、工具、schema、提示、transcript、输出共享上下文窗口,只注册必要工具并保持 schema 紧凑;把不可信用户内容放在 prompt 而非 instructions 中,并对拒绝等生成错误提供降级 UI。
- Core ML 新项目一律使用 mlprogram 格式(.mlpackage,iOS 15+),不要用已弃用的 neuralnetwork(.mlmodel);可预编译为 .mlmodelc 加快加载。
- 用 coremltools 转换 PyTorch 模型:先调用 model.eval(),再 torch.jit.trace,然后 ct.convert(..., inputs=[ct.TensorType(shape=(1,3,224,224), name="image")], minimum_deployment_target=ct.target.iOS18, convert_to='mlprogram'),最后 mlmodel.save("Model.mlpackage")。
- 转换后按流程验证:先冻结源模型的代表性 fixtures 和可接受的输出/任务容差;转换后用同一批 fixtures 对比源模型与 Core ML 模型;若输出一致性或任务指标不达标,检查形状、算子、精度、预处理,修复后重新转换并重跑 fixtures;只有未压缩模型通过后才做压缩,每次压缩改动后重新验证精度,不达标就回退或调参;最后在真机目标设备上做性能剖析,直到正确性、延迟、内存、包体积全部达标。
- MLX Swift 加载 LLM:用 LLMModelFactory.shared.loadContainer(from: HubClient.default, using: TokenizersLoader(), configuration: .init(id: "mlx-community/Qwen3-4B-4bit")),再用 ChatSession(container) 和 session.respond(to:) 运行。
- 按设备内存选模型:iPhone 12-14(4-6 GB)用 SmolLM2-135M 或 Qwen 2.5 0.5B(约 0.3 GB);iPhone 15 Pro+(8 GB)用 Gemma 3n E4B 4-bit(约 3.5 GB);Mac 8 GB 用 Llama 3.2 3B 4-bit(约 3 GB);Mac 16 GB+ 用 Mistral 7B 4-bit(约 6 GB)。
- MLX Swift 内存管理:iOS 上占用不超过总 RAM 的 60%;设置 Memory.cacheLimit = 512 * 1024 * 1024;在进入后台或内存压力时卸载 MLX 和 llama.cpp 模型,MLX 还要在生成密集阶段后调用 Memory.clearCache();更大模型使用 “Increased Memory Limit” entitlement;必须在真机 Apple Silicon 上验证,模拟器无法测试 Metal 推理、内存和性能。
- 多后端架构:按优先级回退,先判断 SystemLanguageModel.default.isAvailable 走 Foundation Models,否则若 canLoadMLXModel() 走 MLX,再否则抛 AIError.noBackendAvailable;用 coordinator actor(如 ModelCoordinator.withExclusiveAccess)串行化所有模型访问以防争用;自定义 Core ML 模型只在此处交接转换/优化,Swift 集成、模型加载、Vision 接线和预测生命周期交给 coreml 技能;除非产品明确选择非本地回退,否则私密用户内容(如日记)保留在设备上。
- 性能优化:在调试器外跑基准(Xcode 用 Cmd-Opt-R 并取消勾选 “Debug Executable”);Foundation Models 在用户交互前调用 session.prewarm();Core ML 预编译为 .mlmodelc;Neural Engine 优化优先用 EnumeratedShapes 而非 RangeDim;用 4-bit 调色板化获得最佳 Neural Engine 内存/延迟收益;Vision、Natural Language 和 Swift Core ML 运行时集成细节交给对应框架技能。
- 避免常见错误:不做可用性检查、没有降级 UI、超出上下文窗口(用 tokenCount(for:) 监控并在需要时摘要)、同一会话并发请求、把不可信内容放进 instructions、跳过转换一致性检查、Core ML trace 前忘记 model.eval()、使用 neuralnetwork 格式、MLX Swift 在 iOS 上超过 60% RAM、轻信 MLX 模拟器结果、不清理 MLX 缓存。
- 按审查清单自检:框架选型匹配用例和目标 OS;Foundation Models 每次调用前检查可用性、有降级、交互前预热、@Generable 属性按逻辑生成顺序排列、考虑 token 预算(检查 contextSize);Core ML 用 mlprogram、源/转换一致性通过固定 fixtures 和任务容差、压缩模型在真机重新验证并剖析;MLX Swift 模型大小匹配设备 RAM、设置缓存上限并清理缓存、卸载模型;所有模型访问经 coordinator actor 串行化;模型类型和工具实现符合 Sendable 或 @MainActor 隔离;在真机而非模拟器上测试。
适用边界 · 注意事项
- 目标设备早于 iOS 26 或未启用 Apple Intelligence 时,不要使用 Foundation Models,应改用 Core ML、MLX Swift 或 llama.cpp 并提供降级路径。
- 不要在模拟器上验证 MLX Swift 或 llama.cpp 的 Metal 推理、内存和性能,模拟器只能做 UI/控制流冒烟测试。
- 不要在未通过未压缩模型一致性验证前就做 Core ML 压缩,也不要在压缩后跳过精度重验证和真机剖析。