Skip to content

Commit 31adca1

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

3 files changed

Lines changed: 137 additions & 1 deletion

File tree

tensorrt_llm/_torch/pyexecutor/error_classification.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,26 @@
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+
"unrecoverable error in the engine",
38+
"cuda error no device",
39+
"gpu has fallen off the bus",
40+
"xid 79",
41+
"nccl communicator abort",
42+
"nccl communicator was aborted",
43+
"ncclcommabort",
44+
"nvshmem peer unreachable",
45+
"mpi rank terminated",
46+
"mpi worker terminated",
47+
"mpi rank exited unexpectedly",
48+
"mpi worker exited unexpectedly",
3249
]
3350

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

4374

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: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
"Unrecoverable error in the engine",
47+
"ncclCommAbort returned during communicator teardown",
48+
"NCCL communicator was aborted during PP send",
49+
"NVSHMEM peer unreachable for EP rank 12",
50+
"MPI rank terminated with signal 9",
51+
"MPI worker exited unexpectedly",
52+
],
53+
)
54+
def test_wide_ep_immediate_fatal_patterns(message):
55+
assert classify_error(message) == "immediate_fatal"
56+
57+
58+
@pytest.mark.parametrize(
59+
"message",
60+
[
61+
"NCCL timeout",
62+
"AlltoAll timeout waiting for completion_flags[3][7]",
63+
"AlltoAll watchdog timed out waiting for peer rank 7",
64+
"completion_flags timeout",
65+
"NCCL operation timed out during all_reduce",
66+
"deep_ep buffer barrier hang",
67+
"deepep buffer barrier hang",
68+
"DeepEP Buffer.__del__ hung in intranode::barrier",
69+
"Symmetric memory access violation reading dead peer",
70+
"RDMA timeout on cross-node transfer",
71+
"NIXL transfer failed: remote peer closed",
72+
"NIXL transfer entered error state",
73+
"NIXL transfer wait timed out after 5000 ms",
74+
],
75+
)
76+
def test_wide_ep_severe_patterns(message):
77+
assert classify_error(message) == "severe"
78+
79+
80+
@pytest.mark.parametrize(
81+
"message",
82+
[
83+
"AlltoAll slow path observed for rank 3",
84+
"NCCL retry scheduled after transient transport hiccup",
85+
"ECC correctable error threshold warning",
86+
"Application marked the request unrecoverable but retryable",
87+
],
88+
)
89+
def test_wide_ep_nonfatal_signals_remain_transient(message):
90+
assert classify_error(message) == "transient"
91+
92+
93+
def test_error_budget_charges_wide_ep_severe_patterns():
94+
budget = ErrorBudget(recovery_rate=0.0)
95+
96+
assert not budget.consume("NIXL transfer failed: remote peer closed")
97+
assert budget.consume("AlltoAll timeout waiting for completion_flags[0][2]")
98+
99+
100+
def test_error_budget_bypasses_budget_for_wide_ep_fatal_patterns():
101+
budget = ErrorBudget(recovery_rate=0.0)
102+
103+
assert budget.consume("MPI rank terminated with signal 9")
104+
assert budget.budget == 1.0

0 commit comments

Comments
 (0)