Skip to content

Commit 331f9ee

Browse files
committed
Add WideEP error classification patterns
Signed-off-by: Chien-Chun Hung <2679986+chienchunhung@users.noreply.github.com>
1 parent 33bf59e commit 331f9ee

3 files changed

Lines changed: 135 additions & 1 deletion

File tree

tensorrt_llm/_torch/pyexecutor/error_classification.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,25 @@
2626
IMMEDIATE_FATAL_PATTERNS: list[str] = [
2727
"cudaerrorillegaladdress",
2828
"cudaerrorlaunchfailure",
29+
"cudaerrorcontextisdestroyed",
30+
"cudaerrornodevice",
2931
"illegal memory access",
3032
"device-side assert",
31-
"unrecoverable",
33+
"cuda context destroyed",
34+
"cuda context is destroyed",
35+
"cuda context was destroyed",
36+
"cuda context is unrecoverable",
37+
"cuda error no device",
38+
"gpu has fallen off the bus",
39+
"xid 79",
40+
"nccl communicator abort",
41+
"nccl communicator was aborted",
42+
"ncclcommabort",
43+
"nvshmem peer unreachable",
44+
"mpi rank terminated",
45+
"mpi worker terminated",
46+
"mpi rank exited unexpectedly",
47+
"mpi worker exited unexpectedly",
3248
]
3349

3450
# Patterns that are serious but may be transient (e.g. a single OOM
@@ -38,6 +54,20 @@
3854
"cuda out of memory",
3955
"cuda error",
4056
"nccl error",
57+
"nccl timeout",
58+
"nccl operation timed out",
59+
"alltoall timeout",
60+
"all-to-all timeout",
61+
"alltoall watchdog",
62+
"completion_flags timeout",
63+
"deep_ep buffer barrier hang",
64+
"deepep buffer barrier hang",
65+
"intranode::barrier",
66+
"symmetric memory access violation",
67+
"rdma timeout",
68+
"nixl transfer failed",
69+
"nixl transfer entered error state",
70+
"nixl transfer wait timed out",
4171
]
4272

4373

tests/integration/test_lists/test-db/l0_a10.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ l0_a10:
3535
- unittest/_torch/executor/test_kv_pool_rebalance.py
3636
- unittest/_torch/executor/test_disagg_index_mapper_early_release.py
3737
- unittest/_torch/pyexecutor/test_kv_cache_compression_manager.py
38+
- unittest/_torch/pyexecutor/test_error_classification.py
3839
- unittest/_torch/modules/dwdp/test_dwdp_fixup_moe_backends.py
3940
- unittest/_torch/modules/dwdp/test_dwdp_manager.py
4041
- unittest/_torch/modules/dwdp/test_dwdp_mapping.py
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import importlib.util
17+
import sys
18+
from pathlib import Path
19+
20+
import pytest
21+
22+
_MODULE_PATH = (
23+
Path(__file__).resolve().parents[4] / "tensorrt_llm/_torch/pyexecutor/error_classification.py"
24+
)
25+
_SPEC = importlib.util.spec_from_file_location("error_classification_under_test", _MODULE_PATH)
26+
assert _SPEC is not None
27+
assert _SPEC.loader is not None
28+
_ERROR_CLASSIFICATION = importlib.util.module_from_spec(_SPEC)
29+
sys.modules[_SPEC.name] = _ERROR_CLASSIFICATION
30+
_SPEC.loader.exec_module(_ERROR_CLASSIFICATION)
31+
32+
ErrorBudget = _ERROR_CLASSIFICATION.ErrorBudget
33+
classify_error = _ERROR_CLASSIFICATION.classify_error
34+
35+
36+
@pytest.mark.parametrize(
37+
"message",
38+
[
39+
"CUDA context destroyed",
40+
"cudaErrorContextIsDestroyed during collective setup",
41+
"CUDA error: cudaErrorNoDevice on rank 37",
42+
"NVRM: Xid 79, GPU has fallen off the bus",
43+
"CUDA context is destroyed after device reset",
44+
"CUDA context was destroyed after device reset",
45+
"CUDA context is unrecoverable after device reset",
46+
"ncclCommAbort returned during communicator teardown",
47+
"NCCL communicator was aborted during PP send",
48+
"NVSHMEM peer unreachable for EP rank 12",
49+
"MPI rank terminated with signal 9",
50+
"MPI worker exited unexpectedly",
51+
],
52+
)
53+
def test_wide_ep_immediate_fatal_patterns(message):
54+
assert classify_error(message) == "immediate_fatal"
55+
56+
57+
@pytest.mark.parametrize(
58+
"message",
59+
[
60+
"NCCL timeout",
61+
"AlltoAll timeout waiting for completion_flags[3][7]",
62+
"AlltoAll watchdog timed out waiting for peer rank 7",
63+
"completion_flags timeout",
64+
"NCCL operation timed out during all_reduce",
65+
"deep_ep buffer barrier hang",
66+
"deepep buffer barrier hang",
67+
"DeepEP Buffer.__del__ hung in intranode::barrier",
68+
"Symmetric memory access violation reading dead peer",
69+
"RDMA timeout on cross-node transfer",
70+
"NIXL transfer failed: remote peer closed",
71+
"NIXL transfer entered error state",
72+
"NIXL transfer wait timed out after 5000 ms",
73+
],
74+
)
75+
def test_wide_ep_severe_patterns(message):
76+
assert classify_error(message) == "severe"
77+
78+
79+
@pytest.mark.parametrize(
80+
"message",
81+
[
82+
"AlltoAll slow path observed for rank 3",
83+
"NCCL retry scheduled after transient transport hiccup",
84+
"ECC correctable error threshold warning",
85+
"Application marked the request unrecoverable but retryable",
86+
],
87+
)
88+
def test_wide_ep_nonfatal_signals_remain_transient(message):
89+
assert classify_error(message) == "transient"
90+
91+
92+
def test_error_budget_charges_wide_ep_severe_patterns():
93+
budget = ErrorBudget(recovery_rate=0.0)
94+
95+
assert not budget.consume("NIXL transfer failed: remote peer closed")
96+
assert budget.consume("AlltoAll timeout waiting for completion_flags[0][2]")
97+
98+
99+
def test_error_budget_bypasses_budget_for_wide_ep_fatal_patterns():
100+
budget = ErrorBudget(recovery_rate=0.0)
101+
102+
assert budget.consume("MPI rank terminated with signal 9")
103+
assert budget.budget == 1.0

0 commit comments

Comments
 (0)