跳到内容

GPU与Altair网格发动机共享 - 第一部分

GPU与Univa网格引擎共享
NVIDIA V100张量核心GPU

越来越多地,GPU功率从结构分析到分子建模的各种HPC和AI工作负载。2020年4月,Univa在HPC调查中的GPU状态发现,83%的调查受访者报告了GPU,在生产中完全62%。

支持gpu的云实例的成本大约是不支持gpu的按需云实例的10倍[一世].考虑到GPU工作负载的普遍以及GPU服务器和云实例的高成本,企业正在寻找使其GPU投资最大化的方法。

随着GPU变得越来越强大,提供了更多的内核和内存,并不是每个工作负载都需要独占访问GPU。共享GPU可以带来更好的GPU利用率、更低的成本和更好的工作负载吞吐量。

调度GPU工作负载是一个复杂的主题,其中概念彼此构建。我决定将这个主题拆除成一系列简短的文章而不是涵盖这一点。第一篇文章从GPU调度的基础开始。未来的文章将涵盖包括GPU共享,处理异构GPU节点,拓扑面具和其他高级Altair网格引擎功能的主题

在我们开始之前,先说说GPU共享

正如大多数开发者所知,GPU共享并不是奇迹般地发生的。它需要开发人员的努力以及与系统和集群管理员的协调。GPU共享通常便于使用NVIDIA多流程服务(MPS)。MPS基本上是CUDA运行时的替代,二进制兼容的实现,便于在同一GPU上运行多个CUDA内核(以及因此应用程序)。bob电竞官方使用MPS,写入CUDA API的多个Linux应bob电竞官方用程序可以使用合作多任务处理有效地共享相同GPU的资源。基于MPS的GPU资bob电竞官方源共享的候选应用程序往往是具有少量块的每个网格的应用程序。

MPS由控制守护程序进程(负责启动和停止MPS服务器),服务器进程(为GPU提供共享连接的Linux客户端),以及可访问任何CUDA应用程序的MPS客户端运行时。对于GPU共享工作,GPU需要处于默认模式(可通过以下配置nvidia-smi命令)。

随着Volta系列GPU(V100)的公告,NVIDIA推出了新的MPS功能,使GPU共享更容易,并增加客户之间的隔离。具体而言,每个Volta MPS客户端都拥有自己的地址空间,并且可以直接向GPU提交工作,而无需通过MPS服务器。

您可以通过阅读NVIDIA的“有关NVIDIA的多流程服务”的更多信息CUDA多进程服务概述.该文档包含了关于哪些应用程序适合与MPS一起使用以及存在哪些限制的有益考虑。bob电竞官方在考虑在工作负载管理器(如Altair Grid Engine)的环境中进行GPU共享之前,开发人员和管理员应该首先确保MPS工作负载共享工作在工作负载管理环境之外。NVIDIA文档解释了如何编写脚本在工作负载管理器(如Altair Grid Engine)的控制下启动共享GPU工作负载。

随着NVIDIA最新的NVIDIA A100图形处理器的发布,NVIDIA推出了一个新的多实例图形处理器(MIG)功能。这个特性提供了更好的GPU资源共享,允许NVIDIA A100 GPU被安全的分区和共享,最多七个CUDA应用实例。MIG的一个关键优势是GPU代码可以在同一个GPU上同时运行——真正的多任务处理。你可以了解更多关于米格在米格用户指南

综上所述,应用程序对gpu资源共享的要求是复杂的。它们将取决于GPU的生成以及应用程序是如何构建的。bob电竞官方调度问题非常具有挑战性,所以在本文和后续文章中,我们将从开发者的角度撇开GPU共享的复杂细节。在本系列文章中,我们从工作负载管理的角度关注GPU共享。

回到基础 - 调度GPU工作负载

在我们继续讨论更复杂的示例之前,有必要回顾一下Altair Grid Engine中如何处理可消耗的资源。

在共享群集中,消耗资源是资源,曾经使用的资源,对其他用户和应用程序不可用。bob电竞官方消耗性资源包括主机上的GPU,内存和作业插槽等内容。其他资源属性是非耗材。这些包括在服务器上可用的计算机架构,主机名和下载Docker映像等资源属性。

在Altair Grid Engine中,复杂资源属性提供有关用户提交作业时可以请求的资源的信息。资源可以在整个集群范围内存在,可以与特定的集群主机关联,也可以与队列关联。命令QCONF-CO.(show complex)提供了Altair Grid Engine中预定义的复杂资源列表。为了调度GPU资源和工作负载,我们需要定义一个新的复杂配置称为GPU..这qconf mc命令(修改复杂)使我们能够仔细阅读和编辑现有的复杂资源定义,并添加新的GPU.条目如图所示:

如果是GPU.属性对已经存在的复杂资源项进行检查和编辑QCONF -MCE.命令。

定义的每个字段的含义GPU.下面提供复杂的资源条目。这复杂的(5)地图页面描述了Altair网格引擎复杂配置的文件格式。

  • 名称指资源的名称(在这种情况下GPU)
  • 快捷方式是一个缩写名称,可以选择性地与Altair Grid Engine命令一起使用,以引用资源
  • 类型RSMAP(资源映射)是定义的专用数据类型sge_resource_map(5)
  • 指的是关系运营商。象征< =(小于或等于)表示用户请求的值必须小于或等于队列中配置的值。换句话说,只有当请求的GPU资源的数量小于或等于可用的GPU资源的数量时,才会访问主机上的GPU
  • 要求消耗品属性表明GPU资源均可要求和消耗
  • 默认不用于RSMAP类型的消耗资源
  • aapre.(先发制后可用)意味着如果作业被抢占,则将报告资源。

配置GPU执行主机

