from __future__ import annotations
import hashlib
from abc import ABC, abstractmethod
from collections.abc import Callable
from dataclasses import dataclass
from enum import Enum
from functools import cached_property
from typing import TYPE_CHECKING, Any, Protocol
if TYPE_CHECKING:
import torch
class NixlMetadataProvider(Protocol):
@property
def agent_name(self) -> str:
...
@property
def nixl_metadata(self) -> bytes:
...
@property
def listen_port(self) -> int | None:
...
def register_tensors(self, tensors: dict[str, torch.Tensor]) -> bytes:
...
class TrainerStagingMode(str, Enum):
UNSPECIFIED = "UNSPECIFIED"
COPY_TO_DEVICE = "COPY_TO_DEVICE"
COPY_TO_HOST = "COPY_TO_HOST"
WRITE_TO_STORAGE = "WRITE_TO_STORAGE"
IN_PLACE = "IN_PLACE"
class WeightPayloadFormat(str, Enum):
UNSPECIFIED = "UNSPECIFIED"
FULL_TENSOR = "FULL_TENSOR"
XOR_DELTA = "XOR_DELTA"
FULL_HF_CHECKPOINT = "FULL_HF_CHECKPOINT"
@dataclass(frozen=True)
class CompletionFence:
_wait: Callable[[], None]
def wait(self) -> None:
self._wait()
@dataclass(frozen=True)
class WeightVersionShardManifest:
data: bytes
tensor_count: int
total_bytes: int
transport: str
def __post_init__(self) -> None:
if not self.data:
raise ValueError("manifest data must not be empty")
if self.tensor_count <= 0:
raise ValueError("tensor_count must be positive")
if self.total_bytes <= 0:
raise ValueError("total_bytes must be positive")
if not self.transport:
raise ValueError("transport must not be empty")
@cached_property
def digest(self) -> str:
return hashlib.sha256(self.data).hexdigest()
@dataclass(frozen=True)
class StagedWeightVersionShardData:
manifest: WeightVersionShardManifest
publish_ready: CompletionFence
buffer_owner: object | None = None
class TrainerEngineAdapter(ABC):
@property
@abstractmethod
def source_slot_id(self) -> str:
@abstractmethod
def bind_tensors(self, tensors: Any) -> str:
@property
@abstractmethod
def supported_staging_modes(self) -> frozenset[TrainerStagingMode]:
@property
@abstractmethod
def supported_payload_formats(self) -> frozenset[WeightPayloadFormat]:
@abstractmethod
def stage_shard(
self,
*,
tensors: Any,
staging_mode: TrainerStagingMode,
payload_format: WeightPayloadFormat,
) -> StagedWeightVersionShardData:
class WeightVersionShardManifestPublisher(Protocol):
def publish_manifest(
self,
*,
version_id: str,
source_slot_id: str,
manifest: WeightVersionShardManifest,
) -> str:
def release_manifest(self, *, version_id: str, source_slot_id: str) -> None:
__all__ = [
"CompletionFence",
"NixlMetadataProvider",
"StagedWeightVersionShardData",
"TrainerEngineAdapter",
"TrainerStagingMode",
"WeightPayloadFormat",
"WeightVersionShardManifest",
"WeightVersionShardManifestPublisher",
]