Skip to content

Commit 1503155

Browse files
committed
init
0 parents  commit 1503155

File tree

16 files changed

+1987
-0
lines changed

16 files changed

+1987
-0
lines changed

.DS_Store

6 KB
Binary file not shown.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Deploy HuggingFace Model to S3 from HuggingFace Hub
2+
3+
on:
4+
push:
5+
branches:
6+
- test
7+
- main
8+
workflow_dispatch:
9+
10+
permissions:
11+
id-token: write
12+
contents: read
13+
14+
env:
15+
AWS_REGION: "us-east-1"
16+
HF_MODEL_NAME: "tabularisai/multilingual-sentiment-analysis"
17+
ENVIRONMENT: ${{ github.ref_name == 'main' && 'prod' || github.ref_name == 'test' && 'test' }}
18+
19+
jobs:
20+
deploy_model:
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- name: Checkout Code
25+
uses: actions/checkout@v3
26+
27+
- name: Deploy Hugging Face Model
28+
run: |
29+
git clone ${{ env.HF_MODEL_NAME }}
30+
cd ${{ env.HF_MODEL_NAME }}
31+
32+
- name: Create Archive
33+
run: |
34+
cd ${{ env.HF_MODEL_NAME }}
35+
tar -czvf model.tar.gz *
36+
37+
- name: Configure AWS Credentials
38+
uses: aws-actions/configure-aws-credentials@v4
39+
with:
40+
audience: sts.amazonaws.com
41+
aws-region: ${{ env.AWS_REGION }}
42+
role-to-assume: arn:aws:iam::639269844451:role/github-actions
43+
role-session-name: testing-deployment
44+
45+
- name: Upload Model to S3
46+
env:
47+
S3_BUCKET_NAME: "dev-sagemaker-us-east-1-639269844451"
48+
S3_MODEL_PATH: "${{ env.ENVIRONMENT }}/${{ env.HF_MODEL_NAME }}/model.tar.gz"
49+
run: s3 cp model.tar.gz s3://${{ env.S3_BUCKET_NAME }}/${{ env.S3_MODEL_PATH }}

.gitignore

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Python-generated files
2+
__pycache__/
3+
*.py[oc]
4+
build/
5+
dist/
6+
wheels/
7+
*.egg-info
8+
9+
# Virtual environments
10+
.venv
11+
12+
.pytest_cache/
13+
hf_model/
14+
model.tar.gz
15+
16+
17+
.terraform/
18+
.terraform.lock.hcl

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.12

Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
ENV = dev
2+
3+
.PHONY: init
4+
init:
5+
terraform -chdir=terraform init
6+
7+
.PHONY: validate
8+
validate:
9+
terraform -chdir=terraform validate
10+
11+
.PHONY: plan
12+
plan:
13+
terraform -chdir=terraform plan
14+
15+
.PHONY: apply
16+
apply:
17+
terraform -chdir=terraform apply -auto-approve
18+
19+
.PHONY: destroy
20+
destroy:
21+
terraform -chdir=terraform destroy
22+
23+
.PHONY: workspace
24+
workspace:
25+
terraform -chdir=terraform workspace select -or-create ${ENV}

README.md

Whitespace-only changes.

pyproject.toml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[project]
2+
name = "aws-hf-model-deployment"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = ">=3.12"
7+
dependencies = [
8+
"huggingface-hub[cli]>=0.27.1",
9+
"humanize>=4.11.0",
10+
"transformers[torch]>=4.48.0",
11+
]
12+
13+
[dependency-groups]
14+
dev = [
15+
"boto3>=1.35.97",
16+
"pytest>=8.3.4",
17+
"sagemaker-huggingface-inference-toolkit>=2.4.1",
18+
]
19+
20+
[tool.mypy]
21+
disallow_untyped_calls = true
22+
23+
[tool.ruff]
24+
target-version = "py312"
25+
26+
[tool.ruff.lint]
27+
select = [
28+
"F", # Pyflakes
29+
"I", # isort
30+
"E", # pycodestyle
31+
"S", # flake8-bandit
32+
"N", # pep8-naming
33+
"PERF",
34+
]

