大多数浏览器和
Developer App 均支持流媒体播放。
-
利用 Core ML 在设备端部署机器学习和 AI 模型
了解在通过 Core ML 转换及运行机器学习和 AI 模型时,可以借助哪些新方式来优化速度表现和内存利用率。我们会介绍有关模型表示、性能洞察信息、执行以及模型拼接的新选项,你可以搭配使用这些选项,打造引人入胜又注重隐私保护的设备端体验。
章节
- 0:00 - Introduction
- 1:07 - Integration
- 3:29 - MLTensor
- 8:30 - Models with state
- 12:33 - Multifunction models
- 15:27 - Performance tools
资源
相关视频
WWDC23
Tech Talks
-
下载
大家好 我叫 Joshua Newnham 是 Core ML 团队的工程师 今天 我很高兴为大家介绍 Core ML 中的一些新功能 帮助你在设备端高效 部署并运行 机器学习模型和 AI 模型
在设备端运行模型 可带来无限可能 包括打造 新的互动形式、 构建强大的专业工具 以及深入分析 健康和健身数据 同时保证个人数据的 私密性和安全性
数以千计的 App 已使用 Core ML 打造了精彩体验 全部由设备端 ML 提供支持 你也可以!
在本视频中 我们先回顾一下 Core ML 在模型部署工作流程中的作用 接下来 我们将深入了解 一些精彩的功能 首先是简化模型整合的新类型 然后 探讨使用状态 来提高模型推理效率 之后 我们将介绍 可实现高效部署的 多函数模型 最后 探索 Core ML 性能工具的更新 帮助你分析和调试模型 让我们开始吧
机器学习的工作流程 包括三个阶段 模型训练、准备 和整合 在本视频中 我们将重点关注 在设备端整合并运行 机器学习模型和 AI 模型 要进一步了解模型训练 建议观看今年有关 基于 Apple GPU 训练 ML 和 AI 模型的视频 要了解如何转换 和优化模型 请观看今年关于 将模型移植到 Apple 芯片的视频
模型整合 从 ML 软件包开始 这是在准备阶段 创建的工件 从这里开始 Core ML 可在 App 中 轻松整合 并使用这个模型
它与 Xcode 紧密整合 可以提供统一的 API 用于在设备端 为广泛的机器学习 和 AI 模型类型执行推理
模型执行会利用 Apple 芯片 强大的计算能力进行 在 CPU、GPU 和 神经网络引擎之间调度工作 这需要 MPS Graph 和 BNNS Graph 的帮助 这是另外两个机器学习框架 它们也可以使用 Core ML 模型 最适合用于 需要与 Metal 紧密整合 或在 CPU 上进行实时推理的用例 欢迎观看相关视频 进一步了解 随着我们对推理堆栈 进行了重大改进 Core ML 今年将提供 更好的性能
例如 在比较 iOS 17 和 18 的 相对预测时间时 你会发现 iOS 18 在许多模型中的速度都更快 这种提速是操作系统自带的优势 无需重新编译模型 也无需更改任何代码 这同样适用于其他设备 不过具体的提速效果 取决于模型和硬件
模型转换完成后 我们就可以探索 如何高效整合和运行模型
将模型整合到 App 中 可能很简单 只需传入所需的输入 然后读取返回的输出
但是 对于更高级的用例 复杂性会迅速增加 例如 生成式 AI 通常是迭代的 并可能涉及多个模型
在这些用例中 模型之外也存在计算 为运行端到端管道发挥 必要的粘合或缝合作用 支持这种计算通常需要 从头开始实现运算 或使用各种底层 API 这都会导致代码冗长而复杂 但现在 我们有了新的解决方案
为大家介绍 MLTensor 这是 Core ML 中的一种新类型 可提供一种方便 高效的方法 来支持这种计算
MLTensor 提供了 机器学习框架中常见的 许多数学运算和转换运算
执行这些运算 会利用 Apple 芯片 强大的计算能力 从而确保高性能执行
这与流行的 Python 数值库相似 只要熟悉机器学习 就能更轻松直观地 加以使用 让我们通过一些 示例来探索 API
首先 我们将创建几个张量 尝试一下 创建张量的 方法有很多种 这里我们将介绍两种
第一种是从 MLShapedArray 创建张量 第二种是使用 标量的嵌套集合 与 MLShapedArray 一样 MLTensor 也是多维数组 由形状和标量类型定义 其中形状指定 每个坐标轴的长度 而标量类型则表示 所包含元素的类型 现在我们知道了如何创建张量 让我们来探索一些 操控张量的方法 我们从基本数学运算开始 张量支持广泛的运算 在本例中 我们执行元素的 加法和乘法运算 然后计算结果的平均值 张量会无缝处理字面量 框架也会自动广播 兼容的形状 然后 在比较了结果与平均值后 就会创建布尔掩码 将这个掩码乘以结果 会创建一个筛选后版本 将掩码为假的 任何值清零 接下来 我们将演示如何索引 和转换张量的形状 与 Python 数值库类似 可通过索引每个维度 来分割张量 在本例中 我们取矩阵的第一行 并使用变形方法 将它展开 所有张量运算 都是异步调度的 出于这个原因 张量必须显式 具体化为 MLShapedArray 然后才能访问 相应的底层数据 这样 可确保所有 上游运算都已完成 且数据可用
现在我们已经了解 如何创建和操控张量 让我们关注 一些更有趣的内容 探索一下 MLTensor 如何简化 大语言模型的整合
首先 我们会简要介绍 示例模型及模型输出 这个模型是一个 自回归语言模型 已经过训练 用于根据 先前词的上下文 预测下一个词或标记
生成句子时 预测词 会加回到输入中 然后重复这一过程 直至检测到序列结束标记 或达到设定长度 然而 语言模型 并不会输出单个词 而是输出词汇表中 所有词的分数 其中每个分数代表 模型对下一个词的信心
解码器使用这些分数 搭配各种策略 来选择下一个词 例如 选择分数最高的词 或在调整后的概率分布上 随机抽样 能够改变解码方法 意味着这一步 通常是与模型分开的 使它成为 MLTensor 的理想应用场景 让我们比较 MLTensor 推出前后 几种解码方法的实现 来看看具体效果如何
在本演示中 我将使用 HuggingFace 的修改版 Swift Transformer 软件包和“Chat”App 以及在准备视频中 经过转换和优化的 Mistral 70 亿参数模型 在比较解码器实现之前 让我们看看模型的运行情况 让模型为一个 关于超级英雄柯基犬的 虚构儿童故事 生成一些创意标题
开头不错 但我希望更有创意一点 应用程序默认 选择最有可能的词 这种方法称为贪婪解码
让我们来探索另一种解码方法
启用“Top-k sampling”后 应用程序将在前 k 个最有可能 出现的词中随机抽样 来选择下一个词 而不是始终选择 分数最高的词
除了随机抽取 最有可能的词外 我们还可以通过 调整温度来影响 概率分布 温度越高 分布越平缓 得到的回答更有创意 而温度较低 效果则相反 导致输出更可预测
让我们重新运行模型 使用温度为 1.8 的 top-k 采样
这些标题更有趣一点 现在我们看到了两种 解码方法的结果 让我们比较一下使用 MLTensor 前后的实现情况 通过比较实现情况 我们发现 两者之间的一个显著区别是 使用 MLTensor 实现相同的功能 只需要很少的代码 这并不是说 原始版本就是错误的 也不是说底层 API 是不必要的 恰恰相反 这是一份写得很棒的高效代码 而且很多实例 也都离不开底层 API 但是 对于许多常见的 机器学习任务来说 MLTensor 是一个简洁的替代方案 让你更多关注 如何创造出色的体验 而不是底层细节 在前一部分中 我们了解了 MLTensor 如何简化语言 模型的解码输出 在本部分中 我们将介绍状态 并探讨如何使用状态 来减少语言模型 生成每个词 所需的时间 首先 先描述一下状态的含义 很可能你接触过的大多数 模型都是无状态的 也就是说 它们独立处理每个输入 不保留任何历史记录 例如 基于卷积神经网络 的图像分类器 是无状态的 因为每个输入都是独立处理的
这与有状态模型形成鲜明对比 你可能已经猜到了 有状态模型 会保留之前输入的历史记录 用于序列数据的循环神经网络等架构 就是有状态模型的例子
如今 通过手动管理状态 可为有状态模型提供支持 其中状态作为输入传入 并从输出中 检索更新版本 为下一次预测做好准备 然而 在每个时间步载入和 卸载用于状态的数据 会产生一些开销 随着状态大小的增加 这些开销会非常明显
今年 Core ML 改进了 对有状态模型的支持 与手动维护状态相比 Core ML 现在可帮忙进行维护 并努力减少之前 提到的一些开销 现在 让我们关注一种 状态非常有用的 模型类型 在上一部分中 我们了解到语言模型 为词汇表中的所有词 输出分数 其中分数代表模型 对下一个词的信心 除分数外 使用的模型还会输出给定词的 键和值向量 每个词都会计算这些向量 然后整个网络中的注意力机制 利用这些向量 帮助模型更好地 生成自然且 与上下文相关的输出 为避免每一步都重新计算 先前词的向量 这些向量通常会存储起来重复使用 这称为 键值缓存 简称 KV 缓存 我们的新功能似乎就是处理这种缓存 的理想工具 我们来看看如何应用
现在无需使用模型的输入和输出 来处理 KV 缓存 而是可以使用 Core ML 状态来管理 这可以减少开销 提高推理效率 从而缩短预测时间
需要注意的是 在准备阶段 必须将对状态的支持 显式添加到模型中 要了解添加方法 请观看视频 了解如何将模型移植到 Apple 芯片
在 Xcode 中检查模型 就可以轻松验证 模型是否具有状态
如果有状态 在模型预览的 “Predictions”标签中 模型输入的正上方 就会显示状态
现在 我来演示一下如何更新 用于预测下一个词的代码 来支持状态 我们先来看看无状态版本 强调一下必要的改动 由于只关注相关部分 我们先创建一个空缓存 来存储键和值向量
然后将缓存作为输入 提供给模型 并使用模型返回的值 进行更新 现在 让我们来看看 支持状态所需的必要改动
大部分代码看起来都没什么变化 只是有一些小调整
我们不再手动预分配 每个状态 而是使用模型实例来创建 在本例中 Core ML 会预先分配缓冲区 来存储键和值向量 并返回一个状态句柄 利用这个句柄 你就可以访问这些缓冲区 并控制状态的有效期
我们现在不再把每个缓存 作为输入 而是只传入模型实例 创建的状态 由于更新 是就地执行的 我们可以省去最后一步 不必再更新缓存 这样就可以了! 我们更新了代码来支持状态 同时充分利用操作系统 在预测下一个词方面的提速优势
这里简要比较了运行 Mistral 70 亿参数模型的 KV 缓存实现情况 使用的设备是 搭载 M3 Max 芯片的 MacBook Pro 左侧显示的是无状态下的 KV 缓存实现 右图是有状态时的情况 我们看到右图 5 秒左右完成 而左图 大约需要 8 秒 也就是说 使用状态时 运行速度快了 1.6 倍 当然 具体性能表现 因机型和硬件而异 但这个例子可以让你大致了解 使用状态有望实现的提升
在接下来的部分 我们来探索 Core ML 的一项新功能 通过一种灵活高效的方法 部署多功能模型 提到机器学习模型 我们通常会想到 接收输入和产生输出 之类的东西 和函数很像
事实上 函数就是 神经网络在 Core ML 中的 表现形式 这些网络通常由包含运算块的 单个函数组成 理所当然 更进一步的扩展 就是支持多个函数 Core ML 现在提供这一功能 我们通过一个具体示例 来演示如何使用这一功能 高效部署具有 多个适配器的模型
你可能还不熟悉适配器 它们其实是嵌入现有 网络的小型模块 经过专门的训练 具备了执行其他任务的知识 适配器让你可以高效地 扩展大型预训练 模型的功能 而无需调整模型权重 因此 单个基础模型 可在多个适配器之间共享 在我们的例子中 我们将使用适配器 来影响潜在扩散模型 生成图像的风格
但如果我们想部署 多种风格呢?
目前 我们会部署 两个或以上的专门模型 每个适配器一个 或者将适配器权重作为输入来传入 但这两种方法都不理想
有了对多函数的支持 我们现在还有一种 更高效的选择
我们现在可以将多个共享基础的 适配器合并为一个模型 向每个适配器公开一个函数
欢迎观看有关将模型 移植到 Apple 芯片的视频 了解如何导出 带多个函数的模型 我们来看看载入带特定函数的模型 所需的代码
要载入多函数模型 只需指定函数名称就可以
载入后 在模型上调用预测 将调用指定的函数 如果没有给定函数 则调用默认函数 让我们来看看实际情况
在本演示中 我将使用开源 Stable Diffusion XL 模型 和 HuggingFace 的 修改版“Diffusers”App 根据文本生成图像 管道由多个模型组成 使用 MLTensor 无缝拼接在一起 这包括一个 带两种函数的 Unet 模型 每个函数使用不同的适配器 来影响所生成 图像的风格 在 Xcode 中打开模型 就可以预览模型的 可用函数
这个模型有两个函数 “sticker”和“storybook” 由于它们的输入和输出 完全相同 因此这两个函数可使用相同的管道 但这并不是必需的 因为有可能每个函数 的输入和输出各不相同 让我们回到 App 为我们的超级英雄 柯基犬生成一个贴纸
太棒了! 现在让我们切换到另一个函数 为超级英雄制作一个不同风格的贴纸
不错! 在本演示中 我向大家展示了 如何部署 包含多个适配器的模型 其中 每个适配器都使用 各自的函数进行访问 这个功能用途广泛 可用于其他许多场景 我很期待看到大家探索更多妙用 在最后一部分中 我们将简要介绍一些增强功能 和新工具 帮助大家更好地 分析和调试模型 首先是 Core ML 性能报告的更新 你可以为任何连接的 设备生成性能报告 无需编写任何代码 只需在 Xcode 中打开一个模型 选择“Performance”标签
点按“+”按钮创建新报告
选择要分析的设备
选择运算单元 然后点击“Run Test”按钮
完成后 报告将显示 负载和预测时间的摘要 以及运算单元使用情况的 详细分析 今年 性能报告 可提供更多信息 特别是每个运算的 预计时间和 计算设备支持 预计时间显示 每个运算所花费的时间 计算方法是 采用预测时间中位数 乘以每个运算的 预计相对开销
它有助于找出 网络中的性能瓶颈 根据预计时间 对运算进行排序 就能轻松发现瓶颈
此外 你现在可以将鼠标 悬停在不支持的运算上 查看相应的提示 了解这个运算无法 在特定计算设备上运行的原因
在本例中 提示显示 数据类型不受支持 这样我们就可以返回 准备阶段 进行必要的修改 确保我们的模型 与所有计算设备兼容
对于这个模型 只需将精度 更新为 Float16 即可 除提供更多信息外 性能报告现在还可以导出 并与其他运行进行比较 通过比较运行情况 可以轻松评估 更改对模型的影响 而无需在应用程序中 编写任何代码 说到代码 有时使用代码 会更方便 推出 MLComputePlan API 后 你可以轻松做到一点 与性能报告一样 MLComputePlan 为 Core ML 提供了 模型调试和性能分析信息 这个 API 可显示模型结构 以及每个运算的 运行时信息 包括支持 和首选的计算设备、 运算支持状态 以及刚才所说的 预计相对开销 以上就是今天的所有内容 我们来总结一下 Core ML 中的新功能可帮助你 在设备端高效部署和运行 机器学习模型与 AI 模型 现在 你可以采用 MLTensor 简化模型整合 利用状态 提高推理效率 使用多函数模型 高效部署 多功能模型 还可利用性能工具中 提供的新信息 来分析和调试模型 我期待看到大家 利用功能强大的 设备端机器学习 打造精彩的新体验
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。