Skip to content

Commit 4ce8a8e

Browse files
Merge branch 'main' into v2.11.8
2 parents 4897e15 + c8526cc commit 4ce8a8e

File tree

9 files changed

+85
-69
lines changed

9 files changed

+85
-69
lines changed

ads/aqua/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515

1616
def get_logger_level():
17-
"""Retrieves logging level from environment variable `LOG_LEVEL`."""
17+
"""Retrieves logging level from environment variable `ADS_AQUA_LOG_LEVEL`."""
1818
level = os.environ.get(ENV_VAR_LOG_LEVEL, "INFO").upper()
1919
return level
2020

ads/aqua/base.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ def create_model_version_set(
163163
tag = Tags.AQUA_FINE_TUNING.value
164164

165165
if not model_version_set_id:
166-
tag = Tags.AQUA_FINE_TUNING.value # TODO: Fix this
167166
try:
168167
model_version_set = ModelVersionSet.from_name(
169168
name=model_version_set_name,

ads/aqua/cli.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from ads.aqua.finetune import AquaFineTuningApp
1818
from ads.aqua.model import AquaModelApp
1919
from ads.config import NB_SESSION_OCID
20+
from ads.common.utils import LOG_LEVELS
2021

2122

2223
class AquaCommand:
@@ -47,14 +48,20 @@ def __init__(
4748
or 'ERROR' if not set. Example values include 'DEBUG', 'INFO',
4849
'WARNING', 'ERROR', and 'CRITICAL'.
4950
"""
51+
if log_level.upper() not in LOG_LEVELS:
52+
logger.error(
53+
f"Log level should be one of {LOG_LEVELS}. Setting default to ERROR."
54+
)
55+
log_level = "ERROR"
5056
set_log_level(log_level)
5157
# gracefully exit if env var is not set
5258
if not ODSC_MODEL_COMPARTMENT_OCID:
53-
logger.error(
59+
logger.debug(
5460
"ODSC_MODEL_COMPARTMENT_OCID environment variable is not set for Aqua."
5561
)
5662
if NB_SESSION_OCID:
5763
logger.error(
58-
f"Aqua is not available for the notebook session {NB_SESSION_OCID}."
64+
f"Aqua is not available for the notebook session {NB_SESSION_OCID}. For more information, "
65+
f"please refer to the documentation."
5966
)
6067
sys.exit(1)

ads/aqua/deployment.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
UNKNOWN_DICT,
2323
get_resource_name,
2424
get_model_by_reference_paths,
25+
get_ocid_substring,
26+
AQUA_MODEL_TYPE_SERVICE,
27+
AQUA_MODEL_TYPE_CUSTOM,
2528
)
2629
from ads.aqua.finetune import FineTuneCustomMetadata
2730
from ads.aqua.data import AquaResourceIdentifier
@@ -391,11 +394,13 @@ def create(
391394
.with_runtime(container_runtime)
392395
).deploy(wait_for_completion=False)
393396

394-
model_type = "custom" if is_fine_tuned_model else "service"
395-
deployment_id = deployment.dsc_model_deployment.id
396-
telemetry_kwargs = (
397-
{"ocid": deployment_id[-8:]} if len(deployment_id) > 8 else {}
397+
model_type = (
398+
AQUA_MODEL_TYPE_CUSTOM if is_fine_tuned_model else AQUA_MODEL_TYPE_SERVICE
398399
)
400+
deployment_id = deployment.dsc_model_deployment.id
401+
# we arbitrarily choose last 8 characters of OCID to identify MD in telemetry
402+
telemetry_kwargs = {"ocid": get_ocid_substring(deployment_id, key_len=8)}
403+
399404
# tracks unique deployments that were created in the user compartment
400405
self.telemetry.record_event_async(
401406
category=f"aqua/{model_type}/deployment",
@@ -461,10 +466,11 @@ def list(self, **kwargs) -> List["AquaDeployment"]:
461466
state = model_deployment.lifecycle_state.upper()
462467
if state in ["ACTIVE", "FAILED"]:
463468
# tracks unique deployments that were listed in the user compartment
469+
# we arbitrarily choose last 8 characters of OCID to identify MD in telemetry
464470
self.telemetry.record_event_async(
465471
category=f"aqua/deployment",
466472
action="list",
467-
detail=deployment_id[-8:] if len(deployment_id) > 8 else "",
473+
detail=get_ocid_substring(deployment_id, key_len=8),
468474
value=state,
469475
)
470476

ads/aqua/utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@
7373
READY_TO_DEPLOY_STATUS = "ACTIVE"
7474
READY_TO_FINE_TUNE_STATUS = "TRUE"
7575
AQUA_GA_LIST = ["id19sfcrra6z"]
76+
AQUA_MODEL_TYPE_SERVICE = "service"
77+
AQUA_MODEL_TYPE_CUSTOM = "custom"
7678

7779

7880
class LifecycleStatus(Enum):
@@ -741,3 +743,9 @@ def known_realm():
741743
742744
"""
743745
return os.environ.get("CONDA_BUCKET_NS") in AQUA_GA_LIST
746+
747+
748+
def get_ocid_substring(ocid: str, key_len: int) -> str:
749+
"""This helper function returns the last n characters of the ocid specified by key_len parameter.
750+
If ocid is None or length is less than key_len, it returns an empty string."""
751+
return ocid[-key_len:] if ocid and len(ocid) > key_len else ""

ads/common/utils.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@
102102
# The number of worker processes to use in parallel for uploading individual parts of a multipart upload.
103103
DEFAULT_PARALLEL_PROCESS_COUNT = 9
104104

105+
LOG_LEVELS = ["NOTSET", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
106+
105107

106108
class FileOverwriteError(Exception): # pragma: no cover
107109
pass
@@ -1751,7 +1753,7 @@ def get_log_links(
17511753
) -> str:
17521754
"""
17531755
This method returns the web console link for the given log ids.
1754-
1756+
17551757
Parameters
17561758
----------
17571759
log_group_id: str, required
@@ -1776,7 +1778,9 @@ def get_log_links(
17761778
query_range = f'''search "{compartment_id}/{log_group_id}/{log_id}"'''
17771779
query_source = f"source='{source_id}'"
17781780
sort_condition = f"sort by datetime desc&regions={region}"
1779-
search_query = f"search?searchQuery={query_range} | {query_source} | {sort_condition}"
1781+
search_query = (
1782+
f"search?searchQuery={query_range} | {query_source} | {sort_condition}"
1783+
)
17801784
console_link_url = f"https://cloud.oracle.com/logging/{search_query}"
17811785
elif log_group_id:
17821786
console_link_url = f"https://cloud.oracle.com/logging/log-groups/{log_group_id}?region={region}"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ dependencies = [
6363
"jinja2>=2.11.2",
6464
"matplotlib>=3.1.3",
6565
"numpy>=1.19.2",
66-
"oci>=2.113.0",
66+
"oci>=2.125.3",
6767
"ocifs>=1.1.3",
6868
"pandas>1.2.1; python_version<'3.9'", # starting pandas v2.1.0 requires-python = '>=3.9'
6969
"pandas>=2.2.0; python_version>='3.9'",

tests/unitary/with_extras/aqua/test_cli.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,17 @@ def test_aqua_command_without_compartment_env_var(self, name, session_ocid):
7777
reload(ads.aqua.cli)
7878
with patch("ads.aqua.cli.set_log_level") as mock_setting_log:
7979
with patch("ads.aqua.logger.error") as mock_logger_error:
80-
AquaCommand()
81-
mock_setting_log.assert_called_with(
82-
TestAquaCLI.DEFAULT_AQUA_CLI_LOGGING_LEVEL
83-
)
84-
mock_logger_error.assert_any_call(
85-
"ODSC_MODEL_COMPARTMENT_OCID environment variable is not set for Aqua."
86-
)
87-
if session_ocid:
88-
mock_logger_error.assert_any_call(
89-
f"Aqua is not available for the notebook session {session_ocid}."
80+
with patch("ads.aqua.logger.debug") as mock_logger_debug:
81+
AquaCommand()
82+
mock_setting_log.assert_called_with(
83+
TestAquaCLI.DEFAULT_AQUA_CLI_LOGGING_LEVEL
9084
)
91-
mock_exit.assert_called_with(1)
85+
mock_logger_debug.assert_any_call(
86+
"ODSC_MODEL_COMPARTMENT_OCID environment variable is not set for Aqua."
87+
)
88+
if session_ocid:
89+
mock_logger_error.assert_any_call(
90+
f"Aqua is not available for the notebook session {session_ocid}. For more information, "
91+
f"please refer to the documentation."
92+
)
93+
mock_exit.assert_called_with(1)

tests/unitary/with_extras/aqua/test_finetuning.py

Lines changed: 36 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
from ads.model.datascience_model import DataScienceModel
2222
from ads.model.model_metadata import ModelCustomMetadata
2323

24-
class FineTuningTestCase(TestCase):
2524

25+
class FineTuningTestCase(TestCase):
2626
SERVICE_COMPARTMENT_ID = "ocid1.compartment.oc1..<OCID>"
2727

2828
def setUp(self):
@@ -61,20 +61,20 @@ def test_create_fine_tuning(
6161
mock_job_create,
6262
mock_job_id,
6363
mock_job_name,
64-
mock_job_run
64+
mock_job_run,
6565
):
6666
custom_metadata_list = ModelCustomMetadata()
6767
custom_metadata_list.add(
6868
key=FineTuneCustomMetadata.SERVICE_MODEL_ARTIFACT_LOCATION.value,
69-
value="test_service_model_artifact_location"
69+
value="test_service_model_artifact_location",
7070
)
7171
custom_metadata_list.add(
7272
key=FineTuneCustomMetadata.SERVICE_MODEL_DEPLOYMENT_CONTAINER.value,
73-
value="test_service_model_deployment_container"
73+
value="test_service_model_deployment_container",
7474
)
7575
custom_metadata_list.add(
7676
key=FineTuneCustomMetadata.SERVICE_MODEL_FINE_TUNE_CONTAINER.value,
77-
value="test_service_model_fine_tune_container"
77+
value="test_service_model_fine_tune_container",
7878
)
7979

8080
ft_source = MagicMock()
@@ -84,10 +84,7 @@ def test_create_fine_tuning(
8484
ft_source.custom_metadata_list = custom_metadata_list
8585
mock_get_source.return_value = ft_source
8686

87-
mock_mvs_create.return_value = (
88-
"test_experiment_id",
89-
"test_experiment_name"
90-
)
87+
mock_mvs_create.return_value = ("test_experiment_id", "test_experiment_name")
9188

9289
ft_model = MagicMock()
9390
ft_model.id = "test_ft_model_id"
@@ -97,10 +94,7 @@ def test_create_fine_tuning(
9794

9895
mock_get_finetuning_config.return_value = {
9996
"shape": {
100-
"VM.GPU.A10.1": {
101-
"batch_size": 1,
102-
"replica": 1
103-
},
97+
"VM.GPU.A10.1": {"batch_size": 1, "replica": 1},
10498
}
10599
}
106100
mock_get_container_image.return_value = "test_container_image"
@@ -122,53 +116,49 @@ def test_create_fine_tuning(
122116
ft_name="test_ft_name",
123117
dataset_path="oci://ds_bucket@namespace/prefix/dataset.jsonl",
124118
report_path="oci://report_bucket@namespace/prefix/",
125-
ft_parameters={
126-
"epochs":1,
127-
"learning_rate":0.02
128-
},
119+
ft_parameters={"epochs": 1, "learning_rate": 0.02},
129120
shape_name="VM.GPU.A10.1",
130121
replica=1,
131122
validation_set_size=0.2,
132123
block_storage_size=1,
133124
experiment_name="test_experiment_name",
134125
)
135126

136-
aqua_ft_summary = self.app.create(
137-
**create_aqua_ft_details
138-
)
127+
aqua_ft_summary = self.app.create(**create_aqua_ft_details)
139128

140129
assert asdict(aqua_ft_summary) == {
141-
'console_url': f'https://cloud.oracle.com/data-science/models/{ft_model.id}?region={self.app.region}',
142-
'experiment': {
143-
'id': f'{mock_mvs_create.return_value[0]}',
144-
'name': f'{mock_mvs_create.return_value[1]}',
145-
'url': f'https://cloud.oracle.com/data-science/model-version-sets/{mock_mvs_create.return_value[0]}?region={self.app.region}'
130+
"console_url": f"https://cloud.oracle.com/data-science/models/{ft_model.id}?region={self.app.region}",
131+
"experiment": {
132+
"id": f"{mock_mvs_create.return_value[0]}",
133+
"name": f"{mock_mvs_create.return_value[1]}",
134+
"url": f"https://cloud.oracle.com/data-science/model-version-sets/{mock_mvs_create.return_value[0]}?region={self.app.region}",
146135
},
147-
'id': f'{ft_model.id}',
148-
'job': {
149-
'id': f'{mock_job_id.return_value}',
150-
'name': f'{mock_job_name.return_value}',
151-
'url': f'https://cloud.oracle.com/data-science/jobs/{mock_job_id.return_value}?region={self.app.region}'
136+
"id": f"{ft_model.id}",
137+
"job": {
138+
"id": f"{mock_job_id.return_value}",
139+
"name": f"{mock_job_name.return_value}",
140+
"url": f"https://cloud.oracle.com/data-science/jobs/{mock_job_id.return_value}?region={self.app.region}",
152141
},
153-
'lifecycle_details': f'{ft_job_run.lifecycle_details}',
154-
'lifecycle_state': f'{ft_job_run.lifecycle_state}',
155-
'name': f'{ft_model.display_name}',
156-
'parameters': {
157-
'epochs': 1,
158-
'learning_rate': 0.02
142+
"lifecycle_details": f"{ft_job_run.lifecycle_details}",
143+
"lifecycle_state": f"{ft_job_run.lifecycle_state}",
144+
"name": f"{ft_model.display_name}",
145+
"parameters": {
146+
"epochs": 1,
147+
"learning_rate": 0.02,
148+
"sample_packing": "True",
159149
},
160-
'source': {
161-
'id': f'{ft_source.id}',
162-
'name': f'{ft_source.display_name}',
163-
'url': f'https://cloud.oracle.com/data-science/models/{ft_source.id}?region={self.app.region}'
150+
"source": {
151+
"id": f"{ft_source.id}",
152+
"name": f"{ft_source.display_name}",
153+
"url": f"https://cloud.oracle.com/data-science/models/{ft_source.id}?region={self.app.region}",
164154
},
165-
'tags': {
166-
'aqua_finetuning': 'aqua_finetuning',
167-
'finetuning_experiment_id': f'{mock_mvs_create.return_value[0]}',
168-
'finetuning_job_id': f'{mock_job_id.return_value}',
169-
'finetuning_source': f'{ft_source.id}'
155+
"tags": {
156+
"aqua_finetuning": "aqua_finetuning",
157+
"finetuning_experiment_id": f"{mock_mvs_create.return_value[0]}",
158+
"finetuning_job_id": f"{mock_job_id.return_value}",
159+
"finetuning_source": f"{ft_source.id}",
170160
},
171-
'time_created': f'{ft_model.time_created}'
161+
"time_created": f"{ft_model.time_created}",
172162
}
173163

174164
def test_exit_code_message(self):

0 commit comments

Comments
 (0)