AI/ML 数据湖参考架构的架构师指南

Architect’s Guide to a Reference Architecture for an AI/ML Datalake

本文的简要版本于 2024 年 3 月 19 日发表在 The New Stack 上。

在企业人工智能领域,模型主要分为两种类型:判别式模型和生成式模型。判别式模型用于对数据进行分类或预测,而生成式模型用于创建新数据。尽管生成式 AI 最近占据了新闻头条,但组织仍在追求这两种类型的人工智能。判别式 AI 对于希望提高运营效率和探索额外收入来源的组织来说,仍然是一项重要的举措。这些不同类型的人工智能有很多共同点,但同时,在构建 AI 数据基础设施时,也必须考虑一些重大的差异。

组织不应该构建一个只专注于 AI 的基础设施,而将商业智能、数据分析和数据科学等工作负载置之不理。完全有可能构建一个完整的数据基础设施,以满足组织的所有需求——商业智能、数据分析、数据科学、判别式 AI 和生成式 AI。

在另一篇文章中,我们介绍了一个现代数据湖的参考架构,该架构能够满足商业智能、数据分析、数据科学以及 AI/ML 的需求。让我们回顾一下现代数据湖参考架构,并重点介绍它在支持 AI/ML 工作负载方面具有的功能。

现代数据湖

让我们首先定义一个现代数据湖,它将作为我们参考架构的基础。这个架构不是“循环利用”的,而是反映了广泛适用的工程第一原则。现代数据湖是数据仓库和数据湖的结合,并且所有内容都使用对象存储。将对象存储用于数据湖非常合理,因为对象存储用于非结构化数据,而数据湖的目的就是存储非结构化数据。但是,将对象存储用于数据仓库可能听起来很奇怪——但这样构建的数据仓库代表了下一代数据仓库。这得益于 Netflix、Uber 和 Databricks 编写的开放表格式规范 (OTF),它使在数据仓库中无缝地使用对象存储成为可能。

OTF 包括 Apache Iceberg、Apache Hudi 和 Delta Lake。它们分别由 Netflix、Uber 和 Databricks 编写,因为市场上没有产品能够满足他们的数据需求。从本质上讲,它们(以不同的方式)所做的都是定义一个可以构建在对象存储(MinIO)之上的数据仓库。对象存储提供了其他存储解决方案无法比拟的可扩展容量和高性能的组合。由于这些是现代规范,因此它们具有传统数据仓库所不具备的高级功能,例如分区演变、模式演变和零拷贝分支。最后,由于数据仓库是使用对象存储构建的,因此您可以将同一个对象存储用于非结构化数据,例如图像、视频文件、音频文件和文档。非结构化数据通常存储在业界称为数据湖的地方。将对象存储作为数据湖和数据仓库的基础,可以得到一个能够容纳所有数据的解决方案。结构化存储位于基于 OTF 的数据仓库中,非结构化存储位于数据湖中。同一个 MinIO 实例可以同时用于两者。

在 MinIO,我们将基于 OTF 的数据仓库和数据湖的这种组合称为现代数据湖,我们认为它是所有 AI/ML 工作负载的基础。它是数据收集、存储、处理和转换的地方。使用判别式 AI(监督学习、无监督学习和强化学习)训练模型通常需要一个能够处理数据仓库中结构化数据的存储解决方案。另一方面,如果您要训练大型语言模型 (LLM),则必须以原始和处理后的形式管理数据湖中的非结构化数据或文档。

来源:现代数据湖参考架构

本文重点介绍了现代数据湖参考架构中支持不同 AI/ML 工作负载的那些领域。这些功能区域列在下面。上面显示了现代数据湖的可视化描述。这些功能区域所在的层已被突出显示。

  • 判别式 AI
    • 非结构化数据的存储
    • 半结构化数据的存储
    • 数据仓库中的零拷贝分支
  • 生成式 AI
    • 使用向量数据库构建自定义语料库
    • 构建文档管道
    • 检索增强生成 (RAG)
    • 微调大型语言模型
    • 衡量 LLM 的准确性
  • 机器学习运维

