Skip to content

Commit

Permalink
Merge pull request #29 from eitansela/main
Browse files Browse the repository at this point in the history
Add for Pip Environments as Kernels sample code
  • Loading branch information
knaresh authored Feb 1, 2023
2 parents 4c0b75e + d043433 commit 086c3a9
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 0 deletions.
7 changes: 7 additions & 0 deletions examples/pip-venv-kernel-image/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM python:3.11.1

RUN pip install ipykernel && \
python -m ipykernel install --sys-prefix

COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
121 changes: 121 additions & 0 deletions examples/pip-venv-kernel-image/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
## Pip Environments as Kernels


### Overview

This custom image sample demonstrates how to create a custom Pip environment in a Docker image and use it as a custom kernel in SageMaker Studio.

The Pip environment must have the appropriate kernel package installed, for e.g., `ipykernel` for a Python kernel. This example creates a Pip environment called `myenv` with a few Python packages (see [environment.yml](environment.yml)) and the `ipykernel`. SageMaker Studio will automatically recognize this Pip environment as a kernel named `pip-venv-myenv-py` (See [app-image-config-input.json](app-image-config-input.json))

### Building the image

Build the Docker image.
```
# Modify these as required. The Docker registry endpoint can be tuned based on your current region from https://docs.aws.amazon.com/general/latest/gr/ecr.html#ecr-docker-endpoints
REGION=<aws-region>
ACCOUNT_ID=<aws-account-id>
IMAGE_NAME=pip-venv-kernel
# Create ECR Repository. Ignore if it exists. For simplcity, all examples in the repo
# use same ECR repo with different image tags
aws --region ${REGION} ecr create-repository --repository-name smstudio-custom
# Build and push the image
aws --region ${REGION} ecr get-login-password | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom
docker build . -t ${IMAGE_NAME} -t ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom:${IMAGE_NAME}
```

### Local testing

Run the image locally to verify that the kernels in the image are visible to a Kernel Gateway.
```
docker run -it "$IMAGE_NAME" bash
```

Run the container with a KernelGateway to validate that the kernels are visible from the REST endpoint exposed to the host.

```
docker run -it -p 8888:8888 "$IMAGE_NAME" bash -c 'pip install jupyter_kernel_gateway && jupyter-kernelgateway --ip 0.0.0.0 --debug --port 8888'
```

Verify the Kernel Gateway is started successfully (e.g., *[KernelGatewayApp] Jupyter Kernel Gateway at http://0.0.0.0:8888* in the Docker logs) and validate that you can list the kernelspecs in the running container

```
curl http://0.0.0.0:8888/api/kernelspecs
```


### Pushing the image
Push the Docker image to Amazon ECR
```
docker push ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom:${IMAGE_NAME}
```

### Using with SageMaker Studio
Create a SageMaker Image (SMI) with the image in ECR. Request parameter RoleArn value is used to get
ECR image information when and Image version is created. After creating Image, create an Image Version during which
SageMaker stores image metadata like SHA etc. Everytime an image is updated in ECR, a new image version should be created.
See [Update Image](#updating-image-with-sageMaker-studio)

```bash
# Role in your account to be used for SageMakerImage. Modify as required.

ROLE_ARN=arn:aws:iam::${ACCOUNT_ID}:role/RoleName
aws --region ${REGION} sagemaker create-image \
--image-name ${IMAGE_NAME} \
--role-arn ${ROLE_ARN}

aws --region ${REGION} sagemaker create-image-version \
--image-name ${IMAGE_NAME} \
--base-image "${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom:${IMAGE_NAME}"

# Verify the image-version is created successfully. Do NOT proceed if image-version is in CREATE_FAILED state or in any other state apart from CREATED.
aws --region ${REGION} sagemaker describe-image-version --image-name ${IMAGE_NAME}
```

Create a AppImageConfig for this image

```bash
aws --region ${REGION} sagemaker create-app-image-config --cli-input-json file://app-image-config-input.json

```

Create a Domain, providing the SageMaker Image and AppImageConfig in the Domain input. Replace the placeholders for VPC ID, Subnet IDs, and Execution Role in `create-domain-input.json`

```bash
aws --region ${REGION} sagemaker create-domain --cli-input-json file://create-domain-input.json
```

If you have an existing Domain, you can also use the `update-domain`. Replace the placeholder for Domain ID in `update-domain-input.json`

```bash
aws --region ${REGION} sagemaker update-domain --cli-input-json file://update-domain-input.json
```

Create a User Profile, and start a Notebook using the SageMaker Studio launcher.

### Update Image with SageMaker Studio
If you found an issue with your image or want to update Image with new features, Use following steps

Re-Build and push the image to ECR

```
# Build and push the image
aws --region ${REGION} ecr get-login-password | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom
docker build . -t ${IMAGE_NAME} -t ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom:${IMAGE_NAME}
docker push ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom:${IMAGE_NAME}
```


Create new App Image Version
```
aws --region ${REGION} sagemaker create-image-version \
--image-name ${IMAGE_NAME} \
--base-image "${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/smstudio-custom:${IMAGE_NAME}"
# Verify the image-version is created successfully. Do NOT proceed if image-version is in CREATE_FAILED state or in any other state apart from CREATED.
aws --region ${REGION} sagemaker describe-image-version --image-name ${IMAGE_NAME}
```


Re-Create App in SageMaker studio.
16 changes: 16 additions & 0 deletions examples/pip-venv-kernel-image/app-image-config-input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"AppImageConfigName": "pip-venv-kernel-config",
"KernelGatewayImageConfig": {
"KernelSpecs": [
{
"Name": "python3",
"DisplayName": "Python [pip venv: myenv]"
}
],
"FileSystemConfig": {
"MountPath": "/root",
"DefaultUid": 0,
"DefaultGid": 0
}
}
}
19 changes: 19 additions & 0 deletions examples/pip-venv-kernel-image/create-domain-input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"DomainName": "domain-with-custom-pip-venv",
"VpcId": "<vpc-id>",
"SubnetIds": [
"<subnet-ids>"
],
"DefaultUserSettings": {
"ExecutionRole": "<role-arn>",
"KernelGatewayAppSettings": {
"CustomImages": [
{
"ImageName": "pip-venv-kernel",
"AppImageConfigName": "pip-venv-kernel-config"
}
]
}
},
"AuthMode": "IAM"
}
3 changes: 3 additions & 0 deletions examples/pip-venv-kernel-image/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
boto3
numpy
pandas
13 changes: 13 additions & 0 deletions examples/pip-venv-kernel-image/update-domain-input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"DomainId": "<domain-id>",
"DefaultUserSettings": {
"KernelGatewayAppSettings": {
"CustomImages": [
{
"ImageName": "pip-venv-kernel",
"AppImageConfigName": "pip-venv-kernel-config"
}
]
}
}
}

0 comments on commit 086c3a9

Please sign in to comment.