from __future__ import annotations
import json
import logging
import math
import time
from collections import deque
import torch
from modelexpress import envs
from modelexpress.client import MxClient
from modelexpress.nixl_transfer import NixlTransferManager
from modelexpress.refit.reshard.cuda_pool import classic_cuda_alloc
from modelexpress.refit.reshard.rendezvous import gather_sources
from modelexpress.refit.reshard.transfer_plan import (
exact_descriptors,
execute_transfer,
plan_transfer,
)
from modelexpress.refit.reshard.transport import (
NixlReshardTransport,
ReadDescriptor,
)
from modelexpress.refit.reshard.types import (
CaptureResult,
IncompleteRefit,
UnsupportedReshard,
summarize_unsupported,
)
logger = logging.getLogger("modelexpress.refit.reshard.receiver")
def _max_gbps() -> float:
ceiling = envs.MX_RESHARD_MAX_GBPS
if not math.isfinite(ceiling):
logger.warning(
"MX_RESHARD_MAX_GBPS=%r is not a finite number; the throughput ceiling "
"is disabled for this run",
ceiling,
)
return 0.0
return ceiling
def handshake_endpoints_for_plan(
plan, session_to_agent: dict, agent_endpoints: dict
) -> dict:
needed = {
session_to_agent[session]
for session in plan.sessions()
if session in session_to_agent
}
missing = sorted(needed - set(agent_endpoints))
if missing:
raise RuntimeError(
f"[reshard] {len(missing)} trainer(s) in the transfer plan published no "
f"metadata endpoint to handshake with: {missing[:10]}"
)
return {
agent_name: endpoint
for agent_name, endpoint in agent_endpoints.items()
if agent_name in needed
}
def handshake_with_peers(
manager,
agent_endpoints: dict,
total_timeout: float,
attempt_timeout: float | None = None,
) -> None:
attempt_timeout = attempt_timeout or envs.MX_RESHARD_HANDSHAKE_ATTEMPT_S
backoff = envs.MX_RESHARD_HANDSHAKE_BACKOFF_S
pending = deque(agent_endpoints.items())
total = len(pending)
attempts: dict = {name: 0 for name in agent_endpoints}
last_error: dict = {}
deadline = time.monotonic() + total_timeout
succeeded = 0
stalled = 0
while pending:
remaining = deadline - time.monotonic()
if remaining <= 0:
outstanding = ", ".join(
f"{name}@{endpoint} ({attempts[name]} attempt(s), last: "
f"{type(last_error.get(name)).__name__}: {last_error.get(name)})"
for name, endpoint in pending
)
raise RuntimeError(
f"[reshard] P2P handshake incomplete after {total_timeout:.0f}s: "
f"{succeeded} of {total} peer(s) answered. Outstanding: "
f"{outstanding}. These publishers are advertised in the MX catalog "
f"but did not answer - either the process is gone while something "
f"still heartbeats its source, or its NIXL listen thread is not "
f"accepting."
)
agent_name, endpoint = pending.popleft()
this_timeout = min(attempt_timeout, remaining)
attempts[agent_name] += 1
logger.info(
"[reshard] _prepare: handshake %d/%d %s at %s (attempt %d, timeout=%.0fs)",
succeeded + 1,
total,
agent_name,
endpoint,
attempts[agent_name],
this_timeout,
)
started = time.perf_counter()
try:
host, port_str = endpoint.rsplit(":", 1)
manager.fetch_remote_and_wait(
agent_name, host, int(port_str), timeout_seconds=this_timeout
)
except Exception as exc: last_error[agent_name] = exc
logger.warning(
"[reshard] _prepare: handshake %s at %s failed after %.1fs on "
"attempt %d (%s: %s); deferring, %d peer(s) still pending",
agent_name,
endpoint,
time.perf_counter() - started,
attempts[agent_name],
type(exc).__name__,
exc,
len(pending) + 1,
)
pending.append((agent_name, endpoint))
stalled += 1
if stalled >= len(pending):
time.sleep(min(backoff, max(0.0, deadline - time.monotonic())))
stalled = 0
continue
succeeded += 1
stalled = 0
last_error.pop(agent_name, None)
logger.info(
"[reshard] _prepare: handshake %d/%d %s ok in %.2fs (attempt %d)",
succeeded,
total,
agent_name,
time.perf_counter() - started,
attempts[agent_name],
)
retried = {name: count for name, count in attempts.items() if count > 1}
if retried:
logger.warning(
"[reshard] _prepare: handshake completed with retries: %s", retried
)
def _coverage_floor() -> float:
floor = float(envs.MX_RESHARD_COVERAGE_FLOOR)
if not 0.0 <= floor <= 1.0:
raise ValueError(
f"MX_RESHARD_COVERAGE_FLOOR must be a fraction in [0.0, 1.0], got {floor}"
)
return floor
def _fused_wire_enabled() -> bool:
return envs.MX_RESHARD_FUSED_WIRE
def _batch_install_enabled() -> bool:
return envs.MX_RESHARD_BATCH_INSTALL
def _cache_descriptors_enabled() -> bool:
return envs.MX_RESHARD_CACHE_DESCRIPTORS
def _destinations_are_disjoint(destinations: list[torch.Tensor]) -> bool:
spans_by_storage: dict[int, list[tuple[int, int]]] = {}
for tensor in destinations:
if tensor.numel() == 0:
continue
min_element = int(tensor.storage_offset())
max_element = min_element
for size, stride in zip(tensor.shape, tensor.stride(), strict=True):
extent = (int(size) - 1) * int(stride)
min_element += min(0, extent)
max_element += max(0, extent)
element_size = int(tensor.element_size())
spans_by_storage.setdefault(
int(tensor.untyped_storage().data_ptr()), []
).append(
(
min_element * element_size,
(max_element + 1) * element_size,
)
)
for spans in spans_by_storage.values():
previous_end = -1
for start, end in sorted(spans):
if start < previous_end:
return False
previous_end = max(previous_end, end)
return True
def _replay_ops(tensor: torch.Tensor, op_chain: tuple) -> torch.Tensor:
value = tensor
for op_name, args, frozen_kwargs in op_chain:
kwargs = dict(frozen_kwargs)
if op_name == "__getitem__":
value = value.__getitem__(*args)
else:
value = getattr(value, op_name)(*args, **kwargs)
return value
class ReshardReceiver:
def __init__(
self,
*,
model_name: str,
mx_server: str,
agent_name: str,
local_rank: int,
global_rank: int,
num_trainer_sources: int,
device: torch.device,
listen_port: int,
timeout: float = 1200.0,
) -> None:
self._device = device
self._model_name = model_name
self._num_trainer_sources = num_trainer_sources
self._timeout = timeout
self._global_rank = global_rank
self._manager = NixlTransferManager(
agent_name=agent_name, device_id=local_rank, listen_port=listen_port
)
self._manager.initialize()
self._mx_client = MxClient(server_url=mx_server)
self._plan = None self._cached_descriptors: tuple | None = None
self._transport: NixlReshardTransport | None = None
self._recv_buffers: dict[
str, torch.Tensor
] = {} self._staging: dict[
str, torch.Tensor
] = {} self._staging_ptr: dict[str, int] = {}
self._full_staging: dict[str, torch.Tensor] = {}
self._full_staging_ptr: dict[str, int] = {}
self._param_ptr: dict[
str, int
] = {} self._prepare_stages: dict[str, float] = {}
logger.info(
"[reshard] receiver init: agent=%s global_rank=%d trainer_sources=%d",
agent_name,
global_rank,
num_trainer_sources,
)
def _capture(self, manifest: list) -> tuple[CaptureResult, dict]:
raise NotImplementedError
def _install(self, recv_buffers: dict) -> None:
raise NotImplementedError
def _prepare(self, timeout: float) -> None:
logger.info(
"[reshard] _prepare: discovering %d trainer source(s) (timeout=%.0fs)",
self._num_trainer_sources,
timeout,
)
self._prepare_stages = {}
_t = time.perf_counter()
sources, session_to_agent, session_to_device, agent_endpoints = gather_sources(
self._mx_client,
expected_trainers=self._num_trainer_sources,
model_name=self._model_name,
role="inference",
rank=self._global_rank,
timeout=timeout,
)
self._prepare_stages["prepare_discover_s"] = time.perf_counter() - _t
logger.info(
"[reshard] _prepare: discovered %d source(s), %d agent(s)",
len(sources),
len(agent_endpoints),
)
manifest = [
(name, src.dtype, tuple(src.global_shape)) for name, src in sources.items()
]
logger.info(
"[reshard] _prepare: capturing geometry over %d manifest entries",
len(manifest),
)
_t = time.perf_counter()
capture, param_layout = self._capture(manifest)
self._prepare_stages["prepare_capture_s"] = time.perf_counter() - _t
logger.info(
"[reshard] _prepare: captured %d copies, %d unsupported",
len(capture.copies),
len(capture.unsupported),
)
_t = time.perf_counter()
plan = plan_transfer(capture, sources)
self._prepare_stages["prepare_plan_s"] = time.perf_counter() - _t
all_params = sorted({c.param_name for c in capture.copies})
self._log_coverage(capture, param_layout, all_params, plan)
if plan.fallback:
causes = summarize_unsupported(
getattr(capture, "unsupported_reasons", {}) or {}
)
cause_text = (
"; ".join(f"{count} x {cause}" for cause, count in causes)
if causes
else "cause not recorded at capture"
)
raise UnsupportedReshard(
f"[reshard] {len(plan.fallback)} source(s) need the unimplemented "
f"full-pull path (unsupported reshard ops); refusing to serve stale "
f"weights. Causes: {cause_text}. Params: {plan.fallback[:10]}"
)
_t = time.perf_counter()
handshake_endpoints = handshake_endpoints_for_plan(
plan, session_to_agent, agent_endpoints
)
logger.info(
"[reshard] _prepare: P2P-fetching remote metadata from %d of %d agent(s)",
len(handshake_endpoints),
len(agent_endpoints),
)
handshake_with_peers(
self._manager,
handshake_endpoints,
envs.MX_RESHARD_HANDSHAKE_TIMEOUT_S,
)
self._prepare_stages["prepare_handshake_s"] = time.perf_counter() - _t
self._transport = NixlReshardTransport(
self._manager, session_to_agent, session_to_device, timeout_seconds=timeout
)
self._plan = plan
self._cached_descriptors = None
alloc_s = 0.0
register_s = 0.0
self._staging = {}
self._staging_ptr = {}
if plan.converts:
_t = time.perf_counter()
with classic_cuda_alloc():
self._staging = {
c.param_name: torch.empty(
c.dest_shape, dtype=c.src_dtype, device=self._device
)
for c in plan.converts
}
alloc_s += time.perf_counter() - _t
_t = time.perf_counter()
self._manager.register_tensors(
{f"__stage__{n}": t for n, t in self._staging.items()}
)
register_s += time.perf_counter() - _t
self._staging_ptr = {n: t.data_ptr() for n, t in self._staging.items()}
self._full_staging = {}
self._full_staging_ptr = {}
if plan.full_pulls:
_t = time.perf_counter()
with classic_cuda_alloc():
self._full_staging = {
full_pull.src_name: torch.empty(
full_pull.global_shape,
dtype=full_pull.dtype,
device=self._device,
)
for full_pull in plan.full_pulls
}
alloc_s += time.perf_counter() - _t
_t = time.perf_counter()
self._manager.register_tensors(
{
f"__full__{name}": tensor
for name, tensor in self._full_staging.items()
}
)
register_s += time.perf_counter() - _t
self._full_staging_ptr = {
name: tensor.data_ptr() for name, tensor in self._full_staging.items()
}
seg_params = {seg.param_name for seg in plan.segments}
self._recv_buffers = {}
_t = time.perf_counter()
with classic_cuda_alloc():
for name in all_params:
shape, dtype = param_layout[name]
self._recv_buffers[name] = torch.empty(
tuple(shape), dtype=dtype, device=self._device
)
alloc_s += time.perf_counter() - _t
self._param_ptr = {}
if seg_params:
_t = time.perf_counter()
self._manager.register_tensors(
{f"__recv__{n}": self._recv_buffers[n] for n in seg_params}
)
register_s += time.perf_counter() - _t
for name in seg_params:
self._param_ptr[name] = self._recv_buffers[name].data_ptr()
self._prepare_stages["prepare_alloc_s"] = alloc_s
self._prepare_stages["prepare_register_s"] = register_s
logger.info(
"[reshard] prepared: %d descriptor(s), %d full-pull source(s), "
"%d convert(s), %.1f MB/pull, %d descriptor(s) saved, "
"%.1f MB extra wire, %d unbounded source(s), %d fallback",
plan.descriptor_count(),
len(plan.full_pulls),
len(plan.converts),
plan.bytes_planned() / 1e6,
plan.descriptor_savings(),
plan.extra_wire_bytes() / 1e6,
len(plan.unbounded_sources),
len(plan.fallback),
)
def _log_coverage(self, capture, param_layout, all_params, plan) -> None:
installed = set(all_params)
dest_bytes = 0
engine_bytes = 0
missed: list[str] = []
for name, (shape, dtype) in param_layout.items():
count = 1
for dim in shape:
count *= int(dim)
nbytes = count * torch.empty(0, dtype=dtype).element_size()
engine_bytes += nbytes
if name in installed:
dest_bytes += nbytes
else:
missed.append(name)
coverage = (dest_bytes / engine_bytes) if engine_bytes else 0.0
unsupported = list(getattr(capture, "unsupported", []) or [])
record = {
"schema": "refit-coverage-v1",
"rank": self._global_rank,
"params_installed": len(all_params),
"engine_params": len(param_layout),
"dest_bytes": dest_bytes,
"engine_bytes": engine_bytes,
"coverage_pct": round(100.0 * coverage, 4),
"params_never_written": len(missed),
"params_never_written_sample": sorted(missed)[:10],
"copies_captured": len(capture.copies),
"unsupported": len(unsupported),
"unsupported_sample": [str(u)[:120] for u in unsupported[:10]],
"unsupported_causes": [
{"cause": cause[:200], "sources": count}
for cause, count in summarize_unsupported(
getattr(capture, "unsupported_reasons", {}) or {}
)
],
"planned_wire_bytes": plan.bytes_planned(),
"extra_wire_bytes": plan.extra_wire_bytes(),
"descriptors": plan.descriptor_count(),
"descriptor_savings": plan.descriptor_savings(),
"full_pull_sources": len(plan.full_pulls),
"unbounded_sources": len(plan.unbounded_sources),
"converts": len(plan.converts),
"fallback": len(plan.fallback),
}
complete = not missed and not unsupported and not plan.fallback
logger.log(
logging.INFO if complete else logging.WARNING,
"MX_REFIT_COVERAGE %s",
json.dumps(record),
)
if envs.MX_RESHARD_REQUIRE_FULL_COVERAGE and coverage < _coverage_floor():
raise IncompleteRefit(
f"refit covers {100.0 * coverage:.2f}% of the engine's parameter "
f"bytes ({dest_bytes} of {engine_bytes}); "
f"{len(missed)} of {len(param_layout)} params would keep their "
f"previous values, e.g. {sorted(missed)[:5]}. No digest gate can "
f"detect this - bytes that are never requested are never checked. "
f"Set MX_RESHARD_REQUIRE_FULL_COVERAGE=0 for an intentionally "
f"partial refit."
)
@torch.no_grad()
def update_weights(self, step: int, *, timeout: float | None = None) -> dict:
timeout = timeout if timeout is not None else self._timeout
stages: dict[str, float] = {}
if self._plan is None:
self._prepare(timeout)
stages.update(self._prepare_stages)
assert self._plan is not None and self._transport is not None
_t = time.perf_counter()
cached = _cache_descriptors_enabled()
fused = _fused_wire_enabled()
reusable = (
self._cached_descriptors is not None
and self._cached_descriptors[0] == fused
)
if not cached or not reusable:
full_descriptors = [
ReadDescriptor(
session=segment.session,
src_addr=segment.src_addr,
dst_addr=(
self._full_staging_ptr[full_pull.src_name] + segment.dst_byte
),
nbytes=segment.nbytes,
)
for full_pull in self._plan.full_pulls
for segment in full_pull.segments
]
convert_descriptors = [
ReadDescriptor(
session=segment.session,
src_addr=segment.src_addr,
dst_addr=self._staging_ptr[convert.param_name] + segment.dst_byte,
nbytes=segment.nbytes,
)
for convert in self._plan.converts
for segment in convert.segments
]
exact = (
exact_descriptors(self._plan, lambda name: self._param_ptr[name])
if fused
else None
)
aux_bytes = sum(
descriptor.nbytes
for descriptor in (*full_descriptors, *convert_descriptors)
)
if cached:
self._cached_descriptors = (
fused,
full_descriptors,
convert_descriptors,
exact,
aux_bytes,
)
else:
_, full_descriptors, convert_descriptors, exact, aux_bytes = (
self._cached_descriptors
)
stages["descriptor_build_s"] = time.perf_counter() - _t
if fused:
assert exact is not None
descriptors = exact
stats = {
"segments": len(descriptors),
"bytes": sum(descriptor.nbytes for descriptor in descriptors),
"fallback": list(self._plan.fallback),
}
_t = time.perf_counter()
self._transport.read(descriptors + full_descriptors + convert_descriptors)
stages["wire_fused_s"] = time.perf_counter() - _t
else:
if self._plan.segments:
_t = time.perf_counter()
stats = execute_transfer(
self._plan,
resolve_param_ptr=lambda name: self._param_ptr[name],
transport=self._transport,
)
stages["wire_exact_s"] = time.perf_counter() - _t
else:
stats = {
"segments": 0,
"bytes": 0,
"fallback": list(self._plan.fallback),
}
if full_descriptors:
_t = time.perf_counter()
self._transport.read(full_descriptors)
stages["wire_full_s"] = time.perf_counter() - _t
if convert_descriptors:
_t = time.perf_counter()
self._transport.read(convert_descriptors)
stages["wire_convert_s"] = time.perf_counter() - _t
stats["segments"] += len(full_descriptors) + len(convert_descriptors)
stats["bytes"] += aux_bytes
self._check_throughput_ceiling(step, stats["bytes"], stages)
if self._plan.full_pulls:
_t = time.perf_counter()
batched = _batch_install_enabled()
destinations: list[torch.Tensor] = []
source_views: list[torch.Tensor] = []
copies_done = 0
for full_pull in self._plan.full_pulls:
full_tensor = self._full_staging[full_pull.src_name]
for copy in full_pull.copies:
source_view = _replay_ops(full_tensor, copy.op_chain)
receive_buffer = self._recv_buffers[copy.param_name]
destination = receive_buffer.as_strided(
copy.dest_shape,
copy.dest_stride,
receive_buffer.storage_offset() + copy.dest_offset,
)
if batched:
destinations.append(destination)
source_views.append(source_view)
else:
destination.copy_(source_view)
copies_done += 1
reslice_copies = len(destinations) if batched else copies_done
if batched and destinations:
if _destinations_are_disjoint(destinations):
torch._foreach_copy_(destinations, source_views)
else:
for destination, source_view in zip(
destinations, source_views, strict=True
):
destination.copy_(source_view)
torch.cuda.synchronize(self._device)
stages["reslice_s"] = time.perf_counter() - _t
stages["reslice_copies"] = float(reslice_copies)
if self._plan.converts:
_t = time.perf_counter()
for convert in self._plan.converts:
self._recv_buffers[convert.param_name].copy_(
self._staging[convert.param_name]
)
torch.cuda.synchronize(self._device)
stages["convert_s"] = time.perf_counter() - _t
_t = time.perf_counter()
self._install(self._recv_buffers)
torch.cuda.synchronize(self._device)
stages["install_s"] = time.perf_counter() - _t
metrics = {
"step": step,
"bytes_received": stats["bytes"],
"segments": stats["segments"],
"converts": len(self._plan.converts),
"full_pull_sources": len(self._plan.full_pulls),
"exact_descriptors": self._plan.exact_descriptor_count,
"descriptor_savings": self._plan.descriptor_savings(),
"extra_wire_bytes": self._plan.extra_wire_bytes(),
"unbounded_sources": len(self._plan.unbounded_sources),
"fallback": len(stats["fallback"]),
}
logger.info(
"[reshard] refit step=%d bytes=%.1fMB descriptors=%d "
"(saved=%d, extra_wire=%.1fMB) full_pulls=%d converts=%d "
"unbounded=%d fallback=%d",
step,
stats["bytes"] / 1e6,
stats["segments"],
self._plan.descriptor_savings(),
self._plan.extra_wire_bytes() / 1e6,
len(self._plan.full_pulls),
len(self._plan.converts),
len(self._plan.unbounded_sources),
len(stats["fallback"]),
)
metrics.update({k: round(v, 6) for k, v in stages.items()})
if envs.MX_REFIT_STAGE_RECORD:
record = {
"schema": "refit-stage-v2",
"rank": self._global_rank,
"step": step,
"bytes": stats["bytes"],
"segments": stats["segments"],
"accounted_s": round(
sum(v for k, v in stages.items() if k.endswith("_s")), 6
),
"extra_wire_bytes": self._plan.extra_wire_bytes(),
"descriptor_savings": self._plan.descriptor_savings(),
"exact_descriptors": self._plan.exact_descriptor_count,
"full_pull_sources": len(self._plan.full_pulls),
"unbounded_sources": len(self._plan.unbounded_sources),
"converts": len(self._plan.converts),
"fallback": len(stats["fallback"]),
"fused_wire": _fused_wire_enabled(),
"batch_install": _batch_install_enabled(),
**{k: round(v, 6) for k, v in stages.items()},
}
logger.warning("MX_REFIT_STAGE %s", json.dumps(record))
return metrics
def _check_throughput_ceiling(
self, step: int, wire_bytes: int, stages: dict
) -> None:
ceiling = _max_gbps()
if ceiling <= 0 or wire_bytes <= 0:
return
wire_s = stages.get("wire_fused_s")
if wire_s is None:
wire_s = sum(
stages.get(key, 0.0)
for key in ("wire_exact_s", "wire_full_s", "wire_convert_s")
)
if wire_s <= 0:
return
implied_gbps = wire_bytes * 8 / wire_s / 1e9
if implied_gbps <= ceiling:
return
detail = {
"schema": "refit-impossible-throughput-v1",
"rank": self._global_rank,
"step": step,
"wire_bytes": wire_bytes,
"wire_s": round(wire_s, 6),
"implied_gbps": round(implied_gbps, 1),
"ceiling_gbps": ceiling,
}
logger.warning("MX_REFIT_IMPOSSIBLE_THROUGHPUT %s", json.dumps(detail))
raise RuntimeError(
f"[reshard] step {step} moved {wire_bytes} bytes in {wire_s:.4f}s, an "
f"implied {implied_gbps:.1f} Gbps against a per-rank ceiling of "
f"{ceiling:.1f} Gbps. The fabric cannot deliver that, so the transport "
f"reported completions without moving the payload - one known cause is "
f"the fabric library selecting adapters this container does not own. "
f"Treat this refit as failed, not fast."
)