模型服务化:TorchServe 与 Triton Inference Server 深度实践
核心观点:凌晨两点,屏幕上的日志还在疯狂滚动。第 37 次尝试启动 TorchServe 服务,依然卡在"Loading model…"然后超时。同事发来的微信还在闪烁:"客户明天要看演示,模型部署必须搞定。"这场景太熟悉了——模型在本地跑得好好的,一到生产环境就各种水土不服。
一、模型服务化基础
1.1 为什么需要模型服务化?
本地推理 vs 生产服务: 本地: - 单次调用 - Python 脚本 - 独占资源 - 无并发 生产: - 高并发请求 - REST/gRPC API - 资源池化 - 监控/告警 - A/B Testing - 蓝绿部署1.2 服务化框架对比
| 框架 | 特点 | 适用场景 | 性能 |
|---|---|---|---|
| TorchServe | PyTorch 官方 | PyTorch 模型 | 高 |
| Triton | NVIDIA | 通用推理 | 最高 |
| TensorFlow Serving | TF 模型 | 高 | |
| FastAPI + Uvicorn | 轻量 | 简单服务 | 中 |
| Ray Serve | 分布式 | 复杂编排 | 高 |
二、TorchServe 深度实践
2.1 核心概念
TorchServe 架构: ┌─────────────────────────────────────────────┐ │ API │ │ (REST / gRPC) │ └──────────────────┬──────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ Handler │ │ (请求预处理 / 推理 / 后处理) │ └──────────────────┬──────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ Model │ │ (PyTorch Model) │ └─────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ Backend │ │ (Worker Management / Metrics) │ └─────────────────────────────────────────────┘2.2 模型打包
# 1. 创建模型类fromtorchserve.inferenceimportModelfromtorchserveimportregistryclassTextClassifier:"""文本分类器"""def__init__(self):self.model=Noneself.mapping={0:"negative",1:"positive"}defload(self,checkpoint_path):"""加载模型"""importtorch self.model=torch.jit.load(checkpoint_path)self.model.eval()defpredict(self,data):"""推理"""importtorchimporttorch.nn.functionalasF# 预处理input_tensor=torch.tensor(data).unsqueeze(0)# 推理withtorch.no_grad():output=self.model(input_tensor)probs=F.softmax(output,dim=-1)pred=probs.argmax(dim=-1).item()return{"prediction":self.mapping[pred],"confidence":probs[0][pred].item()}# 注册模型registry.register("text_classifier")(TextClassifier)# 2. 创建 mar 文件配置# model-config.yamlmar_config={"modelName":"text_classifier","version":"1.0","serializedFile":"model.pt","modelFile":"text_classifier.py","handler":"text_classifier","batchSize":4,"maxBatchDelay":100,"responseTimeout":60,"numberOfWorkers":2}2.3 Handler 编写
# custom_handler.pyfromabcimportABCfromtypingimportListimporttorchfromts.contextimportContextclassBaseHandler(ABC):