定义可以拆分的工作单元
写下什么才算一个被接受的结果:一张图像、一份处理过的文档、一组模拟结果,或是一次训练的最终状态。然后问一问,某个单元能否在不等待其他单元的情况下完成计算。两份文档在处理过程中可以是相互独立的,之后却可能依赖一个共同的索引构建步骤。划分方式必须描述这第二个步骤,而不是在并行化的承诺中把它遗忘。
要把计算层面的独立性与业务层面的独立性区分开来。一份输出可以在没有任何技术交互的情况下产生,却在整个批次通过验证之前一直无法使用。因此,要明确计算单元、交付单元和组装规则。这套共同的术语可以避免采购方计算显卡数量,而应用团队却在计算实例数或同一个模型的各个分片。
在相互独立的任务与紧密协作之间做出选择
对于相互独立的任务,每个进程接收自己的输入并产生一份可识别的输出。另一张卡可以执行另一项任务,无需在每一步都同步。当目标关注的是某个时间窗口内完成的工作量时,这种方式很有价值。它不会自动加速一项孤立的任务,而且仍然需要核实数据、存储或授权许可方面的资源争用。
对于协作式的工作,各设备之间会交换数据,或等待某个中间结果。程序必须管理这种分配方式。CUDA 指南指出,利用多个 GPU 涉及上下文、数据分发、启动和通信。这些都属于软件路径和所观察系统的属性;目录中某张显卡的名称并不能证明这条路径已经存在。
| 问题 | 相互独立的任务 | 协作式工作 |
|---|---|---|
| 每张卡接收到什么? | 一项完整的、彼此不同的任务 | 工作的一部分或一个副本 |
| 需要协调什么? | 输入的分配与输出的收集 | 数据交换、顺序与同步 |
| 需要核实哪项收益? | 每个时间窗口内被接受的结果数量 | 在耗时或容量相应调整后得到相同结果 |
| 需要预判哪种失败? | 一项孤立的任务或一次孤立的发布 | 某个参与者不可用对整体造成的影响 |
不要将副本复制与内存分片混为一谈
一个模型的多个副本并不意味着其参数被拆分到各张卡上。PyTorch DistributedDataParallel 在各进程之间同步梯度,而各进程训练的是各自的本地模型。因此,仅凭这个名称并不能推断出一个对单张卡而言过于庞大的模型可以在多张卡上运行。分片机制需要有自己的文档和独立的验证。
每张卡的内存必须覆盖软件实际放入其中的内容:数据、模型状态、临时空间以及可能的数据交换。峰值占用可能随设置和处理阶段而变化。请按设备逐一记录。把标称容量简单相加,会掩盖一种不均衡:一张卡内存不足,而其他卡仍有富余。仅凭整批的总容量不足以接受该方案。
虚构示例:分配八项相互独立的转换任务
虚构团队「Index des ouvrages」正在准备八项文档转换任务。在其工作假设中,每项转换占用一张卡十二分钟,其中包含加载和输出。一项任务可以单独在一张卡上完成,在最终组装之前无需任何数据交换。这些时长仅用于构建推理过程:它们并不描述 Capordia 所提供的任何实际运行或 GPU 性能。
使用一张卡时,八个连续任务代表 8 × 12 = 96 分钟。使用两张卡并均衡分配,每张卡四个任务,可并行部分理论上为 48 分钟。如果最终组装在独立节点上需要十分钟,完整路径分别变为 106 或 58 分钟,不含出发前的等待时间。该计算假设两张卡不会拖慢彼此的加载。
| 组织方式 | 可并行部分 | 组装 | 计算时长 |
|---|---|---|---|
| 一张卡,八个任务 | 96 分钟 | 10 分钟 | 106 分钟 |
| 两张卡,每张四个任务 | 48 分钟 | 10 分钟 | 58 分钟 |
揭示可能抵消这一理论收益的因素
在同一示例中,各文档的大小可能并不相同。将四个最长的任务分配给一张卡,会让另一张卡在流程末尾等待。按可用性依次分配可以改善均衡,但这需要可靠的分配机制和准入策略。关于队列的指南讨论了这一组织方式;本计算并不证明它已经部署。
存储也可能成为主要的共享资源。两个进程读取相同数据或同时写入大量结果,未必能获得双倍的吞吐量。还要检查工具和许可的并发限制。如果不可并行部分增加,请重新计算完整时间表。某一阶段节省的时间不应掩盖在其他地方增加的延迟。
对于分布式工作,获取真实拓扑
询问哪些卡可见、它们如何通信,以及哪些主机资源被其进程共享。检查所使用的环境可访问的设备,而不仅仅是从管理控制台查看。CUDA 指出,访问另一颗 GPU 的内存尤其取决于拓扑和系统能力。模型支持某项功能,并不证明机器上存在预期的链路。
保留一份简单的数据流图:输入、涉及的卡或进程、交换、最终汇总和输出。对每个箭头,确定它是否经过主机内存、GPU 之间的链路或网络。这一视图用于选择验收检查。它不强制采用某项特定技术,也不会把多 GPU 需求变成对特定拓扑的承诺。
在不改变预期结果的前提下比较两种组织方式
准备一个具有代表性的小型语料库,并在您获准使用的目标上先运行基准组织方式,再运行候选组织方式。保留版本、设置、预期质量和组装规则。比较到验收结果所需的时间、每张卡的峰值内存、错误和共享资源的消耗。将观察与估算分开;提出的命令不等于已经获得的结果。
尤其要确认验收输出的数量保持不变,且没有任何输入被遗漏。对于对运算顺序敏感的计算,应选择有依据的容差,而不是武断地要求完全相等。以不同质量更快完成的组织方式解决的是另一个问题。还要保留一个共享并无优势的案例:这一边界比脱离共同负载的显卡排名更能说明选择的理由。
将选择转化为所需容量
最后写明同时任务的数量、每项任务所需的卡,以及不可或缺的条件。一项任务分摊到两张卡和两项各用一张卡的任务,代表两种不同的组织方式,即使卡的总数相同。所选的配置必须能够支持所需的组织方式;不要从标称总数出发,再为它凭空设想用途。
目录中标注的是显卡批次。一个 B200 批次包含两块各 180 GB 的 GPU;这一组成方式并不保证某个软件会将它们当作单一内存来使用。下一步是将需求与批次对应起来,然后接收实际所需的各项属性。在关键条件得到核实之前,时间表、成本和决策都仍是暂定的。
决策要点
两块 GPU 是否总是比一块更快?
不是。收益取决于可并行化的比例、数据交换以及共享资源。对于无法拆分的一项独立任务,第二块显卡可能始终处于闲置状态。请在同一套明确的测试方案下,比较达到同一可接受结果所需的时间。
两块显卡的批次是否会让我的程序可用的内存翻倍?
并不会自动翻倍。每个设备都有自己的内存,程序必须自行分配其状态或数据。反过来,复制一个模型可能会将该状态中的很大一部分重复存放。请核实软件的机制以及每块显卡的峰值占用。
何时应当从独立任务入手?
当每个单元都可以单独计算,且所追求的目标是完成更多单元时。仍然需要验证任务分配、负载均衡和最终组装,不能假定存储和许可证会自动随之到位。