[PD] Downgrade propagated rank failure logs from error to debug (#27534)

Signed-off-by: Shangming Cai <csmthu@gmail.com>
This commit is contained in:
Shangming Cai
2026-06-08 16:56:46 +08:00
committed by GitHub
parent df6b9c2d9d
commit 8ff0c9fef9
6 changed files with 87 additions and 33 deletions
@@ -49,6 +49,22 @@ from sglang.srt.utils.network import (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class KVTransferError(Exception):
def __init__(
self,
bootstrap_room: int,
failure_reason: str,
is_from_another_rank: bool = False,
):
super().__init__(failure_reason)
self.bootstrap_room = bootstrap_room
self.failure_reason = failure_reason
self.is_from_another_rank = is_from_another_rank
def __str__(self):
return f"KVTransferError(bootstrap_room={self.bootstrap_room}): {self.failure_reason}"
@dataclasses.dataclass @dataclasses.dataclass
class PrefillServerInfo: class PrefillServerInfo:
# Topology fields (fetched from bootstrap server) # Topology fields (fetched from bootstrap server)
@@ -643,10 +643,16 @@ class DecodePreallocQueue(DecodeHiCachePreallocMixin):
decode_req.req.time_stats.set_bootstrap_done_time() decode_req.req.time_stats.set_bootstrap_done_time()
elif poll == KVPoll.Failed: elif poll == KVPoll.Failed:
error_message = f"Decode handshake failed for request rank={self.tp_rank} {decode_req.req.rid=} {decode_req.req.bootstrap_room=}" error_message = f"Decode handshake failed for request rank={self.tp_rank} {decode_req.req.rid=} {decode_req.req.bootstrap_room=}"
is_propagated = False
try: try:
decode_req.kv_receiver.failure_exception() decode_req.kv_receiver.failure_exception()
except Exception as e: except Exception as e:
error_message += f" with exception {e}" error_message += f" with exception {e}"
is_propagated = getattr(e, "is_from_another_rank", False)
# Mute error message for propagated exceptions to avoid duplicate logging
if is_propagated:
logger.debug(error_message)
else:
logger.error(error_message) logger.error(error_message)
prepare_abort( prepare_abort(
decode_req.req, decode_req.req,
@@ -1609,12 +1615,18 @@ class DecodeTransferQueue(DecodeHiCacheTransferMixin):
f"Decode transfer failed for request rank={self.tp_rank} " f"Decode transfer failed for request rank={self.tp_rank} "
f"{decode_req.req.rid=} {decode_req.req.bootstrap_room=}" f"{decode_req.req.rid=} {decode_req.req.bootstrap_room=}"
) )
is_propagated = False
if poll == KVPoll.Failed: if poll == KVPoll.Failed:
try: try:
decode_req.kv_receiver.failure_exception() decode_req.kv_receiver.failure_exception()
except Exception as e: except Exception as e:
error_message += f" with exception {e}" error_message += f" with exception {e}"
is_propagated = getattr(e, "is_from_another_rank", False)
self._clean_hicache_prefetch_resources(decode_req) self._clean_hicache_prefetch_resources(decode_req)
# Mute error message for propagated exceptions to avoid duplicate logging
if is_propagated:
logger.debug(error_message)
else:
logger.error(error_message) logger.error(error_message)
prepare_abort( prepare_abort(
decode_req.req, decode_req.req,
@@ -20,6 +20,7 @@ from sglang.srt.disaggregation.common.conn import (
CommonKVManager, CommonKVManager,
CommonKVReceiver, CommonKVReceiver,
CommonKVSender, CommonKVSender,
KVTransferError,
) )
from sglang.srt.disaggregation.common.staging_handler import ( from sglang.srt.disaggregation.common.staging_handler import (
DecodeStagingContext, DecodeStagingContext,
@@ -62,16 +63,6 @@ FAILED_SESSION_RECOVERIES = Counter(
) )
class KVTransferError(Exception):
def __init__(self, bootstrap_room: int, failure_reason: str):
super().__init__(failure_reason)
self.bootstrap_room = bootstrap_room
self.failure_reason = failure_reason
def __str__(self):
return f"KVTransferError(bootstrap_room={self.bootstrap_room}): {self.failure_reason}"
# decode # decode
@dataclasses.dataclass @dataclasses.dataclass
class TransferInfo: class TransferInfo:
@@ -1747,10 +1738,13 @@ class MooncakeKVSender(CommonKVSender):
self.clear() self.clear()
with self.kv_mgr.failure_lock: with self.kv_mgr.failure_lock:
failure_reason = self.kv_mgr.failure_records.pop( failure_reason = self.kv_mgr.failure_records.pop(self.bootstrap_room, None)
self.bootstrap_room, "Failed due to an unknown reason from another rank" is_propagated = failure_reason is None
if is_propagated:
failure_reason = "Failed due to an unknown reason from another rank"
raise KVTransferError(
self.bootstrap_room, failure_reason, is_from_another_rank=is_propagated
) )
raise KVTransferError(self.bootstrap_room, failure_reason)
def _init_trace_ctx(self): def _init_trace_ctx(self):
if self.kv_mgr.enable_trace: if self.kv_mgr.enable_trace:
@@ -1908,10 +1902,13 @@ class MooncakeKVReceiver(CommonKVReceiver):
self.clear() self.clear()
with self.kv_mgr.failure_lock: with self.kv_mgr.failure_lock:
failure_reason = self.kv_mgr.failure_records.pop( failure_reason = self.kv_mgr.failure_records.pop(self.bootstrap_room, None)
self.bootstrap_room, "Failed due to an unknown reason from another rank" is_propagated = failure_reason is None
if is_propagated:
failure_reason = "Failed due to an unknown reason from another rank"
raise KVTransferError(
self.bootstrap_room, failure_reason, is_from_another_rank=is_propagated
) )
raise KVTransferError(self.bootstrap_room, failure_reason)
class MooncakeKVBootstrapServer(CommonKVBootstrapServer): class MooncakeKVBootstrapServer(CommonKVBootstrapServer):
+13 -6
View File
@@ -32,6 +32,7 @@ from sglang.srt.disaggregation.common.conn import (
CommonKVManager, CommonKVManager,
CommonKVReceiver, CommonKVReceiver,
CommonKVSender, CommonKVSender,
KVTransferError,
) )
from sglang.srt.disaggregation.common.utils import ( from sglang.srt.disaggregation.common.utils import (
AuxDataCodec, AuxDataCodec,
@@ -1539,10 +1540,13 @@ class MoriKVSender(CommonKVSender):
self._finalize_failure() self._finalize_failure()
self.clear() self.clear()
with self.kv_mgr.failure_lock: with self.kv_mgr.failure_lock:
failure_reason = self.kv_mgr.failure_records.pop( failure_reason = self.kv_mgr.failure_records.pop(self.bootstrap_room, None)
self.bootstrap_room, "KV transfer failed" is_propagated = failure_reason is None
if is_propagated:
failure_reason = "KV transfer failed"
raise KVTransferError(
self.bootstrap_room, failure_reason, is_from_another_rank=is_propagated
) )
raise RuntimeError(failure_reason)
def abort(self): def abort(self):
self._finalize_failure("Aborted by AbortReq.") self._finalize_failure("Aborted by AbortReq.")
@@ -1675,10 +1679,13 @@ class MoriKVReceiver(CommonKVReceiver):
self.clear() self.clear()
with self.kv_mgr.failure_lock: with self.kv_mgr.failure_lock:
failure_reason = self.kv_mgr.failure_records.pop( failure_reason = self.kv_mgr.failure_records.pop(self.bootstrap_room, None)
self.bootstrap_room, "KV transfer failed" is_propagated = failure_reason is None
if is_propagated:
failure_reason = "KV transfer failed"
raise KVTransferError(
self.bootstrap_room, failure_reason, is_from_another_rank=is_propagated
) )
raise RuntimeError(failure_reason)
def abort(self): def abort(self):
if self.bootstrap_room is None: if self.bootstrap_room is None:
+13 -3
View File
@@ -22,6 +22,7 @@ from sglang.srt.disaggregation.common.conn import (
CommonKVManager, CommonKVManager,
CommonKVReceiver, CommonKVReceiver,
CommonKVSender, CommonKVSender,
KVTransferError,
) )
from sglang.srt.disaggregation.common.staging_handler import StagingRegisterInfo from sglang.srt.disaggregation.common.staging_handler import StagingRegisterInfo
from sglang.srt.disaggregation.common.utils import ( from sglang.srt.disaggregation.common.utils import (
@@ -1973,8 +1974,10 @@ class NixlKVSender(CommonKVSender):
if exc is not None: if exc is not None:
raise exc raise exc
if failure_reason is not None: if failure_reason is not None:
raise RuntimeError(failure_reason) raise KVTransferError(self.bootstrap_room, failure_reason)
raise RuntimeError("NIXL KVSender Exception") raise KVTransferError(
self.bootstrap_room, "NIXL KVSender Exception", is_from_another_rank=True
)
class NixlKVReceiver(CommonKVReceiver): class NixlKVReceiver(CommonKVReceiver):
@@ -2138,7 +2141,14 @@ class NixlKVReceiver(CommonKVReceiver):
) )
def failure_exception(self): def failure_exception(self):
raise RuntimeError("NIXL KVReceiver Exception") with self.kv_mgr.failure_lock:
failure_reason = self.kv_mgr.failure_records.pop(self.bootstrap_room, None)
is_propagated = failure_reason is None
if is_propagated:
failure_reason = "NIXL KVReceiver Exception"
raise KVTransferError(
self.bootstrap_room, failure_reason, is_from_another_rank=is_propagated
)
class NixlKVBootstrapServer(CommonKVBootstrapServer): class NixlKVBootstrapServer(CommonKVBootstrapServer):
@@ -721,10 +721,16 @@ class SchedulerDisaggregationPrefillMixin:
req.time_stats.set_prefill_kv_transfer_finish_time() req.time_stats.set_prefill_kv_transfer_finish_time()
elif poll == KVPoll.Failed: elif poll == KVPoll.Failed:
error_message = f"Prefill transfer failed for request rank={self.ps.tp_rank} {req.rid=} {req.bootstrap_room=}" error_message = f"Prefill transfer failed for request rank={self.ps.tp_rank} {req.rid=} {req.bootstrap_room=}"
is_propagated = False
try: try:
req.disagg_kv_sender.failure_exception() req.disagg_kv_sender.failure_exception()
except Exception as e: except Exception as e:
error_message += f" with exception {e}" error_message += f" with exception {e}"
is_propagated = getattr(e, "is_from_another_rank", False)
# Mute error message for propagated exceptions to avoid duplicate logging
if is_propagated:
logger.debug(error_message)
else:
logger.warning(error_message) logger.warning(error_message)
req.time_stats.trace_ctx.abort(abort_info={"reason": error_message}) req.time_stats.trace_ctx.abort(abort_info={"reason": error_message})
release_kv_cache(req, self.tree_cache) # unlock the tree release_kv_cache(req, self.tree_cache) # unlock the tree
@@ -802,10 +808,16 @@ class SchedulerDisaggregationPrefillMixin:
f"Prefill bootstrap failed for request rank={self.ps.tp_rank} " f"Prefill bootstrap failed for request rank={self.ps.tp_rank} "
f"{req.rid=} {req.bootstrap_room=}" f"{req.rid=} {req.bootstrap_room=}"
) )
is_propagated = False
try: try:
req.disagg_kv_sender.failure_exception() req.disagg_kv_sender.failure_exception()
except Exception as e: except Exception as e:
error_message += f" with exception {e}" error_message += f" with exception {e}"
is_propagated = getattr(e, "is_from_another_rank", False)
# Mute error message for propagated exceptions to avoid duplicate logging
if is_propagated:
logger.debug(error_message)
else:
logger.warning(error_message) logger.warning(error_message)
req.time_stats.trace_ctx.abort(abort_info={"reason": error_message}) req.time_stats.trace_ctx.abort(abort_info={"reason": error_message})
if req.req_pool_idx is not None or self.tree_cache.supports_mamba(): if req.req_pool_idx is not None or self.tree_cache.supports_mamba():