5月28日 02:03

TensorFlow Serving是什么?如何用它部署模型?

TensorFlow Serving 是什么?

TensorFlow Serving 是 Google 开源的高性能模型服务系统,用 C++ 编写,专门为生产环境设计。它的核心能力是把训练好的 TensorFlow 模型以 REST API 或 gRPC 接口对外提供推理服务,同时支持模型版本管理、热更新和多模型并行托管。

跟 Flask 封一个模型接口相比,TFS 的优势在于:gRPC 协议带来的低延迟(通常比 REST 快 3-10 倍)、内置的版本策略(支持同时服务多个版本做 A/B 测试)、以及自动模型加载/卸载机制。简单说,Flask 能做的 TFS 都能做,而且更适合高并发场景。

TFS 的架构核心是 Servable 抽象——模型、词表、查找表都可以是 Servable。Manager 负责管理 Servable 的生命周期,Source 监控文件系统发现新版本,Loader 负责加载和估算资源。这种解耦设计让 TFS 可以在不中断服务的情况下完成模型切换。

怎么用 TensorFlow Serving 部署模型?

部署流程分三步:导出模型 → 启动服务 → 调用推理接口。

第一步:导出 SavedModel 格式

TFS 只认 SavedModel 格式,不支持 Checkpoint。导出时需要指定签名(SignatureDef),告诉 TFS 输入输出分别叫什么、是什么类型。

python
import tensorflow as tf # 假设 model 是你训练好的 Keras 模型 model.save("/models/my_model/1") # 数字 1 是版本号 # 也可以用 tf.saved_model.save 手动控制签名 tf.saved_model.save(model, "/models/my_model/1", signatures={ 'serving_default': model.__call__.get_concrete_function( tf.TensorSpec(shape=[None, 3], dtype=tf.float32) ) } )

导出后用 saved_model_cli 检查签名是否正确:

bash
saved_model_cli show --dir /models/my_model/1 --all

输出会列出签名的输入输出名称、dtype 和 shape。这一步很关键——调用时字段名必须和签名一致,否则报错。

导出后的目录结构:

shell
/models/my_model/ └── 1/ # 版本号(必须是整数) ├── saved_model.pb # 模型结构和元数据 └── variables/ # 模型权重

关键点:版本号必须是整数,TFS 按数字大小判断最新版本。热更新时只需在同级目录新建 2/ 文件夹放入新模型,TFS 会自动检测并加载。

第二步:启动 TFS 服务

最简单的方式是 Docker:

bash
docker run -d --name tfs \ -p 8501:8501 \ -p 8500:8500 \ -v /models/my_model:/models/my_model \ -e MODEL_NAME=my_model \ tensorflow/serving

