模型服务化任务模板
本篇汇总 5 个面向「模型上线/批量推理」环节的 pipeline 任务模板,覆盖从模型转换、注册、部署到离线推理与评估的完整链路:
| 任务模板 | 算子目录 | 作用 |
|---|---|---|
| model-convert | job-template/job/model-convert |
PyTorch/YOLO → ONNX → OpenVINO/NCNN/MNN/TFLite/RKNN/TensorRT 等边缘多格式 |
| model-register | job-template/job/model_register |
把训练产出的模型注册到平台「模型管理」 |
| deploy-service | job-template/job/deploy-service |
pipeline 内一键创建/更新推理服务并发布上线 |
| model-evaluation | job-template/job/model_evaluation |
传统 ML 离线推理结果对比真值,算指标并输出 JSON |
| offline-predict | job-template/job/offline-predict |
基于 RabbitMQ 的多 Worker 分布式离线推理 |
命名提示:任务家族清单里有一个
model_offline_predict目录,但当前为空,已跳过;平台编排界面里显示的任务名是 model-offline-predict,其实际算子代码就在 offline-predict 目录。其「模板使用」说明见 05-任务模板/模板使用/README.md(对应08-模型服务化.md使用文档),本篇侧重算子设计与参数核对。
model-convert(模型转换:PyTorch/YOLO → ONNX → 边缘多格式)
将 PyTorch / YOLO 模型 统一先转换为 ONNX,再按需分发到下列任意组合的边缘部署格式(核对 job-template/job/model-convert/start.py、backends/、verify/):
- ONNX(基础产物,所有 backend 的前置)
- INT8 动态量化 ONNX(可选)
- OpenVINO(Intel CPU/iGPU:
model.xml+model.bin) - NCNN(手机/嵌入式:
model.param+model.bin) - MNN(阿里 MNN:
.mnn) - TFLite(移动端:
.tflite,含 FP32 / dynamic range / FP16 多变体 + SavedModel) - RKNN(瑞芯微 NPU:
.rknn,支持 RK3566/3568/3588 等) - TensorRT Engine(NVIDIA GPU:
-FP32.engine+-FP16.engine) - 跨平台 SDK 库(lib):把 ONNX 嵌入 C/C++ 动态库
.so/.dll,统一 C ABI
流程与入口
PyTorch / YOLO ──► ONNX ──► (可选) INT8 动态量化
└► 按 --export_format 分发到各 backend
onnx | openvino | ncnn | mnn | tflite | rknn | engine | lib
- 入口脚本:
start.py,工作目录/app,启动命令python start.py。 - 双模式输入(
--model_type,仅允许yolo/torch):- yolo:调用
ultralytics的export(format="onnx"),固定imgsz=640、opset=12、dynamic=True、simplify=True、nms=True(start.py:69)。 - torch:通过
generic_loader.load_model_from_file加载 TorchScript / 完整nn.Module/ state_dict,再经torch2onnx_compat.torch_to_onnx导出(默认动态轴、图简化、导出后数值校验,start.py:103-114)。未指定--arch时会在有限集合内自动猜测架构。
- yolo:调用
- 多 backend 分发:
--export_format是逗号分隔的格式列表,onnx始终被自动加入(它是其它 backend 的前置)。各 backend 错误隔离——某个失败不影响其它格式,但只要有失败 backend,进程以退出码 2 结束(start.py:282-283),便于流水线判定。 - 量化:
--do_quantize true时用onnxruntime.quantization.quantize_dynamic(QInt8、per_channel=True)生成*-int8.onnx(start.py:119-124)。 - TensorRT:
--onnx2engine true等价于把engine加进--export_format,必须分配 NVIDIA GPU,且 engine 与构建时 GPU 架构强绑定,建议在与部署目标同型号的 GPU 上构建。
输出路径
设 BASE 为 --export_model_path 去掉 .onnx 后的部分(如 /out/x.onnx → BASE=/out/x):
| 格式 | 输出 |
|---|---|
onnx |
--export_model_path 指定的 .onnx |
| INT8 量化 | BASE-int8.onnx |
openvino |
BASE_openvino/model.xml + model.bin |
ncnn |
BASE_ncnn/model.param + model.bin |
mnn |
BASE.mnn |
tflite |
BASE_tflite/(SavedModel + 多份 .tflite) |
rknn |
BASE.rknn |
engine |
BASE-FP32.engine + BASE-FP16.engine |
lib |
BASE_sdk/linux-x86_64/lib{lib_name}.so 和/或 BASE_sdk/windows-x86_64/{lib_name}.dll,附 inference.h、README.md |
镜像与参数
- 镜像:
ccr.ccs.tencentyun.com/cube-studio/model-convert:20260506(核对build.sh、Dockerfile,基础镜像nvidia/cuda:12.1.0-devel-ubuntu22.04,内置 PyTorch 2.5 / Ultralytics / ONNX / onnxruntime / TensorRT / OpenVINO / NCNN / MNN / onnx2tf+TF / RKNN-Toolkit2 / cmake+g+++mingw-w64 等全部依赖)。
| 参数 | 适用 | 说明 | 默认值(start.py) |
|---|---|---|---|
--model_type |
必填 | yolo / torch |
torch |
--model_path |
必填 | 待转换模型文件路径(.pt/.pth) | 空 |
--export_model_path |
必填 | 导出 ONNX 的完整路径,其它产物落同目录 | /mnt/pipeline/example/export-onnx/export.onnx |
--export_format |
必填 | 逗号分隔,可选 onnx,openvino,ncnn,mnn,tflite,rknn,engine,lib;onnx 总会自动包含 |
onnx |
--arch |
torch | 架构名,可留空自动猜测 | None |
--input_name / --output_name |
torch | ONNX 输入/输出名,逗号分隔,none 自动推断 |
None |
--do_quantize |
通用 | true/false,是否生成 INT8 量化 ONNX |
false |
--onnx2engine |
通用 | true/false,额外生成 TensorRT engine(需 GPU) |
false |
--rknn_target_platform |
rknn | rk3566/rk3568/rk3588/rk3399pro/rv1103/rv1106 等 |
rk3588 |
--lib_target |
lib | linux/windows/both |
linux |
--lib_precision |
lib | fp32/fp16 |
fp32 |
--lib_name |
lib | 输出库基础名 | model_inference |
注意:README 的「模板参数 JSON」里
--lib_target默认写的是both(model-convert/README.md:215),而start.py:38中 argparse 默认是linux(已核对)。二者一处是平台注册时的展示默认值、一处是代码默认值;以代码(linux)为运行时默认,注册模板时可按需把界面默认改成both。
使用示例
# YOLO -> ONNX + OpenVINO + NCNN(如 yolo11n)
python start.py --model_type yolo --model_path /app/yolo11n.pt \
--export_model_path /app/onnx_model/yolo11n.onnx \
--export_format onnx,openvino,ncnn
# 通用 PyTorch -> 全格式(如 deeplabv3_resnet50)
python start.py --model_type torch \
--model_path /app/deeplabv3_resnet50_coco-cd0a2569.pth \
--export_model_path /app/onnx_model/deeplabv3.onnx \
--export_format onnx,openvino,ncnn,mnn,tflite,rknn,engine,lib \
--rknn_target_platform rk3588 --lib_target both
YOLO 权重来源:https://github.com/ultralytics/assets/releases。示例 PyTorch 权重:ResNet18 https://download.pytorch.org/models/resnet18-f37072fd.pth、DeepLabV3-ResNet50 https://download.pytorch.org/models/deeplabv3_resnet50_coco-cd0a2569.pth。
SDK 库(lib)部署要点 + 模型验证
- 生成的
.so/.dll不自带 ONNX Runtime:部署时需把对应平台的libonnxruntime.so/onnxruntime.dll(Windows 须用微软官方 Windows 版)与产物放同目录,运行期dlopen/LoadLibraryA加载,不在编译期链接。 - C ABI(签名见随产物的
inference.h):model_init→model_get_input_count/model_get_output_count→model_infer→model_free_outputs→model_release。 - 当前交叉编译仅覆盖 x86_64(toolchain
mingw-w64-x86_64.cmake);arm64 Windows 暂未覆盖。 - 产物目录的
verify/提供三种验证脚本与说明:dll-verify.py+dll-readme.md、so-verify.py+so-readme.md、bin-verify.py+bin-readme.md。Jupyter 内.so可能被隐藏,在终端中查看。
model-register(注册模型到模型管理)
将训练完成的模型注册到平台「模型管理」模块,便于版本追溯,并为后续转换、离线预测、在线推理提供模型来源(核对 job-template/job/model_register/launcher.py)。
设计要点
- 注册/更新策略:按「模型名
model_name+ 当前 Run IDKFJ_RUN_ID」查询training_model_modelviewAPI;无记录则 POST 新建,有记录则 PUT 更新(避免同一 Run 重复注册)。 - API 地址:
host = HOST 或 KFJ_MODEL_REPO_API_URL,默认http://kubeflow-dashboard.infra(launcher.py:17,会strip('/'))。 - 鉴权:请求头
Authorization取环境变量SECRET(缺省回退KFJ_CREATOR,再缺省admin,launcher.py:13)。 - 校验项目组:先按
--project_name查project_modelviewAPI,项目不存在则打印「不存在项目组」并直接返回(不注册)。
参数 → 模型管理字段映射
写入 training_model_modelview 的 payload(launcher.py:65-78):
| 启动参数 | 写入字段 | 默认值 |
|---|---|---|
--project_name |
用于校验并取 project 的 id |
public |
--model_name |
name(a-z0-9- 组成,≤54 字符) |
demo |
--model_version |
version |
当前日期 v%Y.%m.%d.1 |
--model_path |
path |
空 |
--describe |
describe |
xx模型 |
--model_metric |
metrics(可为 JSON 字符串) |
空 |
--framework |
framework(lr/xgb/tf/pytorch/onnx/tensorrt/aihub) |
tf |
--inference_framework |
api_type(serving/ml-server/tfserving/torch-server/onnxruntime/triton-server/aihub) |
tfserving |
| 环境变量 | run_id(KFJ_RUN_ID)、pipeline_id(KFJ_PIPELINE_ID)、run_time、md5(空) |
— |
- 镜像:
ccr.ccs.tencentyun.com/cube-studio/model_register:20230501(核对model_register/build.sh)。 - 命令行示例:
python launcher.py \
--project_name public --model_name my-model \
--model_version v2022.10.01.1 \
--model_path minio://bucket/path/to/model \
--model_metric '{"accuracy":0.95}' \
--describe "我的模型" --framework pytorch \
--inference_framework torch-server
注意:
model_path必须是任务运行环境可访问的路径;模型管理只存路径与元数据,本步骤不上传文件。同一 Run 内多次用相同model_name注册会更新同一条记录而非新增。
deploy-service(一键建/更推理服务并发布)
在 pipeline 中一键创建或更新推理服务并自动发布上线:按「模型名 + 模型版本」判断新建还是更新,完成后触发生产环境部署(核对 job-template/job/deploy-service/launcher.py)。
前置条件
- 项目组已存在:
--project_name指定的项目组必须在平台「项目组」中已创建,否则报「不存在项目组」并退出。
行为流程(与 launcher 一致)
- 项目组校验:查
project_modelviewAPI,不存在则退出。 - 查询服务:按
model_name+model_version查inferenceservice_modelviewAPI。- 不存在 → POST
/inferenceservice_modelview/api/创建; - 已存在 → PUT
/inferenceservice_modelview/api/{id}更新。
- 不存在 → POST
- 发布:成功后
time.sleep(5)(等数据落库),再 GET/inferenceservice_modelview/api/deploy/prod/{id}部署到生产;返回302或200视为成功,否则打印错误退出(launcher.py:115-125)。
API 地址与鉴权同 model-register(HOST/KFJ_MODEL_REPO_API_URL + Authorization=SECRET)。
参数
| 参数 | 说明 | 必填 | 默认值 |
|---|---|---|---|
--project_name |
项目组(须已存在) | 是 | public |
--label |
服务中文名/描述 | 是 | 演示服务 |
--model_name |
模型名 | 是 | demo |
--model_version |
版本;同名+同版本→更新,否则新建 | 是 | 当前日期 v%Y.%m.%d.1 |
--model_path |
模型地址 | 否 | 空 |
--service_type |
服务类型(serving/ml-server/tfserving/torch-server/onnxruntime/triton-server/vllm 等,以平台支持为准) | 是 | serving |
--images |
推理服务镜像 | 是 | nginx |
--resource_memory / --resource_cpu / --resource_gpu |
每 Pod 内存/CPU/GPU | 是 | 2G / 2 / 0 |
--replicas |
副本数(min/max 均取此值) | 是 | 1 |
--working_dir / --command / --args / --env |
容器工作目录/启动命令/启动参数/环境变量 | 否 | 空 |
--ports |
暴露端口 | 否 | 80 |
--host |
部署域名,留空自动生成 | 否 | 空 |
--volume_mount |
挂载,支持 pvc/hostpath/configmap,如 pvc名(pvc):/容器路径 |
否 | 空 |
--inference_config |
配置文件内容,挂到容器 /config/,留空被重置 |
否 | 空 |
--hpa |
弹性伸缩配置 | 否 | 空 |
--metrics |
指标采集,如 8080:/metrics |
否 | 空 |
--health |
健康检查,如 8080:/health 或 shell:python health.py |
否 | 空 |
- 镜像:
ccr.ccs.tencentyun.com/cube-studio/deploy-service:20240601。 - 环境变量小技巧:在模板环境变量里配
HOST=http://xx.xx.xx.xx,可让任务把服务发布到当前访问地址。
推理服务本身的使用、各 server 类型(ml-server / tfserving / torchserve 等)详见 03-平台使用/07-服务化与推理 目录下相关文档。
model-evaluation(离线推理结果对比真值算指标)
传统机器学习模型离线推理后,将预测结果与带真实标签的评估数据集逐行对比,按指定指标算评估结果并输出 JSON(核对 job-template/job/model_evaluation/launcher.py)。常置于「离线推理」之后、可与「模型注册」串联实现「推理 → 评估 → 注册」闭环。
执行流程
- 从真实数据集 CSV 取
--true_label_column(多列取第一列)得y_true;从预测数据集 CSV 取--pred_label_column得y_pred。 - 校验
len(y_true)==len(y_pred),不一致直接抛异常退出。 - 按
--model_type分流并按--eval_type选算指标,结果以 JSON 写入--save_result_path。
- 分类指标(classify):precision、recall、accuracy、f1_score(分类用
average='macro')、auc。 - 回归指标(regression):MSE、MAE、R2_Score、Explained_Variance_score。
- eval_type 前缀处理:launcher 会去掉界面下拉里的
分类-/回归-/classify-/regression前缀后再匹配(launcher.py:121)。
注意:README 的
--eval_type下拉choice只列了分类的 precision/recall/accuracy/f1_score 与回归项,未含分类-auc(见model_evaluation/README.md的 choice 数组),但launcher.py:60-64代码里有auc分支(已核对,auc来自from sklearn.metrics import ... auc,按sklearn.metrics.auc(y_true,y_pred)计算)。sklearn.metrics.auc是按梯形法对 (x,y) 坐标积分、并非由标签直接算 ROC-AUC,如需用 auc 请先确认数据形态与该函数语义是否匹配。
参数
| 参数 | 说明 |
|---|---|
--true_dataset_path |
真实标签数据集 CSV 路径 |
--true_label_column |
真实标签列名(多列取第一列) |
--pred_dataset_path |
预测结果数据集 CSV 路径 |
--pred_label_column |
预测值列名(多列取第一列) |
--save_result_path |
评估结果 JSON 输出路径 |
--eval_type |
评估指标,逗号分隔;可带 分类-/回归- 前缀 |
--model_type |
classify 或 regression |
- 镜像:
ccr.ccs.tencentyun.com/cube-studio/model_evaluation:20230801(核对model_evaluation/build.sh)。 - 注意:真实/预测数据集需按行一一对应且无缺失;列名要与各自 CSV 完全一致;分类指标配
classify、回归指标配regression,否则结果无意义。
offline-predict(RabbitMQ 分布式离线推理)
面向大规模离线推理:多个 Worker 并行消费同一份数据源,对每条数据执行模型推理;适合「数据量大、单条耗时、需水平扩展」的场景(核对 launcher-rabbitmq.py、predict_model.py、user_code_demo.py)。
整体架构
- 调度层:
launcher-rabbitmq.py用 Volcano Job(batch.volcano.sh/v1alpha1,queue=default,minAvailable=num_worker)在 K8s 拉起一组 Worker Pod,用stern跟踪日志,按队列消费情况与 Job 状态判断结束;同时拉起一个单机 RabbitMQ Pod+Service(镜像rabbitmq:3.9.12-management,端口 5672/15672,默认账号admin/admin)。 - 任务协调层:RabbitMQ 做任务队列(
predict_model.py):- exchange
predict-exchange(topic),queuepredict-queue,routing keypredict-key,消息持久化,prefetch_count=1保证负载均衡。
- exchange
- 角色划分(
predict_model.py:277-298):VC_TASK_INDEX==0 且 LOCAL_RANK==0:唯一生产者,执行datasource()把数据逐条送入队列,再wait_finish()等待队列消费完。- 其他进程(其他 Pod / 其他
LOCAL_RANK):消费者,从队列取消息执行predict(value)后 ack。 - 本地无
VC_TASK_INDEX时退化为单进程:直接遍历datasource()逐条predict()。
用户只需实现两个方法
继承 Offline_Predict(来自与算子同目录的 predict_model.py),实现:
datasource():返回待推理条目列表(如路径字符串列表),仅生产者调用。predict(value):单条推理逻辑。
# your_code.py
import os, numpy
from predict_model import Offline_Predict # 公司内部可改 from di.cube.offline_predict_model import Offline_Predict
class My_Offline_Predict(Offline_Predict):
def __init__(self):
import tensorflow as tf
self.model = tf.saved_model.load('/mnt/xx/your_model_path/')
def datasource(self):
with open('/mnt/xx/list.txt') as f:
return [l.strip() for l in f.readlines()]
def predict(self, value):
return self.model(numpy.load(value))
if __name__ == '__main__':
My_Offline_Predict().run() # run() 内部据 VC_TASK_INDEX/LOCAL_RANK 自动选生产者/消费者
启动脚本 start.sh 负责装依赖并按 LOCAL_RANK 启多个进程(单机内多进程提利用率):
pip install pika requests numpy psutil --index-url https://mirrors.aliyun.com/pypi/simple
for index in $(seq 0 2); do
{ export LOCAL_RANK=$index; python your_code.py; } &
done
wait
Launcher 启动参数
launcher-rabbitmq.py 接收(launcher-rabbitmq.py:493-497):
| 参数 | 说明 | 默认值 |
|---|---|---|
--working_dir |
Worker 工作目录(需能访问代码与数据,如 /mnt/{{creator}}/...) |
空 |
--command |
Worker 启动命令,通常 bash start.sh |
空 |
--num_worker |
Volcano Job 的 Worker Pod 数(其中一个兼任生产者) | 3 |
--image |
Worker 运行镜像(可与 Launcher 镜像不同) | ubuntu:18.04(注册模板时常配 ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.9) |
- Launcher 镜像:
ccr.ccs.tencentyun.com/cube-studio/offline-predict:20230801,ENTRYPOINT ["python3","launcher-rabbitmq.py"]。 - 建议环境变量(任务模板内):
NO_RESOURCE_CHECK=true、TASK_RESOURCE_CPU=4、TASK_RESOURCE_MEMORY=4G、TASK_RESOURCE_GPU=0、TASK_RESOURCE_RDMA=0。 - 账号:提交 K8s/Volcano 资源使用
kubeflow-pipeline账号。
关于命名:平台编排界面里此模板显示为 model-offline-predict,实际算子代码就是 offline-predict 目录;空目录
model_offline_predict已废弃跳过。其面向使用者的操作说明见 05-任务模板/模板使用/README.md(08-模型服务化.md)。
本篇为知识库导航/核对稿,具体参数与行为以各算子源码(job-template/job/...)为准。