-
Notifications
You must be signed in to change notification settings - Fork 0
137 lines (118 loc) · 4.28 KB
/
Copy pathretrain.yml
File metadata and controls
137 lines (118 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
name: Retrain and Deploy
on:
push:
branches: [main]
workflow_dispatch:
schedule:
- cron: "0 2 * * 1"
concurrency:
group: retrain-${{ github.ref }}
cancel-in-progress: true
jobs:
should-retrain:
runs-on: ubuntu-latest
outputs:
retrain: ${{ steps.check.outputs.retrain }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect data changes
id: check
run: |
git fetch origin main
if [ "${{ github.event_name }}" = "schedule" ] || [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "retrain=true" >> $GITHUB_OUTPUT
else
if [ "${{ github.event_name }}" = "push" ]; then
CHANGED=$(git diff --name-only ${{ github.event.before }} HEAD | grep -E "^data/raw/(human|ai)/" || true)
else
CHANGED=$(git diff --name-only origin/main HEAD | grep -E "^data/raw/(human|ai)/" || true)
fi
if [ -n "$CHANGED" ]; then
echo "retrain=true" >> $GITHUB_OUTPUT
else
echo "retrain=false" >> $GITHUB_OUTPUT
fi
fi
train:
runs-on: ubuntu-latest
needs: should-retrain
if: needs.should-retrain.outputs.retrain == 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install dependencies
run: |
pip install -r requirements.txt
- name: Feature engineering
run: python -m src.features.build_features
- name: Train model
run: python -m src.models.train
- name: Evaluate model
run: python -m src.models.evaluate
- name: Upload model artifacts
uses: actions/upload-artifact@v4
with:
name: model-artifacts
path: |
data/processed/test_metrics.json
models/checkpoints/
models/onnx/
tokenizer/
models/registry/
mlruns/
retention-days: 30
deploy:
runs-on: ubuntu-latest
needs: train
if: github.ref == 'refs/heads/main'
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install dependencies
run: |
pip install -r requirements.txt
- name: Download model artifacts
uses: actions/download-artifact@v4
with:
name: model-artifacts
path: .
- name: Check F1 deployment gate
id: f1-gate
run: python -m src.models.deploy
- name: Deploy model
if: steps.f1-gate.outputs.should_deploy == 'true'
run: |
docker build -t human-ai-detect:latest -f docker/Dockerfile .
docker run -d --name human-ai-detect -p 8080:8080 \
-v ${{ github.workspace }}/models:/app/models \
-v ${{ github.workspace }}/tokenizer:/app/tokenizer \
human-ai-detect:latest
for i in $(seq 1 30); do
if curl -sf http://localhost:8080/health; then
echo "Health check passed"
break
fi
echo "Health check attempt $i failed, retrying..."
sleep 2
done
RESPONSE=$(curl -sf -X POST http://localhost:8080/predict \
-H "Content-Type: application/json" \
-d '{"code": "#include <stdio.h>\\nint main() { return 0; }"}')
echo "Human code prediction result: $RESPONSE"
echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); assert d['prediction'] == 'human', f\"Expected 'human' but got '{d['prediction']}'\"; assert d['human_probability'] > d['ai_probability'], 'Human probability should be higher for human code'; print('Smoke test passed: human code correctly classified as human')"
docker stop human-ai-detect
docker rm human-ai-detect
- name: Promote model to Production
if: steps.f1-gate.outputs.should_deploy == 'true'
run: python -m src.models.registry --promote-staging
- name: Skip deployment notification
if: steps.f1-gate.outputs.should_deploy != 'true'
run: |
echo "Deployment skipped: ${{ steps.f1-gate.outputs.deploy_reason }}"