Either use the existing placement group from driver script (e.g., in the case of RL FW integration), or create a default PACK placement group where each bundle has tp_size GPUs. - When tp_size ≤ GPUs per node, keep one TP group per node. - When tp_size > GPUs per
(
self,
tp_size: int,
worker_kwargs: Dict = None)
| 346 | return [worker.__ray_ready__.remote() for worker in self.workers] |
| 347 | |
| 348 | def _get_placement_group( |
| 349 | self, |
| 350 | tp_size: int, |
| 351 | worker_kwargs: Dict = None) -> Tuple[Any, List[int]]: |
| 352 | """ |
| 353 | Either use the existing placement group from driver script (e.g., in the case of RL FW integration), |
| 354 | or create a default PACK placement group where each bundle has tp_size GPUs. |
| 355 | - When tp_size ≤ GPUs per node, keep one TP group per node. |
| 356 | - When tp_size > GPUs per node, allow a TP group span nodes. |
| 357 | - rank 0 must be put on the driver node |
| 358 | |
| 359 | Returns: |
| 360 | Tuple of (placement_group(s), bundle_indices) |
| 361 | - placement_group(s) can be a single PlacementGroup or a List[PlacementGroup] |
| 362 | - bundle_indices is always a List[int] |
| 363 | """ |
| 364 | llm_args = worker_kwargs.get("llm_args") if worker_kwargs else None |
| 365 | |
| 366 | placement_config = getattr(llm_args, 'ray_placement_config', |
| 367 | None) if llm_args else None |
| 368 | if placement_config and placement_config.placement_groups is not None: |
| 369 | total_workers = sum( |
| 370 | len(indices) |
| 371 | for indices in placement_config.placement_bundle_indices) |
| 372 | if total_workers != self.world_size: |
| 373 | raise ValueError( |
| 374 | f"Total bundle indices ({total_workers}) must equal world_size ({self.world_size})" |
| 375 | ) |
| 376 | |
| 377 | logger.info( |
| 378 | f"Creating {self.world_size} workers with external placement groups" |
| 379 | ) |
| 380 | |
| 381 | flat_pgs = [] |
| 382 | flat_indices = [] |
| 383 | for pg, indices in zip(placement_config.placement_groups, |
| 384 | placement_config.placement_bundle_indices): |
| 385 | for idx in indices: |
| 386 | flat_pgs.append(pg) |
| 387 | flat_indices.append(idx) |
| 388 | |
| 389 | return flat_pgs, flat_indices |
| 390 | |
| 391 | bundle_indices = os.getenv("TRTLLM_RAY_BUNDLE_INDICES", None) |
| 392 | |
| 393 | if bundle_indices: |
| 394 | pg = get_current_placement_group() |
| 395 | if pg is not None: |
| 396 | bundle_indices = list(map(int, bundle_indices.split(","))) |
| 397 | assert len(bundle_indices) == self.world_size, ( |
| 398 | f"Need {self.world_size} bundle indices for world_size, got {bundle_indices=}" |
| 399 | ) |
| 400 | assert len(set(bundle_indices)) == len(bundle_indices), \ |
| 401 | f"TRTLLM_RAY_BUNDLE_INDICES cannot have duplicate values, but got {bundle_indices=}." |
| 402 | |
| 403 | assert max(bundle_indices) < len(pg.bundle_specs), \ |
| 404 | f"{bundle_indices=} out of range for PG with {len(pg.bundle_specs)} bundles" |
| 405 |