JuiceFS 在多云架构中加速大模型推理

打印 上一主题 下一主题

主题 994|帖子 994|积分 2982

在大模型的开辟与应用中,数据预处理、模型开辟、练习和推理构成四个关键环节。本文将重点探究推理环节。在之前的博客中,社区用户 BentoML 和贝壳的案例提到了使用 JuiceFS 社区版来提高模型加载的服从。本文将结合我们的实际履历,详细先容企业版在此场景下的优势
下图是一个典型的大模型推理服务的架构。我们可以观察到几个关键特点。首先,架构超过多个云服务或多个数据中央。目前在大模型领域, GPU 资源告急,多数厂商或公司倾向于采取多云、多数据中央或混合云的计谋来摆设他们的推理服务。

另一个特点是,为了确保数据一致性和管理的便捷性,会在特定地区选择公有云的对象存储作为全部模型数据的存储点。当举行推理任务调度时,大概会选取特定云服务举行任务调度。数据模型的拉取过程需要人工参与,如提前举行数据拷贝。这是由于调度系统不清晰当前数据中央详细需要哪些数据,而这些数据又是动态变革的,以是数据拷贝过程会带来额外本钱。
别的,从每个推理盘算集群的内部环境来看,由于是规模庞大的集群,会有数百到数千 GPU 卡,因此在推理服务器初始化时,会有高并发模型数据拉取需求。
因此,概括地说在大模型推理与存储相干的挑战主要集中这样几个方面:高效访问数据、跨区域数据快速分发、存量数据读取以及资源优化。接下来将逐个为大家先容我们在这些场景中的实践履历。
挑战 1:如何保证大模型数据的高吞吐、高并发读取?

推理环节常需处理百 GB 级别的模型文件,满足高并发次序读取需求。加载速率是用户最关注的题目之一。
为了满足这种场景的性能需求,可以借助 JuiceFS 企业版的分布式缓存构建大规模的缓存空间。将常用模型数据集中存储在缓存集群中,能显著提高数据读取速率,特别是在同时启动数千个推理实例时。别的,对于需要频繁切换模型的 AI 应用场景,如 Stable Diffusion 文生图服务,缓存集群可以大幅减少模型加载时间,从而直接提升用户体验。
比方在单机单卡加载 Safetensors 格式的 Stable Diffusion 模型时,从缓存集群读取数据的延迟可低至 0.5ms,而从对象存储读取的延迟通常在 20ms 左右, 性能提升了将近 40 倍
下图是 JuiceFS 分布式缓存的架构图,上层为推理集群,中心层为 JuiceFS 缓存集群,底层为对象存储,右上角是元数据服务。在推理服务摆设后,首先通过推理集群上挂载的 JuiceFS 访问所需的模型数据。假如数据可以在推理集群的本地内存缓存中找到,则直接使用;若未掷中,则查询位于中心的缓存集群。缓存集群假如也未掷中,最后会从对象存储读取数据。

虽然推理集群和缓存层从图上看好像是分开的两个条理,但在实际应用或摆设中,假如GPU 呆板上有 NVMe SSD,这两层可以归并。
在每个 GPU 呆板都配备多块 SSD 的环境下,下图示例中,每个 GPU 呆板配有三块 SSD,此中一块 SSD 用作本地缓存,其余两块 SSD 则用作分布式缓存的存储盘。这种环境下,我们推荐一个摆设方式:在一个 GPU 服务器上摆设两个客户端,FUSE daemon 和缓存集群客户端。当推理任务需要读取数据时,它首先会尝试从本地 FUSE 挂载点读取数据。假如本地缓存中没有相应的模型数据,推理任务将通过同一台呆板上的另一个 JuiceFS 客户端访问分布式缓存。完成数据读取后,数据将返回给推理任务,并在缓存集群管理的两块 SSD 及本地 FUSE 挂载点上缓存,以便将来快速访问。

这种在一个 GPU 服务器上摆设两个客户端的做法有两个主要利益:


  • 首先,通过本地缓存,可以尽量减少网络通信的开销,虽然 GPU 服务器间通过高速网卡举行网络通信,但网络通信本身还是会产生大量的开销;
  • 其次,通过缓存集群客户端,可以让推理任务访问别的 GPU 服务器上的数据,实现一个分布式缓存集群的结果。
挑战 2:如何在多云、混合云架构中有效地分发模型数据到各盘算节点?

