Skip to main content
Version: v0.7

Inference Resilience Operator (IRO): automated hardware fault recovery for wide-EP deployments

Summaryโ€‹

Add a new Kubernetes-native component to llm-d - the Inference Resilience Operator (IRO) - that automatically coordinates hardware fault events with the inference engine, sequencing the right engine-side response and infrastructure-side recovery action to minimize serving interruption and restore full capacity without manual intervention.

Motivationโ€‹

Production llm-d deployments running wide Expert Parallelism across multiple nodes face a class of hardware failures that no existing component handles end-to-end. When a hardware fault occurs - an accelerator error, a NIC failure, a kernel panic - two things must happen in a specific order: the inference engine must be told to stop routing traffic to the affected rank and drain in-flight requests, and the infrastructure layer must execute the appropriate recovery action (reset the device, reboot the node, or replace the node entirely).

These two concerns are completely decoupled today. Infrastructure fault detection agents can cordon and drain nodes but have no awareness of the inference engine running on them. The inference engine detects internal failures and exposes recovery APIs but has no awareness of what the infrastructure layer is doing. No component coordinates between them.

The consequence is a choice between two bad outcomes: the engine crashes and the entire instance restarts with minutes of full downtime and all in-flight requests dropped, or an operator is paged to manually sequence the recovery steps.

Every vLLM fault tolerance RFC published in the past few months - #27866, #27774, #27908, #20323, and #28243 - explicitly assumes an external orchestrator will own this coordination. None of them build it. IRO is that component.

Goalsโ€‹

  • Automatically coordinate engine-side response and infrastructure-side recovery for hardware faults, without manual operator intervention.
  • Match recovery action to fault severity - a transient device error must not trigger the same engine response as a node replacement.
  • IRO's sole responsibility is engine coordination, with a strong sequencing guarantee: IRO acts on the engine before or in parallel with infrastructure recovery, and resumes the engine only once infrastructure recovery is confirmed complete. The sequencing contract between the two layers is the core value.
  • The infrastructure recovery controller owns all fault-to-action mapping and operator override logic. IRO trusts the resolved action it receives.
  • Restore full serving capacity automatically after infrastructure recovery completes.
  • Work identically across GKE, EKS, bare-metal, and on-premises deployments.
  • Work with any inference engine (initially focusing on vLLM) via swappable adapters.

Non-Goalsโ€‹

  • IRO does not perform fault detection. It consumes signals from existing infrastructure agents.
  • IRO does not decide what recovery action to take for a given fault code, and does not provide an operator policy override mechanism. Both belong to the infrastructure recovery controller.
  • IRO does not execute cloud-provider-specific recovery actions directly. It coordinates the engine while the infrastructure recovery controller executes the action.
  • IRO does not handle planned node maintenance or lifecycle events in v1.
  • IRO does not implement general cluster autoscaling. IRO scales the inference serving group only in response to hardware faults, never in response to load.

Proposalโ€‹

