AI模型监控:这次怎么落地的
他们去年上线的推荐模型,看起来一切正常:预测延迟在100ms以内,接口错误率接近0,监控面板绿油油的。这次写这篇,想梳理一下这几年在生产环境监控AI模型时踩过的坑和积累的经验。
模型监控到底要监控什么
说到底,模型监控的核心问题只有一个:模型现在的表现,和上线那天相比,还符不符合预期?
这个"预期"可以拆成几个维度:
- 数据层面:输入数据的分布、特征值范围、缺失率、异常值比例
- 预测层面:预测结果的分布、类别比例、置信度分布
- 性能层面:准确率、召回率、F1、AUC这些指标的业务表现
- 系统层面:预测延迟、吞吐量、资源使用率
模型卡在训练环境和生产基础设施之间:既要业务指标,也得盯延迟、吞吐和资源占用。
实践中最容易犯的错误是只看基础设施监控。Kafka不丢消息、Redis不超时、接口返回200ms,就觉得没问题。但模型可能已经在偷偷地从一个方向漂向另一个方向了。
先给一张整体图,把几个监控维度之间的关系理清楚:
这张图想说明的是:监控不是单向的,数据漂移会影响到预测结果和模型性能,系统层面的问题也可能触发告警。但更重要的是,漂移检测和性能监控是两个独立但相关的信号——数据变了不代表模型一定变差,模型变差也不一定是因为数据变了。
数据漂移:从"看起来正常"到"真的出问题"
数据漂移是模型监控里最经典的问题,也是最容易过度反应的地方。
分类漂移
最简单的情况是分类漂移——输入数据的类别分布变了。
比如一个垃圾邮件分类模型,训练时样本里垃圾邮件占30%,正常邮件占70%。上线半年后发现,垃圾邮件的占比降到了10%。
乍一看是个好事——垃圾变少了。但问题在于,模型在训练时学到的决策边界是针对30%垃圾比例的。现在输入数据的类别分布变了,模型的预测概率分布也会跟着变,即使模型本身没有"退化"。
用一个简单的例子说明:
import numpy as np
from scipy.stats import ks_2samp
# 模拟训练数据和线上数据的特征分布
train_data = np.random.normal(0, 1, 10000) # 训练数据
online_data = np.random.normal(0.2, 1, 10000) # 线上数据,均值轻微偏移
# 使用KS检验检测分布差异
statistic, p_value = ks_2samp(train_data, online_data)
print(f"KS统计量: {statistic:.4f}")
print(f"P值: {p_value:.6f}")
if p_value < 0.05:
print("警告:检测到显著的分布漂移")
else:
print("分布没有显著漂移")
这个例子用的是KS检验,实践中常用的还有Population Stability Index (PSI)、Jensen-Shannon散度等。但选择哪个指标不那么重要,关键在于阈值怎么设。
早年我犯过一个典型的错误:把p值阈值设成0.05。结果每天都能收到漂移告警——因为只要样本量够大,任何微小的分布差异都能被检测出来。但业务上那些差异根本不造成影响。
后来改成了PSI阈值:PSI < 0.1算稳定,0.1-0.25算轻微漂移,>0.25算严重漂移。这是个经验值,不一定适用于所有场景,但至少比死守0.05要实用。
特征漂移
比分类漂移更隐蔽的是特征漂移——单个特征的分布变了。
比如一个用户年龄特征,训练时大部分用户在20-40岁之间,上线后慢慢变成40-60岁。年龄这个特征值的范围没变,但分布中心漂移了。
如果模型对年龄敏感,这就可能是个问题。但反过来想,年龄分布变了本身也许不构成问题——如果用户的年龄结构真的在自然变化,那模型跟着变是合理的,反而是强行保持"训练时分布"有问题。
实践中更有效的方式是分层监控:先看整体分布变化,再看关键特征的变化,最后结合预测结果判断是否真的需要干预。
def monitor_feature_drift(train_features, online_features, threshold=0.1):
"""
监控特征漂移,返回漂移程度和建议
Args:
train_features: 训练数据的特征字典 {feature_name: array}
online_features: 线上数据的特征字典
threshold: PSI阈值,超过则告警
Returns:
drift_report: 包含每个特征的漂移状态和建议
"""
from scipy.stats import entropy
drift_report = {}
for feature in train_features.keys():
train_vals = train_features[feature]
online_vals = online_features[feature]
# 计算分布(这里简化为直方图)
train_hist, _ = np.histogram(train_vals, bins=20, density=True)
online_hist, _ = np.histogram(online_vals, bins=20, density=True)
# 计算PSI
psi = np.sum((online_hist - train_hist) * np.log(online_hist / (train_hist + 1e-10) + 1e-10))
# 判断漂移等级
if psi < threshold:
level = "stable"
suggestion = "正常,无需干预"
elif psi < threshold * 2.5:
level = "warning"
suggestion = "轻微漂移,建议关注"
else:
level = "critical"
suggestion = "严重漂移,考虑重新训练"
drift_report[feature] = {
"psi": psi,
"level": level,
"suggestion": suggestion
}
return drift_report
直方图 bin 数、阈值都得按场景调;代码只是示例,思路是先量化漂移,再给业务建议,别一上来就告警。
概念漂移
概念漂移是最坑爹的——输入数据看起来没变,但"正确答案"的映射关系变了。
举个真实的例子:一个电商平台的用户流失预测模型。训练数据里,“最近30天登录次数"是一个强特征——登录次数少意味着流失风险高。
但平台后来做了一个产品改动:把登录入口移到了更显眼的位置,还加了每日签到奖励。结果用户登录次数普遍上升了,但流失率并没有下降。模型开始误判那些"登录频繁但行为单一"的用户为低风险,实际上他们只是机械地点了签到按钮,并没有真的活跃。
这种情况下,特征分布看起来是"稳定的”,但特征与目标的映射关系已经变了。
检测概念漂移的有效方法之一是监控预测置信度的分布变化:
def monitor_confidence_drift(predictions_history, window=100):
"""
监控预测置信度的漂移
Args:
predictions_history: 历史预测置信度列表
window: 滑动窗口大小
Returns:
drift_signal: 漂移信号强度 (0-1)
"""
if len(predictions_history) < window * 2:
return 0 # 数据不足,无法判断
# 计算最近窗口和历史窗口的统计差异
recent = predictions_history[-window:]
historical = predictions_history[-(window*2):-window]
# 计算均值差异
mean_diff = abs(np.mean(recent) - np.mean(historical))
# 计算方差差异
var_diff = abs(np.var(recent) - np.var(historical))
# 归一化漂移信号
drift_signal = min(1.0, (mean_diff + var_diff) / 2.0)
return drift_signal
这个方法不能解决概念漂移本身,但至少能在模型开始"自欺欺人"时发个信号。
模型性能监控:准确率只是开始
准确率、召回率这些指标在训练集上跑得再漂亮,在线上也可能一塌糊涂。
离线评估 vs 在线效果
训练时用的评估指标和线上的真实效果往往不是一回事。
一个典型的例子:推荐系统。训练时用AUC评估,模型AUC能达到0.85。上线后发现点击率很低,换了个AUC只有0.82的模型,点击率反而上去了。
原因在于训练时的评估数据是"截断"的——用户看到的只有模型推荐的东西,没看到的被当成负样本。但线上真实场景里,用户没点击可能是因为没看到,也可能是因为真的不感兴趣。这两种情况的负样本含义完全不同。
解决方案:别指望换一个指标就搞定,离线指标和业务指标分开盯,两层监控一起上。
class ModelPerformanceMonitor:
def __init__(self, metrics_window=1000):
self.metrics_window = metrics_window
self.predictions = []
self.labels = []
self.business_metrics = []
def record_prediction(self, prediction, label, business_value):
"""
记录单次预测
Args:
prediction: 模型预测值
label: 真实标签(如果有)
business_value: 业务指标(点击/转化/订单金额等)
"""
self.predictions.append(prediction)
if label is not None:
self.labels.append(label)
self.business_metrics.append(business_value)
# 保持窗口大小
if len(self.predictions) > self.metrics_window:
self.predictions.pop(0)
if self.labels:
self.labels.pop(0)
self.business_metrics.pop(0)
def evaluate(self):
"""
评估当前窗口的模型性能
"""
results = {}
# 离线指标(如果有标签)
if self.labels:
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
binary_preds = [1 if p > 0.5 else 0 for p in self.predictions]
results['accuracy'] = accuracy_score(self.labels, binary_preds)
results['precision'] = precision_score(self.labels, binary_preds, zero_division=0)
results['recall'] = recall_score(self.labels, binary_preds, zero_division=0)
results['f1'] = f1_score(self.labels, binary_preds, zero_division=0)
# 在线业务指标
if self.business_metrics:
results['business_conversion'] = np.mean(self.business_metrics)
results['business_std'] = np.std(self.business_metrics)
# 预测置信度分布
results['prediction_mean'] = np.mean(self.predictions)
results['prediction_std'] = np.std(self.predictions)
return results
这个监控器同时跟踪离线指标和在线业务指标,你可以清楚地看到:离线指标很好但业务指标很差,或者反过来。
滑动窗口 vs 全量数据
另一个常见问题是监控窗口怎么设。
太短的窗口(比如最近1小时)对突发情况敏感,但容易被随机波动误触发。太长的窗口(比如最近30天)反应迟钝,等告警时模型已经烂了很久。
我的做法是分层窗口:
- 实时窗口:最近1小时,用于检测突发问题
- 短期窗口:最近1天,用于评估短期趋势
- 长期窗口:最近7天,用于判断基线偏移
class MultiWindowMonitor:
def __init__(self):
self.realtime_data = [] # 1小时窗口
self.short_term_data = [] # 1天窗口
self.long_term_data = [] # 7天窗口
def add_data_point(self, value, timestamp):
"""
添加数据点,自动分配到不同窗口
"""
now = datetime.now()
self.long_term_data.append((value, timestamp))
if timestamp > now - timedelta(days=1):
self.short_term_data.append((value, timestamp))
if timestamp > now - timedelta(hours=1):
self.realtime_data.append((value, timestamp))
# 清理过期数据
self.realtime_data = [(v, t) for v, t in self.realtime_data if t > now - timedelta(hours=1)]
self.short_term_data = [(v, t) for v, t in self.short_term_data if t > now - timedelta(days=1)]
self.long_term_data = [(v, t) for v, t in self.long_term_data if t > now - timedelta(days=7)]
def evaluate(self):
"""
评估不同窗口的性能
"""
results = {}
for name, data in [('realtime', self.realtime_data),
('short_term', self.short_term_data),
('long_term', self.long_term_data)]:
if not data:
continue
values = [v for v, t in data]
results[f'{name}_mean'] = np.mean(values)
results[f'{name}_std'] = np.std(values)
results[f'{name}_min'] = np.min(values)
results[f'{name}_max'] = np.max(values)
return results
这样你可以在不同时间尺度上观察模型表现:实时窗口如果突然变差,可能服务有问题;短期窗口持续下降,可能是数据漂移;长期窗口稳定但近期变差,可能是业务场景变了。
告警策略:从"狼来了"到"该出手时就出手"
告警设置是模型监控里最容易翻车的地方。
误报陷阱
早期的告警策略很粗暴:准确率下降超过5%就告警。结果经常半夜被叫起来,发现准确率只是从92%掉到87%,还在可接受范围内。
另一个常见问题是数据波动引发的误报。周末的流量和工作日不同,节假日的用户行为和平时不一样,这些正常波动都可能触发告警。
后来我学乖了:告警要考虑上下文,而不是绝对阈值。
class ContextAwareAlert:
def __init__(self, history_window=7):
self.history_window = history_window
self.history_data = []
def add_data_point(self, value, timestamp):
"""
添加历史数据点
"""
self.history_data.append((value, timestamp))
# 清理过期数据
now = datetime.now()
self.history_data = [(v, t) for v, t in self.history_data
if t > now - timedelta(days=self.history_window)]
def should_alert(self, current_value, timestamp):
"""
判断是否应该告警
Args:
current_value: 当前指标值
timestamp: 当前时间
Returns:
(should_alert, reason)
"""
if len(self.history_data) < 24: # 至少需要1天数据
return False, "历史数据不足"
# 计算同一时间段的历史均值和标准差
hour_of_day = timestamp.hour
day_of_week = timestamp.weekday()
historical_values = []
for v, t in self.history_data:
if t.hour == hour_of_day and t.weekday() == day_of_week:
historical_values.append(v)
if len(historical_values) < 3:
return False, "同一时段历史样本不足"
mean = np.mean(historical_values)
std = np.std(historical_values)
# 判断当前值是否偏离历史均值超过2个标准差
z_score = abs(current_value - mean) / (std + 1e-10)
if z_score > 2:
return True, f"当前值{current_value:.2f}偏离历史均值{mean:.2f}超过2个标准差"
else:
return False, f"当前值{current_value:.2f}在正常范围内"
这个告警策略考虑了时间上下文——同样是85%的准确率,在凌晨2点可能是正常的,但在下午2点可能就异常了。
告警分级
不是所有异常都值得立刻叫醒人。
实践中我把告警分成三级:
- P0(紧急):模型完全不可用,预测准确率暴跌到随机水平,或者服务超时、错误率飙升
- P1(重要):模型性能下降超过10%,但还在可用范围内
- P2(关注):轻微性能下降,或者检测到数据漂移但业务指标还正常
class PriorityAlert:
def __init__(self):
self.alert_handlers = {
'P0': self.handle_p0_alert,
'P1': self.handle_p1_alert,
'P2': self.handle_p2_alert
}
def evaluate_alert_priority(self, metrics):
"""
评估告警优先级
Args:
metrics: 包含各种监控指标的字典
Returns:
priority: 'P0', 'P1', 'P2' 或 None
reason: 告警原因
"""
# P0条件:完全不可用
if (metrics.get('error_rate', 0) > 0.1 or
metrics.get('latency_p99', 0) > 5000 or
metrics.get('accuracy', 1) < 0.6):
return 'P0', '模型服务不可用或性能严重下降'
# P1条件:性能下降显著
if (metrics.get('accuracy', 1) < metrics.get('baseline_accuracy', 1) * 0.9 or
metrics.get('conversion_rate', 1) < metrics.get('baseline_conversion', 1) * 0.9):
return 'P1', '模型性能下降超过10%'
# P2条件:轻微异常
if (metrics.get('data_drift', 0) > 0.1 or
metrics.get('confidence_drift', 0) > 0.1):
return 'P2', '检测到轻微数据或置信度漂移'
return None, '正常'
def handle_p0_alert(self, reason):
"""处理P0告警"""
# 立即通知on-call人员
self.send_immediate_notification(reason)
# 尝试自动回滚到上一个稳定版本
self.attempt_auto_rollback()
def handle_p1_alert(self, reason):
"""处理P1告警"""
# 发送邮件和Slack通知
self.send_email_notification(reason)
self.send_slack_notification(reason)
# 记录到监控看板
self.log_to_dashboard(reason)
def handle_p2_alert(self, reason):
"""处理P2告警"""
# 只记录到监控看板,不主动通知
self.log_to_dashboard(reason)
def send_immediate_notification(self, reason):
"""立即通知on-call人员"""
# 实现细节取决于你的通知系统
pass
def attempt_auto_rollback(self):
"""尝试自动回滚"""
# 实现细节取决于你的部署系统
pass
# ... 其他通知方法的实现
这样你不会因为凌晨3点检测到轻微数据漂移被叫起来,但真正出问题时能第一时间知道。
实践中的坑和解决方案
讲完了理论,聊聊这几年踩过的真实坑。
坑一:监控模型但不监控数据源
一次线上事故,模型预测突然变得很奇怪:大部分预测结果都集中在0.8-0.9之间,置信度分布非常不自然。
查了半天发现不是模型问题,是上游的数据管道出了bug——某些特征被错误地填充成了默认值,导致模型输入变得很单一。
教训:模型监控的同时要监控数据管道。至少要监控:
- 特征缺失率的变化
- 特征值范围的异常
- 数据更新频率
- 数据新鲜度
class DataQualityMonitor:
def __init__(self, feature_specs):
"""
Args:
feature_specs: 特征规格字典,包含每个特征的预期范围和类型
例如:
{
'age': {'min': 0, 'max': 120, 'type': 'numeric'},
'gender': {'values': ['M', 'F'], 'type': 'categorical'}
}
"""
self.feature_specs = feature_specs
self.history = {}
def check_data_quality(self, data):
"""
检查数据质量
Args:
data: 输入数据字典
Returns:
quality_report: 质量报告,包含问题和建议
"""
issues = []
for feature, spec in self.feature_specs.items():
if feature not in data:
issues.append(f"特征缺失: {feature}")
continue
value = data[feature]
# 检查数值范围
if spec.get('type') == 'numeric':
if 'min' in spec and value < spec['min']:
issues.append(f"{feature}值{value}低于最小值{spec['min']}")
if 'max' in spec and value > spec['max']:
issues.append(f"{feature}值{value}高于最大值{spec['max']}")
# 检查分类值
elif spec.get('type') == 'categorical':
if value not in spec.get('values', []):
issues.append(f"{feature}值{value}不在允许的值列表中")
# 记录历史
if feature not in self.history:
self.history[feature] = []
self.history[feature].append(value)
# 检测分布异常(简化版)
if len(self.history[feature]) > 100:
recent_values = self.history[feature][-100:]
if value not in recent_values[-20:]:
issues.append(f"{feature}值{value}与最近20个样本差异较大")
return {
'passed': len(issues) == 0,
'issues': issues
}
坑二:监控滞后导致回滚不及时
模型上线后性能逐渐下降,但告警阈值设置得比较宽松,等触发告警时已经烂了一个多星期。这时候回滚成本已经很高了——用户已经开始习惯新结果,回滚反而会被当成故障。
教训:当前值和趋势线一起看,趋势往下走时往往比单次掉点更该警惕。
class TrendMonitor:
def __init__(self, window=7):
self.window = window
self.history = []
def add_data_point(self, value, timestamp):
self.history.append((value, timestamp))
def calculate_trend(self):
"""
计算趋势
Returns:
trend: 'increasing', 'decreasing', 'stable'
slope: 趋势斜率
confidence: 趋势置信度
"""
if len(self.history) < self.window * 2:
return 'stable', 0, 0
# 提取最近window天的数据
now = datetime.now()
recent = [(v, t) for v, t in self.history
if t > now - timedelta(days=self.window)]
if len(recent) < 3:
return 'stable', 0, 0
# 简单线性回归
times = [(t - recent[0][1]).total_seconds() for v, t in recent]
values = [v for v, t in recent]
slope, intercept = np.polyfit(times, values, 1)
# 计算R方(拟合优度)
predictions = [slope * t + intercept for t in times]
ss_res = sum((values[i] - predictions[i])**2 for i in range(len(values)))
ss_tot = sum((values[i] - np.mean(values))**2 for i in range(len(values)))
r_squared = 1 - (ss_res / ss_tot)
# 判断趋势
if r_squared < 0.5:
return 'stable', slope, r_squared
elif slope > 0.01:
return 'increasing', slope, r_squared
elif slope < -0.01:
return 'decreasing', slope, r_squared
else:
return 'stable', slope, r_squared
def should_alert_on_trend(self):
"""
基于趋势判断是否需要告警
"""
trend, slope, confidence = self.calculate_trend()
# 如果趋势是下降且置信度较高
if trend == 'decreasing' and confidence > 0.6:
return True, f"检测到下降趋势(斜率{slope:.4f},置信度{confidence:.2f})"
return False, f"趋势{trend},无需告警"
趋势监控的好处是能在问题变得严重之前就发信号,给团队留出响应时间。
坑三:监控太多指标反而没人看
早期恨不得监控所有指标:准确率、精确率、召回率、F1、AUC、各种漂移指标、延迟、吞吐量、错误率、GPU使用率、内存使用率…
结果监控面板变成了一堆曲线和数字,没人看得懂,更没人知道出问题时该先看哪个。
教训:指标堆满面板没人看,不如只留 accuracy/转化率、稳定性、延迟错误率这几条主线。
现在我通常只监控这几个核心指标:
- 准确性:模型预测准确率或业务转化率
- 稳定性:预测结果的方差或置信度分布
- 可用性:预测延迟和错误率
- 效率:资源使用率(可选)
其他指标只在需要时深入查看,不是日常监控的对象。
坑四:监控但不行动,变成"告警疲劳"
有一段时间告警系统很"勤奋",每天都能收到十几条告警信息。但大部分都只是轻微漂移,业务上影响不大。慢慢地大家开始忽略告警,直到真正出问题时没人第一时间响应。
教训:告警要可行动,否则不如不告警。
每个告警信息都要包含:
- 问题描述:具体是什么问题
- 影响范围:影响了哪些用户或业务
- 可能原因:初步分析的可能原因
- 建议措施:建议采取的措施
class ActionableAlert:
def generate_alert_message(self, alert_type, metrics, context):
"""
生成可行动的告警信息
Args:
alert_type: 告警类型 ('P0', 'P1', 'P2')
metrics: 监控指标
context: 上下文信息(数据版本、模型版本等)
Returns:
alert_message: 结构化的告警信息
"""
message = {
'priority': alert_type,
'timestamp': datetime.now().isoformat(),
'summary': '',
'details': {},
'impact': '',
'possible_causes': [],
'recommended_actions': [],
'context': context
}
if alert_type == 'P0':
if metrics.get('error_rate', 0) > 0.1:
message['summary'] = '模型服务错误率过高'
message['impact'] = '用户请求大量失败,严重影响用户体验'
message['possible_causes'] = [
'模型服务崩溃',
'依赖服务不可用',
'资源耗尽'
]
message['recommended_actions'] = [
'立即检查模型服务状态',
'尝试自动回滚到上一个稳定版本',
'检查依赖服务(数据库、缓存等)',
'增加资源分配'
]
elif metrics.get('accuracy', 1) < 0.6:
message['summary'] = '模型预测准确率严重下降'
message['impact'] = '模型预测结果几乎不可用'
message['possible_causes'] = [
'输入数据异常',
'模型文件损坏',
'业务场景发生重大变化'
]
message['recommended_actions'] = [
'检查输入数据质量',
'尝试回滚到上一个模型版本',
'检查数据管道是否正常',
'评估是否需要紧急重新训练'
]
elif alert_type == 'P1':
message['summary'] = '模型性能下降'
message['impact'] = '用户体验受到一定影响,但不完全不可用'
message['possible_causes'] = [
'数据分布发生漂移',
'模型性能自然衰减',
'用户行为模式变化'
]
message['recommended_actions'] = [
'分析数据漂移情况',
'评估是否需要重新训练',
'考虑A/B测试新模型',
'与业务团队确认是否有产品变更'
]
elif alert_type == 'P2':
message['summary'] = '模型轻微异常'
message['impact'] = '当前影响较小,但需要关注趋势'
message['possible_causes'] = [
'正常的数据波动',
'轻微的数据漂移',
'暂时的环境因素'
]
message['recommended_actions'] = [
'持续监控趋势',
'记录异常现象',
'定期评估模型性能'
]
return message
工具选型:不是越复杂越好
最后聊聊工具选择。市场上监控工具很多,但不是越复杂越好。
Prometheus + Grafana:基础设施监控
如果你的模型部署在K8s上,Prometheus + Grafana几乎是标配。它们擅长监控基础设施层面的指标:延迟、错误率、资源使用率。
但它们不太适合监控业务层面的指标:准确率、漂移、转化率这些。这些指标需要你自己在业务代码里埋点。
Evidently AI:开源模型监控
Evidently AI是一个开源的Python库,专门用于机器学习模型的监控。它提供了数据漂移检测、模型性能评估、数据质量检查等功能。
from evidently import ColumnMapping
from evidently.report import Report
from evidently.metric_preset import DataDriftPreset, ClassificationPerformancePreset
# 配置列映射
column_mapping = ColumnMapping(
target='target',
prediction='prediction',
numerical_features=['feature1', 'feature2'],
categorical_features=['feature3']
)
# 生成数据漂移报告
drift_report = Report(metrics=[DataDriftPreset()])
drift_report.run(reference_data=train_data, current_data=online_data, column_mapping=column_mapping)
# 生成模型性能报告
performance_report = Report(metrics=[ClassificationPerformancePreset()])
performance_report.run(reference_data=train_data, current_data=online_data, column_mapping=column_mapping)
# 导出报告
drift_report.save_html('drift_report.html')
performance_report.save_html('performance_report.html')
Evidently的好处是开箱即用,不需要自己实现各种统计检验。但它的报告是静态HTML,不太适合集成到实时告警系统里。
Arize / WhyLabs:商业SaaS方案
如果你不想自己维护监控基础设施,可以考虑商业SaaS方案,比如Arize或WhyLabs。它们提供了完整的模型监控平台,包括漂移检测、性能监控、异常检测、告警通知等。
但这类方案的缺点也很明显:成本高、数据要上传到第三方、定制化程度有限。
自研方案:灵活但成本高
如果你的场景比较特殊,或者对数据隐私有要求,可能需要自研监控方案。
自研的好处是可以完全按照需求定制,但成本也很高——你需要实现数据采集、指标计算、漂移检测、告警通知等所有组件。
我的建议是:先从开源方案开始,如果确实满足不了需求再考虑自研。
结语
模型上线那天,监控才算真正开始。我后来只盯几件事:业务指标有没有悄悄变差、漂移告警是不是狼来了、趋势往下走时有没有留够回滚窗口。
面板做得再漂亮,业务还在出问题,说明盯错指标了。工具帮不上忙的地方,还是对数据和业务的熟悉——监控只是把那种直觉量化出来。
版权声明: 本文首发于 指尖魔法屋-AI模型监控:这次怎么落地的(https://blog.thinkmoon.cn/post/189-ai-model-monitoring-deployment-runtime-practice/) 转载或引用必须申明原指尖魔法屋来源及源地址!
评论
使用 GitHub 账号登录后即可留言,支持 Markdown。