在多云和混合云架构中,由于数据分散在不同的云平台和数据中央,传统的手动参与、拷贝和迁徙方法不但本钱高,而且管理和维护也较为复杂,包括权限控制在内的各种题目都十分棘手。
JuiceFS 企业版镜像文件系统功能允许用户将数据从一个地区复制到多个地区,形成一对多的复制关系。整个复制流程对用户和应用来说是透明的:只需将数据写入指定区域,系统便会自动规划并复制到别的多个区域。
下图展示了在镜像文件系统中数据写入与数据读取时的流程。图中展示了两个区域:源区域和镜像区域。当数据在源区域写入时,JuiceFS 会自动将数据从源区域复制到镜像区域。

在读取数据时,镜像区域的客户端首先尝试从其地点区域的对象存储中拉取数据。假如数据不存在或因同步延迟未到达,则自动回退到源区域存储,通过备用数据源链路拉取数据。因此,镜像区域的全部客户端最终都能访问到数据,虽然部门数据大概来自备用数据源。

写数据流程示例

这里展示了一个大模型企业实际摆设镜像文件系统的案例,其架构与文章开头展示的典型架构图相似。在图的顶部有一个中央集群,该集群作为数据生产的源头。



  • 步骤 1:写数据。数据首先在中央集群中被创建并写入;
  • 步骤 2:全量镜像元数据。数据生产完成后,将写入到 JuiceFS 中,触发元数据的全量镜像流程。如图所示,数据从中央的 JuiceFS 元数据服务被镜像到一个或多个边沿集群(本例中为三个),使得边沿集群能够就近访问本地集群内的元数据;
  • 步骤 3:预热缓存(可选)。这一步是为了优化数据访问速率。当有新数据添加后,除了复制元数据外,还渴望能够就近访问这些数据。在没有对象存储的环境中,可以结合分布式缓存功能,在每个机房内摆设一个分布式缓存集群。然后通过缓存预热,将新增的数据复制到每个边沿集群的缓存集群中,从而加速数据访问。
读数据流程示例



  • 步骤 1:访问镜像的元数据服务。如上图绿色编号所示,当 GPU 集群需要获取模型数据时,首先会访问镜像的元数据服务;
  • 步骤 2:读取元数据并获取数据。在读取到元数据后,客户端会首先尝试通过机房内的缓存集群获取所需数据。假如之前举行了缓存预热,那么大多数环境下可以直接在机房内的缓存集群中掷中所需的模型数据;
  • 步骤 3:回源数据。假如由于某种缘故原由未能在缓存集群中找到数据,也无需担心,由于全部缓存集群的节点都会自动回源至中央的对象存储桶中获取最终的原始数据。
因此,整个数据读取流程是畅通无阻的。即使部门数据未被预热或新数据尚未预热乐成,也可以通过自动回源的方式,从中央的 JuiceFS 存储桶中拉取数据。
挑战 3:低本钱高效读取海量存量数据

除了多云、混合云架构下数据分发的挑战,还有一个常见的需求,在与多家大模型公司的交换中,我们了解到很多公司渴望将其积累的大量原始数据(如数 PB 级别)直接迁徙到 JuiceFS 中。这种需求增长了大规模数据管理的复杂性,并大概需要举行数据双写等调整,这些都大概影响业务流程的正常运作。
JuiceFS 企业版的「导入对象存储元数据」功能使得企业可以更高效地完成数据导入,同时减少对业务的侵入性。用户无需举行数据拷贝,只需持续导入元数据即可。同时,导入的数据可以通过 JuiceFS 的分布式缓存举行加速,从而提升数据访问速率。下图是该功能的工作流程示意图:

第一步,导入元数据。通过 JuiceFS 的下令行工具,用户可以选择性地导入原始数据桶中的部门数据,而不必导入整个存储桶。这一过程主要通过前缀匹配实现,此步骤仅涉及元数据的导入,不拷贝对象存储中的数据,因此导入流程会很快完成。
元数据导入不是一次性的操纵,随着原始数据的增长或修改,用户可以再次执行增量导入,无需担心重复导入造成额外开销。每次增量导入时,系统只会导入新增或修改的部门数据的元数据,不会重复导入已处理的文件,从而避免额外负担。
第二步,读取元数据。当元数据导入到 JuiceFS 后,应用(比方推理任务)便能通过 JuiceFS 客户端访问这些导入的数据。因此,应用可以立刻开始执行,无需等候原始数据桶中的数据拷贝到 JuiceFS 中。
第三步,读取数据。在推理等场景中,通常会设置分布式缓存以优化数据读取。由于在第一步中仅导入了元数据而未导入实际数据,初次通太过布式缓存读取时将无法直接获取数据。
第四步,回源原始桶并缓存数据。这一步需要通太过布式缓存系统回源到原始数据桶中,从中检索并读取数据。读取完成后,数据会自动缓存到 JuiceFS 的分布式缓存中,这样在后续访问雷同数据时,就无需重新回到原始数据桶中举行数据读取,从而提高数据访问服从。
经过这几个步骤,推理任务便能够快速访问存量数据,并得到高性能分布式缓存的加速结果。
挑战 4:在异构环境中,如何充分利用硬件资源以优化存储和盘算性能?

