在工业级机器学习应用中,模型部署绝不是简单的"训练完扔上线"的过程。去年我们团队将一个NLP分类模型部署到生产环境时,就因为忽略了吞吐量指标,导致上线首日服务器直接过载宕机。以下这些关键指标,每个都直接影响着线上服务的生死存亡:
推理延迟:从请求发出到获得响应的时间。电商推荐系统要求95%的请求在80ms内响应,我们通过以下手段优化:
python复制# TensorRT优化示例
import tensorrt as trt
logger = trt.Logger(trt.Logger.WARNING)
with trt.Builder(logger) as builder:
network = builder.create_network()
parser = trt.OnnxParser(network, logger)
# 加载ONNX模型并优化
with open("model.onnx", "rb") as f:
parser.parse(f.read())
实际测试中,ResNet50的延迟从45ms降至11ms
吞吐量:单位时间处理的请求数(QPS)。当我们的广告CTR预测模型QPS达到2000时,出现了以下典型问题:
| 指标类型 | 监控方式 | 健康阈值 | 异常处理 |
|---|---|---|---|
| GPU内存占用 | nvidia-smi | ≤80% | 启用模型分片 |
| CPU利用率 | Prometheus | ≤70% | 调整线程池大小 |
| 显存泄漏 | 差值检测 | Δ<5MB/min | 重启容器服务 |
我们在图像识别项目中发现,使用FP16精度不仅将显存占用从6GB降到3.2GB,还意外提升了3%的推理速度——这是因为现代GPU的Tensor Core对半精度有特殊优化。
当需要紧急修复线上模型时,传统停机部署方式会导致:
我们采用的蓝绿部署方案实现了300ms内的无缝切换:
ONNX转换时遇到过这些"坑":
tf.get_concrete_functionpython复制# 解决TF模型输入维度问题
concrete_func = model.signatures[tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
concrete_func.inputs[0].set_shape([None, 224, 224, 3])
tf.saved_model.save(model, "saved_model_dir", signatures=concrete_func)
FastAPI部署时推荐这些优化:
app.add_middleware(GZipMiddleware)python复制@app.post("/predict")
async def predict_batch(requests: List[InputSchema]):
batch = preprocess([r.dict() for r in requests])
results = await model_runner.predict(batch)
return [{"score": float(r)} for r in results]
| 引擎 | 优点 | 适用场景 | 我们的教训 |
|---|---|---|---|
| TensorRT | 极致优化 | 固定输入尺寸 | 动态shape支持差 |
| ONNX Runtime | 跨平台 | 多硬件部署 | 自定义OP成本高 |
| TorchScript | 原生支持 | 研究原型 | 线程安全问题多 |
/dev/shm加载模型权重在智能摄像头项目中的实践:
jetson_clocks锁定最高频率Istio实现的功能:
在模型部署这条路上,最深的体会是:没有放之四海皆准的完美方案。去年我们为金融客户部署风控模型时,最终放弃了Kubernetes而采用裸金属服务器——只因那2微秒的延迟差异决定了套利机会的生死。这行当里,业务场景永远是技术选型的最终裁判。