{ "cells": [ { "cell_type": "markdown", "id": "6eb825bb-e3c2-4838-b73c-528e1fc25735", "metadata": {}, "source": [ "# Step 4: Add a model building CI/CD pipeline\n", "\n", "In this step you create an automated CI/CD pipeline for model building using [Amazon SageMaker Projects](https://docs.aws.amazon.com/sagemaker/latest/dg/sagemaker-projects.html). \n", "\n", "\n", "\n", "You are going to use a [SageMaker-provided MLOps project template for model building and training](https://docs.aws.amazon.com/sagemaker/latest/dg/sagemaker-projects-templates-sm.html#sagemaker-projects-templates-code-commit) to provision a CI/CD workflow automation with [AWS CodePipeline](https://aws.amazon.com/codepipeline/) and an [AWS CodeCommit](https://aws.amazon.com/codecommit/) code repository.\n", "\n", "SageMaker project templates offer you the following choice of code repositories, workflow automation tools, and pipeline stages:\n", "- **Code repository**: AWS CodeCommit or third-party Git repositories such as GitHub and Bitbucket\n", "- **CI/CD workflow automation**: AWS CodePipeline or Jenkins\n", "- **Pipeline stages**: Model building and training, model deployment, or both" ] }, { "cell_type": "code", "execution_count": null, "id": "42102a0b-a706-43b3-9f23-59f7084123f1", "metadata": { "tags": [] }, "outputs": [], "source": [ "import boto3\n", "import sagemaker \n", "from time import gmtime, strftime, sleep" ] }, { "cell_type": "code", "execution_count": null, "id": "7c0dd762-ba2a-4141-b937-80cfccf98faf", "metadata": { "tags": [] }, "outputs": [], "source": [ "%store -r \n", "\n", "%store\n", "\n", "try:\n", " initialized\n", "except NameError:\n", " print(\"+++++++++++++++++++++++++++++++++++++++++++++++++\")\n", " print(\"[ERROR] YOU HAVE TO RUN 00-start-here notebook \")\n", " print(\"+++++++++++++++++++++++++++++++++++++++++++++++++\")" ] }, { "cell_type": "markdown", "id": "aaeaa68c-a2aa-4da5-8577-42d7dff2067a", "metadata": {}, "source": [ "## Create an MLOps project\n", "⭐ You can create a project programmatically in this notebook - Option 1 or in Studio - Option 2. Option 1 is recommended as it requires no manual input. Option 2 is given to demonstrate [**Create Project** UX flow](https://docs.aws.amazon.com/sagemaker/latest/dg/sagemaker-projects-create.html)." ] }, { "cell_type": "markdown", "id": "cd7061c4-b0f5-48a9-999c-1b0b84c8a4b9", "metadata": {}, "source": [ "### Option 1: Create project programmatically\n", "Use `boto3` to create an MLOps project via a SageMaker API." ] }, { "cell_type": "code", "execution_count": null, "id": "1002ef46-7906-44fe-a874-78c3607d827a", "metadata": { "tags": [] }, "outputs": [], "source": [ "sm = boto3.client(\"sagemaker\")\n", "sc = boto3.client(\"servicecatalog\")\n", "\n", "sc_provider_name = \"Amazon SageMaker\"\n", "sc_product_name = \"MLOps template for model building and training\"" ] }, { "cell_type": "code", "execution_count": null, "id": "a30b2c04-8c60-4f67-abef-284e47072110", "metadata": { "tags": [] }, "outputs": [], "source": [ "p_ids = [p['ProductId'] for p in sc.search_products(\n", " Filters={\n", " 'FullTextSearch': [sc_product_name]\n", " },\n", ")['ProductViewSummaries'] if p[\"Name\"]==sc_product_name]" ] }, { "cell_type": "code", "execution_count": null, "id": "579caafe-27c5-4a82-84c4-f364675ca7c7", "metadata": { "tags": [] }, "outputs": [], "source": [ "p_ids" ] }, { "cell_type": "code", "execution_count": null, "id": "2cef972c-ff89-49fb-a498-35f8a4768d25", "metadata": { "tags": [] }, "outputs": [], "source": [ "# If you get any exception from this code, go to the Option 2 and create a project in Studio UX\n", "if not len(p_ids):\n", " raise Exception(\"No Amazon SageMaker ML Ops products found!\")\n", "elif len(p_ids) > 1:\n", " raise Exception(\"Too many matching Amazon SageMaker ML Ops products found!\")\n", "else:\n", " product_id = p_ids[0]\n", " print(f\"ML Ops product id: {product_id}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "8b51c8dc-57e7-4ff1-a137-3f4e93d9594c", "metadata": { "tags": [] }, "outputs": [], "source": [ "provisioning_artifact_id = sorted(\n", " [i for i in sc.list_provisioning_artifacts(\n", " ProductId=product_id\n", " )['ProvisioningArtifactDetails'] if i['Guidance']=='DEFAULT'],\n", " key=lambda d: d['Name'], reverse=True)[0]['Id']" ] }, { "cell_type": "code", "execution_count": null, "id": "f65aa4b1-c848-45ce-9f51-b5c4b70175b1", "metadata": { "tags": [] }, "outputs": [], "source": [ "provisioning_artifact_id" ] }, { "cell_type": "code", "execution_count": null, "id": "ed952193-a0cf-48c8-b776-351f6452adc8", "metadata": { "tags": [] }, "outputs": [], "source": [ "project_name = f\"model-build-{strftime('%m-%d-%H-%M-%S', gmtime())}\"\n", "project_parameters = [] # This SageMaker built-in project template doesn't have any parameters" ] }, { "cell_type": "markdown", "id": "22e7f228-8ca1-4c93-8131-8901acf75165", "metadata": {}, "source": [ "Finally, create a SageMaker project from the service catalog product template:" ] }, { "cell_type": "code", "execution_count": null, "id": "4928192d-4580-4f23-ab89-749937365cfb", "metadata": { "tags": [] }, "outputs": [], "source": [ "# create SageMaker project\n", "r = sm.create_project(\n", " ProjectName=project_name,\n", " ProjectDescription=\"Model build project\",\n", " ServiceCatalogProvisioningDetails={\n", " 'ProductId': product_id,\n", " 'ProvisioningArtifactId': provisioning_artifact_id,\n", " },\n", ")\n", "\n", "print(r)\n", "project_id = r[\"ProjectId\"]" ] }, { "cell_type": "markdown", "id": "a82b313e-9025-42cb-8f7a-a617ed771e3e", "metadata": {}, "source": [ "
Shutting down your kernel for this notebook to release resources.
\n", "\n", " \n", "" ] }, { "cell_type": "code", "execution_count": null, "id": "b10fb645-0789-4fc4-a662-1502d7b30fd2", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "availableInstances": [ { "_defaultOrder": 0, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "memoryGiB": 4, "name": "ml.t3.medium", "vcpuNum": 2 }, { "_defaultOrder": 1, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 8, "name": "ml.t3.large", "vcpuNum": 2 }, { "_defaultOrder": 2, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 16, "name": "ml.t3.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 3, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 32, "name": "ml.t3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 4, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "memoryGiB": 8, "name": "ml.m5.large", "vcpuNum": 2 }, { "_defaultOrder": 5, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 16, "name": "ml.m5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 6, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 32, "name": "ml.m5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 7, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 64, "name": "ml.m5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 8, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 128, "name": "ml.m5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 9, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 192, "name": "ml.m5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 10, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 256, "name": "ml.m5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 11, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 384, "name": "ml.m5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 12, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 8, "name": "ml.m5d.large", "vcpuNum": 2 }, { "_defaultOrder": 13, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 16, "name": "ml.m5d.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 14, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 32, "name": "ml.m5d.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 15, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 64, "name": "ml.m5d.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 16, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 128, "name": "ml.m5d.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 17, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 192, "name": "ml.m5d.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 18, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 256, "name": "ml.m5d.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 19, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 384, "name": "ml.m5d.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 20, "_isFastLaunch": true, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 4, "name": "ml.c5.large", "vcpuNum": 2 }, { "_defaultOrder": 21, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 8, "name": "ml.c5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 22, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 16, "name": "ml.c5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 23, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 32, "name": "ml.c5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 24, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 72, "name": "ml.c5.9xlarge", "vcpuNum": 36 }, { "_defaultOrder": 25, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 96, "name": "ml.c5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 26, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 144, "name": "ml.c5.18xlarge", "vcpuNum": 72 }, { "_defaultOrder": 27, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 192, "name": "ml.c5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 28, "_isFastLaunch": true, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 16, "name": "ml.g4dn.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 29, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 32, "name": "ml.g4dn.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 30, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 64, "name": "ml.g4dn.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 31, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 128, "name": "ml.g4dn.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 32, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "memoryGiB": 192, "name": "ml.g4dn.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 33, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 256, "name": "ml.g4dn.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 34, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 61, "name": "ml.p3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 35, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "memoryGiB": 244, "name": "ml.p3.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 36, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "memoryGiB": 488, "name": "ml.p3.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 37, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "memoryGiB": 768, "name": "ml.p3dn.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 38, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 16, "name": "ml.r5.large", "vcpuNum": 2 }, { "_defaultOrder": 39, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 32, "name": "ml.r5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 40, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 64, "name": "ml.r5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 41, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 128, "name": "ml.r5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 42, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 256, "name": "ml.r5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 43, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 384, "name": "ml.r5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 44, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 512, "name": "ml.r5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 45, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 768, "name": "ml.r5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 46, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 16, "name": "ml.g5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 47, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 32, "name": "ml.g5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 48, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 64, "name": "ml.g5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 49, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 128, "name": "ml.g5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 50, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 256, "name": "ml.g5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 51, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "memoryGiB": 192, "name": "ml.g5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 52, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "memoryGiB": 384, "name": "ml.g5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 53, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "memoryGiB": 768, "name": "ml.g5.48xlarge", "vcpuNum": 192 } ], "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.12" } }, "nbformat": 4, "nbformat_minor": 5 }