←Back to Documentation
Model Registry
Centralized ML model versioning, deployment tracking, and lifecycle management
Overview
Model Registry provides:
- • Model Versioning: Track model iterations
- • Deployment Tracking: Monitor production models
- • A/B Testing: Compare model performance
- • Model Lineage: Track training data and features
- • Performance Monitoring: Real-time metrics
Register Models
-- Register a new model
INSERT INTO ml_models (
model_name,
model_type,
version,
framework,
algorithm,
hyperparameters,
training_dataset,
feature_groups,
created_by
) VALUES (
'fraud_detection',
'classification',
'1.0.0',
'scikit-learn',
'RandomForestClassifier',
'{"n_estimators": 100, "max_depth": 10, "random_state": 42}',
'transactions_2024_q1',
ARRAY['user_features', 'transaction_features'],
'data_scientist@example.com'
);
-- Store model artifacts
INSERT INTO model_artifacts (
model_id,
artifact_type,
artifact_path,
file_size_bytes,
checksum
) VALUES (
(SELECT id FROM ml_models WHERE model_name = 'fraud_detection' AND version = '1.0.0'),
'model_pickle',
's3://ml-models/fraud_detection/v1.0.0/model.pkl',
15728640,
'sha256:abc123...'
);
-- Register model metrics
INSERT INTO model_metrics (
model_id,
metric_name,
metric_value,
dataset_type
) VALUES
(1, 'accuracy', 0.9542, 'validation'),
(1, 'precision', 0.9123, 'validation'),
(1, 'recall', 0.8765, 'validation'),
(1, 'f1_score', 0.8938, 'validation'),
(1, 'auc_roc', 0.9678, 'validation');Model Versioning
-- Semantic versioning for models
-- Format: MAJOR.MINOR.PATCH
-- Create new version
INSERT INTO ml_models (
model_name,
version,
parent_version,
changes,
...
) VALUES (
'fraud_detection',
'1.1.0', -- Minor version: new features
'1.0.0',
'Added device fingerprinting features',
...
);
-- View version history
SELECT
version,
created_at,
created_by,
changes,
status
FROM ml_models
WHERE model_name = 'fraud_detection'
ORDER BY created_at DESC;
-- Compare model versions
SELECT
m1.version as version_1,
m2.version as version_2,
m1.hyperparameters as params_1,
m2.hyperparameters as params_2,
(
SELECT jsonb_object_agg(metric_name, metric_value)
FROM model_metrics
WHERE model_id = m1.id AND dataset_type = 'validation'
) as metrics_1,
(
SELECT jsonb_object_agg(metric_name, metric_value)
FROM model_metrics
WHERE model_id = m2.id AND dataset_type = 'validation'
) as metrics_2
FROM ml_models m1
CROSS JOIN ml_models m2
WHERE m1.model_name = 'fraud_detection'
AND m2.model_name = 'fraud_detection'
AND m1.version = '1.0.0'
AND m2.version = '1.1.0';
-- Tag versions
UPDATE ml_models
SET tags = tags || '{"stage": "production"}'
WHERE model_name = 'fraud_detection'
AND version = '1.1.0';
-- Promote to production
UPDATE ml_models
SET status = 'production',
production_deployed_at = NOW()
WHERE model_name = 'fraud_detection'
AND version = '1.1.0';Deployment Tracking
-- Track model deployments
INSERT INTO model_deployments (
model_id,
environment,
endpoint_url,
deployment_config,
deployed_by
) VALUES (
(SELECT id FROM ml_models WHERE model_name = 'fraud_detection' AND version = '1.1.0'),
'production',
'https://api.example.com/predict/fraud',
'{
"instance_type": "ml.m5.xlarge",
"min_instances": 2,
"max_instances": 10,
"traffic_percentage": 100
}',
'mlops@example.com'
);
-- View active deployments
SELECT
m.model_name,
m.version,
d.environment,
d.endpoint_url,
d.deployed_at,
d.deployment_config->>'traffic_percentage' as traffic_pct
FROM model_deployments d
JOIN ml_models m ON d.model_id = m.id
WHERE d.status = 'active'
ORDER BY d.deployed_at DESC;
-- Canary deployment (gradual rollout)
-- Deploy new version to 10% of traffic
INSERT INTO model_deployments (
model_id,
environment,
deployment_config
) VALUES (
(SELECT id FROM ml_models WHERE model_name = 'fraud_detection' AND version = '1.2.0'),
'production',
'{"traffic_percentage": 10, "canary": true}'
);
-- Update existing to 90%
UPDATE model_deployments
SET deployment_config = deployment_config || '{"traffic_percentage": 90}'
WHERE model_id = (SELECT id FROM ml_models WHERE model_name = 'fraud_detection' AND version = '1.1.0')
AND environment = 'production'
AND status = 'active';
-- Rollback deployment
UPDATE model_deployments
SET status = 'rolled_back',
rolled_back_at = NOW(),
rollback_reason = 'Elevated error rate detected'
WHERE model_id = (SELECT id FROM ml_models WHERE version = '1.2.0')
AND environment = 'production';A/B Testing
-- Create A/B test
INSERT INTO ab_tests (
test_name,
model_a_id,
model_b_id,
traffic_split,
start_date,
end_date,
success_metric
) VALUES (
'fraud_v1.1_vs_v1.2',
(SELECT id FROM ml_models WHERE version = '1.1.0'),
(SELECT id FROM ml_models WHERE version = '1.2.0'),
'{"A": 50, "B": 50}',
NOW(),
NOW() + INTERVAL '7 days',
'f1_score'
);
-- Log predictions for A/B test
INSERT INTO ab_test_predictions (
test_id,
variant,
user_id,
prediction,
actual,
latency_ms
) VALUES (
1, 'A', 12345, 0.85, 1, 45
);
-- Analyze A/B test results
SELECT
variant,
COUNT(*) as prediction_count,
AVG(CASE WHEN prediction > 0.5 AND actual = 1 THEN 1 ELSE 0 END) as true_positive_rate,
AVG(CASE WHEN prediction <= 0.5 AND actual = 0 THEN 1 ELSE 0 END) as true_negative_rate,
AVG(latency_ms) as avg_latency
FROM ab_test_predictions
WHERE test_id = 1
GROUP BY variant;
-- Statistical significance test
WITH test_stats AS (
SELECT
variant,
COUNT(*) as n,
AVG(CASE WHEN prediction > 0.5 AND actual = 1 THEN 1 ELSE 0 END) as success_rate
FROM ab_test_predictions
WHERE test_id = 1
GROUP BY variant
),
pooled AS (
SELECT
SUM(n * success_rate) / SUM(n) as p_pooled,
SUM(n) as n_total
FROM test_stats
)
SELECT
ts.variant,
ts.success_rate,
(ts.success_rate - p.p_pooled) /
SQRT(p.p_pooled * (1 - p.p_pooled) * (1.0/ts.n + 1.0/(p.n_total - ts.n)))
as z_score
FROM test_stats ts
CROSS JOIN pooled p;
-- End A/B test and promote winner
UPDATE ab_tests
SET status = 'completed',
winner_variant = 'B',
completed_at = NOW()
WHERE test_name = 'fraud_v1.1_vs_v1.2';Model Monitoring
-- Log predictions for monitoring
INSERT INTO model_predictions (
model_id,
prediction_id,
input_features,
prediction,
prediction_proba,
latency_ms,
timestamp
) VALUES (
1,
gen_random_uuid(),
'{"age": 35, "transaction_amount": 250.0, "hour_of_day": 14}',
0, -- Not fraud
0.15, -- 15% probability
42,
NOW()
);
-- Monitor prediction distribution
SELECT
DATE(timestamp) as date,
AVG(prediction) as avg_prediction,
STDDEV(prediction) as stddev_prediction,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY prediction_proba) as median_proba
FROM model_predictions
WHERE model_id = 1
AND timestamp > NOW() - INTERVAL '7 days'
GROUP BY DATE(timestamp)
ORDER BY date;
-- Detect prediction drift
WITH baseline AS (
SELECT
AVG(prediction_proba) as mean_proba,
STDDEV(prediction_proba) as stddev_proba
FROM model_predictions
WHERE model_id = 1
AND timestamp BETWEEN '2024-01-01' AND '2024-01-31'
),
current AS (
SELECT
AVG(prediction_proba) as mean_proba,
STDDEV(prediction_proba) as stddev_proba
FROM model_predictions
WHERE model_id = 1
AND timestamp > NOW() - INTERVAL '7 days'
)
SELECT
ABS(c.mean_proba - b.mean_proba) / b.stddev_proba as drift_z_score,
CASE
WHEN ABS(c.mean_proba - b.mean_proba) / b.stddev_proba > 3 THEN 'ALERT'
WHEN ABS(c.mean_proba - b.mean_proba) / b.stddev_proba > 2 THEN 'WARNING'
ELSE 'OK'
END as drift_status
FROM baseline b
CROSS JOIN current c;
-- Performance over time
SELECT
DATE(p.timestamp) as date,
COUNT(*) as prediction_count,
AVG(CASE WHEN p.prediction = a.actual THEN 1 ELSE 0 END) as accuracy,
AVG(p.latency_ms) as avg_latency
FROM model_predictions p
LEFT JOIN actuals a ON p.prediction_id = a.prediction_id
WHERE p.model_id = 1
AND p.timestamp > NOW() - INTERVAL '30 days'
GROUP BY DATE(p.timestamp)
ORDER BY date;Best Practices
Versioning
- • Use semantic versioning
- • Track all hyperparameters
- • Document model changes
- • Link to training data
Operations
- • Monitor prediction drift
- • Use canary deployments
- • A/B test new versions
- • Automate rollback on errors