From 6f9401f7b854f41481c2556411fb904e53b3b826 Mon Sep 17 00:00:00 2001 From: Daniel Heinze Date: Thu, 12 Mar 2020 10:35:26 +0100 Subject: [PATCH 1/4] Added helpful get_latest_model method The get_latest_model method helps to get the latest model without providing a specific tag. --- diabetes_regression/util/model_helper.py | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/diabetes_regression/util/model_helper.py b/diabetes_regression/util/model_helper.py index 98df0bb8..296a2cc7 100644 --- a/diabetes_regression/util/model_helper.py +++ b/diabetes_regression/util/model_helper.py @@ -78,3 +78,43 @@ def get_model_by_tag( return None except Exception: raise + +def get_latest_model( + model_name: str, + aml_workspace: Workspace = None +) -> AMLModel: + """ + Retrieves and returns the latest model from the workspace. + + Parameters: + aml_workspace (Workspace): aml.core Workspace that the model lives. + model_name (str): name of the model we are looking for + + Return: + A single aml model from the workspace that matches the name and tag. + """ + try: + # Validate params. cannot be None. + if model_name is None: + raise ValueError("model_name[:str] is required") + if aml_workspace is None: + aml_workspace = get_current_workspace() + + # get model by tag. + model_list = AMLModel.list(aml_workspace, name=model_name, latest=True) + + # latest should only return 1 model, but if it does, + # then maybe sdk or source code changed. + too_many_model_message = ("Found more than one model. " + f"Models found: {model_list}") + no_model_found_message = (f"No Model found with name: {model_name}") + + if len(model_list) > 1: + raise ValueError(too_many_model_message) + if len(model_list) == 1: + return model_list[0] + else: + print(no_model_found_message) + return None + except Exception: + raise From 9bc26142f6fa40795ecfff61054b15ca9f5da533 Mon Sep 17 00:00:00 2001 From: Daniel Heinze Date: Thu, 12 Mar 2020 15:29:54 +0100 Subject: [PATCH 2/4] linting fixes --- diabetes_regression/util/model_helper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/diabetes_regression/util/model_helper.py b/diabetes_regression/util/model_helper.py index 296a2cc7..6ea58d58 100644 --- a/diabetes_regression/util/model_helper.py +++ b/diabetes_regression/util/model_helper.py @@ -79,6 +79,7 @@ def get_model_by_tag( except Exception: raise + def get_latest_model( model_name: str, aml_workspace: Workspace = None @@ -106,7 +107,7 @@ def get_latest_model( # latest should only return 1 model, but if it does, # then maybe sdk or source code changed. too_many_model_message = ("Found more than one model. " - f"Models found: {model_list}") + f"Models found: {model_list}") no_model_found_message = (f"No Model found with name: {model_name}") if len(model_list) > 1: From 273d2bfc66b2eb03c608b3b8ad8f440fae37e2cb Mon Sep 17 00:00:00 2001 From: Daniel Heinze Date: Fri, 13 Mar 2020 09:52:26 +0100 Subject: [PATCH 3/4] Unified code for optional tags for get_latest_model --- .../evaluate/evaluate_model.py | 6 +- diabetes_regression/util/model_helper.py | 90 ++++++------------- ...abetes_regression_verify_train_pipeline.py | 4 +- 3 files changed, 33 insertions(+), 67 deletions(-) diff --git a/diabetes_regression/evaluate/evaluate_model.py b/diabetes_regression/evaluate/evaluate_model.py index f4d4c6db..83e422e8 100644 --- a/diabetes_regression/evaluate/evaluate_model.py +++ b/diabetes_regression/evaluate/evaluate_model.py @@ -26,7 +26,7 @@ from azureml.core import Run import argparse import traceback -from util.model_helper import get_model_by_tag +from util.model_helper import get_latest_model run = Run.get_context() @@ -45,7 +45,7 @@ # sources_dir = 'diabetes_regression' # path_to_util = os.path.join(".", sources_dir, "util") # sys.path.append(os.path.abspath(path_to_util)) # NOQA: E402 -# from model_helper import get_model_by_tag +# from model_helper import get_latest_model # workspace_name = os.environ.get("WORKSPACE_NAME") # experiment_name = os.environ.get("EXPERIMENT_NAME") # resource_group = os.environ.get("RESOURCE_GROUP") @@ -108,7 +108,7 @@ firstRegistration = False tag_name = 'experiment_name' - model = get_model_by_tag( + model = get_latest_model( model_name, tag_name, exp.name, ws) if (model is not None): diff --git a/diabetes_regression/util/model_helper.py b/diabetes_regression/util/model_helper.py index 6ea58d58..3876f4df 100644 --- a/diabetes_regression/util/model_helper.py +++ b/diabetes_regression/util/model_helper.py @@ -22,20 +22,20 @@ def get_current_workspace() -> Workspace: return experiment.workspace -def get_model_by_tag( +def get_latest_model( model_name: str, - tag_name: str, - tag_value: str, + tag_name: str = None, + tag_value: str = None, aml_workspace: Workspace = None ) -> AMLModel: """ Retrieves and returns the latest model from the workspace - by its name and tag. + by its name and (optional) tag. Parameters: aml_workspace (Workspace): aml.core Workspace that the model lives. model_name (str): name of the model we are looking for - tag (str): the tag value the model was registered under. + (optional) tag (str): the tag value & name the model was registered under. Return: A single aml model from the workspace that matches the name and tag. @@ -44,71 +44,37 @@ def get_model_by_tag( # Validate params. cannot be None. if model_name is None: raise ValueError("model_name[:str] is required") - if tag_name is None: - raise ValueError("tag_name[:str] is required") - if tag_value is None: - raise ValueError("tag[:str] is required") + if aml_workspace is None: + print("No workspace defined - using current experiment workspace.") aml_workspace = get_current_workspace() - # get model by tag. - model_list = AMLModel.list( - aml_workspace, name=model_name, - tags=[[tag_name, tag_value]], latest=True - ) + model_list = None + tag_ext = "" + + # Get lastest model + # True: by name and tags + if tag_name is not None or tag_value is not None: + model_list = AMLModel.list( + aml_workspace, name=model_name, + tags=[[tag_name, tag_value]], latest=True + ) + tag_ext = f"tag_name: {tag_name}, tag_value: {tag_value}." + # False: Only by name + else: + model_list = AMLModel.list( + aml_workspace, name=model_name, latest=True) # latest should only return 1 model, but if it does, # then maybe sdk or source code changed. - should_not_happen = ("Found more than one model " - "for the latest with {{tag_name: {tag_name}," - "tag_value: {tag_value}. " - "Models found: {model_list}}}")\ - .format(tag_name=tag_name, tag_value=tag_value, - model_list=model_list) - no_model_found = ("No Model found with {{tag_name: {tag_name} ," - "tag_value: {tag_value}.}}")\ - .format(tag_name=tag_name, tag_value=tag_value) - - if len(model_list) > 1: - raise ValueError(should_not_happen) - if len(model_list) == 1: - return model_list[0] - else: - print(no_model_found) - return None - except Exception: - raise - - -def get_latest_model( - model_name: str, - aml_workspace: Workspace = None -) -> AMLModel: - """ - Retrieves and returns the latest model from the workspace. - Parameters: - aml_workspace (Workspace): aml.core Workspace that the model lives. - model_name (str): name of the model we are looking for + # define the error messages + too_many_model_message = ("Found more than one latest model. " + f"Models found: {model_list}. " + f"{tag_ext}") - Return: - A single aml model from the workspace that matches the name and tag. - """ - try: - # Validate params. cannot be None. - if model_name is None: - raise ValueError("model_name[:str] is required") - if aml_workspace is None: - aml_workspace = get_current_workspace() - - # get model by tag. - model_list = AMLModel.list(aml_workspace, name=model_name, latest=True) - - # latest should only return 1 model, but if it does, - # then maybe sdk or source code changed. - too_many_model_message = ("Found more than one model. " - f"Models found: {model_list}") - no_model_found_message = (f"No Model found with name: {model_name}") + no_model_found_message = (f"No Model found with name: {model_name}. " + f"{tag_ext}") if len(model_list) > 1: raise ValueError(too_many_model_message) diff --git a/ml_service/pipelines/diabetes_regression_verify_train_pipeline.py b/ml_service/pipelines/diabetes_regression_verify_train_pipeline.py index f0a4c965..306f2259 100644 --- a/ml_service/pipelines/diabetes_regression_verify_train_pipeline.py +++ b/ml_service/pipelines/diabetes_regression_verify_train_pipeline.py @@ -3,7 +3,7 @@ import os from azureml.core import Run, Experiment, Workspace from ml_service.util.env_variables import Env -from diabetes_regression.util.model_helper import get_model_by_tag +from diabetes_regression.util.model_helper import get_latest_model def main(): @@ -53,7 +53,7 @@ def main(): try: tag_name = 'BuildId' - model = get_model_by_tag( + model = get_latest_model( model_name, tag_name, build_id, exp.workspace) if (model is not None): print("Model was registered for this build.") From 025b13cc4572a3fbb002cc32accb93b065ebe82b Mon Sep 17 00:00:00 2001 From: Daniel Heinze Date: Sat, 14 Mar 2020 09:02:20 +0100 Subject: [PATCH 4/4] Update model_helper.py --- diabetes_regression/util/model_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diabetes_regression/util/model_helper.py b/diabetes_regression/util/model_helper.py index 3876f4df..ceceff41 100644 --- a/diabetes_regression/util/model_helper.py +++ b/diabetes_regression/util/model_helper.py @@ -54,7 +54,7 @@ def get_latest_model( # Get lastest model # True: by name and tags - if tag_name is not None or tag_value is not None: + if tag_name is not None and tag_value is not None: model_list = AMLModel.list( aml_workspace, name=model_name, tags=[[tag_name, tag_value]], latest=True