Skip to content

Commit be3ad4d

Browse files
Squashed commit of the following:
commit e6684e2 Merge: 9f0b787 5f17132 Author: Anamaria Todor <[email protected]> Date: Mon Nov 7 08:52:54 2022 +0100 Merge pull request #12 from absynthe/refactor/04pipelines refactor: unused vars, language and import changes commit 9f0b787 Merge: 75985c7 388b6b6 Author: Anamaria Todor <[email protected]> Date: Mon Nov 7 08:52:33 2022 +0100 Merge pull request #11 from absynthe/fix/connect-02-03 Fix: connect 02 and 03 commit 5f17132 Merge: ada1a8a 8bac4c3 Author: niklas-palm <[email protected]> Date: Sun Nov 6 21:58:22 2022 +0100 Merge pull request #13 from absynthe/refactor/update-model-fetching refactor: Update model fetching commit 8bac4c3 Author: Niklas Palm <[email protected]> Date: Sun Nov 6 20:57:29 2022 +0000 Remove output commit 6aac58d Author: Niklas Palm <[email protected]> Date: Sun Nov 6 20:54:02 2022 +0000 Fetch model from known prefix commit ada1a8a Author: Niklas Palm <[email protected]> Date: Sun Nov 6 20:36:35 2022 +0000 Remove cleanup step commit f559fab Author: Niklas Palm <[email protected]> Date: Sun Nov 6 20:34:43 2022 +0000 Remove unsed processor and fetch JsonGet from functions package commit 8567136 Author: Niklas Palm <[email protected]> Date: Sun Nov 6 20:30:11 2022 +0000 Remove model approval status commit a31a0f7 Author: Niklas Palm <[email protected]> Date: Sun Nov 6 19:31:12 2022 +0000 Remove approaval status parameter commit 388b6b6 Author: Niklas Palm <[email protected]> Date: Sun Nov 6 19:18:18 2022 +0000 Lower number of max training jobs commit b4aba82 Merge: f14b6c7 75985c7 Author: Niklas Palm <[email protected]> Date: Fri Nov 4 13:46:11 2022 +0000 Merge branch 'main' into fix/connect-02-03 commit f14b6c7 Author: Niklas Palm <[email protected]> Date: Fri Nov 4 13:45:07 2022 +0000 Connect hpo and evaluation
1 parent 0262fcf commit be3ad4d

File tree

6 files changed

+84
-178
lines changed

6 files changed

+84
-178
lines changed