IRO sits between the infrastructure layer and the inference engine. When a hardware fault occurs, the "infrastructure recovery controller" creates a RecoveryRequest CRD (a new CRD introduced by this proposal) carrying the resolved recovery action. IRO watches RecoveryRequest, coordinates the engine-side response, and restores serving capacity once infrastructure recovery completes.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Infrastructure layer โ”‚
โ”‚ Cloud agents ยท on-prem monitors ยท hardware fault detectors โ”‚
โ”‚ Infrastructure recovery controller โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ RecoveryRequest CRD โ”‚ RecoveryRequest status
โ”‚ (write) โ”‚ (read)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Inference Resilience Operator (IRO) โ”‚
โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ InferenceReconciler โ”‚ โ”‚ Rank topology map โ”‚ โ”‚
โ”‚ โ”‚ state machine โ”‚ โ”‚ nodeName + deviceID โ†’ rank โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚
โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ vLLM EngineAdapter (implements EngineAdapter interface) โ”‚ โ”‚
โ”‚ โ”‚ Discovers vLLM API server โ”‚ โ”‚
โ”‚ โ”‚ HTTP client โ†’ vLLM service endpoint โ”‚ โ”‚
โ”‚ โ”‚ ZMQ SUB โ†’ vLLM fault notify port โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ HTTP to engine โ”‚ ZMQ fault events
โ”‚ API server โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Inference engine โ”‚
โ”‚ API server ยท ClientSentinel ยท EngineCore โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The "infrastructure recovery controller" in this context is a cloud provider specific or vendor specific component (e.g., a GKE node repair daemon, or a custom controller) that watches for hardware errors, then creates a RecoveryRequest CR in Kubernetes. The infrastructure recovery controller owns the fault-to-action mapping and all operator override logic for the infrastructure layer. IRO trusts requestedAction on RecoveryRequest as the final decision and coordinates the engine-side response accordingly. IRO will ship a reference implementation of the infrastructure recovery controller but the interface is open to any Kubernetes provider.

Engine recovery tracks are inferred from requestedAction on RecoveryRequest:

  • RESET_DEVICE โ†’ Track A: pause engine, reset device, resume engine (seconds)
  • REBOOT_NODE โ†’ Track B: pause engine, reboot node, resume engine (minutes). For long reboots where serving at reduced capacity is preferable, operators can configure the infrastructure recovery controller to use REPLACE_NODE instead.
  • REPLACE_NODE โ†’ Track C: pause engine, scale down, replace node, scale up (many minutes; serves at reduced capacity during replacement)

All engine-specific logic is encapsulated in swappable EngineAdapter implementations. The vLLM adapter is the initial implementation, targeting the fault tolerance and elastic EP APIs being developed in RFC #27866 / PR #34833, RFC #28243, and RFC #20323.

User Storiesโ€‹

As an inference platform team running wide-EP in productionโ€‹

I can trust that when a single node in my serving group experiences a hardware fault, IRO will automatically coordinate with the inference engine, trigger the appropriate infrastructure recovery action, and restore full capacity once recovery completes - without my team being paged or manually intervening.

As an infrastructure provider or cloud vendorโ€‹

I can integrate my fault detection agent with llm-d by writing an infrastructure recovery controller that creates RecoveryRequest CRDs, populating errorCode and requestedAction based on my hardware knowledge and any operator-configured overrides. My controller does not need to know which inference engine is running or call any engine-specific API - IRO handles that entirely.

As an inference engine teamโ€‹

I can integrate with IRO by implementing the published EngineAdapter interface, without modifying IRO's core recovery logic. My engine's specific API surface is entirely encapsulated in the adapter.

Design Detailsโ€‹

Infrastructure Provider-IRO Interface (CRD)โ€‹

IRO is dependent on a new CRD that infrastructure recovery agents are expected to produce. The infrastructure recovery controller creates RecoveryRequest when it detects a hardware fault on a node running an inference workload. IRO watches it, coordinates engine recovery, and tracks infrastructure recovery completion via it.

RecoveryRequest (created by infrastructure recovery controller, consumed by IRO):

  • nodeName
  • deviceID (optional)
  • errorCode (optional, carried for observability โ€” IRO does not interpret it)
  • requestedAction (RESET_DEVICE | REBOOT_NODE | REPLACE_NODE โ€” resolved by the infrastructure recovery controller before creation)
  • status.phase (Pending | InProgress | Completed | Failed โ€” written by the infrastructure recovery controller; IRO watches for Completed to resume the engine)
  • status.conditions[EngineReadyForRecovery] โ€” optional; see open question below

IRO-Inference Engine Interface (EngineAdapter)โ€‹

