
引子以前在苹果生态里搞 AI有点像去五星级酒店点外卖你想吃火锅前台微笑着说「先生我们这里只提供酒店特供套餐。」Foundation Models 很香隐私也漂亮但菜单是苹果定的。第三方大模型抱歉请去云端排队或者自己用 Metal 手搓推理引擎——后者相当于自带锅、自带火、自带厨师还得保证不被 jetsam 一脚踹出房间。WWDC26 之后情况变了。CoreAI 登场。苹果不再只给你「自家菜」而是递过来一套厨房你可以把 PyTorch 模型端上来切好、炖好、装进.aimodel然后在 iPhone / Mac 上本地端着碗吃。今天这篇就从「这到底是什么」讲到「第三方 Qwen 怎么真在本机流式吐字」——有背景、有逻辑、有能跑通的代码味道。读完你未必马上能上架但至少不会再把 CoreAI 当成「又一个神秘 Framework」。无需等待让我们马上开始 CoreAI 大冒险吧一、WWDC26 的背景苹果为什么要推 CoreAI先把时间线捋直不然后面代码会像无根之木。过去几年苹果的端侧 AI 路线大致是Core ML偏传统机器学习 / 视觉音频擅长「看图说话」不太擅长「边想边聊」。Apple Intelligence Foundation Models系统级大模型能力隐私优先但模型选择权在苹果手里。开发者的真实痛点我想跑 Qwen、Llama、自家微调模型——既要 GPU/ANE 性能又要 Swift 友好 API还想少写一点 KV Cache 手活。WWDC26 给出的答案叫CoreAI面向Apple silicon的新一代本地推理框架配套工具链coreai-torch导出→ coreai-build编译→ CoreAI runtime运行官方参考仓apple/coreai-models既有导出配方也有 Swift 侧 LLM 引擎、采样、KV Cache 等运行时工具系统门槛很硬核macOS / iOS 27.0Xcode 27.0——不是「旧系统装个 SDK 就能用」那种温柔。一句话概括CoreAI 不是「又一个聊天 SDK」而是「把任意合适结构的模型变成苹果芯片上的一等公民」的整条产线。Foundation Models 像「苹果官方外卖」CoreAI 像「你自带食材厨房和灶台归苹果管」。二、先建立心智模型CoreAI 在干什么别一上来就背 API。先记住这条流水线AUTHOR可选 按平台重写模型结构静态 shape、ANE/GPU 友好 ↓ COMPRESS可选 量化 / 调色盘压缩换体积与精度 ↓ EXPORT PyTorch → AIProgramcoreai-torch / TorchConverter ↓ COMPILE可选 AOT 编译到目标平台coreai-build ↓ RUN 设备上加载 .aimodelSwift / Python 推理对应用开发者来说日常最常碰到的是最后一步RUN。而对「第三方大模型适配」来说你会拿到的是别人已经导好的LanguageBundle——目录里通常长这样some_model_bundle/ xxx.aimodel/ ← 真正的模型资产含 main.mlirb 等 metadata.json tokenizer/.aimodel不是「把权重 zip 一下改个后缀」。它是经过导出、优化、面向 Apple 运行时的模型资产LLM 场景下外面还会包一层LanguageBundle把 tokenizer、上下文长度、function map 这些聊天相关的元数据绑在一起。浅层理解CoreAI 本地跑模型的「操作系统级厨房」。深层理解你写的不是「HTTP 请求 OpenAI」而是「加载 bundle → 创建推理引擎 → token 级 generate 流」。三、最简 Runtime先看「一张图」怎么跑在聊 LLM 之前先看官方风格的最小推理——这能帮你分清两层 API底层AIModelInferenceFunctionNDArray通用张量推理上层LanguageBundleEngineFactoryInferenceEngine给 LLM 准备好的引擎底层大概长这样importCoreAIletmodeltryawaitAIModel(contentsOf:modelURL)guardletfntrymodel.loadFunction(named:main)else{return}varinputNDArray(shape:[1,3,224,224],scalarType:.float32)varviewinput.mutableView(as:Float32.self)// 填入图像数据...varoutputstryawaitfn.run(inputs:[image:input])letresultoutputs.remove(logits)?.ndArray导出侧对应的是 Pythonfromcoreai_torchimportTorchConverter,get_decomp_tableimporttorch eptorch.export.export(model,args(torch.randn(1,3,224,224),))epep.run_decompositions(get_decomp_table())program(TorchConverter().add_exported_program(ep,input_names[image],output_names[logits]).to_coreai())program.optimize()program.save_asset(model.aimodel)看到没苹果这次把「训练框架 → 设备资产 → App 调用」串成了闭环。LLM 只是在这条环上多叠了一层语言引擎。四、进入正题第三方 LLM 怎么接进 CoreAI下面以社区已转换好的Qwen3.5-2B CoreAI LanguageBundle为例Hugging Face 上已有现成资产。思路适用于同类 pipelined LLM。1加载不是open(file)是「建一座小发电厂」importCoreAISharedimportCoreAILanguageModelsimportTokenizers// 某些 pipelined decode 图是 static [1,1]需要在创建引擎前设置ifgetenv(COREAI_CHUNK_THRESHOLD)nil{setenv(COREAI_CHUNK_THRESHOLD,1,1)}letbundletryLanguageBundle(at:bundleDirectory)letconfigModelConfig(name:bundle.name,tokenizer:bundle.tokenizer,vocabSize:bundle.vocabSize,maxContextLength:bundle.maxContextLength,serializedModel:[bundle.modelAssetPath],function:bundle.language.functionMap?.name(for:main)??main)letenginetryawaitEngineFactory.createEngine(config:tryJSONEncoder().encode(config),modelURL:trybundle.requireModelURL(for:ModelBundle.ComponentKey.main),options:EngineOptions(variant:coreai-pipelined))lettokenizertryawaitbundle.loadTokenizer()这里有几个「看起来像咒语、其实很关键」的点点为什么重要LanguageBundle一次读齐模型路径、词表、上下文长度、tokenizerEngineFactory.createEngine真正把.aimodel特化成可推理引擎variant: coreai-pipelined告诉运行时这是流水线式 decode 图不是普通前馈COREAI_CHUNK_THRESHOLD1适配 static[1,1]decode设错了可能加载成功、生成翻车第一次加载往往会触发specialization特化系统按当前设备把计算图「烤」成更合适的执行形态。冷启动可能几十秒还可能吃掉数 GB 磁盘缓存——所以产品上千万别让用户盯着转圈圈傻等得有「首次准备模型」的心智。2Prompt别直接encode(用户原话)很多模型吃的是chat template不是裸字符串。正确姿势是先组 messages再套模板letmessages:[[String:String]][[role:system,content:你是一个直接回答问题的助手。优先使用中文回答简洁清楚。],[role:user,content:prompt]]letinputIdstrytokenizer.applyChatTemplate(messages:messages).map{Int32($0)}guardinputIds.countmaxContextLength-1else{throwMyError.promptTooLong}对 Qwen 这类带/think、/no_think的模型还可以在应用层做三种模式高效系统提示 /no_think尽量直接给答案推理追加/think允许展开思考跟随输入尊重用户自己写的控制指令这不是 CoreAI 的硬性要求却是「第三方模型适配」里最容易被忽略的产品细节——引擎只会吐 token不会替你懂产品语义。3生成AsyncSequence 式地「一个字一个字挤牙膏」tryawaitengine.reset()letstreamtryengine.generate(with:inputIds,samplingConfiguration:SamplingConfiguration(temperature:0.7,topK:20,topP:0.8,minP:nil).normalized(),inferenceOptions:InferenceOptions(maxTokens:maxTokens))varanswerfortryawaitstepinstream{tryTask.checkCancellation()lettokenIdInt(step.tokenId)// 解码、过滤 stop sequence、think 块等letchunkdecodeAndFilter(tokenId)if!chunk.isEmpty{answerchunk// 推到 SwiftUI}}这就是本地 LLM 的「灵魂回路」prompt → chat template → token ids → engine.generate 流 → 逐 token 解码 → 停词 / 过滤 / UI 追加采样参数Temperature / Top-K / Top-P / Min-P和云 API 概念一致差别在于一切发生在进程内隐私不错内存账单很真实。五、再深一层适配第三方模型时你会撞上的「人情世故」代码能跑不等于产品能用。真实适配里常见坑如下——每条都来自「本机真跑过」的经验不是 PPT。1模型别塞进.app2B 级量化包常常~3GB。打进 App 包审核会皱眉用户下载会骂娘。正确姿势是首次启动后下载 / 本地导入先落到 staging校验齐全再原子替换到正式目录至少确认.aimodel、main.mlirb、metadata.json、tokenizer/齐全且大文件不是 Git LFS 指针冒充2Think 块会「偷吃」你的可见输出模型可能先吐think...。如果你在「高效模式」还直接把原文糊到 UI用户会以为 App 坏了。应用层需要过滤完整think.../think未闭合时先别展示后面内容必要时用更强硬的 system prompt 重试一次CoreAI 负责「算」你负责「做人话」。3Stop sequence 与「假结束」命中 EOS 不一定等于「答完了」。高效模式下偶发短句提前结束、没有句末标点——这时可以识别为 incomplete EOS再补一句「只从截断处继续」。长回答撞到 token 上限则做续写把已有答案塞回 prompt要求「不要重复从中断处自然接着写」。4内存与 entitlement 是物理定律Mac 上建议给系统和别的进程留足余量官方指导常见说法是留出数 GB headroomiPhone 上大模型可能需要更高内存限额相关 entitlement否则冷 specialization 直接bad_alloc用进程 footprint 观察「加载前后涨了多少」比凭感觉喊「好卡」有用得多5平台策略不同苹果自己的指导也很直白iOS偏能效静态 shape、更激进压缩模型尽量别太大macOS可更吃规模动态 shape / 控制流更宽松同一套「第三方模型适配」在 iPhone 和 Mac 上可能要选不同压缩配方——这不是口味问题是物理与系统策略问题。六、把整条链路压成一张图┌──────────────────────────────┐ │ 已转换的 LanguageBundle │ │ (.aimodel tokenizer md) │ └───────────────┬──────────────┘ │ LanguageBundle(at:) ▼ ┌──────────────────────────────┐ │ ModelConfig EngineFactory │ │ variant: coreai-pipelined │ └───────────────┬──────────────┘ │ loadTokenizer() ▼ ┌──────────────────────────────┐ │ chat template → input ids │ └───────────────┬──────────────┘ │ engine.generate(...) ▼ ┌──────────────────────────────┐ │ Async token stream │ │ → 过滤 / 停词 / UI 流式刷新 │ └──────────────────────────────┘如果你只会画 HTTP 时序图现在可以在旁边再贴一张这个——云端是请求-响应CoreAI 是加载-特化-流式解码。七、一句中式总结CoreAI 的出现意味着苹果终于承认一件事「端侧智能」不能只靠皇家厨师也得允许民间大厨进厨房——但刀具、灶台、排烟系统还得按苹果标准来。对开发者而言浅本地加载.aimodelSwift 里流式生成中LanguageBundle EngineFactory chat template 采样深导出、量化、静态 shape、specialization、内存与平台策略Foundation Models 解决「大多数 App 的官方智能」CoreAI 解决「我就要跑自己的 / 社区的模型而且要跑在苹果芯上」。两条腿才算站稳。尾声今天我们顺着「第三方大模型怎么在 CoreAI 里被叫起来」走完了调用侧bundle、引擎、模板、流式、坑点。你手里已经有一张能照着做的地图——从「听说 WWDC26 出了 CoreAI」走到了「真的能在本机看 Qwen 一个 token 一个 token 往外蹦」。故事到这里就告一段落了感谢宝子们的观赏。我是大熊猫侯佩再会啦