端口说明:

  • 8501:REST API(/v1/models/{model}:predict
  • 8500:gRPC

也可以用二进制直接启动,适合需要精细控制的场景:

bash
tensorflow_model_server \ --model_config_file=models.conf \ --rest_api_port=8501 \ --grpc_port=8500 \ --enable_batching=true \ --batching_parameters_file=batcningenning_config.txt

多模型配置文件 models.conf

shell
model_config_list { config { name: "model_a" base_path: "/models/model_a" model_platform: "tensorflow" model_version_policy { specific { versions: 1 versions: 2 } } } config { name: "model_b" base_path: "/models/model_b" model_platform: "tensorflow" } }

第三步:调用推理接口

REST API 调用(更简单,适合调试):

bash
curl -X POST http://localhost:8501/v1/models/my_model:predict \ -H "Content-Type: application/json" \ -d '{"instances": [[1.0, 2.0, 3.0]]}'

注意 instances 字段对应的是 SignatureDef 中定义的输入名。如果签名中输入名不是默认的,需要用 inputs 字段显式指定:

json
{ "inputs": { "input_tensor": [[1.0, 2.0, 3.0]] } }

gRPC 调用(性能更好,适合生产):

python
import grpc import numpy as np import tensorflow as tf from tensorflow_serving.apis import predict_pb2, prediction_service_pb2_grpc channel = grpc.insecure_channel('localhost:8500') stub = prediction_service_pb2_grpc.PredictionServiceStub(channel) request = predict_pb2.PredictRequest() request.model_spec.name = 'my_model' request.model_spec.signature_name = 'serving_default' request.inputs['input_tensor'].CopyFrom( tf.make_tensor_proto(np.array([[1.0, 2.0, 3.0]]), dtype=tf.float32) ) response = stub.Predict(request, 10.0) # 10秒超时 result = tf.make_ndarray(response.outputs['output_tensor'])

gRPC 比 REST 快的核心原因是使用 Protocol Buffers 序列化,省去了 JSON 解析开销,且支持长连接多路复用。

模型版本管理怎么配?

TFS 支持三种版本策略:

  • 可用性优先(默认):新版本加载完成后才切换,旧版本继续服务直到新版本就绪,零停机
  • 资源优先:先卸载旧版本再加载新版本,节省内存但会有短暂不可用
  • 指定版本:固定使用某个版本号,适合回滚场景

通过 model_version_policy 配置:

shell
model_version_policy { specific { versions: 1 versions: 2 } }

A/B 测试场景下,可以同时加载多个版本,调用时通过 URL 参数 ?version=2 或 gRPC 的 model_spec.version 指定调用哪个版本。

热更新操作:在模型目录下新建版本号文件夹放入新模型即可。TFS 的 Source 模块会定期轮询文件系统(默认 2 秒),发现新版本后自动触发加载。也可以通过 gRPC 调用 ReloadConfig API 手动触发。

TFS 和其他部署方案怎么选?

方案适用场景协议多框架支持生产成熟度
TensorFlow ServingTF 模型、高并发gRPC + REST仅 TensorFlow
TorchServePyTorch 模型REST + gRPC仅 PyTorch中(已归档)
NVIDIA Triton多框架混合HTTP + gRPCTF/PyTorch/ONNX/TensorRT
FastAPI/Flask快速验证、自定义逻辑REST任意框架

选型建议:纯 TF 生态用 TFS 就够了;多框架混合部署考虑 Triton;快速原型验证用 FastAPI 更灵活。注意 TorchServe 已于 2025 年 8 月归档,如果之前在用建议迁移到 Triton。

生产环境要注意什么?

性能优化

  • 开启 batching:TFS 内置请求批处理,设置 --enable_batching--batching_parameters_file 可以把多个请求合并成一个大 batch 再推理,显著提升吞吐。典型配置下吞吐可提升 3-5 倍,但 P99 延迟会增加
  • 用 TensorRT 优化:--model_platform: "tensorflow_tensorrt" 可以把模型转为 TensorRT 格式,推理速度提升 2-8 倍,适合 GPU 部署
  • 调整 inter_op_parallelismintra_op_parallelism 线程数,通常设为 CPU 核心数

监控

  • Prometheus 指标:TFS 默认暴露 http://localhost:8501/monitoring/prometheus 端点,包含请求延迟、QPS、模型加载状态、批处理统计等指标
  • 健康检查:GET /v1/models/my_model 返回模型状态,可配合 Kubernetes liveness/readiness probe

高可用

  • 多副本部署 + 负载均衡,避免单点故障
  • Kubernetes 集成:官方提供 TF Serving 的 Helm Chart,支持 HPA 自动扩缩容
  • 模型存储建议用 NFS 或对象存储挂载,配合 CI/CD 管道自动推送新版本

常见坑

  • 模型签名不匹配是最常见的报错原因,部署前务必用 saved_model_cli 验证
  • Docker 镜像分 CPU 和 GPU 版本,GPU 版本需要安装 NVIDIA Container Toolkit
  • 大模型首次加载耗时较长,建议预热(启动后发几条测试请求触发懒加载)

追问:TFS 能服务非 TensorFlow 模型吗?

不能直接服务。TFS 只支持 SavedModel 格式,也就是说只认 TensorFlow 模型。如果需要服务 PyTorch 或 ONNX 模型,要么先转换格式(ONNX → TF),要么换用 NVIDIA Triton 这种多框架服务系统。不过在实际生产中,模型格式转换往往引入精度损失,不建议这么做。更实际的做法是按框架选择对应的服务系统,或者直接上 Triton 统一托管。

标签:Tensorflow