Skip to content

Commit 22ae99c

Browse files
register and deployment changes for byoc
1 parent 458d0cd commit 22ae99c

File tree

7 files changed

+126
-17
lines changed

7 files changed

+126
-17
lines changed

ads/aqua/common/enums.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class InferenceContainerTypeFamily(str, metaclass=ExtendedEnumMeta):
5252
AQUA_VLLM_CONTAINER_FAMILY = "odsc-vllm-serving"
5353
AQUA_TGI_CONTAINER_FAMILY = "odsc-tgi-serving"
5454
AQUA_LLAMA_CPP_CONTAINER_FAMILY = "odsc-llama-cpp-serving"
55+
AQUA_TEI_CONTAINER_FAMILY = "odsc-tei-serving"
5556

5657

5758
class InferenceContainerParamType(str, metaclass=ExtendedEnumMeta):
@@ -80,3 +81,11 @@ class RqsAdditionalDetails(str, metaclass=ExtendedEnumMeta):
8081
MODEL_VERSION_SET_NAME = "modelVersionSetName"
8182
PROJECT_ID = "projectId"
8283
VERSION_LABEL = "versionLabel"
84+
85+
86+
class TextEmbeddingInferenceContainerParams(str, metaclass=ExtendedEnumMeta):
87+
"""Contains a subset of params that are required for enabling model deployment in OCI Data Science. More options
88+
are available at https://huggingface.co/docs/text-embeddings-inference/en/cli_arguments"""
89+
90+
MODEL_ID = "model-id"
91+
PORT = "port"

ads/aqua/common/utils.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
InferenceContainerParamType,
3636
InferenceContainerType,
3737
RqsAdditionalDetails,
38+
TextEmbeddingInferenceContainerParams,
3839
)
3940
from ads.aqua.common.errors import (
4041
AquaFileNotFoundError,
@@ -51,6 +52,7 @@
5152
MODEL_BY_REFERENCE_OSS_PATH_KEY,
5253
SERVICE_MANAGED_CONTAINER_URI_SCHEME,
5354
SUPPORTED_FILE_FORMATS,
55+
TEI_CONTAINER_DEFAULT_HOST,
5456
TGI_INFERENCE_RESTRICTED_PARAMS,
5557
UNKNOWN,
5658
UNKNOWN_JSON_STR,
@@ -63,7 +65,12 @@
6365
from ads.common.object_storage_details import ObjectStorageDetails
6466
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
6567
from ads.common.utils import copy_file, get_console_link, upload_to_os
66-
from ads.config import AQUA_SERVICE_MODELS_BUCKET, CONDA_BUCKET_NS, TENANCY_OCID
68+
from ads.config import (
69+
AQUA_MODEL_DEPLOYMENT_FOLDER,
70+
AQUA_SERVICE_MODELS_BUCKET,
71+
CONDA_BUCKET_NS,
72+
TENANCY_OCID,
73+
)
6774
from ads.model import DataScienceModel, ModelVersionSet
6875

6976
logger = logging.getLogger("ads.aqua")
@@ -1079,3 +1086,27 @@ def list_hf_models(query: str) -> List[str]:
10791086
return [model.id for model in models if model.disabled is None]
10801087
except HfHubHTTPError as err:
10811088
raise format_hf_custom_error_message(err) from err
1089+
1090+
1091+
def generate_tei_cmd_vars(os_path: str) -> List[str]:
1092+
"""This utility functions generates CMD params for Text Embedding Inference container. Only the
1093+
essential parameters for OCI model deployment are added, defaults are used for the rest.
1094+
Parameters
1095+
----------
1096+
os_path: str
1097+
OCI bucket path where the model artifacts are uploaded - oci://bucket@namespace/prefix
1098+
1099+
Returns
1100+
-------
1101+
List of command line arguments
1102+
"""
1103+
1104+
cmd_prefix = "--"
1105+
cmd_vars = [
1106+
cmd_prefix + TextEmbeddingInferenceContainerParams.MODEL_ID,
1107+
f"{AQUA_MODEL_DEPLOYMENT_FOLDER}{ObjectStorageDetails.from_path(os_path.rstrip('/')).filepath}/",
1108+
cmd_prefix + TextEmbeddingInferenceContainerParams.PORT,
1109+
TEI_CONTAINER_DEFAULT_HOST,
1110+
]
1111+
1112+
return cmd_vars

ads/aqua/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,4 @@
7979
"--port",
8080
"--host",
8181
}
82+
TEI_CONTAINER_DEFAULT_HOST = "8080"

