Skip to content

Commit

Permalink
initia
Browse files Browse the repository at this point in the history
  • Loading branch information
astorfi committed Nov 23, 2024
1 parent 8b6220b commit c2ff686
Show file tree
Hide file tree
Showing 30 changed files with 1,163 additions and 47 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: CI/CD Pipeline

on:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
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 requirements.txt
- name: Lint Code
run: pylint app/**/*.py

- name: Run Unit Tests
run: pytest tests/

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Build and Push Docker Image
uses: docker/build-push-action@v2
with:
context: .
tags: user/repository:latest
push: true

deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy to Kubernetes
uses: azure/k8s-deploy@v1
with:
manifests: |
deployment/kubernetes/deployment.yml
deployment/kubernetes/service.yml
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,45 @@ For hyperparameter tuning, **Optuna** has been integrated to provide automated e
- **🔍 Explainability**: SHAP and LIME explainability metrics are added to the evaluation process, providing insights into model behavior.
- **📜 Logging**: Centralized logging using **ELK Stack** (Elasticsearch, Logstash, Kibana).

## 🚀 Cloud Deployment Instructions (AWS)

To deploy the LLM Alignment Assistant on **AWS**, you can utilize **Elastic Kubernetes Service (EKS)** or **AWS Sagemaker** for model training:

1. **AWS Elastic Kubernetes Service (EKS)**:
- Create an EKS cluster using AWS CLI or the console.
- Apply the Kubernetes deployment files:
```bash
kubectl apply -f deployment/kubernetes/deployment.yml
kubectl apply -f deployment/kubernetes/service.yml
```
- Configure the **Horizontal Pod Autoscaler (HPA)** to ensure scalability:
```bash
kubectl apply -f deployment/kubernetes/hpa.yml
```

2. **AWS Sagemaker for Model Training**:
- Modify the `training/fine_tuning.py` to integrate with AWS Sagemaker.
- Use the Sagemaker Python SDK to launch a training job:
```python
import sagemaker
from sagemaker.pytorch import PyTorch
role = "arn:aws:iam::your-account-id:role/service-role/AmazonSageMaker-ExecutionRole-2023"
pytorch_estimator = PyTorch(
entry_point='training/fine_tuning.py',
role=role,
instance_count=1,
instance_type='ml.p2.xlarge',
framework_version='1.8.0',
py_version='py3'
)
pytorch_estimator.fit({'training': 's3://your-bucket-name/training-data'})
```
- Ensure IAM roles and permissions are properly set for accessing **S3** and **Sagemaker**.


## 🚀 Future Work

- **🌍 Multi-Language Support**: Expand the LLM's training to support multiple languages.
Expand Down
67 changes: 67 additions & 0 deletions app/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# User Authentication using Flask-Login

from flask import Flask, render_template, redirect, url_for, request, flash
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
app.secret_key = 'secret-key'

# User session management setup
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"

# Mock database for users
users = {}

class User(UserMixin):
def __init__(self, id, username, password):
self.id = id
self.username = username
self.password_hash = generate_password_hash(password)

@login_manager.user_loader
def load_user(user_id):
return users.get(user_id)

@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
user_id = len(users) + 1
if username in [user.username for user in users.values()]:
flash("Username already exists. Please choose a different one.")
else:
users[user_id] = User(user_id, username, password)
flash("User registered successfully!")
return redirect(url_for('login'))
return render_template('register.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
user = next((u for u in users.values() if u.username == username), None)
if user and check_password_hash(user.password_hash, password):
login_user(user)
return redirect(url_for('dashboard'))
else:
flash("Invalid username or password.")
return render_template('login.html')

@app.route('/dashboard')
@login_required
def dashboard():
return render_template('dashboard.html')

@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('login'))

if __name__ == '__main__':
app.run(debug=True)
30 changes: 30 additions & 0 deletions app/feedback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Flask route for handling feedback submission

from flask import Flask, request, jsonify, render_template
import csv

app = Flask(__name__)

# Route to render feedback form
@app.route('/feedback', methods=['GET'])
def feedback():
# You can dynamically pass the response to be rated in 'response' variable
response = "Example response from LLM to be rated"
return render_template('feedback.html', response=response)

