RemoteMpiCommSessionClient is a variant of MpiCommSession that is used to connect to a remote MPI pool. Note: This class uses a global singleton pattern because ZeroMQ PAIR sockets only support one connection at a time. Multiple LLM instances will reuse the same client connection.
| 297 | |
| 298 | |
| 299 | class RemoteMpiCommSessionClient(MpiSession): |
| 300 | ''' |
| 301 | RemoteMpiCommSessionClient is a variant of MpiCommSession that is used to connect to a remote MPI pool. |
| 302 | |
| 303 | Note: This class uses a global singleton pattern because ZeroMQ PAIR sockets only support |
| 304 | one connection at a time. Multiple LLM instances will reuse the same client connection. |
| 305 | ''' |
| 306 | _global_instance = None |
| 307 | _global_instance_lock = threading.Lock() |
| 308 | |
| 309 | def __new__(cls, addr: str, hmac_key: Optional[bytes] = None): |
| 310 | # Implement singleton pattern to reuse the same client connection |
| 311 | # for multiple LLM instances, since PAIR sockets only support one connection |
| 312 | with cls._global_instance_lock: |
| 313 | if cls._global_instance is None or cls._global_instance.addr != addr: |
| 314 | logger_debug( |
| 315 | f"Creating new global RemoteMpiCommSessionClient for {addr}\n", |
| 316 | "yellow") |
| 317 | instance = super().__new__(cls) |
| 318 | cls._global_instance = instance |
| 319 | instance._initialized = False |
| 320 | else: |
| 321 | logger_debug( |
| 322 | f"Reusing existing global RemoteMpiCommSessionClient for {addr}\n", |
| 323 | "yellow") |
| 324 | return cls._global_instance |
| 325 | |
| 326 | def __init__(self, addr: str, hmac_key: Optional[bytes] = None): |
| 327 | # Only initialize once |
| 328 | if self._initialized: |
| 329 | return |
| 330 | |
| 331 | # FIXME: this is a hack to avoid circular import, resolve later |
| 332 | from tensorrt_llm.executor.ipc import ZeroMqQueue |
| 333 | self.addr = addr |
| 334 | logger_debug(f"RemoteMpiCommSessionClient connecting to {addr}\n", |
| 335 | "yellow") |
| 336 | self.queue = ZeroMqQueue((addr, hmac_key), |
| 337 | is_server=False, |
| 338 | socket_type=zmq.PAIR, |
| 339 | use_hmac_encryption=bool(hmac_key)) |
| 340 | self._is_shutdown = False |
| 341 | self._initialized = True |
| 342 | |
| 343 | def submit(self, |
| 344 | task: Callable[..., T], |
| 345 | *args, |
| 346 | sync: bool = False, |
| 347 | **kwargs) -> list: |
| 348 | ''' Submit a task to the remote MPI pool. ''' |
| 349 | if self._is_shutdown: |
| 350 | logger_debug("RemoteMpiCommSessionClient is already shut down\n", |
| 351 | "yellow") |
| 352 | return [] |
| 353 | logger_debug( |
| 354 | f"RemoteMpiCommSessionClient [rank{global_mpi_rank()}] sending task {task} to {self.addr}\n", |
| 355 | "yellow") |
| 356 | self.queue.put(RemoteTask(task, args, kwargs, sync=sync)) |
no outgoing calls