我们有一个小型Altair网发引擎群集,在有三个主机的AWS中部署。ip - 172 - 31 - 30 - 47是主主机和执行主机。其他两个主机仅是执行主机。

在我们的示例中,假设我们的两个执行主机(172-31-19-231172.31.19.95)每个有四个物理GPU。目前,我们不关心GPU模型或能力。我们将在未来的例子中达到这一点。

使用qconf加修改每个包含gpu的执行主机的属性并添加值Gpu =4(0 1 2 3)complex_values如所示,在任何其他属性旁边一行。

这个语法告诉Altair Grid Engine主机上有4个可用的gpu。括号内提供了一个简单的资源映射。本例中,资源映射中的每一项都对应主机上的GPU设备ID。即使设备型号不同,NVIDIA也会为每个物理GPU分配简单的数字设备id。

笔记:读者不应该假设由此返回的GPU设备nvidia-smi指令对应于实际的CUDA设备ID。这是因为NVIDIA默认订购了CUDA设备ID,而不是基于PCI_BUS_ID的订购设备。这在这里的CUDA文档中解释了这一点https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#env-vars)。虽然在主机上的所有GPU设备都是相同类型的情况下,但这并不重要,但它在混合GPU环境中变得重要。当我们查看混合GPU类型时,我们将解释如何在本系列中的第三篇文章中处理这一点。

我们可以将上面的相同更改与执行主机进行相同的更改IP-172-31-19-95它也有四个图形处理器。

一旦我们更新complex_values在每个执行主机上,我们可以使用QHOST -F GPU.命令列出具有可用GPU资源的主机,确认更新成功。

hc: gpu = 4与每个执行主机关联,指示每个GPU云实例都有四个主机级,可用的资源。

向群集提交GPU应用程序bob电竞官方

如果没有Workload Manager,用户需要决定每个GPU手动运行的位置。即使在具有两个主机和8个GPU的小型集群上,这也很快就会变得乏味 - 特别是当多个用户或组尝试访问相同的资源时。

而不是硬代码每个GPU应用程序使用的GPU设备,更好的做法是使用使用的CUDA环境可见的物理GPU设备CUDA_VISIBLE_DEVICESshell变量。如果我们有四个物理GPU,例如(0 1 2 3),我们希望使用第三个设备(2)我们可以简单地设置CUDA_VISIBLE_DEVICES = 2并导出shell变量,以便对运行GPU作业的子进程可见。当用户将作业提交给Altair网格引擎时,它们表示其作业需要使用资源需求字符串的GPU数,如图所示:

在上面的示例中,我们在主机上开始交互式会话,并指出我们需要访问单个GPU(- l gpu = 1)。

Altair Grid Engine知道哪些主机拥有gpu,以及当前每个主机上哪些作业正在消耗gpu。调度一个主机和GPU资源,并将其ID放在“热授予资源”(HGR) shell变量中,该变量对应于资源名(在本例中)$ sge_hgr_gpu.)在预定主机上的作业上下文中。

在上面的示例中,我们可以通过远程shell会话检查shell变量的值(QRSH)并确保我们被授权访问执行主机上的GPU设备0IP-172-31-19-231.我现在独家使用了GPU,调度程序将防止其他作业在我们终止会话之前使用此GPU。

一个简单的GPU调度示例

要说明如何在脚本中运行GPU应用程序,我们创建一个名为的脚本gpu_job.sh.如图所示。

当脚本在Altair Grid Engine选择的主机上启动时,它要做的第一件事就是填充变量CUDA_VISIBLE_DEVICES使用Altair网格引擎选择的“热授子资源”。这会限制CUDA应用程序,使用Altair网格引擎选择的GPU。

笔记:在未来的一篇文章中,我们将学习高级Altair网格引擎的功能,其中CUDA_VISIBLE_DEVICES可以由Altair网格引擎自动设置。

我们可以使用QSUB.如图所示,指示我们的应用程序需要单个GPU:

我们可以使用qstat.命令查询上面提交的作业状态,显示作业的资源映射。这表明在主机上选择GPU设备0IP-172-31-19-95.EC2.INTERNAL.

把它们放在一起

当许多用户提交具有不同资源需求和优先级的不同作业时,使用调度器的能力变得显而易见。

我们可以通过一个简单的示例说明Altair Grid Engine如何跨集群节点提供对gpu的适当访问。我们创建了一个脚本,连续快速地提交与上面示例相同的10个GPU作业的请求。

运行此命令将提交10个GPU作业:

假设群集中没有在群集上运行其他工作,运行qstat.要显示Altair网格引擎作业的状态,将显示以下内容[II]

请注意,三个节点集群中只有8个GPU,因此每个作业在主机上分配了物理GPU,并且在使用所有GPU时,其他提交的作业在队列中绑定。跑步QHOST -F GPU.表明我们现在正在使用的所有GPU资源(hc: gpu = 0意味着没有可用GPU)。

既然我们已经显示了GPU感知计划的基础知识,我们可以进入更复杂的例子。

在本系列的下一篇文章中,我们将扩展此示例,并展示我们如何虚拟化GPU资源并在同一设备上运行多个GPU作业。


[一世]https://aws.amazon.com/ec2/pricing/on-demand/具有32个英特尔Skylake VCPU的P3.8xlarge服务器,244个内存和4 x NVIDIA Tesla V100 GPU的需求量为12.24美元/小时。具有32个VCPU,64个GIB和NO GPU的计算优化的C6G.8xlarge实例$ 1.088 /小时。

[II]在本例中,我们使用单个vCPU t2_micro实例来最小化云资源的成本。默认情况下,每个vCPU主机上只允许执行一个作业,因此我们修改了默认的all。q配置允许每个主机有4个作业插槽,这样所有4个GPU资源都可以被消耗。(qconf mq all.q)