Skip to content
Notifications
Clear all

Just built a CI/CD gate that fails if Arize drift score is too high

5 Posts
5 Users
0 Reactions
1 Views
(@carlr)
Estimable Member
Joined: 1 week ago
Posts: 92
Topic starter   [#18931]

We've been running Arize in production for about a year, primarily for monitoring drift and data quality on our core ML models. The dashboards are fine, but alerts are... passive. By the time you get a PagerDuty alert, the model is already serving potentially degraded inferences.

I decided to move the check left, into the CI/CD pipeline for model deployment. The goal: if the candidate model's performance or drift metrics against a reference dataset exceed a threshold, the pipeline fails. No new model version is deployed.

The implementation is straightforward. We run a batch inference job in the CI system (Jenkins, but it's generic), then use the Arize Python SDK to push the results and calculate metrics. The key is the `arize.pandas.logger` for batch logging and the `Client.get_model_metrics` call.

Here's the core of the script that runs in the pipeline:

```python
import os
from arize.pandas.logger import Client
from arize.utils.types import Environments, ModelTypes
import pandas as pd

SPACE_KEY = os.getenv('ARIZE_SPACE_KEY')
API_KEY = os.getenv('ARIZE_API_KEY')
MODEL_ID = 'customer-churn-v3'
MODEL_VERSION = os.getenv('CANDIDATE_VERSION') # From CI env

arize_client = Client(space_key=SPACE_KEY, api_key=API_KEY)

# df_candidate: inferences from the new model version
# df_reference: golden dataset or prior model's inferences
features = [...] # your feature columns

# Log candidate predictions
response = arize_client.log(
dataframe=df_candidate,
model_id=MODEL_ID,
model_version=MODEL_VERSION,
model_type=ModelTypes.SCORE_CATEGORICAL,
environment=Environments.PRODUCTION,
batch_id="ci_batch"
)

# Calculate drift metrics for a specific feature and the prediction score
metrics = arize_client.get_model_metrics(
model_id=MODEL_ID,
metric_type=["drift"],
start_time="2024-01-01",
end_time="2024-05-01",
dimension_filters=[{"name": "feature_name", "value": "transaction_amount"}]
)

# Example: fail if PSI for a key feature > 0.1
psi_value = metrics['data']['drift']['psi']
if psi_value > 0.1:
print(f"Drift threshold exceeded: PSI={psi_value}")
sys.exit(1)
```

The main pitfalls:
* You need a robust, representative reference dataset accessible in your CI environment.
* Metric calculation in Arize isn't instantaneous; you need to add a `time.sleep(60)` or implement a poll for the `calculation_id` if using the more advanced async calls.
* This adds ~2-3 minutes to pipeline runtime, mostly for the batch logging and metric computation.

It's not a silver bullet—you still need production monitoring—but it catches egregious regressions before they hit. So far, it's blocked two deployments where feature drift spiked due to upstream data pipeline changes we hadn't fully accounted for.

- cr


Your fancy demo doesn't scale.


   
Quote
(@data_pipeline_guy)
Estimable Member
Joined: 4 months ago
Posts: 107
 

So you've just moved the passive alert from post-inference to pre-deployment. That's still a reaction. If your drift scores are volatile enough to block a deploy, your real problem is upstream in your feature pipeline. What changed in the data that built the candidate model?

Also, now you've made your CI/CD dependent on a third-party API. Good luck when Arize has an outage and your whole deploy process is dead in the water because you can't get a drift score. Hope you built a circuit breaker.


SQL is enough


   
ReplyQuote
(@data_analytics_rover)
Reputable Member
Joined: 4 months ago
Posts: 150
 

The circuit breaker point is valid. We implemented a similar gate using a timeout and fallback to a stored baseline. If the Arize API call fails or exceeds 10 seconds, the pipeline uses the last known drift score from our metrics store and logs a warning. It prevents a third-party outage from halting deploys entirely.

Have you measured the latency overhead this adds to your pipeline? We saw a 30-45 second increase from the batch inference and metric calculation, which pushed our decision to run it on a subset of reference data.



   
ReplyQuote
(@cloud_ops_learner_3)
Reputable Member
Joined: 2 months ago
Posts: 147
 

That timeout and fallback makes sense. I'm planning something similar with our Datadog checks. How do you handle versioning on the stored baseline? If you fall back to a stored score, are you confident it's still the right threshold for the current model version? Seems like you'd need to tag it.



   
ReplyQuote
(@fred99)
Eminent Member
Joined: 6 days ago
Posts: 14
 

Yeah, tagging the stored baseline with the model version hash makes sense. We just use the git commit SHA from the candidate model's build.

But you're right, it's still a snapshot. If the fallback triggers, you're essentially deploying based on a score that might be stale for the current state of your reference data. Doesn't that just shift the risk?



   
ReplyQuote