# Route to handle feedback submission
@app.route('/submit-feedback', methods=['POST'])
def submit_feedback():
rating = request.form['rating']
comments = request.form['comments']
model_response = request.form['model-response']

# Save feedback to a CSV file
with open('feedback.csv', mode='a') as feedback_file:
feedback_writer = csv.writer(feedback_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
feedback_writer.writerow([model_response, rating, comments])

return jsonify(status='success', message='Thank you for your feedback!')

if __name__ == "__main__":
app.run(debug=True)
47 changes: 46 additions & 1 deletion app/static/app.js
Original file line number Diff line number Diff line change
@@ -1 +1,46 @@
console.log('App JS');
// UI Enhancements - Adding Animations, Dark Mode Toggle, and Tooltips

document.addEventListener('DOMContentLoaded', function() {
// Dark Mode Toggle
const darkModeToggle = document.getElementById('dark-mode-toggle');
const body = document.body;

darkModeToggle.addEventListener('click', () => {
body.classList.toggle('dark-mode');
if (body.classList.contains('dark-mode')) {
localStorage.setItem('theme', 'dark');
} else {
localStorage.setItem('theme', 'light');
}
});

// Persist Dark Mode Setting
if (localStorage.getItem('theme') === 'dark') {
body.classList.add('dark-mode');
}

// Tooltip Initialization
const tooltips = document.querySelectorAll('.tooltip');
tooltips.forEach(tooltip => {
tooltip.addEventListener('mouseover', function() {
const tooltipText = document.createElement('span');
tooltipText.className = 'tooltip-text';
tooltipText.innerText = this.getAttribute('data-tooltip');
this.appendChild(tooltipText);
});
tooltip.addEventListener('mouseout', function() {
const tooltipText = this.querySelector('.tooltip-text');
if (tooltipText) this.removeChild(tooltipText);
});
});

// GSAP Animations for Elements
gsap.from('.card', {
duration: 1,
y: 50,
opacity: 0,
stagger: 0.2,
ease: 'power2.out'
});
});

60 changes: 60 additions & 0 deletions app/static/chart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Interactive Chart.js Visualizations

document.addEventListener('DOMContentLoaded', function() {
const ctx = document.getElementById('modelPerformanceChart').getContext('2d');
const modelPerformanceChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Epoch 1', 'Epoch 2', 'Epoch 3', 'Epoch 4', 'Epoch 5'],
datasets: [{
label: 'Training Loss',
data: [0.8, 0.6, 0.4, 0.3, 0.2],
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
fill: true,
tension: 0.4
}, {
label: 'Validation Loss',
data: [0.9, 0.7, 0.5, 0.4, 0.3],
borderColor: 'rgba(255, 99, 132, 1)',
backgroundColor: 'rgba(255, 99, 132, 0.2)',
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
tooltip: {
mode: 'index',
intersect: false,
}
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
},
scales: {
x: {
display: true,
title: {
display: true,
text: 'Epoch'
}
},
y: {
display: true,
title: {
display: true,
text: 'Loss'
}
}
}
}
});
});

53 changes: 52 additions & 1 deletion app/static/styles.css
Original file line number Diff line number Diff line change
@@ -1 +1,52 @@
body { font-family: Arial; }
/* Dark Mode Styles */
body.dark-mode {
background-color: #121212;
color: #ffffff;
}

button#dark-mode-toggle {
background-color: #333;
color: #fff;
border: none;
padding: 10px;
cursor: pointer;
border-radius: 5px;
}

button#dark-mode-toggle:hover {
background-color: #555;
}

/* Tooltip Styles */
.tooltip {
position: relative;
cursor: pointer;
}

.tooltip .tooltip-text {
position: absolute;
bottom: 125%;
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: #fff;
padding: 5px;
border-radius: 4px;
white-space: nowrap;
opacity: 0;
transition: opacity 0.3s;
}

.tooltip:hover .tooltip-text {
opacity: 1;
}

/* GSAP Animation Styles */
.card {
background: #f8f8f8;
padding: 20px;
margin: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

Loading

0 comments on commit c2ff686

Please sign in to comment.