from __future__ import annotations
import logging
import traceback
import uuid
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, ClassVar
import torch.nn as nn
from .. import envs
from ..nixl_transfer import is_nixl_available
from ..tensor_utils import log_tensor_summary
from ..metadata.publish import publish_metadata_and_ready
from .context import LoadContext, LoadResult
if TYPE_CHECKING:
from ..accelerators import AcceleratorBackend
from ..nixl_transfer import NixlTransferManager
logger = logging.getLogger("modelexpress.load_strategy")
def clear_exception_tracebacks(exc: BaseException) -> None:
pending: list[BaseException] = [exc]
seen: set[int] = set()
while pending:
current = pending.pop()
if id(current) in seen:
continue
seen.add(id(current))
if current.__cause__ is not None:
pending.append(current.__cause__)
if current.__context__ is not None:
pending.append(current.__context__)
if current.__traceback__ is not None:
traceback.clear_frames(current.__traceback__)
current.__traceback__ = None
class SourceTransferError(Exception):
class LoadStrategy(ABC):
name: str
requires: ClassVar[tuple] = ()
def is_available(self, ctx: LoadContext) -> bool:
if not self.requires:
return True
if ctx.adapter is None:
return False
cls = type(ctx.adapter)
return all(getattr(cls, m.__name__) is not m for m in self.requires)
@abstractmethod
def load(self, result: LoadResult, ctx: LoadContext) -> LoadResult:
def rollback(self, ctx: LoadContext) -> None:
return None
def _init_nixl_manager(
global_rank: int,
device_id: int,
role: str,
listen_port: int = 0,
accelerator_backend: AcceleratorBackend | None = None,
) -> NixlTransferManager:
from ..nixl_transfer import NixlTransferManager
agent_name = f"mx-{role}-worker{global_rank}-{uuid.uuid4().hex[:8]}"
logger.debug(f"[Worker {global_rank}] Initializing NIXL manager with agent_name={agent_name}")
manager = NixlTransferManager(
agent_name=agent_name,
device_id=device_id,
listen_port=listen_port,
accelerator_backend=accelerator_backend,
)
manager.initialize()
logger.debug(f"[Worker {global_rank}] NIXL manager initialized")
return manager
def _as_load_result(result_or_model: LoadResult | nn.Module) -> LoadResult:
if isinstance(result_or_model, LoadResult):
return result_or_model
return LoadResult(value=result_or_model, model=result_or_model)
def _metadata_publication_configured(ctx: LoadContext) -> bool:
server_addr = (
ctx.mx_server_url or envs.MODEL_EXPRESS_URL or envs.MX_SERVER_ADDRESS
)
if server_addr:
return True
return getattr(ctx.mx_client, "REQUIRES_P2P_METADATA", False) is True
def register_tensors(
result_or_model: LoadResult | nn.Module,
ctx: LoadContext,
*,
reuse_discovered: bool = False,
) -> None:
if not ctx.p2p_enabled:
return
if not _metadata_publication_configured(ctx):
logger.info(
f"[Worker {ctx.global_rank}] No MX metadata path configured, "
"skipping NIXL registration"
)
return
if not is_nixl_available():
logger.warning(f"[Worker {ctx.global_rank}] NIXL not available, skipping registration")
return
if ctx.adapter is None:
raise RuntimeError("NIXL registration requires an engine adapter")
try:
if reuse_discovered and ctx.tensors:
logger.info(
f"[Worker {ctx.global_rank}] Re-registering "
f"{len(ctx.tensors)} previously-discovered tensors "
f"(skipping model walk)"
)
else:
result = _as_load_result(result_or_model)
if result.model is None:
logger.info(
f"[Worker {ctx.global_rank}] No model available, skipping NIXL registration"
)
return
ctx.tensors = ctx.adapter.discover_tensors(result)
log_tensor_summary(ctx.tensors, ctx.global_rank, "Registering tensors")
if ctx.nixl_manager is None:
base_port = envs.MX_METADATA_PORT
listen_port = base_port + ctx.device_id
ctx.nixl_manager = _init_nixl_manager(
ctx.global_rank,
ctx.device_id,
"auto",
listen_port,
ctx.accelerator_backend,
)
if not ctx.nixl_manager.tensor_descriptors:
if ctx.vmm_arena is not None:
logger.debug(
f"[Worker {ctx.global_rank}] Registering arena with NIXL "
"(single MR via dmabuf)..."
)
ctx.nixl_manager.register_arena(ctx.vmm_arena, ctx.tensors)
else:
logger.debug(f"[Worker {ctx.global_rank}] Registering tensors with NIXL...")
ctx.nixl_manager.register_tensors(ctx.tensors)
logger.debug(f"[Worker {ctx.global_rank}] Tensors registered with NIXL")
except Exception as e:
logger.warning(
f"[Worker {ctx.global_rank}] NIXL registration failed, "
f"worker will continue without P2P serving: {e}"
)
def publish_metadata(ctx: LoadContext) -> None:
if ctx.nixl_manager is None:
logger.info(
f"[Worker {ctx.global_rank}] No NIXL manager, skipping metadata publish"
)
return
if not _metadata_publication_configured(ctx):
logger.info(
f"[Worker {ctx.global_rank}] No MX server configured, skipping metadata publish"
)
return
try:
publish_metadata_and_ready(
ctx.mx_client, ctx.nixl_manager, ctx.tensors,
ctx.worker_rank, ctx.device_id, ctx.identity, ctx.worker_id,
accelerator=ctx.accelerator_backend.name,
ready_fn=ctx.source_ready_fn,
)
except Exception as e:
logger.warning(
f"[Worker {ctx.global_rank}] Failed to publish metadata, "
f"worker will continue without P2P serving: {e}"
)
def publish_source_if_supported(result: LoadResult, ctx: LoadContext) -> None:
if result.model_for_publish is None:
return
publish_metadata(ctx)
def unpublish_metadata(ctx: LoadContext) -> None:
unpublish_metadata_for_worker(
worker_rank=ctx.worker_rank,
device_id=ctx.device_id,
)
def drain_tensor_readers(ctx: LoadContext, *, timeout: float) -> None:
from ..metadata.publish import _heartbeat_threads, _worker_servers
worker_server = _worker_servers.get(ctx.device_id)
if worker_server is not None:
worker_server.drain_tensor_reads(timeout)
return
if _heartbeat_threads.get(ctx.worker_rank) is not None:
raise RuntimeError(
"active refit cannot safely mutate centrally published tensors; "
"enable MX_P2P_METADATA"
)
def unpublish_metadata_for_worker(*, worker_rank: int, device_id: int) -> None:
from ..metadata.publish import _heartbeat_threads, _worker_servers
hb = _heartbeat_threads.pop(worker_rank, None)
if hb is not None:
try:
hb.stop() logger.info(f"[Worker {worker_rank}] Heartbeat stopped")
except Exception as e:
logger.warning(
f"[Worker {worker_rank}] Failed to stop heartbeat cleanly: {e}"
)
ws = _worker_servers.pop(device_id, None)
if ws is not None:
try:
ws.stop()
logger.info(f"[Worker {worker_rank}] Worker gRPC server stopped")
except Exception as e:
logger.warning(
f"[Worker {worker_rank}] Failed to stop worker gRPC server cleanly: {e}"
)