01_preprocessing/data_preprocessing.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@
296296
"kernelspec": {
297297
"display_name": "Python 3 (Data Science)",
298298
"language": "python",
299-
"name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/datascience-1.0"
299+
"name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:eu-west-1:470317259841:image/datascience-1.0"
300300
},
301301
"language_info": {
302302
"codemirror_mode": {

02_training/training.ipynb

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343
"metadata": {},
4444
"outputs": [],
4545
"source": [
46-
"processed_data_prefix = f'{prefix}/outputs' #prefix generated by data processing module\n",
47-
"processed_data_s3_uri = f's3://{default_bucket}/{processed_data_prefix}'"
46+
"processed_data_s3_uri = f's3://{default_bucket}/{prefix}/outputs'\n",
47+
"model_output_path = f's3://{default_bucket}/{prefix}/outputs/model'"
4848
]
4949
},
5050
{
@@ -147,7 +147,7 @@
147147
" hyperparameter_ranges,\n",
148148
" metric_definitions=metric_definitions,\n",
149149
" objective_type=\"Maximize\",\n",
150-
" max_jobs=6,\n",
150+
" max_jobs=2, # Low because of demo purposes\n",
151151
" max_parallel_jobs=2,\n",
152152
" base_tuning_job_name=\"cv-hpo\",\n",
153153
")\n",
@@ -185,6 +185,22 @@
185185
"\n",
186186
"print(f\"\\nBest model artifact file is uploaded here: {best_model_uri}\")"
187187
]
188+
},
189+
{
190+
"cell_type": "markdown",
191+
"metadata": {},
192+
"source": [
193+
"Copy the best model into the prefix used for this project. Note that's possible to directly reference the tuner's output, as above, but given the modularity of this workshop, the artefacts are copied to a known location in S3."
194+
]
195+
},
196+
{
197+
"cell_type": "code",
198+
"execution_count": null,
199+
"metadata": {},
200+
"outputs": [],
201+
"source": [
202+
"!aws s3 cp {best_model_uri} {model_output_path}/model.tar.gz"
203+
]
188204
}
189205
],
190206
"metadata": {

03_model_evaluation/model-evaluation-processing-job.ipynb

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,12 @@
9494
"cell_type": "code",
9595
"execution_count": null,
9696
"source": [
97-
"s3_client = boto3.client('s3')\r\n",
98-
"model_dir = s3_client.list_objects_v2(Bucket=bucket, Delimiter='/', Prefix=f'{prefix}/{prefix}')['CommonPrefixes'][-1]['Prefix']\r\n",
99-
"\r\n",
100-
"s3_images = f's3://{bucket}/{prefix}/outputs/test/'\r\n",
101-
"s3_manifest = f's3://{bucket}/{prefix}/outputs/manifest'\r\n",
102-
"s3_model = f's3://{bucket}/{model_dir}output'\r\n",
103-
"\r\n",
104-
"print(f's3_images: {s3_images},\\n s3_manifest: {s3_manifest},\\n s3_model: {s3_model}')"
105-
],
106-
"outputs": [],
107-
"metadata": {}
97+
"s3_images = f's3://{bucket}/{prefix}/outputs/test/'\n",
98+
"s3_manifest = f's3://{bucket}/{prefix}/outputs/manifest'\n",
99+
"s3_model = f's3://{bucket}/{prefix}/outputs/model/'\n",
100+
"\n",
101+
"print(f's3_images: {s3_images},\\ns3_manifest: {s3_manifest},\\ns3_model: {s3_model}')"
102+
]
108103
},
109104
{
110105
"cell_type": "markdown",
@@ -278,24 +273,22 @@
278273
"cell_type": "code",
279274
"execution_count": null,
280275
"source": [
281-
"script_processor.run(\r\n",
282-
" code='evaluation.py',\r\n",
283-
" arguments=[\"--model-file\", \"model.tar.gz\"],\r\n",
284-
" inputs=[ProcessingInput(source=s3_images, \r\n",
285-
" destination=\"/opt/ml/processing/input/test\"),\r\n",
286-
" ProcessingInput(source=s3_manifest, \r\n",
287-
" destination=\"/opt/ml/processing/input/manifest\"),\r\n",
288-
" ProcessingInput(source=s3_model, \r\n",
289-
" destination=\"/opt/ml/processing/model\"),\r\n",
290-
" ],\r\n",
291-
" outputs=[\r\n",
292-
" ProcessingOutput(output_name=\"evaluation\", source=\"/opt/ml/processing/evaluation\", \r\n",
293-
" destination=s3_evaluation_output),\r\n",
294-
" ]\r\n",
295-
" )"
296-
],
297-
"outputs": [],
298-
"metadata": {}
276+
"script_processor.run(\n",
277+
" code='evaluation.py',\n",
278+
" arguments=[\"--model-file\", \"model.tar.gz\"],\n",
279+
" inputs=[ProcessingInput(source=s3_images, \n",
280+
" destination=\"/opt/ml/processing/input/test\"),\n",
281+
" ProcessingInput(source=s3_manifest, \n",
282+
" destination=\"/opt/ml/processing/input/manifest\"),\n",
283+
" ProcessingInput(source=s3_model, \n",
284+
" destination=\"/opt/ml/processing/model\"),\n",
285+
" ],\n",
286+
" outputs=[\n",
287+
" ProcessingOutput(output_name=\"evaluation\", source=\"/opt/ml/processing/evaluation\", \n",
288+
" destination=s3_evaluation_output),\n",
289+
" ]\n",
290+
")"
291+
]
299292
},
300293
{
301294
"cell_type": "markdown",
@@ -355,7 +348,7 @@
355348
"kernelspec": {
356349
"display_name": "Python 3 (Data Science)",
357350
"language": "python",
358-
"name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/datascience-1.0"
351+
"name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:eu-west-1:470317259841:image/datascience-1.0"
359352
},
360353
"language_info": {
361354
"codemirror_mode": {

04_training_pipeline/pipeline.ipynb

Lines changed: 36 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
"\n",
5757
"- Access to the SageMaker default S3 bucket\n",
5858
"- Access to Elastic Container Registry (ECR)\n",
59-
"- For the optional portion of this lab, you will need access to CloudFormation, Service Catelog, and Cost Explore\n",
59+
"- For the optional portion of this lab, you will need access to CloudFormation, Service Catalog, and Cost Explorer\n",
6060
"- Familiarity with Training on Amazon SageMaker\n",
6161
"- Familiarity with Python\n",
6262
"- Familiarity with AWS S3\n",
@@ -72,9 +72,7 @@
7272
"source": [
7373
"## Setup\n",
7474
"\n",
75-
"Here we define the sagemaker session, default bucket, job prefixes, pipeline and model group names\n",
76-
"\n",
77-
"We are using some of the newly released SageMaker Pipeline features. Please make sure you ugrade your sageMaker version by running the cell below."
75+
"Here we define the sagemaker session, default bucket, job prefixes, pipeline and model group names."
7876
],
7977
"metadata": {}
8078
},
@@ -189,39 +187,34 @@
189187
"cell_type": "code",
190188
"execution_count": null,
191189
"source": [
192-
"from sagemaker.workflow.parameters import (\r\n",
193-
" ParameterInteger,\r\n",
194-
" ParameterString,\r\n",
195-
")\r\n",
196-
"\r\n",
197-
"# Parameters for pipeline execution\r\n",
198-
"processing_instance_count = ParameterInteger(\r\n",
199-
" name=\"ProcessingInstanceCount\", default_value=1\r\n",
200-
")\r\n",
201-
"\r\n",
202-
"model_approval_status = ParameterString(\r\n",
203-
" name=\"ModelApprovalStatus\",\r\n",
204-
" default_value=\"PendingManualApproval\" # ModelApprovalStatus can be set to a default of \"Approved\" if you don't want manual approval.\r\n",
205-
")\r\n",
206-
"\r\n",
207-
"input_data = ParameterString(\r\n",
208-
" name=\"InputDataUrl\",\r\n",
209-
" default_value=s3_raw_data\r\n",
210-
")\r\n",
211-
"\r\n",
212-
"input_annotation = ParameterString(\r\n",
213-
" name=\"AnnotationFileName\",\r\n",
214-
" default_value=\"classes.txt\"\r\n",
215-
")\r\n",
216-
"\r\n",
217-
"# This is a large dataset, we are only going to train a subset of the classes\r\n",
218-
"class_selection = ParameterString(\r\n",
219-
" name=\"ClassSelection\",\r\n",
220-
" default_value=\"13, 17, 35, 36, 47, 68, 73, 87\" #If use the mini dataset, please make sure to use the class index with the available list\r\n",
221-
")\r\n",
222-
"\r\n",
223-
"processing_instance_type = \"ml.m5.xlarge\"\r\n",
224-
"training_instance_count = 1\r\n",
190+
"from sagemaker.workflow.parameters import (\n",
191+
" ParameterInteger,\n",
192+
" ParameterString,\n",
193+
")\n",
194+
"\n",
195+
"# Parameters for pipeline execution\n",
196+
"processing_instance_count = ParameterInteger(\n",
197+
" name=\"ProcessingInstanceCount\", default_value=1\n",
198+
")\n",
199+
"\n",
200+
"input_data = ParameterString(\n",
201+
" name=\"InputDataUrl\",\n",
202+
" default_value=s3_raw_data\n",
203+
")\n",
204+
"\n",
205+
"input_annotation = ParameterString(\n",
206+
" name=\"AnnotationFileName\",\n",
207+
" default_value=\"classes.txt\"\n",
208+
")\n",
209+
"\n",
210+
"# This is a large dataset, we are only going to train a subset of the classes\n",
211+
"class_selection = ParameterString(\n",
212+
" name=\"ClassSelection\",\n",
213+
" default_value=\"13, 17, 35, 36, 47, 68, 73, 87\" #If use the mini dataset, please make sure to use the class index with the available list\n",
214+
")\n",
215+
"\n",
216+
"processing_instance_type = \"ml.m5.xlarge\"\n",
217+
"training_instance_count = 1\n",
225218
"training_instance_type = \"ml.c5.4xlarge\""
226219
],
227220
"outputs": [],
@@ -261,7 +254,7 @@
261254
"cell_type": "markdown",
262255
"source": [
263256
"### Preprocess data step\n",
264-
"We are taking the original code in Jupyter notebook and containerized script to run in a preprocessing job.\n",
257+
"We are taking the original code in Jupyter notebook and create a containerized script to run in a preprocessing job.\n",
265258
"\n",
266259
"The [preprocess.py](./preprocess.py) script takes in the raw images files and splits them into training, validation and test sets by class.\n",
267260
"It merges the class annotation files so that you have a manifest file for each separate data set. And exposes two parameters: classes (allows you to filter the number of classes you want to train the model on; default is all classes) and input-data (the human readable name of the classes).\n",
@@ -478,12 +471,9 @@
478471
"from sagemaker.processing import (\r\n",
479472
" ProcessingInput,\r\n",
480473
" ProcessingOutput,\r\n",
481-
" FrameworkProcessor,\r\n",
482474
" ScriptProcessor,\r\n",
483475
")\r\n",
484476
"\r\n",
485-
"\r\n",
486-
"\r\n",
487477
"eval_steps = dict()\r\n",
488478
"eval_reports = dict()\r\n",
489479
"\r\n",
@@ -527,7 +517,7 @@
527517
" property_files=[evaluation_report],\r\n",
528518
" cache_config=cache_config\r\n",
529519
" )\r\n",
530-
" \r\n",
520+
"\r\n",
531521
" eval_steps[t] = step_eval\r\n",
532522
" eval_reports[t] = evaluation_report"
533523
],
@@ -583,7 +573,6 @@
583573
" inference_instances=[\"ml.t2.medium\", \"ml.m5.large\"],\r\n",
584574
" transform_instances=[\"ml.m5.large\"],\r\n",
585575
" model_package_group_name=model_package_group_name,\r\n",
586-
" approval_status=model_approval_status,\r\n",
587576
" model_metrics=model_metrics,\r\n",
588577
" )\r\n",
589578
" \r\n",
@@ -607,10 +596,8 @@
607596
"execution_count": null,
608597
"source": [
609598
"from sagemaker.workflow.conditions import ConditionGreaterThanOrEqualTo\r\n",
610-
"from sagemaker.workflow.condition_step import (\r\n",
611-
" ConditionStep,\r\n",
612-
" JsonGet,\r\n",
613-
")\r\n",
599+
"from sagemaker.workflow.condition_step import ConditionStep\r\n",
600+
"from sagemaker.workflow.functions import JsonGet\r\n",
614601
"\r\n",
615602
"condition_steps = dict()\r\n",
616603
"\r\n",
@@ -620,7 +607,7 @@
620607
" # Models with a test accuracy lower than the condition will not be registered with the model registry.\r\n",
621608
" cond_gte = ConditionGreaterThanOrEqualTo(\r\n",
622609
" left=JsonGet(\r\n",
623-
" step=eval_steps[t],\r\n",
610+
" step_name=eval_steps[t].name,\r\n",
624611
" property_file=eval_reports[t],\r\n",
625612
" json_path=\"multiclass_classification_metrics.accuracy.value\",\r\n",
626613
" ),\r\n",
@@ -677,7 +664,6 @@
677664
" name=pipeline_name,\r\n",
678665
" parameters=[\r\n",
679666
" processing_instance_count,\r\n",
680-
" model_approval_status,\r\n",
681667
" input_data,\r\n",
682668
" input_annotation,\r\n",
683669
" class_selection\r\n",
@@ -817,7 +803,6 @@
817803
"# ProcessingInstanceType=\"ml.m5.xlarge\",\r\n",
818804
"# TrainingInstanceCount=1,\r\n",
819805
"# TrainingInstanceType=\"ml.c5.4xlarge\",#\"ml.p3.2xlarge\",#\r\n",
820-
" ModelApprovalStatus=\"PendingManualApproval\",\r\n",
821806
" AnnotationFileName=\"classes.txt\",\r\n",
822807
" ClassSelection=\"13, 17, 35, 36\"\r\n",
823808
" )\r\n",
@@ -848,93 +833,14 @@
848833
"To automate the deployment process, You can use event bridge to Invoke a **deployment Lambda function** that checks the `ModelApprovalStatus` attribute in the event. If the status is **Approved** the Lambda will continue with the deployement."
849834
],
850835
"metadata": {}
851-
},
852-
{
853-
"cell_type": "markdown",
854-
"source": [
855-
"## Clean up\n",
856-
"Delete the model registry and the pipeline after you complete the lab."
857-
],
858-
"metadata": {}
859-
},
860-
{
861-
"cell_type": "code",
862-
"execution_count": null,
863-
"source": [
864-
"def delete_model_package_group(sm_client, package_group_name):\r\n",
865-
" try:\r\n",
866-
" model_versions = sm_client.list_model_packages(ModelPackageGroupName=package_group_name)\r\n",
867-
"\r\n",
868-
" except Exception as e:\r\n",
869-
" print(\"{} \\n\".format(e))\r\n",
870-
" return\r\n",
871-
"\r\n",
872-
" for model_version in model_versions[\"ModelPackageSummaryList\"]:\r\n",
873-
" try:\r\n",
874-
" sm_client.delete_model_package(ModelPackageName=model_version[\"ModelPackageArn\"])\r\n",
875-
" except Exception as e:\r\n",
876-
" print(\"{} \\n\".format(e))\r\n",
877-
" time.sleep(0.5) # Ensure requests aren't throttled\r\n",
878-
"\r\n",
879-
" try:\r\n",
880-
" sm_client.delete_model_package_group(ModelPackageGroupName=package_group_name)\r\n",
881-
" print(\"{} model package group deleted\".format(package_group_name))\r\n",
882-
" except Exception as e:\r\n",
883-
" print(\"{} \\n\".format(e))\r\n",
884-
" return\r\n",
885-
"\r\n",
886-
"\r\n",
887-
"def delete_sagemaker_pipeline(sm_client, pipeline_name):\r\n",
888-
" try:\r\n",
889-
" sm_client.delete_pipeline(\r\n",
890-
" PipelineName=pipeline_name,\r\n",
891-
" )\r\n",
892-
" print(\"{} pipeline deleted\".format(pipeline_name))\r\n",
893-
" except Exception as e:\r\n",
894-
" print(\"{} \\n\".format(e))\r\n",
895-
" return\r\n",
896-
" \r\n",
897-
"def delete_sagemaker_project(sm_client, project_name):\r\n",
898-
" try:\r\n",
899-
" sm_client.delete_project(\r\n",
900-
" ProjectName=project_name,\r\n",
901-
" )\r\n",
902-
" print(\"{} project deleted\".format(project_name))\r\n",
903-
" except Exception as e:\r\n",
904-
" print(\"{} \\n\".format(e))\r\n",
905-
" return"
906-
],
907-
"outputs": [],
908-
"metadata": {}
909-
},
910-
{
911-
"cell_type": "code",
912-
"execution_count": null,
913-
"source": [
914-
"import boto3\n",
915-
"import time\n",
916-
"\n",
917-
"client = boto3.client(\"sagemaker\")\n",
918-
"\n",
919-
"# Uncomment the lines below to clean the pipeline.\n",
920-
"#delete_model_package_group(client, model_package_group_name)\n",
921-
"#delete_sagemaker_pipeline(client, pipeline_name)\n",
922-
"\n",
923-
"#delete_model_package_group(client, model_package_group_name2)\n",
924-
"#delete_sagemaker_pipeline(client, pipeline_name2)\n",
925-
"\n",
926-
"# delete_sagemaker_project(client, \"<Your-Project-Name>\")#\"cv-week4-training\") #"
927-
],
928-
"outputs": [],
929-
"metadata": {}
930836
}
931837
],
932838
"metadata": {
933839
"instance_type": "ml.t3.medium",
934840
"kernelspec": {
935841
"display_name": "Python 3 (Data Science)",
936842
"language": "python",
937-
"name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/datascience-1.0"
843+
"name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:eu-west-1:470317259841:image/datascience-1.0"
938844
},
939845
"language_info": {
940846
"codemirror_mode": {

0 commit comments

Comments
 (0)