Python-预训练视觉和大语言模型-全-

Python 预训练视觉和大语言模型(全)

原文:annas-archive.org/md5/ecf89cd1c29c365dd80df4e3ca3315ff

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

所以,你想使用基础模型工作吗?那是一个非常好的起点!我们中许多机器学习领域的从业者多年来一直关注这些有趣的“生物”,从最早期的 Transformer 模型诞生,到它们在计算机视觉领域的扩展,再到如今在文本生成和互动对话中几乎无处不在的存在。

那么,基础模型是从哪里来的呢?它们是如何工作的?是什么驱动它们的运作,什么时候应该进行预训练和微调?如何在你的数据集和应用程序中挖掘出性能提升?你需要多少加速器?一个端到端的应用是什么样的,如何使用基础模型来掌握这个生成式 AI 的新兴趣浪潮?

这些页面希望能为这些非常重要的问题提供答案。正如你无疑已经意识到的,这个领域的创新速度真是令人瞩目,每天都有更多的基础模型从开源和专有模型供应商处上线。为了应对这一现实,我尽力在本书中专注于最重要的概念基础。这意味着,你在这里的细心学习至少会对未来几年产生回报。

在实践应用和指导方面,我主要聚焦于通过 AWS 提供的云计算选项,尤其是 Amazon SageMaker。我在 AWS 已经愉快工作了超过五年,很高兴与大家分享我所有的知识和经验!请注意,本书中所有的观点和意见仅代表我个人的看法,并不代表亚马逊的立场。

接下来的章节将重点讨论概念,而不是代码。这是因为软件变化迅速,而基本原理变化缓慢。你会在与本书相关的代码库中找到我在这十五章中提到的所有关键主题的资源链接,你可以立即使用它们来亲自实践你在这里学到的内容。从 2023 年 7 月 1 日起,你还将在代码库中找到一套新的预训练和微调示例,由我亲自提供,以完成所有相关主题。

你可能很难相信,但在我二十多岁的时候,我其实并没有在编程:我在探索佛教僧侣的生活。我曾在亚利桑那州的一个冥想静修中心——Garchen Institute——生活了五年。在这段时间里,我学会了冥想、集中精力、观察情绪并培养良好的习惯。多年后在芝加哥大学获得硕士学位,以及现在在亚马逊工作,我发现这些品质在今天的世界中也是非常有用的!

我提到这一点是为了让你振作起来。机器学习、人工智能、云计算、经济学、应用开发,这些话题都不简单。但只要你付出努力,真正拓宽思维,去考虑这些话题的核心基础,不断迎接挑战,实际上没有什么是你做不到的。这就是人类的美丽所在!如果一个从静谧的禅修小屋中走出的冥想瑜伽士,最终也能学会预训练和微调基础模型,那么你也一定可以做到!

有了这些概念,接下来让我们更多地了解这本书本身!

注意

这里提到的大部分概念,将会伴随脚本示例在 2023 年 7 月 1 日开始发布在仓库中。然而,为了帮助你提前入门,你今天就可以在仓库中找到一些资源列表,其中包含指向其他地方的实用示例链接,供展示使用。

这本书适合谁阅读?

如果你是希望启动基础模型项目的机器学习研究人员或爱好者,那么这本书非常适合你。应用科学家、数据科学家、机器学习工程师、解决方案架构师、产品经理以及学生都将从本书中受益。要求具备中级 Python 知识,以及云计算的基础概念。需要对深度学习基础有扎实的理解,同时本书也会解释高级话题。内容涵盖了先进的机器学习和云计算技术,以一种可操作、易于理解的方式进行讲解。

本书内容概述

第一章**,基础模型预训练概述 本章将介绍基础模型,这是当今许多人工智能和机器学习系统的支柱。我们将深入了解它们的创建过程,也就是预训练,了解在哪些方面提升模型准确性具有竞争力。我们将讨论支撑当前先进模型(如 Stable Diffusion、BERT、Vision Transformers、CLIP、Flan-T5 等)的核心变换器架构。你将学习解决各种应用场景的编码器和解码器框架。

第二章**, 数据集准备:第一部分 在本章中,我们开始讨论在数据集中需要什么内容来启动一个有意义的预训练项目。这是关于数据集准备的两部分中的第一部分。开篇介绍了关于如何为基础模型找到合适用例的一些业务指导,其中数据变得至关重要。然后,聚焦于数据集的内容,我们使用定性和定量指标将其与用于预训练其他顶级模型的数据集进行比较。你将学习如何使用规模定律来判断你的数据集是否“足够大”和“足够好”,以提高预训练过程中的准确性。我们还讨论了偏差识别与缓解,以及多语言和多模态的解决方案。

第三章**, 模型准备 在本章中,你将学习如何选择哪个模型最适合作为你预训练方案的基础。你将学习如何从参数的角度思考模型的大小,以及关键的损失函数如何决定模型在生产中的表现。你将结合规模定律和预期的数据集大小,选择模型的上限和下限,这些将帮助你指导实验的设计。

第四章**, 云上的容器和加速器 在本章中,你将学习如何将脚本容器化并优化它们以适应云上的加速器。我们将了解适用于基础模型的一系列加速器,包括在整个机器学习生命周期中的成本与性能的权衡。你将学习 Amazon SageMaker 和 AWS 的关键方面,以便在加速器上训练模型、优化性能并排除常见问题。如果你已经熟悉在 AWS 上使用加速器,可以跳过本章。

第五章**, 分布式基础 在本章中,你将学习用于大规模预训练和微调的分布式技术的概念基础。首先,你将掌握机器学习的主要分布式概念,特别是模型并行和数据并行。接下来,你将了解 Amazon SageMaker 如何与分布式软件集成,将任务运行在你需要的任意数量的 GPU 上。你将学习如何优化模型并行和数据并行,以便进行大规模训练,尤其是使用像分片数据并行这样的技术。然后,你将学习如何通过高级技术来减少内存消耗,例如优化器状态分片、激活检查点、编译等。最后,我们将通过一些语言、视觉等方面的示例,将所有这些概念结合起来。

第六章**,数据集准备:第二部分,数据加载器 本章将教您如何准备数据集,以便立即与您选择的模型一起使用。您将掌握数据加载器的概念,了解为什么它是大规模训练中常见的错误源。您将学习如何创建嵌入、使用分词器以及其他方法,将原始数据转换为适用于您的神经网络的特征。按照这些步骤,您将能够准备好整个数据集,适用于视觉和语言模型。最后,您将学习在 AWS 和 Amazon SageMaker 上的数据优化技术,以高效地将大小不一的数据集发送到训练集群。在本章中,我们将从训练循环开始,逐步完成您所需的所有步骤,使您能够在大规模训练中成功实现深度神经网络。您还将跟随一个案例研究,了解我是如何在 SageMaker 上训练 10TB 的 Stable Diffusion 模型的!

第七章**,找到合适的超参数 本章将深入探讨影响顶级视觉和语言模型性能的关键超参数,如批量大小、学习率等。首先,我们将为那些新手或需要轻度复习的读者快速回顾超参数调优,包括视觉和语言领域的关键示例。接着,我们将探讨基础模型中的超参数调优,了解今天可以实现的技术和未来可能出现的趋势。最后,我们将学习如何在 Amazon SageMaker 上进行这些操作,通过逐步增加集群大小并调整每个超参数。

第八章**,SageMaker 上的大规模训练 本章将介绍使用 Amazon SageMaker 进行高度优化的分布式训练的关键功能和特性。您将学习如何优化脚本以适应 SageMaker 训练,同时掌握关键的可用性特性。您还将了解 SageMaker 分布式训练的后端优化,如 GPU 健康检查、抗干扰训练、检查点保存、脚本模式等。

第九章**,高级训练概念 本章将讨论大规模训练中的高级概念,如评估吞吐量、计算每个设备的模型 TFLOPS、编译以及利用扩展法则确定合适的训练时间长度。在上一章中,您学习了如何在 SageMaker 上进行大规模训练的基本方法。本章您将学习一些特别复杂且高效的技术,帮助您降低工作的总体成本。这种降低的成本直接转化为更高的模型性能,因为它意味着您可以在相同的预算下训练更长时间。

第十章**,微调与评估 本章将教你如何在特定用例数据集上微调模型,并将其性能与现成的公共模型进行比较。你应能看到来自预训练过程的定量和定性提升。我们将深入探讨语言、文本及其中的各种示例。你还将学会如何设计一个人类在环的评估系统,包括使得 ChatGPT 运作的相同 RLHF!本章重点介绍更新模型的可训练权重。对于模拟学习但不更新权重的技术,如提示调优和标准的检索增强生成,请参见第十三章的提示工程或第十五章的未来趋势。

第十一章**,偏见的检测、缓解和监控 本章将分析针对大型视觉、语言和多模态模型的偏见识别和缓解策略。你将了解偏见的概念,包括其统计意义以及它如何以关键的方式影响人类。你将掌握量化和解决视觉及语言模型中偏见的关键方法,最终学习能够减少所有形式危害的监控策略,以便在应用基础模型时避免伤害。

第十二章**,如何部署你的模型 本章将介绍多种部署模型的技术,包括实时端点、无服务器计算、批处理选项等。这些概念适用于许多计算环境,但我们将重点讨论在 Amazon SageMaker 上的 AWS 可用功能。我们将讨论为什么在部署前应尝试缩小模型的大小,以及如何在视觉和语言领域应用相关技术。我们还将讨论分布式托管技术,适用于无法或不需要缩小模型的场景。最后,我们将探索模型服务技术和概念,帮助你优化模型的端到端性能。

第十三章**,提示工程 本章将深入探讨一组特殊的技术——提示工程。你将了解这一技术的高级概念,包括它与本书其他学习方法的相似性与差异。我们将探讨视觉和语言领域的示例,并深入了解关键术语和成功标准。特别是,本章涵盖了无需更新模型权重即可提高性能的所有技巧和窍门。这意味着我们将在不改变任何模型参数的情况下模拟学习过程。这包括一些高级技术,如提示和前缀调优。

第十四章**, 视觉与语言的 MLOps 在本章中,我们将介绍机器学习的操作和编排的核心概念,也称为 MLOps。包括构建管道、持续集成与部署、在不同环境中进行推广等内容。我们将探讨监控选项以及对模型预测进行人工审核的方式。我们还将识别在 MLOps 管道中支持大型视觉与语言模型的独特方法。

第十五章**, 预训练基础模型的未来趋势 在本章中,我们将通过展望本书中所有相关主题的未来趋势来结束本书。我们将探讨基础模型应用开发的趋势,如使用 LangChain 构建交互式对话应用程序,以及使用检索增强生成(RAG)等技术减少大语言模型的幻觉问题。我们还将探讨如何利用生成模型解决分类任务、人本设计,以及其他生成模式,如代码、音乐、产品文档、PPT 等!我们将讲解 AWS 提供的服务,如 SageMaker JumpStart 基础模型、Amazon Bedrock、Amazon Titan 和 Amazon Code Whisperer,并讨论基础模型和预训练本身的未来趋势。

要从本书中获得最大收益

如前所述,为了充分利用本书的内容,你需要在 Python 开发中非常得心应手。书中的页面并不会花太多时间聚焦在软件上,但 GitHub 仓库中的所有内容都是 Python。如果你已经在使用一些关键的 AWS 服务,如 Amazon SageMaker、S3 存储桶、ECR 镜像和 FSx for Lustre,那么你在应用本书中学到的知识时将会大大提速。如果你对这些服务不熟悉也没关系,我们将提供这些服务的介绍。

AWS 服务或开源 软件框架 我们使用它的目的
Amazon SageMaker Studio、笔记本实例、训练任务、端点、管道
S3 buckets 存储对象并检索元数据
Elastic Container Registry 存储 Docker 镜像
FSx for Lustre 用于模型训练循环的大规模数据存储
Python 通用脚本:包括管理和与服务交互、导入其他包、清洗数据、定义模型训练与评估循环等
PyTorch 和 TensorFlow 定义神经网络的深度学习框架
Hugging Face 拥有超过 100,000 个开源预训练模型的 hub,以及无数在自然语言处理(NLP)和计算机视觉(CV)中非常有用且可靠的方法
Pandas 数据分析的首选库
Docker 构建和管理容器的开源框架

如果您使用的是本书的数字版本,我们建议您通过本书 GitHub 仓库访问代码(下一个章节中会提供链接),逐步完成示例,并自己键入代码。这样做有助于您避免因复制和粘贴代码而可能出现的错误。

下载示例代码文件

您可以从 GitHub 上下载本书的示例代码文件,网址为github.com/PacktPublishing/Pretrain-Vision-and-Large-Language-Models-in-Python。如果代码有更新,GitHub 仓库中会同步更新。

我们还提供了其他代码包,来自我们丰富的书籍和视频目录,您可以在github.com/PacktPublishing/查看。

使用的约定

本书中使用了许多文本约定。

文中的代码:表示文本中的代码单词、数据库表名、文件夹名称、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 用户名。这里有一个例子:“将下载的WebStorm-10*.dmg磁盘镜像文件挂载为系统中的另一个磁盘。”

代码块的设置如下:

html, body, #map {
 height: 100%;
 margin: 0;
 padding: 0
}

粗体:表示新术语、重要单词或您在屏幕上看到的单词。例如,菜单或对话框中的单词会以粗体显示。这里有一个例子:“从管理面板中选择系统信息。”

提示或重要说明

显示如下。

联系我们

我们始终欢迎读者的反馈。

一般反馈:如果您对本书的任何内容有疑问,请通过customercare@packtpub.com给我们发邮件,并在邮件主题中注明书名。

勘误:虽然我们已经尽力确保内容的准确性,但难免会出现错误。如果您发现本书中的错误,我们将非常感激您向我们报告。请访问www.packtpub.com/support/errata,并填写表单。

盗版:如果您在互联网上遇到我们作品的任何非法复制形式,我们将非常感激您能提供相应的地址或网站名称。请通过copyright@packt.com与我们联系,并附上相关内容的链接。

如果您有兴趣成为作者:如果您在某个主题方面具有专业知识,并且有兴趣撰写或参与书籍的编写,请访问authors.packtpub.com

分享您的想法

一旦您阅读了《Pretrain Vision and Large Language Models in Python》,我们非常希望听到您的反馈!请点击这里直接访问该书的亚马逊评论页面,并分享您的意见。

您的反馈对我们和技术社区都非常重要,将帮助我们确保提供优质的内容。

下载本书的免费 PDF 副本

感谢你购买这本书!

你喜欢随时随地阅读,但又无法携带纸质书籍吗?

你的电子书购买是否无法兼容你选择的设备?

别担心,现在购买每一本 Packt 书籍,你都能免费获得该书的无 DRM PDF 版本。

随时随地,在任何设备上阅读。直接从你最喜欢的技术书籍中搜索、复制并粘贴代码到你的应用程序中。

优惠不止于此,你还可以独享折扣、新闻通讯和每日免费内容,直接发送到你的邮箱。

按照这些简单步骤即可享受优惠:

  1. 扫描二维码或访问下面的链接

packt.link/free-ebook/9781804618257

  1. 提交你的购买证明

  2. 就是这样!我们将直接把你的免费 PDF 和其他福利发送到你的邮箱。

第一部分:预训练之前

在第一部分,你将学习如何准备预训练一个大型视觉和/或语言模型,包括数据集和模型准备。

本节包含以下章节:

  • 第一章预训练基础模型介绍

  • 第二章数据集准备:第一部分

  • 第三章模型准备

第一章:预训练基础模型简介

从 70 年的人工智能研究中可以得到的最大教训是,利用计算的通用方法最终是最有效的,而且差距很大……从长远来看,唯一重要的是利用计算。

– Richard Sutton, “The Bitter Lesson,” 2019 (1)

在本章中,你将接触到基础模型,它们是当今许多人工智能和机器学习系统的核心。特别是,我们将深入了解它们的创建过程,也就是预训练,并了解在哪些情况下,改进模型的准确性具有竞争力。我们将讨论支撑最先进模型的核心 Transformer 架构,如稳定扩散(Stable Diffusion)、BERT、视觉 Transformer、OpenChatKit、CLIP、Flan-T5 等。你将了解编码器和解码器框架,它们用于解决各种使用案例。

本章将涵盖以下内容:

  • 预训练与微调的艺术

  • Transformer 模型架构

  • 最先进的视觉与语言模型

  • 编码器与解码器

预训练与微调的艺术

人类是地球上最有趣的生物之一。我们能够创造出最伟大的美丽,并提出最深刻的问题,然而关于我们的基本方面,在许多情况下仍然知之甚少。意识究竟是什么?人类的心智是什么,它存在于何处?成为人类意味着什么?人类是如何学习的?

当来自无数学科的科学家、艺术家和思想家在应对这些复杂的问题时,计算领域却在不断推进,试图复制(在某些情况下,超越)人类智能。今天,从自动驾驶汽车到编写剧本、搜索引擎和问答系统的应用都有一个共同点——它们都使用模型,有时是多种不同类型的模型。这些模型从哪里来,如何获取智能,以及我们可以采取哪些步骤来最大化它们的影响力?基础模型本质上是大规模数据集的紧凑表示。这种表示是通过将预训练目标应用于数据集来实现的,从预测掩码标记到完成句子。基础模型之所以有用,是因为一旦创建完成(通过预训练过程),它们可以直接部署,也可以为下游任务进行微调。直接部署的基础模型示例是稳定扩散(Stable Diffusion),它在数十亿对图像-文本配对上进行了预训练,预训练后即可根据文本生成有用的图像。微调过的基础模型示例是BERT,它在大规模语言数据集上进行了预训练,但当其适应于下游领域(如分类)时,效果最佳。

在自然语言处理应用中,这些模型可以完成句子补全、将文本分类到不同类别、生成摘要、回答问题、进行基础数学运算,以及生成创意作品如诗歌和标题。在计算机视觉中,基础模型在图像分类到生成、姿态估计到物体检测、像素映射等各个领域都非常有用。

这归因于定义了一个预训练目标,我们将在本书中详细学习这一内容。我们还将讨论它的对等方法——微调,该方法帮助模型学习特定领域的知识。更广泛地说,这属于迁移学习范畴,即将一个预训练的神经网络与一个新数据集结合,期望提升其在某一维度的知识。在视觉和语言领域,这些术语有一些重叠和明显的区别,但别担心,我们将在后续章节中进一步探讨。我使用“微调”这个术语,涵盖了适应模型到另一个领域的所有技术,而非狭义上经典的定义。

基础知识 – 预训练目标

大规模预训练的核心围绕这个核心概念展开:用[MASK]标记替换某些词语,并训练模型去填充这些词语。其他方法则走另一条路,使用给定文本串的左侧部分来尝试生成右侧部分。

训练过程通过前向传播进行,将原始训练数据输入神经网络,产生输出结果。然后,损失函数计算预测结果与数据中实际值之间的差异。这种预测值与实际值之间的差异将作为反向传播的基础。反向传播通常利用一种随机梯度下降方法,根据该损失函数更新神经网络的参数,从而确保下次训练时能够得到更低的损失函数值。

以 BERT(2) 为例,预训练目标称为掩码标记损失。对于 GPT (3) 类型的生成文本模型,预训练目标称为因果语言损失。另一种看待这一过程的方式是自监督学习,利用数据集中已有的内容作为模型的信号。在计算机视觉中,你也会看到它被称为前置任务。关于最先进的模型,后续章节会有更多介绍!

就个人而言,我认为预训练是机器学习研究中最令人兴奋的进展之一。为什么?因为正如理查德·萨顿在本章开始时有争议地指出的那样,它在计算上非常高效。通过预训练,你可以利用互联网上大量的信息构建一个模型,然后结合所有这些知识,使用你自己的专有数据,将其应用到你能想象到的所有应用中。更重要的是,预训练为跨公司、跨国家、跨语言和跨领域的巨大合作打开了大门。整个行业实际上才刚刚开始开发、完善和利用预训练范式。

我们知道预训练既有趣又有效,但它在什么方面具有竞争力呢?当你的专有数据集非常庞大且与常见研究数据集不同,并且主要是未标注的时,预训练自己的模型是非常有用的。我们在本书中将学习的大多数模型都训练于相似的语料库——维基百科、社交媒体、书籍和流行的互联网网站。它们中的许多集中在英语语言上,且很少有模型有意识地利用视觉和文本数据之间的丰富互动。在整本书中,我们将学习选择和完善预训练策略的细微差别和不同优势。

如果你的业务或研究假设依赖于非标准自然语言,例如金融或法律术语、非英语语言,或来自其他领域的丰富知识,你可能需要考虑从头开始预训练自己的模型。你需要问自己一个核心问题,在我的模型中,额外的一个百分点的准确性有多大价值? 如果你无法回答这个问题,我强烈建议你花些时间找到答案。我们将在第二章中详细讨论如何做到这一点。一旦你能自信地说,提高模型的准确性至少值几十万美元,甚至可能值几百万美元,那么你就准备好开始预训练自己的模型了。

现在我们已经了解了基础模型,它们是如何通过一种称为预训练的过程产生的,以及如何通过微调将其适应特定领域,接下来让我们进一步了解 Transformer 模型的架构。

Transformer 模型架构与自注意力机制

Transformer 模型,最早出现在 2017 年那篇著名的论文《Attention is all you need》中,标志着机器学习行业的一个转折点。这主要是因为它使用了一种现有的数学技术——自注意力机制,解决了与序列相关的自然语言处理(NLP)问题。Transformer 当然不是第一个尝试建模序列的模型,之前,递归神经网络RNNs)甚至卷积神经网络CNNs)在语言处理领域中都很流行。

然而,Transformer 引起轰动是因为其训练成本仅为现有技术的一小部分。这是因为 Transformer 在其核心自注意过程中基本上更易于并行化,比之前的技术更为简单。它还在机器翻译领域刷新了世界记录。原始的 Transformer 同时使用了编码器和解码器,我们将在本章后续部分深入讨论这些技术。其他专注于类似文本对文本任务的模型,如 T5,直接遵循了这种联合编码器-解码器模式。

2018 年,Alex Radford 和他的团队提出了生成式预训练转换器,这种方法灵感来自于 2017 年的 Transformer,但仅使用解码器。称为GPT,这种模型很好地处理了大规模无监督的预训练,并与监督微调配对以在下游任务中表现良好。正如我们之前提到的,这种因果语言建模技术优化了令牌的对数概率,使我们能够从左到右找到序列中最可能的单词。

2019 年,Jacob Devlin 和他的团队提出了BERT: Pretraining of Deep Bidirectional Transformers。BERT 也采用了预训练和微调范式,但实施了一种掩码语言建模损失函数,帮助模型学习单词之前和之后的影响。这在消除单词在不同语境中的歧义意义方面非常有用,并自那时以来帮助了仅编码器任务如分类。

尽管它们的名称如此,GPT 和 BERT 都没有像原始 Transformer 论文中展示的完整编码器-解码器那样使用,而是利用了自注意机制作为学习过程中的核心步骤。因此,事实上我们应该理解的是自注意过程。

首先,要记住每个单词或令牌都表示为一个嵌入。这种嵌入是通过使用分词器,每个模型的预训练数据对象,将单词映射到适当的密集向量来创建的。一旦我们获得了每个令牌的嵌入,我们使用可学习权重生成三个新向量:关键词查询。然后,我们使用矩阵乘法和几个步骤与关键词和查询进行交互,最终使用值来确定整个序列中最具信息量的内容。在整个训练循环中,我们更新这些权重,以便根据您的预训练目标获得更好的交互。

您的预训练目标作为指导如何更新模型参数的方向指南。换句话说,您的预训练目标提供了主要信号给您的随机梯度下降更新过程,根据您的模型预测的错误程度改变模型的权重。当您长时间训练时,参数应反映损失的减少,从而使您的整体精度提高。

有趣的是,变压器头的类型会根据你使用的不同预训练目标略有变化。例如,普通的自注意力模块会使用来自标记左右两侧的信息来进行预测。这是为了提供最有价值的上下文信息,以便进行预测,并且在掩蔽语言建模中非常有用。实际上,自注意力头是堆叠起来的,在嵌入矩阵上操作,从而实现多头注意力。然而,日常语言建模使用的是一种不同类型的注意力头:掩蔽自注意力。这将预测信息的范围限制为仅矩阵的左侧,迫使模型学习从左到右的过程。这与传统的自注意力形成对比,后者可以访问序列的左右两侧进行预测。

大多数情况下,实际上,尤其是在本书中,你不需要从头开始编写任何变压器或自注意力头。然而,通过本书,我们将深入探讨许多模型架构,因此拥有这些概念性知识作为基础是很有帮助的。

从直观的角度来看,关于变压器和自注意力,你需要理解的内容可以概括为几点:

  • 变压器本身是完全建立在自注意力函数上的模型:自注意力函数接受一组输入(如嵌入),并执行数学运算将这些输入组合起来。当与标记(单词或子词)掩蔽结合使用时,模型可以有效地学习某些嵌入或序列的部分对其他部分的重要性。这就是自注意力的含义;模型试图理解输入数据集中哪些部分与其他部分最相关。

  • 变压器在处理序列时表现非常出色:它们在最近几年突破的许多基准测试主要来自自然语言处理,原因很简单。这些预训练目标包括标记掩蔽和序列补全,二者都不仅依赖于单独的数据点,还依赖于将它们串联起来以及它们的组合。这对于那些已经处理顺序数据的人来说是好消息,对于那些没有的人来说,则是一个有趣的挑战。

  • Transformer 在大规模应用下表现非常好:底层的注意力机制(attention head)非常容易并行化,这使得它相对于其他候选的基于序列的神经网络架构(如 RNNs,包括长短期记忆LSTM)网络)具有明显的优势。自注意力头可以在预训练时设置为可训练,或者在微调时设置为不可训练。在训练自注意力头时,正如我们在本书中所做的,Transformer 在大数据集上的表现最为优异。它们需要多大的数据集,以及在选择微调或预训练时可以做出哪些权衡,都是未来章节的内容。

Transformer 并不是唯一的预训练方法。正如我们在接下来的章节中将看到的,尤其是在视觉和多模态案例中,有许多不同类型的模型可以提供最先进的性能。

最先进的视觉和语言模型

如果你是机器学习的新手,那么有一个关键概念你最终会想要学习并掌握,那就是最先进技术(state of the art)。正如你所知道的,机器学习任务有很多不同的类型,比如物体检测、语义分割、姿态检测、文本分类和问答等。每一种任务都有许多不同的研究数据集。这些数据集通常会提供标签,通常用于训练、测试和验证数据集划分。这些数据集通常由学术机构托管,每个数据集都专门用于训练解决这些问题的机器学习模型。

在发布新的数据集时,研究人员通常还会发布一个新的模型,该模型已经在训练集上进行了训练,在验证集上进行了调优,并在测试集上进行了独立评估。该模型在新的测试集上的评估分数为该特定类型建模问题确立了一个新的最先进技术。在发布某些类型的论文时,研究人员通常会尝试提高该领域的性能——例如,通过在一些数据集上提高几个百分点的准确率。

最先进技术的性能对你来说很重要,因为它是你模型在最佳情况下可能表现如何的强有力指示。大多数研究结果不容易复制,且实验室通常会开发特殊的技术来提高性能,这些技术可能并不容易被其他人观察和复制。尤其是当数据集和代码库没有公开共享时,像 GPT-3 这样的情况就会变得尤为复杂。而当训练方法未公开时,像 GPT-4 的情况则更加明显。

然而,考虑到足够的资源,确实可以达到类似于顶级论文中所报告的性能。一个很好的地方,可以找到当前最先进的性能,就是由 Meta 维护并由社区增强的一个出色网站——Papers With Code。通过使用这个免费的工具,你可以轻松地找到顶级论文、数据集、模型以及带示例代码的 GitHub 网站。此外,它们还提供了很好的历史视图,因此你可以看到不同数据集中的顶级模型是如何随时间演变的。

在接下来的章节中,我们将详细讨论如何准备数据集和选择模型,包括如何确定与你自身目标的相似性和差异性。书中的后续部分,我们还将帮助你确定最佳模型及其大小。目前,让我们来看一些模型,截至目前,它们仍然稳居各自领域的排行榜之首。

截至 2023 年 4 月的顶级视觉模型

首先,让我们快速看一下当前在图像任务(如分类和生成)中表现最好的模型。

数据集 最佳模型 来自 Transformer 性能
ImageNet Basic-L (Lion 微调) 91.10% 顶级 1% 准确率
CIFAR-10 ViT-H/14 (1) 99.5% 正确率
COCO InternImage-H (M3I 预训练:paperswithcode.com/paper/internimage-exploring-large-scale-vision) 65.0 Box AP
STL-10 Diffusion ProjectedGAN 6.91 FID(生成)
ObjectNet CoCa 82.7% 顶级 1% 准确率
MNIST 简单 CNN 的异构集成 (1) 99.91% 准确率(0.09% 错误)

表格 1.1 – 顶级图像结果

初看这些数字,可能会让人感到有些畏惧。毕竟,其中许多模型的准确率接近或达到了 99%!对于初学者或中级机器学习从业者来说,这是不是太高的标准了?

在我们对疑虑和恐惧过于担忧之前,理解一个关键点是很有帮助的,那就是这些准确度分数大多是在研究数据集发布后至少五年才取得的。如果我们分析Paper With Code上提供的历史图表,很容易发现,当第一批研究人员发布他们的数据集时,初始的准确度分数通常在 60%左右。随后,经过多年各个组织和团队的努力,才最终生产出能够达到 90%以上的模型。所以,不要灰心!只要你投入时间,你也可以训练出在特定领域内创造新最优性能的模型。这是科学,而非魔法。

你会注意到,尽管这些模型中有一些确实采用了 Transformer 启发式的后端结构,但也有一些并没有。经过仔细观察,你还会发现,这些模型中的一些依赖于我们将在本书中学习的预训练和微调范式,但并不是所有模型都是如此。如果你对机器学习是新手,那么这种差异可能是你需要开始适应的!强大而多元的科学辩论、观点、见解和观察是维持健康社区和提升领域整体成果质量的关键因素。这意味着,你可以并且应该对遇到的方法有所预期,并且这种差异是件好事。

现在,既然你对当前计算机视觉领域的顶尖模型有了更好的理解,让我们来探讨一下将大规模语言模型技术与视觉技术相结合的早期方法:对比预训练和自然语言监督。

对比预训练和自然语言监督

关于现代和经典图像数据集的有趣之处在于,从 Fei-Fei Li 于 2006 年提出的 ImageNet,到 2022 年在 Stable Diffusion 中使用的 LAION-5B,这些数据集的标签本身都是由自然语言构成。换句话说,由于图像的范围包括了物理世界中的物体,因此标签必然比单一数字更为细致。从广义上讲,这种问题框定方式被称为自然语言监督

想象一下,拥有一个包含数千万张图片的大型数据集,每张图片都有对应的描述。除了简单地命名物体之外,描述还会为你提供更多关于图片内容的信息。一个描述可以是Stella 坐在一张黄色沙发上,也可以是Pepper,这只澳大利亚小狗。仅用几句话,我们就能获得比单纯描述物体更多的背景信息。现在,假设你使用一个预训练的模型,比如编码器,将语言处理成一个密集的向量表示。然后,将这个向量与另一个预训练模型——这次是图像编码器——结合起来,将图像处理成另一个密集的向量表示。将这两者结合在一个可学习的矩阵中,你就可以开始进行对比预训练了!这一方法同样由 Alex Radford 和他的团队提出,距离他们在 GPT 上的研究成果仅仅几年的时间,这种方法为我们提供了一个联合学习图像和语言之间关系的方式,同时也给出了一个非常适合执行这一任务的模型。这个模型叫做对比语言-图像预训练CLIP)。

CLIP 并不是唯一一个使用自然语言监督的视觉-语言预训练任务。早在 2019 年,一支来自中国的研究团队就提出了视觉语言 BERT模型,试图实现类似的目标。从那时起,视觉与语言基础模型的联合训练变得非常流行,Flamingo、Imagen 和 Stable Diffusion 都展示了有趣的研究成果。

现在我们已经了解了一些关于联合视觉与语言对比预训练的内容,让我们来探讨今天语言领域中的顶级模型。

2023 年 4 月顶级语言模型

现在,让我们评估一些当前最顶尖的模型,针对一个与基础模型极为相关的任务,这也是本书的主题:语言建模。此表展示了一组在多种场景下的语言模型基准测试结果。

数据集 最佳模型 来自 Transformer 性能
WikiText-103 混合 H3 (2.7B 参数) 10.60 测试困惑度
Penn Treebank (词汇级别) GPT-3 (零-shot) (1) 20.5 测试困惑度
LAMBADA PaLM-540B (少-shot) (1) 89.7% 准确率
Penn Treebank (字符级别) Mogrifer LSTM + 动态评估 (1) 1.083 每字符比特
C4 (庞大清理抓取语料库) Primer 12.35 困惑度

表 1.2 – 顶级语言建模结果

首先,让我们尝试回答一个基本问题。什么是语言建模,为什么它如此重要?今天所知的语言建模似乎在两篇基础论文中得到了形式化:BERT (9) 和 GPT (10)。启发这两篇论文的核心概念看似简单:我们如何更好地使用无监督的自然语言?

如你所料,我们世界上绝大多数自然语言并没有直接的数字标签。一些自然语言适合使用具体标签,例如那些客观性毋庸置疑的情况。这包括回答问题的准确性、总结、情感分析、高级情感分析、文档检索等。

但寻找这些标签并生成所需数据集的过程可能会非常昂贵,因为这一过程完全是手动的。同时,许多无监督数据集在不断增大。现在,由于全球对话大多在线进行,丰富多样的数据集变得容易获取。那么,机器学习研究人员如何定位自己,借助这些庞大且无监督的数据集获益呢?

这正是语言建模试图解决的问题。语言建模是将数学技术应用于大规模无标签文本的过程,依赖多种预训练目标,使模型能够自我学习这些文本内容。也称为自监督,具体的学习方法根据所使用的模型而有所不同。BERT 在数据集中随机应用掩码,并学习预测被掩码隐藏的单词,使用的是编码器。GPT 使用解码器从左到右进行预测,例如,从句子的开头开始,学习如何预测句子的结尾。T5 家族的模型使用编码器和解码器共同学习文本到文本的任务,如翻译和搜索。正如在 ELECTRA (11) 中提出的,另一种选择是标记替换目标,它选择将新标记注入原始文本,而不是对其进行掩码处理。

基础知识 – 微调

基础语言模型只有与其配套方法——微调一起使用时,才在应用中发挥作用。微调的直觉非常容易理解;我们希望利用一个在其他地方预训练的基础模型,并应用一个更小的数据集,使其更加专注和适用于我们的具体任务。我们也可以称之为领域适应——将一个预训练的模型适应到一个完全不同的领域,这个领域在其预训练任务中并未涉及。

微调任务无处不在!你可以使用一个基础语言模型,例如 BERT,并将其微调用于文本分类,或者问答,或者命名实体识别。你也可以使用其他模型,例如 GPT-2,并将其微调用于摘要生成。或者,你可以使用类似 T5 的模型并将其微调用于翻译。基本的思路是,你正在利用基础模型的智能。你正在利用计算力、数据集、大型神经网络,以及最终,研究人员通过继承他们的预训练模型所利用的分发方法。然后,你可以选择性地为网络添加额外的层,或者更可能的是,使用像 Hugging Face 这样的软件框架来简化这一过程。Hugging Face 已经成功构建了一个极其流行的开源框架,拥有数万个预训练模型,我们将在未来的章节中学习如何最佳利用它们的示例来构建我们自己的视觉和语言模型。微调有许多不同类型,从参数高效的微调到指令微调、思维链,甚至有些方法并不严格更新核心模型参数,比如检索增强生成。我们将在本书的后续章节中讨论这些内容。

正如我们将在未来章节中发现的那样,基础语言和视觉模型也并非没有负面影响。首先,它们对计算资源的极大需求对服务提供商造成了显著的能源压力。确保能源通过可持续方式得到满足,并且建模过程尽可能高效,是未来模型的主要目标。这些巨大的计算需求显然也非常昂贵,对资源不足的人来说构成了固有的挑战。然而,我认为,本书中你将学习到的核心技术适用于各种计算需求和资源配置。一旦你在较小规模的预训练中取得成功,通常更容易证明额外资源的需求是合理的。

此外,正如我们将在后续章节中看到的那样,大型模型因能够继承其训练数据中存在的社会偏见而声名狼藉。从将某些就业领域与性别挂钩,到基于种族分类犯罪可能性,研究人员已识别出数百种(9)偏见渗入自然语言处理系统的方式。和所有技术一样,设计师和开发人员必须意识到这些风险,并采取措施加以缓解。在后续章节中,我将指出你今天可以采取的各种措施,以减少这些风险。

接下来,让我们了解一种用于为语言模型定义适当实验的核心技术:扩展规律!

语言技术聚焦——因果建模与扩展规律

你无疑听说过现在臭名昭著的模型ChatGPT。几年来,总部位于旧金山的人工智能公司 OpenAI 致力于研究,旨在改善人类在人工智能领域的成果。为了实现这一目标,他们在扩展语言模型方面取得了大胆的突破,像物理学中推导公式一样,解释了大规模语言模型(LLM)性能的规律。最初,他们将自己定位为一个非营利组织,发布了他们的核心见解和代码以供复现。然而,创立四年后,他们转向与微软达成独家数十亿美元的合作协议。如今,他们的 600 人研发团队专注于开发专有模型和技术,许多开源项目则试图复制并改进他们的成果。尽管这一转型备受争议,但 OpenAI 团队为行业提供了几个极具价值的见解。第一个是 GPT,第二个是扩展规律。

如前所述,基于 GPT 的模型使用因果语言建模来学习如何最好地完成文本。这意味着使用从左到右的完成学习标准,不断更新模型的可学习参数,直到文本完全准确。虽然 2018 年的首个 GPT 模型本身已经很有用,但真正的兴奋出现在几年后的两个阶段。首先,贾里德·凯普兰(Jared Kaplan)领导 OpenAI 的团队提出了一个新概念:利用受到他在物理学研究中的启发的公式,来估算模型、数据集和整体计算环境的规模对模型损失的影响。这些神经语言模型的扩展规律 (9) 表明,对于给定的计算环境,最优的模型规模是非常庞大的。

2018 年发布的原版 GPT 模型仅包含 1.17 亿个参数,而它的第二版,恰如其名的 GPT-2,将模型规模提高了最多 10 倍。参数数量的增加使模型的整体准确度翻倍以上。在这些结果的鼓舞下,且受凯普兰(Kaplan)理论和实证研究成果的推动,OpenAI 大胆地将模型参数大小再增加了 10 倍,最终推出了 GPT-3。

随着模型规模的增大,从 13 亿个参数到 130 亿,最终达到 1750 亿个参数,准确性也取得了巨大的飞跃!这一结果催生了自然语言处理(NLP)领域,释放了新的应用场景并引发了一波新的工作,探索并扩展了这些影响。从那时起,新的研究探索了更大(PaLM (9))和更小(Chinchilla (10))的模型,Chinchilla 提出了对扩展规律的全新更新。Meta 的 Yann LeCunn 团队也提出了一些小型模型,这些模型在特定领域超越了更大模型,例如问答(Atlas (9))。亚马逊也提出了两个超越 GPT-3 的模型:AlexaTM 和 MM-COT。许多团队也在努力推出开源版本的 GPT-3,例如 Hugging Face 的 BLOOM、EleutherAI 的 GPT-J 和 Meta 的 OPT。

本书的其余部分将专注于讨论这些模型——它们来自哪里、它们的用途,尤其是如何训练你自己的模型!虽然许多优秀的工作已经覆盖了如何通过微调使用这些预训练模型进行生产,例如 Hugging Face 自己的自然语言处理与变换器(Tunstall 等,2022),但我依然相信,自己进行基础模型的预训练,可能是当今你能参与的最有趣的计算智能挑战。我还认为,这是最具盈利性的之一。但更多内容将在后面展开!

接下来,让我们了解两个你需要详细理解的关键模型组件:编码器和解码器。

编码器和解码器

现在,我想简要介绍两个关键的主题,你将在讨论基于变换器的模型时看到:编码器和解码器。我们先建立一些基本的直觉,帮助你理解它们的含义。编码器只是一个计算图(或神经网络、函数或对象,具体取决于你的背景),它接受一个具有较大特征空间的输入,并返回一个具有较小特征空间的对象。我们希望(并通过计算演示)编码器能够学习到输入数据中最重要的部分。

通常,在大型语言和视觉模型中,编码器本身由多个多头自注意力对象组成。这意味着在基于变换器的模型中,编码器通常是多个自注意力步骤,学习输入数据中最重要的部分,并将其传递给下游模型。我们来看一个简短的图示:

图 1.1 – 编码器和解码器

图 1.1 – 编码器和解码器

直观地,正如您在前面的图中看到的,编码器从较大的输入空间开始,并逐步将其压缩成较小的潜在空间。在分类的情况下,这只是一个分类头,为每个类别分配输出。在掩蔽语言建模的情况下,编码器堆叠在一起,更好地预测要替换的掩蔽标记。这意味着编码器输出的是一个嵌入,即该标记的数值表示,经过预测后,分词器将重新利用该嵌入将其转化回自然语言。

作为最早的“大型语言模型”之一,BERT 是一个仅包含编码器的模型。大多数其他基于 BERT 的模型,如 DeBERTa、DistiliBERT、RoBERTa、DeBERTa 等,采用的是仅编码器的模型架构。解码器的操作正好相反,从压缩表示开始,逐步将其重新组合回较大的特征空间。编码器和解码器可以结合使用,如原始 Transformer 中所示,以解决文本到文本的问题。

为了简化,下面是一个简短的表格,快速总结了我们所看过的三种自注意力模块:编码器、解码器及其组合。

输入和输出的大小 自注意力模块类型 机器学习任务 示例模型
长到短 编码器 分类,任何稠密表示 BERT, DeBERTa, DistiliBERT, RoBERTa, XLM, AlBERT, CLIP, VL-BERT, Vision Transformer
短到长 解码器 生成,摘要,问答,任何稀疏表示 GPT, GPT-2, GPT-Neo, GPT-J, ChatGPT, GPT-4, BLOOM, OPT
相等 编码器-解码器 机器翻译,风格转换 T5, BART, BigBird, FLAN-T5, Stable Diffusion

表 1.3 – 编码器、解码器及其组合

现在,您对编码器、解码器及它们所创建的模型有了更深入的理解,让我们快速回顾一下您刚刚学习过的所有概念,结束这一章。

摘要

我们在这一章中已经涵盖了很多内容!在继续之前,让我们快速回顾一些关键主题。首先,我们讨论了预训练和微调的技巧,包括一些关键的预训练对象,如掩蔽语言模型和因果语言建模。我们了解了 Transformer 模型架构,包括其变种的核心自注意力机制。我们探讨了最先进的视觉和语言模型,重点介绍了来自自然语言监督的对比预训练,以及神经语言模型的扩展规律。我们还了解了编码器、解码器及其组合,这些概念今天在视觉和语言领域中仍然非常有用。

现在,您已经具备了理解预训练基础模型的良好概念性和应用基础,让我们来看看如何准备数据集:第一部分。

参考文献

请参阅以下内容,以获取更多有关本章中涵盖的某些主题的信息:

  1. 痛苦的教训, Rich Sutton, 2019 年 3 月 13 日: www.incompleteideas.net/IncIdeas/BitterLesson.html

  2. Jacob Devlin, Ming-Wei Chang, Kenton Lee, 和 Kristina Toutanova. 2019. BERT: 深度双向转换器的预训练用于语言理解: aclanthology.org/N19-1423/。在 2019 年北美计算语言学学会年会论文集:人类语言技术,第 1 卷(长文与短文),第 4171-4186 页,明尼阿波利斯,明尼苏达州。计算语言学学会。

  3. Brown, Tom 和 Mann, Benjamin 和 Ryder, Nick 和 Subbiah, Melanie 和 Kaplan, Jared D 和 Dhariwal, Prafulla 和 Neelakantan, Arvind 和 Shyam, Pranav 和 Sastry, Girish 和 Askell, Amanda 和 Agarwal, Sandhini 和 Herbert-Voss, Ariel 和 Krueger, Gretchen 和 Henighan, Tom 和 Child, Rewon 和 Ramesh, Aditya 和 Ziegler, Daniel 和 Wu, Jeffrey 和 Winter, Clemens 和 Hesse, Chris 和 Chen, Mark 和 Sigler, Eric 和 Litwin, Mateusz 和 Gray, Scott 和 Chess, Benjamin 和 Clark, Jack 和 Berner, Christopher 和 McCandlish, Sam 和 Radford, Alec 和 Sutskever, Ilya 和 Amodei, Dario. 2020. 语言模型是少样本学习者。在 神经信息处理系统进展,第 33 卷。第 1877-1901 页。Curran Associates, Inc.

  4. 一张图片等于 16x16 个词:用于 规模化图像识别的变换器: arxiv.org/pdf/2010.11929v2.pdf

  5. 一个简单卷积神经网络模型的集成用于 MNIST 数字 识别: arxiv.org/pdf/2008.10400v2.pdf

  6. 语言模型是少样本 学习者: arxiv.org/pdf/2005.14165v4.pdf

  7. PaLM: 使用 Pathways 扩展语言建模: arxiv.org/pdf/2204.02311v3.pdf

  8. MOGRIFIER LSTM: arxiv.org/pdf/1909.01792v2.pdf

  9. BERT: 深度双向转换器的预训练用于语言 理解: arxiv.org/pdf/1810.04805.pdf

  10. 通过生成式 预训练提升语言理解: s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf

  11. ELECTRA: 作为判别器而非 生成器的预训练文本编码器: arxiv.org/pdf/2003.10555.pdf

  12. 语言(技术)是权力:NLP 中“偏见”的批判性调查: arxiv.org/pdf/2005.14050.pdf

  13. 神经语言模型的规模定律: arxiv.org/pdf/2001.08361.pdf

  14. PaLM: 利用路径提升语言建模的规模: arxiv.org/pdf/2204.02311.pdf

  15. 训练计算优化的大型语言模型: arxiv.org/pdf/2203.15556.pdf

  16. Atlas: 使用增强检索语言模型进行少样本学习: arxiv.org/pdf/2208.03299.pdf

第二章:数据集准备:第一部分

在本章中,我们将开始讨论启动有意义的预训练项目所需的数据集内容。这是关于数据集准备的两部分内容中的第一部分。首先,我们提供一些关于如何为基础建模找到合适用例的业务指导,其中数据起着至关重要的作用。然后,专注于数据集的内容,我们使用定性和定量的标准将其与用于预训练其他顶级模型的数据集进行比较。你将学会如何判断你的数据集是否“足够大”和“足够好”,以在预训练时提高准确性。我们还将讨论偏差识别与缓解,以及多语言和多模态解决方案。

在本章中,我们将涵盖以下主题:

  • 讨论如何为基础建模寻找数据集和用例的业务层面内容

  • 通过将你的数据集与开源研究社区中可用的数据集进行对比来评估它

  • 使用扩展定律来合理规划你的数据集规模

  • 偏差检测与缓解

  • 数据集增强——多语言和数据增强

为基础建模寻找数据集和用例

数据集——我们热爱它们,挣扎于它们,依赖它们,也常常忽视它们,往往是同时发生的。每一笔交易、每一个数字瞬间、每一个档案、每一张快照都可能成为数据集的候选项。如果你的组织已经经历了数字化转型,或者你是数字原生企业,那么很可能你已经大量投资于某些数据存储解决方案。无论是本地存储还是云存储,每个组织都需要一个安全、可靠、可操作且强大的解决方案来存储各种数据类型。此时你面临的主要问题是,我如何通过这些数据进行盈利?我如何利用我组织历史和优势中最独特的部分,并通过它开发新的能力,进一步提升我的竞争优势?

对于已经在生产应用中部署机器学习模型的公司,找到一个适合基础建模项目的候选数据集的简单方法是问自己,所有模型的共同点是什么?这些模型依赖于哪些领域、哪些模式、哪些信号,哪些资源可以用来提高这些模型的整体智能?

一种常见的思维练习是考虑与业务核心相关的互动。从搜索到客户支持、供应链、产品开发和维护、营销等,你的每一条业务线都涉及到定期的决策过程。现在,问问自己以下问题:

  • 如果我能将决策准确性提高 1%呢?

  • 如果我能将我的营销潜在客户转化率提高 1%呢?

  • 如果我能为客户推荐更好的内容,提高 1%呢?

  • 如果我能将我的运营效率提高 1%呢?

  • 如果我能更准确地回答问题,提高 1%呢?

  • 如果我能让我的产品交付速度提高 1%,会怎样呢?

一旦你找到自己最感兴趣的业务领域,或者你认为投资影响最大的一块,尝试量化这个数字。准确度提高 1%会为你带来$50,000 吗?那$500,000 呢?甚至$1,000,000?或者更多倍的收益?我说的显而易见,但所有条件相同的情况下,显然数字越高越好。你要选择一个你认为能带来最大投资回报的领域。

现在,一旦你确定了组织中的那个领域,拿出总预估收入的 10%,或者是你觉得更合适的其他低百分比。这就是你的最大计算预算。别担心——我们不会一次性花光这些预算。你甚至可能根本不需要花完它。随着我们逐步阅读本书,我将帮助你弄清楚如何通过早期信号判断你的项目是否会成功,例如在1%的数据上进行训练,以确保性能优于开源模型。在你的预训练项目中,你需要达到关键的里程碑,随着你完成这些里程碑,你会越来越接近最终目标。这个总体目标也将是你用来决定花费多少时间、需要多少人手、要使用多少次冲刺等的数字。

一旦你有了这个目标应用,并且清楚了预估的回报和成本,你就可以开始将其付诸实践了!开始列出你的组织中已经存储的、与您想要构建的应用相关的任何数据集。你是否有与此相关的事务型关系数据库?客户历史记录?点击流数据?搜索结果?那图像呢?有没有视频?有没有音频文件?有没有实验结果?尽量发挥创意,列出你所拥有的尽可能多的候选数据集。考虑花一个小时四处看看,看看你的组织已经存储了哪些与这个候选应用领域相关的数据。如果它已经是关键任务系统,那么很可能你已经存储了不少数据。

如果你还没有至少几个 GB 的数据,或者更好的是,几十 GB 的数据,那么你可能需要考虑从开源解决方案中收集一个新的数据集。这些可能包括通过Papers With Code网站(1)提供的 6000 多个数据集的任何组合。你也可以查看Hugging Face Hub提供的 8000 个数据集(2)。记住,这些数据集是免费的!开源数据集是开始验证你想法概念的绝佳方式。常见的语言预训练数据集包括The PileCommon CrawlWikipediaCodeParrot(3)。你还可以查看用于多模态预训练的 OSCAR 语料库。视觉变换器ViT(4)模型就是从头开始在 ImageNet 上训练的。你有很多选择!你也可以利用所有这些开源数据集来增强你的原始数据集,结合开源和专有选项的最佳部分。

另一个需要记住的事情是,预训练明显受益于未标记数据。最好的预训练项目是在利用大量未标记数据和较少量的标记数据时发生的。这也是为什么预训练基础模型如此流行的原因——世界上大多数数据都没有标记。然而,当我们使用预训练目标时,正如我们在第一章中学到的,我们可以轻松地训练模型来学习这些数据。然后,我们使用监督数据对模型进行微调,通常这些数据量较少。

所以,如果你发现自己处于一个拥有数百 GB 数据的场景中,例如图像、文件、记录、交易、元数据和时间序列数据,那么你可能需要考虑将其作为定制预训练的首选候选。

按行业划分的顶级预训练应用场景

现在,让我们突出展示一些按行业定制预训练基础模型的顶级应用场景。这些是我们世界中,预训练和微调已经在今天产生影响的领域:

  • 软件 和互联网

    • 搜索与发现

    • 生成文档和代码

    • 问答

  • 酒店业 和旅游业

    • 客户支持和服务

    • 预定推荐

  • 消费电子

    • 设计自动化

    • 时尚设计自动化

  • 金融服务

    • 文档总结和生成

    • 多模态预测

  • 媒体 和娱乐

    • 创意增强

    • 加速创意生成(新图像、新电影、更好的艺术品等)

    • 确定最佳创意进入决赛(最佳镜头、最佳镜头序列、最佳旋律等)

  • 医疗保健和 生命科学

    • 蛋白质建模、药物发现和实验优先排序

    • 记录综述和诊断确认

    • 视觉结果确认和实验结果优先排序

    • 科学文献综述和实验设计建议

  • 制造业 和农业

    • 部件缺陷和构建错误检测

    • 部件和产品的整体设计自动化

    • 自主产品设计

  • 公共 部门治理

    • 政策影响分析自动化

    • 政策建议自动化

    • 政治和哲学差异调解

    • 预算影响评估和分析自动化

现在让我们继续看看你的数据集有多不同。

Delta ——你的数据集有多不同?

既然你已经有了对最感兴趣的应用场景的某种理解,并且知道哪些数据集能为你的组织带来最大价值,现在是时候了解你的数据集有多独特了。这一分析很重要,因为它将回答两个问题:

  1. 首先,哪些模型已经可以供你使用,因为它们已经在类似的数据上训练过?

  2. 其次,这些模型的表现如何?

这一见解将开始为你提供一个线索,指引你在最佳情况下能期望在数据集上实现的性能。然后,我们将把这个预期的性能数值重新带入我们整体项目的价值中,确保我们仍然在正确的轨道上。下一章将完全致力于回答这些问题。在这里,我们将学习如何分析你的数据集。这一部分对于那些刚接触数据分析的人来说非常有帮助。

首先,花时间真正分析你正在处理的任何数据集总是一个好主意。无论你是从自己数据库中的定制数据开始,还是使用开源选项,预计至少会花上几个小时来详细了解它。我听过的最能激励这个过程的短语是,一个好的数据科学团队提出的问题比他们回答的问题还要多。这是因为分析数据集的过程是一个动态的过程,而不是一个有限的状态。了解一个数据集有点像了解一个人;只不过你提问和观察的方式完全不同。

从口头描述你的数据集的轮廓开始。它有多少行?有多少列?图像有多大?它有多少个标记?它有哪些特征?这些特征是数值型的还是类别型的?它是基于时间的吗?它有哪些元数据?确保你对这个数据集的样貌有清晰的认知。和你团队中的其他人讨论,直到你感到自信,并能快速回答有关数据集组成的基本问题。使用常见的数据分析技术,如 Jupyter 笔记本,生成总结性统计和图表,并进行探索性数据分析。

关键是要问自己,这个数据集是从哪个现实世界过程中抽取出来的?这个数据集是如何获取的?我们称这为抽样机制。如果您是数据分析新手,尤其是在应用设置中进行数据分析而不是在理论研究中,您首先需要了解的是“并非所有抽样机制都是完美的”。换句话说,您应该习惯于假设您的数据集可能存在问题。您需要批判性地评估数据集的开发方式。它是随机收集的吗?或者所有数据都具有某些潜在的相似性?有任何错误吗?数据分析过程中最重要的部分是消除原始数据本身的任何潜在错误、不一致性、奇怪之处和缺陷。您需要确信数据本身确实是有效且可靠的。为什么?因为这种确定性是您从这些数据集产生的一切内容的基本保证。如果数据不可靠,您的工作永远不可能是可靠的。

当您对数据集有了想法,但在您通过实证观察到的结果证明之前,这被称为假设。假设是您认为可能适用于您的数据集或任何现实世界过程的概念。然而,由于目前缺乏实证证据来验证此假设的确定性,因此您不能断言它在当前时间是客观真实的。这就是为什么我们称其为假设!

科学过程的核心部分,以及作为推论的,您在机器学习中自身的发展,是学会如何清晰地陈述这一假设。您可以将其表述为一个简单的问题,例如“哪种模型最好地解决了这个问题?”,“什么是最优解决这种类型问题的意义?”,或者甚至,“我们如何在这个领域改进现有技术水平?”

一旦您有了假设,也称为研究目标,清晰地表达出来,接下来您需要学习“如何设计实验来回答这个问题”。实验设计是一项令人惊讶地具有挑战性的技能!这包括评估某些领域的当前研究工作,考虑开放性问题和他人展示的结果,并试图从经验上构建。在项目结束时,您希望有明确的经验性结果可以证明您的工作。我们将在关于模型评估的后续章节中进一步讨论这一点,但这是一个需要牢记的关键话题。

接下来,让我们学习如何调整我们的数据集大小。

使用缩放定律来确定您的数据集大小。

到目前为止,您应该已经确定了您的数据集,并对其有了基本的理解,能够描述它们与以前的数据集及您选择的领域中的研究工作的相似之处和不同之处。有几篇论文可以参考会很有帮助,这样在遇到困难时就能派上用场。

在本节中,我们将探讨数据集应该有多大,才能在预训练或微调项目中产生预期的结果,从而清楚地验证你将投入的时间和计算开销。我们还将讨论你希望这个数据集具备的某些特征,比如足够的多样性、质量和没有重复项。下一章的内容将完全专注于选择合适的模型,包括模型的大小和范围,但现在我们将重点讨论数据集。

首先,了解所谓的大模型和小模型之间,以及它们通常运行的数据集大小之间有一个非常大的灰色地带是很有帮助的。在任何情况下,你都不应该认为,只有多达数 TB 和/或 PB 的数据才能考虑预训练,或者认为即使是无法放入单个 GPU 的模型也不值得考虑。你可以通过继续预训练你的模型,而不必从零开始预训练,单凭无监督数据就能产生有意义的结果,并且仍然可以实现你的商业和知识目标。根据你的项目以及它可能的独特性和有趣程度,你完全可以在不到 1 GB 的数据上展示一些有用的工作。因此,不要因为没有大量网络数据而犹豫不决;从你现有的资源开始吧!

接下来,你需要理解一种叫做扩展法则的东西 (6)。这些是关于大模型在不同规模下如何表现的理论和公式,尤其是作为幂律。这些公式本身是通过不同规模的经验行为推导出来的。你可以用它们来确定给定计算预算下,什么样的模型和数据集大小是最优的,反之亦然。在某种程度上,这些法则,以及在Chinchilla中提出的更新版本,与模型架构本身是独立的。这意味着,提高模型准确性的最大方式是扩大规模,而不是改变模型架构本身。Kaplan 最初在语言模型的背景下,明确提出了扩展法则,并利用了变换器模型架构。然而,考虑到这一被验证的假设在 GPT-3 论文中引发了准确度的 10 倍提升,我和许多其他人 (7) 相信,有理由在大语言模型LLMs)之外探索这种基本关系,特别是在视觉和多模态领域。

你可能会想,那又怎样?为什么这会是一个大问题?显然,你会希望在数据集、计算资源和模型之间取得某种平衡,那么,问题出在哪里呢?Kaplan 的研究之所以具有突破性,是因为拥有一个有效的公式来量化最优的计算、数据和模型值,可以让你估算出模型可能达到的损失范围。换句话说,现在我们有了尺度定律,我们可以通过数学推导出在给定范围内,模型训练结束时应该预期的损失是多少。对于那些计算成本可能达到数十万美元,甚至数百万美元的训练任务来说,这种知识极为宝贵。OpenAI 在其 GPT-4 技术报告中验证了这一点,声称能够根据规模变化准确预测其模型的损失。

这为我们开辟了一个新的问题领域。机器学习的其他哪些方面也有经验可观测的定律?除了模型本身的内部运作外,我们还能从物理学中获得哪些灵感,发现依赖于数学关系的公式化模式?这个问题非常重要,因为如今,绝大多数机器学习仍然是试验和错误的过程。我们希望某种方法能奏效,尝试后从实验中学习,然后再采取下一步。然而,我认为尺度定律指向了一个未来,在这个未来中,机器学习将越来越多地通过简单、高效、快速的检查来增强,而不是依赖漫长的计算实验。如果我们这些年来一直在错误地思考这一问题呢?

基础知识——神经语言模型的尺度定律

如果你查看原始论文:《神经语言法则的尺度定律》(Scaling Laws of Neural Language Laws),你会发现有一个核心概念贯穿整个分析——比例性。Kaplan 等人在文中指出,当数据集大小或模型大小发生变化时,伴随其变化的数量也应该成比例变化。换句话说,如果你使用更大的数据集,就应该使用更大的模型,反之亦然。那么,这种关系的强度究竟有多大?是什么描述了它?涉及哪些常数?应该做多大的缩放调整,这些问题恰恰是他们论文的核心内容。

尽管知道关系是成比例的很有帮助,但这仍然不够。Kaplan 等人建议并通过经验发现,神经语言模型的最优尺度遵循幂律。幂律实际上非常简单;归根结底,它们只是关于指数的。如果两个量遵循幂律,你可以假设方程的一侧遵循指数变化:

为了估算基于 Transformer 的训练方案中,早停时的测试损失,考虑到数据集和模型的大小,Kaplan 等人提出了以下建议。

让我们尝试用非常简单的术语来解释——首先是左侧部分:

  • L = 模型在测试集上早停时的最终损失

  • N = 你模型中可训练参数的数量

  • D = 数据集中令牌的大小(对于语言)

现在,你已经理解整个方程是关于计算模型的潜在损失,这样你就可以提前知道了!右侧的其余项是关于如何达到这个目标的。所有这四个项: 都描述了必须从数据集和训练过程中发现的常数。可以把它们看作超参数;我们希望找到一些常数项,用以描述我们的特定数据集和模型。然而,在许多情况下,我们可以直接使用他们工作中呈现的常数。

Kaplan 等人在他们的训练过程中通过拟合损失曲线与其缩放法则函数,发现了每个常数的值。利用他们核心方程的数学扩展,他们能够准确地拟合学习曲线。进行这种拟合帮助他们发现了在其余研究中都非常有用的常数。

在现实世界中,一旦你进行了一些初步的数据分析,并对你需要的特征有了清晰的了解,大多数数据科学团队会立即开始训练你的第一个模型。这是因为机器学习过程通常是迭代的;你会测试多种方法,看看在特定时间点哪些方法最有前景,然后扩大规模并进行评估,接着再尝试。为了更全面地阐述这个主题,我将详细介绍两个可以帮助你改善数据集的关键话题。这些步骤你可能不会在数据科学旅程的最初就实施,但随着时间的推移,你应该不断回顾它们,以提高工作整体质量。第一个是偏差检测与缓解,第二个是数据集增强。

偏差检测与缓解

“偏差”一词的轨迹非常有趣,因为在过去的 15 年里,它已经走完了一圈。最初,偏差无疑是一个统计学术语。正式来说,它意味着样本大小不当,给某些变量赋予了过大的权重。统计学家们开发了许多方法来识别和减少偏差,以正确评估研究,例如公共卫生中的随机对照试验或计量经济学中的政策评估所使用的方法。基本策略包括确保处理组和控制组大致相同大小,并且具有大致相同的特征。如果没有保证这种基本的数学等价性,或者更现实地说,研究团队尽可能接近它,就很难相信研究结果是真正有效的。结果本身会受到偏差的影响,简单地指示基本特征的存在与否,而不是暗示关于治疗本身的任何有意义的信息。

然而,在过去五年里,许多研究已经证明,机器学习模型在特定情境下无法对某些群体的人群做出适当的表现。最严重的例子包括面部识别、图像检测、就业、司法决策等无数案例。大型科技公司首先受到指责,金融机构甚至公共政策组织也纷纷受到波及。这些指控是有根据的。虽然数据集中的偏见一直是机器学习中的一个大问题,但如今它对全球人类生活的影响如此显著,值得进行充分的对话、讨论、解决和监控。如果某个数据集中存在偏见,那么几乎可以肯定它会渗透到模型本身中。模型当然不是客观的;它们实际上是它们所训练的那些数据集的“孩子”。偏见已经走到了一个完整的循环,最初在统计学中出现,与人权相关联,现在推动着机器学习研究。

“偏见”一词现在已经走到了一个完整的循环;最初在统计学中出现,与人权相关联,现在推动着机器 学习研究。

为了开发和尝试部署一个机器学习模型,尤其是一个具有自己预训练机制的大型模型,你需要知道一些事情。首先,最可靠的减少偏见的方法是通过增加或减少数据集中的不同方面。特别是在计算机视觉领域,这一点尤为明显。如果你增加某些群体的图片——例如,非裔美国人——你的模型将能够识别他们。如果没有足够数量的这些图片,你的模型在应用中就无法识别这些群体。

对于自然语言而言,这个问题变得更加具有挑战性。这是因为语言中的大部分数据并没有以性别、种族、宗教和性取向等不同的社会类别进行分类。对于我们关心的、并且知道需要保护的所有这些类别,我们需要引入自己的方法,以便在我们的数据集中识别、比较和综合它们。仅仅做到这一点就已经很难了,正如你可以想象的那样。

识别偏见是你迈向负责任机器学习之旅的第一步。从一开始,你就需要能够回答关于你的数据集的两个关键问题:

  • 首先,我的数据集中目前存在哪些类型的偏见?

  • 其次,这种偏见给我的组织带来了多大的风险?

从对客户的影响角度来思考风险,特别是来自有偏见的机器学习模型的预测。如果你的模型可能会对客户造成伤害,比如拒绝贷款、降低就业申请、推荐有害内容,甚至拒绝保释或其他法律判决,那么毫无疑问,应该把偏见检测和缓解作为你的最高优先事项!

虽然关于负责任的人工智能有各种框架,我喜欢将其归结为四个关键步骤。在训练偏差数据集的机器学习模型中,你的四个关键步骤是预期识别缓解监控

  1. 预期:在选择机器学习项目和数据集时,预期每个数据集的根本上都会有某种偏差。问问自己,我的机器学习模型试图解决什么问题,如果我没有足够的某些类型数据,会遇到哪些问题?

  2. 识别:然后,使用各种技术来识别数据集中存在的偏差。确保从一开始就知道某些组中你是否有某些属性。不断进行这个过程,直到你能够量化出至少几种不同类型的偏差指标。请参见以下提示框,了解如何识别偏差的一些建议。

  3. 缓解:一旦你在数据集中识别出偏差,采取措施来缓解它。增加或减少数据集中的某些方面。使用增强、上采样或下采样以及数据转换来降低偏差指标,直到它们达到一个较低的危险阈值。

  4. 监控:一旦你部署了机器学习模型,冒险仍在继续。你可以使用在步骤 2中采用的相同偏差检测方法来监控你在应用程序中部署的模型。确保你的应用程序和整体系统设计包括统计监控,并为可接受的统计水平设置阈值。当模型开始达到或超过这些阈值时,开始手动审查模型预测并启动你的训练管道。保持人为干预,特别是那些既有知识又有责任心的人,是减少偏见预测风险的最佳方法。

如何进行偏差检测和监控

现在我们知道偏差很重要,那么我们如何在数学上找到它呢?一旦做到了这一点,我们如何缓解并监控它?有很多方法可以做到这一点,我们可以根据它们各自的领域将这些方法进行分类:

表格数据:检测表格数据中的偏差等同于计算一些统计数据。首先,你需要在数据集中有一些真实标签,指示某个组内或组外的状态。值得注意的是,对于许多团队来说,仅此一点就已是一个相当大的问题。然而,针对这一点的合理反应非常简单。预期你的数据会有偏差,无论你是否有一个列标记它为某些组的成员。引入这个标签是识别数据集中固有偏差并最终消除它的唯一方法。否则,尝试使用代理,但这些已知是有缺陷的。

假设你有一个标签,例如性别或种族,那么你就有两种度量标准——预训练和后训练度量。一个简单的预训练统计量是类别不平衡。类别不平衡指的是来自你的优势群体的观测数,减去来自劣势群体的观测数,再除以整体数据集的大小。如果你的类别不平衡过高,那么你的数据集以及随后的模型肯定会存在偏差。

一个常见的后训练度量标准是不平等待遇影响,它的定义非常简单,即在你的劣势群体中预测为正标签的数量,除以在你的优势群体中预测为正标签的数量。直观地说,这衡量了你的模型在不同群体中预测为正的可能性,正如你所想象的,这在某些领域(如就业或法律)是至关重要的。在此,有一些法律先例表明使用 4/5 或 80%作为此处的下限阈值。

视觉与语言:最后,视觉与语言有不同的处理方式。在语言领域,通常会评估语言模型在特定条件下提出某个类别的偏好,例如将“he”或“her”归类于某些就业标准下。

在计算机视觉领域,你可以使用一个预训练的文本分类器来确保数据集在训练前是平衡的。此外,你还可以清楚地指出模型在检测某些类别时的不足表现——例如,在图像识别中的某些群体。

提升你的数据集——多语言、多模态和增强技术

最后,既然你已经学会了如何选择数据集,如何与研究数据集进行比较,如何确定合适的大致大小,以及如何评估偏差,那么我们就可以开始提升数据集了。特别是,我们将关注几个维度——多语言多模态增强技术。这三者通常会在你的机器学习项目的稍后阶段出现,特别是在模型的前几个版本训练完成后,你会寻找下一个能够给你带来提升的思路。

个人而言,我认为在世界上很少有应用场景是多语言不是一个强有力的附加价值的。多语言仅仅意味着多种语言。尽管许多最先进的语言模型最初是基于仅英文文本进行训练的,但近年来研究人员已在大力提升这些语料库的语言多样性。这意味着他们正在为许多语言增加支持。2022 年,Hugging Face 发起了一项全球性的大规模努力,旨在民主化大语言模型的创建,称其项目为Big Science (8)。这促成了一个新模型的创建,命名为BigScience 开放科学开放访问多语言语言模型BLOOM)。Hugging Face 希望在多语言应用场景中,尤其是在零样本语言翻译等任务上,能改进现有技术。然而,该模型在许多情况下表现不如 GPT-3,这让我们认为最优秀的模型可能还是仅限于单一语言。

坦率地说,多语种化就是好的商业。对于你开发的任何产品,运行的任何程序,以及提供的任何服务,最终,你在与潜在消费者互动时都受到语言的限制。将语言视为一个市场。在你开发产品时,你希望将其推向尽可能多的市场。最终,这意味着尽可能多的语言。因此,我对行业能够找到更好的方法,将多种语言融入到可能是同一个模型中,而不导致结果恶化感到乐观。也许这仅仅是像链式思维或指令调整那样适当格式化数据集的问题。

简而言之,让我们探讨一下增加其他模态的问题。简单来说,这意味着不同类型的数据集,例如将视觉与文本结合,或者反过来。我在第一章的结尾部分更详细地介绍了这一概念。在这里,我只是想指出,如果你的文本中有图片,或者你的图片中有文本,尽量加以利用。一旦你投入到一个项目中,花费了大量时间分析数据、训练、评估模型、部署模型等,为什么不再进一步探索增加其他模态呢?特别是当它有提升准确性的潜力时,确实如此。从模型的角度来看,另一种模态仅仅是另一种嵌入类型。你最可能需要使用一些其他地方预训练的模型,将原始图像转换成嵌入——也就是说,在将其作为模型的另一个输入之前。

这里有一些权衡;增加模型的大小会增加其运行时间。增加数据集的大小也会增加数据转换的成本。增加数据转换的步骤使得托管变得更复杂,这意味着你可能需要重新考虑系统设计,以便部署你的模型。所有这些权衡都是值得讨论的,最终,你需要优先考虑那些为你的团队和客户带来最大价值的项目,而这其中可能非常包含仅限语言的模型。

我对多模态项目一般来说持乐观态度,而不是仅限语言的项目的另一个原因是,视觉领域对人类传达了如此多的信息。人类在学会说话之前学会了看东西,我们的许多经验和知识都是通过视觉收集的。基于这个原因,我相信基础模型将继续朝着联合视觉与语言任务的方向收敛。

最后,数据增强是一个简单易行的步骤,可以提高模型的准确性,而不需要额外付出大量工作。其核心思想是向你的数据集中添加一定程度的多样性和对提供样本的轻微变化,这将帮助模型学习信号和噪声之间的区别。无论是文本还是视觉,都有经过验证的增强方法。在视觉方面,这通常仅仅是像素操作、轻微的颜色变化或图像旋转。

对于文本来说,这可能是替换同义词、句子层面的重构或轻微的标点修改。关键是你不想改变你正在尝试学习的基本机制。如果你在训练一个图像检测模型,就不要修改任何图像,以免无法检测到它们。如果你在训练一个文本分类器,也不要修改文本到它变成一个不同的类别。

在大规模预训练中,数据增强通常不是一个问题,因为大多数数据集非常庞大,已经包含了足够的噪声和变化。然而,这似乎是一个特别有前景的偏差减少途径。预训练的另一个关键技术是减少重复文本。这在网络数据中尤为重要,因为表情包、评论和讨论线程很容易在平台和用户之间反复出现同一段文本。

现在你已经了解了数据准备的早期阶段,让我们在继续准备模型之前,快速回顾一下你刚刚学到的内容!

总结

本章介绍了各种基础模型的使用案例,包括你可以微调现有基础模型的场景以及预训练本身具有竞争力的场景。我们提供了一个简单的经济学框架,帮助你为预训练项目提供依据,特别是通过将其与你预计基于更准确的模型,业务将如何增长相联系。之后,我们讨论了评估你的数据集,将其与研究数据集进行比较,并学习如何批判性地思考其采样机制。我们提出了一些基本的想法,用于将这种批判性思维应用于实验框架的设定,这将在下一章继续讨论。我们了解了扩展法则,并提供了一个开源笔记本,你可以用来找到在固定模型和计算预算下,哪个数据集大小能帮助你达到预期的性能水平。我们还讨论了如何检测和减轻数据集中的偏差,并通过增强、模态和语言进行改善。

接下来是模型准备!

参考文献

请阅读以下内容,了解本章中涉及的一些主题:

  1. Papers With Code: paperswithcode.com/datasets.

  2. Hugging Face Hub: huggingface.co/datasets

  3. Hugging Facehuggingface.co/datasets?task_ids=task_ids:language-modeling&sort=downloads

  4. 一张图胜过 16x16 个词:用于图像识别的变换器模型(Transformer)arxiv.org/pdf/2010.11929.pdf

  5. 神经语言模型的扩展法则:arxiv.org/pdf/2001.08361.pdf

  6. 训练计算最优的大型语言模型:arxiv.org/pdf/2203.15556.pdf

  7. BigScience 第五集 – 创建大型语言模型的挑战与视角bigscience.huggingface.co/acl-2022

第三章:模型准备

在本章中,你将学习如何决定哪个模型最适合作为你预训练方案的基础。你将学会如何考虑模型的参数大小,以及关键的损失函数和它们如何在生产中决定性能。最后,你将结合缩放法则和数据集的预期大小,选择模型的上限和下限大小,以指导你的实验。

在本章中,我们将涵盖以下主题:

  • 寻找最佳基础模型

  • 寻找你的预训练损失函数

  • 解决模型大小问题

  • 规划未来的实验

寻找最佳基础模型

到了本书的这一部分,你应该已经学会了如何选择使用场景,如何找到数据集,以及如何将其与研究数据集进行对比。你特别应该已经学会了如何将这个数据集与开源社区中可用的数据集进行对比。接下来是有趣的部分:选择你的模型!

很可能,你已经心中有几个候选模型。如果你在处理自然语言,可能会考虑生成预训练变换器GPT)系列中的某个模型用于生成任务,BERT 用于分类任务,或者 T5 用于类似翻译的任务。如果是视觉任务,你可能会选择 CoCa (1)、CLIP (2),或者联合掩码的视觉和语言模型 (3)。对于多模态数据集,你可以选择直接来自视觉领域的模型,或者根据具体的使用场景选择一个更独特的模型。

第一章《预训练基础模型介绍》中,我们简要介绍了这些最先进的模型,并深入探讨了它们背后的核心基于变换器的神经网络架构。让我们简要回顾一下这些模型,并强调它们为何重要:

  • 编码器。广义上讲,编码器架构接受较长的输入,比如一长句子或长嵌入,并将其压缩成更紧凑的表示。一个编码器可能会接收一个长度为 500 的输入,通过一系列神经网络,将其压缩成一个长度为 50 的输出。编码器模型通过 BERT 及其后续系列(包括 DeBERTa、RoBERTa、XLM、AlBERT 等)得到了广泛应用。如果你感兴趣,DeBERTa 在这里被提到,因为尽管它采用了更新的注意力机制,使用了一个解耦目标函数并结合了新颖的增强掩码解码器,但它仍然普遍适用于分类任务。

重要提示

如果你希望保持模型较小,并且确信不需要任何生成能力,那么可以选择仅包含编码器的模型架构。这意味着你应该计划不使用此模型进行文本生成、零样本性能、摘要生成以及问答的最后步骤。

  • 解码器:解码器模型架构正好与编码器相反。它接收密集输入,例如长度为 50 的输入,并利用可学习的前馈网络将其重新组合成更大的空间,例如长度为 250 的输出。我们将在本章稍后深入探讨这一过程的细节(提示:这一切都与预训练损失函数有关)。解码器单一模型首次进入全球舞台是通过 GPT-4 模型(4),如今像 OPT 和 BLOOM 这样的开源选项也已问世。

如果你想专注于模型的生成能力,可以选择解码器单一模型(即扩散模型)。如果你需要强大的总结能力、生成能力或生成高质量图像的能力,解码器单一模型是最佳选择。

  • 扩散模型:如果你想预训练一个图像生成模型,例如 DALL-E 2(5)、Imagen(6)、Flamingo(7)和 Stable Diffusion,那么你需要使用扩散模型。扩散模型是一些非常有趣的训练系统,它们通过使用多个预训练模型来嵌入联合的视觉和语言对。最终,通过 U-Net 将它们连接起来,U-Net 在训练过程中逐步加入噪声,然后再去除噪声。模型通过将生成的图像与给定的描述进行对比,学习如何生成图像,并根据图像与描述的差距来更新模型权重。

  • 组合编码器-解码器模型:当前最常见的编码器和解码器混合使用的神经网络应用场景是翻译。这个类别的模型因 T5(8)而闻名,它能够在大规模的情况下处理一种语言的字符串与另一种语言的翻译对。T5 之后发展成了 BART、FLAN-T5、M2M、MBart、BigBird 等模型。

当你确信翻译是你使用场景的核心时,选择一个组合编码器-解码器模型。这可能适用于从提示中写代码、总结文档或转移风格等场景。

现在,想一想,你需要哪一种模型?希望此时你已经能够确定其中一个主要类别。

从最小的基础模型开始。

在本章中,我们将学习如何使用扩展法则来解决模型的大小问题。然而,在此时,引入基础模型的概念是有帮助的。基础模型通常是可用模型中最小的版本。例如,你可以在 Hugging Face Hub 或与论文相关的 GitHub 网站上找到这些模型。基础模型通常包含几亿个参数,因此它们适合放在单个 GPU 上。它们不占用太多 GPU 内存,在大多数环境中也可以很好地存储在磁盘上。基础模型在生产中运行非常快,因为神经网络的实际大小较小,计算可以更快地完成,数据也需要经过较少的层才能输出最终结果。所有这些好处意味着,将基础模型投入生产并在整个管道中使用它要比使用更大的模型容易得多。因此,在与客户合作时,我强烈建议从你能找到的最小模型开始实验,只有在该模型不再提供你需要的效果时,再逐步增大模型的规模。

在本章后面,我们将讨论何时、何地以及如何设计包含更大模型的实验。在第十四章中,我们将学习如何通过 MLOps 管道将这些实验付诸实践!

权衡 —— 简单与复杂

在应用机器学习时,一个有帮助的方面是考虑这个简单的维度:简单与复杂。一个简单的模型可能更小,可能包含更少的创新操作。它在 Hugging Face Hub 上的描述可能字面上更短。它可能有更少的 GitHub 问题,但可能有更多相关的论文。从一个简单的工件开始是为你的团队提供健康开端的好方法。你希望在项目初期获得成功,而不是在启动时就遇到困难。一个简单的项目,例如在几 GB 数据上对 BERT 进行微调,可能是一个不错的选择。当你在实际用例上测试完后,并且有更多的无监督数据时,你可以简单地尝试继续在这个无监督数据集上进行预训练。

重要说明

从一个简单的工件开始是为你的团队提供健康开端的好方法。你希望在项目初期获得成功,而不是在启动时就遇到困难。

另一方面,复杂性可能会提升模型性能,超越简单模型所能达到的水平。这包括模型、数据集和计算规模的扩展,以及在预处理、训练和部署管道中融入多个模型。

正如我们在本书中所看到的,仅仅依靠规模对许多用例来说是一种有前景的策略。然而,在微调章节中,我们将探讨如何通过指令微调、思维链微调以及带有人工反馈的强化学习等技术,在不必扩大参数规模的情况下提高模型性能。这些都是有前景的趋势!

权衡——应用于许多用例与仅限于单一用例

在设计整体解决方案或产品时,另一个关键方面是你扩展到尽可能多用例的能力。这符合最大化投资回报的基本经济学原则。在这个项目中,你将有两个重要的投资:

  • 你的时间

  • 你的计算成本,我们将在接下来的关于 GPU 的章节中深入探讨。

这两者都是你所在组织的资源分配,用于产生某些输出,或者在这种情况下,生成一个模型。这个模型能够解决的每一个用例都是你项目创造价值的潜在路径。每次你对这个模型进行微调,将其部署到生产中用于应用,或用它进行下游分析,或者将其集成到演示或报告中时,你就为你的组织创造了从对项目投资中获取价值的途径。当你的项目能够解决尽可能多的用例时,你就为成功打下了基础。

在预训练和微调的情况下,这是一个容易解决的问题。首先,看看你组织中已经部署了多少模型。如果这些是基于变换器的模型,那么它们很可能是从某些开源模型中微调出来的产物。将这些开源模型视为你的目标范围。你的团队使用 BERT 吗?RoBERTa?GPT-2?选择覆盖尽可能多下游任务的模型。

另外,如果这些用例具有极高的价值,你可以考虑解决数量更少的用例。搜索就是一个很好的例子。从电子商务到酒店业,从客户服务到产品交付,当搜索引擎获得大量流量时,它很可能是一个高价值的业务。搜索是大型预训练模型的顶级应用,特别适用于那些希望利用前沿技术产生最大影响的新项目。

寻找最佳基础模型的战术方法

实际上,这是我思考如何找到最佳基础模型的方式。首先,像在第二章中做的那样,列出你希望模型解决的关键用例。查看模型排行榜,比如我们在第一章中讨论过的排行榜,看看哪些模型似乎始终排在前列。考虑这些模型的基础架构,并将其与您的顶级用例进行比较。如果你找到一个最近的模型,且它有开源代码样本和模型权重,并且看起来与您正在探索的用例匹配良好,那么我建议从这个模型开始。

如果你想挑战自己,试着重新设想模型的低层次方面作为改进的方向。这可能是对神经网络的更新,或者是这些网络的组合,甚至是可能改善整体目标的自定义操作符。记住,你要把准确性和效率作为关键指标!

一旦你确定了最适合的基础模型或想要考虑的一组顶级模型,就该深入探讨这个模型的一个关键要素,它决定了模型的学习能力:预训练损失函数。

找到你的预训练损失函数

我们在第一章中介绍了这个话题,作为预训练目标,或者在视觉领域中作为前置任务。记住,这些本质上是不同的词语,但指的是同一件事:你的模型在执行自监督学习时会优化的数学量。这很有价值,因为它使你能够接触到大量的无监督数据,而这些数据通常比有监督数据更容易获得。通常,这个预训练函数会注入某种噪声,然后尝试从虚假数据中学习真实数据的模式(如 GPT 的因果语言建模)。一些函数会注入掩码并学习如何预测被掩盖的词(如 BERT 的掩码语言建模)。还有一些会用合理的替代词替换某些词,从而减少所需数据集的总体大小(如 DeBERTa 的标记检测)。

重要提示

当我们预训练我们的模型时,我们使用一个预训练损失函数来赋予模型识别数据集各个方面的能力,最终从虚假中预测出真实。

那么,为什么这么重要呢?为什么我们如此关心预训练目标?它将如何影响你的项目?你应该关心预训练损失函数的原因是,它是决定你的模型可以在哪里使用以及其表现如何的主要因素。在前一节中,我们将某些类型的模型架构(编码器、解码器和混合架构)映射到不同的机器学习用例(分类、生成和翻译)。这种映射存在的真正原因就是因为预训练损失函数!

考虑仅解码器模型,尤其是 GPT-3 和类似的候选模型。这里的预训练函数被称为因果,因为它是从左到右工作的。预训练函数会从一个基础文本字符串开始,比如半句话,然后使用解码器尝试生成剩余的句子。通常,你会将这个与目标度量(比如困惑度)配对,来考虑你生成的字符串与根文本的接近程度。随着训练的继续,神经网络会优化困惑度度量,通过调整权重使得总体损失减少,一步步提高模型的性能。

有趣的是,鉴于基于 GPT 的模型近期表现出色,我们开始看到它们在各种使用场景中得到应用,并且具备零样本性能。这意味着一旦你大规模训练了 GPT 模型,你就可以将其用于无须提供前置示例的提示场景,完成分类、实体抽取、情感分析、问答等任务。虽然从严格意义上说,你仍然是在进行文本生成,但这种方式的使用可以解决的不仅仅是开放性内容生成问题。

接下来,让我们看看在视觉、语言和多模态场景中,不同模型的预训练损失函数。

视觉中的预训练损失函数——ViT 与 CoCa

我们已经学习了很多关于核心的变换器模型架构的知识,现在你应该对这种模型在自然语言处理中的工作方式有所了解。但计算机视觉呢?视觉变换器(9)朝这个方向迈出了重要一步,弥合了自然语言处理(NLP)中的进展,并将这些成果带给了视觉社区。特别地,视觉变换器(ViT)展示了完全可以从模型中去除卷积操作。一个预训练的 ViT 减少了训练下游模型所需的整体计算资源,并且这些模型的表现与当时顶级的基于卷积的方法相媲美。

当然,卷积神经网络(CNN)今天仍然在使用,且在许多场景下,它们的表现明显优于 ViT。CNN 的核心优势在于它能够很好地保持图像的视觉结构。卷积操作的核心过程是将图像的所有像素从左到右、从上到下地渲染为密集的表示。这种方法的一个好处是归纳偏差,即模型在训练过程中对像素之间的相互关系产生的学习偏好。这是 CNN 能够学习视觉的核心原因。ViT 没有这种能力,而是将像素当作令牌进行处理。由于其核心的自注意力机制,ViT 在扩展性方面提供了一些优势,但在较小的数据集和模型中,CNN 可能更为常见。近期的研究(5)已经开始弥补 ViT 的这一缺陷,为它们引入了归纳偏差。

那么它是如何工作的呢?通过一个编码器!这个解决方案从一种基本的数据处理技术开始,它将输入展平。将二维图像取出,简单地重塑成一个展平的二维补丁序列。接着,编码器应用线性投影过程,将图像的所有部分合并成一个单独的行,并包括位置信息,这样内容的位置仍然能为模型所知。这个单独的行被送入变换器编码器,而变换器编码器本身使用自注意力过程。编码器不断缩小行的大小,直到最终得到标签行。然后,模型从可用的类别中选择一个。最后,损失函数与实际标签相结合,提供了一个可学习的信号,供模型更新其权重并在下一轮训练中提高准确性。让我们来看一下这个过程。

图 3.1 – ViT

图 3.1 – ViT

值得注意的是,ViT 仍然是一个有效的监督学习过程。显然,这里的学习方法依赖于事先已知的标签。这与语言领域中的预训练方式有很大不同,因为语言中的标签通常是未知的。但这种基础的视觉迁移仍然能提升下游模型的准确性,因此值得评估。虽然有一些项目(10)尝试在视觉中实现真正的无监督方法,但个人而言,我尚未见过在视觉领域中严格优于监督方法的情况。也许这就是两个领域之间的核心区别。也许下个月我会被证明是错的。

另一个在视觉领域至关重要的预训练损失函数是对比损失。我们在第一章中提到过这个概念,但现在我想带你深入了解。我们将重点介绍一个使用此方法的模型:CoCA。有趣的是,作者尝试将我们迄今为止提到的三种模型架构统一起来:仅编码器、仅解码器和混合编码器-解码器。经过训练的模型能够解决视觉识别、视觉-语言对齐、图像描述、端到端微调、冻结特征评估以及零-shot 迁移等用例(稍后书中会详细讨论零-shot)。事实上,CoCA 使用了两种预训练目标:一个用于处理图像,另一个用于处理文本。让我们来详细了解一下!

工作流程中的图像部分与 ViT 类似;它先取一张图像,应用展平过程,然后将其输入到编码器中。事实上,CoCA 的基础实现默认使用 ViT!然而,它并不是直接在编码器的输出端产生分类结果,而是将这些密集数组以两种方式使用:

  • 首先,作为最终解码器的输入

  • 其次,作为中间 损失函数的输入

这被称为对比损失,因为它有效地将视觉内容与文本内容进行对比。最终的输出随后应用标注损失,提高模型在最后阶段为提供的图像进行标签或标注时生成文本的准确性。这就是为什么这个模型被命名为 CoCa:对比标注生成器。

图 3.2 – 对比损失与标注损失

图 3.2 – 对比损失与标注损失

在工作流的语言部分,我们看到一个解码器。解码器接收提供的文本输入,例如图像的原始标注。然后,它应用另一个扁平化过程,将单词进行分词和嵌入,为解码器做准备。接着,解码器将单词的维度降到更低,输出一个更密集的标注表示。然后,这个表示被作为输入提供给对比损失函数,从而更好地实现图像与文本之间的联合比较。

这是 CoCa 的加权损失函数:

  • = CoCa 的整体损失

  • = 对比损失

  • = 标注损失

  • = 用于加权对比损失的超参数

  • = 用于加权标注损失的超参数

最后,整个模型使用这两种损失函数的加权组合作为全局损失函数。你可能会问,他们是如何确定这些权重的?通过实验!这些实验几乎肯定依赖于数据集和任务。如果你使用 CoCa 来解决一个视觉数据极其丰富但语言数据非常薄弱的使用场景,你可能会考虑从较高的对比损失权重开始。然而,如果你的语言数据一开始就非常优秀,而视觉数据只有轻微的信息量,你可能会从较高的标注损失权重开始。

通过这种方式,你可以开始理解我们是如何为模型选择超参数的。这是后续章节的内容,所以现在,我希望你能培养一种直觉,即每个模型的具体实现可以根据你的数据集和使用场景高度个性化。阅读这些论文并了解这些最先进的模型如何工作是一个有助于你加深自己分析和理解的步骤。你可以并且应该把这些知识应用到你的工作中去获取更多收益!

语言中的预训练损失函数 – Alexa 教师模型

在这一点上,你应该已经对我们讨论过的掩码语言建模感到相当熟悉,尤其是它如何在语言中实现仅编码器的模型,如 BERT。你还应该了解因果语言建模,它使得像 GPT 这样的仅解码器模型成为可能。现在,让我们看看当我们将两者结合时会发生什么!

Alexa 教师模型(11)就在我写这段文字的几周前发布,作为一名亚马逊员工,我可以告诉你,看到自己公司推出一个大型语言模型的感觉真好!但这并不是我在这里提到它的唯一原因。我认为你应该了解Alexa 教师 模型AlexaTM)有两个原因:

  • 首先,它使用一个叫做少量学习(few-shot learning)的概念,轻松地将关于人类语言交流的知识从一种语言转移到另一种语言。正如我们在第十三章的提示工程中将要学习的那样,少量学习意味着你给模型提供一些推理的示例。这些少量示例能帮助模型更准确地回应。这对于语言来说尤其有用,因为它允许语言研究人员为低资源语言开发解决方案,从而为相关社区引入一些数字技术。

  • 其次,使用这种少量学习方法,一个拥有 200 亿参数的 AlexaTM 模型在同样的问题上,能够超越一个 540 亿参数的 27 倍大模型 PaLM (12)。这是一个至关重要的时刻,我希望我们在未来几年能看到这种趋势。虽然在机器学习模型中,规模更大有时意味着更好,但并不总是如此,有时甚至可能更差。记住,较小的模型训练速度更快,使用起来更简便,推理速度也更快,所以如果准确性相同或更好,总是选择小模型。

那么,它是如何工作的呢?类似于 CoCa 示例,我们现在追踪了两个损失函数。第一个你已经熟悉:因果语言建模,简称CLM。在这里,CLM 过程尝试预测一句话的结尾。现在,AlexaTM 20B 将其与去噪损失函数结合在一起。去噪过程在 BART (13) 中被引入,作为一种在编码器和解码器的组合上进行联合学习的方法,特别是通过引入噪声。给定的文档通过编码器故意被破坏,加入掩码。然后,解码器被要求预测文档是否是原始的。实际上,加入噪声然后尝试区分噪声与真实信息的过程,和对抗学习有些相似。

图 3.3 – Alexa 教师模型

图 3.3 – Alexa 教师模型

有趣的是,AlexaTM 20B 只在20%的时间内使用 CLM 预训练目标。这是为了引入模型在少量样本情况下表现良好的能力。在这段时间里,模型完全不产生噪声;它只是尝试完成句子。这通过提供一个信号来表示,信号出现在 20%的句子的开头[CLM]。作者还随机向模型输入了 20%和 80%的文档,以确保它在短文本和长文本的情况下都能表现良好。为了快速启动训练,他们还从一个 10B 预训练编码器开始,并在达到 100,000 步后解冻。整个过程在 128 个 A100 GPU(NVIDIA 硬件)上进行了 120 天,这相当于在 Amazon SageMaker 分布式训练中使用 16 个ml.p4d.24xlarge实例。更多关于 SageMaker 训练的内容将会介绍!

供你参考,AlexaTM 中的“教师”指的是一种称为蒸馏的过程。蒸馏是另一种传递知识的方式,可以与微调相媲美。在微调中,我们将额外的层附加到较大的基础模型上,然后通常在一个较小的有监督数据集上运行它。在蒸馏中,我们将一个较大的“教师”模型与一个较小的“学生”模型配对。然后,学生模型被训练以生成与教师模型相同的概率分布,但计算成本要低得多。第十章全部讲述了微调模型的方法,并附有代码示例。

改变你的预训练损失函数

现在我们已经调查了在视觉、语言和多模态场景中一些最顶尖的预训练损失函数,你可能会想:就这些吗?我该如何使用这些信息呢?

这个问题的答案很大程度上取决于你在机器学习领域的经验年限。如果你刚开始入门,那么你当然不需要过分关注项目中的这一方面。只需选择最适合的模型,理解它是如何学习的,然后继续推进你的项目。然而,随着经验的增加,你可能开始想要尝试调整预训练损失函数,这很好!随着你在机器学习方面的成长,特别是作为开发者或科学家,回馈社区自己独特的创意是非常有价值的。在整个建模过程中,发明新的预训练损失函数或其他任何新的优化方法,不仅极具价值,而且令人满足。在这一过程中,你可以真正为某个领域设立新的技术标准,甚至可能是你自己发明的新领域!

解决你的模型大小问题

现在你已经选择了最佳的基础模型,并理解了它的预训练机制,同时在上一章中识别了你的数据集及其整体大小,接下来让我们开始了解你可以瞄准的模型大小!

你可能还记得,在第一章中,我们介绍了一个核心概念——规模法则。这个大胆的观点是由 Kaplan 等人在 2020 年提出的,建议了计算训练集群的整体规模、数据集和模型之间的正式关系。在 Kaplan 之前,大多数机器学习从业者已经理解到这三者之间存在某种一般关系,但他的团队勇敢地通过幂律的实证研究来证明了这一点。

你需要理解的基本内容可以通过一个简单的图示来展示。为了更好地训练你的模型,无论是在实现最高准确度方面,还是在充分利用你整体计算预算方面,考虑以下关键项作为一个基本关系是很有帮助的。

就个人而言,我发现以视觉化的方式来考虑这一点是非常有帮助的。你的模型学习任何关于真实世界的知识,根本的方式是通过数据集本身。自然地,你可以看到,随着模型的规模增加,你希望数据集在某种程度上也要增大。随着数据集的增加,模型也应该在一定程度上增大。

图 3.4 – 机器学习的相互关系

图 3.4 – 机器学习的相互关系

你甚至可以从人类学习的角度来思考这一点。当我们获得更多经验、更多知识、更多理解时,我们的大脑实际上会构建新的路径,以解读、存储和从这些经验中学习。你拥有的新的经历越多,解决的问题越多,你的大脑就会越进化,存储所需的信息。反之,当我们的经历和新挑战减少时,我们的大脑会失去一定的弹性,无法作出相应的反应。这就是生物优化的一个例子!

完成这个类比,我们的生活经验就像是一个数据集。每一个新的挑战、新的关系、新的经历和新的问题就像是往数据集中添加额外的记录和方面。类似地,我们的大脑就像是一个模型。我们的身体自然地处理在大脑中建立和释放路径的过程,这个过程是动态的,依据我们最新的经历。作为计算机科学家,我们所要做的就是通过一种叫做训练的过程,用代码来复制这一过程。

在跨视觉、语言和多模态场景的预训练方面,请知道这种关系仍然适用。如果你将一个大型、复杂的模型与一个小数据集配对,很可能会出现过拟合的情况。过拟合意味着你可能在训练集上获得极高的准确率,但完全无法进行良好的泛化,也无法在训练过程之外提供有意义的结果。另一方面,如果你将一个小型模型与一个极大的数据集配对,你很可能会出现欠拟合。这意味着你可能在训练集上表现不佳,更不用说在其他地方了。

将计算与模型和数据集大小相匹配完全是关于成本优化的问题。横向扩展存在固有的权衡,这意味着向你的集群中添加更多计算资源。这与纵向扩展不同,后者意味着将实例升级到更大和更新的版本。大多数团队会在尽量用尽可能多的机器来降低运行时间与尽量少用机器但需要多天、数周甚至数月才能完成训练之间找到一个自然的平衡。你需要在这两者之间找到一个合适的中间地带。我们将在第五章中深入探讨这些话题,包括核心的分布式方法,如模型并行和数据并行,分布式基础

案例研究——亚马逊搜索通过分布式训练将运行时间缩短七倍

寻找速度与每小时成本之间自然平衡的一个很好的例子是亚马逊搜索!搜索团队,正如你所料,负责帮助你在amazon.com上找到你最感兴趣的产品。每次你在亚马逊上寻找某样东西时,查询都会通过我们的搜索引擎,精确找到你正在寻找的内容。

科学家和开发者重视快速迭代的能力。他们喜欢尽快测试想法,快速获得反馈,然后迅速进入下一个版本。这使他们能够优化,或者简单地快速改进他们的想法。保持实验的灵活性有助于降低研发的整体成本,因为它减少了从初步产品构思到全面发布所需的时间。

在亚马逊,SageMaker 与搜索团队合作,推出了对 PyTorch Lightning 的原生支持,并优化了节点间通信项目——分布式数据并行。因此,搜索团队能够将训练从 1 个节点扩展到 8 个节点,将整体训练时间从 99 分钟缩短到 13.5 分钟!

他们并没有改变模型大小或数据集,保持这两者不变,只是加入了数据并行策略,复制模型并将数据分发到所有加速器(GPU)。这使他们能够进行横向扩展,向集群中添加额外节点,从而减少了整体作业时间。

我们将在后续章节中深入探讨这些分布式概念,但现在,只需知道,当你使用分布式策略并在集群中增加额外节点时,你可以缩短训练模型所需的时间

解决模型大小问题的实际方法

现在你已经对数据、模型和计算资源之间的关系有了较好的理解,我们来深入探讨如何确定适合你的配置!

大多数团队会把计算预算视为固定的。把这个数字看作你应该计划向高级领导层申请批准的项目预算。正如我们在第二章中学到的,你应该将这个数字视为你业务中增加的准确度所带来的整体价值的某一部分。

第二个真正的瓶颈是你的数据集大小。弄清楚你的候选数据集有多大。在视觉任务中,你可能是在计算图像数量;在语言任务中,你可能是在计算标记数量。我仍然喜欢以 GB 为基准,因为它容易理解且可以跨领域转化。一般来说,一个好的起点是找到你受到启发的模型和论文,深入研究它们,了解它们的数据集有多大,并以此作为你的基准。这些大小范围通常从几十 GB 到几个 PB 不等。对于那些刚接触机器学习的人来说,这是一个很好的起点。遵循已经验证过的专家经验路径是开始成功项目的好方法。然而,对于那些不新手的人,我们快速看一下如何利用缩放法则来计算最佳模型大小。

不是所有的缩放法则都一样

首先,了解一下,虽然模型、数据和计算大小之间的关系在直觉上是可以理解的,但精确的数学公式实际上可能会有很大差异。正如我们在第二章中学到的,Kaplan 使用了数学术语!,这表示两个量是“成比例”的。换句话说,当两个项被比例符号等号连接时,我们知道这两个量是相关的,但我们并不知道确切的常数项来支配这个关系。

这就是大型深度学习模型的情况。不同的论文和研究团队在这方面有各自的偏好,例如 Kaplan 倾向于保持模型规模较大,而数据集相对较小,而 Hoffman 则建议两者都要增加。Kaplan 最初提出自回归模型,或者基于解码器的模型,作为最样本高效的模型。然而,AlexaTM 项目表明,联合编码器和解码器实际上可能更高效。所有这些都说明,尽管缩放法则可以建议最佳的模型设置,结果会有所不同。

接下来,让我们尝试定义你想在实验中构建的模型大小的下限和上限。

规划未来的实验

既然你已经对在计算预算和数据限制下想要针对的模型大小有所了解,让我们来学习如何将每一次作业的执行视为一次实验。从根本上讲,机器学习过程中的每个阶段都可以看作是一次独特的实验。你在项目中某些阶段的输入保持不变;这些可以称为你的因变量。而有些输入会发生变化;这些则是你的自变量。在项目中积累技能需要时间,简单来说,改变某些东西并观察结果。只需确保你只改变一项内容,这样结果才会有实证依据!

关键是要明白,你整个项目的范围不会一蹴而就。很多时候,这是因为在项目中积累技能需要时间。即使你从一支经验丰富的团队开始,坦率来说,这种情况非常少见,机器学习的生态系统本身变化如此之快,以至于每隔几个月,你就会学习到一些新的内容。因此,计划为学习所有最新发布的内容预留额外的时间。

一开始,尽量从最小的实验开始。让你的模型的最小版本在本地 IDE 上运行。根据模型的大小和你需要的硬件,你可以选择多种计算选项,从 Jupyter notebooks 和更强大的选项,到你的笔记本电脑、免费的计算实验环境等。在 AWS 上,我们通过我们的完全托管机器学习服务 Amazon SageMaker 提供了各种这些选项。

在对数据集的一小部分展示出有趣的结果之后,我喜欢直接进入远程 SageMaker 训练任务。你将在下一章中了解更多关于 SageMaker 上的训练,但现在我只想让你知道,你可以轻松且无缝地根据需求在 Amazon SageMaker 上扩展和缩减训练工作量。本书中所有的实践指南将聚焦于如何高效地实现这一点。在你的项目中,你可以考虑在 SageMaker Training API 上工作,直到成功运行作业。我会坚持做这项工作,直到你在一台拥有多个 GPU 的单实例上运行:我常用的是 g 系列,配备四个 GPU。这个可以是 ml.g4dn.12xlarge,也可以是 ml.g5.12xlarge。接下来的章节会详细说明这些配置!使用多个 GPU 将需要数据和/或模型并行化策略,这一部分内容会在 第五章中讲解。

一旦你成功地在 SageMaker 远程训练和多个 GPU 上运行,那么就该提高一切了。增加数据的规模。记住,模型、数据、计算能力以及关键超参数(如学习率和批量大小)和模型架构本身是相互关联的。找到合适的设置是第七章的全部内容。

一旦你开始增加,额外的复杂性就会出现。你需要确保你的损失足够减少,但同时也要保持 GPU 的高利用率。你想调试和改进工作中的运算符和通信,但也需要评估训练吞吐量。当你的工作出现故障时,几乎可以确定它会发生,你希望尽快将其恢复,但也要确保准确性。

深入这些细节,解构它们,帮助你让项目重新回到正轨,避免尽可能多的障碍并利用已知问题的机会,正是第三部分的重点。

简而言之,预训练大模型有许多不同的离散阶段。整本书的目标是帮助你安全地应对这些阶段。在下一章,我们将深入探讨 GPU 本身,揭示如何最佳利用这些高效的处理器,也被称为加速器

总结

在本章中,你学习了如何找到最佳的基础模型,包括架构基础、最常见的使用案例和模态,同时你获得了从最小模型开始的一般指导。你了解了关键的权衡,比如简单与复杂的平衡,以及多种使用案例与单一使用案例的应用。你收到了关于如何找到支持良好的基础模型的策略性指导。你学习了如何找到预训练损失函数,包括掩蔽语言建模、因果语言建模,以及在视觉模型中常见的如 ViT 和 CoCa 等模型。我们探讨了 Alexa 教师模型,并了解了如何通过扩展法则计算我们的模型规模,结合亚马逊搜索的案例研究。

下一步:与加速器一起工作!

参考文献

请阅读以下内容以获取更多本章涉及的部分主题的信息:

  1. CoCa: 对比性字幕生成器是图像-文本基础模型: arxiv.org/abs/2205.01917

  2. CLIP: 连接文本和 图像: openai.com/blog/clip/

  3. 面向多模态表示学习的遮罩视觉与语言建模: arxiv.org/pdf/2208.02131.pdf

  4. 语言模型是少量样本 学习者: arxiv.org/abs/2005.14165

  5. 基于 CLIP 潜变量的层次化文本条件图像生成: cdn.openai.com/papers/dall-e-2.pdf

  6. 逼真的文本到图像扩散模型与深度语言理解: arxiv.org/abs/2205.11487

  7. Flamingo:一种少样本学习的视觉语言模型: arxiv.org/pdf/2204.14198.pdf

  8. 探索统一文本到文本变换器的迁移学习极限: arxiv.org/pdf/1910.10683.pdf

  9. 一张图片值 16X16 个词:用于大规模图像识别的变换器: arxiv.org/pdf/2010.11929.pdf

  10. 在非策划数据上无监督图像特征预训练: arxiv.org/pdf/1905.01278.pdf

  11. Alexa 教师模型:预训练和提炼多十亿参数编码器用于自然语言理解系统: arxiv.org/pdf/2206.07808.pdf

  12. Alexa 教师模型:预训练和提炼多十亿参数编码器用于自然语言理解系统: arxiv.org/pdf/2208.01448.pdf

  13. BART:用于自然语言生成、翻译和理解的去噪序列到序列预训练: arxiv.org/pdf/1910.13461.pdf

第二部分:配置你的环境

在第二部分,你将学习如何为大规模预训练配置你的环境。我们将深入探讨图形处理单元GPU)、并行化基础知识以及数据集准备的第二部分。

本节包含以下章节:

  • 第四章云中的容器和加速器

  • 第五章分布基础知识

  • 第六章数据集准备:第二部分,数据加载器

第四章:云上的容器和加速器

在本章中,你将学习如何将脚本容器化,并为云上的加速器进行优化。我们将了解一系列用于基础模型的加速器,包括在整个机器学习生命周期中围绕成本和性能的权衡。你将学习关于 Amazon SageMaker 和 AWS 的关键方面,以便在加速器上训练模型,优化性能,并排除常见问题。如果你已经熟悉 AWS 上的容器和加速器,可以跳过本章。

在本章中,我们将覆盖以下主要内容:

  • 什么是加速器,为什么它们对基础模型很重要?

  • 将你的脚本容器化以便在 AWS 上的加速器使用

  • 使用加速器与 Amazon SageMaker

  • AWS 上的基础设施优化

  • 排除加速器性能问题

什么是加速器,为什么它们很重要?

有些关于人类行为的事情是值得注意的。我们非常关心自己的体验。许多艺术和科学,特别是社会科学,专注于量化、预测和理解人类行为的含义和特性。其中最明显的一种就是人类对技术性能的反应。虽然这在不同人群之间有所差异,但对于选择花费大量时间与技术互动的群体来说,有一个定理是不言而喻的:更快、更简便永远是更好的。

以视频游戏为例。虽然 20 世纪 40 年代和 50 年代见证了一些最早的视频游戏,但直到 70 年代初期,像乒乓这样的街机游戏才开始获得广泛的流行。或许并不奇怪,这几乎与原始图形处理单元GPU)的诞生时间相吻合,GPU 于 1973 年问世(1)!1994 年,PlayStation1 推出,配备了索尼 GPU。作为一个孩子,我花了许多小时沉迷于任天堂 64 的图形性能,玩着塞尔达传说超级大乱斗马里奥赛车 64等游戏!如今,你只需要看看像Roblox英雄联盟堡垒之夜这样的游戏,就能明白图形性能对游戏行业成功的重要性。几十年来,游戏一直是 GPU 市场中最重要的信号之一。

直到机器学习才是。我们在第一章中了解了 ImageNet 数据集,并简要介绍了 2012 年的冠军 AlexNet。为了高效地在大型 ImageNet 数据集上训练模型,作者使用了 GPU!当时,GPU 的性能较低,仅提供 3 GB 的内存,因此他们需要实现模型并行策略。该策略使用两个 GPU 将整个模型加载到内存中。这些增强功能,除了其他修改(如使用 ReLU 激活函数和重叠池化)外,使得 AlexNet 凭借压倒性的优势赢得了挑战。

自从十多年前取得这一成就以来,大多数最优秀的机器学习模型都使用了 GPU。从变换器到强化学习,从训练到推理,从计算机视觉到自然语言处理,绝大多数最先进的机器学习模型都需要 GPU 才能达到最佳性能。在适合的处理类型下,GPU 的速度可以比 CPU 快数个数量级。在训练或托管深度学习模型时,选择使用 GPU 还是 CPU,通常会导致完成任务所需时间的差异,可能是几小时到几天。

我们知道,与标准的 CPU 处理相比,GPU 有很多有前景的优点,但究竟是如何实现的呢?从根本上说,GPU 与 CPU 有什么不同?答案可能会让你吃惊:分布式!让我们看一下这张图,来理解 CPU 和 GPU 之间的区别:

图 4.1 – CPU 与 GPU 的区别

图 4.1 – CPU 与 GPU 的区别

CPU 只有少数几个核心,但拥有大量内存。这意味着它们一次只能执行少数几个操作,但可以非常快速地完成这些操作。可以把它想象为低延迟。CPU 几乎像一个缓存一样工作;它们非常擅长处理需要交互的任务。

另一方面,GPU 拥有成千上万的核心。例如,英伟达最新一代的 GH100 芯片就拥有 18,432 个核心。这意味着它们非常擅长同时处理许多操作,比如在神经网络中的数百万到数十亿个参数上进行矩阵乘法。可以把它想象为高吞吐量。

难道我们不关心低延迟和高吞吐量吗?是的,绝对如此!这就是为什么你今天使用的大多数计算设备,从手机到笔记本电脑,从笔记本实例到你需要训练最先进模型的大量实例,都同时使用了 CPU 和 GPU。问题是,如何做到的呢?

正如你可能想象的那样,编写一个软件程序,成功地在成千上万的微处理器上运行复杂的操作,显然不是世界上最简单的事情。这就是为什么,为了编写 GPU 的代码,你需要一个专门为超大规模操作分发而构建的软件框架。这里就引入了CUDA,英伟达的计算统一设备架构。CUDA 抽象了底层分布式微处理器的协调工作,允许用户在无需成为该架构专家的情况下,利用其强大的分发能力。例如,Python 可以直接与 CUDA 一起工作。PyTorch 和 TensorFlow 也可以与 CUDA 进行交互。

NVIDIA 显然不是唯一提供高性能分布式微处理器的供应商。通常称为加速器,类似 GPU 的大规模并行处理单元可以从亚马逊(Inferentia 和 Trainium)、谷歌(TPU)、英特尔(Habna Gaudi)、AMD(ROCm)等处获得。然而,利用底层分布式硬件需要专门的步骤。当这些硬件适用于你的用例时,它们显然具有明显的优势,但对于初学者的书籍目的而言,我们将只关注 GPU。我们将深入研究亚马逊的加速器 Trainium 和 Inferentia,位于第九章**,高级培训概念

现在你已经了解了加速器,让我们弄清楚如何使用它们!

准备使用加速器

让我们从学习如何使用你的加速器开始:

  1. 第一步:获取。在没有至少一台 GPU 的情况下,你绝对不能在 GPU 上训练模型。幸运的是,有一些免费选择供你选择。亚马逊的一个项目中,我实际上是编写了关于这个的原始文档:SageMaker Studio Lab!Studio Lab 是在云中运行免费 Jupyter Notebook 服务器的一种方式。如果你想在 CPU 或 GPU 上使用免费的笔记本环境,存储你的文件,与他人合作,并连接到 AWS 或任何其他服务,Studio Lab 是一个很好的开始方式。

  2. 第二步:容器。一旦你进入 Jupyter 笔记本并尝试运行一些示例代码,你会意识到一切都依赖于安装正确的软件包。即使安装了这些软件包,将它们连接到 GPU 还取决于笔记本中的 CUDA 安装。如果你尝试使用的 PyTorch 或 TensorFlow 版本与特定的 CUDA 安装不兼容,那就没办法了!

这就是为什么选择正确的容器作为你的基础镜像是开始开发的完美方式,特别是在 GPU 上进行深度学习时。AWS、NVIDIA、PyTorch 和 TensorFlow 都提供了可以用来开始使用深度学习框架的基础镜像。在 AWS,我们有 70 多个跨多个框架和关键版本的容器(2)。我们提供这些容器,涵盖 CPU、GPU、训练、托管、SageMaker 和我们的容器服务。

你问什么是容器?想象一下编写一个 Python 脚本,其中包含 5、10、15 甚至超过 100 个软件包。安装所有这些软件包真的非常耗时且容易出错!试想一下,单独成功安装一个软件包是多么困难;所有这些复杂性、时间和你找到的小心解决方案都可以轻松地转移到任何你喜欢的地方。如何实现?通过容器!容器是一个强大的工具。学会如何让它们成为你的朋友。

现在你对使用容器有了一些了解,特别是它们作为模型与 GPU 之间中介的角色,让我们讨论一下在哪里运行 GPU 的选项。

在这里,我想强调的是,显然我在 AWS 工作了很多年。我非常喜欢它!这段经历为我提供了一个极好的平台来提升我的技能、了解世界、实践深度学习、服务客户,并与一些非常优秀的人一起合作。我还花了很多时间研究云计算与本地计算之间的权衡。事实上,在加入 AWS 之前,我曾在很多不同的组织工作过:一些初创公司、一家银行、一所大学、餐馆、政策组织和一个非营利机构。这些地方的计算资源管理方式各不相同。

一方面,购买本地计算资源可能一开始看起来是更安全的选择。重要的是,你实际上用钱买到了实物!你不需要支付使用机器的费用,而且似乎更容易保护它。毕竟,你可以把它放在桌子下。那么,为什么会这样呢?

在本地运行计算存在五个主要问题:

  • 第一个问题是后勤。假设你确实购买了一些带有 GPU 的本地服务器。你会把它们放在哪里?如何将它们连接到你的笔记本电脑?如何保持它们的低温?如何确保它们有足够的电力?如果在实验过程中房间里的电力突然中断,你该怎么办?你还需要等待 GPU 通过邮件送达。然后,你需要“安装和配置”这些机器,把它们放入你的本地数据中心。很快,这些辅助任务就可能成为你全职工作的内容,如果你打算为整个组织运行这些计算资源,你还需要一个团队。

  • 第二个问题是规模。假设你一开始只购买了八个 GPU。你可以进行少量的实验,每次执行一个。但如果你有一个新的项目想要测试怎么办?如果你只有这八个 GPU,你将受到它们的限制,无法在其他地方进行额外的实验。在这种情况下,大多数人会选择购买更多 GPU 来进行额外的实验,这就引出了第三个问题。

  • 第三个问题是资源闲置。当大家晚上回家不再训练模型时,那些昂贵的 GPU 都发生了什么?可能什么都没发生。它们可能完全没有被利用。如果你晚上或几个星期内进行实验,可能会看到更高的 GPU 利用率。然而,组织通常会大量投资昂贵的 GPU 基础设施,但实际使用这些资源的团队往往是最少的!通常,你会看到少数几个高级用户,而大多数轻度使用者只是偶尔登录。

  • 第四个是货币。硬件更新,迅速。许多公司每年都会投入大量资源发布更新、更快、更好的硬件版本。每年,你都应该期望看到最新版本的性能提升。如果你在本地 GPU 上投入了大量资金,却在几个月内看到它们被淘汰,这种感觉可不好。这还会给你的实验带来风险;如果你不能从计算预算中获得最好的性能,你可能无法取得最先进的结果。

  • 第五个是碳足迹。你对为你所在电网提供能源的类型了解多少?它是否可持续?所有这些 GPU 会为你的社区带来多少额外的碳足迹,更不用说你的账单了?实际上,亚马逊是全球最大的可再生能源企业采购商。我们非常谨慎地选择供应我们区域的电网,并能证明,转向 AWS 云可以将平均数据中心的碳足迹减少最多 80%,当我们完全使用 100%可再生能源时,目标是减少至 96%。

另一个在 Amazon SageMaker 上运行 GPU 的好处是,如果你没有运行任务,就不需要为实例付费。在使用 SageMaker 训练机器学习模型时,GPU 只有在你训练模型时才会上线。也就是说,搬到 SageMaker 后,你的整体 GPU 利用率会显著提高,这仅仅是因为系统架构的原因。大多数数据中心并没有为深度学习训练所需要的动态性而建,因为当你不在训练模型时,节点仍然在运行!同样的逻辑也适用于 Amazon EC2。

最后,你需要确保你的项目实际上使用了 GPU。这比听起来复杂得多。首先,软件框架本身需要连接到底层的 CUDA 内核。然后,你需要使用一些工具来确保 GPU 的使用率尽可能高。你将在本章后面学到各种技术,深入了解这些话题。

现在你已经学会了如何准备使用加速器,让我们来看看如何在 Amazon SageMaker 上使用它们吧!

如何在 AWS 上使用加速器——Amazon SageMaker

正如你在上一节中学到的,AWS 是一个极好的方式,让你在无需配置、存储、物理保护和维护 GPU 的情况下就能获得 GPU。现在,我们将看看在 AWS 上利用 GPU 的一种简单、高效且高性能的方法——Amazon SageMaker。我要明确的是,SageMaker 当然不是在 AWS 上运行 GPU 或加速器的唯一方式。然而,它是我个人最喜欢的方法,因此我们从这里开始。

有许多书籍、博客文章、网络研讨会和 re:Invent 会议专门介绍和讨论 SageMaker。我自己也有一个包含 16 个视频的 YouTube 系列,你可以通过它来学习更多关于 SageMaker 的内容!不过,为了本书的目的,我希望你了解 SageMaker 的三个关键部分:Studio训练托管。这些部分的共同点是:实例

实例 是我们用来描述 AWS 上虚拟机的术语。这个服务叫做 弹性计算云,简称 EC2。每次你启动一个虚拟机,我们都称之为一个 实例。你可能以前使用过 EC2 实例,比如在 AWS 控制台中启动它们,使用 SSH 连接,尝试写一些代码。但你是不是觉得,每当需要更改实例的大小时,这个过程有点儿烦人?下载日志或输出文件呢?分享你的笔记本?更不用提你忘记关机后收到的账单了!

那么,如果我告诉你,有一种简单的方式可以在不需要管理底层基础设施的情况下,运行笔记本、训练模型并围绕你的数据科学工作成果构建业务应用,你是不是会感兴趣呢?

这就是 SageMaker 的核心理念。我们通过让你能够在一个统一的界面上轻松运行你的笔记本、模型、任务、管道和流程,来实现机器学习的普及化。我们还提供高性能并以实惠的价格交付服务。让我们更仔细地看看 SageMaker 的一些关键部分。

SageMaker Studio

SageMaker Studio 是我们旗舰级的开发环境,完全与机器学习集成。我最喜欢 Studio 的一点是,我们将支撑用户界面的计算资源与运行你的笔记本的计算资源解耦。这意味着 AWS 会为每个用户托管一个 Jupyter 服务器,负责你的可视化体验。这包括大量专为机器学习构建的功能,如 Feature Store、Pipelines、Data Wrangler、Clarify、Model Monitor 等等。

然后,每当你创建一个新的 Jupyter 笔记本,我们会在专用实例上运行它。这些实例叫做 内核网关应用,它们让你能够在 IDE 中无缝运行许多不同的项目,满足不同的包需求和数据集,而无需离开你的开发环境。更棒的是,Studio 中的笔记本非常容易升级、降级或更换内核。也就是说,你可以在 CPU 和 GPU 之间切换,而几乎不需要中断工作。

SageMaker 训练

现在你大概了解了如何在 SageMaker 上运行笔记本,但如果是一个大规模的分布式训练任务呢?

对于这个主题,我们需要介绍 SageMaker 的第二个关键支柱:训练。SageMaker Training 让你能够轻松定义作业参数,例如所需的实例、脚本、包依赖、软件版本等。然后,当你训练模型时,我们会在 AWS 上启动一群远程实例来运行你的脚本。所有的元数据、包细节、作业输出、超参数、数据输入等都会被存储、可搜索并默认进行版本管理。这样,你就能轻松追踪工作进展、重现结果,并在作业完成后,即使是几个月或几年后,也能找到实验的详细信息。

此外,我们在更新训练后端平台方面投入了大量精力,以支持超大规模建模。从使用 FSx for Lustre 的数据优化到分布式库(如模型和数据并行),我们正在推动下一代大规模模型在 AWS 上无缝训练,涵盖视觉和文本领域。下一章会更详细地介绍这一点。本书中我们分析的大部分 GPU 实例都属于 SageMaker Training。

SageMaker 托管

最后,你还可以在 SageMaker 托管中运行 GPU。当你想在核心模型之上构建可扩展的 REST API 时,这非常有用。你可能会使用 SageMaker 托管端点来运行搜索体验、提供问答服务、进行内容分类、推荐内容等多种应用。SageMaker 托管支持 GPU!我们将在 第十二章《如何部署你的模型》中更详细地探讨这一点。

现在你已经了解了 SageMaker 的一些关键支柱,让我们深入探讨它们背后的概念:实例。

SageMaker 上 GPU 实例解析

截至 2022 年 11 月,我们支持 SageMaker 上两种主要的 GPU 实例系列、两种自定义加速器和 Habana Gaudi 加速器。在这里,我将为你解析所有实例的命名规范,并介绍你可能会使用这些实例的具体场景。

所有实例的命名规范实际上由三部分组成:前缀、中缀和后缀。例如,ml.g4dn.12xlarge。其中,ml 部分表示这是一个 SageMaker 实例,因此你不会在 EC2 控制平面中看到它。g 部分告诉你这个实例属于哪个计算系列,特别是它的计算类型。在这里,g 表示它是一个特定类型的 GPU 加速器:g4 实例配备 NVIDIA T4,而 g5 配备 NVIDIA A10G。紧跟字母后的数字是该实例的版本号,数字越大,版本越新。所以,g5g4 更新,依此类推。每个实例的最新版本通常会提供更好的性价比。

这里,g4 表示你正在使用 NVIDIA T4 GPU。数字后面的字母告诉你该实例上还可用的其他资源,在这种情况下,d 表示我们可以使用 n 来运行 ml.t3.medium 的 Jupyter notebook,但之后可以升级到更大的实例,如 ml.g4dn.12xlarge 进行开发,最终可能会使用 ml.p4dn.24xlarge 进行大规模训练。

一般来说,g 实例非常适合较小的模型。这可以包括开发和测试,例如在此上运行复杂的笔记本、使用热池,或者只是使用数据并行的多 GPU 模型训练。g5 实例在这里尤其具有竞争力。

然而,如果你想训练大型语言模型,强烈推荐使用 p 系列实例。这是因为这些 GPU 实际上性能更强,并且更大。它们支持更大的模型和更大的批量大小。ml.p4dn.24xlarge 配备 8 个 NVIDIA A100,每个卡有 40 GB 的 GPU 内存。ml.g5.48xlarge 配备 8 个 NVIDIA A10G,每个卡只有 24 GB 的 GPU 内存。

在撰写本文时,Trainium 刚刚上线!这是亚马逊开发的定制加速器,旨在为客户提供高达 50% 的成本性能提升。

现在你已经了解了如何在 AWS 上使用 GPU,特别是在 Amazon SageMaker 上使用 GPU,以及哪些实例你应该关注,接下来我们来探讨如何优化 GPU 性能。

优化加速器性能

这里有两种方法可以处理这个问题,而这两种方法都很重要。第一种是从超参数的角度来看。第二种是从基础设施的角度来看。让我们一一解析吧!

超参数

整个 第七章 都致力于选择正确的超参数,而优化 GPU 性能是其中一个重要因素。值得注意的是,随着你集群中 GPU 数量的变化,也就是我们所说的 世界大小,你需要调整你的超参数以适应这种变化。此外,在最大化批量大小以提高整体工作吞吐量和找到一个较小的批量大小以最终提高准确性之间,有一个核心的权衡。书中的后续部分将教你如何通过超参数调优来弥补这一差距。

AWS 上加速器的基础设施优化

在这里,你将学习到五个关键主题,它们能够决定你的脚本如何使用 AWS 上的 GPU 基础设施。在你学习的这个阶段,我不期望你成为这些主题的专家。我只是希望你了解它们的存在,并且知道在以后工作流中,你可能需要更新与它们相关的标志和配置:

  • EFA:亚马逊的 弹性网络适配器 是 AWS 上的定制网络解决方案,旨在为高性能深度学习提供最佳规模。专为亚马逊 EC2 网络拓扑结构设计,它使从几个到几百甚至几千个 GPU 在 AWS 上实现无缝的网络扩展。

  • ml.p4d.24xlargeml.p3dn.24xlargeml.g4dn.12xlarge 等等。

  • AllReduceBroadcastReduceAllGatherReduceScatter。你将使用的大多数分布式训练软件框架都采用了这些算法的组合或其自定义实现,并且有多种方式。第五章将详细探讨这一点。另一个需要了解的关键 NVIDIA 库是 CUDA,正如前面提到的,它允许你在加速器上运行深度学习框架软件。

  • GPUDirectRDMA:这是 NVIDIA 的一款工具,允许 GPU 在同一实例上直接相互通信,而无需经过 CPU。这也可以在 AWS 上通过特定的实例使用。

  • Open MPI开放消息传递接口是一个开源项目,旨在使远程计算机能够轻松地相互通信。你大多数的分布式训练工作负载,特别是那些在 SageMaker 上运行的工作负载,将使用 MPI 作为基础通信层,以确保各个工作节点能够保持同步。

如果你在想,"现在,我该如何使用这些东西呢?",答案通常非常简单。只需要三步,如下所示:

  1. 首先,问问自己,我使用的是哪种基础容器?如果你使用的是 AWS 的深度学习容器,那么在我们进行广泛的测试和检查后,这些能力都将会提供给你。

  2. 其次,查看你使用的是哪种实例。正如你之前学到的,每种实例类型都会影响你在 AWS 上是否能使用某些功能。确保你获得最佳性能!

  3. 第三,查看如何在作业参数中配置这些内容。在 SageMaker 中,我们将使用超参数和脚本中的设置,确保你能够最大化性能。

现在你已经了解了一些优化 GPU 性能的知识,接下来我们来看看如何排查性能问题。

排查加速器性能问题

在分析 GPU 性能之前,我们需要一般了解如何在训练平台上进行调试和分析性能。SageMaker 为此提供了一些非常不错的解决方案。首先,所有的日志都会发送到Amazon CloudWatch,这是另一个 AWS 服务,帮助你监控作业性能。你集群中的每个节点都会有一个完整的专用日志流,你可以通过查看日志流来了解整个训练环境,SageMaker 如何运行你的作业,你的作业状态,以及你的脚本所生成的所有日志。所有你写入标准输出的内容,或者打印的语句,都会被自动捕获并存储在 CloudWatch 中。调试代码的第一步是查看日志,弄清楚到底出了什么问题。

一旦你发现脚本中存在问题,你可能会想尽快修复并让它恢复运行,对吧?这就是为什么我们在 SageMaker 上引入了托管的热池功能,一个即使在任务完成后也能保持训练集群在线的功能。通过 SageMaker 热池,你现在可以在几秒钟内就在 SageMaker 训练上运行新的任务!

当脚本工作正常时,接下来你需要分析任务的整体性能。这时调试工具就非常有用。SageMaker 提供了调试器和分析器,它们在任务运行时会启动远程实例,应用规则并在整个训练过程中检查张量。分析器是一个特别有用的工具;它会自动生成图表,帮助你评估任务的整体性能,包括哪些 GPU 正在被使用,以及使用的程度。NVIDIA 还提供了 GPU 调试和分析工具。

如前所述,编写软件以无缝协调成千上万的 GPU 核心绝非易事。因此,GPU 突然出现故障的情况非常常见。你可能会看到 NCCL 错误、CUDA 错误或其他看似无法解释的故障。对于其中许多情况,SageMaker 实际上会提前为你运行 GPU 健康检查!这也是为什么p4d实例初始化时间比较长的原因;我们在将 GPU 暴露给你之前,会分析它们的健康状况。

除了这些已知的以 GPU 为中心的问题外,你可能还会遇到其他故障,比如损失值不下降或突然爆炸、容量不足、GPU 吞吐量异常低或节点拓扑结构发生小变化。对于这些问题,通常会在你的账户中实现一个Lambda 函数来监控你的任务。你可以使用这个 Lambda 函数来分析 Cloudwatch 日志、触发警报、重启任务等。

只要记住每 2 到 3 小时检查一次模型。我们将在接下来的章节中讨论在 SageMaker 上大规模训练时的最佳实践,但现在请记住,你需要定期写入最近训练的模型的完整副本,以确保训练过程的顺利进行。

现在你已经了解了一些排查 GPU 性能问题的技术,接下来让我们总结一下本章所学的内容。

总结

在本章中,我们介绍了机器学习加速器,包括它们如何与标准 CPU 处理方式不同,以及为何在大规模深度学习中需要它们。我们讲解了获取加速器并为软件开发和模型训练做好准备的一些技术。我们还介绍了 Amazon SageMaker 的关键方面,特别是 Studio、Training 和托管。你应该知道,有一些关键的软件框架让你可以在 GPU 上运行代码,例如 NCCL、CUDA 等。你还应该了解 AWS 提供的用于高性能 GPU 计算的顶级功能,以训练深度学习模型,如 EFA、Nitro 等。我们介绍了如何找到并构建预装了这些软件包的容器,以便成功运行脚本。我们还讲解了如何在 SageMaker 上调试代码并排查 GPU 性能问题。

现在我们已经详细了解了 GPU,接下来的章节将探索分布式训练的基础知识!

参考文献

请查看以下内容,了解更多本章中涉及的一些主题:

  1. 微控制外围处理器:dl.acm.org/doi/10.1145/800203.806247

  2. AWS,深度 学习github.com/aws/deep-learning-containers

第五章:分布式基础

在本章中,您将学习大规模预训练和微调所需分布技术的基本概念。首先,您将掌握机器学习ML)的顶级分布概念,特别是模型并行和数据并行。接着,您将了解如何通过 Amazon SageMaker 与分布式软件集成,在您需要的 GPU 上运行任务。您将学习如何优化模型并行和数据并行,以便进行大规模训练,特别是使用诸如分片数据并行等技术。然后,您将学习如何通过高级技术来减少内存消耗,比如优化器状态分片、激活检查点、编译等。最后,我们将通过一些语言、视觉等方面的示例来整合这些概念。

在本章中,我们将讨论以下主要主题:

  • 理解关键概念——数据并行和模型并行

  • 结合模型并行和数据并行

  • 在 Amazon SageMaker 上进行分布式训练

  • 减少 GPU 内存的高级技术

  • 用当今模型的示例总结所有内容

理解关键概念——数据并行和模型并行

我在处理 ML 基础设施时的一些最极端的记忆来自研究生阶段。我将永远记得新作业的压力,通常是需要分析的某个大数据集。然而,往往数据集无法在我的笔记本电脑上存储!我不得不清除掉所有先前的作业,只为开始下载。然后,下载会花费很长时间,而且经常被我不稳定的咖啡馆网络中断。一旦我设法下载完成,我失望地发现它太大,无法加载到内存中!在一个好的日子里,您在第二章中接触过的 Python 库 pandas 有一个内置的功能来读取这种类型的文件,它可以限制读取为少数几个对象。而在糟糕的日子里,我需要自己构建一个流式读取器。在我设法运行一些分析后,我会选择几个我认为相关且适合的模型。然而,它们似乎训练起来永远也结束不了!我会坐在笔记本电脑前几个小时,确保网络连接不掉线、Jupyter 内核没有崩溃,阅读调试语句,并希望循环能在第二天早上提交报告之前完成。

幸运的是,今天的 ML 开发人员已经有许多这些问题的优秀解决方案——正如我们在上一章中介绍的,Amazon SageMaker 和 AWS 云平台通常就是其中之一。现在,让我们深入拆解其中一个方面:训练运行时。事实证明,分布是一个您可以掌握的概念,用来训练极其庞大的模型和数据集。在本章中,我们将探讨两个关键概念,正确使用它们将帮助您将训练规模扩展到您梦想的大小。这两个概念如下所示:

  • 数据并行

  • 模型并行

数据并行为每个 GPU 创建模型副本,将你的数据集拆分以帮助你更快地训练,而模型并行将你的模型拆分到多个 GPU 上,帮助你训练更大的模型。换句话说,数据并行将数据拆分到单节点和多节点设置中的加速器上,并对完全相同的模型应用不同的数据拆分,模型副本数为N。另一方面,模型并行将同一个模型拆分到多个加速器和节点上,并为每个模型拆分使用相同的数据。

数据并行的基本概念

数据并行在处理极大数据集时非常有用。在最简单的情况下,你可能有一个包含两块 GPU 的实例。假设你正在使用一个小到只能放进单个 GPU 的模型——比如参数数量少于 10 亿——你的数据并行软件框架可能会在每个 GPU 上创建模型的两个副本。这个框架还需要一个分布式数据加载器。这个数据加载器需要指向一个单一的源——例如你的训练和测试文件——但是将每个批次按模型副本的数量进行拆分。例如,如果你的全局批次大小为 32,则每个 GPU 上的批次大小将变为 16。数据加载器会为你管理这一切,确保每个全局批次在你整个世界大小(即你用于训练的所有机器上的 GPU 总数)上正确地拆分和分配。

那么,如何将两个模型变成一个呢?通过简单的平均!前向传播很容易理解:每个模型副本使用每个 GPU 的批次执行一次前向传播。然而,对于反向传播,梯度会在所有模型副本之间进行平均。前向传播之后,每个模型副本将其输出发送到集中的控制平面。控制平面计算所有副本输出的加权平均值,并将其与真实值进行比较,然后通过优化器运行梯度下降算法。优化器随后将新的模型权重发送到每个模型副本。每完成一个批次就叫做一步,而完整通过一次数据集就叫做一个周期

这一基本概念可以随着你不断增加 GPU 而扩展。这意味着像SageMaker 分布式数据并行SM DDP)这样的优秀数据并行软件,将帮助你在单实例和多实例情况下都能在多个 GPU 上运行。我们将在本章稍后的部分学习更多关于 SageMaker 管理的分布式训练库。

但是首先,现在你已经对数据并行有了初步的理解,让我们来探讨分布式的第二个维度:模型并行。

模型并行的基本概念

如我们所发现的,今天世界上的许多最先进的模型都是极其庞大的。通常,这些模型的参数范围从几十亿个到几百亿个,偶尔会达到万亿级别。记住,参数就是神经网络中的权重。它们是所有层内的内容。当数据通过网络时,每一步都是一个数学函数,利用某种由层类型定义的公式转换输入数据,通常会应用某种激活函数,然后将结果传递给下一层。从计算的角度来看,层本质上是一个列表。这个列表由参数组成!当设置为可训练时,这些参数会在反向传播的随机梯度下降过程中发生变化。当设置为不可训练时,这些参数将不会改变,从而允许你部署模型或使用下游层进行微调。

那么,我们如何处理大型模型呢?模型并行性就是答案!

模型并行性涵盖了多种帮助你将模型分布到多个 GPU 上的方法。最简单的方法叫做流水线并行。在流水线并行中,你的软件框架会将神经网络的各个层放置到不同的 GPU 上。如果你的神经网络有两个非常大的层,且你希望在一个有两个 GPU 的实例上进行训练,你可能会将每个层放到一个 GPU 上。

类似于前述的数据并行示例,你仍然需要一个分布式数据加载器。这个分布式数据加载器仍然会将每个全局批量大小分解成每个 GPU 的微批次。然后,模型的每一部分——在这个例子中是模型的每一层——可以一次接收一个微批次进行前向传播。集中的控制平面将会异步执行每一层,在适当的时刻将微批次传递到相关层。每一层仍然会看到数据集中的每一项,因此从数学上讲,就像所有层都被打包到某个庞大的单一 GPU 上一样。谢谢你,交换律!

你可以在以下图示中看到该过程的示意图:

图 5.1 – 模型并行

图 5.1 – 模型并行

模型并行的另一个关键方面是处理过大以至于无法在单个 GPU 上容纳的层。在大型语言模型中尤其常见,正如我们在第一章中了解到的 Transformer 注意力头,它很容易超出现代 GPU 的内存限制。那么我们该如何解决这个问题呢?张量并行性,这是分布式训练的第三个维度。在张量并行框架中,您可能会将一个张量的一部分放在一个 GPU 上,而将同一个张量的另一部分放在另一个 GPU 上。集中式的分布式软件仍然会将小批量数据传递给它们,从逻辑上来看,操作没有任何区别。张量并行性是今天训练像 GPT-3 这样的大型模型的必备技术,GPT-3 拥有 1750 亿个参数或更多。

若想了解更多关于模型并行性,尤其是通过 SageMaker 模型并行性提供的分布式库,可以查看我们在该主题上的论文(4)。现在,您已经了解了分布式训练中的两个基础主题,分别是数据并行性和模型并行性,接下来让我们学习如何将它们结合起来!

结合模型并行和数据并行

正如您之前可能已经怀疑的那样,正如通过规模定律得到的实验证据所显示的,大型模型只有与大数据集结合时才有效。换句话说,如果您将一个极大的模型与一个小型或中型的数据集一起使用,您极有可能会导致模型过拟合。这意味着它可能最终会学会如何复制您提供的核心示例,但很难应对新的挑战。

出人意料的是,反过来并不一定成立。作为一个一般规则,随着数据集规模的增加,增大模型规模通常是有帮助的。然而,在大多数计算机视觉的应用场景中,模型规模很少会超过单个 GPU 的内存限制。我可以说,我与之合作的绝大多数视觉客户,从自动驾驶汽车到制造业,从金融服务到医疗保健,都倾向于使用能够很好地适应单个 GPU 的模型。在这些情况下,仅使用数据并行就能显著提高训练过程的吞吐量,因为每增加一个 GPU 上的模型副本,您的训练速度就会提升。

然而,在 自然语言处理NLP)中,通常情况并非如此,最具性能的模型通常至少需要几个 GPU,有时甚至需要数百个或数千个 GPU。在这些情况下,您可以预期使用模型与数据并行的组合,正如 Alpa 早期示例(5)所演示的那样。模型并行使您能够将模型保存在 GPU 的活动内存中,而数据并行则通过复制模型并增加每步处理的数据量来提高整体速度。当即便一个模型的副本也需要多个 GPU 时,意味着每增加一个副本都需要相同数量的 GPU。因此,如果您的模型需要 4 个 GPU,基于数据大小,您使用扩展规律来确定总计算预算包括 64 个 GPU(8 个实例,每个实例有 8 个 GPU),那么您将拥有 16 个模型副本!这是因为每个 8-GPU 实例可以容纳 2 个副本的模型。让我们通过图示来进一步分析:

图 5.2 – 模型与数据并行

图 5.2 – 模型与数据并行

记住——每个模型副本通过模型并行进行处理。然后,所有模型副本的合并则通过数据并行处理。看起来很复杂,对吧?但希望这些概念开始在您脑海中扎根——一旦它们明确,所有这些术语和想法就会开始变得有意义。记住——您并不孤单,我们有一个完全托管的服务来帮助您在令人难以置信的规模上训练模型!在下一部分,我将与您分享 Amazon SageMaker 在自动化、管理和为您提供支持方面的一些内容,帮助您更快地达成目标。

Amazon SageMaker 上的分布式训练

在上一章中,我们大致了解了 SageMaker。现在,我想深入探讨分布式训练的能力。我们可以将这些能力分为四个不同的类别:容器、编排、可用性和大规模性能。

正如我们在前面章节中所学到的,AWS 提供了 深度学习DL)容器,您可以轻松地将它们指向自己的脚本和代码。这些容器作为您项目的起点是强烈推荐的,因为所有的框架、版本和库都已经为您进行了测试和集成。这意味着您只需根据使用的深度学习框架选择一个容器——例如 PyTorch 或 TensorFlow——并且这个容器已经在 AWS 和 SageMaker 上经过测试。您还可以选择这个容器的 GPU 版本,它已经编译并安装了所有 NVIDIA 库,以便在您的 GPU 上顺利运行。然而,如果您有自己的容器,您可以直接将它推送到 Amazon 的 弹性容器注册表ECR),并用于训练。您还需要添加训练工具包,以启用自定义容器的所有训练功能,如入口点脚本、日志输出、热池等。

一旦选择了您的镜像,您就可以开始格式化您的脚本!在 SageMaker 上,我们使用 CreateTrainingJob,这是一个您会非常熟悉的概念。核心思想是您使用您的估算器指向基本对象,例如您的 DL 容器、您的脚本和所有作业参数。然后,您只需调用 estimator.fit()。这将提交您的调用到 CreateTrainingJob API,然后执行命令以创建作业!

记住,SageMaker 训练 在训练期间为您初始化远程实例。这意味着一旦您执行了 estimator.fit(),然后在训练作业下的控制台中,您将看到新初始化的实例。这些由服务管理。一旦实例初始化完成,它们将把您的数据复制到其中,下载您的镜像,并在您的数据上运行训练脚本。所有日志都发送到 CloudWatch,并维护作业的所有元数据。这意味着您的实验是可以默认重现的!一旦作业完成,训练好的模型工件将代表您发送到亚马逊 简单存储服务S3)。

现在,您一定在想:对于只使用一个 GPU 的脚本来说,这似乎是可行的。但如何使用多个 GPU 呢?答案很简单:软件!

分布式训练软件

从一个 GPU 扩展您的代码的关键步骤是使用正确的软件来做这件事。而对您来说,今天有许多选择。在 SageMaker 上,您可以使用任何您想要的开源软件;轻松带入额外的软件包、脚本和框架到 training API。这意味着您可以在我们的训练 API 中实现任何一种顶级分布式训练框架。其中一些包括 DeepSpeed ZeRO-3D、Megatron-LM、PyTorch 分布式数据并行DDP)、Horovod 等等。如果您已经在这些框架中运行代码,您扩展的第一步很可能就是将其移至 AWS 和 SageMaker。然而,如果您仅使用开源分布式框架,您可能会错失效率收益

这些效率收益的原因根本来自于我们在亚马逊经常使用的一个概念:经验没有压缩算法。这字面意思是亚马逊在优化云上的 DL,特别是大规模 DL 方面不断做出了很多改进。特别是我们有一个软件解决方案,SageMaker 分布式训练库,帮助您在 AWS 上实现最先进的性能。

我们将更深入地探讨不同的分布式训练软件的细微差别,包括关键的设计决策,如参数服务器和基于环的方法的区别,在第八章中。现在,让我们从高层次探索可用的库。

SM DDP

记得在 第四章中,我们学习了一个叫做通信集体的概念。这些是旨在促进多 GPU 分布式梯度下降的核心算法。然而,NVIDIA 集体通信库NCCL)实际上是针对特定基础设施设计的:InfiniBand。这是一种极其宽松的网络解决方案,支持超过 1 TB 的通信传输。将其投入使用是相当昂贵的,并且需要大额的前期投资才能在本地获取并使用该解决方案。

在 AWS,我们设计了自己的定制通信集体,这些集体是专门为 弹性计算云EC2)网络拓扑构建的。它们使得在 AWS 上实现最佳性能成为可能,能够扩展到数千个 GPU 甚至更多,而不会带来巨大的网络开销。与这些定制集体交互的主要方式是通过 SM DDP (3)。SM DDP 是一种完全托管的数据并行软件,通过后端与你的训练脚本集成。这意味着你可以使用自己的数据并行神经网络软件——特别是 PyTorch DDP、Hugging Face 的 Accelerate 或 TensorFlow 的 Horovod——并简单地将 SM DDP 设置为你的后端。

设置 SM DDP 作为你的后端的主要原因是为了提高扩展效率。如果没有 SM DDP,你可能会使用一些并非专门为 AWS EC2 实例拓扑设计的通信集体算法。因此,当你向整体集群中添加更多实例时,你会体验到 收益递减。从理论上讲,在一个完美的世界里,你应该能够通过将节点从一个增加到两个,精确地将训练时间缩短一半。将节点从一个增加到三个应该将训练时间缩短三倍。将节点从一个增加到四个应该将训练时间缩短四倍。这个理论上的极限被称为线性 扩展效率

然而,我们并不生活在一个完美的世界。从计算角度来看,这种线性扩展效率实际上是无法达到的。你将看到的是一些接近更好扩展效率的尝试,例如通过 SM DDP 提供的更好的通信集体算法。SM DDP 在更大规模下的效果尤其显著。例如,如果你比较一个使用 PyTorch DDP 的 8 节点集群与一个使用 SM DDP 的相同集群,SM DDP 作业的性能可能会提高多达 40%。这些提升是大规模的。这意味着不仅你的实验结果返回更快,给你更多时间尝试新想法并更快地将解决方案推向市场,而且训练的实际计算成本也大大降低!

现在我们了解了 SM DDP 库,让我们探索在 AWS 上获取扩展效率提升的另一种选择:SageMaker 模型并行SMP)库。

SMP 库

记住,在本章前面,我们介绍了 Amazon SageMaker 上的大规模训练。我们还澄清了,这使得你可以在不受分布式软件限制的情况下,在任意数量的 GPU 上运行任何开源库。在模型并行性方面,这包括 DeepSpeed、Megatron-LM 等。然而,为了真正充分利用 SageMaker 提供的所有性能增强,我强烈建议你评估 SMP 库。本书中,我们将详细使用这个库。

SMP 是一个由 AWS 构建和管理的 Python SDK,帮助你轻松地将神经网络模型扩展到多个 GPU 上。SMP 与 PyTorch 集成得很好,并提供了先进的功能,帮助你将模型扩展到从少数几个到几百甚至几千个 GPU 上。这些功能包括流水线并行性、张量并行性、优化器状态分片、激活卸载与检查点、分片数据并行性等。在本章后面,我们将探讨这些高级功能,但首先,让我们简单了解如何配置和使用库来进行基础的模型分布。

一般来说,一旦你拥有一个能在单个 GPU 上训练的有效 PyTorch 模型,就可以开始评估如何扩展它。首先,确保你正在使用的基础容器与 SMP 兼容。如果你使用的是 AWS 管理的支持 GPU 的 DL 容器、SageMaker 和训练,那么你已经准备好进入下一步。如果没有,请按照文档步骤(1)从任意基础镜像扩展一个预构建的 Docker 容器。

一旦确保你的容器支持 SMP,就可以将库集成到你的训练脚本中。这主要集中在以下三个关键方面:

  1. 将库导入你的脚本。从 2022 年 11 月开始,这仅仅是执行以下命令:import smdistributed.modelparallel.torch as smp

  2. 使用相关的smp对象包装你的模型和优化器。实际上,这非常简单。完成用 PyTorch 定义神经网络后,或者在从 Hugging Face 加载 PyTorch 模型后,只需将其作为参数传递给smp.DistributedModel()对象。接着,像平常一样在脚本的其他部分继续使用你的模型。优化器的结构类似。

  3. 重构你的训练循环,包含两个独立的函数,一个是训练步骤,另一个是测试步骤。这两个函数都应当接收你的模型、优化器和其他相关参数。训练步骤应当将数据通过网络向前传递,计算损失,通过优化器将其反向传播到网络中,并返回损失值。测试步骤仅需计算损失,并返回损失值。

对于训练和测试步骤函数,你需要添加一个 Python 装饰器,将它们声明为@smp.step。这个装饰器非常关键,因为这个函数中的所有内容都会被切分到多个 GPU 上。SMP 库会显式地评估这些函数中的活动,特别是你的模型以及数据如何在其中流动,以便将模型最优地分配到多个 GPU 上。

一旦你的脚本完成了这些以及其他一些相关的更改,你将需要进行最后一次配置。在 SageMaker 训练作业估算器中,添加另一个名为distribution的参数。正如我们在本书中将看到的,这个参数将允许我们配置 SageMaker 训练后端的多个方面,包括 SMP 和 SM DDP。传递一个标志来启用 SMP,并包括其他相关参数。你还需要启用消息传递接口MPI),这是我们在本书前面学到的。MPI 是一个开源框架,能够在训练过程中使你的节点之间进行通信。SMP 通过 MPI 来跨节点通信。

最后,测试你的脚本!在 SageMaker 训练中测试模型并行性的一个简单方法叫做本地模式。本地模式是一个非常有用的技术,它允许你在不等待集群启动开销的情况下开发 SageMaker 训练 API,包括容器、数据指针、脚本和作业参数。你可以在任何运行 Docker 的地方使用 SageMaker 本地模式,比如 SageMaker 笔记本实例,甚至是你本地的笔记本电脑。截至本书写作时,Studio 不支持本地模式。本地模式帮助你在编写代码时快速而轻松地进行步骤,确保一切设计合理并且正常工作。

一旦你通过从 Hugging Face 导入一个更大的版本,或者通过手动增加 PyTorch 定义中的参数数量,已经增大了模型的规模,并且有证据表明它在至少两个 GPU 上运行良好,那么就可以开始探索 SMP 库中的高级技术,减少你的整体 GPU 内存占用。

减少 GPU 内存的高级技巧

现在,假设你已经深入到项目中。你已经确定了数据集、使用场景和基础模型。你在 SageMaker 上进行了小规模的测试,例如在模型的最小版本上使用 1%的数据,并且效果不错。你已经使用了扩展法则,或者通过另一个示例看到大型模型能够帮助提高准确性,并且你确信自己有足够的数据来证明更大的模型是合理的。你已经将模型规模增大,至少能够在两个 GPU 上运行,并且已经在 AWS 上成功测试过。

如果你还没有达到这些阶段,那么老实说,我建议你直接跳到下一部分。在这里,我们将深入探讨模型并行的前沿领域,这些话题非常复杂、细节丰富且小众。如果你还没有准备好,比如没有经历我之前提到的所有前置阶段,那么最好现在跳过这个话题。你可以随时回来参考这些内容。特别是如果你在这个领域是初学者,我们将讨论的话题可能会让你不知所措,进而影响你继续进行分布式训练。你依然可以训练像 Stable Diffusion 这样的最先进的模型,而不需要使用极大规模的模型并行。然而,对于那些准备好完全深入模型并行世界的人,我们现在可以开始了!

你可能已经注意到,将一个模型分割到多个加速器上会自然地减少模型的 GPU 内存占用。换句话说,当一个模型太大,无法放入单个 GPU 时,它会受到该 GPU 可用内存的瓶颈限制,因此我们需要一种方式来减少其内存占用。将模型分割到多个 GPU 上是实现这一点的一种方法,但这并不是唯一的方式。接下来,我们将介绍更多方法。

一旦你将训练脚本与 SMP 库集成,使用其余功能就像添加和移除超参数一样简单。虽然编写代码实现它们非常简单,但理解它们并成功设计是相当具有挑战性的。首先,让我们回顾一下基础知识。pipeline_parallel_degree 参数表示你将如何在多个 GPU 之间分配模型。例如,如果你的机器有 8 个 GPU,并且你将 pipeline_parallel_degree 设置为 2,那么根据你在模型中分配参数的方式,模型可能会被分成两半。如果每一半使用 4 个 GPU,那么整个模型就能使用 8 个 GPU,每一半使用 4 个 GPU。如果你想在此基础上增加数据并行度,你还需要另一个实例。

你还需要考虑每个 GPU 的批量大小。在 SMP 库中,我们称之为 microbatches。整个第七章都在讨论如何找到正确的超参数,但在这里你需要理解的是,增加批量大小会直接增加 GPU 利用率。模型并行的核心目标是找到有效的方式来减少模型的 GPU 内存占用,这样你就可以增加批量大小——从而提高 GPU 利用率——这减少了作业的总体运行时间,因此也降低了成本。然而,正如你在第七章中会学到的,精确的模型通常需要较小的批量大小。Yann LeCunn 在 Twitter 上著名地表示,“朋友们不会让朋友使用超过 32 的批量大小”。

除了流水线并行和微批次,理解模型并行性时,还需要掌握一些其他关键术语,包括张量并行、优化器状态分片、激活检查点和分片数据并行。

张量并行

虽然流水线并行性使我们能够将神经网络的不同层分配到不同的设备上,但在张量并行中,我们将这一步走得更远,进一步拆分层本身。通常,这在极端模型并行的情况下很常见,例如具有超过 1000 亿个参数的 GPT-3 类型的模型。在 SMP 中,你可以通过tensor_parallel_degree简单地启用这一点。确保将单个层的所有部分保留在同一个节点内,因为这对于最大化训练集群中的带宽至关重要。

如果你特别好奇,要将模型规模扩展到 1 万亿参数,另一种有用的技术是备用网络。这最早在 2017 年提出(6),作为专家混合MoE)技术,用于在训练过程中仅激活神经网络的一部分,从而实现更高效的扩展到超大参数规模。一支来自华为的分布式训练团队提出了一个专门针对 transformer 的更新,实施了他们所称的随机路由专家。令人印象深刻的是,他们声称这项工作在超过 100 天的时间里仅使用了 512 个加速器,显著提升了中文 NLP 任务的最前沿(7)。然而,在本书的其余部分,我们将主要关注适用于几百亿参数的密集型网络。

优化器状态分片

当你的神经网络中的可训练权重或参数数量非常大时,你可以预期优化器也会变得同样庞大。如果你在训练集群中有多个模型副本,比如结合使用数据并行和模型并行,那么可以通过设置shard_optimizer_state : True来考虑将优化器进行拆分。有趣的是,这样做将DistributedOptimizer对象的作用域仅限于该数据并行 rank 中所持有的参数。这些参数被称为虚拟参数,并且与原始参数共享底层存储。

激活检查点

激活检查点实际上是一种通过增加计算时间来减少内存开销的技术。换句话说,当启用激活检查点时,你可以将更多对象加载到清空的 GPU 内存中,但代价是每一步的计算会稍微变长。这是通过清除某些层的激活值并在反向传播时重新计算它们来实现的。

分片数据并行

亚马逊的一个团队在 2022 年开发了一种新颖的策略,用于在 AWS 上优化大规模分布式训练。特别是,他们意识到 并非所有 GPU 都应被平等对待。当你试图优化通信集群时,假设某些组合的模型和数据并行,这一点尤为重要。他们设计了一种分层方法,用于分布式训练的 完成证书 (CCLs),这种方法首先在数据并行组内(文档中称之为“分片”)进行检查,然后在数据并行组之间进行检查。这种方法最大程度地减少了在反向传播过程中同步梯度时所需的整体通信量,从而提高了工作的整体速度。因此,他们将其命名为:最小化通信规模,或称 MiCS (8)。这种 MiCS 技术已在 SageMaker 的 SMP 库中提供,称为 分片数据并行

现在你已经了解了一些先进的方式来减少整体 GPU 消耗并加速你的任务,让我们通过一些有趣模型的示例来帮助你将这些概念整合在一起。

通过今天模型的示例,将这一切带回家

记得我们在书中早些时候学习到的内容,真正的每个先进模型都需要一定的分布式处理。这是因为好的模型源于好的数据集,而好的数据集往往非常庞大。处理这些数据集需要时间,因此你需要分布式地处理任务,以便及时完成。有些模型的规模太大,无法放入单个 GPU,所以它们需要一定程度的模型并行处理。但也有一些模型相对较小,只需要数据并行处理即可。让我们通过今天一些顶级模型的两个例子来进一步探讨:Stable Diffusion 和 GPT-2。

Stable Diffusion – 大规模数据并行处理

Stable Diffusion 是一个迷人的模型,它使你能够 从文本中生成图像。训练完成后,你只需提供文本输入给 Stable Diffusion,它就会为你生成一幅新的图片!尽管研究人员从至少 2017 年起就尝试过这种方法,但 Stable Diffusion 的表现已经接近人类水平的创造力。与之具有相似表现但未公开共享的模型包括 Imagen (9) 和 DALL-E (10)。它生成的图像质量几乎可以立即使用。虽然在偏见、图像控制、分辨率和常识推理等方面仍然存在问题,但自 2017 年以来,技术的飞跃真是令人兴奋。

对于普通的 Python 开发者来说,幸运的是,Stable Diffusion 是一个小型模型!它的设计使得它可以适配单个 GPU,这意味着只需要稍微编写一些脚本和一块中等性能的 GPU,你就可以轻松地搭建自己的演示。Stable Diffusion 成功的驱动因素有几个,具体如下:

  1. 他们在训练过程中使用了四种模型:CLIP 分词器、CLIP 文本编码器、变分自编码器VAE)和 2D 卷积 U-Net。分词器和编码器使用智能语言模型处理文本数据,而 VAE 对图像进行编码并将其转换为更小的潜在空间。

  2. 在“扩散”或学习过程中,他们将噪声添加到这些相同的潜在图像中。使用语言模型编码的文本,他们试图预测噪声残差,计算损失并将其反向传播通过 UNet。

  3. 他们使用了数十亿张图像!他们的训练数据和代码都是公开可用的。就我个人而言,我编写了脚本将 5000 万张图像下载到 AWS 上的优化分布式文件系统 FSx for Lustre,并使用了接近 200 个 GPU 在 Amazon SageMaker 上对这个庞大的数据集进行了几步操作。他们原始的数据集是LAION-5B,其中的“5B”代表 50 亿。这些数十亿张图像来自互联网,每张图像都有相应的文本描述。然后,在训练过程中,他们的模型将这些图像与描述结合起来。

这意味着,当你读完这一章后,如果你已经对数据并行性有了深入的理解,那么你就具备了训练自己稳定扩散模型所需的所有知识!无论是预训练还是微调,情况都是如此。在下一章中,我们将深入了解数据加载器,你将学会如何为预训练或大规模微调准备新数据集。但首先,让我们通过一个复杂的模型并行案例研究来分析:GPT-3。

GPT-3 – 大规模的模型和数据并行

正如我们在 第一章 中学到的那样,GPT-3 是一个非常重要的模型。当 OpenAI 团队将模型规模提高了 10 倍,并且将准确率提升了三倍,从 GPT-2 迁移到 GPT-3 时,他们引发了一场全球性的运动,现在这几乎与人工智能AI)同义。正如我们在本章中所学到的,扩展的核心步骤是模型并行性。让我们来解开对于拥有超过 1000 亿参数的模型,这一过程是如何运作的!

我们先来估算一下模型本身的内存大小。首先,我们按参数数量来计算——假设是 1000 亿个参数。那么,对于一个使用 FP16 数据类型和 Adam 优化器的任务,你可以假设单个 FP16 参数大约占用 2 字节,FP16 梯度占用的字节数也差不多。所以,对于一个有 100 亿个参数的模型,你至少需要 200 GB 的 GPU 内存。一个有 1000 亿个参数的模型则需要大约 2 TB 的 GPU 内存!

假设每个设备可用 40 GB 的 GPU 内存,如 p4d.24xlarge 实例的配置,那仅为了在内存中存储一个完整的模型副本就需要 50 个 GPU。每个 p4d.24xlarge 实例有 8 个 GPU,所以每个模型副本大约需要 6 个 p4d 实例。假设你既想要一个准确的模型,又不希望等上几年才能完成训练,你将需要多个模型副本。我曾经帮助客户在 SageMaker 上使用 128 个 p4d 实例训练这类大型语言模型,这样的配置大约可以在 1,024 个 GPU 上分布 20 个模型副本。

若想通过脚本示例更好理解这一过程的实际应用,建议查阅我们在 GitHub 上的 SageMaker 示例 仓库中的笔记本。如果你在仓库中搜索 GPT-2模型并行,应该能找到相关内容。目前的链接在这里:(2)。

如果你检查笔记本,你会注意到一些细节:

  • 它提供了不同的模型训练尺寸,从最小的开始,一直到数十亿个参数。

  • 每个不同的配置都需要略微不同的超参数。

第七章的全部内容都在讲如何选择这些配置。现在,你刚刚了解到为何这一过程如此具有挑战性且重要!在配置工作时,你需要确定你的分发策略,集成模型和数据并行、总体世界规模、任何额外的 GPU 内存优化技术、模型大小及相关参数等等。

但不要灰心——我们还有很多东西需要学习。现在,让我们通过一个简短的总结来结束这一章。

总结

在这一章中,你学习了分布式训练的基础知识。你了解了数据并行和模型并行这两个关键概念,这将帮助你将训练规模扩展到接近最新技术的水平。你还学会了如何结合这两者,特别是如何利用像 Amazon SageMaker 这样的托管编排平台,帮助你无缝地使用成百上千个 GPU,并借助优化的分布式训练库进行工作。接着,你了解了先进的 GPU 内存优化技术,并通过 Stable Diffusion 和 GPT-3 等实际示例将其付诸实践。

在下一章,我们将深入探讨构建数据加载器所需的工程基础知识和概念!

参考文献

请浏览以下内容,了解章节中涉及的几个主题:

  1. SMP docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-sm-sdk.html#model-parallel-customize-container

  2. Amazon SageMaker 示例github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/smp-train-gpt-simple.ipynb

  3. SM DDP docs.aws.amazon.com/sagemaker/latest/dg/data-parallel.html

  4. Amazon SageMaker 模型并行:一个通用且灵活的大型模型 训练框架:arxiv.org/pdf/2111.05972.pdf

  5. Alpa:自动化分布式深度 学习的操作间与操作内并行性: https://www.usenix.org/conference/osdi22/presentation/zheng-lianmin

  6. 极大规模神经网络:稀疏门控专家混合 arxiv.org/pdf/1701.06538.pdf

  7. Pangu-Σ:迈向万亿参数语言模型与稀疏异构 计算https://arxiv.org/pdf/2303.10845.pdf

  8. MiCS:在公共 上训练巨大模型的近线性扩展性:https://arxiv.org/pdf/2205.00119.pdf

  9. 照片级真实感文本到图像扩散模型与深度语言 理解arxiv.org/pdf/2205.11487.pdf

  10. 零样本文本到图像 生成arxiv.org/pdf/2102.12092.pdf

第六章:数据集准备:第二部分,数据加载器

与数据融为一体。 – Andrej Karpathy

在本章中,你将学习如何准备数据集,以便立即将其与选择的模型一起使用。你将掌握数据加载器的概念,了解它为何在训练大型模型时是常见的错误来源。你还将学习如何创建嵌入、使用分词器以及其他方法,将原始数据特征化,以适应你首选的神经网络。按照这些步骤,你将能够准备整个数据集,涵盖视觉和语言任务。最后,你将学习如何在 AWS 和 Amazon SageMaker 上进行数据优化,以高效地将大大小小的数据集发送到训练集群。在本章中,我们将从训练循环的后端开始,逐步为你提供所需的所有步骤,帮助你在大规模训练中构建功能性深度神经网络。你还将跟随一个案例研究,了解我如何在 SageMaker 上训练了 10TB 数据用于 Stable Diffusion!

永远不要低估数据的力量。无论是获取尽可能高质量的样本和标签,还是未能捕捉到微妙的损坏,抑或是优化计算选择,数据都能真正决定你项目的成败。许多顶尖的深度学习模型实际上是通过开发一个新颖的数据集诞生的,从 MNIST 到 AlexNet,从 GPT-3 到 Stable Diffusion!当我们在机器学习中思考宏大时,往往意味着对你的数据集进行宏大的思考。

你无法拥有一个功能完整的训练循环,除非你有一个功能完善的数据加载器,所以让我们来解析它!在本章中,我们将覆盖以下主要主题:

  • 通过 Python 中的关键概念介绍数据加载器

  • 构建并测试你自己的数据加载器:来自 Stable Diffusion 的案例研究

  • 嵌入和分词器

  • 在 AWS 上优化你的数据管道

  • 在 AWS 上大规模转换深度学习数据集

在 Python 中介绍数据加载器

数据加载器是一个深度学习中特有的概念。在统计机器学习中,你仍然会看到许多模型使用梯度更新,这需要小批量数据,但其加载方面更为隐蔽——更多地与算法本身集成。PyTorch 从早期便采纳了这一概念,明确地提供了一个data loader对象,并将整个训练循环暴露给开发者。尽管比早期的 TensorFlow 稍显复杂,但这实际上使开发者在训练过程中拥有了更多的灵活性和控制权,从而帮助他们更轻松地开发定制解决方案。这也是越来越多的研究项目最终选择 PyTorch 而非 TensorFlow 作为其深度学习框架的原因之一。现在,我接触到的大多数模型都是首先在 PyTorch 中实现的,偶尔会用 TensorFlow。

数据加载器是什么?数据加载器为你的训练循环注入数据。大多数 PyTorch 训练循环实际上只是嵌套的循环。首先,外部循环遍历训练的轮次(epochs)。每个轮次是对数据集的完整遍历。也就是说——你猜对了——内部循环其实就是对数据加载器的遍历。这意味着,数据加载器需要在底层使用一个非常有用的 Python 对象,称为迭代器

首先,我们快速了解一下 Python 中的对象,然后逐步构建数据加载器。

图 6.1 – Python 中的类

图 6.1 – Python 中的类

记住,Python 是一门面向对象的语言。这意味着,大多数时候,当你在使用 Python 时,你是在与对象打交道。类则是构建、维护和使用对象的便捷方式。

大多数情况下,在现实世界中,你不会自己构建对象,除非你正在构建一个新的软件 SDK。通常,作为服务的消费者,你只是使用别人已经构建好的对象,并开发脚本将其集成到你的任务中。这在深度学习中也同样适用;我们的大多数对象已经在 PyTorch、pandas、sklearn 等软件包中实现。

那么,如果我想一次性指向一个非常大的列表,但每次调用该函数时只返回预定义数量的对象呢?我需要自己构建整个结构吗?现在我不再是研究生了,可以很高兴地说不需要!我只需使用一个迭代器,就像下面截图所示的那样。

图 6.2 – Python 中的简单迭代器类

图 6.2 – Python 中的简单迭代器类

Python 迭代器是为这种场景特别设计的,能够多次调用一个对象,但每次返回不同的项目。Python 中许多对象都支持迭代器,比如列表和字典。将它们转换为迭代器通常非常简单。你需要做两步,首先在定义核心对象时,将其作为迭代器,这里使用 iter() 语法。其次,当你调用迭代器来提供下一个批次的项目时,使用 next()。可以预期语法会发生变化,但大部分概念会保持不变。

构建数据加载器时,你的任务并不是从头开始构建一个类。你的任务是使用一些软件框架,如 NumPy、Hugging Face、PyTorch 或 TensorFlow,来接收你想要使用的数据。然后,你需要使用那些预先构建好的数据加载器来遍历你的批次,并将它们填充到训练循环中。

现在你已经知道数据加载器应该做什么,接下来让我们探讨如何构建你自己的数据加载器。

构建和测试你自己的数据加载器——以 Stable Diffusion 为案例分析

数据加载器的语法有可能发生变化,所以我不想过于依赖 PyTorch 当前的实现。不过,让我先提供一张简单的截图:

图 6.3 – 在 PyTorch 中使用数据加载器

图 6.3 – 在 PyTorch 中使用数据加载器

这实际上来自我在 2022 年 re:Invent 大会上与 SageMaker 的 Gal Oshri 和 AI21 的 Dan Padnos 一起进行的大规模训练演示:medium.com/@emilywebber/how-i-trained-10tb-for-stable-diffusion-on-sagemaker-39dcea49ce32。在这里,我使用 SageMaker 和 FSx for Lustre 训练 Stable Diffusion,数据量为 10 TB,FSx for Lustre 是为高性能计算设计的分布式文件系统。关于这一点以及相关优化将在本章后面详细介绍!

正如你所看到的,实际上唯一困难的部分是构建输入的训练数据集。一旦你有了一个有效的数据集对象,获取一个有效的数据加载器就像把最新的语法复制到你的脚本中并确保它有效一样简单。所以,你可能会问,我们如何获得自己的训练数据集?一个词:字典!

在我当前的设置中,我有一个在 Studio 上运行的 Jupyter 笔记本。我根据是否需要进行大规模或小规模处理,不断升级和降级运行我的内核网关应用程序或临时笔记本的实例。在这个笔记本中,我开发了我确信能够工作的脚本和函数,然后将它们复制到在 SageMaker 训练任务上运行的主脚本中。这就是我构建自定义数据加载函数的地方。

Hugging Face 提供了一个很好的load_dataset()函数,可以从其数据集库加载数据,但经过几个小时的搜索和测试,我还是无法使它与我的自定义数据集一起工作。所以,我最终构建了自己的数据加载器后端,然后指向了DatasetDict()对象。在我的笔记本中,它看起来是这样的:

图 6.4 – 在 Hugging Face 中创建你自己的 DatasetDict 对象

图 6.4 – 在 Hugging Face 中创建你自己的 DatasetDict 对象

很简单,对吧?你可以看到,我显然有一个训练集,它本身只是指向 Hugging Face Dataset对象的train词。你还可以看到,这个数据集中只有 1,736 个对象,这很好,因为我仅使用一个ml.t3.medium实例来运行我的笔记本,而这个实例非常小。当我需要指向并测试一个更大的数据集时,我只需在 Studio 中几次点击就能升级我的实例,突然间,我的实例内存达到数百 GB,数十个 CPU 核心触手可及!

当它简单时,那是由于优雅的设计决策。你的代码应该像诗歌一样:简短、简单、有效、富有表现力。强大。这可以追溯到莎士比亚:

简洁是智慧的灵魂。

对于我的 Stable Diffusion 数据集,我下载了 5000 万个图像和标题对。关于我是如何做到这一点的,稍后会在本章中介绍!

在这之后,我意识到,浪费宝贵的 GPU 时间将整个数据集加载到内存中是极其低效的。这是因为我的实现,尽管毫无疑问可以改进,却懒散地列出了所有图片,逐一查看,读取标题,并将其与指针一起存储。

现在,幸运的是,我至少可以使用 Python 的多进程包并发列出图片,每个 CPU 核心处理一张,但对于 5000 万张图片,这可能需要 24 小时才能完成。更何况,我只需要一台机器来执行此任务。我的训练集群有 24 台ml.p4d.24xlarge机器,所以我不打算让这些主机闲置,等着我列出图片并逐一查看。因此,我构建了一个索引!

在这里,索引只是一个 JSON Lines 对象。让我们来检查一下!

图 6.5 - 检查数据索引

图 6.5 - 检查数据索引

我花了几天时间构建了整个过程的端到端流程:

  1. 首先,我在 SageMaker 上使用一些玩具数据测试了我的训练脚本,确保它能正常工作。

  2. 然后,我使用多个大型 CPU 机器在 SageMaker 上下载了一个新的数据集。

  3. 接下来,我将数据集放到了 FSx for Lustre 上。我在 SageMaker 上进行了测试,指向了相关的虚拟私有云VPC)位置。

  4. 然后,我在 Studio 中复制了一个小版本,仅包含几个对象。我编写了一些脚本来解析这些对象,确保它们在执行过程中能够扩展并且可操作。我将这些脚本移到了 SageMaker 的训练作业中,并在一个大型 CPU 机器上进行了过夜运行。

第二天早上,我构建并测试了我的索引加载器,在它正常工作时将其移到了 SageMaker 训练中。现在,我正在 16 个ml.p4d.24xlarge实例上运行,或者说 128 个 A100 GPU。明天,我将在 24 个ml.p4d.24xlarge实例上进行完整的运行,处理 5000 万张图片,或者 192 个 GPU。如果我能做到端到端运行,你也可以!

在本章中,我将与您分享整个管道的优化方案,但现在,让我们拆解一下这条训练流程中的一个关键环节,这对为您选择的模型准备数据至关重要:分词器。

创建嵌入——分词器和其他智能特征的关键步骤

现在,您已经测试并构建了数据加载器,并可能进行了扩展,您可能会在想,我该如何处理这些原始图片和/或自然语言字符串?我是否直接将它们丢进神经网络?事实上,过去五年的学习表示已经明确证明了这一点:不,您不应该直接将原始图片或文本输入到神经网络中。您应该通过使用另一个模型将原始输入转换为嵌入。

这个直觉非常简单:在你教会模型如何识别数据集中的关系之前,你首先得向它介绍数据集的概念。创建嵌入基本上就是这么做的;你使用一个已经通过其他过程训练过的数据结构来创建你数据的向量表示。也就是说,你将原始文本和图像作为输入,然后得到高维的向量作为输出。这些向量是通过你希望它能够捕捉到数据之间细微关系的有效过程生成的。在多模态设置中,像 Stable Diffusion 这样的模型,你实际上会使用不同的过程来处理视觉和语言的嵌入,将它们分别输入到你的模型中,并通过学习循环进行集成。

自然语言通常使用一种叫做分词(tokenization)的过程。每个模型都有一个独特的分词器,这个分词器是基于特定词汇表训练出来的。如果你想要预训练或微调一个类似于 GPT-3 的模型,你需要下载与模型一起提供的分词器,并将其应用到你的数据集上。这个分词器会有独特的方式将字符串拆分成单词、子词或字符,具体取决于模型的不同。最终,每个词元都会被转换成一个高维向量,或者用更简单的术语来说,就是一个非常长的数字列表。我们称之为向量嵌入(vector embeddings)。许多词嵌入还包括位置编码(positional encoding),这是一种用数值表示特定单词或词元在句子中相对于其他单词位置的方式。这种位置编码帮助基于变换器(transformer)的模型理解该数据集中特定单词的含义。如果你正在预训练一个全新的模型或数据集,你可能最终需要训练你自己的分词器。

在计算机视觉中,一种常见的生成图像嵌入的方式是使用预训练的视觉模型来创建特征。这意味着你可以使用一个完全训练好的计算机视觉模型,比如对比语言-图像预训练CLIP),并将权重设置为仅用于推理。这就相当于冻结权重。也就是说,当图像通过这个网络时,网络会创建图像的密集表示,而不是正式地做出预测。然后,这个密集表示会与可训练的模型进行交互,这个模型才是你实际用梯度下降算法训练的模型。

现在,让我们通过在 SageMaker 上训练 Stable Diffusion 的示例来使这些概念更加具体化。

图 6.6 – 导入库

图 6.6 – 导入库

首先,你会看到我指向了两个关键的库:diffuserstransformers。它们都是来自我们在 Hugging Face 的朋友们!

transformers 库提供了许多有用的自然语言处理方法和技术。diffusers 库也提供了类似的功能,只不过它是针对基于扩散的模型。扩散模型通常可以生成高质量的图像,通常通过提供自然语言提示。这意味着您可以提供自然语言提示,并让模型为您生成图像!

在前面的代码片段中,我们只是指向我们将用来特征化图像和文本对的基础模型和分词器,这些是我们训练 Stable Diffusion 模型所需的。之后,我们需要正确地下载它们。

图 6.7 – 导入模型以训练 Stable Diffusion

图 6.7 – 导入模型以训练 Stable Diffusion

为了节省我庞大的 GPU 集群的时间,我提前下载了这些模型。我将它们保存在我的 S3 存储桶中,然后创建了一个训练渠道,指向当我运行 SageMaker 训练作业时的 S3 路径。脚本随后从训练集群的路径读取它们,这些模型在作业开始时已经下载到该路径。

渠道只是将您的 SageMaker 训练作业指向任何支持的数据输入。这可以是一个 S3 路径、一个 FSx for Lustre 挂载,或一个 EFS 卷。渠道是组织作业中不同输入的便捷方式。您可以为指向数据中不同切分的部分创建渠道,例如训练集和验证集、基础模型、脚本或任何您想要的内容。这些会作为作业参数进行跟踪,您可以看到它们与作业的其余元数据一起存储。它们也是可搜索的。SageMaker 会在实例启动后复制、流式传输或挂载您的渠道,因此请确保尽量减少复制时间,因为这将有助于降低成本。

接下来,我们需要冻结权重。这与将其设置为“不可训练”或“仅推理”是一样的。它意味着我们只想要数据通过该模型的结果,而不是预测。幸运的是,这个语法非常简单。

图 6.8 – 冻结不可训练模型的参数

图 6.8 – 冻结不可训练模型的参数

之后,我们需要处理原始数据,将其输入到神经网络中。这时,分词和特征化就显得尤为重要。

图 6.9 – 图像预处理

图 6.9 – 图像预处理

这个代码片段应该比较容易理解。我们传入训练集。这个函数明确期望有两列,一列是图像路径,另一列是图像的描述。然后,它使用 Python Image 对象来简单地从磁盘读取所有图像并将它们转换为机器可读的格式。通常,这意味着三通道,每个通道分别对应红色、绿色和蓝色。每个通道是一个二维数组,或者是一个简单的浮点像素值列表。读取完图像后,函数接着会对描述进行分词处理。这个脚本使用 ClipTokenizer 来解析提供的自然语言文本。

这个函数在我们创建了 DataSetDict() 对象后应用,就像本章前面笔记本中展示的那样。我们指向训练集,应用转换,然后我们终于可以将其传递给数据加载器了!

图 6.10 – 指向训练数据集

图 6.10 – 指向训练数据集

现在我们已经学习了如何构建、测试和扩展我们的数据加载器,让我们来学习 AWS 上可用的整个数据流的不同优化方法。

优化 Amazon SageMaker 上的数据管道

记住,我们已经学习了 Amazon SageMaker 上的短暂训练,在那里你可以无缝地启动从几到几百、甚至几千个 GPU,运行完全托管的远程实例。现在,让我们学习如何优化数据发送到 SageMaker 训练实例的不同选项。

如果你曾经使用过 SageMaker 训练,你会记得你的任务经历的不同阶段:启动实例、下载数据、下载训练镜像并调用它,然后上传完成的模型。

这是我 2022 年 re:Invent 演示中的一个截图,展示了 Stable Diffusion。你可能会问,我怎么能在仅仅两分钟内下载 5000 万对图像/文本呢?答案是优化的数据管道。在这个案例中,我使用了 FSx for Lustre。

图 6.11 – 训练任务状态

图 6.11 – 训练任务状态

对于非常小的数据集,比如只有几十 GB 的数据,直接将 S3 作为输入训练通道是完全可以的。当你使用 S3 作为训练输入时,SageMaker 可以在训练过程中以复制(文件模式)或流式传输(管道模式或快速文件模式)方式处理你的文件。数据的移动通常是一个缓慢的过程,这里受到主训练机器带宽的瓶颈限制。使用文件模式将 S3 作为输入,可能会让你的训练时间增加数十分钟,随着数据集规模的扩大,可能会增加几个小时甚至更长时间。例如,当我训练 100 GB 数据时,如果使用 S3 作为输入数据模式而不进行流式传输,训练时间就会增加整整 20 分钟。遗憾的是,我需要为这段等待时间付费,因为实例已经初始化,所以优化我的数据管道是对我最有利的选择。

在某些情况下,S3 复制选项的简单且具有成本效益的替代方案是流式传输,可以使用管道模式(Pipe Mode)或快速文件模式(Fast File Mode)。管道模式需要您在本地做一些脚本修改,但幸运的是,快速文件模式则不需要!然而,快速文件模式在处理大量文件时已知存在扩展性问题。为了解决这个问题,并处理数百到数千个 GPU 的数据加载,我们通常推荐使用 FSx for Lustre。

FSx for Lustre 是一个分布式文件系统,能够轻松连接到 S3 中的数据存储库,挂载到您的 SageMaker 训练任务上,并代表您执行高吞吐量的训练循环。这是因为它从 S3 读取数据一次,然后将数据存储在缓存中,并且通过挂载水平扩展读取操作。换句话说,一旦数据加载到 Lustre 中,训练循环的吞吐量读写会随着加速器的数量线性扩展。

您需要在 VPC 中创建 Lustre,也就是说,在 AWS 上的虚拟私有云中创建 Lustre。这对处理个人身份信息或在高度监管行业中工作的人员来说是个好消息。通过使用 VPC,您可以在云上构建和维护一个私有网络,利用安全性和网络控制来管理流量并确保对高度受限内容的访问。

说实话,管理来自 S3 数据存储库的流量并确保安全访问相当直接。通常我大约需要二十分钟,过程中偶尔会遇到一些小问题,这包括了卷创建的时间。

以下是在创建 Lustre 时建立数据存储库的方法:

  1. 首先,指向包含所有数据的 S3 路径。

  2. 其次,确定您想要设置的策略类型。导入策略将决定 Lustre 如何自动从 S3 获取数据,而导出策略则决定 Lustre 如何自动将数据推送到 S3。

最后,这里是我加载了 9.5 TB 稳定扩散图像/文本对后的卷视图:

图 6.12 – 我的 FSx for Lustre 卷

一旦创建了 Lustre,您需要花大约三十分钟左右的时间来测试和完善从 SageMaker 到 Lustre 的连接。这包括配置 VPC 及其相关子网。目前,以下是关键步骤:

  1. 确保您的目标 VPC 中有一个互联网网关。

  2. 确保创建 Lustre 的子网有通往该网关的路由。

  3. 确保该子网的安全组允许以多种方式定义的进出流量。

  4. 为您的目标存储桶建立一个 S3 VPC 终端节点,以允许 SageMaker 在完成后将模型结果上传到 S3。

我见过一些配置,它们有两个子网,一个用于与实际的公共互联网交互以执行 pip install 新包,另一个用于运行训练任务。就个人而言,我跳过了这个过程,通过构建一个包含所有包的 Docker 容器,然后将其加载到 ECR,在启动训练任务时指向它。

当你运行训练作业时,如果想指向特定的 VPC,确保将相关凭证传递给估算器。你还需要传递一些额外的参数来指向 FSx for Lustre。

最后,你还可以直接将 Lustre 挂载到你的笔记本电脑上!在这种设置中,你需要重新构建笔记本实例以连接到相同的 VPC 凭证。实际上,启动 Lustre 作业时并不需要这样做,但要直接挂载卷时是必须的。这里有一个很好的脚本,可以帮助你完成这个操作 (1)。如果你想更详细地了解每种选项的优缺点,请查看我们关于这个话题的博客文章 (2)

现在你对如何优化数据管道选项,指向 SageMaker 进行训练循环有了更好的了解,让我们退后一步,评估一下在 AWS 上大规模下载和转换数据集的几种选项!

在 AWS 上大规模转换深度学习数据集

在这一点上,你一定在想,我现在知道如何构建和测试我的数据加载器,甚至将我的数据放到 FSx for Lustre 上,以便与 SageMaker 训练集成。但如果我需要提前进行大规模的下载或转换怎么办?如何以大规模、具有成本效益且简单的方式完成这些操作?

虽然有许多不同的工具和方法可以解决这个问题,但我个人最喜欢的始终是采取最简单、最经济且最具可扩展性的方法。对我来说,实际上这是使用 作业并行性 在 SageMaker 训练上实现的。

事实证明,SageMaker 训练是一项非常广泛的计算服务,你可以用它来运行几乎任何类型的脚本。特别是,你可以用它并行运行大型 CPU 数据转换作业。你可以运行的 SageMaker 训练作业数量没有上限,我们有客户每天运行 数千个作业 来训练模型,以满足他们独特的业务需求。这可能是为广告、个性化推荐、定价或其他增强功能训练小型模型。

对于我的 Stable Diffusion 案例研究,我实际上使用了 18 个并发的 SageMaker 作业来下载我的所有数据!首先,我使用了一个大的 CPU 作业来下载 Laion-5B 数据集中的所有 Parquet 文件。然后,我对它们进行循环,将每个 Parquet 文件发送到它自己的作业。它大致看起来是这样的:

图 6.13 – 使用作业并行性大规模转换数据

图 6.13 – 使用作业并行性大规模转换数据

你看到我实际上在运行 18 个不同的作业吗?这样,你可以轻松追踪、管理和评估每个作业。所有结果都返回到 S3 —— 在这种情况下,是通过工具本身,它代表我写入 S3。现在我甚至不需要使用 Spark!我可以根据需要运行任意多的 SageMaker 作业,使用 Python 和其 multiprocessing 包来执行所需的多个任务。

图 6.14 – 数据处理脚本

图 6.14 – 数据处理脚本

你可能会问,Python 的multiprocessing是如何工作的?其实很简单。关键在于Pool.map()这个过程。首先,你通过提供可用 CPU 的数量来创建池。你可以使用multiprocess.cpu_count()方法查找这个数量。然后,你将两个对象传递给map():第一个是你想分发给所有进程的对象列表,第二个是你希望在列表中的每个对象上执行的函数。基本上,这就是一个for循环的概念,不过在这里,你不仅使用一个进程,而是使用实例上所有可用的进程。这意味着,如果你从 2 个 CPU 增加到 96 个 CPU,你的运行速度将提升超过 10 倍。

将尽可能多的数据转换工作交给 CPU 处理是个不错的主意,因为 CPU 非常便宜。以我每小时使用 192 个 GPU 与 18 个基于 CPU 的作业的成本做比较,CPU 的成本大约是 GPU 的 13 倍便宜!

如你所料,我们实际上有数百种其他方法可以在 AWS 上操作数据。我这里不打算详细讲解这些内容,但你可以随时自己去探索。

总结

在本书的这一部分,以及在你的项目中,你应该已经构建、测试并优化了一个完全可用的数据加载器,且在本地笔记本和 SageMaker 训练实例上都能正常工作。你应该已经确定、下载、处理并准备好整个数据集,准备通过训练循环运行。你应该至少用数据集中的一个小样本(例如 100 个样本)完成过一次完整的训练循环。你应该已经确定如何将大型数据集发送到 SageMaker 训练实例,可能是使用 FSx for Lustre,你应该已经建立、测试并投入使用。你还应该了解其他一些在 AWS 上存储和处理数据的方法。

你应该非常熟悉做出能够降低项目成本的架构决策,比如选择基于 CPU 的数据下载和处理,并使用 Python 的multiprocessing包,轻松地将任务分发到所有可用的 CPU 上。你也应该能够轻松地在 SageMaker 训练中并行化作业,使得你可以同时运行不同的作业,每个作业处理项目的不同部分。

现在你已经完全准备好数据集,在下一章中,我们将进入主题:训练你的模型!

参考文献

请参阅以下内容,了解本章中涉及的几个主题的更多信息。

  1. amazon-sagemaker-notebook-instance-lifecycle-config-samples: [github.com/aws-samples/amazon-sagemaker-notebook-instance-lifecycle-config-samples/blob/master/scripts/mount-fsx-lustre-file-system/on-start.sh](https://github.com/aws-samples/amazon-sagemaker-notebook-instance-lifecycle-config-samples/blob/master/scripts/mount-fsx-lustre-file-system/on-start.sh

)

  1. 为你的 Amazon SageMaker 训练 作业选择最佳数据源aws.amazon.com/blogs/machine-learning/choose-the-best-data-source-for-your-amazon-sagemaker-training-job/

第三部分:训练你的模型

在第三部分,你将学习如何训练大规模语言和视觉模型。你将学习如何找到合适的超参数,确保损失下降,并解决持续的性能问题。

本节包含以下章节:

  • 第七章找到正确的超参数

  • 第八章在 SageMaker 上进行大规模训练

  • 第九章高级训练概念

第七章:寻找合适的超参数

在本章中,你将深入探讨影响顶级视觉和语言模型性能的关键超参数,如批量大小、学习率等。首先,我们将为那些新手或需要简单复习的人提供超参数调优的快速概述,并包括视觉和语言中的关键示例。接着,我们将探讨基础模型中的超参数调优,既包括当前的可能性,也包括未来可能出现的趋势。最后,我们将学习如何在 Amazon SageMaker 上进行超参数调优,逐步增加集群大小,并在此过程中调整每个超参数。在本章中,我们将覆盖以下主要内容:

  • 超参数——批量大小、学习率等

  • 调优策略

  • 基础模型的调优

  • 使用 SageMaker 按世界规模进行扩展

超参数——批量大小、学习率等

超参数决定了深度学习中大多数关键决策点。它们像是你、你的模型、你的数据集和你的计算环境之间的中介。你将学习到如批量大小、学习率、注意力头数量等术语,以平衡你当前问题的整体解决方案,平衡成本,并确保在训练和推理过程中模型的最佳性能。

内存不足 错误。较大的批量大小帮助你快速通过训练循环,但如果你没有足够频繁地运行优化器,它可能会导致无法捕捉数据集中的所有变化。这个核心的权衡是你需要熟悉并学习解决的方法。提示:接下来的整个部分都将介绍一种名为超参数调优的方法。

学习率几乎像是整个学习过程的方向盘,控制着梯度下降优化过程。字面上讲,它是你用来参数化更新可训练权重的步长。较小的学习率意味着你在梯度上走小步,理想情况下沿着损失曲线下降,但这可能会显著减慢你的工作进度。较大的学习率意味着你在损失曲线上走大步,虽然这可以加速你的工作,但也有可能导致陷入所谓的局部最小值,或是梯度下降函数中的小谷底。基本上,这意味着你的模型欠拟合;循环会认为训练已经完成,因为优化器指示损失已经平稳,但模型实际上只是卡在了一个小的损失谷底。正如之前所述,这引入了另一个核心的权衡,超参数调优非常适合帮助我们解决这个问题。学习率调度器是解决这个问题的一步,允许你在循环开始时选择一个足够大的值,并逐渐减小它。

让我们来看一下影响著名视觉和语言模型性能的各种重要超参数。

视觉和语言中的关键超参数

让我们来看看一些关键的视觉和语言超参数:

  • 批处理大小 – 每个训练步骤中,模型从 GPU 内存中提取的对象数量。较高的批处理大小可以加速训练,而较低的批处理大小可能提高泛化性能。梯度噪声尺度似乎是预测最大批处理大小的一个有前景的途径。

  • 学习率 – 一个术语,用于确定在梯度下降优化过程中可训练权重应更新多少。较大的学习率加速训练,可能导致过拟合,而较小的学习率可能导致欠拟合,无法充分学习训练数据。如前所述,这些通常与调度器配对使用。

  • 训练轮数 – 完整数据集的总遍历次数。较少的轮数减少训练作业的总运行时间,而较多的轮数可以提高准确性。然而,设置这个数字过大可能会浪费资源并导致过拟合。在 第九章 中,我们将学习如何使用规模定律来解决这个问题。

  • 注意力头数 – 模型中使用的自注意力头的总数。这是模型训练参数总大小的一个重要决定因素。当你看到 GPT-2 到 GPT-3 的大小跃升时,通常是因为更多的注意力头和更大的头部。

  • 序列长度 – 训练循环中作为一个对象使用的令牌总数。这在语言模型中特别相关,因为训练循环中的每一步都使用句子的一部分来预测另一部分。令牌大致对应于单词。这意味着序列长度几乎可以普遍理解为每个预测步骤中的单词数。这直接影响训练和推理。对于推理,这意味着这是该模型可以使用的最大单词数。对于训练,它可以直接增加或减少 GPU 内存占用。

还有无数其他超参数。你将会看到一些特定于不同 SDK 的超参数,例如 Hugging Face 的 transformersdiffusers,它们允许你定义训练作业的各个方面,比如基础模型名称、数据集名称、数据类型等。SageMaker 也有适用于我们分布式训练库的超参数,例如优化器状态分片、张量并行、激活检查点和卸载等。在 SageMaker 训练作业 API 中,你还可以定义并引入任何你喜欢的任意超参数。

调优策略

从某种意义上说,超参数调优是一种大规模猜测和验证的艺术与科学。通过使用复杂的算法和策略,你实际上可以训练一整批模型,在各种配置中测试整个超参数范围。你的调优策略最终将帮助你找到最佳的模型,并最终确定在更大规模下使用的关键超参数。我见过超参数调优帮助客户将准确性提升从不到 1%到超过 15 个百分点不等。如果这能够直接转化为商业回报,你就能理解为什么它是一个有吸引力的方案。

超参数调优有很多策略和技术方案。这些方案有一个共同点,即作为最终用户,你需要选择你想要测试的超参数及其范围。许多超参数调优方案会为你提供默认值作为起点,并附有相关文档。在你逐步使用你偏好的超参数调优方案时,我建议你为研究这些超参数预留足够的时间,并且要深入了解其中的一些。如果你计划将来面试数据科学岗位,那么你应当花大量时间理解这些超参数,特别是它们如何影响模型的表现。

大多数超参数调优方案实际上会为你训练从几到几百个模型,每个模型的超参数配置略有不同。在调优过程结束时,你应该能在你偏好的指标上看到改善,例如损失的降低或准确率的提高。你可能会问,这些方案是如何找到并选择最佳超参数的?答案是通过调优策略

调优策略是一种优化方法,它通过测试各种配置并根据预定义的性能指标评估每个配置。这些策略在几个维度上有所不同。有些仅仅是随机猜测,另一些尝试逻辑地填充某个空间,部分使用基本的机器学习算法,还有一些则使用极其复杂的机器学习算法。除了搜索方法外,它们在搜索的时机上也会有所不同。有些调优方法会同时或并行运行所有实验,这样的优势在于整体任务完成得更快。其他方法则是顺序运行,在测试一些配置后才进行下一组测试。虽然这种方式可能最终达到更高的准确性,但缺点是整体运行时间较长。我们来看一些常见的超参数调优策略及其权衡。

以下是一些常见的超参数调优策略:

  • 随机搜索 – 顾名思义,随机搜索是一种调整策略,它通过随机性来评估你的搜索空间。例如,假设你想探索从 2 到 26 的批量大小,并且使用随机搜索,你指定希望运行 4 个任务。你可能会同时运行 4 个任务,每个任务的批量大小随机选择,例如 4、7、17 和 22。你的调整方案应该告诉你哪个任务在你偏好的指标上表现最好。

  • 网格搜索 – 与随机搜索相反,网格搜索将建立一组有序的实验来平衡你可用的搜索空间。例如,使用与前面相同的批量大小配置,但使用网格搜索,你可能最终会同时运行 4 个任务,批量大小分别为 8、14、20 和 26。和上次一样,这些任务将同时运行并给出表现最好的模型。

  • 贝叶斯搜索 – 贝叶斯搜索通过两种方式将这个基本概念颠倒过来:

    • 首先,它是一种顺序调整策略。这意味着它会同时运行几个任务,然后评估它们的结果,并启动另一组实验进行运行。

    • 其次,它实际上使用机器学习算法来选择超参数。通常,这是一种简单的逻辑回归;通过使用模型的元数据作为输入,预测下一组超参数的值。自 2018 年以来,我们至少在 Amazon SageMaker 中提供了这一功能!顺便提一下,SageMaker 也支持随机搜索和网格搜索。

  • Hyperband – 由一个研究团队 (1) 在 2018 年提出,Hyperband 策略实际上专注于优化随机搜索。它们开发了一种无限臂赌博机,能够自适应地探索并选择调整配置,使用预定义的偏好。这与强化学习非常相似!在 AWS,我们将其与一种称为异步连续减半算法ASHA(2)的大规模并行策略相结合,该策略利用并行性和激进的早停技术。我们已经证明,这些解决方案能够支持大规模调整,例如用于视觉和语言模型。我们的测试 (3) 显示,相比于随机和贝叶斯策略,它们的加速分别达到约 5 倍和 4.5 倍。

如你所见,我基本上是按照从简单到复杂的顺序列出了搜索策略。在你的学习旅程中,你也可以将这个目标路径作为参考。先从最简单的调整策略入手,然后随着时间的推移,逐步向更复杂的策略过渡。

你可能已经猜到的另一个主题是必须平衡成本和准确度提升。看看你的搜索策略在哪里运行,以及它们是如何运行的;它们是否高效地使用计算资源?当增益放缓时,它们会继续运行任务和实验,还是会在增益停止时果断关闭你的资源?

最后,了解当你围绕模型构建一个完整应用时,你很可能希望在重新训练管道中集成调优策略。比如,你在 SageMaker 上部署了一个视觉或语言模型,当新数据到达时,你会触发一个管道来重新训练你的模型。在这个管道中,一个非常重要的资源就是调优你的模型,以确保你获得最高的准确率。更多内容请见第十四章

现在,让我们探索在基础模型中调优超参数的独特挑战和方法。

基础模型的超参数调优

基础模型在超参数调优上存在一些独特的挑战。让我们来试着理解这些挑战:

  • 模型大小 – 可能是调优基础模型时最大的问题就是它们的庞大规模。我们之前提到的许多经典调优策略都依赖于尽可能多地训练模型。当仅仅将模型的一个副本保存在内存中就需要数十个加速器时,这种方法的经济性就会崩溃。

  • 下游任务的数量 – 正如我们在本书中所见,基础模型的候选下游任务数量庞大。这使得超参数调优变得更加复杂,因为每个任务的目标指标都是独一无二的。选择正确的下游任务本身可能就是一种调优挑战!

  • 超参数的多样性 – 在这些规模下,相关的超参数不仅仅是训练过程的指示符。它们还涉及分布式技术,比如之前我们提到过的模型并行和数据并行。

我们应该如何思考克服这些挑战?这里提出了一种方法;基本上,你可以在数据集的小样本上高效地调优超参数。这意味着你可以使用 1%的数据进行大规模的超参数搜索,并且这有助于你在工作开始时找到正确的设置。

另一种方法,正如我们之前提到的,是一种更高效的调优策略,叫做Hyperband。通过这篇博客文章(4),你可以看到如何将其与 SageMaker Training 集成,且有一个 Cifar10 的示例。

这就是故事的结局吗?我不这么认为。如今,基础模型开发领域中的大部分工作都依赖于他人的成果,包括重用他们的超参数,或者在大规模数据集和加速器规模上进行非常轻量的实验;我觉得这种做法最终会与超参数调优策略相结合。此外,考虑到我们将在第十章和第十五章中学习的一些参数高效的微调策略,我们可能会看到超参数调优在预训练过程后调整模型时变得更加相关。我们还将在第十三章中讨论调优推理请求的策略。

接下来,让我们看看如何将调优实验扩展到处理大模型和大数据集,除了在 SageMaker 上进行超参数调优之外。

使用 SageMaker 按照世界规模进行扩展

在本节中,我们将分解两个你需要掌握的关键概念,尤其是在分布式训练的背景下。第一个是扩展的概念,特别是使用超参数调优作为一种方法,在最终运行大规模训练任务之前先进行小规模实验。第二个是使用 SageMaker 提供的超参数调优技巧和窍门。

在数据样本上进行调优,并根据世界规模更新

正如你在本章中学到的,超参数调优是提升性能的好方法,但它可能需要大量的计算资源,执行大量的实验。你可能在想,如何将这种方法轻松应用到我的用例中,尤其是在数据集大小至少有几百 GB,甚至可能有几 TB 或更多的情况下? 答案就是从一个小样本开始!

在数据集的极小一部分上进行调优的目标是查看模型对其关键超参数变化的敏感度。在 1% 的样本上,你可能对一些核心算法设置感兴趣,比如注意力头数、优化器或层操作的变化、序列长度,以及任何其他在整体训练循环中至关重要的设置。如果你看到一个大的提升,那就意味着你可能需要更多关注这个超参数,或者将调优直接集成到你的训练任务中,或者简单地增加一个检查,以确定什么设置在大规模下能带来最佳性能。你还可以调优批量大小和学习率,包括其预热阶段,以查看哪种设置效果最好。

正如我希望你已经想到的,如果你仅在整个数据集的 1% 上进行调优,那么你只需要使用你整体计算资源的一小部分!这意味着你可以并且应该计划使用非常小的实例进行超参数调优,比如 ml.g5.12xlarge 或更小的实例。然而,一旦你准备好扩展到更多的实例,你将需要根据整体的世界规模来更新你的关键超参数。

记住,世界规模只是一个用来计数你训练集群中所有 GPU 或加速器的术语。如果你有 2 个实例,每个实例配有 8 个 GPU,那么你整体的世界规模就是 16 个 GPU。你的一些超参数应该在每次改变世界规模时更新,因为它们决定了你的模型如何与训练环境交互。特别是批量大小和学习率。

比如,在我们之前的 16 个 GPU 示例中,假设你通过超参数调优找到了合适的每设备批次大小为 22 和学习率为 5e-5。接下来,假设你想将实例数增加到 4 个,每个实例配备 8 个 GPU,总共得到 32 个 GPU。这个从 16 到 32 的跃升显然是一个倍增,将加速器数量增加了 2 倍。我们会对全局批次大小和学习率应用相同的比例调整,使它们和世界大小一起扩展。

简单的超参数调优扩展示例

接下来我们按以下示例逐步进行:

原始

  • 两个实例,每个实例配备八个 GPU

  • 世界大小 = 16

  • 每设备批次大小 = 22

  • 学习率 = 5e-5

增加的 集群大小

  • 四个实例,每个实例配备八个 GPU

  • 世界大小 = 32

  • 每设备批次大小 = 22

请注意,每设备批次大小不会随着世界大小的增加而必然发生变化。然而,具体取决于你的脚本,确保你了解自己是提供每设备批次大小还是全局批次大小。当然,全局批次大小是需要进行调整的!

学习率 = 5e-5 * 2 = 0.0001

在随着整体世界大小的增加,更新批次大小和学习率的同时,确保也考虑到模型本身的大小。这可能包括增加更多的参数、更多的注意力头、更深的层次等等。正如我们所见,这是最终得到更精确模型的重要指标。例如,在我们公开的训练大规模 GPT-2 模型的示例中,提供了三种不同配置的模型,并为每个模型大小选择了相应的超参数:

图 7.1 – 模型配置参数

图 7.1 – 模型配置参数

你可以看到,对于30b参数的模型,我们建议将头数设置为64,层数设置为48,隐藏宽度设置为7168,训练批次大小为5

然而,对于仅有1.5b参数的更小模型,我们将头数设置为24,隐藏宽度为1536,训练批次大小为2。你可能会问,为什么一个更小的模型使用更小的批次大小?这是不是有些反直觉,因为更小的模型应该占用更少的 GPU 内存,从而可以增加批次大小?

问题的答案是肯定的,理论上来说,更小的模型应该使用更大的批次大小,但在这种情况下,因为我们在大模型上实现了显著的模型并行性,它实际上抵消了这种影响,并且具有较小的 GPU 内存占用。

如果你感兴趣的话,隐藏宽度参数实际上只是你神经网络内层的大小。我们称它们为“隐藏层”,因为它们位于黑盒内部;在输入层和输出层之间。这个非常符合整体模型大小的逻辑;一个参数数量更大的模型,隐藏宽度也应该更大。

最后,我们快速看一下在 SageMaker 上进行超参数调优的情况。

使用 Amazon SageMaker 进行调优

使用 SageMaker 进行超参数调优非常简单,并且你有几个选项。首先,和往常一样,你可以直接在脚本中添加任何调优策略,并在训练集群上执行它。你可以通过网格搜索来完成这一操作,简单地将自己的脚本导入并运行。

然而,随着规模的扩大,特别是在将调优集成到重训管道中时,你可能最终希望使用我们完全托管的 HyperparameterTuner。这本质上是一个对象,它将你的训练任务(以预构建的估算器形式)与一些其他规格结合在一起:

图 7.2 – 定义调优对象

图 7.2 – 定义调优对象

你定义了目标指标、超参数及其范围,以及你希望运行的总任务数和并行任务数。这些默认设置将使用贝叶斯优化。事实上,在这个示例中,它们会同时启动最多三个实例,并重用它们以运行最多九个任务。

你可以通过增加早期停止,或者使用我们之前学到的 Hyperband 算法来增强这一点。你可以通过将它作为另一个参数添加到这个函数中来指定该策略。 (5)

在目标指标方面,你会很高兴知道你可以带上任何你想要的。我们所做的就是查看你的任务的 CloudWatch 日志,寻找指标定义。老实说,我发现这是整个过程最困难的部分:将你的正则表达式字符串准确匹配到训练任务的输出。在一个 PyTorch MNIST 示例中,下面是它的样子:

图 7.3 – 为任务配置定义调优指标

图 7.3 – 为任务配置定义调优指标

你可以看到我们要求你编写一个正则表达式字符串并将其提供给这个对象。然后,这应该直接与训练脚本中定义的内容匹配:

图 7.4 – 在你的训练脚本中定义调优指标

图 7.4 – 在你的训练脚本中定义调优指标

为了更好的效果,这里有一个超参数范围的可视化图,方便你查看它们是如何定义的:

图 7.5 – 定义超参数范围

图 7.5 – 定义超参数范围

我们还有另一种方法,我认为它设计得特别好。它允许你通过将调优任务导入 pandas DataFrame 来进行分析!相关的笔记本在这里 (6)

图 7.6 – 调用 tuner.dataframe()

图 7.6 – 调用 tuner.dataframe()

就是这样!让我们快速回顾一下你在这一章中学到的内容。

总结

在本章关于超参数调优的内容中,你学习了什么是超参数,包括批次大小、学习率、训练轮数、注意力头的数量、序列长度等。你学习了如何使用超参数调优来提高模型的性能,以及实现这一目标的最佳策略。你还学习了如何扩展调优,从数据集的 1%开始,然后根据你的整体 GPU 世界规模调整关键超参数。最后,你学习了在 Amazon SageMaker 上实现这一切的关键功能。

在下一章中,我们将学习大规模分布式训练!

参考文献

  1. Hyperband: 一种基于赌博机的新型超参数 优化方法: arxiv.org/pdf/1603.06560.pdf

  2. 一种大规模并行超参数 调优系统: arxiv.org/pdf/1810.05934.pdf

  3. Amazon SageMaker 自动模型调优现在提供最高三倍速度的超参数调优,使用的是 Hyperbandaws.amazon.com/blogs/machine-learning/amazon-sagemaker-automatic-model-tuning-now-provides-up-to-three-times-faster-hyperparameter-tuning-with-hyperband/

  4. amazon-sagemaker-examples: github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/smp-train-gpt-simple.ipynb

  5. HyperparameterTuner: sagemaker.readthedocs.io/en/stable/api/training/tuner.html

  6. amazon-sagemaker-examples: github.com/aws/amazon-sagemaker-examples/blob/main/hyperparameter_tuning/analyze_results/HPO_Analyze_TuningJob_Results.ipynb

第八章:在 SageMaker 上的大规模训练

在本章中,我们将介绍 Amazon SageMaker 提供的关键功能和特性,以便进行高效的分布式训练。你将学习如何优化脚本以适应 SageMaker 训练,并掌握一些关键的可用性特性。你还将了解 SageMaker 的后端优化,例如 GPU 健康检查、弹性训练、检查点和脚本模式。

本章将覆盖以下主题:

  • 为 SageMaker 训练优化你的脚本

  • SageMaker 训练的顶级可用性特性

为 SageMaker 训练优化你的脚本

到目前为止,你已经学到了很多内容!我们已经涵盖了从预训练基础到 GPU 优化、选择合适的用例、数据集和模型准备、并行化基础、寻找合适的超参数等等。这些内容绝大部分是适用于你选择应用的任何计算环境的。然而,本章专门面向 AWS 和特别是 SageMaker。为什么?这样你就可以掌握至少一种计算平台的所有细节。一旦你学会了如何在一种计算平台上变得熟练,那么你就能够将它用于任何你喜欢的项目!当出于各种原因需要过渡到另一个平台时,你至少能掌握过渡时所需要了解的基本概念。

首先,让我们看看你的脚本。大多数 SageMaker 训练脚本的核心至少包含以下三项内容:

  • 包导入

  • 参数解析

  • 函数定义和使用

接下来我们将逐一解析这些内容。

导入包

正如我们之前讨论过的,你可以安装并访问任何你需要的包。你有多种方法可以在 SageMaker 训练中使它们可用。至少,当你定义你的作业时,你可以带上一个包含已定义包的 requirements.txt 文件。然后,SageMaker 将使用 pip install 安装这些包到你的训练计算环境中,使它们可用。

或者,你可以构建一个预装了所有这些内容的基础容器。这无疑是最快的选择,因为它节省了训练过程中的时间。与其使用 pip install,不如使用一个预构建的镜像,所有的包都已包含。另一种选择是导入你自己的 Python 包,将整个项目发送到 SageMaker 训练环境中。然后,你可以导入你正在工作的代码。

参数解析

在 SageMaker 训练环境中,我们经常使用的一个非常常见的包是 argparse。如果你不熟悉它,让我来介绍一下。

一旦你构建了 Python 脚本,你可能需要通过不同的标志、设置或参数来运行它。其中一些可能是不同的超参数、模式或你希望脚本执行的功能。argparse包是 Python 中实现这一目标的绝佳方式。首先,在脚本中,你需要明确地为每个你想使用的参数添加一行代码。在 SageMaker 中,你可能会这样开始。

图 8.1 – 一个基本的参数解析函数

图 8.1 – 一个基本的参数解析函数

正如你在图 8.1中看到的,我只是导入了argparse,创建了parser对象,然后添加了一个名为train_folder的参数。默认情况下,它会查找我的环境变量,你可能还记得,SageMaker 训练通过这种方式将信息注入到你的环境中。如果你感兴趣,你可以通过 CloudWatch 日志查看任何 SageMaker 训练作业,了解所有可用环境变量的列表。这些环境变量包括你作业的所有元数据、所有超参数等等。

在这个简短的示例中,我指向了我的训练通道。当我创建训练作业时,通过指向 S3 或可选的 FSx for Lustre,我创建了这个训练通道。这就是我的训练数据。首先,我将其上传到 S3。然后,我在配置作业时指向它。SageMaker 将其复制到我的 SageMaker 训练实例,并加载到本地路径。这个本地路径通常是/opt/ml/input/data/train/这样的路径。当你想指向训练容器上的本地路径时,你调用args.train_folder,或者你定义的任何名称。要读取文件,你可以列出文件夹中的文件名,或将文件名作为另一个参数传递。

我个人喜欢保持脚本清晰整洁的方法是将所有的arg解析封装在一个专用函数中。然后,它会整齐地返回args对象。以下是完整脚本。

图 8.2 – 在主脚本中调用参数解析函数

图 8.2 – 在主脚本中调用参数解析函数

另一个常见的参数是model_dir。你可以将其指向SM_MODEL_DIR SM 环境变量。SageMaker 将在作业完成后,将你的模型从训练容器写入 S3。

你可以使用作业配置中的hyperparameters参数添加任何你想要的超参数。然后,你可以在脚本中使用这些超参数。我已经创建了指向诸如我的数据索引、如何运行我的脚本、检查点模型路径以及你项目中可能需要的其他无数参数的命令行参数。

函数的定义和使用

在此声明可能有些显而易见,你可以编写你想编写的任何软件。你可以直接从任何可访问的数据源读取和写入,启动其他作业,启动其他云资源,或使用开源包——可能性无穷无尽。

使用 mpi 调用你的脚本

当你使用分布式训练时,SageMaker 会通过 mpi 调用你的脚本。如前所述,这是一个在分布式训练中非常有用的核心库。我们将使用 mpirunsmddprun 来调用你的脚本。如你所见,我们会使用所有相关的参数来调用你的脚本。

图 8.3 – SageMaker 训练如何调用你的脚本

图 8.3 – SageMaker 训练如何调用你的脚本

这是一个非常复杂的示例,训练了 GPT-2 的数百亿参数,但它展示了你可以在 SageMaker 上配置分布式训练集群的多种方法。

日志记录与 CloudWatch

如你所知,你有很多日志记录的选项。打印语句是调试的好方法,但随着项目的发展,你可能会转向更为管理化的工具,比如 logging 包。记住,所有这些日志都会发送到 CloudWatch 中,因此你可以轻松查看和调试你的脚本。打开 AWS 控制台中的训练任务视图,滚动到底部,点击 查看日志。这将带你进入 CloudWatch,提供每个节点的日志流,每个日志流被命名为 algo。通常,顶部的日志流是主节点,但所有日志流都会尝试连接到主节点,因此你只需查看它们尝试连接的 algo。日志将在你的实例上线并且脚本被调用后开始记录,因此在任务开始后可能需要几分钟才能看到这些日志。

检查点

在 SageMaker 训练脚本中,另一个需要注意的参数是 检查点。在 SageMaker 中,检查点的作用不同于仅仅作为模型路径。模型路径将在训练任务结束时复制到 S3,但你的检查点 将在整个过程中被复制。这使得它们成为在任务中调试、运行 TensorBoard (2) 和从最新检查点重启的理想选择。

实现从检查点重启是一种非常高效的技术,值得学习和完善。这并不难——只需在 S3 中查找正确的路径,配置你的任务,然后确保你在正确的目录中查找你的基础模型。对于大规模任务,我们建议你至少每 2 到 3 小时创建一次检查点。这将帮助你应对训练过程中几乎肯定会出现的硬件、软件、网络、数据或其他问题。

若要查看更详细的示例,可以参考我们在 参考文献 部分 (3) 中的 GPT-2 训练示例。它实现了一个 load_partial 参数,指向你可以为检查点提供的 S3 路径。

通过 SageMaker 估算器配置任务

尽管你有多种方法可以运行你的 SageMaker 任务,特别是通过 UI、CLI 和 boto3,但最常见的方式可能是通过 Python SDK。

以下是一个可能的示例:

图 8.4 – 使用 SageMaker 估算器运行远程训练任务

图 8.4 – 使用 SageMaker 估算器运行远程训练任务

请注意,我们指向的是一个基础镜像,实际上是通过 PyTorch 对象来指向的。它指向一个基础的 AWS 深度学习容器,具体由你指定的框架版本决定。你可以通过指向 image_uri 来覆盖它,这需要是 Amazon ECS 中的 Docker 容器。在这个估算器中,你还可以传递一些关键参数,例如:

  • instance_countinstance_type 用于配置你的训练资源。

  • 你的入口点脚本及其源目录。这是 SageMaker 查找 requirements.txt 和你的主脚本以执行两个文件的地方。

  • 你的超参数 – 再次提醒,你根据自己的需求定义这些参数。

  • 你的分发参数。我们将在本章的最后一节中讲解它们。

接下来,让我们来看看一些 SageMaker 训练中的有趣可用性功能。

SageMaker 训练的顶级可用性功能

现在你对如何将脚本与 SageMaker 训练集成有了一些了解,我们来学习一下 SageMaker 的一些关键方面,它们让使用 SageMaker 变得尤其简单和有趣。

热池用于快速实验

一旦你的 SageMaker 任务上线,它将经历以下阶段:

  • 初始化资源

  • 下载你的数据

  • 下载你的训练镜像

  • 调用你的主脚本

  • 任务完成后,将模型文件上传到 S3

你可能会想,如果我的任务崩溃了,我需要更新几行代码怎么办?我需要从头开始完全重启整个集群吗?

幸运的是,答案是否定的!绝对不是。你可以使用托管的热池。只需添加一个额外的超参数 keep_alive_period_in_seconds,它将保持你的任务在线,即使脚本失败或完全完成。这非常有用,因为在许多情况下,前期的任务初始化实际上是你工作流程中最大的瓶颈。它可能需要几分钟,取决于小型基于 CPU 的实例,而较大型基于 GPU 的实例可能需要 8 分钟或更长时间来初始化。

从积极的一面来看,GPU 实例的等待时间最终为你节省了时间和金钱,因为我们在后台运行 GPU 健康检查,确保你只接收到好消息。消极的一面是,8 分钟的等待时间对于开发迭代之间来说实在是太长了。如果你只是更新一些非常简单的内容,比如一个基础的语法错误,那就特别痛苦了。

图 8.5 – 在控制台查看你的训练任务

图 8.5 – 在控制台查看你的训练任务

托管的热池通过以下方式为你解决了这个问题:

  1. 首先,将该超参数添加到你的任务配置中。

  2. 接下来,一旦任务完成训练,无论是成功还是出错,热池状态应该显示为可用

  3. 此后,当你提交另一个具有匹配的镜像 URI、实例类型和实例数量的作业时,它将显示正在使用状态,最终显示已重用,如 图 8.5 所示。

虽然通过使用托管的热池节省几分钟时间看起来可能不是一个巨大的收益,但它确实在大规模上积累起来。当你在与截止日期赛跑时,每一小时都至关重要,使用热池可能就是你是否能够按时完成任务的关键。它意味着在一个小时内,你可以轻松地更新你的脚本数百次,而以前你可能只能做到每小时大约更新 10 次。

SSM 和 SSH 连接到训练实例

一旦你的作业成功启动并运行,尤其是一个长期运行并包含许多复杂步骤的作业,你可以想象直接连接到实例、查看它并运行调试命令是多么有用。

幸运的是,我们有一个解决方案——我们的一组 ML SAs 构建了一个自定义设计模式,帮助你在自己的环境中启用这一功能 (1)。他们仔细听取了客户的意见,反复迭代需求,并开发了一个非常不错的项目。

你可以按照以下代码库中的步骤,在自己的 SageMaker 资源中安装这个功能,轻松地连接到正在运行的作业并分析它们。

图 8.6 – 在 SageMaker 训练作业中的 SSH

图 8.6 – 在 SageMaker 训练作业中的 SSH

从系统架构的角度来看,在评估这个解决方案时,有两条关键路径。 一方面,你可以使用完全托管的服务 AWS Systems Manager。这通常比 SSH 更安全,但功能上有些限制。如果你所需的只是打开一个终端,连接到远程实例,运行一些调试命令,并查看进度中的输出,这可能就是适合你的解决方案。设置起来并不难,你只需相应配置 IAM 和 SSM 资源。与热池结合使用时,这非常强大!

另一方面,你也可以直接使用 SSH。通常,SSH 的安全性低于 SSM,因为 SSM 使用的是托管的 AWS 服务,而 SSH 打开了一个可能性,即任何恶意用户都可以通过端口转发连接到节点。这意味着在企业环境中,在许多情况下,你最好从 SSM 开始。然而,SSH 允许你更新本地脚本并使用端口转发。这意味着,如果你想让某个东西将你的本地脚本无缝地传输到远程训练实例,SSH 是最合适的选择。然而,考虑到现在有了热池,你可能不再需要这个。SSH 解决方案非常适合你的 IDE 支持远程连接点的情况,比如 VS Code 或 PyCharm。

跟踪作业和实验以复制结果

我个人最喜欢的 SageMaker 训练功能,老实说,就是它最基本的功能——默认情况下,存储有关你的作业的所有信息并保持可搜索性!这就叫做元数据。每次提交时,所有的超参数、输入数据位置、图像、变量和其他作业信息都会被存储。这意味着你可以轻松地追踪你的作业,通过登录查看 CloudWatch 日志,随时从 S3 下载模型,添加标签来指定其他细节,等等。

图 8.7 – 在 AWS 控制台查看训练作业的元数据

图 8.7 – 在 AWS 控制台查看训练作业的元数据

所有这些数据都长期保存在你的账户中,你无需为此付费。你还可以使用 SageMaker Search 查找来自指定 S3 路径、实例类型或数量、超参数或任何可用值的精度最高的作业。最近,我们发布了一些新的功能,使得使用 SageMaker 训练变得更加轻松。其一是托管的 TensorBoard(aws.amazon.com/about-aws/whats-new/2023/04/amazon-sagemaker-hosted-tensorboard/),它让你轻松跟踪和比较实验。其二是新的 @remote 装饰器,它让你轻松地将本地函数转为远程作业!(aws.amazon.com/blogs/machine-learning/run-your-local-machine-learning-code-as-amazon-sagemaker-training-jobs-with-minimal-code-changes/?sc_channel=sm&sc_campaign=Machine_Learning&sc_publisher=LINKEDIN&sc_geo=GLOBAL&sc_outcome=awareness&sc_content=ml_services&trk=machine_learning&linkId=211795861)

现在,让我们通过学习后端优化来结束本章!

使用 SageMaker 进行分布式训练的后端优化

你已经学习了如何更新你的 SageMaker 训练脚本,并且你也更深入地了解了 SageMaker 在使用时一些有趣且友好的特性。现在,让我们通过探讨 SageMaker 如何优化大规模分布式训练的后端来结束本章内容。

正如你可能已经猜到的那样,SageMaker 可以在任何地方启动从几个到几千个 GPU。这是因为训练的核心服务提供——在你定义训练作业时,打开、编排和管理所有这些 GPU 的能力。你在定义这个集群时,以及你在本章早些时候学到的一样,使用 mpi 在所有节点之间进行通信。你可以存储所有的超参数和作业元数据,将所有的日志流式传输到 CloudWatch,连接到你喜爱的操作工具,确保节点健康,连接到 S3 中的数据,下载并运行你的镜像,等等。这种 大规模集群编排 完全是弹性的,可以轻松地从一个实例流动到数百个实例。

然而,编排这个集群并不特别有用,除非你的 GPU 健康状况良好。正如你在本书的早些部分所学到的,编写软件成功地编排单个 GPU 上数以万计的核心并不是一件小事。即使你更新了 CUDA、驱动程序和最新的深度学习框架,坏消息是你仍然可能会遇到糟糕的 GPU。硬件故障,特别是 GPU 故障是非常常见的。随着你将训练作业扩展到更多的 GPU,你在这个庞大的计算池中遇到一次 GPU 故障的概率也会增加。这就是为什么 SageMaker 提供的 GPU 健康检查 非常有用!我们可以追踪最新的 GPU 错误,并在我们的作业编排器中集成检查这些错误。这意味着当你在 SageMaker 上获得一个节点时,它更有可能是健康的。

即使进行了广泛的 GPU 健康检查和大规模作业编排,你的作业在开始之前可能仍会出现错误。你可能会遇到类似 容量不足错误 的情况,这表明你请求的实例类型在请求的区域内数量不足。你也可能遇到 内部服务错误,并不奇怪地告诉你在你这端出了问题。对于这些以及其他情况,设置 max_retry_attempts 非常有用;就我个人而言,每次运行超过 8 个实例的作业时,我都会将其最大化设置为 30 次。

虽然这对于成功启动作业非常有用,但我也有客户实现了另一个作业重启。这可能会在你通过训练循环的迷你批次时发生。当bf16数据类型被证明对大规模分布式 GPU 训练的稳定性有极大的改善作用时,仍然不罕见看到模型损失突然飙升、停滞或下降。你还可能看到总作业吞吐量的意外变化。如果发生这些情况,最好触发紧急检查点,终止作业,然后从相同的检查点和步骤号重新开始。将训练脚本中的一些附加功能与通过EventBridge监听的 Lambda 函数结合使用,是一种自然的做法。有关一些最佳实践的最新总结,请查看参考文献部分中的博客文章(4)

分布式训练库 – 模型和数据并行

正如你之前学到的,AWS 针对分布式训练进行了优化。这些方法在 SageMaker 上有效地扩展到了数百甚至数千个 GPU。让我们再详细看看它们。

还记得 AlexNet 之所以取得突破性成果,是因为它使用了多个 GPU 吗?从历史上看,最早的多节点深度学习方法之一被称为参数服务器。如下面的图所示,参数服务器是一种简单而有效的方式,用于大规模地协调分布式梯度下降。一个节点作为主节点,负责与工作节点同步梯度,检查节点的健康状况,并维护一个全局一致的模型版本。参数服务器可能稍显缓慢,但在带宽消耗方面更为高效。让我们通过图示来进一步了解。

图 8.7 – 分布式梯度下降的历史方法

图 8.7 – 分布式梯度下降的历史方法

然而,这种慢速性导致了稍微不同的方法。基于环的拓扑结构在底层使用AllReduce算法在所有节点之间进行通信,收集梯度的平均值,并将结果分发给每个节点。这是 Horovod 和 PyTorch DistributedDataParallel 中常见的基本方法,因其速度比旧版本更快而受到广泛使用。

然而,AllReduce作为一种基本的集体操作,在大规模下表现不佳。每增加一个节点,AllReduce步骤所消耗的带宽就会增加。这意味着,随着实例数量的增加,你的扩展效率会变差,最终导致实例的利用率低下,从而影响计算预算。

为了应对这种负面影响,AWS 开发了 自定义数据并行集合。这是在 AWS 云上获得最高性能的最佳方式。这一技术被称为 SageMaker 分布式数据并行 (SMDDP) (5),作为 SDK 提供,可以在容器中使用,并适用于任何支持的 SageMaker 作业。使用 SMDDP 可以确保您的大规模 GPU 作业运行尽可能快速和高效,将其作为任何支持的分布式软件的后端。SMDDP 还与亚马逊的弹性网络适配器(Elastic Fabric Adapter)集成,这是 AWS 上的一项低抖动、低延迟通信增强功能。通常,SMDDP 使您可以轻松地将其从深度学习框架中指向,将其设置为分布式后端。

幸运的是,从 2022 年 12 月发布开始,这项功能现在也可以在 模型并行 系列中使用。现在,您可以在 smp_options 对象中设置 ddp 后端,使用 ddp_dist_backend:auto。当这个新的后端选项与我们在 第五章 中讨论的 分片数据并行 配置结合使用时,它将带来额外的 30% 提升!

现在,让我们通过简短的回顾来结束本章。

总结

本章中,我们了解了 Amazon SageMaker 在大规模分布式训练中的关键功能。我们探讨了如何优化脚本,从导入包到解析参数、编写代码、使用 mpi 调用脚本、写入 CloudWatch 日志、检查点、与 SM 估算器一起使用等。我们涵盖了提高 SageMaker 可用性的关键功能,以使其更有趣且更易于使用,例如用于快速实验的热池、训练实例中的 SSM 和 SSH 以及作业追踪。最后,我们了解了分布式训练的后端优化,如 SMDDP 集合,既可以单独使用,也可以与模型并行包结合使用。

在下一章,我们将探索分布式训练中的更高级主题!

参考文献

请查看以下内容,了解本章涵盖的一些主题:

  1. aws-sample/sagemaker-ssh-helper: github.com/aws-samples/sagemaker-ssh-helper

  2. 在 Amazon SageMaker Studio 中使用 TensorBoard:docs.aws.amazon.com/sagemaker/latest/dg/studio-tensorboard.html

  3. aws/amazon-sagemaker-examples: github.com/aws/amazon-sagemaker-examples/blob/main/training/distributed_training/pytorch/model_parallel/gpt2/train_gpt_simple.py

  4. 在 Amazon SageMaker 上训练大型语言模型:最佳 实践aws.amazon.com/blogs/machine-learning/training-large-language-models-on-amazon-sagemaker-best-practices/

  5. SageMaker 分布式数据并行 库简介docs.aws.amazon.com/sagemaker/latest/dg/data-parallel-intro.html

第九章:高级训练概念

本章将涵盖大规模训练的高级概念,例如评估吞吐量、计算每个设备的模型teraFLOPS(TFLOPS)、编译以及使用缩放法则来确定合适的训练时间长度。在上一章中,你学习了如何在 SageMaker 上进行大规模训练的基本知识。在本章中,你将学习一些复杂且先进的技术,帮助你降低作业的总体成本。较低的成本直接转化为更高的模型性能,因为你可以在相同的预算下进行更长时间的训练。

本章将涵盖以下主题:

  • 使用模型 TFLOPS 评估和提升吞吐量

  • 使用 FlashAttention 加速训练过程

  • 通过编译加速作业

  • Amazon SageMaker 训练编译器和 Neo

  • 在 Amazon 的 Trainium 和 Inferentia 定制硬件上运行编译后的模型

  • 解决最优训练时间的问题

评估和提升吞吐量

正如我们在本书中之前提到的,总作业吞吐量是一个重要的指标。 一方面,你需要保持小的批处理大小,以确保模型得到适当训练。另一方面,你希望最大化整体作业性能,以获得尽可能准确的模型。我们在第七章中学习了如何使用超参数调整来解决这两个问题。我们还在第五章第八章中介绍了减少图形处理单元(GPU)内存占用的其他技巧。现在,让我们进一步解决这一领域的一些问题。

首先,重要的是要考虑如何在一般情况下衡量吞吐量。你可能已经在 PyTorch 中使用过一些日志包,它们方便地报告训练循环中的每秒迭代次数。显然,这对于监控训练速度非常有用,但你如何考虑模型的大小呢?如果你想与他人比较你的速度,以确定是否处于相同的水平,该怎么办呢?

为了解决这个问题,许多研究团队计算一个聚合指标,将模型大小和完成的操作结合在一起。通常,这被称为模型 TFLOPS。这些计算会根据不同团队的偏好有所变化,但我们将探讨来自近期 Chinchilla (11) 论文的设置,这篇论文刚刚获得了神经信息处理系统(NeurIPS)最佳论文奖。你会发现,这个短语在评估大规模分布式训练系统时非常常见。

计算模型的 TFLOPS

你听说过每秒浮动操作数FLOPS)吗?这是一个简单的方式来展示一个给定机器可以执行多少次计算。数值越高越好,因为这意味着在相同时间内,机器可以完成更多的任务。TFLOPS是一种更容易比较分布式训练解决方案性能的方式。

在 Chinchilla 中,作者有一种清晰的计算模型 TFLOPS 的方法。首先,考虑到前向传播和反向传播的性能是不同的。反向传播实际上是前向传播计算成本的两倍,因为我们不仅需要计算梯度,还需要更新权重和参数。因此,模型的 TFLOPS 将如下所示:

简单吧?现在让我们来解读一下这个术语。

在他们论文的附录 F中,作者详细定义了他们的其他术语。另一种更简单但稍微不那么精确的计算总模型 TFLOPS 的方法是直接使用 C=6⋅D⋅N,其中N是模型中的参数数量。Chinchilla 实际上发现这个计算方式与前面公式中的计算结果没有显著差异。

在阅读这些指标时,考虑到每个术语都与神经网络的一个部分相关,特别是它的规模。将这些与每秒处理的令牌数量结合起来,你就可以得到一个衡量整体训练循环效率的实际指标。这个效率指标随后成为一个你可以在运行时比较实验的共同标准。

记得在第三章中,你学习了如何将整体项目视为一系列实验吗?虽然项目的准确性无疑应该是一个关键性能指标,但我强烈建议你同时包括一个效率指标。这有助于确保你充分利用计算预算,这对于初始训练、随后的再训练、推理、监控和整体项目维护都非常重要。

例如,你可能会考虑以下实验计划:

阶段 模型类型 模型大小 数据集大小 计算规模 计算效率 实验运行时间
一 – 小规模测试 通用预训练 基础 5–30 GB 1–4 个较便宜的 GPU 对小数据样本进行一次完整的传递
二 – 增加数据集 半定制 数十亿参数 100 GB 至 TB 数十至数百个更强的 GPU 中等 几个步骤或纪元
三 – 增加模型(及数据) 非常定制 数十亿参数 TB 数百至数千个高性能 GPU 几个步骤或纪元
四 – 最大化计算预算 完全定制 数十亿至数百亿参数 TB 至 PB 数千个或更多高性能 GPU 最先进 训练至最优时期

图 9.1 – 建议用于大规模训练基础模型的实验阶段

让我明确地说一下这张表;无论在任何情况下,我都不指望每个人都完全按此执行。新颖的训练模式、数据集规模、模型、GPU 性能、建模结果、计算预算以及不同视角有着无数的细微差别,单一的表格无法囊括所有这些差异。有些团队永远无法构建超过 10 亿参数的模型,但仍然能打造出世界喜爱的作品,例如 Stable Diffusion!但我向你保证,实验室的构建经历了多个阶段,最终才达成了大规模运行。你需要学习如何将项目的范围从“可行”扩展到“令人印象深刻”。如何适当地实现这一点,取决于你正在解决的具体问题。

现在,让我们看看一些可以用来提高训练效率的方法。接下来是 Flash Attention!

使用 Flash Attention 加速你的训练过程

在前面的章节中,我们了解了核心的 Transformer 模型,以及其底层的自注意力机制,这成为了如今视觉、语言和生成任务中大多数先进模型的基础。虽然 Transformer 模型很容易并行化,但它们在优化现代 GPU 中不同内存速度方面并不特别擅长。当由于简单的实现方式导致 Transformer 出现在 GPU 中最慢的部分时,就会成为问题。正如你所想象的那样,这会让性能提升无法得到完全释放。

斯坦福大学领导的研究团队意识到,他们可以改进这一点,并开发出一种创新的 Transformer 架构实现。简而言之,这是一种极其巧妙的方式来处理一个二次嵌套的 for 循环。让我们仔细看看。

图 9.2 – 来源于 Tri Dao 等人 2022 年的 FlashAttention (1)

图 9.2 – 来源于 Tri Dao 等人 2022 年的 FlashAttention (1)

这张论文中的图示展示了三个关键概念。左侧部分,我们看到一个简单的金字塔,展示了大多数 GPU 服务器上可用的三种常见计算类型。在底部,我们有许多 CPU,并且主内存超过 1 TB,但其带宽最高为 12.8 GB/s。接下来是 GPU 中较慢的部分,内存更少,但带宽更大,只有 40 GB 的 GPU HMB,但带宽高达 1.5 TB。最后,我们有 GPU 中最快的部分,内存仅有 20 MB,但带宽可达 19 TB。显然,19 TB 的带宽比 1.5 TB 快超过 10 倍!这立刻向你展示了,将尽可能多的计算移至静态随机存取内存SRAM)可以为你节省大量时间。

然而,你会注意到,这个 10 倍的提升是指带宽,而不一定是吞吐量。纯吞吐量意味着高效处理大量数据,而带宽在这里有助于优化 输入/输出I/O)。在这种情况下,它指的是数据在整个计算机架构中如何在不同的数据结构之间传递。这就是为什么我们最关注带宽指标;带宽控制了我们能够传递到或从给定计算单元的数据量。这意味着当我们处理 I/O 密集型过程时,例如在自注意力头中使用的二次嵌套循环,将尽可能多的数据传输到带宽最高的部分,是加速整体速度的一个方法。

这种技术能带来什么样的收益?在图像的最右侧,你可以看到 FlashAttention 提供的这一新 融合内核,它的运行时间等同于在一个普通 PyTorch 实现中完成五个操作中的一个所需的时间。普通实现需要大约 17 秒来完成所有的 矩阵乘法Matmul)、掩蔽、Softmax、Dropout,最后是 Matmul,而 FlashAttention 融合内核可以在不到几秒钟的时间内完成所有这些操作!

FlashAttention 目前尚未直接集成到 PyTorch 中,尽管如果在接下来的 12 个月内没有集成,我会感到非常惊讶。暂时,你可以使用一个开源实现,详情见这里 (2)。作者展示了,使用 FlashAttention 可以让 生成预训练变换器GPT)模型在 Hugging Face 的选项上实现 3–5 倍的加速,在每个 NVIDIA A100 GPU 上达到 189 TFLOPS。虽然在较小规模下这可能听起来不是很大的提升,但一旦你使用了数百到上千个 GPU,这就可能带来巨大的节省!FlashAttention 在 SageMaker Model Parallel 库中已提供支持,从 2022 年 12 月开始 (3)

现在让我们看看另一个先进的训练概念,帮助加速你的训练过程:编译。

利用编译加速你的任务

记得在 第四章 中,我们学习了 GPU 系统架构的一些基本概念。我们介绍了 计算统一设备架构CUDA)软件框架,它使你可以在 GPU 上运行普通的 Python 代码。我们讨论了管理容器和深度学习框架,如 PyTorch 和 TensorFlow,这些框架已经经过测试并且可以很好地运行在 AWS 云平台上。大多数神经网络实现的问题在于它们并没有针对 GPU 进行特别优化。这就是编译发挥作用的地方;你可以通过它为同一个模型带来两倍的加速!

在深度学习编译器的上下文中,我们主要关注的是 torch.compile 方法。

在我们进入使用编译的示例之前,让我们先尝试理解它是什么以及为什么它有用。假设你有两个向量(记住,想成是“列表”),每个向量的大小都是 1000。一个向量填充的是零,另一个向量填充的是一。现在假设你有一个基本操作要应用于这两个向量:加法。你想将这两个向量相加,得到一个长度为 1000 的第三个向量,该向量是原始两个向量中每个项的直接和。

一种简单的做法是遍历两个列表,计算和,并将结果添加到新列表中。但如果你提前知道其中一个向量是零呢?那样的话,你不想完全跳过加法操作吗?如果你这样做,可能会节省很多时间!

这种跃升的实现得益于中间表示。如 2020 年一项调查所示 (4),深度学习编译器会对神经网络的图进行分析。首先,前端编译器计算出图的一个更优版本,如融合操作符、简化代数表达式、执行静态内存规划等多种技术。接着,后端编译器会根据特定硬件、低级表示、内存分配、定制内核等因素再次计算这一过程。然后,它会生成新的代码,这些代码会被加速器使用。

现在让我们来学习如何将编译添加到你的脚本中!

将编译集成到你的 PyTorch 脚本中

从这里的 PyTorch 文档 (5) 中,你会看到有三种主要方式可以在你自己的 PyTorch 代码中使用编译。首先,你可以使用任何 PyTorch 内置的函数,比如torch.sintorch.cos,然后将这些传递给torch.compile。这会使用我们之前讨论的多种技术来根据可用的 GPU 编译你的函数。或者,你可以为你的 PyTorch 函数添加一个装饰器,简单地写@torch.compile,它提供相同的功能。这两种功能也适用于torch.nn.Module基础对象,这意味着你应该能够在你的任何 PyTorch 模型中使用它们!

如果你觉得编译带来的加速很有用,但又不想重写我的模型代码来使用它们,那么接下来的部分对你来说一定非常有趣!我们来看看 AWS 上的托管编译功能——SageMaker 训练编译器和 SageMaker Neo。

亚马逊 SageMaker 训练编译器与 Neo

如果你今天使用的是 Hugging Face 语言模型,比如 BERT、GPT、RoBERTa、AlBERT、DistiliBERT 或其他数百种模型,那么你很幸运!通过简单的操作,你就可以轻松将作业的运行时间提高最多 50%。这是因为 SageMaker Training Compiler (SMTC) 的存在。正如我们之前所学,编译通常具有提高训练速度的潜力。使用 SMTC,我们在 SageMaker 训练中提供了一个托管的编译功能,轻松地为你自己的模型和脚本启用这一功能。

如你在提供的图示中所见,启用这一功能非常简单。在这里,我们使用 Hugging Face 提供的 AWS 托管深度学习容器,并只需添加 TrainingCompilerConfig()。如果你正在使用带有 Hugging Face Trainer API 的模型,这将自动触发训练编译器:

图 9.3 – 配置 SageMaker Training Compiler

图 9.3 – 配置 SageMaker Training Compiler

它是如何工作的?SMTC 在三个不同的层次上使用各种编译方法:图层、数据流层和后端层。图层优化包括操作符融合、内存规划和代数简化。数据流层优化包括布局转换和常见子表达式消除。后端优化包括内存延迟隐藏和面向循环的优化。这些优化可以将训练过程加速最多 50%,且结果模型与未应用 SMTC 时的模型相同。例如,在微调 Hugging Face 的 GPT-2 模型时,SMTC 将训练时间从将近 3 小时减少到仅 90 分钟!

编译的最佳实践

在使用编译器时,你需要确保相应地更新你的超参数。这是因为编译器的最终效果是减少模型的 GPU 内存占用。例如,未编译时,你的模型可能会消耗大约 10 GB 的 GPU 内存。经过编译后,可能会将其减少到 5 GB!这为你提供了更多的空间来增加批量大小中的对象。如我们在书中早些时候学到的,这直接提高了 GPU 的利用率,从而提高了整体项目效率。只需小心不要过度增加批量大小,否则会使收敛变得更加困难。你还需要以相同的速度增加学习率。

正如你可能预料的那样,有些时候编译是非常有用的,而有些时候编译可能会浪费时间。这是因为大多数编译器在执行你的代码之前需要一些时间来运行编译过程。这意味着,与正常的 Python 代码执行相比,编译器会提前运行其子进程,生成一个更优化的模型版本。一旦这个版本生成完成,你的代码就会开始正式运行。

这种提前编译的过程引入了评估编译整体影响的关键权衡。你的模型训练周期越长,编译带来的提升就越大。这意味着如果你使用大量的 epoch,或者数据集非常庞大,那么编译应该是一个节省计算成本的有效方法。就我个人而言,如果你的模型运行超过 30 或 40 分钟,尝试通过编译来缩短这个时间。

或者,如果你有一个频繁的重训练流程或任务,特别是一个半定期运行的任务,可以尝试使用编译来缩短时间。我的一些客户每天、每周,甚至每几小时或几分钟就会重训练他们的模型。我们将在第十四章中深入讨论这个以及其他与操作相关的话题。

现在,让我们学习如何通过使用 PyTorch 编译,使我们能够轻松使用亚马逊的定制硬件进行机器学习:Trainium 和 Inferentia!

在亚马逊的 Trainium 和 Inferentia 定制硬件上运行已编译的模型

到目前为止,在本书中,我们评估的大多数加速器都是由 NVIDIA 设计和制造的 GPU。正如我们之前所了解的,NVIDIA 的优秀软件使得大部分深度学习框架能够在这些 GPU 上运行得非常顺畅,这也成为了使用 GPU 的主要决定因素。我们还了解到,这些 GPU 同样可以在 AWS 上使用,特别是通过我们的机器学习服务 Amazon SageMaker。

然而,正如你到目前为止无疑已经意识到的那样,那些 GPU 的价格可能非常高!即使 AWS 有慷慨的企业折扣计划,比如通过使用预留实例节省高达 75%的费用(6),你仍然可以从了解替代方案中获益。基础经济学告诉我们,当供给增加,比如通过替代加速器,而需求保持不变时,价格就会下降!这正是我们兴奋地为客户提供的:我们的机器学习定制加速器——Trainium 和 Inferentia。正如你可能猜到的,Trainium 专门用于训练机器学习模型,而 Inferentia 则专注于托管。至本文写作时,这些加速器已经可以通过 EC2 和 SageMaker 作为 Inf1 和 Trn1 实例使用。

幸运的是,对于那些已经通过前一节了解过编译的读者,许多使用 XLA 编译的模型已经得到 Trainium 和 Inferentia 的支持!这意味着,如果你已经在使用通过 PyTorch 或 TensorFlow 的 XLA 编译,那么你已经很接近成功迁移到 Trainium 和 Inferentia 了。不过需要提醒的是,并不是每个模型和操作都已经得到支持。在开发和测试时,可能会遇到一些摩擦。AWS Neuron 软件开发工具包 (SDK) 是测试兼容性的好方法(7)

有两个原因需要评估我们的定制加速器:

  • 首先,它是一种新型的硬件。对你们这些科学家来说,这一点尤其重要,因为你们很可能是世界上第一个在这种硬件上使用某种类型模型的人。这可能实际上会增加你们发表论文和获得认可的机会,因为你们可以基于模型在该硬件上的表现开发出真正新颖的见解。

  • 第二,与我们在 AWS 上的所有新实例一样,性价比应该比以前大大提高。

什么是性价比?考虑你需要完成的每项任务。以 Inferentia 为例,这将是完成的模型推理请求数。对于 Trainium,则是通过训练循环的步骤数。然后,考虑完成每项任务的成本。现在你就有了性价比!我们的 Trn1 实例提供比同类 GPU 实例高达 50% 的训练成本节省,而 Amazon Search 通过 Inferentia 将其推理成本降低了 85% (8)

现在我们已经对 Trainium 和 Inferentia 有了一个非常高层次的了解,接下来让我们探讨如何利用扩展法则来解决最佳训练时间的问题。

寻找最佳训练时间

时间是训练大型视觉和语言模型中的一个有趣的概念。一方面,你可能会将其视为一个超参数,仅仅是迭代次数的数量。另一方面,你可能会将其视为训练数据的一个方面,比如数据的总令牌数或图像数。你也可能会将其视为项目的固定输入,即你的总计算预算。我与之合作的大多数研究团队通过直觉和良好的判断力,结合这些因素来确定最佳方案。

正如我们在书中早些时候所学,提出的 扩展法则 提供了一种有趣的理论工具,您可以用它来预测模型的表现。其原作者 Kaplan 等人 (9) 实际上建议,在给定的计算预算下,最佳的使用应当在“远未收敛”时就停止。他们提出这一建议,是基于他们对大型语言模型“比小型模型更具样本效率”的洞察。

然而,2022 年,这些原始法则发生了翻转。在这个图示中,你可以看到由 Chinchilla 提出的新一组扩展法则所确定的理论预测:

图 9.4 – 来自 Hoffman 等人的改进表现,2022 年 (10)

图 9.4 – 来自 Hoffman 等人的改进表现,2022 年 (10)

在这里,Hoffman 等人提出了一个优雅的建议,认为训练数据和模型大小应该线性增加。也就是说,如果你把模型的大小加倍,训练数据的大小也应该加倍。我很欣赏这种自然的对称性,并且觉得它非常直观。幸运的是,这些预测得到了跨越至少 400 个模型、150 个下游任务和 6 个领域的广泛实证证据的验证,其中包括语言建模、阅读理解、问答、常识推理等。根据作者的说法,“Chinchilla 在大量下游评估任务上统一且显著地超越了Gopher (280 B)GPT-3 (175 B)Jurassic-1 (178 B)Megatron-Turing NLG (530B)。”这意味着这些模型训练不足,实际上需要更大的数据集来验证它们的参数大小。

使用这些方程式和大量的实验结果,作者建议了以下一组参数、FLOPS 和 tokens 的值:

图 9.5 – 每个模型大小建议的 FLOPS 和 tokens

图 9.5 – 每个模型大小建议的 FLOPS 和 tokens

记住,当我们查看这个 FLOPS 值时,我们需要考虑以下几点:

  1. 我期望这个模型为我的组织带来什么价值?

  2. 根据这些,我可以规划多少总的计算预算?

  3. 我的训练数据有多大?

  4. 基于这些,应该使用多大规模的模型?

  5. 我的训练循环和分布式系统有多高效?换句话说,我每个 GPU 能挤出多少 TFLOPS?

  6. 我能从我的云服务提供商那里获取多少个 GPU?

  7. 我需要多长时间才能运行整个训练循环,直到训练收敛?

对于问题(1)、(2)、(3)和(5)的答案只能由你来提供。问题(4)和(7)的答案是前面答案的函数导数。至于问题(6),我认为它是问题(1)的函数导数与当时市场的一个简单事实之间的中间值。如果电子产品出现全球供应链问题,那么获取 GPU 将变得困难。

呼,您已经完成了高级章节!现在让我们快速回顾一下概念,然后进入第四部分:评估 您的模型

总结

在本章中,我们介绍了一些训练大规模视觉和语言模型的高级概念。首先,你学习了如何通过计算每个 GPU 上的模型 TFLOPS 来评估和提高吞吐量,并使用这一指标与其他多个指标来比较实验结果。你了解了 FlashAttention,以及它的 I/O 感知优化二次循环如何将 Transformer 自注意力机制的速度提高 3-5 倍。你学习了如何使用 PyTorch 内置和 AWS 管理的方法进行编译。你还了解了几种不同类型的编译方法。你学会了如何更新你的编译超参数,以及在某些情况下编译是否能提供提升(或没有提升)。

你还学到了如何使用编译器在亚马逊的机器学习定制硬件 Trainium 和 Inferentia 上运行。最后,我们使用缩放定律来解决最优训练时间问题。

在下一章,你将学习如何微调你的模型,并将其与开源替代方案进行比较。

参考文献

  1. FlashAttention:快速且内存高效的精确注意力机制,具备 I/O 感知:arxiv.org/pdf/2205.14135.pdf

  2. HazyResearch/flash-attention:github.com/HazyResearch/flash-attention

  3. 亚马逊 SageMaker 模型并行库的新性能改进:aws.amazon.com/blogs/machine-learning/new-performance-improvements-in-amazon-sagemaker-model-parallel-library/

  4. 深度学习编译器:综合调查:arxiv.org/pdf/2002.03794.pdf

  5. TORCH.COMPILE 教程:pytorch.org/tutorials/intermediate/torch_compile_tutorial.html

  6. 企业客户:aws.amazon.com/pricing/enterprise/

  7. 欢迎使用 AWS Neuron:awsdocs-neuron.readthedocs-hosted.com/en/latest/

  8. 亚马逊搜索如何通过 AWS Inferentia 将 ML 推理成本降低 85%:aws.amazon.com/blogs/machine-learning/how-amazon-search-reduced-ml-inference-costs-by-85-with-aws-inferentia/

  9. 神经语言模型的缩放定律:arxiv.org/abs/2001.08361

  10. 训练计算最优的大型语言模型:arxiv.org/pdf/2203.15556.pdf

  11. 训练计算最优的大型语言模型:openreview.net/pdf?id=iBBcRUlOAPR

第四部分:评估你的模型

在第四部分,你将学习如何评估你的模型。你将使用扩展规律来确定最短的训练时间,微调你的模型并与公共基准进行比较,同时识别并缓解偏差。

本节包含以下章节:

  • 第十章微调与评估

  • 第十一章检测、缓解与监控偏差

  • 第十二章如何部署你的模型

第十章:微调和评估

在本章中,您将学习如何在用例特定数据集上微调您的模型,比较其性能与现成的公共模型。您应该能够从预训练中看到定量和定性的提升。您将深入一些涉及语言、文本及其间关系的例子。您还将学习如何思考和设计一个人在循环评估系统,包括使 ChatGPT 运行的 RLHF!本章重点在于更新模型的可训练权重。对于模仿学习但不更新权重的技术,如提示调整和标准检索增强生成,请参阅第十三章中的提示工程。

我们将在本章中涵盖以下主题:

  • 语言、文本及其间的微调

  • LLM 微调分解 - 指令微调、参数高效微调以及带有人类反馈的强化学习

  • 视觉微调

  • 在视觉、语言和联合任务中评估基础模型

语言、文本及其间的微调

在本书的这一部分,我们已经涵盖了很多内容。我们主要关注预训练方面,涵盖了从寻找合适的用例和数据集到定义损失函数,准备您的模型和数据集,定义逐渐扩展的更大实验,基本并行化,与 GPU 合作,寻找合适的超参数,高级概念等!在这里,我们将探讨如何使您的模型更加针对特定应用:微调

假设,如果您正在进行大规模的训练项目,您可能会有以下一些目标:

  • 您可能正在预训练您自己的基础模型

  • 您可能正在设计自动驾驶车辆的新方法

  • 您可能正在对 3D 数据进行分类和分割,比如在房地产或制造业中

  • 您可能正在训练一个大型文本分类模型或设计一个新颖的图像文本生成模型

  • 您可能正在构建一个文本到音乐的生成器,或者正在开发一个机器学习社区尚未发现的全新联合训练模态

  • 您可能正在训练一个大型语言模型,以解决全球范围内的通用搜索和问答问题,或者针对特定社区、语言、组织和目的

所有这些使用案例有一个共同点;它们使用一个大规模模型,通过在极大规模的数据集和模型规模中学习模式来实现通用智能。然而,在许多情况下,这些模型只有在经过微调以解决特定问题时才会变得特别有用。这并不是说你不能简单地部署其中一个并使用专门的提示工程来立即获得有用的结果,因为你可以。事实上,我们将在本书后续内容中深入探讨这个话题。但仅仅依靠提示工程是有限的。通常,将提示工程与微调相结合,以便将你的模型集中于目标应用,并运用你的创造力和技能解决实际的人工问题,这种方式更加常见。

我喜欢将这种预训练和微调范式视为一种类似于通用和专业教育之间差异的思考方式,无论是正式的本科和研究生课程、在线课程还是在职培训。通用教育是广泛的。如果做得好,它涵盖了多个学科的广泛技能。可以说,通用教育的主要产出就是批判性思维本身。

专业化培训非常不同,它通常专注于某个狭窄领域的卓越表现。专业化培训的例子包括硕士学位、证书、研讨会或训练营。它的产出通常是应用于某一特定领域的批判性思维。

虽然这种直观差异容易理解,但在实践中,设计既优化了通用知识又优化了专业知识的机器学习应用程序和实验,并保持这些内容的更新,却并不那么明显。从个人观点出发,我认为预训练和微调模型的结合是迄今为止最佳的解决方案。很可能,这将是我们未来几年,甚至几十年,继续处理机器学习的方式。

正如你在本书中这一部分应该开始感到非常熟悉的那样,构建一个出色的机器学习应用程序或有效实验的艺术在于同时利用通用模型和专业模型的优势。不要局限于使用单一模型;这与限制自己只拥有单一的世界观或视角没有太大不同。增加你使用的模型种类有可能提高你应用程序的整体智能水平。只要确保你在每个实验和迭代中都设定清晰的目标和可交付成果。

你可能使用一个单一的预训练模型,比如 GPT-2,然后对其进行微调,以生成你自己的语言风格的文本。或者你可能使用预训练模型对输入文本进行特征化,比如在稳定扩散(Stable Diffusion)中,然后将其传递给下游模型,如 KNN。

提示

这是解决图像搜索的一个很好的方法!或者你可以使用下文所列的任何微调方法。

微调一个仅处理语言的模型

如果你的模型是一个仅处理语言的项目——比如受 BERT 或 GPT 启发的模型——那么一旦你完成了预训练或达到了一个重要的里程碑(可能是几百步),你就需要在更具体的数据集上微调这个预训练的基础模型。我会开始考虑将模型应用于哪个用例——很可能是在我拥有最多监督训练数据的地方。这也很可能是我的业务中影响客户最强的部分——从客户支持到搜索,从问答到翻译。你也可以探索产品创意、功能请求优先级、文档生成、文本自动补全等方面。

收集你的监督数据,并按照上一章关于分析数据的步骤进行操作。我会有许多笔记本来比较数据集,运行摘要统计,并对关键特征的分布进行比较。完成这基本分析后,我会运行一些训练任务!这些任务可以是完整的 SageMaker 训练任务,也可以是使用你的笔记本实例或 Studio 资源。通常,微调任务并不庞大;通常只微调几 GB 的数据。如果你有明显更多的数据,我可能会考虑将其直接加入到我的预训练数据集中。

你的最终模型应结合预训练项目的输出和与目标用例相关的通用数据。如果你做得对,你应该已经有了多个用例排队等待,因此微调将让你可以将预训练模型应用于所有这些用例!

就个人而言,我会使用 Hugging Face 来处理仅涉及语言的项目,将我的新预训练模型作为基础对象。你可以按照其 SDK 中的步骤来指向不同的下游任务。发生的事情是,我们将预训练模型作为神经网络的基础,然后在末尾简单地添加额外的层,以便将输出的标记渲染成与你想处理的用例更为接近的格式。

你将再次选择所有的超参数。这是超参数调优极为有用的又一个时刻;把它当作朋友,轻松地进行几十到几百次的模型迭代,找到最佳版本。

现在,让我们详细拆解几种显式更新模型参数的语言微调策略。请注意,接下来的评论只是描述了这些技术的常见场景;我毫不怀疑今天的开发中会有更好的方法来处理这些问题。

名称 方法 结果
经典微调 这种方法需要一组监督学习的文本对和一个预训练的基础模型,并向模型添加一个新的下游头部。新的头部,可能还会更新原始模型的几层。 新模型在给定任务和数据集上表现良好,但在其他方面表现不佳。
指令微调 这项技术本质上是常规的微调,但关键在于使用包含明确指令和期望回应的数据集。有关样本数据集,请参见斯坦福的 Alpaca 项目 (1)。指令包括“讲个故事”,“制定一个计划”或“总结一篇文章”等命令。 基础生成模型生成任意文本,并且仅在少量示例学习情况下,结合复杂的提示工程时表现良好。一旦指令经过微调,模型就能在零-shot 情况下很好地响应,而无需在提示中提供示例。自然地,人们更喜欢这种方式,因为它使用起来更简单、更快捷。
参数高效 微调PEFT PEFT 基于 LoRA (2) 启发,通过将新的可训练矩阵注入原始模型,而不是更新原始模型的所有权重。这使得训练和存储变得更加高效且具有成本效益,效率提高了三倍 对于相似数据集,PEFT 基础的方法似乎能达到与完全微调相当的准确度,同时所需的计算量少了一个数量级。新训练的层可以像经典微调模型一样被重复使用。个人而言,我在想,这种方法是否能够为基础模型的大规模超参数调优开辟新的可能!
领域适应 通过大量无监督数据,这项技术可以在语言领域继续对模型进行预训练。这对于将模型性能集中在新领域(如特定行业垂直或专有数据集)尤为重要。 这会导致一个更新后的基础模型,它应该掌握基于更新领域的新词汇和术语。但要在特定任务上实现最佳性能,仍然需要针对任务的微调。
强化学习与人类 反馈RLHF 该技术允许你在大规模上量化人类对生成内容的偏好。这个过程将多个模型响应展示给人类标注员,并让他们对其进行排序。这用于训练奖励模型,奖励模型作为强化学习过程的指导,用来训练新的 LLM。我们稍后会详细讨论这一点。 OpenAI (3) 表明,通过 RLHF 训练的模型在人类偏好上始终优于其他模型,甚至超过指令微调。这是因为奖励模型学习了人类群体平均认为更好的生成内容。这种偏好随后通过 RL 融入 LLM 中。

如果你想直接了解这些技术,包括它们如何与示例一起工作,那么请直接前往代码库。你也可以直接跳转到第十五章以深入了解参数高效微调。记住,在第十三章中,我们将学习所有关于模仿学习的技术,但这些技术并不更新模型本身的任何参数。这包括提示调优、提示工程、前缀调优等。现在,让我们先了解一下微调视觉专用模型。

微调视觉专用模型

在微调方面,视觉和语言是完全不同的世界。在语言中,使用一个大型预训练模型,如 BERT 或 GPT,添加一个额外的数据集,进行微调,并能在开箱即用的情况下获得相对较好的表现,已成为一种较为可靠的做法。这并不是说语言中没有无数其他细微差别和问题,因为它们确实存在,但通过简单的微调获得较好表现的普遍可能性较高。

在视觉中,立即获得良好表现的可能性并不是很高。你可能有一个来自 ImageNet 的模型,想用它作为你的基础模型,然后与另一组标注图像配对。如果你的图像看起来已经像是来自 ImageNet,那你就处于有利位置。然而,如果你的图像完全不同,风格、语调、特征、细微差别或模式都不一样,那么你的模型很可能不会立即表现得很好。这是一个早在基础模型之前就存在的视觉问题。

图 10.1 – 来自凯特·塞恩科的 WACV 预训练研讨会 2023 年主旨演讲 (4)

图 10.1 – 来自凯特·塞恩科的 WACV 预训练研讨会 2023 年主旨演讲 (4)

领先的视觉研究者凯特·塞恩科(Kate Saenko)开创了解决这一问题的方法,她称之为分布偏差。正如她在 2010 年的第一篇论文中所指出的(5),核心问题在于领域之间的巨大差距。在计算机视觉中,使用专注于某一特定数据集的预训练模型并不能很好地转化到下游任务。即使在新一组标注样本上对预训练基础模型进行微调,模型也很可能只是过拟合,或者甚至无法很好地学习新领域。

凯特的研究发现,事实上,使用最近预训练的基础模型对于克服领域适应问题非常有帮助(6)。她发现“仅仅使用最先进的骨干网络就超过了现有的最先进领域适应基准,并在 OfficeHome 和 DomainNet 上设置了新的基准,分别提高了 10.7%和 5.5%”。在这种情况下,骨干网络指的是模型,这里是 ConvNext-T、DeiT-S 和 Swin-S。

在同一项工作中,Kate 还发现,较大的模型往往表现得更好。在下图中,你可以看到,通过将模型的参数数量增加数千万,她也提高了准确性。

图 10.2 – Saenko 关于在视觉中增加模型大小的影响的结果

图 10.2 – Saenko 关于在视觉中增加模型大小的影响的结果

现在我们已经了解了一些与仅视觉相关的微调机制,让我们来探索视觉与语言结合的微调机制吧!

微调视觉-语言模型

首先,让我们回顾一下几项与视觉和语言明确结合独特相关的有趣任务。这些任务包括视觉问答、文本到图像、文本到音乐,正如 Allie Miller 所说的,“文本到一切”。它们还包括图像描述、视频描述、视觉蕴含、基础对接等。你可能会在电商应用中使用视觉-语言模型,确保页面上的产品正确,甚至在电影行业中用于生成新的故事板点。

微调预训练的视觉-语言模型,在最基本的层面上,应该遵循我们为其他范式讨论的相同模式。你需要一个基础模型,然后需要一组符合相同标签方案的数据。如果你使用过Lensa应用,那么你已经对微调视觉-语言模型有些了解了!Lensa 会要求你上传自己的照片到应用中。假设一下,我猜它会利用这些照片,并迅速在这些新图像上微调 Stable Diffusion。然后,它可能使用一个提示工具,并配合内容过滤器将图像发送回给你。

我最近非常印象深刻的另一个视觉-语言微调的案例研究是Riffusion (7)。目前,你可以使用他们的免费网站来听从文本生成的音乐,而且效果相当不错!他们建立了一个开源框架,能够将音频片段转换成图像。这些图像被称为声谱图,是通过使用短时傅里叶变换得出的,这是一种将音频转换为二维图像的近似方法。这样就能为声音本身提供一种视觉特征。声谱图也可以转回音频,重新生成声音。

自然地,他们使用了音频片段的简短文本描述作为每张图像的文本标签,瞧!他们拥有了一个标注数据集来微调 Stable Diffusion。通过使用这些声谱图和其文本描述,他们对模型进行了微调并进行了托管。现在,你几乎可以写下像“牙买加舞厅人声”或“日出 DJ 集”的文本提示,他们的模型就会为你生成这些音频!

我喜欢这个项目,因为作者更进一步:他们设计了一种新颖的平滑函数,可以无缝地从一个谱图过渡到另一个谱图。这意味着当你使用他们的网站时,你可以非常自然地从一种音乐模式过渡到另一种音乐模式。所有这一切都得益于使用了大规模预训练的稳定扩散基础模型,并用他们的新型图像/文本数据集进行了微调。值得一提的是,还有其他一些音乐生成项目,包括 MusicLM (8)、DiffusionLM (9)、MuseNet (10) 等等。

现在你已经了解了各种预训练和微调策略,应该对找到利用你一直在训练的模型的方式感到非常兴奋。让我们学习如何与开源模型进行性能比较吧!

评估基础模型

正如我们在本书中多次讨论的那样,进行大规模训练的主要原因是开源模型无法满足你的需求。在开始自己的大规模训练项目之前,你应该已经完成了以下步骤:

  1. 在你的特定使用场景中测试过开源模型

  2. 确定了性能差距

  3. 在你数据的子集上微调了同一个开源模型

  4. 确定了更小的性能差距

关键是,你应该有一些经验性的理由相信开源模型可以解决你部分的业务问题,但并不是全部问题。你还需要经验性地证明小规模微调也在同样的情况下;它应该提高系统性能,但仍然有改进的空间。接下来的整个部分将讨论如何评估这种改进空间。让我们试着理解如何评估基础模型。

正如你无疑已经猜到的那样,评估基础模型分为两个阶段。首先,我们关注的是预训练性能。你希望看到预训练损失下降,无论是掩码语言建模损失、因果建模损失、扩散损失、困惑度、FID 还是其他任何指标。其次,我们关注的是下游性能。下游任务可以是分类、命名实体识别、推荐、纯生成、问答、聊天等。我们在前面的章节中已经讨论了如何评估预训练损失函数。在接下来的部分,我们将主要讨论下游任务的评估。让我们从一些视觉模型中的重要术语开始吧。

视觉模型评估指标

在视觉项目中,和所有机器学习任务一样,评估完全依赖于当前任务。常见的视觉任务包括图像分类、物体检测、分类、分割、人脸识别、姿态估计、分割图等。对于图像分类问题,你会很高兴知道,主要的评估指标通常是准确率!精确率和召回率在这里也同样重要,因为它们在任何分类任务中都相关。

对于物体检测,如你在图中所见,问题要复杂得多。仅仅知道给定类别是否在图像中的某个位置是不够的;你还需要模型知道图像的哪一部分包含了该物体。

图 10.3 – 交集与并集的比值

图 10.3 – 交集与并集的比值

物体检测在自动驾驶、制造业、安全、零售和其他应用中非常有用。通常,仅仅识别物体是不够的;你希望共同最小化边界框包含的错误像素数量,同时最大化包含的正确像素数量。

在这里,我们使用了一个叫做IOU的术语,它的字面意思是交集与并集的比值。如你所见,该术语对应的是两个边界框的重叠区域面积,除以这两个边界框并集的面积。正如你可能想象的那样,较大的 IOU 值更好,因为它意味着你的边界框更加一致。较小的 IOU 值则意味着两者之间的差异较大,你的分类器可能没有捕捉到相似的内容。如果你的物体检测器包含多个类别,并且你想对这些类别进行比较,你可能会对这个概念感兴趣。你还可以计算所有类别的加权平均 IOU,从而得到均值 IOUmIOU)。

另一种常见的聚合物体检测算法中多个分类器整体性能的方式是mAP,即均值平均精度。对于单个模型,你会称其为平均精度,因为它是跨所有分类阈值的结果平均值。对于多个模型,你会取每个类别的平均值,因此就是均值平均精度mAP)。

在基础模型领域,另一个非常有趣的视觉解决方案是 Meta 的Segment Anything ModelSAM(9)。如下面图中的展示,它提出了一项新的任务、数据集和模型,旨在启用基于提示的掩码生成。分割图是计算机视觉中的一种有用结构,用来识别图像中属于某个特定类别的像素。在这项工作中,SAM 学习如何根据给定图像和自然语言提示生成新的分割图。然后,它会从图像中隔离出解决自然语言提示问题的像素。

图 10.4 – Meta 的 SAM

图 10.4 – Meta 的 SAM

为了评估模型生成的分割图,Meta 团队随机抽取了 50,000 个掩码,并要求他们的专业标注员使用图像编辑工具(如“画笔”和“橡皮擦”)来改进这些掩码的质量。然后,他们计算了原始图和最终图之间的 IOU 值。

现在我们已经看过了一些视觉领域的评估示例,接下来我们也来看看语言领域的类似评估。

语言中的模型评估指标

虽然许多分类型指标仍适用于语言,但如何评估生成语言本身是一个固有的挑战。可以说,人文学科中的许多领域,比如文学批评、历史学和哲学,归根结底都是对给定的文本语料库进行评估。如何将这些知识应用到改善大型语言模型的输出并不显而易见。

提供一个标准化框架的一个尝试是斯坦福大学基础模型研究中心的HELM (12)项目。HELM代表的是语言模型的整体评估。它提供了一个极为丰富的多个评估指标的分类法,包括准确性、公平性、偏见、毒性等,以及来自近 30 个现有 LLM 的结果。以下是他们工作中的一个简短示例(13)。它标准化了跨模型和数据集评估的指标。

图 10.5 – 来自 HELM 的多个指标分类

图 10.5 – 来自 HELM 的多个指标分类

HELM 评级是开源的,并且可以在一个网页界面(14)和 GitHub 仓库(15)中找到。在很多情况下,当你寻找最合适的模型作为基础时,HELM 是一个很好的起点。现在,让我们更详细地探讨这些评估指标。我们将从翻译开始,然后继续总结、问答,最后是纯生成。

自然语言处理的第一个应用之一就是翻译,也叫做机器翻译。字面意思就是训练一个大型语言模型,学习你提供的成对字符串之间的关系,例如不同自然语言之间的翻译,例如从英语到德语。一个早期用来比较生成翻译质量的指标是bleu,这个指标由 IBM 的一个团队在 2002 年的 ACL 会议上提出(16)。他们将其方法称为双语评估替代方法,因此叫做bleu。通常,这个指标是通过比较模型生成的精确单词,以及这些单词是否出现在目标句子中来进行评估。

然而,Bleu 有许多缺点,例如不能充分处理同义词、相同单词的小变体、单词的重要性或它们的顺序。因此,许多实践者使用了最近开发的评估指标,例如 rouge(17)。与 bleu 预测字面翻译不同,rouge 则预测文本的总结。它计算了重叠的子词、单词序列和单词对的数量。

问答评估非常有趣,因为从根本上讲,你可以将问题分解为两部分。首先,根据给定问题,通常你希望检索与该问题相关的文档。多年前,这个问题通常通过词频/逆文档频率(TF-IDF)来解决,当然,这一方法后来被 Google 的页面排名取代,页面排名是根据其他页面链接的高质量站点链接的次数来对页面进行评分的。今天,NLP 初创公司 deepset 提供了一个有趣的解决方案,叫做haystack,它为你自己预训练的 NLP 模型提供了一个方便的封装,用来检索与问题最相关的文档。

评估问答系统的第二部分实际上是你呈现的文本质量作为答案。你可能只是尝试找到与问题最相关的原始文档部分,使用信息检索的技术。或者你可能尝试总结文档,或者文档的某部分,它最接近问题的内容。如果你有大量标注数据,比如点击流数据,你实际上可以准确指出文档中获得最多点击的数据部分,并将其作为答案。显然,这似乎就是今天 Google 的做法。

评估生成文本的质量尤其具有挑战性。尽管分类和一些其他机器学习问题有着固有的客观答案,人在标注时是明确对错的,但在文学分析中并非如此。因为有很多正确的答案,合理的人们会根据他们对给定故事或文本的不同解读,得出不同的结论。这就是主观性的一个例子。

我们如何处理在评估生成文本时主观性与客观性之间的这种差异呢?我能想到至少三种方法。首先,我非常喜欢训练一个判别器。这可以是一个使用正负样本训练的分类器,在某些情况下(例如试图模仿某位作者的风格)是准确的。你可以很容易地用一小部分作者作品对基于 BERT 的模型进行微调,和 GPT-3 的随机输出进行对比,从而获得一种非常可靠的方式来评估生成的文本。另一个有趣的项目是 GPTScore,它使用零-shot 提示测试其他 LLM:arxiv.org/pdf/2302.04166.pdf

你也可以让人类标注回答,然后简单地汇总这些标签。就个人而言,我对 ChatGPT 在这个问题上的有趣方法感到非常印象深刻。他们直接让人类对来自 GPT-3 模型的回答进行排序,然后使用强化学习训练模型,以优化所有回答中的最佳答案!我们将在本章最后一部分深入探讨这个方法。

现在你已经了解了一些语言评估指标,让我们在共同训练的视觉-语言任务中探讨相同的内容。

联合视觉-语言任务中的模型评估指标

正如你自发布以来无疑已经见证的那样,基于扩散的模型是一个非常引人注目的领域。这些模型通常是联合训练的视觉-语言模型,通过一种叫做扩散的过程来学习如何生成图像。这个过程学习了提供的文字与图像之间的关系,使得使用者可以通过简单地提供一组新文字来轻松生成新图像。在验证集上训练时实现低损失后,评估通常是由使用者离线手动完成的。大多数人只是通过猜测和检查,测试模型的几个不同超参数,最终选择自己最喜欢的图片。一支雄心勃勃的团队可能会训练一个鉴别器,类似于我之前提到的,用于评估生成的文本。

但是,如果你想专注于一个特定对象,并简单地将该对象放到另一个背景上呢?或者将该对象进行风格化?或者改变它的情绪或姿势?幸运的是,现在你可以了!来自波士顿大学的 Nataniel Ruiz,在谷歌实习时,开发了一个名为DreamBooth (18)的项目,专门实现这一目标。

图 10.6 – 使用 DreamBooth 微调保持损失

图 10.6 – 使用 DreamBooth 微调保持损失

DreamBooth 通过自定义标记和专业损失函数来实现这一点。这个损失函数被称为先验保持,它旨在对抗在视觉微调过程中常见的过拟合问题,以及语言微调中已知的语言漂移问题。我将省略损失函数的数学细节,但如果你感兴趣,欢迎直接阅读论文!一般来说,这个新的损失函数在微调过程中保留了其生成的样本,并在监督中使用这些样本。这有助于它保持先验。他们发现大约 200 次迭代和仅 3-5 张输入训练图像就足以生成优秀的图像了。你可以将这个自定义损失函数视为图像-文本模型的另一种评估方式。

现在我们已经探讨了多种视觉和语言模型的评估方法,让我们来学习如何保持人类在循环中的方法!

通过 SageMaker Ground Truth 结合人类标注视角

显然,将人工视角融入工作的一种关键方式就是标注!在 AWS,我们有一个低级标注服务 机械土耳其人 (MTurk) 和一个更为管理化的功能叫做 SageMaker Ground Truth。正如我们讨论的那样,MTurk 已经通过用于创建像 ImageNet 这样著名的数据集,影响了 ML 领域!就个人而言,我更喜欢 SageMaker Ground Truth,因为它在使用预建的图像标注任务(如物体检测、图像分类和语义分割)时更加方便。它还提供 NLP 任务,如文本分类和命名实体识别,视频任务以及 3D 点云任务。

图 10.7 – 使用 SageMaker Ground Truth 管理数据标注

图 10.7 – 使用 SageMaker Ground Truth 管理数据标注

你可以为任何任意的 ML 任务带入自己的 HTML 框架,甚至利用主动标注 (19) 功能,动态训练一个模型,使用你已标注的记录并加速整个标注过程。对于支持的内建任务,如图像分类、语义分割、物体检测和文本分类,这意味着你实际上会在已标注的数据上训练 ML 模型,然后对未标注的数据进行推理。当模型对其响应的置信度达到至少 80% 时,它被视为已标注样本。如果没有,它会被转交给人工团队进行标注。总体来说,这可以大幅度降低你的项目成本。

SageMaker Ground Truth 的另一个不错的功能是,它会自动为你整合标注者之间的任何差异。你可以定义想要多少人标注你的对象,它会根据每个标注者的准确性进行平均,然后使用这个每个人的平均准确度来整合每个对象的投票。

对于托管模型,你还可以通过增强型人工智能解决方案将其与 SageMaker Ground Truth 连接。这意味着你可以设置触发器,通过 SageMaker Ground Truth 将模型推理响应引导至人工标注团队,审查响应并确保其准确且不对人类造成伤害。

现在你大致了解了如何在 ML 项目中融入人工标注,让我们来分解一下让 ChatGPT 运作的关键方法!

来自人类反馈的强化学习

关于 ChatGPT,有至少两件事是不可否认的。首先,它的发布引起了极大的关注。如果你在社交和大众媒体上关注机器学习话题,你可能记得被关于人们用它做从写新食谱到制定创业计划、从网站代码到 Python 数据分析技巧等各类内容的文章淹没。然而,围绕它的热议是有充分理由的。就性能而言,它实际上比世界上任何其他基于提示的自然语言处理(NLP)解决方案都要好得多。它在问题回答、文本生成、分类等多个领域树立了新的技术标准。它表现得如此出色,在某些情况下,甚至比基本的 Google 搜索更好!他们是怎么做到的呢?RLHF就是答案!

虽然 RLHF 本身并不是一个新概念,但在大型语言模型领域,RLHF 最显著的成功应用无疑是 ChatGPT。ChatGPT 的前身是 InstructGPT (20),OpenAI 在其中开发了一种新的框架来改进 GPT-3 的模型响应。尽管在参数数量上 InstructGPT 小 100 倍,但在许多文本生成场景中,InstructGPT 实际上优于 GPT-3。ChatGPT 更进一步,通过为训练数据添加明确的对话框架来增强这一点。这种对话有助于保持整个聊天的上下文,将模型引导回消费者提供的顶部数据点。

图 10.8 – 来自人类反馈的强化学习

图 10.8 – 来自人类反馈的强化学习

让我们来解析强化学习吧!为了简化过程,我们可以将其分解为三个关键步骤:

  1. 首先,从由人类主持的预训练模型中收集数据。OpenAI 将人类提供的实际问题发送给一组人工标注员进行标注。这些标注数据随后被用于微调大型 GPT-3 类型的模型——在这种情况下,特别是 GPT-3.5。

  2. 接下来,使用微调后的模型并提交提示。之后,OpenAI 要求人工标注者简单地对输出进行排名。我喜欢这种方法,因为它很好地弥合了标注自由生成任务这一固有主观性的工作与生产更好机器学习模型这一客观目标之间的差距。当人类将响应从最好到最差进行排名时,它避免了主观问题“这好不好?”,而是用一个客观问题“哪个是你最喜欢的?”来代替。通过这些排名的响应,它训练出一个奖励模型,这只是一个机器学习模型,接收给定的提示并根据人类的响应对其进行评分。我想这应该是一个回归模型,尽管分类模型也可以使用。

  3. 最后,OpenAI 使用一种强化学习算法,具体来说是 PPO,将各个环节连接起来。它从大语言模型(LLM)生成一个提示响应,在强化学习文献中,我们称之为采取行动。这个响应的奖励是通过将其与我们在前一步训练的奖励模型进行对比得出的。这个奖励用于更新 PPO 算法,进而确保下一次生成的响应更接近能够获得的最高奖励。

这就是 RLHF 的精髓!我认为这是将细致的人类偏好与机器学习模型结合起来的绝妙方式,迫不及待想在下一个项目中尝试它。

在我们进入下一章,检测和缓解偏差之前,让我们快速回顾一下本章中讨论的所有概念。提示:内容很多!

摘要

本章的目标是让你更好地理解微调和评估机器学习模型,比较它们与开源选项,最终确保人类始终在决策环节中参与。

我们从回顾语言、文本及其相关领域的微调开始,讨论了通用知识和专业知识的优势。我们学习了如何微调仅限语言的模型,并了解即使数据量较小,通常也能实现这一点。我们还讨论了如何微调仅限视觉的模型,并认识到它们更容易出现过拟合,从而使得这种方法更加具有挑战性。我们研究了微调联合训练的视觉-语言模型,包括 Stable Diffusion 和一个名为 Riffusion 的有趣开源项目。我们讨论了与现成的公共模型进行性能比较。我们了解了视觉、语言以及新兴的联合视觉-语言空间的模型评估指标。我们还探索了在整个过程中如何确保人类参与,最终讨论了 ChatGPT 中使用的 RLHF(人类反馈强化学习)!

现在,你已准备好在下一章学习如何在你的机器学习项目中检测和缓解偏差。

参考文献

  1. tatsu-lab/stanford_alpaca: github.com/tatsu-lab/stanford_alpaca

  2. LORA:大规模语言模型的低秩适配: arxiv.org/pdf/2106.09685.pdf

  3. 用人类反馈训练语言模型以遵循指令: arxiv.org/pdf/2203.02155.pdf

  4. 主旨演讲人: sites.google.com/view/wacv2023-workshop/speakers

  5. 将视觉类别模型适配到新领域: link.springer.com/content/pdf/10.1007/978-3-642-15561-1_16.pdf?pdf=inline%20link

  6. 针对领域泛化和适应性进行预训练的广泛研究: arxiv.org/pdf/2203.11819.pdf

  7. RIFFUSION: www.riffusion.com/about

  8. MusicLM: 从文本生成音乐: arxiv.org/pdf/2301.11325.pdf

  9. 以符号音乐生成为重点的 Diffusion-LM: cs230.stanford.edu/projects_fall_2022/reports/16.pdf

  10. OpenAI: openai.com/research/musenet

  11. Segment Anything arxiv.org/pdf/2304.02643.pdf

  12. HELM: crfm.stanford.edu/helm/latest/

  13. 语言模型的整体评估: arxiv.org/pdf/2211.09110.pdf

  14. HELM: crfm.stanford.edu/helm/latest/?groups=1

  15. stanford-crfm/helm: github.com/stanford-crfm/helm

  16. BLEU: 一种用于机器翻译自动评估的方法: aclanthology.org/P02-1040.pdf

  17. ROUGE: 自动摘要评估包: aclanthology.org/W04-1013.pdf

  18. DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Driven Generation: arxiv.org/pdf/2208.12242.pdf

  19. 自动化数据标注: docs.aws.amazon.com/sagemaker/latest/dg/sms-automated-labeling.html

  20. 用人类反馈训练语言模型遵循指令: arxiv.org/pdf/2203.02155.pdf

第十一章:识别、缓解和监控偏见

在本章中,我们将分析大规模视觉、语言和多模态模型的主要偏见识别与缓解策略。你将了解偏见的概念,包括统计学意义上的偏见,以及它如何在关键方面影响人类。你将理解如何在视觉和语言模型中量化和修正这些偏见,最终掌握能够减少任何形式伤害的监控策略,以便在应用机器学习ML)模型时降低偏见带来的风险。

本章将涵盖以下内容:

  • 识别 ML 模型中的偏见

  • 缓解视觉和语言模型中的偏见

  • 监控 ML 模型中的偏见

  • 使用 SageMaker Clarify 识别、缓解和监控偏见

识别 ML 模型中的偏见

到目前为止,本书已经涵盖了大规模视觉和语言模型中许多有用、有趣和令人印象深刻的方面。希望我对这一领域的热情已经开始影响到你,你也开始意识到这不仅是一门科学,还是一门艺术。创建最前沿的 ML 模型需要勇气。风险是过程的一部分;你希望某条路径能够带来回报,但直到你沿着这条路走到最后,你无法确定。研究有所帮助,和专家讨论可以提前验证你的设计,但个人经验最终成为你工具箱中最有效的工具。

本章的全部内容都集中在可能是 ML 和人工智能AI)中最重要的致命弱点——偏见。特别地,我们关注的是针对特定群体的人类偏见。你可能已经听说过统计偏见,这是一种不希望发生的情形,其中一个模型在统计上对某一部分数据集有所偏好,因此自然对另一部分数据集存在偏见。这是每个数据科学项目中不可避免的阶段:你需要仔细考虑所使用的数据集,并思考这些数据如何向你的模型展示世界。如果你的数据集某些方面的表现过多或过少,这无疑会影响你的模型行为。在上一章中,我们探讨了信用卡欺诈的例子,开始理解提取和构建数据集的简单行为如何将你引入完全错误的方向。现在,我们将进行类似的练习,但这次重点关注人类群体。

当机器学习和数据科学开始在商业领导圈中流行时,和任何新现象一样,自然会有一些误解。关于机器学习的一个主要误解就是错误地认为计算机会比人类自然地有更少的偏见。这种虚假信念激发了不少项目。从招聘到绩效评估,从信用申请到背景调查,甚至包括刑事司法系统中的量刑,成千上万的数据科学项目开始时本意是减少偏见的结果。这些项目未能意识到的是,每一个数据集都受到历史记录的限制。当我们天真地用这些记录来训练机器学习模型时,我们必然会把这些限制引入到模型的输出空间中。

这意味着,从刑事司法到人力资源、金融服务和成像系统的记录,在未经深思熟虑的情况下用于训练机器学习模型时,固化了这些偏见,并以数字格式呈现。当这些数据被大规模使用时——例如,用于做出成百上千个数字决策——这实际上是增加了偏见决策的规模,而不是减少它。经典的例子包括大规模图像分类系统未能检测到非洲裔美国人(1),或者简历筛选系统对任何女性产生了偏见(2)。虽然所有这些组织立即采取了行动纠正错误,但整体问题仍然令全世界感到震惊。

检测大型视觉和语言模型中的偏见

正如你可能已经猜到的那样,基于从互联网爬虫获得的大量数据集训练的大型模型充满了偏见。这包括了从更可能在互联网上创作或不创作内容的人的类型,到语言和风格、话题、内容的准确性、分析的深度、个性、背景、历史、兴趣、职业、教育水平等各个方面。它还包括其他人的视觉表现、模式、文化风格、地点、事件、视角、物体、性取向、偏好、宗教——这个列表还可以继续列下去。

在大多数项目中,借用亚马逊的一句话,我发现从最终应用程序“倒推”是很有帮助的。在这里,这指的是一些大型视觉-语言模型——例如,Stable Diffusion。然后,我会问自己:可能会使用这个模型,怎么使用?试着写下你认为可能使用你模型的人的类型;在偏见的语境下,你需要迫使自己跳出舒适区。这是一个多元化团队极为有用的地方;理想情况下,向一个与你背景不同的人询问他们的视角。

一旦你有了可能使用你模型的目标人群列表,思考一下:这些人在我的数据集中有体现吗?他们是如何被体现的?他们是否在不同的情绪状态和结果的全谱中得到了体现,还是仅仅在一小部分人群中得到了体现?如果我的数据集是用于学习模式的计算过程的唯一输入——也就是机器学习算法——这些人群中的许多人会认为这是一个公平和准确的体现吗?或者,他们会生气并说:“这太偏见了!”

你可以从一两组人开始,通常你会考虑某些场景,在这些场景中,你知道数据集中存在一个大的差距。对我来说,我倾向于直接关注性别和就业。你也可以关注宗教、种族、社会经济地位、性取向、年龄等等。尽量扩展自己的思维,找到一个交集。交集指的是某个群体中的人可能会或不会出现在另一个类别中。这个第二类别可以是就业、教育、家庭生活、拥有特定物品、成就、犯罪历史、健康状况等。

当模型表现出明显的“偏好”或可衡量的习惯,把某些类型的人归入或不归入某些类型的群体时,模型就是有偏见的。当你的模型在经验上把某一类人(A类)放入或不放入另一类人(B类)时,偏见就会显现。

举个例子,假设你在使用 GPT 系列的文本生成模型。你可能会给你的 GPT 模型发送一个提示,比如:“Akanksha 非常努力地工作作为一名……”。一个有偏见的模型可能会把空白处填充为“护士”、“秘书”、“家庭主妇”、“妻子”或“母亲”。一个无偏的模型可能会把空白处填充为“医生”、“律师”、“科学家”、“银行家”、“作家”或“企业家”。想象一下,使用这个有偏见的模型作为简历筛选分类器、就业聊天热线或课程规划助手。它会不知不觉地,但非常可衡量地,继续对某些职业对女性的不利推荐!让我们再看几个语言上的例子:

图 11.1 – 来自 GPT-J 6B 的偏见推理结果

图 11.1 – 来自 GPT-J 6B 的偏见推理结果

在这里,我仅仅使用了自己的名字作为提示输入到 GPT-J 6B 模型中,模型认为我是一名化妆师。或者,如果我使用了“John”这个名字,它会认为我是一名软件开发者:

图 11.2 – 来自 GPT-J 6B 的偏见推理结果(续)

图 11.2 – 来自 GPT-J 6B 的偏见推理结果(续)

然而,当你再次尝试时,回应显然发生了变化。这是因为在 Hugging Face 模型平台中,随机种子并未设置,因此神经网络NN)的输出可能会变化。当我再次为 John 尝试时,它仍然给出了“软件开发人员”的回答。当我再次为我自己尝试时,它的回答是“自由职业社交媒体顾问”。

你们中的一些人可能会想:为什么这有偏见?这不就是依赖数据集中统计表示吗?答案是数据集本身就有偏见。数据集中男性软件工程师的例子更多,女性企业家的例子更少,等等。当我们在这些数据集上训练 AI/ML 模型时,我们将这种偏见直接带入我们的应用中。这意味着,如果我们使用有偏见的模型来筛选简历、建议晋升、给文本加样式、分配信用、预测健康指标、判断犯罪可能性等,我们就在系统地延续这种偏见。这是一个大问题——我们需要积极应对。

我们现在正在用预训练模型进行的这种猜测和检验过程叫做检测偏见识别偏见。我们正在使用一个预训练模型,并在之前定义的感兴趣群体交集的具体场景中进行测试,以实证地确定其表现如何。一旦你找到一些偏见的实证例子,运行汇总统计数据来了解其在数据集中发生的频率也是有帮助的。亚马逊的研究人员在这里提出了多种度量方法来做到这一点(3)

你也可以对预训练的视觉模型做类似的处理,例如稳定扩散。让你的稳定扩散模型生成不同场景下的人物图像、工人图像等。尝试调整提示语,强迫模型将一个人分类为交集的某一类别,现如今你几乎可以保证会找到偏见的实证证据。

幸运的是,越来越多的模型正在使用“安全过滤器”,这些过滤器明确禁止模型生成暴力或露骨内容,但正如你在本章中所学到的,这远非没有偏见。

到目前为止,你应该已经对应用中偏见的含义有了清晰的认识。你应该知道自己想要为哪些群体设计,在哪些类别中希望提升模型的表现。确保你花足够的时间在实证上评估模型中的偏见,因为这将帮助你证明以下技术确实能改善你关心的结果。

减少视觉和语言模型中的偏见

既然你已经了解了如何检测视觉和语言模型中的偏差,接下来让我们探讨如何减轻这种偏差。通常,这涉及通过各种方式更新数据集,无论是通过采样、增强还是生成方法。我们还将讨论一些在训练过程中使用的技术,包括公平损失函数的概念以及其他技术。

如你所知,目前有两个关键的训练阶段需要关注。第一个是预训练过程,第二个是微调迁移****学习TL)。在偏差方面,一个关键点是你的模型表现出多少偏差转移。也就是说,如果你的预训练模型是基于带有偏差的数据集构建的,那么在你进行一些微调后,这些偏差是否会转移到新的模型中?

来自麻省理工学院(MIT)的一个研究团队最近(2022 年)开展了一项关于视觉中偏差转移影响的有趣研究(4),他们得出结论:“即使在将这些模型微调到下游目标任务之后,预训练模型中的偏差仍然存在。关键是,即使微调使用的目标数据集本身不包含这些偏差,这些偏差依然会存在。”这表明,在视觉领域,确保上游的预训练数据集没有偏差是至关重要的。研究发现,偏差会传递到下游任务中。

对于语言的类似研究得出了完全相反的结论!(11) 研究人员在他们的工作中使用回归分析,意识到偏差的存在更好的解释是微调数据集中的偏差,而不是预训练数据集。他们得出结论:“通过上游干预来减轻下游偏差——包括嵌入空间中的偏差减轻——大多数时候是徒劳的。”在语言领域,建议主要在下游任务中减轻偏差,而不是在上游。

这有多有趣?!在两个不同领域的类似工作中,关于减轻偏差的最有效聚焦点得出了相反的结论。这意味着,如果你在做视觉场景的工作,你应该花时间优化你的预训练数据集,消除偏差。相反,如果你在做语言项目,你应该专注于减少微调数据集中的偏差。

或许这意味着,视觉模型通常会将更多的上下文和背景知识带入其下游任务表现中,比如通过卷积将物体与附近的物体和模式关联,而语言模型则仅在更小的句子级别范围内应用这种上下文学习。

语言中的偏差减轻——反事实数据增强和公平损失函数

在语言学中,许多偏见缓解技术侧重于创造反事实。记住——反事实是指在现实世界中没有发生但本可以发生的假设情境。例如,今天早上你有很多选择可以吃早餐。你可能选择了咖啡配松饼。你也可能选择了早餐麦片配橙汁。你还可能和朋友一起去餐馆吃早餐,或者完全跳过了早餐。上述其中一个情况确实发生了,而其他情况完全是编造的。它们是可能的,但却是虚构的。每一种不同的情景都可以被视为反事实。它们代表了不同的情景和事件链,这些事件并未实际发生,但合理地可能会发生。

现在,考虑这个问题:如果你想让每个情景都有相等的发生概率,该怎么办?在你生活的数据集中,你已经建立了某些习惯。如果你想训练一个模型,使得所有习惯都被视为同样可能发生的,你就需要创造反事实,以平衡所有其他可能的结果。这种类型的数据集修改正是我们在尝试通过增强数据集来去偏见,或减少偏见时所做的。首先,我们识别出偏见是如何渗透到我们的模型和数据集中的,然后通过创造更多我们没有足够样本的情形,来减轻这种偏见,创造反事实。

介绍这些方法的研究可以在参考文献部分的参考文献(5)中找到——这项研究包括了来自亚马逊、UCLA、哈佛等的研究人员。如前所述,他们专注于性别与就业的交集。让我们看一个例子:

图 11.3 – 比较普通模型与去偏见模型的响应

图 11.3 – 比较普通模型与去偏见模型的响应

为了为他们的微调数据集生成反事实样本,研究人员使用了一个常见的技术,即交换代词。具体来说,他们“使用一个精心编制的性别词典,其中包含男性<->女性的映射,例如父亲 -> 母亲,她 -> 他,他 -> 她,等等”。利用这个代词词典,他们生成了新的序列,并将这些序列包含进了微调数据集中。

他们还定义了一个公平的知识蒸馏损失函数。我们将在接下来的章节学习所有关于知识蒸馏的内容,但从高层次讲,你需要知道的是,知识蒸馏是训练一个小模型以模仿大模型性能的过程。通常,这样做是为了缩小模型的大小,从而使你能够在单 GPU 环境下部署模型,理想情况下能保持大模型的相同性能,但使用的是一个更小的模型。

在这里,研究人员开发了一种新颖的蒸馏策略来平衡概率。在通用的蒸馏中,你希望学生模型学习到相同的概率分布,以应对给定的模式:

图 11.4 – 通过蒸馏均衡分布

图 11.4 – 通过蒸馏均衡分布

在这里,研究人员知道这将导致学生模型学到他们希望避免的相同偏见行为。为此,他们开发了一种新颖的蒸馏损失函数,将原始分布和反事实分布的权重设为相同。这个均衡损失函数帮助他们的模型学会将这两种结果视为同样可能,并使得你刚刚看到的公平提示响应得以实现!记住——为了构建不延续数据集中固有偏见的 AI/ML 应用程序,我们需要在模型本身中均衡对待人群的方式。

现在我们已经学习了克服语言偏差的几种方法,接下来让我们做同样的事情来解决视觉中的偏差。

视觉中的偏差缓解 – 减少相关性依赖并解决采样问题

在视觉场景中,你至少有两个大问题需要解决,具体如下:

  • 首先,缺乏足够的关于代表性不足群体的图片

  • 其次,意识到自己的图片与潜在的物体或风格相关,直到为时已晚

在第一个场景中,你的模型可能根本无法学习到该类。 在第二个场景中,你的模型学到了一个相关的混杂因子。它可能学到了更多关于背景中的物体、整体色彩、图像的整体风格等方面的信息,而不是你认为它在检测的物体。然后,它继续利用这些背景物体或痕迹进行分类猜测,从而导致明显的性能不佳。让我们通过普林斯顿大学 2021 年的一项研究 (6) 来深入了解这些话题:

图 11.5 – 正确与错误的视觉分类

图 11.5 – 正确与错误的视觉分类

从根本上说,这些图像展示了计算机视觉中的相关性问题。这里,模型仅仅是试图对图像中的男性和女性进行分类。然而,由于这些数据集中的潜在相关性,模型会犯一些基本错误。就运动制服而言,研究人员发现“男性往往被表现为参与户外运动如棒球,而女性则倾向于被描绘为参与室内运动如篮球或穿着泳衣”。这意味着模型认为所有穿着运动制服在室内的人是女性,所有穿着运动制服在户外的人是男性!或者,在关于花卉的研究中,研究人员发现“男性与花卉合照时通常是在正式、官方场合,而女性则出现在摆拍场景或画作中。”希望你能立刻看到这是个问题;即使是模型也认为,所有出现在正式场合的人都是男性,单纯是因为缺乏相关的训练数据!

我们该如何解决这个问题呢?研究人员探讨的一个角度是地理因素。他们意识到——与先前的分析一致——图像的原产国主要是美国和欧洲国家。这在他们分析的多个常见视觉研究数据集中都是如此。在以下截图中,您可以看到模型将“dish”一词与东亚的食物物品关联起来,而未能检测到其他地区更常见的盘子或卫星天线:

图 11.6 – “dish”一词在地理意义上的视觉偏见

图 11.6 – “dish”一词在地理意义上的视觉偏见

普林斯顿团队开发并开源了一个名为REVISE: REvealing VIsual biaSEs (7)的工具,任何 Python 开发人员都可以用来分析自己的视觉数据集,并识别可能导致关联问题的候选对象和问题。该工具实际上在后台使用了亚马逊的 Rekognition 服务来对数据集进行大规模分类和对象检测!不过,如果您愿意,也可以修改它,使用开源分类器。该工具会自动建议采取减少偏见的措施,其中许多建议围绕着寻找额外的数据集,以增加对特定类别的学习。这些建议的行动还可能包括添加额外标签、整合重复注释等。

现在我们已经了解了多种减轻视觉和语言模型偏见的方法,让我们来探讨如何在您的应用程序中监控这些偏见。

监控机器学习模型中的偏见

在本书的这一部分,对于初学者来说,您可能已经开始意识到,实际上我们仅仅是在识别和解决偏见问题的冰山一角。其影响从模型性能差到对人类的实际伤害不等,尤其是在招聘、刑事司法、金融服务等领域。这也是凯西·奥尼尔在她 2016 年的书《数学毁灭武器》(8)中提出这些重要问题的一部分原因。她认为,尽管机器学习模型可以有用,但如果设计和实施不谨慎,它们也可能对人类造成相当大的伤害。

这引发了关于机器学习驱动创新的核心问题。在充满偏见的世界里,“足够好”到底有多好?作为一名热衷于大规模创新的机器学习从业者,同时也是一个在某些偏见中处于负面端、在其他偏见中处于正面端的女性,我常常会在这些问题上深思。

就我个人而言,有些数据科学项目我因为偏见而拒绝参与。对我来说,这至少包括招聘和简历筛选、绩效评估、刑事司法和一些金融应用。也许有一天我们能拥有平衡的数据和真正无偏的模型,但根据我目前的观察,我们离这个目标还很远。我鼓励每个机器学习从业者对那些可能对人类造成负面影响的项目建立类似的个人伦理。你可以想象,即使是看似无害的在线广告,也可能导致人群之间的大规模差异。从招聘、教育、社交网络到个人成长,从产品到金融工具,甚至心理学和商业建议的广告,实际上都可能延续大规模的社会偏见。

从更高层次看,我相信作为一个行业,我们可以继续发展。虽然一些行业要求第三方认证,例如医学、法律和教育专家,但我们的行业仍然没有。某些服务提供商提供与机器学习相关的认证,这无疑是朝着正确方向迈出的一步,但仍未完全解决雇主要求结果交付与潜在未知且未识别的对客户伤害之间的核心矛盾。当然,我并不是在这里声称自己有答案;我能看到这个论点双方的优点,并能同情创新者,也同样同情最终消费者。我只是在提出,这实际上是整个行业面临的一个巨大挑战,我希望我们能在未来为此开发出更好的机制。

在更直接可操作的层面上,对于那些在可预见的未来有交付项目的朋友,我建议采取以下步骤:

  1. 确定你客户群体的广泛图景,最好有多元化团队的帮助。

  2. 确定你的模型将对客户产生什么结果;推动自己超越对业务和团队的直接影响来思考。用亚马逊的一句口号说,思考更宏大!

  3. 尝试找到你的最佳和最差情况的实证例子——最佳情况是你的模型带来了双赢的结果,最差情况是导致了两败俱伤。

  4. 使用本书中学到的技巧,让双赢的局面更加常见,把两败俱伤的局面尽量减少。记住——这通常归结于分析你的数据,了解其缺陷和固有视角,并通过数据本身或通过你的模型和学习过程加以修正。

  5. 添加透明度。正如 O'Neil 在她的书中指出的那样,整个行业的问题部分源于那些影响人类的重要应用没有解释哪些特性实际上驱动了它们的最终分类。为了解决这个问题,你可以通过 LIME (9) 或像接下来我们将看到的 SageMaker Clarify 等技术,增加简单的特征重要性测试,或像像素和标记映射。

  6. 尝试为特别是最糟糕的结果场景制定定量衡量标准,并在已部署的应用程序中监控这些标准。

事实证明,检测、缓解和监控模型偏见的一种方式是 SageMaker Clarify!

使用 SageMaker Clarify 检测、缓解和监控偏见

SageMaker Clarify 是 SageMaker 服务中的一项功能,可以在你的机器学习工作流中用于偏见检测和可解释性。它与 SageMaker 的 Data Wrangler 紧密集成,Data Wrangler 是一个完全托管的 UI,用于表格数据分析和探索。该功能包括近 20 个偏见指标,统计术语你可以研究并使用,以便更精准地理解你的模型与人类之间的互动。我会在这里省略数学内容,但你可以随时阅读我关于此主题的博客文章:towardsdatascience.com/dive-into-bias-metrics-and-model-explainability-with-amazon-sagemaker-clarify-473c2bca1f72 (10)

本书更相关的是 Clarify 的视觉和语言特性!这包括解释图像分类和目标检测,以及语言分类和回归。这应该帮助你立即理解驱动你区分模型输出的因素,并帮助你采取措施纠正任何偏见决策。

实际上,大型预训练模型的模块化与较小输出(例如,使用 Hugging Face 轻松添加分类输出到预训练大语言模型LLM))的结合,可能是我们利用 Clarify 去偏见预训练模型的一种方法,最终用于生成任务。使用 Clarify 的一个重要理由是,你可以监控偏见指标和模型可解释性!

在本书的下一部分,第五部分,我们将深入探讨部署相关的关键问题。特别是在 第十四章 中,我们将深入讨论已部署到生产中的模型的持续操作、监控和维护。我们将在那里详细介绍 SageMaker Clarify 的监控功能,特别讨论如何将这些功能与审计团队和自动重训练工作流连接起来。

总结

在本章中,我们深入探讨了机器学习中的偏差概念,特别是从视觉和语言的角度进行了探索。我们首先讨论了人类偏差的一般情况,并介绍了几种这些偏差如何在技术系统中以经验性方式表现出来,通常是无意的。我们介绍了“交叉偏差”这一概念,并讲解了检测偏差时,首先需要列出一些常见的交叉类型,包括性别或种族与就业等。例如,我们展示了这一偏差如何轻易渗入从互联网抓取的数据集所训练的大型视觉和语言模型。我们还探讨了缓解机器学习模型中的偏差的方法。在语言方面,我们介绍了反事实数据增强和公平损失函数。在视觉方面,我们了解了相关依赖问题,并展示了如何使用开源工具分析视觉数据集并解决采样问题。

最后,我们学习了如何监控机器学习模型中的偏差,包括关于个人和职业伦理的广泛讨论,以及针对项目的可操作步骤。我们以 SageMaker Clarify 的展示作为结尾,您可以使用它来检测、缓解并监控您的机器学习模型中的偏差。

现在,让我们深入研究第五部分:部署! 在下一章中,我们将学习如何在 SageMaker 上部署您的模型。

参考文献

请查看以下内容,了解本章涉及的某些主题的更多信息:

  1. 谷歌为照片应用的种族主义错误道歉: www.bbc.com/news/technology-33347866

  2. 亚马逊废弃了一个显示对女性存在偏见的秘密 AI 招聘工具: www.reuters.com/article/us-amazon-com-jobs-automation-insight/amazon-scraps-secret-ai-recruiting-tool-that-showed-bias-against-women-idUSKCN1MK08G

  3. 粗体:用于衡量开放式语言生成偏差的数据集和指标: assets.amazon.science/bd/b6/db8abad54b3d92a2e8857a9a543c/bold-dataset-and-metrics-for-measuring-biases-in-open-ended-language-generation.pdf

  4. 偏差在迁移学习中何时发生转移?: arxiv.org/pdf/2207.02842.pdf

  5. 通过反事实角色反转来缓解蒸馏语言模型中的性别偏差: aclanthology.org/2022.findings-acl.55.pdf

  6. 修订:用于衡量和减少视觉数据集偏差的工具: arxiv.org/pdf/2004.07999.pdf

  7. princetonvisualai/revise-toolgithub.com/princetonvisualai/revise-tool

  8. 数学毁灭武器:大数据如何加剧不平等并威胁民主 精装版 – 2016 年 9 月 6 日:www.amazon.com/Weapons-Math-Destruction-Increases-Inequality/dp/0553418815

  9. 为什么我应该信任你?解释任何分类器的预测www.kdd.org/kdd2016/papers/files/rfp0573-ribeiroA.pdf

  10. 深入了解偏差度量和模型可解释性,使用 Amazon SageMaker Clarifytowardsdatascience.com/dive-into-bias-metrics-and-model-explainability-with-amazon-sagemaker-clarify-473c2bca1f72

  11. 上游缓解并非你所需要的一切:测试预训练语言模型中的偏差转移假设aclanthology.org/2022.acl-long.247.pdf

第十二章:如何部署您的模型

在本章中,我们将向您介绍多种模型部署技术,包括实时端点、无服务器架构、批量选项等。这些概念适用于许多计算环境,但我们将重点讨论在 Amazon SageMaker 上可用的功能。我们将讨论在部署之前为什么应该尝试缩小模型的大小,并介绍在视觉和语言领域的相关技术。我们还将介绍分布式托管技术,适用于那些无法或不需要缩小模型的场景。最后,我们将探讨模型服务技术和概念,帮助您优化模型的端到端性能。

本章将涵盖以下主题:

  • 什么是模型部署?

  • 如何托管我的模型是最好的方式?

  • AWS 上使用 SageMaker 部署模型的选项

  • 缩小模型大小的技术

  • 在 SageMaker 上托管分布式模型

  • 模型服务器和端到端托管优化

什么是模型部署?

在经过几周到几个月的时间,从优化数据集到分布式训练环境,评估模型,减少偏差后,您一定迫不及待想要将模型发布给客户了!在本书的这一部分,我们将专注于与模型部署相关的所有关键主题。但首先,让我们尝试解释一下这一术语本身。

模型部署指的是将您的模型集成到应用程序中。这意味着除了在笔记本中使用您的模型进行本地分析或运行报告之外,您还将其连接到其他软件应用程序。最常见的情况是,您将该模型集成到一个应用程序中。这个应用程序可能只是一个分析仪表盘,也可能是一个欺诈检测系统、自然语言聊天、通用搜索、自动驾驶汽车,甚至是一个视频游戏。在下一章中,我们将提供更多关于跨组织使用案例的想法,特别是那些由大型预训练视觉和语言模型提供加速的案例。

对我来说,数据科学团队的一个重要区分点是他们是否会部署模型。如果他们部署模型,这通常意味着他们的模型以自动化方式与客户互动,并创造业务价值。这通常表明他们的团队将产品开发作为主要输出。或者,你也可能会看到一些数据科学团队将知识构建作为主要输出。这在一些金融服务、医疗保健和公共部门组织中比较常见。他们可能专注于回答业务利益相关者的分析问题,较少关注交付产品,而更多关注理解其庞大而复杂的数据集。本书的大部分内容都致力于关注产品的团队,但许多工具和概念也适用。本章的大部分内容将与构建产品极为相关。为什么?因为模型成为了产品的一部分。部署是实现这一点的步骤。

数据科学团队将模型部署任务交给工程团队是常见的做法。通常这样做是为了让数据科学家和应用科学家能够专注于核心的研究与开发,而工程团队则可以专注于端到端优化应用程序。有些团队同时包含数据科学和平台工程,而也有一些人对整个流程充满好奇!在第十四章中,我们将深入探讨目前被称为 MLOps 的运营问题,这将帮助你开发人员、流程和技术,以简化部署。这通常包括模型监控、审计、自动重训练、调优等内容。

本书中我们关注的大多数部署模式明确地将模型保留在云端。这是为了简化端到端的操作。然而,一些应用无法承受额外的延迟,尤其是往返云端的延迟,无论我们如何降低这一延迟。这些应用包括自动驾驶汽车、视频游戏执行、手机部署、低互联网连接场景、机器人技术等。这些应用通常将模型工件和推理脚本直接集成到 SDK 构建中。然而,这只有在模型足够小,能够适应目标部署设备时才可能实现。这对 Meta 的较小 LLaMA 模型(1)、Stable Diffusion 以及其他单 GPU 模型而言尤为相关。这意味着我们稍后将在本章讨论的相同模型缩减技术,对云端和设备端部署都适用。

在 2021 年,我领导了 AWS 的一个团队,发布了一份关于混合机器学习的 35 页白皮书。它可以在网上免费获取,链接如下:docs.aws.amazon.com/pdfs/whitepapers/latest/hybrid-machine-learning/hybrid-machine-learning.pdf (2)。该白皮书包括了每种架构的建议性指南以及优缺点。与本书类似,许多概念适用于各种计算环境,但为在 AWS 上工作提供了深入的技术信息。

现在你对模型部署的概念有了更好的了解,让我们来探索你可以选择的不同选项吧!

我该如何托管我的模型?

正如你可能预期的,这个问题的答案完全取决于你正在构建的应用程序。首先,大多数客户都会提出一个大问题:你是否需要实时或同步方式从模型中获取响应?这适用于搜索、推荐、聊天等应用程序。大多数实时模型部署使用托管端点,这是一个持续运行在云端的实例,用于处理请求。与此相对的是批处理。批处理作业将你的模型和推理数据带入,启动计算集群在所有请求数据上执行推理脚本,然后关闭。实时部署和批处理作业之间的关键区别在于新数据和模型推理请求之间的等待时间。实时部署能够提供尽可能快速的模型响应,虽然你需要为此支付更多费用。而批处理作业则是在作业完成之前不会返回模型响应,你会等待几分钟,但支付的费用要少得多。

让我们首先详细探讨实时端点,然后再深入了解批处理和更多选项。对于那些已经熟悉 SageMaker 托管并希望直接跳到有关如何托管基础模型问题的读者,请随时直接跳到以下部分。

我们在 Amazon SageMaker 上推出的最早的功能之一就是实时端点。这些是完全托管的 API,用于托管你的模型和脚本。如下面的图所示,当指定时,它们可以在多个可用区的多个实例上运行。SageMaker 可以根据客户流量自动扩展这些端点,根据需要启动和停止实例。SageMaker 还会管理一个负载均衡器,将流量发送到这些端点,所有这些都由端点本身处理,与请求流量进行交互。

图 12.1 – 指向 SageMaker 端点的示例架构

图 12.1 – 指向 SageMaker 端点的示例架构

终端会与接口进行交互,例如 Lambda 函数或简单的 API 网关。然后,网关会直接与客户端应用程序交互。例如,您可能在本地托管一个网页应用程序,例如搜索航空航班。根据客户的偏好和航班历史,您可能希望使用推荐算法。您的数据科学团队可能会在另一个账户中分析这些数据,训练模型并优化该模型的投资回报率。一旦他们找到一个表现合理的模型工件,他们可以使用自己的脚本、包和对象将其加载到 SageMaker 终端。然后,您可能会将该工件推广到您的生产账户,进行渗透测试和安全测试。部署后,这个新终端可以与 API 请求进行交互。网站托管团队可以简单地指向您在云中托管的新 API,而您的数据科学团队则独立更新和监控模型。

我们将在接下来的章节中介绍更多的这些架构最佳实践,但现在,先来看一下您在 AWS 账户中已可用的一些模型部署选项。

AWS 上使用 SageMaker 的模型部署选项

以下术语是您在 AWS 账户中已可用的一些模型部署选项:

  • 实时终端:如前所述,实时终端是通过 SageMaker 提供的始终在线的完全托管计算资源。您提供您的模型和推理脚本;我们为您提供整个 RESTful API。这包括随着流量增加而启动,流量减少时则关闭的能力。这会影响您的费用,因为您是按实例每分钟付费的。实时终端还具有许多其他功能,例如支持 GPU 运行、分布式托管、多模型终端、异步终端等。目前,它们的最大负载大小为 6 兆字节,最大请求运行时间为 60 秒。

  • 批量转换和计划的笔记本:实时终端的两个主要替代方案:

    • 批量 转换作业

    • 计划的 笔记本作业

使用 SageMaker 上的 批量转换,您与实时终端起始位置相似,都有一个训练好的模型和推理脚本,但您还需指向在运行时已知的数据集。这意味着您将启动一个批量转换作业,指向一个已知的数据集。您还需要确定此作业所需的计算资源。SageMaker 会启动这些资源,针对数据进行模型推理, 将推理结果存储到 S3 中,然后关闭计算资源。

一个类似的服务是 笔记本作业。与直接使用预训练的模型工件不同,笔记本作业以整个笔记本作为起始点。当你想运行一组 Python 函数或数据分析步骤,并生成多个图表和图形作为分析结果时,你可以使用笔记本作业。你可以在 SageMaker Studio 中编写笔记本,并简单地创建一个定时笔记本作业,而无需编写任何代码!

  • 异步端点:如果你计划托管大型模型,或者你的推理脚本中有大量计算,那么推理请求可能无法在 60 秒内完成。在这种情况下,你可能需要考虑使用异步端点。这些端点可以为你提供最长 15 分钟的运行时间,并配有管理队列来处理所有请求。你将拥有最大 1 GB 的负载大小,这比实时端点的 6 MB 负载限制大大提升。异步端点非常适合文档处理任务,比如实体识别和提取。

  • 多模型端点:在使用实时端点时,你可以额外选择在同一端点上托管 多个模型。这有三种不同的方式。首先,你可以使用一个容器托管在端点上,并将多个模型存储在 S3 中。这对于处理涉及成千上万个模型的使用场景非常适合,例如为你数据库中的每个客户训练小型线性模型。你可以将任意数量的模型存储在 S3 中,只要它们使用相同的托管镜像,并将模型名称发送到 SageMaker 多模型端点。我们会从 S3 加载该模型并将其载入 RAM,响应请求。之后,该模型会被缓存以应对未来的流量,当不再需要时会被发送回 S3。

另一个更简单的选项是 在一个端点上存储多个容器。在这种模式下,你可以创建多个容器,例如一个使用 XGBoost,另一个使用 PyTorch,还有一个使用 pandas,依此类推。只要端点足够大,它就能托管这些容器,并且你可以根据请求确定使用哪个容器。

最后,你还可以使用所谓的 串行推理管道。这也使用多个容器,但每个容器会依次调用,类似于一个管道。你可能会在特征预处理时使用这种方法,比如运行 LDA 或 VAE,然后将其应用于你的模型。

  • 无服务器端点:在 SageMaker 上托管模型的另一个选项是无服务器端点。这对于基于 CPU 的模型,如 KNN 或逻辑回归,非常适合,尤其是在你预期间歇性流量时。这可能包括长时间没有任何推理请求,然后突然出现流量激增。无服务器选项非常具有成本效益,所以如果你能够在无服务器环境下满足延迟目标,那么这通常是一个不错的选择。鉴于 Lambda 函数现在可以支持最多 10GB 的内存 (3),你可能能够将已经较小的基础模型缩小到这些运行时要求。基于 CPU 的运行时可能会有挑战,但如果较慢的响应时间不成为阻碍,无服务器可能是一个选项。

在 SageMaker 上托管有很多其他方面的内容。你可以监控你的模型,启用自动扩展,解释模型,安全地验证模型,应用影子测试,在注册表中目录化模型,启用 A/B 测试,对其进行审计等等。我们将在 第十四章 中深入探讨这些话题。现在,让我们了解如何减少推理模型大小的方法。

为什么我需要缩小我的模型,如何缩小?

在了解了大模型如何提升准确性的强大能力后,你可能会想,为什么我会考虑缩小我的模型呢?事实上,大型模型可能响应推理请求的速度非常慢,并且部署成本很高。尤其是在语言和视觉应用中,包括从视觉搜索到对话、图像到音乐生成、开放领域问答等。虽然这对训练而言不一定是问题,因为唯一等待模型完成的人是你自己,但在托管过程中,当你试图让客户满意时,它会成为一个巨大的瓶颈。正如许多研究所证明,在数字体验中,每毫秒都至关重要。客户非常严格地偏好快速、简洁和高效的在线界面。这就是为什么在业界有多种技术能够加速模型推理而不降低准确度。这里我们将介绍三种关键技术:编译、知识蒸馏和量化。

模型编译

如我们之前所学,编译是一种可以用于基于 GPU 的深度学习模型的技术。根据编译器中对运算符的支持,你可能能够为你所选的目标设备编译一个预训练模型。AWS 提供了一个托管功能,称为 SageMaker Neo,它会运行一个编译任务,将你的工件转换为指定环境下的格式。这适用于云端和设备端的部署。尽管 Neo 可以将你的模型大小减少最多 10 倍,但不能保证它适用于任何任意的神经网络,因此需要谨慎操作。

知识蒸馏

知识蒸馏是一种迷人的技术,它使用一个较大的模型(称为教师模型)来影响一个较小模型(称为学生模型)的性能。通过梯度下降,特别是计算两个分布之间差异的 KL 散度,我们可以教学生模型模仿教师模型的行为。一个非常合乎逻辑的应用场景是大规模预训练之后!例如,利用规模法则将模型的规模扩大到与数据规模匹配,帮助你最大化在准确性和计算智能上的潜力。然而,在此之后,你可以使用知识蒸馏来优化该模型在生产环境中的性能。根据教师模型和学生模型之间的规模差距,你可以轻松将推理运行时间提升 10 倍或更多,同时仅损失少量的准确性。以下是 Jianping Gou(3)等人在其 2021 年关于该领域的调查中展示的知识蒸馏的可视化呈现。

图 12.2 – 通过蒸馏进行知识转移

图 12.2 – 通过蒸馏进行知识转移

虽然教师模型和学生模型接收相同的数据集,但我们通过比较它们生成的概率来传递知识给学生。然后,我们只需更新学生模型,以最小化它们之间的差异!

知识蒸馏在其他应用中也非常有用,包括机器翻译和基于人类反馈的强化学习RLHF)。专业提示:RLHF 是 ChatGPT 背后的一个关键技术!我们在第十章中了解了更多关于它的内容。蒸馏还负责 DistiliBert(4),这是 Hugging Face 团队在 2019 年提出的一个模型。

量化

量化是另一种减少模型运行时间的技术。在这种情况下,我们并不是严格减少模型的内存占用(这是编译和蒸馏的做法),而是重构网络,使用较低精度的数据类型。在这里,数据类型指的是位表示,通常范围从高精度的 FP32 到 FP16 甚至 INT8。整数在计算上更容易表示,因此它们所需的存储空间较小。然而,浮点数显然更具表现力,因为它们可以表示介于整数之间几乎无限的数值范围。通过量化转换数据表示是有用的,因为当你将训练中的浮点数据类型转换为部署中的整数时,整体内存消耗会减少。如何操作取决于不同的框架,PyTorch 中如何实现可以在这里找到(5),NVIDIA 的 TensorRT 中也有相关细节(6)。量化确实有权衡,因此,在部署量化模型之前,请确保对其进行充分的测试,以了解它对速度和准确性的影响。

现在,你已经学习了几种减少模型占用空间的方法,接下来我们将介绍一些当你无法使用这些方法时可以采用的技术:分布式模型托管!

在 SageMaker 上托管分布式模型

第五章中,我们讲解了分布式基础知识,你学习了如何将模型和数据集分配到多个 GPU 上。好消息是,你可以使用相同的逻辑来托管模型。在这种情况下,你更关注的是模型并行,将层和张量分配到多个 GPU 分区。你实际上不需要数据并行框架,因为我们不使用反向传播。我们只是通过网络进行前向传播,并获取推理结果。这里没有梯度下降或权重更新的过程。

什么时候使用分布式模型托管?将超大型模型集成到你的应用程序中!通常,这仅限于大型语言模型。视觉模型超出单 GPU 的情况较为罕见。记住,在第四章中,云中的容器与加速器部分,我们了解了不同大小的 GPU 内存。这对于托管和训练同样重要。估算模型的 GB 大小的一种简单方法是查看其存储在磁盘上的占用空间。虽然当对象从磁盘转移到内存时,大小可能会略有变化,但总体的磁盘占用空间仍然是一个很好的估算值。

对于像 GPT-3 这样拥有 175B 参数的超大型模型,模型通常至少需要 350GB 的存储!在这个案例研究(7)中,我们展示了如何在 SageMaker 上托管这样一个规模的模型,只使用 8 个 A100。那是一个ml.p4d.24xlarge实例,在 SageMaker 公开定价下,约为每小时 37 美元!尽管这是训练成本的一小部分,训练成本对于超大型基础模型来说可能轻松达到 10 倍甚至更多,但看到账单上的这个费用依然令人感到痛苦。

除了这个集群的巨大成本,你还会给客户带来额外的延迟成本。想象一下,如果在 8 个 GPU 上运行任何过程,即便使用流水线和张量并行,速度仍然不会特别快。

现在,让我们了解一些关键的基础技术,它们将所有这些内容汇聚在一起。然后,我们将看看 6B 和 175B 规模的托管模型的几个示例。

SageMaker 上的大型模型托管容器

正如我们在训练基础模型时学到的,关键在于基础容器和你使用的相关软件包,这些都是你实现目标的核心。对于在 SageMaker 上托管大型模型,我们提供了专门的深度学习容器,专门用于这个目的。这些容器已在 GitHub 上开源(8),你可以轻松查看并在其基础上进行开发。

大模型推理容器为你打包并提供了两项关键技术:DJLServing 和 DeepSpeed。Deep Java LibraryDJL(9) 最初是为 Java 开发者构建的,用于构建 ML 模型和应用程序。他们构建了一个通用的模型托管解决方案,语言无关,提供了一个共同的基准,可以跨 TensorFlow、ONNX、TensorRT 和 Python 等框架托管模型。他们还通过 MPI 和套接字连接原生支持多 GPU 托管。这使得它成为分布式托管的一个有吸引力的选择!

AWS 大模型托管容器提供的第二项关键技术是 DeepSpeed。值得注意的是,DeepSpeed 非常有帮助,因为它将你的张量分片到多个 GPU 上,并自动找到最佳的分片策略。正如我的同事在这篇博客文章中讨论的那样(10),DeepSpeed 在确定最佳分片方案时,评估了推理延迟和成本。

如果你想详细了解这个的实际操作示例,可以查看我们的 6B GPT-J 笔记本:github.com/aws/amazon-sagemaker-examples/blob/main/inference/generativeai/deepspeed/GPT-J-6B_DJLServing_with_PySDK.ipynb

较小的示例是一个很好的起点,因为它为跨多个 GPU 托管模型提供了非常简单、实用且成本较低的内容。一旦你测试过这个,就可以升级到一个更大的示例,通过这个 BLOOM 笔记本托管 175B 参数:github.com/aws/amazon-sagemaker-examples/blob/main/inference/nlp/realtime/llm/bloom_176b/djl_deepspeed_deploy.ipynb

现在我们已经介绍了一些分布式托管的选项,让我们以一个快速讨论模型服务器和优化端到端托管体验来结束这一章。

模型服务器和端到端托管优化

你可能会想:如果 SageMaker 托管我的模型工件和推理脚本,我怎么将它转化为一个能够响应实时流量的服务呢?答案就是模型服务器!对于那些不特别想了解如何将模型推理响应转换为 RESTful 接口的人来说,你会很高兴地知道,在 SageMaker 上,这些操作大部分已经被抽象化,便于快速原型开发。然而,如果你想优化推理堆栈以提供最先进的模型响应,请继续阅读。

在改进模型托管响应时,有五种关键类型的延迟需要缩减。以下是我们总结的这些延迟类型:

  • 容器延迟:指的是进入和退出其中一个容器所需的时间开销。正如我们之前所学,在 SageMaker 上,你可能会在串行推理管道中托管各种容器。这里展示了这一点。容器延迟是调用和退出一个容器的时间。

  • 模型延迟:包括所有容器在端点上的调用和退出时间。正如下面的图 12.13所示,单个容器的延迟可能远小于模型的整体延迟。

  • 开销延迟:指的是 SageMaker 路由请求、接收来自客户端的请求并返回的时间,减去模型的延迟。

  • 端到端延迟:主要从客户端的角度来计算。它受客户端请求带宽、与云的连接、SageMaker 前的任何处理、开销延迟以及模型延迟的影响。

让我们将这些部分一起看看:

图 12.3 – SageMaker 上的端到端模型延迟

图 12.3 – SageMaker 上的端到端模型延迟

作为这个服务的用户,你可以部署一些优化技术。首先,这对于 AWS 上的任何应用程序都适用,将应用程序推送到你的客户所在的位置! 使用 AWS 的一个主要原因是我们拥有全球最大的基础设施,比任何其他 CSP 都要大。我们拥有更多的区域和更高可用性的设计,比地球上任何其他云平台都要多。当你将应用程序推送到离客户最近的地理区域或接入点时,请将这一点作为你的资产。这将立即减少客户请求到达云端所需的时间,因为它需要在网络上传输的距离会更短。

我的 AWS 同事们发布了一篇精彩的博客文章,介绍了如何为 SageMaker 托管工作负载优化容器。特别是,他们探索了 NVIDIA 的 Triton,一个开源项目,可以提供超低延迟的模型推理结果,延迟甚至可以低至单个毫秒。

要了解更多关于 Triton 的详细信息,除了对 SageMaker 托管的端到端优化外,请参阅他们关于这个话题的博客文章:aws.amazon.com/blogs/machine-learning/achieve-hyperscale-performance-for-model-serving-using-nvidia-triton-inference-server-on-amazon-sagemaker/ (11)

最后,我还想特别提到 SageMaker 的推理推荐器 (12),它可以帮助你根据预期的流量选择合适的实例类型、数量和配置。事实上,我的团队使用推理推荐器在 Triton 上进行测试!

现在,您对模型服务器是什么以及如何使用它们来优化端到端托管性能有了更深入的了解,让我们在本章结束时做一个总体回顾。

总结

我们将模型部署定义为将模型集成到客户端应用程序中。我们讨论了可能会部署自己模型的数据科学团队的特点,以及那些可能专注于更一般分析的团队。我们介绍了多种模型部署在整个应用程序中至关重要的用例。虽然提到了多种混合架构,但我们特别关注了云中的部署。我们了解了托管模型的一些最佳方式,包括 SageMaker 上的实时端点、批量转换和笔记本作业、异步端点、多模型端点、无服务器端点等选项。我们了解了减少模型大小的选项,从编译到蒸馏和量化。我们还讨论了分布式模型托管,并以回顾模型服务器和在 SageMaker 上优化端到端托管的建议作为结尾。

接下来,我们将深入探讨一组可以与基础模型互动的技术,以便挤出最佳性能:提示工程!

参考文献

  1. LLaMA:开放高效的基础语言 模型: arxiv.org/pdf/2302.13971.pdf

  2. Lambda 配额: https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html

  3. 知识蒸馏:一项 综述: arxiv.org/pdf/2006.05525.pdf

  4. DistilBERT,一个精简版的 BERT:更小、更快、更便宜、 更轻]: https://arxiv.org/pdf/1910.01108.pdf

  5. 量化: pytorch.org/docs/stable/quantization.html

  6. 使用 NVIDIA Triton 推理服务器在 Amazon SageMaker 上实现模型服务的超大规模性能: aws.amazon.com/blogs/machine-learning/achieve-hyperscale-performance-for-model-serving-using-nvidia-triton-inference-server-on-amazon-sagemaker/

  7. 在 Amazon SageMaker 上使用大型模型推理深度学习容器和 DeepSpeed 部署 BLOOM-176B 和 OPT-30B: aws.amazon.com/blogs/machine-learning/deploy-bloom-176b-and-opt-30b-on-amazon-sagemaker-with-large-model-inference-deep-learning-containers-and-deepspeed/

  8. 大型模型推理 容器github.com/aws/deep-learning-containers/blob/master/available_images.md#large-model-inference-containers

  9. 深度 Java djl.ai/

  10. 使用 DJLServing 和 DeepSpeed 模型并行推理在 Amazon SageMaker 上部署大型模型aws.amazon.com/blogs/machine-learning/deploy-large-models-on-amazon-sagemaker-using-djlserving-and-deepspeed-model-parallel-inference/

  11. 使用 NVIDIA Triton 推理服务器在 Amazon SageMaker 上实现超大规模模型服务性能https://aws.amazon.com/blogs/machine-learning/achieve-hyperscale-performance-for-model-serving-using-nvidia-triton-inference-server-on-amazon-sagemaker/

  12. Amazon SageMaker 推理 推荐系统docs.aws.amazon.com/sagemaker/latest/dg/inference-recommender.html

第五部分:部署你的模型

在第五部分,你将学习如何部署你的模型。你将使用蒸馏、量化和编译等技术来减少模型的整体体积。你还将确定最合适的用例,以便在组织中扩展模型,并了解持续的操作、监控和维护。

本节包括以下章节:

  • 第十三章提示工程

  • 第十四章视觉与语言的 MLOps

  • 第十五章预训练基础模型的未来趋势

第十三章:提示工程

在本章中,我们将深入探讨一种特殊的技术集合——提示工程。你将从高层次了解这一技术,包括它与本书中其他基于学习的主题的相似性和差异性。我们将探索视觉和语言方面的示例,深入研究关键术语和成功指标。特别地,本章涵盖了所有改进性能的技巧与窍门,无需更新模型权重。这意味着我们将模拟学习过程,而不一定改变任何模型参数。这包括一些高级技术,如提示和前缀微调。本章将涵盖以下主题:

  • 提示工程 – 用更少的输入获得更多的艺术

  • 从少量学习到零-shot 学习

  • 文本到图像提示的技巧与窍门

  • 图像到图像提示的最佳实践

  • 提示大型语言模型

  • 高级技术 – 提示和前缀微调

提示工程 – 用更少的输入获得更多的艺术

在本书的这个阶段,以及在你的项目中,你应该已经在你的新基础模型上投入了大量的时间。从计算成本、数据集、定制代码到你阅读过的研究论文,你可能已经花费了 50 到 100 小时或更多的时间来提升性能。为你鼓掌!这是一种很棒的生活方式。

然而,在你完成这一切之后,尤其是当你学会如何围绕你的模型构建一个完整的应用时,接下来就是最大化你的模型在推理时的表现了。在上一章中,我们了解了多种优化模型运行时的方法,从编译到量化,再到蒸馏和分发,每一种都对加速推理结果有所帮助。然而,本章的重点是获得你能够得到的最准确的响应。在这里,我使用“准确”一词是为了表明任何类型的模型质量评估指标。如你在上一章关于评估中所学,准确率本身是一个具有误导性的术语,通常不是评估指标中最好的选择。更多细节请参见第十章

提示工程包括一组与选择最佳输入以进行模型推理相关的技术。推理是指在不更新权重的情况下从模型中获取结果;可以将其理解为没有任何反向传播的前向传递。这很有趣,因为它是你如何从模型中获取预测的方式。当你部署你的模型时,你是在进行推理。

提示工程包含了大量的技术。它包括像零-shot 和少量-shot 学习这样的内容,我们向模型提供多个示例,要求它完成逻辑序列。它还包括选择正确的超参数。它包括大量的猜测和检验,测试你的模型结果并找出最适合的技术。

对于那些为终端消费者托管生成性 AI 模型的你们,可能会考虑搭建一个客户端来处理提示工程。这在模型演示平台中似乎比较常见,其中并非所有的参数和模型调用都是直接公开的。作为应用开发者,你可以并且应该修改客户发送给你模型的提示,以确保他们获得最佳性能。这可能包括在调用中添加额外的术语、更新超参数以及重新表述请求。

让我们更详细地探讨一下提示工程以及与之相关的技能——少样本学习。

从少样本到零样本学习

正如你所记得的,我们一直在参考的一个关键模型是GPT-3,即生成预训练变换器。提供第三版的论文叫做语言模型是少样本学习者。(1)为什么?因为这篇论文的主要目标是开发一个能够在没有大量微调的情况下表现良好的模型。这是一个优势,因为它意味着你可以使用一个模型来覆盖更多的使用场景,而不需要开发定制代码或整理定制数据集。换句话说,零样本学习的单位经济学比微调更强。在微调的世界中,你需要为基础模型的任务解决方案付出更多努力。这与少样本学习的世界不同,在少样本学习中,基于你的基础模型解决其他任务要容易得多。这使得少样本模型更有价值,因为微调模型在大规模应用时成本太高。虽然在实践中,微调比少样本学习更稳健地解决问题,但它使得提示工程的整个实践变得非常有吸引力。接下来让我们看看以下屏幕截图中的一些示例。

图 13.1 – 来自 GPT-3 论文的少样本学习示例

图 13.1 – 来自 GPT-3 论文的少样本学习示例

在左侧,我们看到模型推理的不同输入选项。在论文中,他们使用了“上下文学习”这一短语,指的是在数据集中,可以包含任务定义和示例的样本。这些重复的样本帮助模型学习任务的名称和示例。在这里,任务的名称或任务描述是将英语翻译成法语。然后,我们看到这样的示例,例如海獺 -> loutre de mer。当你向 GPT-3 提供任务名称以及一些样本时,它便能够做出相当不错的响应。

我们称之为少-shot 学习。这是因为我们为模型提供了少量示例,显然比一个示例多,但又少于完整的数据集。我在这里使用“学习”这个词有些困难,因为从技术上讲,模型的权重和参数并没有更新。模型并没有发生变化,因此可以说我们甚至不应该使用“学习”这个词。另一方面,提前提供这些示例作为输入显著提升了模型的表现,因此从输出的角度来看,或许我们可以使用“学习”这个词。无论如何,这已是标准的术语。

一个类似的例子是零-shot 学习,在这种情况下,我们不给模型提供任何完成任务的示例,而是希望它能够表现良好。这种方法非常适合开放领域的问答任务,比如 ChatGPT。然而,正如许多人发现的那样,一个在零-shot 学习场景中表现良好的模型,也可以在少-shot 甚至单-shot 示例中表现得很好。所有这些技术对于理解大型模型都非常有用。

正如我们在图 13.1中看到的,这种学习方法的自然比较是微调。在微调方法中,正如我们在第十章中学到的,我们使用预训练的模型作为基础,并使用更大的数据集样本对其进行再训练。通常,这个数据集样本是有监督的,但在必要时也可以使用无监督的微调。在语言场景中,这种监督可能是分类、问答或摘要。在视觉领域,你可能会看到新的图像和文本对,涵盖了各种应用场景:时尚、电商、图像设计、营销、媒体娱乐、制造业、产品设计等等。

最常见的进展通常包括以下几个步骤:

  1. 首先,尝试在你的模型上进行零-shot 学习。它能在每个用例和边缘场景下完美运行吗?很可能,它在一些非常狭窄的场景下能工作得很好,但在其他场景下可能需要一些帮助。

  2. 接下来,尝试单-shot 和少-shot 学习。

如果你提供一些你期望的示例,模型能否理解并给出合适的响应?它是否能按照你提供的提示做出好的反应?如果这些都不行,可以尝试微调。去收集一个更具体的、与你想要增强模型的应用场景相关的数据集并进行训练。有趣的是,微调在仅涉及语言的场景中似乎更加成功。在视觉领域,微调很容易导致模型过拟合或陷入灾难性遗忘,即模型失去了保持基础数据集中的图像和物体的能力。你可能更适合探索图像到图像的方式,下面会进一步讲解。

现在,让我们学习一些关于视觉和语言的最佳提示工程实践。

文本到图像的提示工程技巧

正如我们之前在书中提到的,Stable Diffusion 是一个很棒的模型,你可以通过自然语言与其互动并生成新图像。Stable Diffusion 基于模型的美妙、趣味和简单性在于,你可以在设计提示时尽情发挥创意。在这个例子中,我为一件艺术作品编造了一个挑衅性的标题。我要求模型想象一下,如果这幅图像是由安塞尔·亚当斯(Ansel Adams)创作的,会是什么样子。安塞尔·亚当斯是 20 世纪中期著名的美国摄影师,以其黑白自然风光摄影而闻名。以下是完整的提示:“关闭即是开放,安塞尔·亚当斯,高分辨率,黑白,获奖。指导(20)*”。让我们仔细看看。

图 13.2 – 由 Stable Diffusion 生成的图像

图 13.2 – 由 Stable Diffusion 生成的图像

在以下列表中,你会找到一些有助于提升你 Stable Diffusion 结果的提示:

  • 在你的提示中添加以下词汇获奖、高清晰度、在<你喜欢的网站>上流行、以<你喜欢的艺术家>的风格、400 高 dpi,等等。网上有成千上万的优秀照片和它们的相应提示;一个很好的网站是 lexica.art。以有效的方法为起点总是一个不错的选择。如果你对视觉充满热情,你可以轻松地花费几个小时只是在浏览这些示例并找到好的案例。为了更快速的方式,同一个网站允许你以关键词作为提示进行搜索并渲染图像。这是开始提示模型的快捷方式。

  • 添加负面提示:Stable Diffusion 提供了负面提示选项,允许你向模型提供它明确不使用的词语。常见的负面提示包括:手、人类、过度饱和、绘制不佳、畸形等。

  • 图像放大:虽然大多数使用 Stable Diffusion 的提示生成的图像较小,比如 512x512 的大小,但你可以使用另一种技巧,称为图像放大,将同一图像渲染成更大、更高质量的图像,大小可以是 1,024x1,024 或更大。图像放大是你可以用来获得今天最佳质量 Stable Diffusion 模型的一个重要步骤,无论是在 SageMaker (2) 上,还是通过 Hugging Face 直接使用 (3)。我们将在接下来的图像到图像部分进一步探讨这一点。

  • 精准度与细节:当你向 Stable Diffusion 提供更长的提示词时,例如在提示中加入更多术语并详细描述你想要它生成的物体类型和风格,实际上会提高响应效果的几率。要小心你在提示中使用的词汇。正如我们在第十一章关于偏见的部分学到的,大多数大型模型都是基于互联网上的数据进行训练的。对于 Stable Diffusion 来说,无论是好是坏,这意味着你要使用网络上常见的语言。这也意味着标点符号和大小写并不是那么重要,你可以非常创造性和自发地描述你想要看到的内容。

  • 顺序:有趣的是,单词的顺序在给 Stable Diffusion 下达提示时非常重要。如果你想让提示中的某部分更具冲击力,比如黑暗美丽,可以把它放在提示词的前面。如果它太强烈了,可以把它移到后面。

  • 超参数:这些在纯语言模型中也有关系,但我们来特别提一下几个对 Stable Diffusion 尤为重要的超参数。

Stable Diffusion 提示工程的关键超参数

1. guidance=20 在第二张图像中,模型捕捉到了亚当斯作品中明显的对比和阴影渐变。此外,我们得到了一个新的风格,几乎像 M.C. 艾舍尔(M.C. Escher),树木似乎变成了地板。

2. 种子:这指的是一个整数,你可以设置它作为扩散过程的基准。设置种子对模型响应有很大影响。特别是如果我的提示词不太好,我喜欢从种子超参数开始,尝试几次随机启动。种子影响图像的高层属性,如风格、物体大小和颜色。如果你的提示词足够强大,你可能不需要在这里做大量实验,但它是一个不错的起点。

3. 宽度和高度:这些非常直接;它们只是输出图像的像素尺寸!你可以通过它们来改变结果的范围,从而影响模型生成的图片类型。如果你想要一张完全方形的图像,使用 512x512。如果你想要竖版方向,使用 512x768。如果是横版方向,使用 768x512。记住,你可以使用稍后我们会学习的放大过程来提高图像的分辨率,因此最好先从较小的尺寸开始。

4. steps 设置为 50。增加这个数字也会增加处理时间。为了得到很好的结果,个人来说,我喜欢根据 guidance 的值来调整这个数字。如果你计划使用非常高的 guidance 值(大约 16),比如在一个强力提示下,那么我不建议将推理步骤设置为超过 50。这看起来会出现过拟合,结果会很差。不过,如果你的 guidance 值较低,接近 8,那么增加步骤数量可能会得到更好的结果。

对于 Stable Diffusion 和其他文本到图像的扩散模型,还有许多其他的超参数可以探索。现在,让我们来探讨一下图像到图像的技术!

图像到图像提示工程技巧

在生成性 AI 中,尤其是在提示模型时,图像到图像 是一个引人入胜的趋势。这涵盖了一系列广泛的技术,允许你在调用模型时带入一张图像。然后,模型的响应将把你的源图像整合到响应中,让你更具体地确定模型提供的响应。这对于提高图像分辨率、添加遮罩,甚至引入物体以无缝地格式化到输出图像中的任何背景都非常有帮助。

这些核心能力是通过一种在 2022 年初提出的技术实现的 (4),称为随机微分方程编辑SDEdit),它利用随机微分方程使得图像合成和编辑变得更加容易。虽然听起来有点吓人,但实际上它非常直观。它允许你将源图像添加到预训练的扩散模型中,并使用该基础图像作为灵感来源。怎么做呢?通过以多种方式反复添加和去除噪声,直到最终结果符合你的偏好标准。SDEdit 在真实性上比其前身——基于 GAN 的方法提高了多达 98%,在人类满意度评分上提高了 91%。

让我们探索一下,在使用扩散模型进行提示时,如何利用这一增强的图像到图像技术!

放大

如前所述,这是一种简单且快速的提高图像分辨率的方法。在提示模型时,你可以增强低分辨率的图像,并结合其他参数来提高质量。使用 SageMaker JumpStart (5),你可以直接使用内置的选项,此外,通过 Hugging Face,你还可以使用完整的放大流程。(6) 这还可以接受除了源图像之外的其他文本提示。

遮罩

提示扩散模型时,另一个有趣的技术是遮罩。遮罩就是一组像素,覆盖在照片中的某个区域:山脉、汽车、人类、狗或图像中的任何其他物体。如何找到像素图呢?现在,老实说,一个简单的方法可能是从 Meta 的新任何物体分割模型SAMSAM)* 开始。(7) 你可以上传一张图像,并让模型生成该图像中任何物体的像素图。

一旦你有了一个遮罩,你可以将其发送到 Stable Diffusion 图像中,在遮罩区域生成一张新图像。经典的例子是改变人们所穿衣服的风格。你可以使用 SAM 或开源的 CV 工具提取照片中衣服的区域,渲染遮罩,然后将遮罩发送给 Stable Diffusion。它将生成一张新图像,将原始图像与新生成的元素结合起来,填充遮罩区域。

如果你想看一个简单又完整的端到端示例,可以看看我刚在 GitHub 上找到的一个!(8)

使用 DreamBooth 进行物体到图像的提示

与我们在前面几节中看到的其他方法不同,DreamBooth (9) 并不使用底层的 SDEdit 方法。相反,它使用一组输入图像,并通过结合文本指导的微调过程,将来自所有输入图像的源物体放置到模型生成的目标场景中。该技术使用了两个损失函数,一个用于保留预训练模型已经学到的先前类别,另一个用于将新物体重建到最终图像中。

这意味着可以说,它并不是一种提示技术;它更接近于一种微调技术。然而,我将它包括在这里,因为我觉得它的意图更类似于遮蔽(masking),而不是创建一个全新的模型,但实际上它的结果就是如此。我们来更仔细地看看 DreamBooth 的损失函数。

图 13.3 - DreamBooth 损失函数

图 13.3 - DreamBooth 保留先前信息的损失函数

DreamBooth 是一个很棒的开源解决方案,你可以用它将你喜欢的任何物体放置到你选择的任何背景中!接下来,我们来学习一些你可以用来改善语言模型提示的技巧。

提示大型语言模型

我之前说过:我非常喜欢并大力支持 Hugging Face。我从他们那里学到了很多关于自然语言处理NLP)的知识,因此如果不提到他们的书作为一个关于提示工程技巧和技术的极佳资源,我就不对得起自己了。(10) 其中大多数做法围绕着为你的模型选择合适的超参数展开,每种类型的模型都会提供稍有不同的结果。

然而,我认为 ChatGPT 的崛起几乎完全改变了这一点。在今天的世界里,OpenAI 模型的极高准确度提高了所有 NLP 开发者的标准,迫使我们交付相似的结果。无论好坏,都无法回头。让我们尝试理解如何提示我们的大型语言模型LLMs)!我们将从指令微调开始。

指令微调

首先,理解一个经过指令微调的模型和一个未经过微调的模型之间的区别是非常有帮助的。正如我们在第十章关于微调的内容中所学到的,指令微调是指一种监督式的微调步骤,它使用模型提供的指令,例如“告诉我含羞草和三角饺的区别”,并将这些指令与答案配对,如“含羞草是一种含有香槟和橙汁的酒精饮料,而三角饺则是一种印度酥皮点心,里面填充有蔬菜或肉类,通常还有土豆馅料。”模型随后会明确学习如何遵循指令。

这对提示 LLM 非常重要,因为它会完全改变你的提示风格。如果你正在使用一个已经经过指令微调的 LLM,你可以直接进入零-shot 性能,并立即让它无缝地为你执行任务。如果没有,你可能需要在提示中添加一些示例,也就是少量示例学习,以鼓励它按照你希望的方式做出回应。

一旦你弄清楚了这个关键区别,花时间尝试你选择的模型也是有帮助的。它们有细微的差别;有些模型需要不同的符号和分隔符,而其他的则对关键字和短语反应较好。你需要了解并测试你的 LLM,而提示工程是一个很好的方法。另一个值得学习的风格是思维链提示

思维链提示

即使你正在使用一个在零-shot 情况下表现良好的模型,比如一个已经接受了指令微调的模型,正如我们之前讨论的,你仍然可能会遇到一些需要在提示中添加示例以获得期望输出的使用场景。思维链提示就是一个很好的例子。思维链提示指的是提示模型展示它是如何 得出答案的。这在解释性至关重要的场景中极为有价值,例如解释 LLM 为什么做出风格更新或分类决策。举个例子,假设你正在法律场景中使用 LLM,并且你希望 LLM 更新法律文件中的语言。当你这样提示它时,模型不仅仅是提供答案,而是可以一步步解释它是如何得出某个结论的。这种逻辑清晰性有助于大多数用户对系统更有信任,帮助他们理解并相信模型提出的建议是有效的。

它在很多情况下也有助于提高准确性!这是因为大多数大语言模型(LLMs)本质上是自回归的;它们非常擅长预测在给定字符串中下一个最可能出现的词。当你引导它们进入一连串的思维时,你实际上是在推动它们按一步步的思路生成,从而使它们更接近真实情况。让我们通过以下原始论文中的图示来更直观地理解这一点。(11)

图 13.4 – 思维链提示

图 13.4 – 思维链提示

如你所见,在左侧,我们仍然在进行一些少量学习,但提示中的答案很简单。它仅仅回答问题,完结。可是,在右侧,我们通过提供一个重新表述问题的答案来提示模型。现在,答案开始于重新生成问题中提供的信息的快速摘要,然后进行一次逻辑跳跃,输出正确答案。你可以看到,左侧的模型没有正确回答,而右侧的模型是正确的。实际上,模型本身是一样的,唯一的区别是提示。

对于经过指令微调的模型,你还可以通过一个像“逐步指导我如何...”这样的语句来触发连锁思维表现。

摘要

这可能是我今天看到的最常见的 LLM 应用场景:总结电话记录、文档等。使用顶级 LLM,摘要现在变得非常容易。只需根据模型的上下文长度,将尽可能多的文档粘贴到 LLM 中,并在提示的底部添加Summarize:。一些模型可能有所不同;你也可以添加TL;DRin summary:或其他类似的变体。它们会完美地工作吗?当然不行。它们会抓住所有内容吗?绝对不可能。它们偶尔会产生幻觉吗?毫无疑问。我们该如何减轻这个问题?微调、大规模验证、实体识别和审计。

防御提示注入和越狱

在提示模型时需要考虑的一种技巧是它对越狱的敏感程度。正如我们在第十一章中学到的关于检测和缓解偏见的内容,越狱是指恶意用户诱导模型执行有害行为。这可能就像是要求模型讲一些关于某些群体的粗鲁笑话,要求它提供盗窃的指导,或者询问它对某些政治家或社会群体的看法。在每个 LLM 应用中,至少会有一些用户尝试越狱,看看是否能诱使模型做出不当行为。一个类似的方法是提示注入,用户可以恶意欺骗模型,让它输出来自数据集、提示集或任何其他指令列表中的 IP。

如何防御这一点?一种方法是通过有监督的微调。Anthropic 维护了一个大型的红队数据集,可以在 Hugging Face 上找到,链接在这里。(12) 请小心使用;这个数据集中的词汇非常直白,可能会让一些读者感到不适。就个人而言,我甚至觉得很难研究这个数据集中的几行内容。作为一种有监督的微调技术,或者正如 Anthropic 所建议的,作为一种带有人工反馈的强化学习技术,你可以对模型进行微调,以拒绝任何看起来恶意或有害的内容。

除此之外,你还可以为应用程序增加分类器来处理输入数据。这意味着,当你的应用接收到来自用户的新问题时,你可以轻松地增加额外的机器学习模型来检测这些问题中的恶意或异常行为,并绕过回答。这使你能更好地控制应用的响应方式。

现在我们已经学习了一些提示 LLM 的基本技巧,让我们看看一些更高级的技巧!

高级技巧 – 前缀与提示调优

你可能在想,难道没有一种更精巧的方式,通过优化技术找到正确的提示,而不需要更新模型参数吗?答案是肯定的,确实有许多方法可以实现这一点。首先,让我们试着理解前缀调优

前缀调优

这一技术由一对斯坦福研究人员在 2021 年提出,专门用于文本生成。正如你在他们论文中的下图所看到的,核心思想是,与其为每个下游任务生成一个全新的模型,不如创建一个简单的向量来表示每个任务,这个向量被称为前缀,且该方法消耗的资源较少。

图 13.5 – 前缀调优

图 13.5 – 前缀调优

这里的核心思想是,不是为每个下游任务微调整个预训练的变换器,而是尝试只更新该任务的一个单一向量。这样,我们就不需要存储所有的模型权重;我们只需要存储那个向量!

可以说,这一技术与我们在第十章**中简要提到的有些相似,即微调与评估*。这项技术向 LLM 注入可训练的权重,让我们只学习新的参数,而不是更新整个模型本身。我觉得前缀调优很有趣,因为我们根本没有触及模型架构;我们只是从一开始就学习这个基本对象。

为什么你应该了解这个?因为正如斯坦福团队所展示的,这种方法只使用了完整模型的 0.1%参数,却能提供与微调整个模型相媲美的性能。

如何开始前缀调优?使用我们 Hugging Face 的朋友们提供的新库!他们正在构建一个开源库,让各种参数高效的微调在这里变得可用:github.com/huggingface/peft。前缀调优肯定是可用的。

幸运的是,来自无可比拟的 Phill Schmid 的通用 PEFT 示例,在这里似乎非常易于访问。(14) 通过一些专门的数据预处理和自定义模型配置,你也可以将其添加到你的脚本中。

现在,让我们来看看提示调优。

提示调优

正如我们所见,找到合适的提示是相当具有挑战性的。通常,这些提示基于人类自然语言中的离散单词,可能需要相当多的手动迭代才能欺骗模型提供预期的答案。在谷歌 2021 年 ACL 论文中((15))引入这一概念时,他们提出了可以通过反向传播学习的“软提示”。幸运的是,这种方法包含了来自任何数量标记示例的信号,从而简化了之前提出的前缀调优方法。

通过提示调优,我们冻结整个预训练模型,但允许为每个下游任务向输入文本添加额外的k可调令牌。这些令牌被视为软令牌,或者是模型学习到的信号,用于识别每个下游任务。你可以在他们论文中的图示中看到这一点。

图 13.6 – 提示调优

图 13.6 – 提示调优

类似于前缀调优,通过提示调优,我们仍然冻结基础模型的权重。我们同样还会向输入数据集中添加一些新的、可学习的项,并与各种下游任务数据样本混合。关键的区别在于,与学习完整模块不同,我们学习新的、机器可读的令牌。这意味着这些令牌本身应在梯度更新后发生变化,标志着模型识别出这基本上是该类型下游任务的触发信号。如果你正在处理参数高效微调不可行的场景,例如模型完全对你隐藏的情况,那么前缀调优或提示调优可能是一个不错的探索选项。这两种技术都可以在相关的 Hugging Face 库中找到,peft

现在,让我们通过快速总结来结束本章。

总结

在本章中,我们介绍了提示工程的概念。我将其定义为在不更新模型权重的情况下,从模型中榨取准确性提升的所有方法。换句话说,这就是以更少的投入获取更多成果的艺术。我们介绍了少样本学习,其中你向模型提供几个期望推理结果的示例,零样本学习则是你希望模型在没有任何先前信息的情况下给出回应。毋庸置疑,消费者通常更喜欢零样本学习。我们讨论了一些针对文本到图像模型的提示技巧,特别是如何从开源的 Stable Diffusion 中获得良好的表现。我们了解了图像到图像的提示方法,通过向基于扩散的模型传递图像,从而利用交集生成新图像。我们还了解了提示大语言模型(LLM),包括指令微调、思维链提示、摘要生成、防止提示注入和越狱的影响。最后,我们介绍了一些高级技巧,包括提示和前缀调优。

现在,让我们开始阅读 第十四章,内容是关于视觉和 LLM 的 MLOps!

参考文献

请查看以下内容,了解本章节涵盖的一些主题的更多信息:

  1. Language Models are Few-Shot Learners:arxiv.org/pdf/2005.14165.pdf

  2. 使用稳定扩散在 Amazon SageMaker JumpStart 中提升图像质量:aws.amazon.com/blogs/machine-learning/upscale-images-with-stable-diffusion-in-amazon-sagemaker-jumpstart/

  3. stabilityai/stable-diffusion-x4-upscaler Copied:huggingface.co/stabilityai/stable-diffusion-x4-upscaler

  4. SDEDIT:使用随机微分方程进行引导图像合成和编辑:arxiv.org/pdf/2108.01073.pdf

  5. 使用稳定扩散在 Amazon SageMaker JumpStart 中提升图像质量:aws.amazon.com/blogs/machine-learning/upscale-images-with-stable-diffusion-in-amazon-sagemaker-jumpstart/

  6. Hugging Face:huggingface.co/stabilityai/stable-diffusion-x4-upscaler

  7. Segment Anything:arxiv.org/pdf/2304.02643.pdf

  8. amrrs/stable-diffusion-prompt-inpainting:github.com/amrrs/stable-diffusion-prompt-inpainting/blob/main/Prompt_based_Image_In_Painting_powered_by_ClipSeg.ipynb

  9. DreamBooth:Fine Tuning Text-to-Image Diffusion Models for Subject-Driven Generation:arxiv.org/pdf/2208.12242.pdf

  10. nlp-with-transformers/website:github.com/nlp-with-transformers/website

  11. Chain-of-Thought Prompting Elicits Reasoning in Large Language Models:arxiv.org/pdf/2201.11903.pdf

  12. Hugging Face:huggingface.co/datasets/Anthropic/hh-rlhf

  13. Prefix-Tuning:优化连续提示以进行生成:arxiv.org/pdf/2101.00190.pdf

  14. huggingface/notebooks:github.com/huggingface/notebooks/blob/main/sagemaker/24_train_bloom_peft_lora/scripts/run_clm.py

  15. The Power of Scale for Parameter-Efficient Prompt Tuning:aclanthology.org/2021.emnlp-main.243.pdf

  16. arxiv.org/pdf/1902.00751.pdhttps://arxiv.org/pdf/1902.00751.pd

第十四章:MLOps 在视觉和语言中的应用

本章将介绍机器学习操作与协调的核心概念,也称为 MLOps。这包括构建管道、持续集成与部署、环境间的推广等内容。我们将探讨如何监控模型预测并进行人工干预审计。我们还将寻找独特的方式,以支持在 MLOps 管道中使用大型视觉和语言模型。

本章将涵盖以下主题:

  • 什么是 MLOps?

  • 持续集成与持续部署

  • 模型监控与人工干预

  • 基础模型的 MLOps

  • AWS 提供的 MLOps 服务

什么是 MLOps?

本书中我们已经涵盖了如此庞大的内容,几乎令人难以想象。从预训练的绝对基础开始,我们一步步深入探讨了用例、数据集、模型、GPU 优化、分布式基础、优化、超参数、与 SageMaker 的配合、微调、偏差检测与缓解、托管模型及提示工程等内容。现在,我们将进入将所有内容 结合在一起的艺术与科学。

MLOps代表机器学习操作。广义来说,它包括一整套技术、人员和流程,供您的组织采纳,以简化机器学习工作流。在前几章中,您学习了如何构建 RESTful API 来托管模型,并且获得了改进提示工程的技巧。在这里,我们将重点讨论构建部署工作流,以将该模型集成到您的应用程序中。

就个人而言,我认为 MLOps 中的管道(pipeline)部分最为关键。管道是一个由多个步骤组成的流程,用于协调机器学习工作流。这可以包括自动重新训练模型、超参数调整、审计与监控、应用测试与集成、推广到更安全的环境、漂移与偏差检测,以及对抗性强化等内容。

图 14.1 – 机器学习操作的管道

图 14.1 – 机器学习操作的管道

管道是您可以使用多种软件工具构建的工具。如果您使用的是 SageMaker 本地工具,并且还没有一个协调栈,您可以从查看SageMaker 管道开始。或者,如果您已经在使用某个协调栈,例如 AirFlow、KubeFlow、Ray、MLFlow 或 StepFunctions,您也可以继续使用它们,并简单地调用 SageMaker API 来处理您的机器学习工作流。

流水线的核心组件是步骤。一个步骤可能是数据预处理模型训练模型评估人工审核模型部署等。一个基本的流水线将通过你定义的多个步骤。流水线通常以触发器开始,触发器是某个事件,它将通知系统引入流水线。你的触发器可能是上传到 S3、提交到代码库、某个时间点、数据集更新或客户事件。通常,你会看到一个触发器启动整个流水线,在前一步骤完成后启动每个后续步骤。

让我们继续讨论常见的 MLOps 流水线。

常见的 MLOps 流水线

让我们来看几个在机器学习中常见的流水线:

  • 模型部署流水线:在这里,核心任务是指向你的预训练模型工件,特别是推理脚本和模型本身,并将这些内容放入你选择的任何部署选项中。你可能会使用SageMaker 实时端点进行产品推荐,或者使用异步端点来托管大型语言模型。你可能通过多容器端点使用不同的镜像,甚至通过多模型端点使用不同的模型。无论如何,最基本的流水线步骤可能如下所示:

    1. 更新模型工件。

    2. 创建一个新端点。

    3. 测试端点。

    4. 如果测试成功,将生产流量指向该端点。如果测试失败,通知开发团队。

  • 模型再训练流水线:模型再训练流水线适用于那些需要定期再训练模型的使用场景。每次有新数据时都需要再训练,可能是每隔几小时,或者每个月一次。对于像重新运行报告或笔记本这样的简单场景,你可以使用 SageMaker 的notebook job功能(自 2022 年 12 月推出)按计划运行笔记本。然而,如果你希望基于更新的数据触发此再训练,则流水线将非常有用。或者,如果模型或数据集很大并且需要分布式训练,流水线将是一个理想的选择。你的流水线步骤可能如下所示:

    1. 上传新数据。

    2. 运行预处理。

    3. 训练模型。

    4. 调整模型。

    5. 触发部署流水线。

  • 环境推广流水线:某些客户,特别是那些在安全敏感环境中工作的客户(例如高度监管的行业),要求通过越来越安全的环境来升级应用程序。在这里,环境一词指的是一个隔离的计算边界,通常是一个全新的 AWS 账户,或者更简单地说,是一个不同的区域。此流水线的步骤可能如下所示:

    1. 从开发账户中的数据科学家触发流水线。

    2. 将资源提升到测试账户。

    3. 测试端点。

    4. 如果端点通过测试,将其提升到生产账户。如果端点未通过测试,通知数据科学家。

    5. 在生产账户中,创建端点。

    6. 将生产流量设置到端点。

正如你无疑注意到的那样,每个管道都可以相互交互。它们可以作为独立步骤触发彼此,与其他组件交互,并持续添加价值。它们的基本组件也是可互换的 – 你可以轻松替换一些步骤,定义你需要的整体系统。

支撑其中大部分概念的一个概念是微服务。你可以把每个管道都视为一个微服务,从某些输入开始并生成输出。为了最大化跨团队的价值,你可以构建和维护每个步骤或整个管道的基本模板,以便未来的团队更容易使用它们。

正如我们在第十二章中学到的那样,如何部署你的模型,你可以使用很多技术来改进你的模型以进行部署。这包括量化和压缩、偏差检测和对抗性硬化 (1)。个人而言,我倾向于看到许多方法在模型上执行得很少,比如当它首次从研发团队移交到部署团队时。对于定期的重新训练,我会避免过度的计算资源,假设模型的大部分基本更新已在更近期的版本中工作。

持续集成和持续部署

在机器学习中,我们倾向于看两种略有不同的堆栈。一方面,你有模型创建和部署过程。这包括你的模型工件、数据集、指标和目标部署选项。正如我们之前讨论的那样,你可能创建一个管道来自动化这个过程。另一方面,你有真正的软件应用程序,你想要暴露你的模型。这可能是一个视觉搜索移动应用程序、问答聊天、图像生成服务、价格预测仪表板,或者真正使用数据和自动化决策来改进的任何其他过程。

许多软件堆栈使用他们自己的持续集成和持续部署CI/CD)管道,无缝连接应用程序的所有部分。这可以包括集成测试、单元测试、安全扫描和机器学习测试。集成是指将应用程序组合在一起,而部署则是指采取步骤将应用程序投入生产环境。

我们之前看过的许多管道可能被认为是 CD 管道,特别是当它们涉及更新生产中的服务时。持续集成管道可能包括指向应用程序的步骤,测试各种响应,并确保模型作出适当的响应。让我们仔细看看。

图 14.2 – 机器学习的 CI/CD 选项

图 14.2 – 机器学习的 CI/CD 选项

我在这里想表达的是,你有许多选项可以设置你的管道。对于一个大规模的基础模型,比如你自己的预训练大语言模型或文本到视觉模型,你可能会拥有由不同团队为拼图的不同部分开发的极其强大的多个代码库。将这些代码库整合在一起,使用它们的片段相互支持,并通过强大的单元测试尽可能地自动化,以确保整体的最高性能是符合你最佳利益的。与模型开发分开,你可能还会有一个部署管道,能够检查所有必要条件,为模型准备好实时流量并成功地与客户端应用进行通信。

既然我们已经讨论了一些关于一般运营的基础话题,那么让我们仔细看看与机器学习特别相关的两个关键方面——模型监控和人工介入。

模型监控和人工介入

第十一章中,我们探讨了关于偏见检测、缓解和监控的大型视觉与语言模型的相关话题。这些内容主要集中在评估模型的背景下。现在,我们已经进入了关于模型部署的部分,重点是运营,我们来更仔细地看看模型监控。

一旦你将模型部署到任何应用中,能够查看该模型随时间变化的表现就变得极其有用。这对于我们之前讨论的任何用例都是如此——聊天、通用搜索、预测、图像生成、推荐、分类、问答等等。所有这些应用都从能够看到你的模型随时间变化的趋势并提供相关警报中受益。

例如,假设你有一个价格预测模型,它根据经济状况为某个特定产品建议价格。你在某些经济条件下训练模型,也许是 1 月的经济条件,并在 2 月部署了该模型。在部署期间,模型继续关注那些相同的条件并帮助定价。然而,你可能没有意识到,3 月时整个市场状况发生了变化。我们的世界变化如此迅速,以至于整个行业可能已经发生了颠覆。你的模型进入世界时认为一切看起来和训练时完全一样。除非你重新校准模型,否则它不会意识到情况已经不同。

但是,您该如何知道何时重新校准模型呢?通过模型监控!使用 Amazon SageMaker,包括我们完全托管的模型监控功能,您可以轻松运行测试,学习训练数据的汇总统计信息。然后,您可以安排作业将这些汇总与传入端点的数据进行比较。这意味着,随着新数据与您的模型互动,您可以将所有这些请求存储在 S3 中。请求存储之后,您可以使用模型监控服务安排作业,将这些推理请求与您的训练数据进行对比。这很有用,因为您可以利用它向自己发送警报,了解模型在推理上的趋势,尤其是在您需要触发重新训练作业时。模型监控的基本概念同样适用于视觉和语言;唯一的问题是如何生成汇总统计信息。

那么,模型监控与人为参与有何关系呢?因为您还可以使用来自托管模型的触发器来触发人工审核。如下面的图所示,您可以引入一些软件检查,以确认模型输出的内容是否大致符合您的预期。如果不符合,您可以触发人工审核。这使用了 SageMaker 的另一个选项——增强型人工智能A2I),而这个功能又依赖于 SageMaker Ground Truth。换句话说,如果模型没有按预期工作,您可以将预测请求和响应发送给团队进行人工审核。这有助于您的团队对整体解决方案建立更多信任,更不用说提升您的数据集以便为模型的下一次迭代做准备了!让我们直观地看一下这个过程。

图 14.3 – 带有人类参与的模型监控

图 14.3 – 带有人类参与的模型监控

在前面的图中,您可以看到各种组件或微服务,您可以将它们组合起来,提供一个完整的管道,同时进行模型监控并保持人为参与。首先,您的客户端应用可以与一个 Lambda 函数进行交互,而该函数又会调用一个 SageMaker 模型。您可以通过自己在 Lambda 中编写代码,将模型请求和响应存储在 S3 存储桶中,或者您也可以设置 SageMaker 端点来为您完成此操作。一旦您将记录存储在 S3 中,就可以运行模型监控作业。这可以利用 SageMaker 的功能——模型监控,来学习训练数据与推理数据之间的统计差异,并在这些差异超出大范围时向您发送警报。或者,您也可以编写自己的对比脚本,并在 SageMaker 的训练或处理作业中运行这些任务。

一旦你对模型的整体响应情况有了一定的了解,接下来的最佳策略是尽可能地融入人工反馈。在生成领域尤其如此,在这里,内容的准确性、风格和语气是大多数组织的首要标准。一个很好的选择是SageMaker Ground Truth!正如我们在第二章中学习的数据准备部分所述,这是一个完全托管的服务,你可以用它来增加标注数据集,并实时增强模型响应。

这里的类似方法是使用多个模型来确认预测结果。试想你快速处理了一份文档,并希望准确提取其中的内容。你的客户将 PDF 文件上传到你的网站,你通过机器学习模型解析它,并希望确认或否定某个字段的内容。增加利益相关者对系统准确性的信心的一种方式就是使用不止一个模型。也许你使用的是自己的模型,一个托管在 SageMaker 中的定制深度学习模型,同时,你也可以指向一个完全托管的 AWS 服务,如 Textract,它可以从视觉表单中提取数字化自然语言。然后,你可能还会有一个 Lambda 函数来查看两个模型是否对结果一致。如果一致,那么你可以直接回复客户!如果不一致,则可以将请求路由到人工审核。

监控模型的方法有无数种,其中包括将这些方法与人类结合的方式!不过,现在让我们继续探讨与视觉和语言相关的 MLOps 组件。

基础模型的 MLOps

现在,你已经对 MLOps 有了一个清晰的了解,并且掌握了一些关于如何使用“人工在环”和模型监控的思路,接下来让我们从 MLOps 的角度具体探讨视觉和语言模型中哪些方面值得我们关注。

这个问题的答案并不那么显而易见,因为从某个角度来看,视觉和语言只是机器学习和人工智能的略微不同的方面。一旦你配置好了合适的包、图像、数据集、访问权限、治理和安全性,其他部分应该会自然而然地流畅进行。然而,达到这一点的过程却是一场艰难的斗争!

构建一个大型语言模型的管道并非易事。正如我之前提到的,我认为这其中至少涉及两个非常不同的方面。从其中的一方面来看,你需要关注整个模型开发生命周期。正如我们在本书中所学到的,这涉及到大量的开发工作。从数据集、模型和脚本准备到训练和评估循环,再到性能和超参数优化,有无数种技术需要追踪,以便构建你的基础模型。

一旦你拥有了基础模型,为开发做准备就变成了一个不同的问题。正如我们之前讨论的,对抗性强化包括了一系列技术,你可以用它们来提升模型在目标领域中的表现。从第十章中学到的微调和评估,第十一章中的偏差检测与缓解,以及第十二章中的部署技术,都可以直接应用到这里。对我来说,将这些内容放在一个专注于部署的不同流程中似乎很自然。让我们通过下图来看看这些内容。

图 14.4 – LLM 开发与部署流程

图 14.4 – LLM 开发与部署流程

使这件事变得更加复杂的是,这些不同的步骤中有许多使用了相似的软件包和函数。这意味着,要实现每一个步骤,你可能需要指向至少一个,甚至可能是几个 git 仓库和软件包。当你将这些步骤解耦,使用不同的容器、资源和步骤来管理每个部分时,这有助于每个团队独立工作。我们都知道,基础模型的开发速度在未来几年只会加快,因此可以预见的是,每一个步骤都会需要你定期暂停,捕捉最新的开源脚本或研究技术,进行开发和测试,并将它们重新集成到更大的流程中。

现在,让我们学习一下视觉领域的 MLOps。

视觉领域的 MLOps

视觉基础模型与我们之前为语言模型提出的建议相比如何?在某种程度上,差别不大。你依然是在处理图像、脚本、软件包、数据集和模型质量。你仍然希望保持模型的最新状态,并且尽可能多地融入人类反馈。正如我们在本书中迄今所看到的,模型和评估指标会有所不同,数据集也会大不相同,任务也并非完全相同。然而,许多基本的逻辑仍然是通用的。不过,值得提醒的是——在语言领域的微调与视觉领域的微调是完全不同的。

关于视觉领域的过拟合和呼吁常识的警告

请记住,视觉比语言更容易受到过拟合的影响。为了理解这一点,我们可以考虑这两种模式之间的根本区别。语言本质上是离散的;我们通过字母和单词来表达整个世界,而这些项本身就是非连续的。你可以说,语言的整个模式等同于世界上所有语言词典的总和,词典本身只是人类不断使用、发展和表达的词语的近似。词语的排列、它们的解释以及在广泛的人类生活经验中的意义是无穷无尽的。

视觉完全不同。该模式本身是连续的;尽管像素本身当然是有起止的,但图像中物体之间的界定几乎是主观的。我们使用指标来量化标记物体之间的质量和差异,比如交集与并集比。物体会旋转;在不同的光照和背景下,它们似乎完全变化。即使是完全不同类型的物体,例如动物与杯子、路标与衣物、家具与自然景观,它们的模式可能看起来也非常相似。虽然视觉和语言都在进入模型时被分解成嵌入,但神经网络在捕捉内容的意义并将其推断到其他环境中的能力,似乎在语言和视觉中是非常不同的。语言微调在许多情况下效果很好,而视觉微调通常在初期表现较差。

就个人而言,我觉得另一种机器学习技术非常有趣,它在本质上似乎是这些结合模式的核心——常识推理。机器常识指的是确保概念、物体以及这些物体的定义特征之间的逻辑一致性。大多数人擅长这一点,比如知道水是湿的,重物被丢到空中会下落,火会产生热量,等等。

然而,计算机在这方面做得非常糟糕。它们似乎根本无法理解物理维度的存在;当然,生物学层面对它们来说完全是个异常。图像生成器不了解食物必须进入嘴巴才能算作进食。图像分类器常常把斑马与家具混淆。语言模型不理解人类沟通的节奏,偶尔让使用者感到不堪重负。电影生成器经常让人反感多于愉悦,因为它们无法识别婴儿首先掌握的基本辨别能力——人类及其动作。对于人类来说,杯子和动物都是物体,可能偶尔还会有一些相似的风格特征,但在物理世界里,它们分别来自完全不同的领域。对计算机而言,似乎这个物理维度根本不存在。它们实际上只是在学习你提供的二维图像中存在的内容。这就是我们一开始使用标签的原因——通过将物理世界转化为像素,赋予模型一定的意义。

我有幸在去年与叶津·崔(2)见面并进行了简短的交流。她在世界顶尖的自然语言处理会议之一——计算语言学协会年会上发表了主题演讲,讲述了一个引人入胜的假设性预测,关于未来 60 年自然语言研究的走向。我被她对人文学科、哲学以及深层科学发现的热情深深打动。她在一个极少有人关注机器常识的时代开始了这方面的探索,事实上,她今天开玩笑说,当时她还遭到积极反对,因为大家都认为在这个话题上发表文章几乎是不可能的。从那时起,她已经成为这个领域可能最顶尖的专家,主要通过语言和视觉作为她的研究方式。从那时起,我对常识产生了浓厚的兴趣,想要更详细地探讨它。

我在想,人类的知识本身是否具有内在的关系性,甚至可能是多模态的。我们在大脑中构建概念,是基于经历——无论是亲身体验、感知、想象还是理解。这些心理概念引导着我们的言语和行动,有时通过语言表达,有时则完全通过身体语言表达。或许我们需要更深层的表示来引导模态的交融。或许语言能帮助我们的视觉模型更快适应新领域。也许这是因为它提供了一些常识。

实际上,我之所以提到这一点,是因为如果你准备开始进行视觉微调工作,我希望你提前知道,这不会是件容易的事,而且在语言领域对你有效的东西,可能并不会像你想的那样顺利迁移到视觉领域。我还想提到这一点,是因为我希望你们这些未来的研究人员要有勇气,相信直觉,挑战自己的假设。现在我们已经了解了基础模型的 MLOps,让我们来看一看 AWS 提供的一些服务,帮助简化流程并加速你掌握这一主题!

AWS 提供的 MLOps 服务

幸运的是,AWS 提供了各种工具来简化这一过程!其中一个很棒的功能叫做血缘追踪。SageMaker 可以自动为关键工件创建血缘(3),甚至跨账户创建血缘。这包括数据集工件、镜像、算法规格、数据配置、训练作业组件、端点和检查点。这与实验 SDK 集成,允许你以编程方式在大规模上比较实验和结果。让我们通过可视化来看一下。我们甚至会为你生成一个可视化图,展示所有这些是如何关联的!请查看下图。

图 14.5 – SageMaker 自动创建血缘追踪

图 14.5 – SageMaker 自动创建血缘追踪

如你所见,追踪血缘的第一步是运行 SageMaker 中的关键资源,如训练作业、镜像和处理作业。你可以使用自动追踪的实体,也可以定义自己的实体。为了生成如前图所示的血缘视图,你可以使用血缘查询语言。如果你想直接进入带有可视化解决方案的笔记本,可以查看参考资料部分中的点(4)。血缘追踪的详细说明见此处 – (5),查询语言的定义见此处 – (6)。通过 SageMaker 血缘追踪,你可以轻松追踪一个模型是如何训练的以及它被部署到哪里。

它是如何工作的?你可以使用LineageFilter API来查找与模型工件相关的不同对象,如端点。你还可以搜索与端点相关的试验组件,查找与模型相关的数据集,并在关联项的图谱中前后穿梭。拥有这些关系的程序化访问,使得将所有必要资源放入管道和其他治理结构中变得更加容易。

一旦你识别了资源,如何将它们封装成一个管道?正如我们在本章之前提到的,许多基础的 AWS 和 SageMaker 资源都可以作为独立的构建模块使用。这些资源包括模型、相关的模型工件、部署配置、关联的训练和处理作业、超参数调优和容器。这意味着你可以使用 AWS SDK for Python,boto3SageMaker Python SDK来编程地指向并执行所有资源和任务。将这些资源封装到一个管道中意味着使用你偏好的工具堆栈来自动化操作它们。实现这一点的一种方式是SageMaker Pipelines

SageMaker Pipelines 简介

如果你正在使用 SageMaker 原生资源,例如作业、端点、模型工件和 Docker 镜像,那么通过 Pipelines SDK 构造(7)将它们连接起来应该不会增加太多额外的负担。SageMaker Pipelines 是一个托管功能,你可以使用它来创建、运行和管理 AWS 上的完整机器学习工作流。一旦你为 SageMaker 定义了基础的 Python SDK 对象,如训练作业、评估指标、超参数调优和端点,你就可以将这些对象传递给 Pipelines API 并将其创建为一个图!接下来让我们在下面的图中更详细地探讨这一点。

图 14.6 – SageMaker Pipelines

图 14.6 – SageMaker Pipelines

如果你想要查看一个类似于前面图中所示的图形的笔记本示例,可以访问 GitHub 上的资源(8)。核心思路是,你将管道的每个部分单独构建,比如数据处理、训练和评估步骤,然后将这些部分传递给 SageMaker Pipelines API,创建一个连接的图。

如你在上面的图中看到的,这在 SageMaker Studio 中以可视化方式呈现!这使得数据科学家更容易开发、审查、管理和执行这些管道。Studio 还提供了许多其他与 MLOps 相关的功能,例如特征存储、模型注册、端点管理、模型监控和推理推荐器。如果你想更深入了解这些话题,可以查阅 AWS Well-Architected Framework 关于机器学习的完整白皮书(9)

现在我们已经了解了 AWS 的 MLOps 产品,让我们通过一个完整的回顾来结束本章内容。

总结

在本章中,我们介绍了 MLOps 的核心概念,尤其是在视觉和语言的背景下。我们讨论了机器学习操作,包括使其运行的一些技术、人员和流程。我们特别关注了流水线方面,学习了构建它们的有用技术,如 SageMaker Pipelines、Apache Airflow 和 Step Functions。我们研究了与机器学习相关的几种不同类型的流水线,如模型部署、模型再训练和环境推广。我们讨论了核心操作概念,如 CI 和 CD。我们了解了模型监控和人机协同设计模式。我们学习了 MLOps 中一些适用于视觉和语言的特定技术,如大型语言模型的常见开发和部署流水线。我们还探讨了语言中可能有效的核心方法,如何由于模态之间的根本差异以及当前学习系统的运作方式,在视觉中固有地不太可靠。我们通过讨论常识推理,快速走了一遍哲学路线,然后通过介绍 AWS 的 MLOps 关键产品,如 SageMaker Lineage、Experiments 和 Pipelines,结束了本章内容。

现在,让我们通过最后一章讨论未来趋势来结束本书。

参考文献

请阅读以下内容,以获取本章中涵盖的几个主题的更多信息:

  1. 通过对抗模型 级联强化深度神经网络arxiv.org/pdf/1802.01448.pdf

  2. Yejin Choihomes.cs.washington.edu/~yejin/

  3. Amazon SageMaker ML 谱系 追踪docs.aws.amazon.com/sagemaker/latest/dg/lineage-tracking.html

  4. aws/amazon-sagemaker-examplesgithub.com/aws/amazon-sagemaker-examples/blob/main/sagemaker-lineage/sagemaker-lineage.ipynb

  5. 谱系追踪 实体docs.aws.amazon.com/sagemaker/latest/dg/lineage-tracking-entities.html

  6. 查询谱系 实体docs.aws.amazon.com/sagemaker/latest/dg/querying-lineage-entities.html

  7. SageMaker 流水线sagemaker.readthedocs.io/en/stable/workflows/pipelines/index.html

  8. aws/amazon-sagemaker-examplesgithub.com/aws/amazon-sagemaker-examples/blob/main/sagemaker-pipelines/tabular/train-register-deploy-pipeline-model/train%20register%20and%20deploy%20a%20pipeline%20model.ipynb

  9. 机器学习镜头 AWS Well-Architected 框架docs.aws.amazon.com/pdfs/wellarchitected/latest/machine-learning-lens/wellarchitected-machine-learning-lens.pdf

第十五章:预训练基础模型的未来趋势

在本章中,我们将通过指引未来的趋势来总结本书,涵盖书中所有相关主题。我们将探讨基础模型应用开发的趋势,例如使用 LangChain 构建互动对话应用程序,以及使用检索增强生成(retrieval augmented generation)等技术来减少大语言模型的幻觉问题。我们还将探索如何使用生成模型解决分类任务、人本设计以及其他生成模式,如代码、音乐、产品文档、幻灯片等!我们将讨论 AWS 的服务,例如 SageMaker JumpStart 基础模型、Amazon Bedrock、Amazon Titan 和 Amazon Code Whisperer,并展望基础模型及预训练技术的未来趋势。

我们特别将深入探讨以下主题:

  • 构建大语言模型应用的技术

  • 视觉与语言之外的生成模式

  • AWS 在基础模型方面的服务

  • 基础模型的未来

  • 预训练的未来

构建大语言模型应用的技术

现在你已经了解了基础模型,特别是大语言模型,我们来聊聊几种关键方式,如何利用它们来构建应用程序。2022 年 12 月 ChatGPT 事件中,最重要的一个收获就是,用户显然喜欢他们的聊天能够记住对话中的每一刻,记住之前提到的主题,并涵盖对话的所有曲折变化。换句话说,除了通用的问答之外,用户明显偏好聊天能够进行链式对话。我们来看看下面截图中的一个例子:

图 15.1 – 用于聊天应用的链式提问

图 15.1 – 用于聊天应用的链式提问

图 15.1 左右两边的关键区别在于,左侧的回答是不连续的。这意味着模型只是将每个问题作为单独的实体来看待,然后提供其回答。而右侧的回答则是连续的,即整个对话被提供给模型,最新的问题位于底部。这有助于确保回答的连贯性,模型能够更好地保持上下文。

你如何自己设置这个?嗯,首先,我刚才描述的其实并不难。想象一下,只需从你的 HTML 页面读取,将所有的问答数据打包进提示词中,然后提取回答并返回给终端用户。然而,如果你不想自己构建,完全可以使用一些优秀的开源选项!

使用开源堆栈构建互动对话应用

如果你之前没有见过,允许我快速向你介绍 LangChain。它可以在 GitHub 上免费获取,链接是:github.com/hwchase17/langchain。LangChain 是由 Harrison Chase 和其他超过 600 名贡献者共同构建的开源工具包。它提供了类似于著名的 ChatGPT 的功能,可以指向 OpenAI 的 API 或任何其他基础模型,但允许你作为开发者和数据科学家创建自己的前端和客户体验。

将应用程序与模型解耦是一个明智的做法;仅在过去几个月里,全球已经上线了数百个新的大型语言模型,全球各地的团队也在积极开发更多。当你的应用程序通过单一的 API 调用与模型交互时,你可以更容易地从一个模型切换到下一个,因为随着时间的推移,许可、定价和功能都会升级。这对你来说是一个大大的好处!

另一个有趣的开源技术是 Haystack (26)。由德国初创公司 Deepset 开发,Haystack 是一个非常有用的工具,用于……在大海捞针。具体来说,它充当一个接口,帮助你将自己的 LLMs 带入广泛的问答场景。这是他们的初步专长,后来他们扩展了很多!

在 AWS,我们有一个开源模板,用于在 AWS 上构建 LangChain 应用程序。可以在 GitHub 上找到,链接是:github.com/3coins/langchain-aws-template。在下面的图示中,你可以看到架构的简要表示:

图 15.2 – 在 AWS 上托管 LangChain

图 15.2 – 在 AWS 上托管 LangChain

虽然这可以指向任何前端,但我们提供了一个示例模板,供你用于启动应用程序。你也可以轻松地指向任何自定义模型,无论它是在 SageMaker 端点上,还是在新的 AWS 服务 Bedrock 中!稍后在本章中我们会进一步介绍。正如你在前面的图像中看到的,这个模板可以轻松地在任何与云交互的地方运行 UI。让我们来看一下所有的步骤:

  1. 第一,UI 访问 API 网关。

  2. 第二,通过 IAM 检索凭据。

  3. 第三,通过 Lambda 调用该服务。

  4. 第四,通过 Secrets Manager 检索模型凭据。

  5. 第五,模型通过调用无服务器模型 SDK 的 API,或者通过调用你训练的并托管在 SageMaker 端点上的自定义模型来调用。

  6. 第六,查找 DynamoDB 中相关的对话历史,以确保你的回答准确无误。

这个聊天界面如何确保不产生幻觉回答?它如何指向存储在数据库中的一组数据?通过检索增强生成RAG),我们将在接下来的部分进行讲解。

使用 RAG 确保 LLM 应用程序的高准确性

正如原始的 2020 年(1)论文中所解释的那样,RAG 是一种检索与给定查询相关的文档的方法。假设你的聊天应用程序接收关于你数据库中特定项目的问题,比如你的产品之一。与其让模型编造答案,不如从你的数据库中检索正确的文档,并仅使用 LLM 来美化响应。这就是 RAG 如此强大的地方;你可以用它来确保生成答案的准确性保持高,同时在风格和语气上保持一致的客户体验。让我们更仔细地看看:

图 15.3 – RAG

图 15.3 – RAG

首先,一个问题从左侧出现。在左上方,你可以看到一个简单的问题,定义“中耳”。这个问题被一个查询编码器处理,查询编码器只是一个语言模型,用于生成查询的嵌入。然后,这个嵌入被应用到一个数据库的索引中,这里使用了许多候选算法:K 最近邻最大内积搜索MIPS)等。一旦你检索到一组相似的文档,就可以将最好的文档输入到生成器中,右侧的最终模型。这会根据输入的文档返回一个简单的答案。在这里,答案是中耳包括鼓室和 三块小骨

然而,值得注意的是,这里的 LLM 并没有真正定义什么是中耳。它实际上是在回答问题:“中耳内包含哪些物体?”可以说,中耳的任何定义都会包括其功能,特别是作为耳道和内耳之间的缓冲区,帮助你保持平衡并让你听到声音。因此,这可能是专家强化学习与人类反馈RLHF)优化的一个好候选。

图 15.3所示,这整个 RAG 系统是可调的。这意味着你可以并且应该对编码器和解码器部分进行微调,以便根据你的数据集和查询类型调整模型性能。另一种分类文档的方法,正如我们将看到的,是生成!

生成是新的分类吗?

正如我们在 第十三章中学到的,提示工程,有很多方法可以促使你的语言模型输出你想要的响应类型。其中一种方法实际上是让它分类文本中看到的内容!这里有一个简单的图表来说明这个概念:

图 15.4 – 使用生成代替分类

图 15.4 – 使用生成代替分类

如图所示,传统的分类方法是在训练模型时提前完成一个任务:分类。这个模型可能在分类上表现良好,但它完全无法处理新任务。这一关键缺点是基础模型,特别是大型语言模型如今如此受欢迎的主要原因之一:它们非常灵活,可以在不需要重新训练的情况下处理许多不同的任务。

图 15.4的右侧,你可以看到我们使用相同的文本作为起始点,但我们并不是将其传递给基于编码器的文本模型,而是传递给基于解码器的模型,并简单地添加了指令:将此句子分类为正面或负面情感。你也可以同样说:“告诉我更多关于这个顾客真实感受的事情,”或者“这个购房者有多乐观?”或者“帮助这个购房者找到一所符合他需求的房子。”可以说,以上三种指令有所不同,逐渐脱离了纯粹的分类任务,转向了更广泛的应用开发或客户体验。随着时间的推移,预计会看到更多类似的例子!让我们再看看另一种构建 LLM 应用程序的关键技术:保持人类在环中的参与。

面向人类的应用程序设计方法,利用大型语言模型(LLMs)

我们之前在第二章**, 数据集准备:第一部分第十章**, 微调与评估第十一章**, 检测、缓解和监控偏见以及第十四章**, 计算机视觉与语言的 MLOps中涉及过这个话题。我再说一遍,我相信人工标注将成为公司能够提供的竞争优势。为什么?因为构建 LLM 现在变得极具竞争力,开放源代码和专有技术的竞争方都在积极争夺你的业务。开放源代码的选项来自 Hugging Face 和 Stability 等公司,而专有技术则来自 AI21、Anthropic 和 OpenAI。这些选项之间的差异是值得质疑的;你可以查看斯坦福大学的 HELM (2)上最新的排名模型,顺便提一句,它也属于该校的人本 AI 倡议。通过足够的微调和定制,你通常应该能够达到预期的性能。

那么,是什么决定了最佳的大型语言模型应用,如果不是基础模型呢?显然,端到端的客户体验至关重要,且始终如此。消费者偏好随时间变化,但一些普遍的技术原则依然存在:速度、简洁、灵活性和低成本。通过基础模型,我们可以清楚地看到,客户更倾向于可解释性和他们信任的模型。这意味着应用设计师和开发人员应当与这些长期的消费者偏好作斗争,选择最大化这些偏好的解决方案和系统。正如你可能猜到的,仅这一点就不是一项小任务。

除了设计和构建成功应用的核心技能外,我们还可以做些什么来在这个充满挑战的 LLM 新世界中保持竞争力呢?我认为,答案就是定制你的数据。专注于让你的数据和数据集变得独特:在目的、广度、深度和完整性上独一无二。充分利用你能获得的最佳资源对数据进行标注,并将其作为整个应用工作流程的核心部分。这将带你进入持续学习,即模型能够根据最终用户的反馈不断变得越来越好。

接下来,让我们看看即将出现的生成模态。

其他生成模态

自 2022 年 ChatGPT 事件以来,技术界大多为生成新内容这一命题所着迷。虽然这一点一直是比较有趣的,但高性能基础模型与媒体对于这些能力的过度热情相遇,再加上疫情后社区对错失机会的强烈恐惧,导致我们进入了生成 AI 的全球关注风暴。

这是一件好事吗?说实话,我很高兴终于看到这种转变;自 2019 年以来,我就一直以某种方式在使用 AI/ML 模型生成内容,作为一个作家和创意工作者,我一直认为这是机器学习中最有趣的部分。我对 David Foster 的关于这一主题的书(3)印象深刻。他刚刚发布了这本书的更新版,包含了最新的基础模型和方法!让我们快速回顾一下目前在生成 AI 应用中常见的其他类型的模态。

视觉和语言之外的生成关键模态

这里是我认为最有趣的内容生成类型的简短清单,超出了我们在本书中看到的内容:

  • 生成代码

  • 生成音乐

  • 生成 PowerPoint 幻灯片、广告和视觉内容

  • 生成产品文档

  • 生成建筑设计,然后构建应用

  • 生成电影、电视节目和娱乐内容

  • 生成网站、游戏和移动应用

生成代码对大多数人来说并不意外;它与语言生成的核心相似性使得它成为完美的候选者!微调一个大型语言模型(LLM)以输出你所选择语言的代码非常简单;这是我 2019 年的项目(4),它正是利用 SageMaker 示例笔记本完成了这一任务!代码好吗?绝对不好,但幸运的是,LLM 自那时以来已经取得了很大进展。许多现代的代码生成模型非常优秀,感谢 Hugging Face 和 ServiceNow 的合作,我们现在可以使用一个开源模型!它叫做StarCoder,并且可以在 Hugging Face 上免费获取:huggingface.co/bigcode/starcoder

我喜欢使用开源 LLM 进行代码生成的一个原因是你可以自定义它!这意味着你可以指向你自己的私有代码库,对数据进行标记,更新模型,并立即训练这个 LLM 以生成你组织风格的代码!在组织层面,你甚至可以对开源 LLM 进行一些持续的预训练,以加速所有开发人员的工作,尤其是用于你自己的代码库。接下来,在我们重点讨论 AWS 产品,特别是Amazon Code Whisperer时,我们将看看你可以如何利用 LLM 来更快地编写自己的代码。(27)

前面提到的内容都可以是你自己生成式 AI 项目的绝佳候选者。真的,就像我们看到的,通用机器学习从实验室走向了大多数企业和项目的基础,生成能力也很可能以某种方式走上相同的道路。

那么这意味着工程岗位会被取代吗?老实说,我对此表示怀疑。就像优秀的搜索引擎的崛起并没有取代软件工程岗位,反而让许多人觉得这些岗位更加有趣和可做,我预期生成能力也会有相同的效果。它们擅长快速搜索大量可能性并找到很好的选择,但仍然需要你了解消费者、产品和设计的方方面面。模型并不擅长批判性思维,但它们擅长提出创意并发现不足,至少在文字方面如此。

现在我们已经从高层次上了解了其他生成方式,让我们来看看 AWS 在基础模型方面的产品吧!

AWS 在基础模型方面的产品

在 AWS 上,正如你在本书中所看到的,你有成百上千种方式来优化基础模型的开发和部署。现在让我们来看一下 AWS 在这一领域明确投资以提升客户体验的几种方式:

  • SageMaker JumpStart Foundation Model Hub:该功能在 2022 年 re:Invent 大会预览中宣布,这是一个可以在 SageMaker 环境中便捷访问基础模型的选项。它包括开源模型,如 Hugging Face 提供的 BLOOM 和 Flan-T5,以及专有模型,如 AI21 Jurassic。所有基础模型的列表可在这里查看 (5)。至今,我们已有近 20 种基础模型,所有模型都可以在您自己的安全环境中进行托管。您用于与这些模型进行交互或微调的任何数据都不会与提供方共享。您还可以通过自行选择实例来优化成本。我们有数十个示例笔记本,指向这些模型,适用于各种训练和托管使用场景,您可以在这里 (6) 以及其他地方查看。关于模型训练数据的更多信息,您可以直接在游乐场中阅读。

  • Amazon Bedrock:如果您密切关注 AWS 在 2023 年初的新闻,您可能已经注意到我们发布了一个新的基础模型服务:Amazon Bedrock!正如 Swami Sivasubramanian 在这篇博客文章中所讨论的 (7),Bedrock 是一项通过无服务器接口与各种基础模型进行交互的服务,并且保持安全性。换句话说,Bedrock 为多个基础模型提供了一个入口点,让您能够获得各大提供商的最佳服务。这包括 AI 初创公司,如 AI21、Anthropic 和 Stability。与 Bedrock 交互意味着使用无服务器体验,免去了处理底层基础设施的麻烦。您还可以使用 Bedrock 对模型进行微调!

  • Amazon Titan:通过 Bedrock 提供的另一个模型是 Titan,这是一款由 Amazon 完全训练和管理的大型语言模型!这意味着我们负责处理训练数据、优化、调优、去偏以及所有增强功能,以帮助您获得大规模语言模型的最佳结果。Titan 也将支持微调功能。

亚马逊 Code Whisperer:正如你可能已经看到的,Code Whisperer 是 AWS 在 2022 年发布的服务,并在 2023 年正式上线。有趣的是,它似乎与特定的开发环境紧密结合,利用你正在编写的脚本的整个上下文,并基于此生成推荐。你可以编写伪代码、Markdown 或其他函数起始部分,并通过快捷键调用模型。这样,系统会根据脚本的上下文为你提供多种选项,最终让你选择最适合你的脚本!幸运的是,Jupyter notebooks 和 SageMaker Studio 现在都支持这一功能;你可以阅读 AWS 高级首席技术专家 Brian Granger 的博客,Brian 是 Project Jupyter 的联合创始人,了解更多这些倡议。以下是 Brian 关于这一主题的博客文章:aws.amazon.com/blogs/machine-learning/announcing-new-jupyter-contributions-by-aws-to-democratize-generative-ai-and-scale-ml-workloads/ 小贴士:Code Whisperer 对个人用户免费!仔细阅读 Swami 的博客文章的读者也会注意到我们最新的机器学习基础设施更新,如第二版的Inferentia 芯片inf2,以及带有更高带宽的 Trainium 实例,trn1n

细心的 Swami 博客文章读者还会注意到我们最新机器学习基础设施的更新,例如第二版的Inferentia 芯片inf2,以及带有更高带宽的 Trainium 实例,trn1n。我们还推出了免费的代码生成服务CodeWhisperer

现在我们已经了解了 AWS 在这个领域的一些产品,让我们来假设一下基础模型的未来。

基础模型的未来

对我而言,关于基础模型的发展趋势,有几点似乎是显而易见的:

  • 开源和专有模型提供者之间的激烈竞争将持续下去。正如前面提到的,目前我们正处于全球大多数科技行业对基础模型的高度关注的完美风暴中。这里的一个关键轴线是专有模型与开源模型的对比。正如 5 月 4 日泄露的 Google 文档(8)所建议的,开源世界的能力正在不断提升,在许多情况下,开源选项比专有选项更优。实际上,他们将开源模型描述为“按重量计算更强大”。这意味着就模型本身的规模而言,开源世界所生产的小型模型在按字节大小比较时表现得更好。

  • 如果模型消费者对模型提供者保持灵活性,他们将以更低的成本获得更多的选择。对我来说,这场激烈竞争的结果很明确;随着时间的推移,你会得到越来越多的选择,且价格会越来越低!这意味着,作为模型消费者,明智的选择是不要把自己锁定在单一模型上。随着基础模型的勇敢新世界的推进,确保你和你的团队处于最佳的情境,并保持灵活性,跟随新模型的出现。

  • 模型正变得越来越小且更强大。这在很大程度上得益于开源社区中由 Stable Diffusion 推动的热情,基础模型现在正在减小体积,但其准确性却在提高。这意味着今天你可以用一个 13B 参数的模型,如 StableVicuna (28),完成几年前需要 175B 参数模型才能完成的任务。在你设计应用时,记得这一点!

  • 将专有数据和人工反馈作为你的优势。为了最大限度地利用这些竞争,我建议你依托你的数据。只要你愿意接受最新最强的模型基础,将你的专有数据和人工反馈作为关键投资领域,就能使你从市场中脱颖而出。确保你和你的团队从一开始就频繁地标注数据,并尽可能多地利用你们独特的视角和专业知识。

  • 安全性对于与基础模型的互动至关重要。这一信号在市场中非常明显,消费者强烈偏好那些能够保护其数据并且不允许与模型提供者共享数据的环境,包括模型查询和微调资产。从某种意义上说,这也是将专有数据和人工反馈作为优势的衍生品;在未来的世界里,你的数据将成为你的卖点。以你自己的基础模型的形式保护这些数据,保持模型公正,避免越狱攻击,并防止生成仇恨言论,依旧是至关重要的。看起来,确保基础模型应用程序安全,可能需要一套全新的安全措施。

  • 基础模型正在成为新的数据库,自然语言则是新的编程语言。我预计未来十二个月内,大多数应用将把基础模型作为一种新型数据库。现在,除了将记录存储在磁盘上,你还可以通过神经网络对其进行处理,学习映射关系和数据之间的联系,这些是单个人类无法与之竞争的,并且能与人类进行自然语言交互。优化、扩展、去偏见、确保准确性以及降低成本将是未来几年的工作重点。

我还预计会有更多的基础模型,涵盖不同的模式、用户群体、语言、技术、目标和领域。随着训练和生产它们的成本因激烈的竞争而下降,我们可能会看到越来越多的入门级开发者进入这个市场。考虑到这一点,让我们在最后总结一下关于预训练未来的思考。

预训练的未来

让我们回顾一些提供谨慎和批判性评估的趋势,来看一看最近基础模型的“淘金热”。其中最突出的例子之一是杰弗里·辛顿辞去谷歌职务(29),警告 AI 发展的危险,并呼吁对所有基础模型研究实施 6 个月的暂停(30)。

个人来说,我认为这一暂停并没有认识到最初推动这种炒作的原因:AI 经济学的无形之手。找到高薪的技术工作并不容易;获得并维持美国及类似国家的签证也并非易事。在一个拥有一些最聪明且最有驱动力的人才的行业中,随着快速变革和颠覆性的变化来发展你的职业生涯是绝非简单的。基础模型和所有技术的进步之所以发展,是因为人类需要证明自己、发展职业并养家糊口。要求暂停大规模训练的实验几乎等同于要求大量年轻人停止将他们的热情、技能和时间投入到自己职业发展的最佳选择中。显然,这与他们的最佳利益背道而驰!

然而,即便是在支持继续研究基础模型的阵营中,并非每个人都对预训练变压器的持续价值持过于乐观的态度。我们在第一章中提到的科学家雅恩·勒昆,曾开发了 MNIST,他认为自监督学习是“智能的暗物质。(9)”自从 ChatGPT 全球热潮以来,勒昆对大型语言模型和自回归模型的局限性提出了严厉批评,因为它们的核心优势仅仅是预测序列中下一个最可能的词素,而并非以任何可靠的方式理解世界。相反,他建议我们构建能够学习推理的 AI 模型,包括开发行动计划的层级表示。

他在这个警示中并不孤单。华盛顿大学和艾伦人工智能研究所的麦克阿瑟学者崔烨金 (10) 最近在 TED 演讲中分享了她的看法,关于为什么“AI 非常聪明——但又令人震惊地愚蠢。” (11) 崔烨金在常识推理方面的几十年工作表明,尽管 NLP 模型可能能解决一些有限的任务,但它们仍然在一些极其基础的人类任务上挣扎,比如理解现实与虚构之间的区别,或者假设和规划、简洁性的价值,以及基本的世界逻辑映射。

对我来说,这里的分界是清晰的。一方面,我们有着数十年的推动,致力于构建最佳且最令人印象深刻的人工智能表现。另一方面,我们有着庞大的商业、技术和学术产业,数百万的人的努力致力于构建应用并提供价值,这些应用和价值为他们的职业生涯和团队的长久发展奠定了基础。这个技术发展经济体是否会创造出最聪明的机器?可能会。是否会建立起提供消费者价值的应用和商业?当然会。未来几十年,这两种相关却不同的方向会继续重叠吗?毫无疑问。

在我们结束之前,我想提一下几个特别与预训练相关的有趣技术趋势:

  • 持续预训练:如果你的基础模型能够从最新的数据中受益,并且这些数据以持续的更新流提供,为什么不构建一个持续的摄取和训练循环,以保持你的应用性能呢?这是 2022 年论文中的核心提议 (12)。我想象一些应用会从这种持续的训练流中受益,特别是当参数高效微调 (31) 使得这种方式的成本更具吸引力时。

  • 检索预训练:随着生成式 AI 应用的扩展,对准确生成文本的需求将持续增加。DeepMind 提出的这种方法,将检索过程 (14) 应用于预训练,并在使用 25 倍更少的参数的情况下,达到与 GPT-3 相似的性能,使其在训练和托管时更加高效且更具吸引力。我预计,在预训练期间检索令牌的基本概念会与 RAG (15) 结合,发展成提供更高准确性保证的大型语言模型(LLM)。

  • 更多通用的预训练机制:正如你们可能已经注意到的,很多媒体和开源关注似乎仅集中在模型和低级任务中的新一代表现上。我认为这是一个问题,因为它忽略了这些模型的根基——它们的来源和构建方式:预训练本身。这意味着,如果预训练能够变得更易于获取和更具普遍性,我们就能从对模型的固守转向对预训练本身的广泛支持。目前已有一些朝着这个方向迈出的步伐,例如 Data2Vec (16),它提出了一个适用于视觉、语音和语言的自监督学习通用框架。另一个尝试是UL2统一语言学习范式。Google Brain 团队建议结合不同的预训练范式,然后在微调时切换不同的范式。

  • 更多语言,拜托!我在疫情后亲自参加的第一场会议之一是 2022 年计算语言学协会大会(18)。我惊喜地发现,他们特别关注多语言,强烈且令人钦佩地推动着能够跨越语言障碍并拓展自然语言处理技术在全球濒危语言和社区中的应用。令人钦佩的是,联合国宣布 2022-2023 年为国际土著语言十年,估计到 2100 年,至少 50%的现有语言将会灭绝或面临严重危险(32)。这将继续成为基础模型中的一个重要话题,因为它是技术采用和创新的瓶颈之一。朝着这一方向迈出的一个步骤是清华大学的 GLM-130B (19),这是一个明确以中文和英文预训练的模型。另一个值得注意的双语模型是 Hugging Face 的 BLOOM (20),该模型在 46 种自然语言和 13 种编程语言上进行了训练。其他类似的项目也提供了针对单一非英语语言的能力,例如 LightOn 的法语模型 PAGnol (21)、日语掩码语言模型(22)、德语 LLM (23)等。甚至还有呼声要求推出 BritGPT (24),以将生成能力引入英国的口语和会话风格。

在这一点上,让我们以最后的结论结束本书。

总结

真是一次难忘的旅程!感谢那些和我一起坚持到最后的你们,感谢你们投入的时间、创意和精力,学习我的文字和思考。我希望至少一些见解对你们来说是值得的,也希望错误没有过于显眼。

在本书中,我们详细讲解了预训练基础模型的整个过程,展示了来自视觉和语言的关键用例和示例,并了解了在 AWS 上构建应用程序和项目的核心能力。我非常喜欢听取读者的反馈,所以请随时联系我并保持联系!我在 LinkedIn 上很活跃,您可以随时通过问题或评论与我交流。我每周在 Twitch 上做一档关于生成式 AI 的节目,您可以在那里找到我,并参与反馈或评论。(25)

当然,您也可以随时与您的 AWS 团队联系,直接与我交流!我喜欢与客户见面,思考架构选择,将您的需求传达给我们的服务团队,并与您一起构思如何创造更美好的明天。告诉我您迫不及待想要构建的项目!

参考文献

请查看以下内容以获取更多章节涉及主题的信息:

  1. 知识密集型自然语言处理任务的检索增强生成:arxiv.org/pdf/2005.11401.pdf

  2. HELM:crfm.stanford.edu/helm/latest/

  3. 生成式深度学习:教机器绘画、写作、作曲和演奏(第 1 版):www.amazon.com/Generative-Deep-Learning-Teaching-Machines/dp/1492041947

  4. aws-samples/amazon-sagemaker-architecting-for-ml:github.com/aws-samples/amazon-sagemaker-architectingfor-ml/tree/master/Example-Project

  5. 开始使用 Amazon SageMaker JumpStart:aws.amazon.com/sagemaker/jumpstart/gettingstarted/?sagemaker-jumpstart-cards.sort-by=item.additionalFields.priority&sagemaker-jumpstart-cards.sort-order=asc&awsf.sagemakerjumpstart-filter-product-type=*all&awsf.sagemaker-jumpstartfilter-text=*all&awsf.sagemaker-jumpstart-filter-vision=*all&awsf.sagemaker-jumpstart-filter-tabular=*all&awsf.sagemaker-jumpstartfilter-audio-tasks=*all&awsf.sagemaker-jumpstart-filtermultimodal=*all&awsf.sagemaker-jumpstart-filter-RL=*all

  6. aws/amazon-sagemaker-examples:github.com/aws/amazon-sagemaker-examples/tree/main/

  7. 宣布 AWS 上用于构建生成型人工智能的新工具: aws.amazon.com/blogs/machine-learning/announcing-new-tools-for-building-with-generative-ai-on-aws/

  8. Google "我们没有护城河,OpenAI 也没有": www.semianalysis.com/p/google-we-have-no-moat-and-neither

  9. 自监督学习:智能的暗物质: ai.facebook.com/blog/self-supervised-learning-the-dark-matter-of-intelligence/

  10. Yejin Choi: homes.cs.washington.edu/~yejin/

  11. 为什么人工智能非常聪明却又令人震惊地愚蠢: www.ted.com/talks/yejin_choi_why_ai_is_incredibly_smart_and_shockingly_stupid/c?language=en

  12. 持续预训练缓解语言和视觉中的遗忘问题: arxiv.org/pdf/2205.09357.pdf

  13. LoRA:大型语言模型的低秩适应: arxiv.org/abs/2106.09685

  14. 通过从万亿个标记中检索来改进语言模型: arxiv.org/pdf/2112.04426.pdf

  15. 检索增强生成用于知识密集型自然语言处理任务: arxiv.org/pdf/2005.11401.pdf

  16. data2vec: 一个通用的自监督学习框架,适用于语音、视觉和语言: arxiv.org/pdf/2202.03555.pdf

  17. UL2:统一语言学习范式: arxiv.org/pdf/2205.05131.pdf

  18. ACL 2022: www.2022.aclweb.org/

  19. GLM-130B:一个开放的双语预训练模型: openreview.net/pdf?id=-Aw0rrrPUF

  20. BLOOM:一个 176B 参数的开放访问多语言语言模型: arxiv.org/pdf/2211.05100.pdf

  21. LightOn 发布 PAGnol,最大的法语语言模型: medium.com/@LightOnIO/lighton-releases-pagnol-the-largest-french-language-model-f50b719352ab

  22. 日本学术领域的掩码语言模型: aclanthology.org/2022.sdp-1.16.pdf

  23. Cedille.ai 推出了最大的德语文本生成语言模型: cedille.ai/blog/cedille-ai-launches-the-largest-language-model-in-german-for-text-generation

  24. 英国需要自己的“BritGPT”,否则将面临不确定的未来,议员们听闻:www.theguardian.com/business/2023/feb/22/uk-needs-its-own-britgpt-or-will-face-an-uncertain-future-mps-hear

  25. AWS 时间表:www.twitch.tv/aws/schedule?seriesID=340be301-27dc-42c6-890a-302cd13899af

  26. deepset-ai/haystack:github.com/deepset-ai/haystack

  27. AWS 概览:aws.amazon.com/codewhisperer/

  28. Hugging Face: https://huggingface.co/CarperAI/stable-vicuna-13b-delta

  29. AI 之父:www.theguardian.com/technology/2023/may/02/geoffrey-hinton-godfather-of-ai-quits-google-warns-dangers-of-machine-learning

  30. 暂停大型 AI 实验:一封公开信:futureoflife.org/open-letter/pause-giant-ai-experiments/

  31. huggingface/peft:github.com/huggingface/peft

  32. 经济和社会事务部土著人民:www.un.org/development/desa/indigenouspeoples/indigenous-languages.html

posted @ 2025-07-17 15:21  绝不原创的飞龙  阅读(14)  评论(0)    收藏  举报