Skip to content

Commit 0b0d7c8

Browse files
authored
Add Ray Serve Deployment Support for Multimodal Models (#574)
1 parent 990a3a7 commit 0b0d7c8

6 files changed

Lines changed: 1353 additions & 0 deletions

File tree

‎nemo_deploy/deploy_ray.py‎

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
from nemo_deploy.llm.hf_deployable_ray import HFRayDeployable
2929
from nemo_deploy.llm.megatronllm_deployable_ray import MegatronRayDeployable
30+
from nemo_deploy.multimodal.megatron_multimodal_deployable_ray import MegatronMultimodalRayDeployable
3031
from nemo_export.tensorrt_llm_deployable_ray import TensorRTLLMRayDeployable
3132

3233
HAVE_RAY = True
@@ -39,6 +40,7 @@
3940
MegatronRayDeployable = MagicMock()
4041
HFRayDeployable = MagicMock()
4142
TensorRTLLMRayDeployable = MagicMock()
43+
MegatronMultimodalRayDeployable = MagicMock()
4244
HAVE_RAY = False
4345

4446
LOGGER = logging.getLogger("NeMo")
@@ -470,3 +472,83 @@ def deploy_tensorrt_llm_model(
470472
LOGGER.error(f"Error during TensorRT-LLM model deployment: {str(e)}")
471473
self._stop()
472474
sys.exit(1)
475+
476+
def deploy_vlm_inframework_model(
477+
self,
478+
megatron_checkpoint: str,
479+
num_gpus: int = 1,
480+
tensor_model_parallel_size: int = 1,
481+
pipeline_model_parallel_size: int = 1,
482+
model_id: str = "megatron-multimodal-model",
483+
num_cpus_per_replica: float = 8,
484+
num_replicas: int = 1,
485+
test_mode: bool = False,
486+
**model_config_kwargs,
487+
):
488+
"""Deploy an inframework Megatron multimodal (VLM) model using Ray Serve.
489+
490+
This method handles the complete deployment lifecycle for multimodal models including:
491+
- Starting Ray Serve
492+
- Creating and deploying the MegatronMultimodalRayDeployable
493+
- Setting up signal handlers for graceful shutdown
494+
- Keeping the deployment running until interrupted
495+
496+
Args:
497+
megatron_checkpoint (str): Path to the Megatron checkpoint directory.
498+
num_gpus (int, optional): Number of GPUs per node. Defaults to 1.
499+
tensor_model_parallel_size (int, optional): Tensor model parallel size. Defaults to 1.
500+
pipeline_model_parallel_size (int, optional): Pipeline model parallel size. Defaults to 1.
501+
model_id (str, optional): Model identifier for API responses. Defaults to "megatron-multimodal-model".
502+
num_cpus_per_replica (float, optional): CPUs per model replica. Defaults to 8.
503+
num_replicas (int, optional): Number of replicas for deployment. Defaults to 1.
504+
test_mode (bool, optional): Enable test mode. Defaults to False.
505+
**model_config_kwargs: Additional model configuration arguments (e.g., params_dtype,
506+
inference_batch_times_seqlen_threshold, inference_max_seq_length).
507+
508+
Raises:
509+
SystemExit: If parallelism configuration is invalid.
510+
Exception: If deployment fails.
511+
"""
512+
if not HAVE_RAY:
513+
raise UnavailableError(MISSING_RAY_MSG)
514+
515+
# Calculate total GPUs and GPUs per replica
516+
gpus_per_replica = num_gpus // num_replicas
517+
518+
LOGGER.info(f"Configuration: {num_replicas} replicas, {gpus_per_replica} GPUs per replica")
519+
520+
# Set up signal handlers for graceful shutdown
521+
signal.signal(signal.SIGINT, self._signal_handler)
522+
signal.signal(signal.SIGTERM, self._signal_handler)
523+
524+
try:
525+
# Start Ray Serve
526+
self._start()
527+
528+
# Create the Multi-Rank Megatron multimodal model deployment
529+
app = MegatronMultimodalRayDeployable.options(
530+
num_replicas=num_replicas,
531+
ray_actor_options={"num_cpus": num_cpus_per_replica},
532+
).bind(
533+
megatron_checkpoint_filepath=megatron_checkpoint,
534+
num_gpus=gpus_per_replica,
535+
tensor_model_parallel_size=tensor_model_parallel_size,
536+
pipeline_model_parallel_size=pipeline_model_parallel_size,
537+
model_id=model_id,
538+
**model_config_kwargs,
539+
)
540+
541+
# Deploy the model
542+
serve.run(app, name=model_id)
543+
544+
LOGGER.info(f"Megatron multimodal model deployed successfully at {self.host}:{self.port}")
545+
LOGGER.info("Press Ctrl+C to stop the deployment")
546+
547+
# Keep the deployment running
548+
while not test_mode:
549+
signal.pause()
550+
551+
except Exception as e:
552+
LOGGER.error(f"Error during multimodal model deployment: {str(e)}")
553+
self._stop()
554+
sys.exit(1)

0 commit comments

Comments
 (0)