The EngineAdapter interface exposes operations mapped to the fault tolerance and elastic EP APIs being developed in the vLLM RFCs (PR #34833, RFC #28243, RFC #20323). The exact operations and their mapping to engine APIs are subject to refinement as those APIs stabilize.

EngineAdapter OperationvLLM APIRFC / PRStatus
FaultEventsZMQ vllm_fault PUBRFC #27866 / PR #34833Draft PR
EngineStatusGET /fault_tolerance/statusRFC #27866 / PR #34833Draft PR
PauseEnginePOST /fault_tolerance/apply {pause}RFC #27866 / PR #34833Draft PR
ResumeEnginePOST /fault_tolerance/apply {retry}RFC #27866 / PR #34833Draft PR
ScaleDown(new_world_size)handle_eep_event {SCALING_REQUEST} to API serverRFC #28243Proposed
ScaleUp(new_world_size)handle_eep_event {SCALING_REQUEST} + NOTIFICATION to rank 0RFC #28243Proposed

Dual input channelsโ€‹

IRO receives fault signals from two independent directions with distinct, non-overlapping responsibilities:

  • RecoveryRequest (infrastructure-initiated) โ€” the primary input channel. IRO coordinates the full engine recovery sequence: pause or scale down engine, coordinate with infrastructure recovery, then resume or scale up the engine once RecoveryRequest.status.phase reaches Completed state.
  • Engine fault events via ZMQ (engine-initiated) - when the engine's internal fault monitoring pushes a fault notification with no corresponding RecoveryRequest, the fault is treated as transient and engine-internal. IRO tells the engine to retry without triggering any infrastructure recovery action.

Sequence of eventsโ€‹

Open question: should infrastructure recovery gate on IRO?โ€‹

The EngineReadyForRecovery condition on RecoveryRequest is designed to be optional. This is the key open design question.

Without gating - the infrastructure recovery controller creates RecoveryRequest and immediately proceeds with the recovery action. IRO independently watches RecoveryRequest, pauses the engine on the remaining healthy ranks, and resumes once phase reaches Completed. Because PauseEngine and ScaleDown only need to talk to the surviving ranks, IRO can act in parallel with infrastructure recovery even if the faulted chip is already gone. This is simpler and has no coordination overhead.

With gating - the infrastructure recovery controller creates RecoveryRequest with EngineReadyForRecovery: False and waits for IRO to set it to True before acting. This provides a stronger guarantee: the engine is in a clean paused state before the chip is touched. This may be required if vLLM cannot handle a rank disappearing mid-collective without hanging.

The deciding factor is vLLM's behavior when a rank disappears suddenly: if PR #34833's internal fault detection catches and handles a sudden rank loss gracefully (pausing the remaining ranks automatically), gating adds overhead for no benefit. If vLLM hangs waiting for the dead rank until IRO intervenes, gating is necessary.

We will be seeking input from the vLLM team on this before finalizing the coordination contract. The RecoveryRequest CRD is designed to support both models - the condition is present if the infrastructure recovery controller opts in to gating, absent if not.

For more details, please refer to the WIP design doc.

Alternativesโ€‹

Extend an existing infrastructure agentโ€‹

Infrastructure agents have hardware domain knowledge but no inference engine awareness. Adding engine coordination to an agent would create a reverse dependency - infrastructure code depending on inference engine APIs - and would need to be duplicated per cloud provider. The coordination layer should be cloud-agnostic and engine-agnostic by construction.

Build recovery logic into the inference engine (vLLM)โ€‹

Each vLLM fault tolerance RFC explicitly defers recovery orchestration to an external orchestrator. Adding recovery logic into vLLM itself would tightly couple hardware recovery to a specific engine, making it unavailable for other engines and requiring infrastructure knowledge to live in the model server.

Extend other existing controllers (such as LWS)โ€‹

LWS is responsible for pod group lifecycle - creating, scheduling, and restarting groups of pods as a unit. Adding IRO's responsibilities to LWS would conflate pod lifecycle management with inference engine coordination in a single component, and would require LWS to grow awareness of hardware fault signals and engine-specific APIs. IRO instead treats LWS as one actuation target it coordinates alongside the other layers.