Skip to content

Commit

Permalink
added a simple workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Santhosha Rajashekar committed Jun 10, 2024
1 parent 7bb3e01 commit 848c1fd
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 0 deletions.
57 changes: 57 additions & 0 deletions .github/workflows/mlops-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: ML Ops Workflow

on: [push]

env:
workspace-name: aml-ws-mlops
resource-group: rg-mlops

jobs:
build-and-deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.8'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r ./ml/requirements.txt
- name: Configure Azure credentials
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Set up Azure Machine Learning
run: |
az extension add -n azure-cli-ml
az ml workspace configure -w your-workspace-name -g your-resource-group --subscription your-subscription-id
- name: Upload dataset
run: |
az ml data create -f data.yaml
- name: Submit training run
run: |
az ml job create --file train.yaml
# - name: Register the model
# run: |
# az ml job create --file register_model.yaml

# - name: Deploy the model
# run: |
# az ml job create --file deploy_model.yaml

# - name: Test the deployment
# run: |
# python test_deployment.py
5 changes: 5 additions & 0 deletions ml/data.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$schema: http://azuremlsdk2.blob.core.windows.net/latest/data.schema.json
name: attrition_data
version: 1
type: uri_file
path: ./employee_attrition.csv
30 changes: 30 additions & 0 deletions ml/deploy_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from azureml.core import Workspace, Model, Environment
from azureml.core.webservice import AciWebservice, Webservice
from azureml.core.model import InferenceConfig

# Initialize workspace
ws = Workspace.from_config()

# Get the registered model
model = Model(ws, "employee_attrition_model")

# Create environment
env = Environment.from_conda_specification(
name="project_environment", file_path="environment.yml"
)

# Create inference configuration
inference_config = InferenceConfig(entry_script="score.py", environment=env)

# Define the deployment configuration
aci_config = AciWebservice.deploy_configuration(cpu_cores=1, memory_gb=1)

# Deploy the model
service = Model.deploy(
workspace=ws,
name="attrition-service",
models=[model],
inference_config=inference_config,
deployment_config=aci_config,
)
service.wait_for_deployment(show_output=True)
13 changes: 13 additions & 0 deletions ml/deploy_model.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: >
python deploy_model.py
environment: azureml:project_environment:1
inputs:
attrition_data:
data: azureml:attrition_data:1
compute: azureml:cpu-cluster
experiment_name: deploy_model_experiment
output:
name: outputs
type: uri_folder
mode: Upload
6 changes: 6 additions & 0 deletions ml/employee_attrition.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
EmployeeNumber,Age,Department,DistanceFromHome,Education,Gender,JobRole,MaritalStatus,MonthlyIncome,NumCompaniesWorked,PercentSalaryHike,TotalWorkingYears,TrainingTimesLastYear,YearsAtCompany,YearsInCurrentRole,YearsSinceLastPromotion,YearsWithCurrManager,Attrition
1,41,Sales,1,2,Male,Sales Executive,Single,5993,8,11,8,0,6,4,0,5,Yes
2,49,Research & Development,8,1,Female,Research Scientist,Married,5130,1,23,10,3,10,7,1,7,No
3,37,Research & Development,2,2,Male,Laboratory Technician,Single,2090,6,15,7,3,0,0,0,8,Yes
4,33,Research & Development,3,4,Female,Research Scientist,Married,2909,1,11,8,3,8,7,3,0,8,No
5,27,Research & Development,2,1,Male,Laboratory Technician,Married,3468,9,12,6,3,2,2,2,2,Yes
10 changes: 10 additions & 0 deletions ml/environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: project_environment
dependencies:
- python=3.8
- scikit-learn
- pandas
- numpy
- pip
- pip:
- azureml-sdk
- joblib
11 changes: 11 additions & 0 deletions ml/register_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import joblib
from azureml.core import Run, Model

run = Run.get_context()

# Register the model
model = Model.register(
workspace=run.experiment.workspace,
model_path="outputs/model.joblib",
model_name="employee_attrition_model",
)
13 changes: 13 additions & 0 deletions ml/register_model.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: >
python register_model.py
environment: azureml:project_environment:1
inputs:
attrition_data:
data: azureml:attrition_data:1
compute: azureml:cpu-cluster
experiment_name: register_model_experiment
output:
name: outputs
type: uri_folder
mode: Upload
20 changes: 20 additions & 0 deletions ml/score.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import json
import joblib
import numpy as np
from azureml.core.model import Model


def init():
global model
model_path = Model.get_model_path("employee_attrition_model")
model = joblib.load(model_path)


def run(data):
try:
data = np.array(json.loads(data)["data"])
result = model.predict(data)
return json.dumps({"prediction": result.tolist()})
except Exception as e:
error = str(e)
return json.dumps({"error": error})
16 changes: 16 additions & 0 deletions ml/test_deployment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import requests
import json

# Replace with your service URI
scoring_uri = "YOUR_SERVICE_URI"

# Example data for prediction
data = {"data": [[41, 1, 2, 1, "Male", "Sales Executive", "Single", 5993, 8, 11, 8, 0, 6, 4, 0, 5]]}
input_data = json.dumps(data)

# Set the content type
headers = {'Content-Type': 'application/json'}

# Make the request
response = requests.post(scoring_uri, data=input_data, headers=headers)
print(response.json())
44 changes: 44 additions & 0 deletions ml/train.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import os
import pandas as pd
from azureml.core import Run, Dataset
from azureml.core.model import Model
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import joblib

# Get the current run context
run = Run.get_context()

# Load the dataset
dataset = run.input_datasets["attrition_data"].to_pandas_dataframe()

# Data preprocessing
X = dataset.drop(columns=["Attrition"])
y = dataset["Attrition"].apply(lambda x: 1 if x == "Yes" else 0)

X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)

# Train model
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# Evaluate model
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
run.log("accuracy", accuracy)

# Save the model
os.makedirs("outputs", exist_ok=True)
joblib.dump(model, "outputs/model.joblib")

# Register the model
model = Model.register(
workspace=run.experiment.workspace,
model_path="outputs/model.joblib",
model_name="employee_attrition_model",
)

run.complete()
13 changes: 13 additions & 0 deletions ml/train.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
command: >
python train.py
environment: azureml:project_environment:1
inputs:
attrition_data:
data: azureml:attrition_data:1
compute: azureml:cpu-cluster
experiment_name: employee_attrition_experiment
output:
name: outputs
type: uri_folder
mode: Upload

0 comments on commit 848c1fd

Please sign in to comment.