ads/aqua/model/entities.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ class ImportModelDetails(CLIBuilderMixin):
287287
compartment_id: Optional[str] = None
288288
project_id: Optional[str] = None
289289
model_file: Optional[str] = None
290+
inference_container_uri: Optional[str] = None
290291

291292
def __post_init__(self):
292293
self._command = "model register"

ads/aqua/model/model.py

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414

1515
from ads.aqua import ODSC_MODEL_COMPARTMENT_OCID, logger
1616
from ads.aqua.app import AquaApp
17-
from ads.aqua.common.enums import Tags
17+
from ads.aqua.common.enums import InferenceContainerTypeFamily, Tags
1818
from ads.aqua.common.errors import AquaRuntimeError, AquaValueError
1919
from ads.aqua.common.utils import (
2020
LifecycleStatus,
2121
_build_resource_identifier,
2222
copy_model_config,
2323
create_word_icon,
24+
generate_tei_cmd_vars,
2425
get_artifact_path,
2526
get_hf_model_info,
2627
list_os_files_with_extension,
@@ -67,7 +68,9 @@
6768
from ads.common.oci_resource import SEARCH_TYPE, OCIResource
6869
from ads.common.utils import get_console_link
6970
from ads.config import (
71+
AQUA_DEPLOYMENT_CONTAINER_CMD_VAR,
7072
AQUA_DEPLOYMENT_CONTAINER_METADATA_NAME,
73+
AQUA_DEPLOYMENT_CONTAINER_URI_METADATA_NAME,
7174
AQUA_EVALUATION_CONTAINER_METADATA_NAME,
7275
AQUA_FINETUNING_CONTAINER_METADATA_NAME,
7376
COMPARTMENT_OCID,
@@ -629,6 +632,7 @@ def _create_model_catalog_entry(
629632
validation_result: ModelValidationResult,
630633
compartment_id: Optional[str],
631634
project_id: Optional[str],
635+
inference_container_uri: Optional[str],
632636
) -> DataScienceModel:
633637
"""Create model by reference from the object storage path
634638
@@ -640,6 +644,7 @@ def _create_model_catalog_entry(
640644
verified_model (DataScienceModel): If set, then copies all the tags and custom metadata information from the service verified model
641645
compartment_id (Optional[str]): Compartment Id of the compartment where the model has to be created
642646
project_id (Optional[str]): Project id of the project where the model has to be created
647+
inference_container_uri (Optional[str]): Inference container uri for BYOC
643648
644649
Returns:
645650
DataScienceModel: Returns Datascience model instance.
@@ -685,6 +690,36 @@ def _create_model_catalog_entry(
685690
raise AquaRuntimeError(
686691
f"Require Inference container information. Model: {model_name} does not have associated inference container defaults. Check docs for more information on how to pass inference container."
687692
)
693+
metadata.add(
694+
key=AQUA_DEPLOYMENT_CONTAINER_METADATA_NAME,
695+
value=inference_container,
696+
description=f"Inference container mapping for {model_name}",
697+
category="Other",
698+
)
699+
if (
700+
inference_container
701+
== InferenceContainerTypeFamily.AQUA_TEI_CONTAINER_FAMILY
702+
):
703+
if not inference_container_uri:
704+
logger.warn(
705+
f"Proceeding with model registration without the inference container URI for "
706+
f"{inference_container}. You can still add this configuration during model deployment."
707+
)
708+
else:
709+
metadata.add(
710+
key=AQUA_DEPLOYMENT_CONTAINER_URI_METADATA_NAME,
711+
value=inference_container_uri,
712+
description=f"Inference container URI for {model_name}",
713+
category="Other",
714+
)
715+
716+
cmd_vars = generate_tei_cmd_vars(os_path)
717+
metadata.add(
718+
key=AQUA_DEPLOYMENT_CONTAINER_CMD_VAR,
719+
value=",".join(cmd_vars),
720+
description=f"Inference container cmd vars for {model_name}",
721+
category="Other",
722+
)
688723
if finetuning_container:
689724
tags[Tags.READY_TO_FINE_TUNE] = "true"
690725
metadata.add(
@@ -706,12 +741,6 @@ def _create_model_catalog_entry(
706741
category="Other",
707742
)
708743

709-
metadata.add(
710-
key=AQUA_DEPLOYMENT_CONTAINER_METADATA_NAME,
711-
value=inference_container,
712-
description=f"Inference container mapping for {model_name}",
713-
category="Other",
714-
)
715744
metadata.add(
716745
key=AQUA_EVALUATION_CONTAINER_METADATA_NAME,
717746
value="odsc-llm-evaluate",
@@ -1012,7 +1041,10 @@ def _validate_model(
10121041
AQUA_MODEL_TYPE_CUSTOM
10131042
)
10141043
elif model_format == ModelFormat.GGUF and len(gguf_model_files) > 0:
1015-
if import_model_details.finetuning_container and not safetensors_model_files:
1044+
if (
1045+
import_model_details.finetuning_container
1046+
and not safetensors_model_files
1047+
):
10161048
raise AquaValueError(
10171049
"Fine-tuning is currently not supported with GGUF model format."
10181050
)
@@ -1193,6 +1225,7 @@ def register(
11931225
validation_result=validation_result,
11941226
compartment_id=import_model_details.compartment_id,
11951227
project_id=import_model_details.project_id,
1228+
inference_container_uri=import_model_details.inference_container_uri,
11961229
)
11971230
# registered model will always have inference and evaluation container, but
11981231
# fine-tuning container may be not set

ads/aqua/modeldeployment/deployment.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
from ads.config import (
4747
AQUA_CONFIG_FOLDER,
4848
AQUA_DEPLOYMENT_CONTAINER_METADATA_NAME,
49+
AQUA_DEPLOYMENT_CONTAINER_URI_METADATA_NAME,
4950
AQUA_MODEL_DEPLOYMENT_CONFIG,
5051
AQUA_MODEL_DEPLOYMENT_CONFIG_DEFAULTS,
5152
COMPARTMENT_OCID,
@@ -106,6 +107,7 @@ def create(
106107
memory_in_gbs: Optional[float] = None,
107108
ocpus: Optional[float] = None,
108109
model_file: Optional[str] = None,
110+
container_image_uri: Optional[None] = None,
109111
cmd_var: List[str] = None,
110112
) -> "AquaDeployment":
111113
"""
@@ -153,6 +155,9 @@ def create(
153155
The ocpu count for the shape selected.
154156
model_file: str
155157
The file used for model deployment.
158+
container_image_uri: str
159+
The image of model deployment container runtime, ignored for service managed containers.
160+
Required parameter for BYOC based deployments if this parameter was not set during model registration.
156161
cmd_var: List[str]
157162
The cmd of model deployment container runtime.
158163
Returns
@@ -198,9 +203,11 @@ def create(
198203
f"from custom metadata for the model {config_source_id}"
199204
) from err
200205

201-
# set up env vars
206+
# set up env and cmd var
202207
if not env_var:
203208
env_var = {}
209+
if not cmd_var:
210+
cmd_var = {}
204211

205212
try:
206213
model_path_prefix = aqua_model.custom_metadata_list.get(
@@ -236,11 +243,37 @@ def create(
236243
model=aqua_model, container_family=container_family
237244
)
238245

239-
# fetch image name from config
240-
container_image = get_container_image(container_type=container_type_key)
246+
# todo: revisit this when TEI is added to SMC list. Currently, container_image_uri is ignored if container
247+
# family is SMC.
248+
if container_type_key == InferenceContainerTypeFamily.AQUA_TEI_CONTAINER_FAMILY:
249+
if not container_image_uri:
250+
try:
251+
container_image_uri = aqua_model.custom_metadata_list.get(
252+
AQUA_DEPLOYMENT_CONTAINER_URI_METADATA_NAME
253+
).value
254+
except ValueError as err:
255+
raise AquaValueError(
256+
f"{AQUA_DEPLOYMENT_CONTAINER_URI_METADATA_NAME} key is not available in the custom metadata "
257+
f"field. Either re-register the model with custom container URI, or set container_image_uri "
258+
f"parameter when creating this deployment."
259+
) from err
260+
261+
try:
262+
cmd_var_string = aqua_model.custom_metadata_list.get(
263+
AQUA_DEPLOYMENT_CONTAINER_URI_METADATA_NAME
264+
).value
265+
cmd_var.append(cmd_var_string.split(","))
266+
except ValueError as err:
267+
raise AquaValueError(
268+
f"{AQUA_DEPLOYMENT_CONTAINER_URI_METADATA_NAME} key is not available in the custom metadata "
269+
f"field. Please check if the model was registered with {container_type_key} inference container."
270+
) from err
271+
else:
272+
# fetch image name from config
273+
container_image_uri = get_container_image(container_type=container_type_key)
241274

242275
logging.info(
243-
f"Aqua Image used for deploying {aqua_model.id} : {container_image}"
276+
f"Aqua Image used for deploying {aqua_model.id} : {container_image_uri}"
244277
)
245278

246279
model_formats_str = aqua_model.freeform_tags.get(
@@ -310,7 +343,7 @@ def create(
310343
# AQUA_LLAMA_CPP_CONTAINER_FAMILY container uses uvicorn that required model/server params
311344
# to be set as env vars
312345
raise AquaValueError(
313-
f"Currently, parameters cannot be overridden for the container: {container_image}. Please proceed "
346+
f"Currently, parameters cannot be overridden for the container: {container_image_uri}. Please proceed "
314347
f"with deployment without parameter overrides."
315348
)
316349

@@ -364,7 +397,7 @@ def create(
364397
# configure model deployment runtime
365398
container_runtime = (
366399
ModelDeploymentContainerRuntime()
367-
.with_image(container_image)
400+
.with_image(container_image_uri)
368401
.with_server_port(server_port)
369402
.with_health_check_port(health_check_port)
370403
.with_env(env_var)

ads/config.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/usr/bin/env python
2-
# -*- coding: utf-8; -*-
32

43
# Copyright (c) 2020, 2024 Oracle and/or its affiliates.
54
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
@@ -66,6 +65,8 @@
6665
AQUA_DEPLOYMENT_CONTAINER_METADATA_NAME = "deployment-container"
6766
AQUA_FINETUNING_CONTAINER_METADATA_NAME = "finetune-container"
6867
AQUA_EVALUATION_CONTAINER_METADATA_NAME = "evaluation-container"
68+
AQUA_DEPLOYMENT_CONTAINER_CMD_VAR = "container_cmd_var"
69+
AQUA_DEPLOYMENT_CONTAINER_URI_METADATA_NAME = "deployment-container-uri"
6970
AQUA_DEPLOYMENT_CONTAINER_OVERRIDE_FLAG_METADATA_NAME = "deployment-container-custom"
7071
AQUA_FINETUNING_CONTAINER_OVERRIDE_FLAG_METADATA_NAME = "finetune-container-custom"
7172
AQUA_MODEL_DEPLOYMENT_FOLDER = "/opt/ds/model/deployed_model/"
@@ -212,7 +213,7 @@ def open(
212213
frame.f_globals.pop("config", None)
213214

214215
# Restores original globals
215-
for key in defined_globals.keys():
216+
for key in defined_globals:
216217
frame.f_globals[key] = defined_globals[key]
217218

218219
# Saving config if it necessary

0 commit comments

Comments
 (0)