在扩容 GPU 池之前,先衡量实际产出
Before you expand your GPU pool, measure the outcome
在 Kubernetes 上运行 AI 工作负载的团队应先明确每个工作负载的截止时间、运行时长和可中断性,再用错峰调度、Kueue 准入控制等手段压降峰值需求,而不是直接扩容 GPU 池。文章指出 GPU 被分配、GPU 繁忙与工作负载产出有价值结果并不等同,高 GPU 活跃度也不能说明还有多少可用吞吐,需用代表性负载测试测出可持续容量。还可将 OpenCost 的分配 API 与推理成本追踪(含每百万 token 成本)同服务遥测、产出记录关联,计算每个已验证产出的成本。
正文 · AI 翻译
对于在 Kubernetes 上运行 AI 工作负载的团队来说,GPU 池已全部分配且批处理作业队列不断增长,可能让扩容看起来是显而易见的下一步。但队列增长也可能指向时序、服务容量或模型与硬件选择方面的问题。在扩容 GPU 池之前,团队应明确成功的定义、必须完成的时间以及交付的成本。
“一块已分配的 GPU、一块繁忙的 GPU,和一个正在产出有价值结果的工作负载,并不是一回事。”
这首先要区分一点:一块已分配的 GPU、一块繁忙的 GPU,和一个正在产出有价值结果的工作负载,并不是一回事。理解它们之间的关系,可以帮助团队在真正需要额外容量之前,更有效地利用现有容量。
从结果和截止时间出发
审视工作负载及其支撑的底层用例。客服聊天机器人可能需要全天候的推理容量,而模型评估作业的结果可能只需在下一次内部发布同步之前准备好。将工作负载归入“推理”和“训练”等宽泛类别,并不能决定紧迫性。有些批处理推理可以等待,而训练作业可能有硬性截止时间。
对每个工作负载,记录其截止时间、预期运行时长、资源需求以及是否允许中断。同时定义什么才算有价值的输出。推理服务应具备针对具体任务的质量阈值和延迟目标。仅仅完成请求或返回有效的 JSON 响应,并不能说明工作负载是否达成了目标。
将启动时间的灵活性与中断容忍度分开考虑。一个可以等待启动的作业,可能仍然需要不中断地运行。
在扩容 GPU 池之前先利用调度灵活性
假设中午到下午 5 点有四块兼容的 GPU 可用于批处理工作。四个独立的评估作业在中午就绪。每个作业需要两块 GPU 运行一小时,所有结果都须在下午 5 点前交付。
立即启动全部四个作业需要八块 GPU。但如果在中午运行两个、下午 1 点运行两个,就能在下午 2 点前用已有的四块 GPU 完成全部四个作业。假设运行时长和配套资源保持不变,两种调度方案都消耗八 GPU 小时,不含启动开销。
“错峰调度可以降低峰值需求。作业仍能按时完成,无需扩容 GPU 池。”
错峰调度可以降低峰值需求。作业仍能按时完成,无需扩容 GPU 池。在为了清空队列而配置更多 GPU 之前,先考虑启动时间上还有多少灵活性。
Kueue 等工具提供了准入控制点,利用配置的配额和策略来决定何时接纳工作。团队仍需决定如何表示和执行截止时间与工作负载要求。灵活的排队可以支持容量规划,并减少为了提前启动作业、随后又将其抢占的需求。
衡量部署能够维持多少有效工作
灵活的调度可以缓解容量约束。但推理团队还必须审视模型和服务配置与这项工作的匹配程度。
高 GPU 活跃度并不能确定还有多少额外吞吐可用。Nvidia 的性能分析文档解释说,流式多处理器活跃度可能包含正在等待内存的 warp。运行中请求、等待中请求和缓存占用等服务指标可提供背景信息,而抢占计数有助于解释行为。在 vLLM 中,KV 缓存使用率衡量的是已占用缓存块的比例,但它并不直接衡量总服务容量。
“高 GPU 活跃度并不能确定还有多少额外吞吐可用。”
用具有代表性的负载测试来衡量可持续容量。保持模型、硬件、服务设置和请求组合不变。然后提高到达率,观察吞吐、质量和延迟。在仍满足工作负载要求(包括错误上限和选定的延迟百分位数)的前提下所能维持的最高速率,可提供有用的容量估计。对于交互式生成,要包含首 token 时间和后续 token 交付时间,而不仅仅是平均完成时间。DistServe 说明了为什么应根据延迟等应用级目标来评估服务容量。
将生产流量与该测试容量进行比较。缓存占用低可能值得进一步调查,但声称吞吐量高出十倍则需要吞吐测试。短暂的队列可能代表临时突发,而持续存在的队列可能需要诊断。两者单独都无法确定限制性资源。
将 OpenCost 数据与已验证的结果关联起来
FinOps 社区围绕成本和有效结果来界定 AI 效率。对于 AI 工作负载,当成本与基础设施帮助交付的结果相关联时,成本才更有用。Kubernetes 团队可以通过结合工作负载成本、服务行为和应用程序结果,将这种关系具体化。
使用 OpenCost 的分配 API 按既定间隔获取工作负载成本,然后通过工作负载标识和时间戳将该数据与服务遥测和结果记录关联起来。OpenCost 还提供可选的推理成本追踪,包括每百万 token 成本。计算每个结果的成本时,应计入适用的 GPU、CPU、内存及其他基础设施成本,并记录共享成本和空闲成本的分摊方式。OpenCost 之外的相关成本应单独添加,避免重复计算。
一个有用的指标是每个已验证结果的成本:总可归属成本除以满足既定质量要求并在规定时间内交付的结果数量。在重试、失败、启动和空闲时段对总成本有贡献时,应将其计入。最终业务结果只计一次。当正确性通过抽样评审来估计时,应记录抽样方法和不确定性。
OpenCost 提供成本分配的详细信息;应用程序提供结果定义和评估证据。容量仍然需要单独测量。OpenCost 提案 3915 探索将服务引擎遥测纳入成本模型。该提案仍为草案,而非已发布的饱和度或正确性评分。
检验闲置容量是否物有所值
考虑一个示例服务:每小时接收 1,000 个任务,正确性要求为 98%。一个正确率达到 90% 的小模型并不适用,即使其 GPU 便宜且完全占用。
一个更强的模型可能以每小时 2 美元的成本产出 990 个正确且及时的结果,同时仅使用其测试服务容量的一小部分。其成本约为每 1,000 个合格结果 2.02 美元,而这份闲置容量可能是满足质量要求并吸收突发活动的可接受代价。
下一个测试是:更小的 GPU、更少的副本或不同的批处理设置能否保持这些结果和所需的可靠性。如果某个经过测试的配置以 1.50 美元的成本产生同样的 990 个合格结果,那么每 1,000 个合格结果的成本将降至约 1.52 美元。节省来自用更少的资源交付相同的结果。在不改善结果的情况下提高原 GPU 的利用率,不会带来可比的价值。
“目标是以可辩护的成本交付所需结果的部署,并留有足够的余量来满足其需求。”
当两个模型都满足最低要求时,如果额外的质量改进能减少后果严重的错误或减少人工审核,那么它可能值得更高的成本。请将该价值与实际需求进行比较。当所比较的结果具有相似的价值和错误后果时,每个正确结果的成本最为有用。
一次只改变一个主要变量,然后在代表性需求下比较成本、已验证结果、延迟和截止时间达成情况。为突发流量和故障保留容量,并确认低活动量对应的是可用容量。独占分配给一个 Pod 的 GPU 在释放之前不能重新分配给另一个 Pod。
然后,团队可以选择证据支持的变更:延迟灵活作业、改进批处理、调整部署规模、选择不同的模型,或配置额外的 GPU。目标是以可辩护的成本交付所需结果的部署,并留有足够的余量来满足其需求。
本文《在扩容 GPU 池之前,先衡量实际产出》首发于 The New Stack。