运用竞价实例等经济高效的资源,并管理包括 GPU 在内任何硬件固有的不可靠性,是经济地运行大型 AI 系统的重要方面。扩散模型推理通常每个请求的处理时间较长,尤其容易受到 GPU 故障或竞价实例被回收的影响。因此,在部署架构中构建容错能力不仅是值得做的,更是提供可靠服务所必需的。理解故障模式两种主要故障情况需要不同的处理策略:GPU 硬件/驱动故障: GPU 可能因过热、硬件缺陷、驱动崩溃或供电不足等多种原因意外发生故障。当分配给推理任务的 GPU 无响应或报错时,其上运行的进程通常会突然终止。当前推理任务的进展会丢失。竞价实例中断: 云提供商以大幅降低的价格提供备用计算能力,即“竞价实例”。其权衡在于,当提供商需要将此容量用于按需用户或其他目的时,他们可以几乎不经警告(通常只有两分钟或更少)地回收此容量。这种中断并非传统意义上的“故障”,但会导致实例及其上运行的所有进程终止。这些中断的频率因实例类型可用性、需求和出价(如果适用)而异。两种情况都会导致可能长时间运行的图像生成任务中断,如果处理不当,会影响用户体验并浪费计算资源。处理 GPU 故障的策略尽管比竞价中断的频率低(希望如此!),GPU 故障需要检测和恢复机制。健康检查: 为推理工作器实施全面的健康检查。除了基本的进程健康检查外,还要包含专门探测 GPU 状态的检查。可以调用 nvidia-smi 等工具检查 GPU 温度、内存使用和响应能力。Kubernetes 的存活探针和就绪探针应包含这些 GPU 特定的检查。失败的 GPU 检查应将 Pod 标记为不健康,从而促使其被替换。编排与自动替换: 运用容器编排器(如 Kubernetes)或云提供商的托管实例组(例如 AWS 自动扩缩组、GCP 托管实例组)自动检测失败的实例或 Pod(通过失败的健康检查识别),并用新的、健康的实例替换它们。冗余: 在不同节点(以及可能的可用区)上运行推理服务的多个副本。负载均衡器分发传入请求。如果一个实例或 GPU 发生故障,编排器和负载均衡器会确保请求路由到健康的副本,从而最大程度地减少服务中断。监控和告警: 将 GPU 监控整合到可观测性堆栈中。追踪 GPU 利用率、内存使用、温度和功耗等指标。监控系统日志中的驱动程序错误或特定硬件错误代码(例如 nvidia-smi 报告的 ECC 错误)。为异常读数或错误模式设置告警,以便进行主动调查和可能的硬件替换。处理竞价实例中断的策略竞价实例需要一种积极主动的方法,以平稳关机和工作负载重新调度为核心。检测中断信号: 云提供商提供机制,用于通知实例即将终止。元数据服务: 大多数提供商都公开一个元数据端点(例如 AWS 上的 http://169.254.169.254/latest/meta-data/spot/termination-time),应用程序可以定期轮询。如果此端点返回时间戳,则实例已计划终止。操作系统事件: 某些系统可能在关机前不久收到 SIGTERM 信号。 您的应用程序需要迅速检测到此信号。平稳关机逻辑: 检测到即将中断时:停止接收新工作: 实例应立即向负载均衡器或队列监听器发出信号,表明它不再接收新请求。完成进行中的工作(如果可能): 考虑到通知时间很短(通常为 2 分钟),完成一项可能需要 30 秒到几分钟的扩散任务通常是不可能的。重点转变为防止数据丢失并确保任务可以重试。交回/重新入队当前任务: 最重要的一步是确保当前正在处理的任务不会丢失。如果使用消息队列,工作器在中断时绝不能确认(ACK)消息。相反,它应该要么显式地将消息交回队列(如果消息系统支持可见性超时),要么直接终止,让队列的可见性超时过期,以便另一个工作器可以接收该任务。检查点(高级): 对于非常特定、长时间运行的生成过程(对于典型推理较不常见),您或许可以设计一个系统,在收到终止信号时将中间状态(例如,扩散步数、噪声状态)保存到持久存储。新的工作器可能会加载此状态并恢复。这会增加很大的复杂性和开销,并且对于标准无状态推理 API 通常不实用。清理退出: 执行所有必要的清理并退出。任务排队和重试: 这是扩散模型可靠使用竞价实例的基础。将系统围绕消息队列构建(例如 AWS SQS、Google Pub/Sub、RabbitMQ、Redis Streams)。API 端点将生成请求放入队列。无状态 GPU 工作器轮询队列以获取任务。如果工作器中断,任务最终会在队列中再次可见,并由另一个工作器(可能在不同的竞价实例上,甚至是按需实例上运行)接收。在队列上配置适当的可见性超时,考虑到最大预期处理时间加上一个缓冲。实现幂等工作器,或者设计任务,使得多次重新处理同一消息(在处理后但在确认前发生故障的情况下)不会产生不利影响。多样化和实例混合:实例类型多样化: 请求多种适合的 GPU 实例类型的竞价容量。这降低了某种特定类型短缺影响整个实例组的可能性。可用区多样化: 将竞价请求分散到区域内的多个可用区。混合方法(竞价 + 按需): 维护少量按需 GPU 实例的基础实例组,以保证最低服务水平,并在竞价容量暂时不可用时处理即时重试。根据队列深度动态调整竞价实例组的规模。云提供商服务(如 AWS EC2 Fleet 或具有混合实例策略的自动扩缩组)可以帮助自动管理这种混合。弹性架构模式使用消息队列的解耦架构对于处理 GPU 故障和竞价中断都非常有效。digraph G { rankdir=LR; node [shape=box, style=rounded, fontname="sans-serif", colorscheme=blues3]; edge [fontname="sans-serif", color="#495057"]; subgraph cluster_api { label = "API 层"; color="#dee2e6"; style=filled; api [label="推理 API\n(例如 FastAPI)", shape=component, color="#1c7ed6"]; } subgraph cluster_queue { label = "消息系统"; color="#dee2e6"; style=filled; queue [label="请求队列\n(例如 SQS, RabbitMQ)", shape=cylinder, color="#74c0fc"]; } subgraph cluster_workers { label = "工作器集群"; color="#dee2e6"; style=filled; subgraph cluster_spot { label="竞价实例"; style=dashed; bgcolor="#e9ecef"; spot_worker [label="GPU 工作器\n(处理中断)", shape=component, color="#40c057"]; spot_worker_2 [label="GPU 工作器\n(处理中断)", shape=component, color="#40c057"]; labeljust="l"; /* Align subgraph label left */ } subgraph cluster_ondemand { label="按需实例"; style=dashed; bgcolor="#e9ecef"; ondemand_worker [label="GPU 工作器", shape=component, color="#fab005"]; labeljust="l"; /* Align subgraph label left */ } } subgraph cluster_storage { label = "输出"; color="#dee2e6"; style=filled; storage [label="输出存储\n(例如 S3, GCS)", shape=folder, color="#adb5bd"]; } api -> queue [label=" 入队任务"]; queue -> spot_worker [label=" 出队任务"]; queue -> spot_worker_2 [label=" 出队任务"]; queue -> ondemand_worker [label=" 出队任务"]; spot_worker -> storage [label=" 写入结果"]; spot_worker_2 -> storage [label=" 写入结果"]; ondemand_worker -> storage [label=" 写入结果"]; spot_worker -> queue [label=" 交回任务\n(中断时)", style=dashed, color="#f03e3e"]; spot_worker_2 -> queue [label=" 交回任务\n(中断时)", style=dashed, color="#f03e3e"]; }使用消息队列的解耦架构。API 服务器将任务入队。竞价和按需 GPU 工作器的混合集群将任务出队。竞价工作器设计为在中断时将任务交回队列,从而确保任务由另一个可用的工作器完成。这种设计确保任何单个工作器的故障或中断都不会使系统停顿。队列充当缓冲区,并使得任务可以由其他可用工作器透明地重试。通过实施健康检查、依靠编排进行自动替换、为竞价实例设计平稳关机、以及围绕消息队列构建系统以实现解耦和重试,您可以构建一个扩散模型部署,该部署既经济高效,又能抵御在大型云环境中遇到的不可避免的故障和中断。