请添加图片描述

前言

拿到一个 ResNet50 的 .om 文件,要部署成推理服务。用 TorchServe,一天时间能走完全流程。


一、环境搭建(09:00-10:30)

安装 TorchServe

官方文档说 pip install torchserve,但昇腾版本要换源:

pip install torchserve torch-model-archiver -i https://pypi.tuna.tsinghua.edu.cn/simple

装完之后启动服务:

torchserve --start --model-store ./model_store

报错:libtorch_npu.so not found。原因是 TorchServe 默认用 CPU 版本的 PyTorch,需要手动指定 NPU 版本。

安装 torch_npu

pip uninstall torch
pip install torch_npu -f https://repo.huaweicloud.com/kunpeng/pypi/simple

再次启动 TorchServe,这次成功了。访问 http://localhost:8080/predictions/resnet50,返回 500 错误。日志显示:Model not found


二、Handler 开发(10:30-12:00)

Handler 是什么

Handler 是 TorchServe 调用模型的入口,负责三个步骤:

  1. 预处理:解析请求,转 tensor,归一化
  2. 推理:调用 .om 模型
  3. 后处理:tensor 转 JSON,返回结果

Handler 代码示例

# handler.py
import torch
import torch_npu
import json
from torchvision import transforms

class ResNetHandler:
    def initialize(self, context):
        # 加载 .om 模型
        self.model = torch.jit.load("resnet50.om", map_location="npu:0")
        self.model.eval)
        
        # 预处理 pipeline
        self.preprocess = transforms.Compose([
            transforms.Resize(256),
            transforms.CenterCrop(224),
            transforms.ToTensor(),
            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ])

    def handle(self, data, context):
        # 解析请求
        images = [self.preprocess(img) for img in data]
        input_tensor = torch.stack(images).to("npu:0")
        
        # 推理
        with torch.no_grad():
            output = self.model(input_tensor)
        
        # 后处理:取 top5 类别
        probs = torch.nn.functional.softmax(output, dim=1)
        top5 = torch.topk(probs, 5)
        
        return [{"labels": top5.indices.tolist(), "probs": top5.values.tolist()}]

Handler 的核心是 initializehandle 两个方法。initialize 在模型加载时调用一次,handle 在每次推理时调用。


三、打包 .mar 文件(12:00-14:00)

什么是 .mar 文件

.mar(Model Archive)是 TorchServe 的模型打包格式,包含:

  • 模型文件(.om
  • Handler 代码
  • 依赖列表
  • 配置文件

打包命令

torch-model-archiver \
    --model-name resnet50 \
    --version 1.0 \
    --handler handler.py \
    --extra-files resnet50.om \
    --export-path ./model_store

参数说明:

  • --model-name:模型名称,调用时用这个名字
  • --handler:Handler 文件路径
  • --extra-files:额外的文件(比如 .om 文件)
  • --export-path:输出目录

四、注册与测试(14:00-16:00)

注册模型

curl -X POST "http://localhost:8081/models?url=resnet50.mar&model_name=resnet50"

返回 200 OK,模型注册成功。

测试推理

curl -X POST "http://localhost:8080/predictions/resnet50" -T cat.jpg

返回:

{
  "labels": [281, 282, 285, 287, 289],
  "probs": [0.873, 0.041, 0.023, 0.012, 0.008]
}

单次推理延迟 15ms,满足要求。

推理流程示意图

客户端请求 → TorchServe → Handler.preprocess → .om 推理 → Handler.postprocess → 返回结果

五、性能调优(16:00-17:30)

Worker 数量调优

默认 worker 数量是 1,只用了单核。压测结果:

ab -n 1000 -c 50 http://localhost:8080/predictions/resnet50

QPS 180,P99 延迟 320ms。QPS 偏低(单卡理论上能到 400+)。

修改 worker 数量:

curl -X PUT "http://localhost:8081/models/resnet50?min_worker=4&max_worker=4"

重新压测:QPS 提到 620,P99 延迟 85ms。

性能对比表

配置 QPS P99 延迟 AICore 利用率
worker=1 180 320ms 45%
worker=4 620 85ms 78%
worker=8 580 92ms 72%(下降)

Worker 数量不是越多越好。4 个 worker 时,每个 worker 独占一个 AICore,利用率最高。8 个 worker 时,多个 worker 竞争同一个 AICore,反而下降。


六、监控与告警(17:30-18:00)

Prometheus 指标

TorchServe 自带 metrics 接口:

curl http://localhost:8082/metrics

返回 Prometheus 格式的指标:

torchserve_requests_total{model="resnet50"} 1523
torchserve_inference_latency_seconds{model="resnet50"} 0.015
torchserve_model_load_time_seconds{model="resnet50"} 2.3

Grafana 配置

接入 Grafana 后,配置告警规则:

  • P99 延迟 > 500ms 持续 5 分钟 → 发钉钉通知
  • QPS < 100 持续 10 分钟 → 发邮件通知
  • 错误率 > 1% 持续 2 分钟 → 发短信通知

七、回滚方案

GPU 版本的模型还在,如果 NPU 版本出问题,可以立刻切回去。

准备两个 .mar 文件:

  • resnet50_npu.mar:NPU 版本
  • resnet50_gpu.mar:GPU 版本

切换方法:

# config.properties
load_models=resnet50_gpu.mar  # 默认加载 GPU 版本

切到 NPU 版本:改一行 load_models=resnet50_npu.mar,重启 TorchServe。


参考资源

  • TorchServe 官方文档:https://pytorch.org/serve/
  • 昇腾模型部署指南:https://www.hiascend.com/document
  • torch_npu 安装指南:https://gitee.com/ascend/pytorch

总结

.om 文件到 TorchServe 上线,核心步骤是:环境搭建(换 torch_npu)→ Handler 开发 → 打包 .mar → 注册模型 → Worker 调优 → 配监控。最花时间的是处理 NPU 环境的依赖,Handler 和打包是标准流程。Worker 数量调到 4,单卡 QPS 能到 600+,满足大多数在线服务需求。监控和回滚是上线前必做的,避免线上翻车。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