forked from microsoft/MLOpsPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate_scoring_image.py
More file actions
124 lines (107 loc) · 4.36 KB
/
create_scoring_image.py
File metadata and controls
124 lines (107 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""
Copyright (C) Microsoft Corporation. All rights reserved.
Microsoft Corporation (“Microsoft”) grants you a nonexclusive, perpetual,
royalty-free right to use, copy, and modify the software code provided by us
("Software Code"). You may not sublicense the Software Code or any use of it
(except to your affiliates and to vendors to perform work on your behalf)
through distribution, network access, service agreement, lease, rental, or
otherwise. This license does not purport to express any claim of ownership over
data you may have shared with Microsoft in the creation of the Software Code.
Unless applicable law gives you more rights, Microsoft reserves all other
rights not expressly granted herein, whether by implication, estoppel or
otherwise.
THE SOFTWARE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
MICROSOFT OR ITS LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE CODE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
"""
import os, json, sys
import argparse
from azureml.core import Workspace
from azureml.core.image import ContainerImage, Image
from azureml.core import Run
from azureml.core.model import Model
from azureml.core.authentication import AzureCliAuthentication
cli_auth = AzureCliAuthentication()
run = Run.get_context()
if "OfflineRun" in run.id:
print("offline run")
# Get workspace
ws = Workspace.from_config(auth=cli_auth)
else:
exp = run.experiment
ws = run.experiment.workspace
# Get the latest model details
parser = argparse.ArgumentParser("scoring_image")
parser.add_argument(
"--config_suffix", type=str, help="Datetime suffix for json config files"
)
parser.add_argument(
"--json_config",
type=str,
help="Directory to write all the intermediate json configs",
)
args = parser.parse_args()
register_model_json = "model_{}.json".format(args.config_suffix)
register_output_path = os.path.join(args.json_config, register_model_json)
try:
with open(register_output_path) as f:
config = json.load(f)
except:
print("No new model to register thus no need to create new scoring image")
# raise Exception('No new model to register as production model perform better')
sys.exit(0)
model_name = config["model_name"]
model_version = config["model_version"]
model_list = Model.list(workspace=ws)
model, = (m for m in model_list if m.version == model_version and m.name == model_name)
print(
"Model picked: {} \nModel Description: {} \nModel Version: {}".format(
model.name, model.description, model.version
)
)
os.chdir("scoring")
image_name = "diabetes-model-score"
image_config = ContainerImage.image_configuration(
execution_script="score.py",
runtime="python-slim",
conda_file="conda_dependencies.yml",
description="Image with ridge regression model",
tags={"area": "diabetes", "type": "regression"},
)
image = Image.create(
name=image_name, models=[model], image_config=image_config, workspace=ws
)
image.wait_for_creation(show_output=True)
os.chdir("..")
if image.creation_state != "Succeeded":
raise Exception("Image creation status: {image.creation_state}")
print(
"{}(v.{} [{}]) stored at {} with build log {}".format(
image.name,
image.version,
image.creation_state,
image.image_location,
image.image_build_log_uri,
)
)
# Writing the image details to /aml_config/image.json
image_json = {}
image_json["image_name"] = image.name
image_json["image_version"] = image.version
image_json["image_location"] = image.image_location
# with open("aml_config/image.json", "w") as outfile:
# json.dump(image_json, outfile)
filename = "image_{}.json".format(args.config_suffix)
output_path = os.path.join(args.json_config, filename)
with open(output_path, "w") as outfile:
json.dump(image_json, outfile)
# How to fix the schema for a model, like if we have multiple models expecting different schema,