CI/CD Pipeline for Auto-Deploying AI Models with GitHub Actions
How I built a CI/CD pipeline using GitHub Actions to automatically fine-tune, test, and deploy AI models to production when code is pushed.
The Problem
Every time I updated training data or tweaked model parameters, I had to manually:
- SSH into the GPU server
- Run the fine-tuning script
- Wait for training to complete
- Convert the model to Ollama format
- Deploy to production
- Test the endpoints
This was slow, error-prone, and didn't scale. I needed automation.
The Solution: GitHub Actions CI/CD
I built a complete CI/CD pipeline using GitHub Actions that automatically handles the entire AI model lifecycle when code is pushed to the main branch.
Pipeline Architecture
name: AI Model CI/CD Pipeline
on:
push:
branches: [main]
paths:
- 'training/**'
- 'models/**'
- 'config/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate training config
run: python scripts/validate_config.py
- name: Lint training data
run: python scripts/lint_dataset.py
train:
needs: validate
runs-on: self-hosted # GPU runner
steps:
- uses: actions/checkout@v4
- name: Fine-tune model
run: python train.py --config config/model.yaml
- name: Export model weights
run: python scripts/export_gguf.py
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: model-weights
path: output/*.gguf
test:
needs: train
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download model
uses: actions/download-artifact@v4
- name: Run evaluation suite
run: python evaluate.py --model output/model.gguf
- name: Check quality threshold
run: python scripts/check_metrics.py --min-score 0.85
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- name: Deploy to Ollama server
run: |
ollama create mymodel -f Modelfile
curl -X POST $PROD_API/reload
- name: Health check
run: python scripts/health_check.py
- name: Notify on success
run: echo "Model deployed successfully"Key Design Decisions
1. Self-Hosted GPU Runners
GitHub's standard runners don't have GPUs. I set up a self-hosted runner on a machine with an NVIDIA GPU for the training job. The runner connects to GitHub Actions and picks up training jobs automatically.
2. Artifact Passing Between Jobs
The trained model weights (.gguf files) are passed between the train and test jobs using GitHub Actions artifacts. This keeps the pipeline modular — each job runs on the best hardware for its task.
3. Quality Gates
The test job runs an evaluation suite against the fine-tuned model. If the model's quality score drops below 0.85 (configurable), the pipeline fails and the model is not deployed. This prevents regressions from reaching production.
4. Path-Based Triggers
The pipeline only runs when files in training/, models/, or config/ directories change. Frontend changes don't trigger expensive GPU training jobs.
Results
- Deployment time: 2 hours manual → 25 minutes automated
- Error rate: Eliminated manual deployment mistakes
- Iteration speed: 4x faster model experimentation
- Cost: Only uses GPU when actually training (self-hosted runner sleeps otherwise)
What I Learned
- GitHub Actions self-hosted runners are perfect for GPU workloads — you get the CI/CD integration without paying for cloud GPU runners
- Quality gates in CI/CD are essential for AI — a model that passes unit tests can still produce bad outputs
- Artifact caching saves significant time when model weights are large
- Path filters on triggers prevent unnecessary GPU costs
Tech Stack Used
- GitHub Actions — CI/CD orchestration
- Python — Training and evaluation scripts
- Ollama — Model serving and deployment
- Docker — Containerized training environment
- GGUF format — Efficient model weight storage
This pipeline now powers all my AI model deployments at Glixen Tech. Every push triggers validation, training, testing, and deployment — fully automated.