本文还探讨了 GPU 的现状及其对 AI 数据基础设施的影响。我们还将探讨几个场景,说明如何构建您的基础设施以及如何避免构建错误的基础设施。最后,本文提供了一些构建您自己的 AI 数据基础设施的建议。

  • GPU 的现状
    • 饥饿的 GPU 问题
    • 增强对象存储性能
  • 两个组织的故事
  • 构建 AI 数据基础设施的计划

判别式 AI

判别式 AI 模型需要各种类型的数据进行训练。图像分类和语音识别模型将使用图像和音频文件形式的非结构化数据。另一方面,欺诈检测和医疗诊断模型根据结构化数据进行预测。让我们看看现代数据湖中可用于存储和处理判别式 AI 所需数据的选项。

非结构化数据的存储

非结构化数据将驻留在数据湖中,可用于训练和测试模型。可以将适合内存的训练集加载到训练之前(在您的 epoch 循环开始之前)。但是,如果您的训练集很大并且不适合内存,则必须在训练之前加载对象列表,并在 epoch 循环中处理每个批次时检索实际对象。如果您没有使用高速网络和高速磁盘驱动器构建数据湖,这可能会给您的数据湖带来压力。如果您使用无法放入内存的数据训练模型,请考虑使用 100 GB 网络和 NVMe 驱动器构建您的数据湖。

半结构化数据的存储

在现代数据湖中,有几个选项可用于存储半结构化文件,例如 Parquet 文件、AVRO 文件、JSON 文件,甚至 CSV 文件。最简单的方法是将它们存储在数据湖中,并以与加载非结构化对象相同的方式加载它们。如果这些半结构化文件中的数据不需要现代数据湖支持的其他工作负载(商业智能、数据分析和数据科学),那么这是最佳选择。

另一个选项是将这些文件加载到数据仓库中,其他工作负载可以使用它们。当数据加载到数据仓库中时,您可以使用零拷贝分支执行数据实验

数据仓库中的零拷贝分支

特征工程是一种用于改进用于训练模型的数据集的技术。基于 OTF 的数据仓库具有的一个非常巧妙的功能是零拷贝分支。这允许数据像在 Git 存储库中分支代码一样进行分支。顾名思义,此功能不会复制数据,而是利用用于实现数据仓库的开放表格式的元数据层来创建数据唯一副本的外观。数据科学家可以对分支进行实验——如果他们的实验成功,则可以将其分支合并回主分支以供其他数据科学家使用。如果实验不成功,则可以删除该分支。

生成式 AI

所有模型,无论是使用 Scikit-Learn 构建的小型模型、使用 PyTorch 或 TensorFlow 构建的自定义神经网络,还是基于 Transformer 架构的大型语言模型,都需要数字作为输入并产生数字作为输出。如果您对生成式 AI 感兴趣,这个简单的事实会对您的 AI/ML 基础设施提出一些额外的要求,在生成式 AI 中,单词必须转换为数字(或向量,正如我们将看到的)。如果您想使用包含公司专有知识的私有文档来增强 LLM 生成的答案,则生成式 AI 解决方案会变得更加复杂。这种增强可以采取检索增强生成或 LLM 微调的形式。

本节将讨论所有这些技术(将单词转换为数字、RAG 和微调)及其对 AI 基础设施的影响。让我们首先讨论如何构建自定义语料库以及它应该驻留在哪里。

使用向量数据库创建自定义语料库

如果您对生成式 AI 非常重视,那么您的自定义语料库应该能够定义您的组织。它应该包含其他人没有的知识文档,并且只包含真实准确的信息。此外,您的自定义语料库应该使用向量数据库构建。向量数据库会对您的文档及其向量嵌入进行索引、存储和提供访问,这些向量嵌入是您的文档的数值表示。(这解决了上面描述的数字问题。)

向量数据库促进了语义搜索。如何实现语义搜索需要大量的数学背景,并且非常复杂。但是,语义搜索在概念上很容易理解。假设您想查找所有讨论与“人工智能”相关的任何内容的文档。在传统数据库上执行此操作,您需要搜索“人工智能”的所有可能缩写、同义词和相关术语。您的查询将类似于以下内容