异构环境涉及到一个系统内部集成多种不同类型或设置的硬件装备,只有充分利用异构的硬件资源才气为企业带来最大价值。在下面这个示例中,我们有三台呆板,每台呆板配备的 SSD 数目和容量如下表所示,根据每台呆板的总存储容量,这三台呆板的缓存容量比例为 1:2:3。
编号SSD 数目单块 SSD 容量(TB)总容量(TB)呆板 1248呆板 22816呆板 33824 默认环境下,JuiceFS 的分布式缓存假设全部呆板的硬件设置是同构的,因此全部缓存节点的权重雷同。在这种设置下,整个系统的性能将被最小容量呆板的容量上限所限制,在这个示例中是 8TB,别的呆板缓存盘无法被充分利用,第三台呆板中甚至有 ⅔ 大概未被利用。
为了避免这种环境,我们引入了「缓存节点权重」的概念,允许用户根据实际环境动态或静态地调整每个 GPU 节点的权重。比方,第一台 GPU 服务器的缓存权重可以设置为默认值 100,第二台为 200,第三台为 300,这些权重与 SSD 容量的比例(1:2:3)相对应。通过这种差别化权重设置,可以更有效地利用各缓存呆板的存储资源,优化整体系统的性能。这种方法为处理不同硬件设置的呆板提供了一个典型的解决方案。
除了上述这个场景外,缓存节点权重还可以应用于别的场景。比方,GPU 呆板轻易出现故障,用户大概每周需要对一两台呆板举行下线和更换硬件等常规运维操纵。因呆板直接停机将导致该呆板上的缓存数据丢失或暂时无法访问,这大概影响整个缓存集群的掷中率。在这个场景中,也可以使用「缓存节点权重」功能,来尽大概减少呆板故障或维护过程中对缓存集群利用率的影响。
将来展望

最后,让我们探究一下将来我们在推理场景以及别的潜伏应用场景中将要举行哪些改进。
首先,引入分布式缓存的多副本特性。目前,分布式缓存系统中的数据通常是单副本情势,意味着假如某台呆板(如 GPU 服务器)意外宕机,该呆板上的缓存数据将因缺乏备份而丢失,从而直接影响缓存掷中率。由于这种环境是突发的,我们无法通过人工干预来徐徐迁徙数据至别的节点。
在这种配景下,单副本缓存将不可避免地影响整个缓存集群的服从。因此,我们正在思量将其从单副本升级为多副本。这种升级的利益显而易见:尽管使用了更多的存储空间,但是可以显著提高呆板频繁故障场景的缓存掷中率和缓存的可用性。
第二点,我们正在探索用户态客户端的实现。当前,基于 FUSE 挂载方式的文件系统虽然能有效地实现文件系统功能,但由于其依靠 Linux 系统内核,涉及用户态与内核态之间的多次切换和数据拷贝,因此带来了肯定的性能开销。尤其在云上的无服务器(serverless)和 Kubernetes 环境中,FUSE 挂载大概无权限使用,这限制了 JuiceFS 的应用场景。
因此,我们正在思量开辟一个纯用户态的客户端,这将是一个不依靠内核态的组件,可以显著低落使用门槛,并在不支持 FUSE 的环境中提供服务。别的,由于避免了内核态与用户态的频繁切换和内存拷贝,这种客户端在性能上也大概有显著提升,特别是在需要高吞吐量的 GPU 麋集型环境中。
然而,这种客户端的一个潜伏缺点是它大概不如 POSIX 接口透明,由于它大概需要用户通过引入特定的库(如 JuiceFS 库)来实现功能,这种方式大概会对应用步伐产生肯定的侵入性。
第三,提升可观测性。鉴于 JuiceFS 架构中包罗多个复杂环节,如从 GPU 呆板到缓存集群,再通过专线回到中央的对象存储,以及缓存预热等,我们计划引入更便捷的工具和方法来加强整体架构的可观测性。这将有助于 JuiceFS 的用户更快更方便地定位及分析题目。将来我们将进一步优化包括分布式缓存在内的各个组件的可观测性,资助用户在出现题目时举行快速的题目排查息争决。
渴望这篇内容能够对你有一些资助,假如有其他疑问欢迎加入 JuiceFS 社区与大家共同交换。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

一给

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表