Install a manifest through vLLM's in-process `reload_weights` utility path. This adapter is for single-process vLLM deployments, for example vLLM V1 with `VLLM_ENABLE_V1_MULTIPROCESSING=0`. It is a real hot-weight install path, but it is not CUDA IPC zero-copy: tensors are passed d
| 325 | |
| 326 | |
| 327 | class VLLMInProcessWeightReloadAdapter: |
| 328 | """ |
| 329 | Install a manifest through vLLM's in-process `reload_weights` utility path. |
| 330 | |
| 331 | This adapter is for single-process vLLM deployments, for example vLLM V1 |
| 332 | with `VLLM_ENABLE_V1_MULTIPROCESSING=0`. It is a real hot-weight install |
| 333 | path, but it is not CUDA IPC zero-copy: tensors are passed directly to the |
| 334 | in-process worker and vLLM performs the model reload/copy into GPU weights. |
| 335 | Multiprocess vLLM should use the IPC or NCCL public `update_weights` APIs |
| 336 | once those transports are validated on the target hardware. |
| 337 | """ |
| 338 | |
| 339 | def __init__( |
| 340 | self, |
| 341 | engine: Any, |
| 342 | *, |
| 343 | target_dtype: Optional[torch.dtype] = None, |
| 344 | target_device: Optional[torch.device | str] = None, |
| 345 | is_checkpoint_format: bool = True, |
| 346 | synchronize_cuda: bool = True, |
| 347 | ): |
| 348 | self.engine = engine |
| 349 | self.target_dtype = target_dtype |
| 350 | self.target_device = target_device |
| 351 | self.is_checkpoint_format = bool(is_checkpoint_format) |
| 352 | self.synchronize_cuda = bool(synchronize_cuda) |
| 353 | self.active_weight_version: Optional[int] = None |
| 354 | self.active_update_id: Optional[str] = None |
| 355 | |
| 356 | def install( |
| 357 | self, |
| 358 | manifest: WeightUpdateManifest, |
| 359 | tensors: Mapping[str, torch.Tensor], |
| 360 | ) -> None: |
| 361 | WeightLayout.from_metadata(manifest.metadata).validate_supported() |
| 362 | tensor_map = dict(tensors) |
| 363 | if set(tensor_map) != set(manifest.tensors): |
| 364 | missing = sorted(set(manifest.tensors) - set(tensor_map)) |
| 365 | extra = sorted(set(tensor_map) - set(manifest.tensors)) |
| 366 | raise WeightManifestValidationError( |
| 367 | f"vLLM reload tensor set mismatch: missing={missing}, extra={extra}" |
| 368 | ) |
| 369 | |
| 370 | weights: list[tuple[str, torch.Tensor]] = [] |
| 371 | for name, descriptor in manifest.tensors.items(): |
| 372 | tensor = tensor_map[name] |
| 373 | if tuple(int(dim) for dim in tensor.shape) != descriptor.shape: |
| 374 | raise WeightManifestValidationError( |
| 375 | f"vLLM reload tensor shape mismatch for {name}: " |
| 376 | f"expected {descriptor.shape}, got {tuple(tensor.shape)}" |
| 377 | ) |
| 378 | if str(tensor.dtype) != descriptor.dtype: |
| 379 | raise WeightManifestValidationError( |
| 380 | f"vLLM reload tensor dtype mismatch for {name}: " |
| 381 | f"expected {descriptor.dtype}, got {tensor.dtype}" |
| 382 | ) |
| 383 | |
| 384 | weight = tensor.detach() |
no outgoing calls