SELECT snippet
FROM MyCorpusTable
WHERE (text like '%artificial intelligence%' OR
text like '%ai%' OR
text like '%machine learning%' OR
text like '%ml%' OR
... and on and on ...

手动相似性搜索不仅繁琐且容易出错,而且搜索本身也非常缓慢。向量数据库可以接收如下请求,并以更快的速度和更高的准确性运行查询。如果您希望使用检索增强生成,则快速准确地运行语义查询的能力非常重要。

{
Get {
MyCorpusTable(nearText: {concepts: ["artificial intelligence"]}) 

      {代码片段}
    }

自定义语料库的另一个重要考虑因素是安全性。对文档的访问应遵循原始文档的访问限制。(如果实习生能够访问尚未发布到华尔街的首席财务官的财务结果,那将是不幸的。)在您的向量数据库中,您应该设置授权以匹配原始内容的访问级别。这可以通过将您的向量数据库与组织的身份和访问管理解决方案集成来实现。

从本质上讲,向量数据库存储非结构化数据。因此,它们应该使用您的数据湖作为存储解决方案。

构建文档管道

不幸的是,大多数组织都没有一个包含干净准确文档的单一存储库。相反,文档分散在组织的各个团队门户中,并采用多种格式。因此,构建自定义语料库的第一步是构建一个管道,该管道仅获取已批准用于生成式 AI 的文档,并将它们放入您的向量数据库中。对于大型全球组织而言,这可能是生成式 AI 解决方案中最困难的任务。团队通常会在其门户中以草稿格式保存文档。还可能存在一些关于可能性的随机的想法文档。这些文档不应成为自定义语料库的一部分,因为它们不能准确地反映业务情况。不幸的是,过滤这些文档将是一项手动工作。

文档管道还应将文档转换为文本。幸运的是,一些开源库可以为许多常见文档格式执行此操作。此外,文档管道必须将文档分解成小段,然后再将其保存到向量数据库中。这是因为在使用这些文档进行检索增强生成(将在后面的章节中讨论)时,提示大小存在限制。

微调大型语言模型

当我们微调大型语言模型时,我们会使用自定义语料库中的信息对其进行更多训练。这可能是获得特定领域 LLM 的一种好方法。虽然此选项确实需要计算能力才能针对您的自定义语料库执行微调,但它不像从头开始训练模型那样密集,可以在适度的时间范围内完成。

如果您的领域包含日常用语中找不到的术语,则微调可能会提高 LLM 响应的质量。例如,使用医学研究、环境研究和任何与自然科学相关的文档的项目可能会从微调中受益。微调采用文档中高度特定的术语,并将它们融入模型的参数参数中。在决定采用这种方法之前,应了解微调的优缺点。

缺点

  • 微调需要计算资源。
  • 无法进行可解释性。
  • 随着语料库的发展,您将需要定期使用新数据重新微调。
  • 幻觉是一个问题。
  • 文档级安全性无法实现。

优点

  • LLM 通过微调获得了来自自定义语料库的知识。
  • 推理流程比 RAG 更加简单。

虽然微调是教授 LLM 业务语言的好方法,但它会稀释数据,因为大多数 LLM 包含数十亿个参数,而您的数据将分布在所有这些参数中。微调最大的缺点是无法实现文档级授权。一旦文档用于微调,其信息就成为模型的一部分。无法根据用户的授权级别限制此信息。

让我们看看一种在推理时结合自定义数据和参数数据的方法。

检索增强生成 (RAG)

检索增强生成 (RAG) 是一种技术,它从提出的问题开始 - 使用向量数据库将问题与其他数据结合起来,然后将问题和数据传递给 LLM 以创建内容。使用 RAG,无需进行训练,因为我们通过向 LLM 发送来自高质量文档语料库的相关文本片段来对其进行教育。

它在使用问答任务时是这样的:用户在应用程序的用户界面中提出问题。您的应用程序将获取问题 - 特别是其中的单词 - 并使用向量数据库在高质量文档语料库中搜索在上下文中相关的文本片段。这些片段和原始问题将发送到 LLM。整个包 - 问题加上片段(上下文)被称为提示。LLM 将使用这些信息来生成您的答案。这看起来可能是一件愚蠢的事情 - 如果您已经知道答案(片段),为什么要费心使用 LLM 呢?请记住,这是实时发生的,目标是生成文本 - 您可以复制粘贴到您的研究中的内容。您需要 LLM 来创建包含来自自定义语料库信息的文本。

这比微调更复杂。但是,可以实现用户授权,因为文档(或文档片段)是在推理时从向量数据库中选择的。文档中的信息永远不会成为模型参数参数的一部分。RAG 的优缺点如下所示。

缺点

  • 推理流程更复杂。

优点

  • LLM 直接获得了来自自定义语料库的知识。
  • 可以进行可解释性。
  • 无需微调。
  • 幻觉大大减少,并且可以通过检查向量数据库查询的结果来控制。
  • 可以实现授权。

机器学习运维 (MLOps)

为了更好地理解 MLOps 的重要性,将模型创建与传统的应用程序开发进行比较非常有帮助。传统的应用程序开发,例如实现一个向应用程序添加新功能的新微服务,首先要审查规范。任何新的数据结构或对现有数据结构的任何更改都应首先进行设计。数据的设计在编码开始后不应更改。然后实现服务,编码是此过程中的主要活动。单元测试和端到端测试也需要进行编码。这些测试证明代码没有错误,并且正确地实现了规范。它们可以在部署整个应用程序之前由 CI/CD 管道自动运行。

创建和训练模型是不同的。了解原始数据和所需的预测是第一步。机器学习工程师确实需要编写一些代码来实现他们的神经网络或设置算法,但编码不是主要活动。重复实验是主要活动。在实验过程中,数据的設計、模型的設計以及使用的参数都会发生变化。在每次实验之后,都会创建指标来显示模型在训练过程中的表现。还会针对验证集和测试集生成模型性能指标。这些指标用于证明模型的质量。一旦模型准备好集成到应用程序中,就需要对其进行打包和部署。

MLOps(机器学习运维)是一组旨在解决这些差异的实践和工具。实验跟踪和协作是与 MLOPs 最相关的功能,但当今行业中更现代的 MLOps 工具可以做更多的事情。例如,它们可以为您的实验提供运行时环境,并且一旦模型准备好集成到应用程序中,它们就可以打包和部署模型。以下是当今 MLOps 工具中发现的功能的超集。此列表还包括其他需要考虑的事项,例如支持和数据集成。

  1. **主要参与者的支持** - MLOps 技术和功能在不断发展。您需要一个由主要参与者支持的工具,以确保该工具在不断开发和改进。
  2. **现代数据湖集成** - 实验会生成大量结构化和非结构化数据。理想情况下,这可以存储在数据仓库和数据湖中。但是,许多 MLOps 工具在出现导致现代数据湖的开放表格格式之前就已经存在,因此大多数工具将为其结构化数据提供单独的解决方案。
  3. **实验跟踪** - 跟踪每个实验的数据集、模型、超参数和指标。实验跟踪还应促进可重复性。
  4. **促进协作** - 允许团队成员查看所有机器学习工程师运行的所有实验的结果。
  5. **模型打包** - 打包模型,以便可以从其他编程环境访问。
  6. **模型服务** - 将模型部署到组织的正式环境中。如果您找到了将模型集成到现有 CI/CD 管道中的方法,则无需此功能。
  7. **模型注册表** - 维护所有模型的所有版本。
  8. **无服务器函数** - 一些工具提供允许以某种方式注释代码的功能,以便可以将函数或模型部署为容器化服务,以便在集群中运行实验。
  9. **数据管道功能** - 一些 MLOps 工具旨在提供完整的端到端功能,并具有允许您构建用于检索和存储原始数据的管道的功能。如果您已经拥有数据管道,则无需此功能。
  10. **训练管道功能** - 将您的无服务器函数编排到有向无环图中的能力。还允许计划和运行训练管道。

GPU 对 AI 数据基础设施的影响

一条链条的强度取决于其最薄弱的环节 - 您的 AI/ML 基础设施的速度仅取决于其最慢的组件。如果您使用 GPU 训练机器学习模型,那么您的薄弱环节可能是您的存储解决方案。结果就是我们所说的“GPU 饥饿问题”。GPU 饥饿问题发生在您的网络或存储解决方案无法足够快地为您的训练逻辑提供训练数据以充分利用您的 GPU 时。症状相当明显。如果您监控您的 GPU,您会注意到它们从未接近完全利用。如果您已经为您的训练代码设置了监控,那么您会注意到总训练时间主要由 IO 决定。

不幸的是,对于那些正在努力解决此问题的人来说,有一个坏消息。GPU 正在变得越来越快。让我们看看 GPU 的当前状态以及对其进行的一些改进,以了解这个问题在未来几年将如何变得更糟。

GPU 的现状

GPU 正在变得越来越快。不仅原始性能在提升,内存和带宽也在不断增加。让我们来看看英伟达最新 GPU 的这三个特性,包括 A100H100H200

GPU

性能

内存

内存带宽

A100

624 TFLOPS

40GB

1,555GB/s

H100

1,979 TFLOPS

80GB

3.35TB/s

H200

1,979 TFLOPS

141GB

4.8TB/s

(注意:上表使用与 A100 的 PCIe(外设组件互连高速)插槽解决方案以及 H100 和 H200 的 SXM(服务器 PCI Express 模块)插槽解决方案一致的统计数据。A100 不存在 SXM 统计数据。在性能方面,使用浮点 16 张量核心统计数据进行比较。)

以上统计数据的一些对比观察值得注意。首先,H100 和 H200 具有相同的性能(1,979 TFLOPS),是 A100 的 3.17 倍。H100 的内存是 A100 的两倍,内存带宽也相应增加了——否则逻辑上讲不通,GPU 会饿死自己。H200 可以处理高达 141GB 的内存,其内存带宽也相对于其他 GPU 成比例地增加。

让我们更详细地了解每个统计数据,并讨论它对机器学习的意义。

性能 - 千兆浮点运算每秒 (TFLOP) 是每秒一万亿 (10^12) 次浮点运算。也就是 1 后面跟着 12 个零 (1,000,000,000,000)。很难将 TFLOPS 等同于以 GB 为单位的 IO 需求,因为模型训练期间发生的浮点运算涉及简单的张量数学以及针对损失函数的一阶导数(也称为梯度)。但是,相对比较是可能的。查看上面的统计数据,我们可以看到 H100 和 H200 都以 1,979 TFLOPS 的速度运行,速度快了三倍——如果其他一切都能跟上,则可能消耗数据的速度快三倍。

GPU 内存 - 也称为视频 RAM 或显卡 RAM。GPU 内存与系统的内存 (RAM) 是分开的,专门设计用于处理显卡执行的密集图形处理任务。GPU 内存决定了训练模型时的批次大小。过去,当训练逻辑从 CPU 转移到 GPU 时,批次大小会减小。但是,随着 GPU 内存容量赶上 CPU 内存,用于 GPU 训练的批次大小将增加。当性能和内存容量同时增加时,结果就是更大的请求,其中每 GB 训练数据处理速度都更快。

内存带宽 - 可以将 GPU 内存带宽视为连接内存和计算核心的“高速公路”。它决定了每单位时间可以传输多少数据。就像更宽的高速公路允许更多汽车在给定时间内通过一样,更高的内存带宽允许在内存和 GPU 之间移动更多数据。如您所见,这些 GPU 的设计人员将每个新版本的内存带宽与内存成比例地提高;因此,芯片的内部数据总线将不会成为瓶颈。

为模型训练增强对象存储

如果您遇到 GPU 饥饿问题,请考虑使用 100 GB 网络和 NVMe 驱动器。使用这种配置的 最近的基准测试 使用 MinIO 在仅 32 个现成的 NVMe SSD 节点上实现了 325 GiB/s 的 GET 和 165 GiB/s 的 PUT。

随着计算世界的不断发展以及 DRAM 价格的暴跌,我们发现服务器配置通常配备 500GB 或更大的 DRAM。当您处理更大的部署时,即使是那些具有超密集 NVMe 驱动器的部署,服务器数量乘以这些服务器上的 DRAM 也会迅速增加——通常每个实例达到多个 TB。该 DRAM 池可以配置为一个分布式共享内存池,非常适合需要大量 IOPS 和吞吐量性能的工作负载。因此,我们构建了 MinIO 缓存,使我们的企业版和企业精简版客户能够配置其基础架构以利用此共享内存池,从而进一步提高核心 AI 工作负载(如 GPU 训练)的性能,同时保留完整的持久性。

两个组织的故事

作为最后的思考实验,让我们讲述两个在 AI/ML 之旅中采取截然不同方法的组织的故事。组织 #1 拥有“迭代改进”的文化。他们相信所有大型计划都可以分解成更小、更易于管理的项目。然后,这些较小的项目以这样的方式安排,即每个项目都建立在先前项目的成果之上,以解决越来越复杂的问题。他们还喜欢这些小型项目以这样的方式组织,即每个项目都能为业务带来价值。他们发现,纯粹是为了改进基础设施或对软件进行现代化改造而没有为业务带来任何新功能的项目,在控制预算的高管中并不受欢迎。因此,他们了解到,为生成式 AI 概念验证请求花哨的存储设备和计算集群并不是协调基础设施改进和新软件功能的最佳方法。相反,他们将从小规模的基础设施产品开始,这些产品可以随着业务增长而扩展——他们将从简单的 AI 模型开始,以便他们能够将 MLOPs 工具就位,并弄清楚如何与现有的 DevOps 团队和 CI/CD 管道协作。

组织 #2 拥有“闪亮事物”的文化。当行业出现最新想法时,它首先解决最引人注目的挑战,以展示其技术实力。他们发现这些项目在内部和外部都具有很高的知名度。如果出现问题,聪明的员工总能解决。

组织 #1 通过构建其 AI 数据基础架构的一部分来构建其第一个项目,同时为其主要的电子商务网站构建推荐模型。推荐模型相对容易训练。它是一个判别模型,使用已经存在于文件共享上的数据集。但是,在这个项目结束时,团队还构建了一个小型(但可扩展的)现代数据湖,实现了 MLOPs 工具,并制定了一些用于训练和部署模型的最佳实践。即使模型并不复杂,它仍然为他们的网站带来了很多效率。他们利用这些积极的结果获得了下一个项目的资金,该项目将是一个生成式 AI 解决方案。

组织 #2 为其电子商务网站构建了一个聊天机器人,用于回答客户有关产品的问题。大型语言模型相当复杂——团队不熟悉微调或检索增强生成——因此,该项目的所有工程师周期都集中在快速克服陡峭的学习曲线。模型完成后,它产生了还可以的结果——没什么特别的。不幸的是,它必须手动加载到预生产和生产环境中,因为没有 MLOPs 工具可以部署它。这导致与 DevOps 团队之间出现了一些摩擦。模型本身在生产中也存在一些稳定性问题。它运行所在的集群没有足够的计算能力来处理生成式 AI 工作负载。出现了一些严重性 1 的调用,导致对集群进行了紧急增强,以防止 LLM 在繁重流量条件下失败。项目结束后,回顾发现,如果他们想在 AI 方面取得成功,则需要增强其基础架构。

构建您的 AI/ML 数据基础架构的计划

以上简短的故事是两种极端情况的简单叙述。构建 AI 模型(判别模型和生成模型)与传统的软件开发有很大不同。在排队进行 AI/ML 工作时,应考虑到这一点。下面的图形是前面部分故事的视觉描述。它是 AI 数据基础架构优先与模型优先方法的并排比较。如上所述——基础架构优先方法中的每个积木都不必是独立的项目。组织应寻找创造性的方法来在构建其基础架构的同时交付 AI——这可以通过了解 AI 的所有可能性、从小处着手,然后选择越来越复杂的 AI 项目来实现。

结论

本文概述了我们与企业合作构建面向 AI/ML 的现代数据湖参考架构的经验。它确定了核心组件、关键构建块以及不同 AI 方法的权衡。基础要素是构建在对象存储之上的现代数据湖。对象存储必须能够大规模提供性能——其中规模为数百 PB,通常为 EB。

通过遵循此参考架构,我们预计用户将能够构建一个灵活的可扩展数据基础架构,虽然其目标是 AI 和 ML,但它在所有 OLAP 工作负载上都将同样高效。要获得有关组件的具体建议,请随时通过 keith@min.io 与我联系。