From 44728050b4185657b41907fa306258be0b94eba7 Mon Sep 17 00:00:00 2001 From: Lu Peng Date: Thu, 2 Oct 2025 16:19:58 -0400 Subject: [PATCH] Added support to edit multi deployment. --- ads/aqua/modeldeployment/deployment.py | 197 ++++++---- ads/aqua/modeldeployment/entities.py | 339 +++++++++--------- .../modeldeployment/model_group_config.py | 23 +- .../with_extras/aqua/test_deployment.py | 18 +- 4 files changed, 329 insertions(+), 248 deletions(-) diff --git a/ads/aqua/modeldeployment/deployment.py b/ads/aqua/modeldeployment/deployment.py index fa7eebdf0..5b1aa1e8c 100644 --- a/ads/aqua/modeldeployment/deployment.py +++ b/ads/aqua/modeldeployment/deployment.py @@ -377,7 +377,7 @@ def create( combined_model_names, ) = self._build_model_group_configs( models=create_deployment_details.models, - create_deployment_details=create_deployment_details, + deployment_details=create_deployment_details, model_config_summary=model_config_summary, freeform_tags=freeform_tags, source_models=source_models, @@ -429,7 +429,9 @@ def _validate_input_models( def _build_model_group_configs( self, models: List[AquaMultiModelRef], - create_deployment_details: CreateModelDeploymentDetails, + deployment_details: Union[ + CreateModelDeploymentDetails, UpdateModelDeploymentDetails + ], model_config_summary: ModelDeploymentConfigSummary, freeform_tags: Optional[Dict] = None, source_models: Optional[Dict[str, DataScienceModel]] = None, @@ -442,9 +444,9 @@ def _build_model_group_configs( ---------- models : List[AquaMultiModelRef] List of AquaMultiModelRef instances for creating a multi-model group. - create_deployment_details : CreateModelDeploymentDetails - An instance of CreateModelDeploymentDetails containing all required and optional - fields for creating a model deployment via Aqua. + deployment_details : Union[CreateModelDeploymentDetails, UpdateModelDeploymentDetails] + An instance of CreateModelDeploymentDetails or UpdateModelDeploymentDetails containing all required and optional + fields for creating or updating a model deployment via Aqua. model_config_summary : ModelConfigSummary Summary Model Deployment configuration for the group of models. freeform_tags : Optional[Dict] @@ -667,7 +669,7 @@ def _build_model_group_configs( model_custom_metadata.add( key=AQUA_MULTI_MODEL_CONFIG, value=self._build_model_group_config( - create_deployment_details=create_deployment_details, + deployment_details=deployment_details, model_config_summary=model_config_summary, deployment_container=deployment_container, ).model_dump_json(), @@ -719,21 +721,21 @@ def _extract_model_task( def _build_model_group_config( self, - create_deployment_details, + deployment_details: Union[ + CreateModelDeploymentDetails, UpdateModelDeploymentDetails + ], model_config_summary, deployment_container: str, ) -> ModelGroupConfig: """Builds model group config required to deploy multi models.""" - container_type_key = ( - create_deployment_details.container_family or deployment_container - ) + container_type_key = deployment_details.container_family or deployment_container container_config = self.get_container_config_item(container_type_key) container_spec = container_config.spec if container_config else UNKNOWN container_params = container_spec.cli_param if container_spec else UNKNOWN - multi_model_config = ModelGroupConfig.from_create_model_deployment_details( - create_deployment_details, + multi_model_config = ModelGroupConfig.from_model_deployment_details( + deployment_details, model_config_summary, container_type_key, container_params, @@ -1305,7 +1307,7 @@ def update( # updates model group if fine tuned weights changed. model = self._update_model_group( - runtime.model_group_id, update_model_deployment_details + runtime.model_group_id, update_model_deployment_details, model_deployment ) # updates model group deployment infrastructure @@ -1356,7 +1358,9 @@ def update( # applies LIVE update if model group id has been changed if runtime.model_group_id != model.id: runtime.with_model_group_id(model.id) - update_type = ModelDeploymentUpdateType.LIVE + if model.dsc_model_group.model_group_details.type == DeploymentType.STACKED: + # only applies LIVE update for stacked deployment + update_type = ModelDeploymentUpdateType.LIVE freeform_tags = ( update_model_deployment_details.freeform_tags @@ -1395,6 +1399,7 @@ def _update_model_group( self, model_group_id: str, update_model_deployment_details: UpdateModelDeploymentDetails, + model_deployment: ModelDeployment, ) -> DataScienceModelGroup: """Creates a new model group if fine tuned weights changed. @@ -1405,6 +1410,8 @@ def _update_model_group( update_model_deployment_details: UpdateModelDeploymentDetails An instance of UpdateModelDeploymentDetails containing all optional fields for updating a model deployment via Aqua. + model_deployment: ModelDeployment + An instance of ModelDeployment. Returns ------- @@ -1412,62 +1419,124 @@ def _update_model_group( The instance of DataScienceModelGroup. """ model_group = DataScienceModelGroup.from_id(model_group_id) - if ( - model_group.dsc_model_group.model_group_details.type - != DeploymentType.STACKED - ): - raise AquaValueError( - "Invalid 'model_deployment_id'. Only stacked deployment is supported to update." - ) - # create a new model group if fine tune weights changed as member models in ds model group is inmutable if update_model_deployment_details.models: - if len(update_model_deployment_details.models) != 1: - raise AquaValueError( - "Invalid 'models' provided. Only one base model is required for updating model stack deployment." - ) # validates input base and fine tune models - self._validate_input_models(update_model_deployment_details) - target_stacked_model = update_model_deployment_details.models[0] - target_base_model_id = target_stacked_model.model_id - if model_group.base_model_id != target_base_model_id: - raise AquaValueError( - "Invalid parameter 'models'. Base model id can't be changed for stacked model deployment." + source_models, _ = self._validate_input_models( + update_model_deployment_details + ) + if ( + model_group.dsc_model_group.model_group_details.type + == DeploymentType.STACKED + ): + # create a new model group if fine tune weights changed as member models in ds model group is inmutable + if len(update_model_deployment_details.models) != 1: + raise AquaValueError( + "Invalid 'models' provided. Only one base model is required for updating model stack deployment." + ) + target_stacked_model = update_model_deployment_details.models[0] + target_base_model_id = target_stacked_model.model_id + if model_group.base_model_id != target_base_model_id: + raise AquaValueError( + "Invalid parameter 'models'. Base model id can't be changed for stacked model deployment." + ) + + # add member models + member_models = [ + { + "inference_key": fine_tune_weight.model_name, + "model_id": fine_tune_weight.model_id, + } + for fine_tune_weight in target_stacked_model.fine_tune_weights + ] + # add base model + member_models.append( + { + "inference_key": target_stacked_model.model_name, + "model_id": target_base_model_id, + } ) - # add member models - member_models = [ - { - "inference_key": fine_tune_weight.model_name, - "model_id": fine_tune_weight.model_id, - } - for fine_tune_weight in target_stacked_model.fine_tune_weights - ] - # add base model - member_models.append( - { - "inference_key": target_stacked_model.model_name, - "model_id": target_base_model_id, - } - ) + # creates a model group with the same configurations from original model group except member models + model_group = ( + DataScienceModelGroup() + .with_compartment_id(model_group.compartment_id) + .with_project_id(model_group.project_id) + .with_display_name(model_group.display_name) + .with_description(model_group.description) + .with_freeform_tags(**(model_group.freeform_tags or {})) + .with_defined_tags(**(model_group.defined_tags or {})) + .with_custom_metadata_list(model_group.custom_metadata_list) + .with_base_model_id(target_base_model_id) + .with_member_models(member_models) + .create() + ) - # creates a model group with the same configurations from original model group except member models - model_group = ( - DataScienceModelGroup() - .with_compartment_id(model_group.compartment_id) - .with_project_id(model_group.project_id) - .with_display_name(model_group.display_name) - .with_description(model_group.description) - .with_freeform_tags(**(model_group.freeform_tags or {})) - .with_defined_tags(**(model_group.defined_tags or {})) - .with_custom_metadata_list(model_group.custom_metadata_list) - .with_base_model_id(target_base_model_id) - .with_member_models(member_models) - .create() - ) + logger.info( + f"Model group of base model {target_base_model_id} has been updated: {model_group.id}." + ) + else: + compartment_id = model_deployment.infrastructure.compartment_id + project_id = model_deployment.infrastructure.project_id + freeform_tags = ( + update_model_deployment_details.freeform_tags + or model_deployment.freeform_tags + ) + defined_tags = ( + update_model_deployment_details.defined_tags + or model_deployment.defined_tags + ) + # needs instance shape here for building the multi model config from update_model_deployment_details + update_model_deployment_details.instance_shape = ( + model_deployment.infrastructure.shape_name + ) - logger.info( - f"Model group of base model {target_base_model_id} has been updated: {model_group.id}." - ) + # rebuilds MULTI_MODEL_CONFIG and creates model group + base_model_ids = [ + model.model_id for model in update_model_deployment_details.models + ] + + try: + model_config_summary = self.get_multimodel_deployment_config( + model_ids=base_model_ids, compartment_id=compartment_id + ) + if not model_config_summary.gpu_allocation: + raise AquaValueError(model_config_summary.error_message) + + update_model_deployment_details.validate_multimodel_deployment_feasibility( + models_config_summary=model_config_summary + ) + except ConfigValidationError as err: + raise AquaValueError(f"{err}") from err + + ( + model_group_display_name, + model_group_description, + tags, + model_custom_metadata, + combined_model_names, + ) = self._build_model_group_configs( + models=update_model_deployment_details.models, + deployment_details=update_model_deployment_details, + model_config_summary=model_config_summary, + freeform_tags=freeform_tags, + source_models=source_models, + ) + + model_group = AquaModelApp().create_multi( + models=update_model_deployment_details.models, + model_custom_metadata=model_custom_metadata, + model_group_display_name=model_group_display_name, + model_group_description=model_group_description, + tags=tags, + combined_model_names=combined_model_names, + compartment_id=compartment_id, + project_id=project_id, + defined_tags=defined_tags, + ) + + logger.info( + f"Model group of multi model deployment {model_deployment.id} has been updated: {model_group.id}." + ) return model_group diff --git a/ads/aqua/modeldeployment/entities.py b/ads/aqua/modeldeployment/entities.py index 2076da1e2..daf7e0e8e 100644 --- a/ads/aqua/modeldeployment/entities.py +++ b/ads/aqua/modeldeployment/entities.py @@ -255,6 +255,9 @@ class Config: class ModelDeploymentDetails(BaseModel): """Class for the base details of creating and updating Aqua model deployments.""" + instance_shape: str = Field( + None, description="The instance shape used for deployment." + ) display_name: Optional[str] = Field( None, description="The name of the model deployment." ) @@ -267,6 +270,9 @@ class ModelDeploymentDetails(BaseModel): instance_count: Optional[int] = Field( None, description="Number of instances used for deployment." ) + container_family: Optional[str] = Field( + None, description="Image family of the model deployment container runtime." + ) log_group_id: Optional[str] = Field( None, description="OCI logging group ID for logs." ) @@ -299,6 +305,172 @@ class ModelDeploymentDetails(BaseModel): None, description="Defined tags for model deployment." ) + def validate_multimodel_deployment_feasibility( + self, models_config_summary: ModelDeploymentConfigSummary + ) -> None: + """ + Validates whether the selected model group is feasible for a multi-model deployment + on the chosen instance shape. + + Validation Criteria: + - Ensures that the model group is not empty. + - Verifies that the selected instance shape is supported by the GPU allocation. + - Confirms that each model in the group has a corresponding deployment configuration. + - Ensures that each model's user-specified GPU allocation is allowed by its deployment configuration. + - Checks that the total GPUs requested by the model group does not exceed the available GPU capacity + for the selected instance shape. + + Parameters + ---------- + models_config_summary : ModelDeploymentConfigSummary + Contains GPU allocations and deployment configuration for models. + + Raises + ------ + ConfigValidationError: + - If the model group is empty. + - If the selected instance shape is not supported. + - If any model is missing from the deployment configuration. + - If a model's GPU allocation does not match any valid configuration. + - If the total requested GPUs exceed the instance shape’s capacity. + """ + # Ensure that at least one model is provided. + if not self.models: + logger.error("No models provided in the model group.") + raise ConfigValidationError( + "Multi-model deployment requires at least one model. Please provide one or more models." + ) + + selected_shape = self.instance_shape + + if models_config_summary.error_message: + logger.error(models_config_summary.error_message) + raise ConfigValidationError(models_config_summary.error_message) + + # Verify that the selected shape is supported by the GPU allocation. + if selected_shape not in models_config_summary.gpu_allocation: + supported_shapes = list(models_config_summary.gpu_allocation.keys()) + error_message = ( + f"The model group is not compatible with the selected instance shape `{selected_shape}`. " + f"Supported shapes: {supported_shapes}." + ) + logger.error(error_message) + raise ConfigValidationError(error_message) + + total_available_gpus: int = models_config_summary.gpu_allocation[ + selected_shape + ].total_gpus_available + model_deployment_config = models_config_summary.deployment_config + + # Verify that every model in the group has a corresponding deployment configuration. + required_model_ids = {model.model_id for model in self.models} + missing_model_ids = required_model_ids - set(model_deployment_config.keys()) + if missing_model_ids: + error_message = ( + f"Missing deployment configuration for models: {list(missing_model_ids)}. " + "Ensure all selected models are properly configured. If you are deploying custom " + "models that lack AQUA service configuration, refer to the deployment guidelines here: " + "https://github.com/oracle-samples/oci-data-science-ai-samples/blob/main/ai-quick-actions/multimodel-deployment-tips.md#custom_models" + ) + logger.error(error_message) + raise ConfigValidationError(error_message) + + sum_model_gpus = 0 + is_single_model = len(self.models) == 1 + + # Validate each model's GPU allocation against its deployment configuration. + for model in self.models: + sum_model_gpus += model.gpu_count + aqua_deployment_config = model_deployment_config[model.model_id] + + # Skip validation for models without deployment configuration details. + if not aqua_deployment_config.configuration: + error_message = ( + f"Missing deployment configuration for model `{model.model_id}`. " + "Please verify that the model is correctly configured. If you are deploying custom models without AQUA service configuration, " + "refer to the guidelines at: " + "https://github.com/oracle-samples/oci-data-science-ai-samples/blob/main/ai-quick-actions/multimodel-deployment-tips.md#custom_models" + ) + + logger.error(error_message) + raise ConfigValidationError(error_message) + + allowed_shapes = ( + list( + set(aqua_deployment_config.configuration.keys()).union( + set(aqua_deployment_config.shape or []) + ) + ) + if is_single_model + else list(aqua_deployment_config.configuration.keys()) + ) + + if selected_shape not in allowed_shapes: + error_message = ( + f"Model `{model.model_id}` is not compatible with the selected instance shape `{selected_shape}`. " + f"Select a different instance shape from allowed shapes {allowed_shapes}." + ) + logger.error(error_message) + raise ConfigValidationError(error_message) + + # Retrieve valid GPU counts for the selected shape. + multi_model_configs = aqua_deployment_config.configuration.get( + selected_shape, ConfigurationItem() + ).multi_model_deployment + + valid_gpu_configurations = [cfg.gpu_count for cfg in multi_model_configs] + + if model.gpu_count not in valid_gpu_configurations: + valid_gpu_str = valid_gpu_configurations or [] + + if is_single_model: + # If total GPU allocation is not supported by selected model + if selected_shape not in aqua_deployment_config.shape: + error_message = ( + f"Model `{model.model_id}` is configured with {model.gpu_count} GPU(s), " + f"which is invalid. The allowed GPU configurations are: {valid_gpu_str}." + ) + logger.error(error_message) + raise ConfigValidationError(error_message) + + if model.gpu_count != total_available_gpus: + error_message = ( + f"Model '{model.model_id}' is configured to use {model.gpu_count} GPU(s), " + f"which not fully utilize the selected instance shape with {total_available_gpus} available GPU(s). " + "Consider adjusting the GPU allocation to better utilize the available resources and maximize performance." + ) + logger.error(error_message) + raise ConfigValidationError(error_message) + + else: + error_message = ( + f"Model `{model.model_id}` is configured with {model.gpu_count} GPU(s), which is invalid. " + f"Valid GPU configurations are: {valid_gpu_str}. Please adjust the GPU allocation " + f"or choose an instance shape that supports a higher GPU count." + ) + logger.error(error_message) + raise ConfigValidationError(error_message) + + if sum_model_gpus < total_available_gpus: + error_message = ( + f"Selected models are configured to use {sum_model_gpus} GPU(s), " + f"which not fully utilize the selected instance shape with {total_available_gpus} available GPU(s). " + "This configuration may lead to suboptimal performance for a multi-model deployment. " + "Consider adjusting the GPU allocation to better utilize the available resources and maximize performance." + ) + logger.warning(error_message) + # raise ConfigValidationError(error_message) + + # Check that the total GPU count for the model group does not exceed the instance capacity. + if sum_model_gpus > total_available_gpus: + error_message = ( + f"The selected instance shape `{selected_shape}` provides `{total_available_gpus}` GPU(s), " + f"but the total GPU allocation required by the model group is `{sum_model_gpus}` GPU(s). " + "Please adjust the GPU allocation per model or choose an instance shape with greater GPU capacity." + ) + logger.error(error_message) + raise ConfigValidationError(error_message) + def validate_input_models(self, model_details: Dict[str, DataScienceModel]) -> None: """ Validates the input models for a stacked-model or multi-model deployment configuration. @@ -565,6 +737,7 @@ class Config: extra = "allow" protected_namespaces = () + class CreateModelDeploymentDetails(ModelDeploymentDetails): """Class for creating Aqua model deployments.""" @@ -621,172 +794,6 @@ def validate(cls, values: Any) -> Any: ) return values - def validate_multimodel_deployment_feasibility( - self, models_config_summary: ModelDeploymentConfigSummary - ) -> None: - """ - Validates whether the selected model group is feasible for a multi-model deployment - on the chosen instance shape. - - Validation Criteria: - - Ensures that the model group is not empty. - - Verifies that the selected instance shape is supported by the GPU allocation. - - Confirms that each model in the group has a corresponding deployment configuration. - - Ensures that each model's user-specified GPU allocation is allowed by its deployment configuration. - - Checks that the total GPUs requested by the model group does not exceed the available GPU capacity - for the selected instance shape. - - Parameters - ---------- - models_config_summary : ModelDeploymentConfigSummary - Contains GPU allocations and deployment configuration for models. - - Raises - ------ - ConfigValidationError: - - If the model group is empty. - - If the selected instance shape is not supported. - - If any model is missing from the deployment configuration. - - If a model's GPU allocation does not match any valid configuration. - - If the total requested GPUs exceed the instance shape’s capacity. - """ - # Ensure that at least one model is provided. - if not self.models: - logger.error("No models provided in the model group.") - raise ConfigValidationError( - "Multi-model deployment requires at least one model. Please provide one or more models." - ) - - selected_shape = self.instance_shape - - if models_config_summary.error_message: - logger.error(models_config_summary.error_message) - raise ConfigValidationError(models_config_summary.error_message) - - # Verify that the selected shape is supported by the GPU allocation. - if selected_shape not in models_config_summary.gpu_allocation: - supported_shapes = list(models_config_summary.gpu_allocation.keys()) - error_message = ( - f"The model group is not compatible with the selected instance shape `{selected_shape}`. " - f"Supported shapes: {supported_shapes}." - ) - logger.error(error_message) - raise ConfigValidationError(error_message) - - total_available_gpus: int = models_config_summary.gpu_allocation[ - selected_shape - ].total_gpus_available - model_deployment_config = models_config_summary.deployment_config - - # Verify that every model in the group has a corresponding deployment configuration. - required_model_ids = {model.model_id for model in self.models} - missing_model_ids = required_model_ids - set(model_deployment_config.keys()) - if missing_model_ids: - error_message = ( - f"Missing deployment configuration for models: {list(missing_model_ids)}. " - "Ensure all selected models are properly configured. If you are deploying custom " - "models that lack AQUA service configuration, refer to the deployment guidelines here: " - "https://github.com/oracle-samples/oci-data-science-ai-samples/blob/main/ai-quick-actions/multimodel-deployment-tips.md#custom_models" - ) - logger.error(error_message) - raise ConfigValidationError(error_message) - - sum_model_gpus = 0 - is_single_model = len(self.models) == 1 - - # Validate each model's GPU allocation against its deployment configuration. - for model in self.models: - sum_model_gpus += model.gpu_count - aqua_deployment_config = model_deployment_config[model.model_id] - - # Skip validation for models without deployment configuration details. - if not aqua_deployment_config.configuration: - error_message = ( - f"Missing deployment configuration for model `{model.model_id}`. " - "Please verify that the model is correctly configured. If you are deploying custom models without AQUA service configuration, " - "refer to the guidelines at: " - "https://github.com/oracle-samples/oci-data-science-ai-samples/blob/main/ai-quick-actions/multimodel-deployment-tips.md#custom_models" - ) - - logger.error(error_message) - raise ConfigValidationError(error_message) - - allowed_shapes = ( - list( - set(aqua_deployment_config.configuration.keys()).union( - set(aqua_deployment_config.shape or []) - ) - ) - if is_single_model - else list(aqua_deployment_config.configuration.keys()) - ) - - if selected_shape not in allowed_shapes: - error_message = ( - f"Model `{model.model_id}` is not compatible with the selected instance shape `{selected_shape}`. " - f"Select a different instance shape from allowed shapes {allowed_shapes}." - ) - logger.error(error_message) - raise ConfigValidationError(error_message) - - # Retrieve valid GPU counts for the selected shape. - multi_model_configs = aqua_deployment_config.configuration.get( - selected_shape, ConfigurationItem() - ).multi_model_deployment - - valid_gpu_configurations = [cfg.gpu_count for cfg in multi_model_configs] - - if model.gpu_count not in valid_gpu_configurations: - valid_gpu_str = valid_gpu_configurations or [] - - if is_single_model: - # If total GPU allocation is not supported by selected model - if selected_shape not in aqua_deployment_config.shape: - error_message = ( - f"Model `{model.model_id}` is configured with {model.gpu_count} GPU(s), " - f"which is invalid. The allowed GPU configurations are: {valid_gpu_str}." - ) - logger.error(error_message) - raise ConfigValidationError(error_message) - - if model.gpu_count != total_available_gpus: - error_message = ( - f"Model '{model.model_id}' is configured to use {model.gpu_count} GPU(s), " - f"which not fully utilize the selected instance shape with {total_available_gpus} available GPU(s). " - "Consider adjusting the GPU allocation to better utilize the available resources and maximize performance." - ) - logger.error(error_message) - raise ConfigValidationError(error_message) - - else: - error_message = ( - f"Model `{model.model_id}` is configured with {model.gpu_count} GPU(s), which is invalid. " - f"Valid GPU configurations are: {valid_gpu_str}. Please adjust the GPU allocation " - f"or choose an instance shape that supports a higher GPU count." - ) - logger.error(error_message) - raise ConfigValidationError(error_message) - - if sum_model_gpus < total_available_gpus: - error_message = ( - f"Selected models are configured to use {sum_model_gpus} GPU(s), " - f"which not fully utilize the selected instance shape with {total_available_gpus} available GPU(s). " - "This configuration may lead to suboptimal performance for a multi-model deployment. " - "Consider adjusting the GPU allocation to better utilize the available resources and maximize performance." - ) - logger.warning(error_message) - # raise ConfigValidationError(error_message) - - # Check that the total GPU count for the model group does not exceed the instance capacity. - if sum_model_gpus > total_available_gpus: - error_message = ( - f"The selected instance shape `{selected_shape}` provides `{total_available_gpus}` GPU(s), " - f"but the total GPU allocation required by the model group is `{sum_model_gpus}` GPU(s). " - "Please adjust the GPU allocation per model or choose an instance shape with greater GPU capacity." - ) - logger.error(error_message) - raise ConfigValidationError(error_message) - class Config: extra = "allow" protected_namespaces = () diff --git a/ads/aqua/modeldeployment/model_group_config.py b/ads/aqua/modeldeployment/model_group_config.py index 046d6101b..ca8961620 100644 --- a/ads/aqua/modeldeployment/model_group_config.py +++ b/ads/aqua/modeldeployment/model_group_config.py @@ -23,7 +23,10 @@ ConfigurationItem, ModelDeploymentConfigSummary, ) -from ads.aqua.modeldeployment.entities import CreateModelDeploymentDetails +from ads.aqua.modeldeployment.entities import ( + CreateModelDeploymentDetails, + UpdateModelDeploymentDetails, +) from ads.common.object_storage_details import ObjectStorageDetails from ads.common.utils import UNKNOWN @@ -157,7 +160,9 @@ def _extract_model_params( def _merge_gpu_count_params( model: AquaMultiModelRef, model_config_summary: ModelDeploymentConfigSummary, - create_deployment_details: CreateModelDeploymentDetails, + deployment_details: Union[ + CreateModelDeploymentDetails, UpdateModelDeploymentDetails + ], container_type_key: str, container_params, ): @@ -170,9 +175,7 @@ def _merge_gpu_count_params( deployment_config = model_config_summary.deployment_config.get( model.model_id, AquaDeploymentConfig() - ).configuration.get( - create_deployment_details.instance_shape, ConfigurationItem() - ) + ).configuration.get(deployment_details.instance_shape, ConfigurationItem()) params_found = False for item in deployment_config.multi_model_deployment: @@ -198,9 +201,11 @@ def _merge_gpu_count_params( return params @classmethod - def from_create_model_deployment_details( + def from_model_deployment_details( cls, - create_deployment_details: CreateModelDeploymentDetails, + deployment_details: Union[ + CreateModelDeploymentDetails, UpdateModelDeploymentDetails + ], model_config_summary: ModelDeploymentConfigSummary, container_type_key, container_params, @@ -212,11 +217,11 @@ def from_create_model_deployment_details( """ models = [] seen_models = set() - for model in create_deployment_details.models: + for model in deployment_details.models: params = ModelGroupConfig._merge_gpu_count_params( model, model_config_summary, - create_deployment_details, + deployment_details, container_type_key, container_params, ) diff --git a/tests/unitary/with_extras/aqua/test_deployment.py b/tests/unitary/with_extras/aqua/test_deployment.py index c6f49d6ae..0d5b1016e 100644 --- a/tests/unitary/with_extras/aqua/test_deployment.py +++ b/tests/unitary/with_extras/aqua/test_deployment.py @@ -2268,6 +2268,8 @@ def test_update_model_group_deployment( mock_update.return_value = model_deployment_obj + mock_validate_input_models.return_value = (MagicMock(), MagicMock()) + ft_weights = [ LoraModuleSpec( model_id="ocid1.datasciencemodel.oc1..", @@ -2922,8 +2924,8 @@ def test_from_create_model_deployment_details(self): ) ) - model_group_config = ModelGroupConfig.from_create_model_deployment_details( - create_deployment_details=create_deployment_details, + model_group_config = ModelGroupConfig.from_model_deployment_details( + deployment_details=create_deployment_details, model_config_summary=model_config_summary, container_type_key="odsc-vllm-serving", container_params="--example-container-params test", @@ -2945,13 +2947,11 @@ def test_from_create_model_deployment_details(self): predict_log_id="ocid1.log.oc1..", ) ) - model_group_config_no_ft = ( - ModelGroupConfig.from_create_model_deployment_details( - create_deployment_details=create_deployment_details_no_ft, - model_config_summary=model_config_summary, - container_type_key="odsc-vllm-serving", - container_params="--example-container-params test", - ) + model_group_config_no_ft = ModelGroupConfig.from_model_deployment_details( + deployment_details=create_deployment_details_no_ft, + model_config_summary=model_config_summary, + container_type_key="odsc-vllm-serving", + container_params="--example-container-params test", ) assert (