terraform/main.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
locals {
2+
env = terraform.workspace
3+
}
4+
5+
module "model" {
6+
source = "./modules/aws-sagemaker-hf-pytorch-inference-model-deployment"
7+
aws_region = "us-east-1"
8+
model_author_name = "tabularisai"
9+
model_name = "multilingual-sentiment-analysis"
10+
model_src = abspath("../model.tar.gz")
11+
python_version = "py310"
12+
ubuntu_version = "22.04"
13+
transformers_version = "4.37.0"
14+
pytorch_version = "2.1.0"
15+
model_bucket_name = "sagemaker-us-east-1-639269844451"
16+
model_bucket_key = "${local.env}/tabularisai/multilingual-sentiment-analysis/model.tar.gz"
17+
instance_type = "ml.m5.large"
18+
memory_size_in_mb = 2048
19+
max_concurrency = 1
20+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
data "aws_caller_identity" "current" {}
2+
3+
4+
locals {
5+
env = terraform.workspace
6+
account_id = data.aws_caller_identity.current.account_id
7+
ecr_image_name = "763104351884.dkr.ecr.${var.aws_region}.amazonaws.com/huggingface-pytorch-inference"
8+
ecr_image_tag = "${var.pytorch_version}-transformers${var.transformers_version}-cpu-${var.python_version}-ubuntu${var.ubuntu_version}"
9+
}
10+
11+
resource "aws_s3_object" "model_upload" {
12+
bucket = var.model_bucket_name
13+
key = var.model_bucket_key
14+
source = var.model_src
15+
etag = filemd5(var.model_src)
16+
}
17+
18+
resource "aws_iam_role" "model_execution_role" {
19+
name = "${local.env}-sagemaker-${var.model_name}-execution-role"
20+
21+
assume_role_policy = jsonencode({
22+
Version = "2012-10-17"
23+
Statement = [
24+
{
25+
Effect = "Allow"
26+
Principal = {
27+
Service = "sagemaker.amazonaws.com"
28+
}
29+
Action = "sts:AssumeRole"
30+
},
31+
]
32+
})
33+
}
34+
35+
resource "aws_iam_policy" "s3_policy" {
36+
name = "${local.env}-sagemaker-${var.model_name}-s3-policy"
37+
38+
policy = jsonencode({
39+
"Version" : "2012-10-17",
40+
"Statement" : [
41+
{
42+
"Effect" : "Allow",
43+
"Action" : [
44+
"s3:GetObject",
45+
"s3:ListBucket",
46+
],
47+
"Resource" : "arn:aws:s3:::${var.model_bucket_name}/*"
48+
}
49+
]
50+
})
51+
}
52+
53+
resource "aws_iam_policy" "ecr_policy" {
54+
name = "${local.env}-sagemaker-${var.model_name}-ecr-policy"
55+
56+
policy = jsonencode({
57+
"Version" : "2012-10-17",
58+
"Statement" : [
59+
{
60+
"Effect" : "Allow",
61+
"Action" : [
62+
"ecr:GetAuthorizationToken",
63+
"ecr:BatchCheckLayerAvailability",
64+
"ecr:GetDownloadUrlForLayer",
65+
"ecr:GetRepositoryPolicy",
66+
"ecr:DescribeRepositories",
67+
"ecr:ListImages",
68+
"ecr:DescribeImages",
69+
"ecr:BatchGetImage",
70+
"ecr:GetLifecyclePolicy",
71+
"ecr:GetLifecyclePolicyPreview",
72+
"ecr:ListTagsForResource",
73+
"ecr:DescribeImageScanFindings",
74+
],
75+
"Resource" : "arn:aws:ecr:${var.aws_region}:*:repository/*"
76+
}
77+
]
78+
})
79+
}
80+
81+
resource "aws_iam_role_policy_attachment" "s3_policy_attachment" {
82+
policy_arn = aws_iam_policy.s3_policy.arn
83+
role = aws_iam_role.model_execution_role.name
84+
}
85+
86+
resource "aws_iam_role_policy_attachment" "ecr_policy_attachment" {
87+
policy_arn = aws_iam_policy.ecr_policy.arn
88+
role = aws_iam_role.model_execution_role.name
89+
}
90+
91+
92+
resource "aws_sagemaker_model" "model" {
93+
name = var.model_name
94+
execution_role_arn = aws_iam_role.model_execution_role.arn
95+
# primary_container {
96+
# image = "${local.ecr_image_name}:${local.ecr_image_tag}"
97+
# model_data_url = "s3://${aws_s3_object.model_upload.bucket}/${aws_s3_object.model_upload.key}"
98+
# }
99+
100+
primary_container {
101+
image = "763104351884.dkr.ecr.us-east-1.amazonaws.com/huggingface-pytorch-inference:2.1.0-transformers4.37.0-cpu-py310-ubuntu22.04"
102+
environment = {
103+
HF_MODEL_ID = "distilbert-base-uncased"
104+
HF_TASK = "text-classification"
105+
}
106+
}
107+
}
108+
109+
resource "aws_sagemaker_endpoint_configuration" "model_endpoint_configuration" {
110+
name = "${local.env}-sagemaker-${var.model_name}-endpoint-config"
111+
production_variants {
112+
initial_variant_weight = 1
113+
model_name = aws_sagemaker_model.model.name
114+
variant_name = "Version1"
115+
116+
serverless_config {
117+
memory_size_in_mb = var.memory_size_in_mb
118+
max_concurrency = var.max_concurrency
119+
}
120+
}
121+
}
122+
123+
resource "aws_sagemaker_endpoint" "model_endpoint" {
124+
endpoint_config_name = aws_sagemaker_endpoint_configuration.model_endpoint_configuration.name
125+
name = "${local.env}-sagemaker-${var.model_name}-endpoint"
126+
}
127+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
output "sagemaker_endpoint_name" {
3+
value = aws_sagemaker_endpoint.model_endpoint.name
4+
}

0 commit comments

Comments
 (0)