{ "cells": [ { "cell_type": "markdown", "id": "9060b8c1-364a-4ce0-9cd9-4ac1d8bef574", "metadata": { "tags": [] }, "source": [ "# Using [@remote](https://sagemaker.readthedocs.io/en/stable/remote_function/sagemaker.remote_function.html#remote-decorator) Decorator from Amazon SageMaker Python SDK with private PyPI repository" ] }, { "cell_type": "markdown", "id": "3b034e53-a264-4511-b2ac-b89f06e81c14", "metadata": {}, "source": [ "This notebook shows how to use @remote decorator from Amazon SageMaker Python SDK, to use a private package repository hosted on [AWS CodeArtifact](https://docs.aws.amazon.com/codeartifact/latest/ug/welcome.html). The training job runs in a VPC with no internet access." ] }, { "cell_type": "markdown", "id": "ce94f110-992c-4f2c-a51e-d9970814a3e5", "metadata": {}, "source": [ "## Fetch VPC Endpoint URL for CodeArtifact API\n", "\n", "First of all, we need to fetch the VPC Endpoint URLs for CodeArtifact API. This endpoint URL is needed to establish connection with the private PyPI repository.\n", "\n", "The `describe_vpc_endpoints` API returns two VPC Endpoint URLs and we can use any of those to connect to CodeArticat repository." ] }, { "cell_type": "code", "execution_count": null, "id": "97187a2c-7d81-46eb-8929-6bf0eae795cb", "metadata": { "tags": [] }, "outputs": [], "source": [ "import boto3\n", "\n", "ec2 = boto3.client('ec2')\n", "boto3_session = boto3.session.Session()\n", "region = boto3_session.region_name\n", "sts = boto3.client('sts', endpoint_url=f\"https://sts.{region}.amazonaws.com/\")\n", "account_id = sts.get_caller_identity()[\"Account\"]\n", "\n", "account_id" ] }, { "cell_type": "code", "execution_count": null, "id": "31e31a79-c4fc-47dd-a64e-2e172d6d25bf", "metadata": { "tags": [] }, "outputs": [], "source": [ "\n", "response = ec2.describe_vpc_endpoints(\n", " Filters=[\n", " {\n", " 'Name': 'service-name',\n", " 'Values': [\n", " f'com.amazonaws.{boto3_session.region_name}.codeartifact.api'\n", " ]\n", " },\n", " ]\n", ")\n", "\n", "code_artifact_api_vpc_endpoint = response['VpcEndpoints'][0]['DnsEntries'][0]['DnsName']\n", "\n", "endpoint_url = f'https://{code_artifact_api_vpc_endpoint}'\n", "endpoint_url" ] }, { "cell_type": "markdown", "id": "715f72b4-a812-42dd-a834-e703a5990d5f", "metadata": {}, "source": [ "## Update Config.yaml\n", "\n", "Next, we need to update the `config.yaml`. It can be found under [config](../config/config.yaml) folder. The following fields need to be updated:\n", "- **PreExecutionCommands** - Update this field with the right connection URL for CodeArtifact private repository\n", " \n", "- **RoleArn** : Provide an execution role ARN which should be used for running the training job. In this case, the current SageMaker Execution role would work fine. This can be found either from the output of studio-codeartifact.yaml stack created earlier. Alternatively, this can also be found in the domain details from SageMaker Console.\n", " \n", "- **S3RootUri**: S3 Bucket where all the job config and output will be stored. Provide any bucket in the current region.\n", " \n", "- **VpcConfig**: Provide details around the subnet IDs of the VPC and Security Group ID associated with SageMaker Studio. This info can be found from the output of the vpc.yaml stack created earlier. Another way would be to just navigate to VPC console and find the Subnet IDs and navigate to EC2 console to find the SageMaker Security Group.\n", "\n", "\n", "___NOTE: It is not mandatory to use the config.yaml in order to work with @remote decorator. Rather this is just a cleaner way to supply all configurations to @remote decorator. All the configs can very well be supplied directly in the decorator arguments but that reduces readability and maintainability of changes in the long run.___" ] }, { "cell_type": "markdown", "id": "0408e375-b1f6-4d2b-8fe0-e1db1e998590", "metadata": {}, "source": [ "## Authenticate to CodeArtifact private PyPI repository\n", "\n", "The next thing to do is to authenticate to CodeArtifact private PyPI repository so an active login session can be established. By default the session is valid for 12 hours and is configurable as well. Change the domain owner value to the AWS account id\n" ] }, { "cell_type": "code", "execution_count": null, "id": "2ff8b185-a7a0-471f-b24b-d35beb86ca4b", "metadata": { "tags": [] }, "outputs": [], "source": [ "!aws codeartifact login --tool pip --domain anycompany --domain-owner {account_id} --repository private-pypi --endpoint-url {endpoint_url}" ] }, { "cell_type": "markdown", "id": "ecd40223-4674-400b-842f-3d9ef2f34ba7", "metadata": {}, "source": [ "## Install dependencies in the notebook env\n", "\n", "This is needed in order to run the train.py in the subsequent cells" ] }, { "cell_type": "code", "execution_count": null, "id": "af4841af-e408-4f77-abe7-7f3e6b7d74d5", "metadata": { "tags": [] }, "outputs": [], "source": [ "!pip install --no-cache-dir -r ./config/requirements.txt" ] }, { "cell_type": "markdown", "id": "7aa72ce4-b55d-4f85-9c32-a07a9946484d", "metadata": {}, "source": [ "## Run the training job\n", "\n", "Now, we can start the training job by simply running the `train.py` file. Lets see the content of the file to see how different it is from native pytorch code." ] }, { "cell_type": "code", "execution_count": null, "id": "e1a70c0f-e35e-42e2-818a-79b2554ca16c", "metadata": { "tags": [] }, "outputs": [], "source": [ "!pygmentize scripts/train.py" ] }, { "cell_type": "markdown", "id": "72af3264-2833-4d20-bddc-295011555679", "metadata": {}, "source": [ "# \n", "As we can see the code is agnostic to SageMaker with only change being `@remote(include_local_workdir=True)` being mentioned for `perform_train()` method. And that's it.\n", "\n", "Now, lets run the training job" ] }, { "cell_type": "code", "execution_count": null, "id": "a628e2e6-61b1-4677-9530-f193ffa7576a", "metadata": { "tags": [] }, "outputs": [], "source": [ "import os \n", "os.chdir ('scripts')\n", "\n", "!python ./train.py\n", "\n", "os.chdir('../')" ] }, { "cell_type": "code", "execution_count": null, "id": "c997740e-acd9-4e8a-ba3e-87ba50e06f20", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "availableInstances": [ { "_defaultOrder": 0, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 4, "name": "ml.t3.medium", "vcpuNum": 2 }, { "_defaultOrder": 1, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.t3.large", "vcpuNum": 2 }, { "_defaultOrder": 2, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.t3.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 3, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.t3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 4, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.m5.large", "vcpuNum": 2 }, { "_defaultOrder": 5, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.m5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 6, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.m5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 7, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.m5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 8, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.m5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 9, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.m5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 10, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.m5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 11, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.m5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 12, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.m5d.large", "vcpuNum": 2 }, { "_defaultOrder": 13, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.m5d.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 14, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.m5d.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 15, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.m5d.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 16, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.m5d.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 17, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.m5d.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 18, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.m5d.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 19, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.m5d.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 20, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": true, "memoryGiB": 0, "name": "ml.geospatial.interactive", "supportedImageNames": [ "sagemaker-geospatial-v1-0" ], "vcpuNum": 0 }, { "_defaultOrder": 21, "_isFastLaunch": true, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 4, "name": "ml.c5.large", "vcpuNum": 2 }, { "_defaultOrder": 22, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.c5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 23, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.c5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 24, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.c5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 25, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 72, "name": "ml.c5.9xlarge", "vcpuNum": 36 }, { "_defaultOrder": 26, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 96, "name": "ml.c5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 27, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 144, "name": "ml.c5.18xlarge", "vcpuNum": 72 }, { "_defaultOrder": 28, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.c5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 29, "_isFastLaunch": true, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.g4dn.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 30, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.g4dn.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 31, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.g4dn.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 32, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.g4dn.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 33, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.g4dn.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 34, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.g4dn.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 35, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 61, "name": "ml.p3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 36, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 244, "name": "ml.p3.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 37, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 488, "name": "ml.p3.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 38, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 768, "name": "ml.p3dn.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 39, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.r5.large", "vcpuNum": 2 }, { "_defaultOrder": 40, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.r5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 41, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.r5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 42, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.r5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 43, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.r5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 44, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.r5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 45, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 512, "name": "ml.r5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 46, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 768, "name": "ml.r5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 47, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.g5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 48, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.g5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 49, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.g5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 50, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.g5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 51, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.g5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 52, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.g5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 53, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.g5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 54, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 768, "name": "ml.g5.48xlarge", "vcpuNum": 192 }, { "_defaultOrder": 55, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 1152, "name": "ml.p4d.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 56, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 1152, "name": "ml.p4de.24xlarge", "vcpuNum": 96 } ], "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:eu-west-1:470317259841:image/datascience-1.0" }, "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.7.10" } }, "nbformat": 4, "nbformat_minor": 5 }