[Feature] Add fault tolerance framework (simplified) for DP+EP external LB deployments - #44428
Merged
Merged
Conversation
Contributor
|
This pull request has merge conflicts that must be resolved before it can be |
fangyuchu
force-pushed
the
feature/ft-simplify
branch
from
June 4, 2026 03:40
171d530 to
36edbc9
Compare
fangyuchu
force-pushed
the
feature/ft-simplify
branch
3 times, most recently
from
June 12, 2026 06:57
1033db2 to
ecabd80
Compare
fangyuchu
marked this pull request as ready for review
June 12, 2026 11:10
fangyuchu
requested review from
DarkLight1337,
ProExpertProg,
WoosukKwon,
aarnphm,
chaunceyjiang,
hmellor,
houseroad,
mgoin,
njhill,
pavanimajety,
robertgshaw2-redhat,
russellb,
tlrmchlsmth,
yewentao256,
youkaichao and
zyongye
as code owners
June 12, 2026 11:10
Contributor
|
This pull request has merge conflicts that must be resolved before it can be |
fangyuchu
force-pushed
the
feature/ft-simplify
branch
from
June 18, 2026 08:06
c3cc2da to
f90ff1b
Compare
Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
…r state cleanup Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
#250) Signed-off-by: fangyuchu <fangyuchu@qq.com>
Signed-off-by: fangyuchu <fangyuchu@qq.com>
fangyuchu
force-pushed
the
feature/ft-simplify
branch
from
July 25, 2026 10:55
e7bf4cc to
5be79f8
Compare
This was referenced Jul 27, 2026
[Bug]: FT recovery reads residual responses from unconsumed response_mqs after worker failure
#49972
Open
yao-xiaobai
pushed a commit
to Ascend/MindIE-Motor
that referenced
this pull request
Aug 13, 2026
Co-authored-by: 吕有辉<lvyouhui@huawei.com> # message auto-generated for no-merge-commit merge: !678 merge feature/fault_reporterV2 into master [Feature] FaultReporter 对齐 vLLM FT 框架:ZMQ 订阅改为 HTTP 轮询 Created-by: codeDogPro Commit-by: 吕有辉 Merged-by: tobking Description: ### 1. 合入背景 vLLM FaultTolerance 框架(vllm-project/vllm#44428)最终实现不再通过 ZMQ 广播引擎故障状态,改为外部轮询 REST 接口(`GET /fault_tolerance/status`)。Motor 侧 FaultReporter 仍基于旧版 ZMQ 设计将无法感知引擎故障。本 PR 将 FaultReporter 重构为 HTTP 轮询模式并上报软件故障。 关联 ISSUE:#448 ### 2. 修改内容 1. **NodeManager FaultReporter 重构**(`motor/node_manager/core/fault_reporter.py`): - ZMQ SUB 订阅 → HTTP 轮询每个 endpoint 的 `GET /fault_tolerance/status`(business_port) - 连续轮询失败 `max_poll_failures` 次按 dead 上报;`_STARTUP_GRACE_SEC`(300s)冷启动宽限期防误报;去重 key 统一为受管 endpoint id(多 endpoint 不互相覆盖);状态解析异常不杀死轮询线程 - 自动启用:检测 user config 引擎段 FT 开关(`enable-fault-tolerance`/`enable_fault_tolerance` 为 true 或 1),无需 NodeManager 显式配置 2. **引擎 FT 协议层**(`motor/common/constants.py` + `motor/common/http/engine_ft_client.py`):FT 状态路径/状态词/超时协议常量收敛为共享模块,`query_engine_ft_status` 为 FaultReporter 状态轮询入口 3. **配置变更**(NodeManager):`zmq_pub_port` 删除,新增 `poll_interval_sec`(5.0)/ `poll_timeout_sec`(5.0)/ `max_poll_failures`(3) ### 3. 资料变更 涉及,同步更新: - `docs/zh/developer_guide/components/node_manager.md`:软件故障上报章节(轮询模式 + 自动启用)、配置表 - `docs/zh/design/fault_tolerance/fault_manager.md`:FaultReporter 架构与上报链路(HTTP 轮询)、NodeManager 侧配置表 - `examples/features/config_sample.json`:NodeManager 段 fault_tolerance_config 字段同步 ### 4. 接口变更 涉及(NodeManager 管理面接口): - 删除 NodeManager 配置字段 `fault_tolerance_config.zmq_pub_port`,新增 `poll_interval_sec` / `poll_timeout_sec` / `max_poll_failures` ### 5. 测试结果 **单测**(`bash tests/run_tests.sh tests/controller/ tests/node_manager/ tests/config/`):**839 passed** 新增/重写测试覆盖: - FaultReporter:轮询 healthy/unhealthy/dead 处理、fault_info 传递、去重、连续失败上报 dead、恢复清计数、上报失败重试、user_config 自动启用检测、malformed payload 不死线程、多 endpoint dedup 互不覆盖、冷启动宽限期(宽限期内外)、`1` 值检测、非引擎段忽略(14 项) - NodeManager 配置:poll_interval_sec / poll_timeout_sec / max_poll_failures 字段与校验 **静态检查**:pylint / ruff 通过 ### 6. CheckList - [x] 代码注释完备 - [x] 正确记录维测日志(错误场景 error_window 防刷屏) - [x] 是否有 UT 用例(839 passed) - [x] 若涉及多线程场景,考虑了并发场景,不存在死锁问题(FaultReporter 锁内快照 endpoints、stop/start 防双线程) See merge request: Ascend/MindIE-Motor!678
5 tasks
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
Add fault tolerance (FT) framework for DP+EP (Data Parallelism + Expert Parallelism) MoE deployments. When one DP rank dies, the EP all2all operation on surviving ranks blocks indefinitely, causing a full cluster hang. This framework detects faults, aborts in-flight requests, and allows an external orchestrator to trigger coordinated recovery via a REST API.
Key design:
EngineCoreSentinelandWorkerSentinelobjects -- EngineCore and Worker hold only a referencePOST /fault_tolerance/applywith{"instruction": "xxx"}for different recovery policiescall_utility_async(client -> engine) andcollective_rpc(engine -> workers) mechanisms. No new communication channels or threads are introducedfault_tolerant_wrapperdecorator on the busy loop is the only structural integration pointThis is a simplified version -- redundant abstractions, unused config fields, and unnecessary manual state resets have been removed compared to earlier iterations.
Details
External LB mode only. Per community feedback, external LB mode is the recommended topology for production deployments. This PR targets FT exclusively for external LB mode (
--data-parallel-external-lb/--data-parallel-rank), which also significantly reduces implementation complexity.Fault detection prerequisites. FT relies on each engine being able to detect peer failures instead of hanging indefinitely. This requires: (a) an FT-capable all2all backend (
nixl_epordeepep_low_latency) that supports timeout + rank masking, and (b) a configured Gloo timeout (--cpu-distributed-timeout-seconds) for the CPU allreduce used in DP batch synchronization.Status semantics during fault propagation. After a DP rank fails, all other ranks will eventually raise exceptions too (via Gloo allreduce timeout and/or all2all kernel timeout). If the status API shows some ranks as
unhealthybut others still ashealthy, the "healthy" ranks are most likely still waiting inside a timeout window (e.g., the Gloo CPU group timeout or the all2all backend's kernel timeout) and have not yet raised their exception. The orchestrator should wait for all ranks to becomeunhealthybefore issuing a recovery command.Retry recovery for transient faults. The current implementation supports
retryrecovery for transiently recoverable faults such as network blips. Onretry, the framework reinitializes the DP process group, cleans worker state (input batch, model runner state), and resets RDMA buffers and mask state in the all2all backend.Test Plan
Model: Qwen3-30B-A3B (MoE, 128 experts)
Configuration: DP=4, TP=1, EP=4,
deepep_low_latencybackendLaunching the cluster
Each DP rank runs as a separate
vllm serveprocess. The command below shows rank 0 -- launch one such process per GPU, incrementingCUDA_VISIBLE_DEVICES,--data-parallel-rank, and--portfor each rank:CUDA_VISIBLE_DEVICES=0 python -m vllm.entrypoints.cli.main serve \ Qwen/Qwen3-30B-A3B \ --data-parallel-size 4 \ --data-parallel-size-local 1 \ --data-parallel-rank 0 \ --port 8100 \ --enable-expert-parallel \ --all2all-backend deepep_low_latency \ --gpu-memory-utilization 0.5 \ --max-model-len 1024 \ --trust-remote-code \ --cpu-distributed-timeout-seconds 3 \ --enable-fault-tolerance \ --fault-tolerance-config '{"engine_recovery_timeout_sec": 500}'Simulating faults
To simulate a transient device-side failure, inject a
RuntimeErrorin the DP allreduce path (_run_arinvllm/v1/worker/dp_utils.py). The patch adds a step counter and raises an exception at specific steps (250 and 5000) on a target rank (rank 1), after the allreduce completes:Sending inference requests
Querying FT status and issuing recovery
Test Results
Run log:
test_inject_fault_and_retry.log
Tested with DP=4, EP=4,
deepep_low_latencybackend. Faults were injected at step 250 and step 5000 on DP rank 1. Both fault-recovery cycles completed successfully.Fault Injection # 1 -- Step 250
/fault_tolerance/apply,/fault_tolerance/status) registeredRuntimeErrorraised after allreduce at step 250Timed out waiting 3000ms for recv operation[0, 1, 0, 0](rank 1 faulted)GET /fault_tolerance/statusconfirms all 4 engines areunhealthyPOST /fault_tolerance/apply(retry) sent to all 4 engines. All 4 -> HEALTHYKey log lines:
Fault Injection # 2 -- Step 5000
RuntimeErrorat step 5000[0, 1, 0, 0]POST /fault_tolerance/apply(retry) sent. All 4 -> HEALTHYSummary
[0, 1, 0, 0]retry, all 4 engines returned toHEALTHYand inference throughput was fully restoredEssential Elements of an Effective PR Description Checklist
supported_models.mdandexamplesfor a new model.