Spaces:
Sleeping
Sleeping
Merge pull request #1 from YakobusIP/main
Browse files- .github/workflows/ci-production.yml +61 -0
- Dockerfile +17 -0
- hypothesis.py +2 -2
- main_model.py +1 -1
- models/albert_model.pth +3 -0
- models/random_forest.joblib +0 -0
- random_forest_model.py +2 -2
- requirements.txt +3 -1
- scalers/rf_scaler.joblib +0 -0
- scalers/scaler-normalized-text-length.joblib +0 -0
- scalers/scaler-not-normalized.joblib +0 -0
.github/workflows/ci-production.yml
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Deploy to Google Vertex AI
|
2 |
+
|
3 |
+
on:
|
4 |
+
push:
|
5 |
+
branches:
|
6 |
+
- production
|
7 |
+
|
8 |
+
jobs:
|
9 |
+
setup-build-publish-deploy:
|
10 |
+
name: Setup, Build, Publish, and Deploy
|
11 |
+
runs-on: ubuntu-latest
|
12 |
+
|
13 |
+
steps:
|
14 |
+
- name: Checkout code
|
15 |
+
uses: actions/checkout@v2
|
16 |
+
|
17 |
+
- name: Set up Cloud SDK
|
18 |
+
uses: google-github-actions/[email protected]
|
19 |
+
with:
|
20 |
+
project_id: ${{ secrets.GCP_PROJECT_ID }}
|
21 |
+
service_account_key: ${{ secrets.GCP_DEPLOYER_SA_KEY }}
|
22 |
+
export_default_credentials: true
|
23 |
+
|
24 |
+
- name: Authenticate Docker
|
25 |
+
run: |
|
26 |
+
gcloud auth configure-docker ${{ secrets.GCP_REPO_REGION }}-docker.pkg.dev --quiet
|
27 |
+
|
28 |
+
- name: Build image
|
29 |
+
working-directory: ./
|
30 |
+
run: docker build . --file Dockerfile --tag ${{ secrets.GCP_REPO_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/interview-ai-detector/model-prediction
|
31 |
+
|
32 |
+
- name: Push image
|
33 |
+
run: docker push ${{ secrets.GCP_REPO_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/interview-ai-detector/model-prediction
|
34 |
+
|
35 |
+
- name: Create model
|
36 |
+
id: create_model
|
37 |
+
run: |
|
38 |
+
MODEL_ID=$(gcloud ai models upload \
|
39 |
+
--region=${{ secrets.GCP_VERTEX_AI_REGION }} \
|
40 |
+
--display-name="interview-ai-detector-model" \
|
41 |
+
--container-image-uri="${{ secrets.GCP_REPO_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/interview-ai-detector/model-prediction:latest" \
|
42 |
+
--format="value(model)")
|
43 |
+
echo "MODEL_ID=${MODEL_ID}" >> $GITHUB_ENV
|
44 |
+
|
45 |
+
- name: Create Vertex AI endpoint
|
46 |
+
id: create_endpoint
|
47 |
+
run: |
|
48 |
+
ENDPOINT_ID=$(gcloud ai endpoints create \
|
49 |
+
--region=${{ secrets.GCP_VERTEX_AI_REGION }} \
|
50 |
+
--display-name="interview-ai-detector-endpoint" \
|
51 |
+
--format="value(name)")
|
52 |
+
echo "ENDPOINT_ID=${ENDPOINT_ID}" >> $GITHUB_ENV
|
53 |
+
|
54 |
+
- name: Deploy model to endpoint
|
55 |
+
run: |
|
56 |
+
gcloud ai endpoints deploy-model ${{ env.ENDPOINT_ID }} \
|
57 |
+
--region ${{ secrets.GCP_VERTEX_AI_REGION }} \
|
58 |
+
--model ${{ env.MODEL_ID }} \
|
59 |
+
--display-name interview-ai-detector-deployment \
|
60 |
+
--machine-type n1-standard-4 \
|
61 |
+
--accelerator count=1,type=nvidia-tesla-t4
|
Dockerfile
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Use an official Python runtime as a base image
|
2 |
+
FROM python:3.12-slim
|
3 |
+
|
4 |
+
# Set the working directory in the container
|
5 |
+
WORKDIR /app
|
6 |
+
|
7 |
+
# Copy the current directory contents into the container at /app
|
8 |
+
COPY . /app
|
9 |
+
|
10 |
+
# Install any needed packages specified in requirements.txt
|
11 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
12 |
+
|
13 |
+
# Make port 8080 available to the world outside this container
|
14 |
+
EXPOSE 8080
|
15 |
+
|
16 |
+
# Run gunicorn with Uvicorn workers
|
17 |
+
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "-w", "4", "-b", "0.0.0.0:8080", "prediction:app"]
|
hypothesis.py
CHANGED
@@ -23,9 +23,9 @@ class BaseModelHypothesis:
|
|
23 |
self.features_not_normalized = []
|
24 |
|
25 |
self.scaler_normalized_text_length = joblib.load(
|
26 |
-
"scaler-normalized-text-length.joblib")
|
27 |
self.scaler_not_normalized = joblib.load(
|
28 |
-
"scaler-not-normalized.joblib")
|
29 |
|
30 |
def process_emotion_lexicon(self):
|
31 |
emotion_lexicon = {}
|
|
|
23 |
self.features_not_normalized = []
|
24 |
|
25 |
self.scaler_normalized_text_length = joblib.load(
|
26 |
+
"scalers/scaler-normalized-text-length.joblib")
|
27 |
self.scaler_not_normalized = joblib.load(
|
28 |
+
"scalers/scaler-not-normalized.joblib")
|
29 |
|
30 |
def process_emotion_lexicon(self):
|
31 |
emotion_lexicon = {}
|
main_model.py
CHANGED
@@ -50,7 +50,7 @@ class PredictMainModel:
|
|
50 |
self.model = AlbertCustomClassificationHead(
|
51 |
self.albert_model).to(self.device)
|
52 |
# TODO : CHANGE MODEL STATE DICT PATH
|
53 |
-
self.model.load_state_dict(torch.load("
|
54 |
|
55 |
def preprocess_input(self, text: str, additional_features: np.ndarray):
|
56 |
encoding = self.tokenizer.encode_plus(
|
|
|
50 |
self.model = AlbertCustomClassificationHead(
|
51 |
self.albert_model).to(self.device)
|
52 |
# TODO : CHANGE MODEL STATE DICT PATH
|
53 |
+
self.model.load_state_dict(torch.load("models/albert_model.pth"))
|
54 |
|
55 |
def preprocess_input(self, text: str, additional_features: np.ndarray):
|
56 |
encoding = self.tokenizer.encode_plus(
|
models/albert_model.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:6b203b54caba10e290830cf720c8cd35093a358792e996ee04ee7d8e5e341651
|
3 |
+
size 70752187
|
models/random_forest.joblib
ADDED
Binary file (228 kB). View file
|
|
random_forest_model.py
CHANGED
@@ -5,8 +5,8 @@ from typing import List
|
|
5 |
|
6 |
class RandomForestModel:
|
7 |
def __init__(self):
|
8 |
-
self.scaler = joblib.load("rf_scaler.joblib")
|
9 |
-
self.model = joblib.load("random_forest.joblib")
|
10 |
|
11 |
def preprocess_input(self, secondary_model_features: List[float]) -> np.ndarray:
|
12 |
return self.scaler.transform(np.array(secondary_model_features).astype(np.float32).reshape(1, -1))
|
|
|
5 |
|
6 |
class RandomForestModel:
|
7 |
def __init__(self):
|
8 |
+
self.scaler = joblib.load("scalers/rf_scaler.joblib")
|
9 |
+
self.model = joblib.load("models/random_forest.joblib")
|
10 |
|
11 |
def preprocess_input(self, secondary_model_features: List[float]) -> np.ndarray:
|
12 |
return self.scaler.transform(np.array(secondary_model_features).astype(np.float32).reshape(1, -1))
|
requirements.txt
CHANGED
@@ -5,4 +5,6 @@ pandas
|
|
5 |
textstat
|
6 |
scikit-learn==1.4.1.post1
|
7 |
transformers
|
8 |
-
fastapi
|
|
|
|
|
|
5 |
textstat
|
6 |
scikit-learn==1.4.1.post1
|
7 |
transformers
|
8 |
+
fastapi
|
9 |
+
uvicorn
|
10 |
+
gunicorn
|
scalers/rf_scaler.joblib
ADDED
Binary file (1.17 kB). View file
|
|
scalers/scaler-normalized-text-length.joblib
ADDED
Binary file (1.85 kB). View file
|
|
scalers/scaler-not-normalized.joblib
ADDED
Binary file (1.17 kB). View file
|
|