模型管理与推理服务

把训练好的模型注册、发布成在线推理服务,配置域名/IP 访问、端口、灰度分流、弹性伸缩、资源与镜像时阅读

平台使用 / 服务化与推理
模型管理模型注册model-register推理服务inference serviceserving模型发布部署测试部署生产域名访问ip portSERVICE_DOMAINSERVICE_EXTERNAL_IPINFERENCE_PORT灰度升级流量分流

模型管理与推理服务

实现源码:模型/推理服务模型 myapp/models/model_serving.py,推理服务视图 myapp/views/view_inferenceserving.py,端口/域名配置 myapp/config.py

模型管理

在"模型管理"中添加模型

模型管理可记录模型所属的项目组、模型版本、算法框架等关键信息,可进行模型的版本管理。在"服务化"-"模型管理"-"添加模型"可添加模型,在每个模型的"更多"中,可以查看更多详情,也可以删除和修改模型信息。

模型管理列表

添加模型

通过 pipeline 中的"模型注册"模板添加模型

除了手动在模型管理中添加模型,还可以在模型训练的 pipeline 中,通过"模型服务化"类别下的 model-register 模板来自动注册模型,将模型元数据添加到"模型管理"中来。

子模型

如果在模型管理中注册的 模型地址 填写的为 json 格式,那么表示该模型是由多个子模型构成。每个 key 都表示一个子模型,这种情况下,模型拉取时可以直接拉取子模型。

模型指标

模型指标可填写字符串或者 json 格式,json 格式时,在 list 列表页面展示的时候会展开成 key1=value1,key2=value2 的格式。


推理服务

服务发布

想要将模型发布成推理服务,可以分两步:

  1. 在"模型管理"中添加模型,并且点击"发布",自动为模型创建推理服务,或者在"推理服务"中,手动添加服务;
  2. 在"推理服务"中,点击已发布的推理服务的"部署测试",将模型部署到测试环境,测试通过后,点击"部署生产",将模型部署到生产环境。

发布推理服务

推理服务列表

推理服务类型

service_type 当前支持以下类型(见 myapp/views/view_inferenceserving.py:214,实际可见类型还会被全局配置 ENABLE_INFERENCE 过滤):

servingml-servertfservingtorch-servertriton-servervllmvllm-distributedtriton-llmollamamindiemindie-distributed

其中 tfserving / torch-server / triton-server 等可做到 0 代码推理发布(自动生成配置/端口/环境变量);serving 为自定义镜像服务(见下文"自定义镜像服务");vllm / triton-llm / ollama / mindie 等用于大模型推理。

域名访问

第一种方式:公司申请泛域名,并将泛域名解析地址配置到 svc/istio-ingressgateway 的服务地址上。通过域名访问,在 istio-ingressgateway 中进行转发到对应的服务上。

第二种方式:配置本地 host 文件,以产生域名解析的效果,不过因为这种方式需要在每个人电脑上配置,所以仅适用于测试。

第三种方式:客户端的请求中在 header 中配置 Host,istio-ingressgateway 检测 http 请求中的 Host 来进行转发。不过这种方式需要侵入性修改客户端请求,适用于仅提供 api 的下层服务。

流量流向:客户端 -> istio-ingressgateway(VirtualService)-> k8s service -> k8s pod。

泛域名的配置:config.py 中配置 SERVICE_DOMAIN 变量为泛域名后缀。

注意:SERVICE_DOMAINmyapp/config.py:1378 与各集群 CLUSTERS[*].SERVICE_DOMAIN(如 config.py:1408)默认值为 service.svc.cluster.local(集群内域名)。文中"例如 local.com""*.cube-studio.local.com"等仅为对外泛域名示例,实际泛域名后缀以你的部署配置为准。

ip:port 访问

平台会为每个 Service / 推理服务 / Notebook 生成一个 ip:port 形式的访问入口。

代理 IP 的取值优先级(从高到低,见 myapp/views/view_inferenceserving.py:1635-1663myapp/models/model_serving.py:382-413):

  1. 项目组扩展字段 expand 里配置的 SERVICE_EXTERNAL_IP
  2. 集群配置 CLUSTERS[$env].HOST
  3. 全局配置 SERVICE_EXTERNAL_IP
  4. 浏览器访问时的 request.host(仅当是合法 IP)

SERVICE_EXTERNAL_IP 支持 ["内网IP|外网IP"] 这种写法:

  • 用于 k8s service 代理绑定(externalIP)时取 | 左侧(内网 IP,见 view_inferenceserving.py:1667,注释"代理需要配置内网 ip");
  • 用于界面展示 / 对外访问 URL 时取 | 右侧(外网 IP/域名,见 model_serving.py:112156split('|')[-1])。

端口规则(以 myapp/config.py 为准,可被修改,见 config.py:1105-1107):

  • Notebook:NOTEBOOK_PORT,默认 10000+2*ID
  • 内部服务(Service):SERVICE_PORT,默认 30000+2*ID
  • 推理服务(InferenceService):INFERENCE_PORT,默认 20000+2*ID

ID 为对应资源的数据库 id。开放两个端口时,第二个端口取第一个端口之后首个未被屏蔽的端口,见 core.get_not_black_port。)

注意:代码中 conf.get('INFERENCE_PORT', '20000+10*ID') 的硬编码兜底为 20000+10*IDview_inferenceserving.py:1668model_serving.py:384),仅在 config 未设置该项时生效;随仓库发布的 config.py 已设为 20000+2*ID。请以 config.py 实际取值为准。

流量流向:客户端 -> k8s service external ip -> k8s pod。

版本/域名/pod/ip 的关系

$服务名 = $模型名-$模型版本(版本会做归一化处理)

推理服务的 name 会根据 model_namemodel_version 生成:把 model_name 中的 / : . 替换为 -model_version 中的 v . : 去掉后用 - 拼接,截断到 60 字符并把 _ 换成 -(见 view_inferenceserving.py:608764-787),用于生成 k8s deployment/service 等资源名。

服务名归一化
  • $k8s-deployment名称 = $服务名
deployment
  • $k8s-hpa名称 = $服务名,在最大最小副本数不一致时创建 hpa
  • $k8s-service名称 = $服务名 用于域名的代理
  • $k8s-service名称 = $服务名-external 用于 ip 的代理
  • $ip:port = $代理服务ip:(INFERENCE_PORT 按 id 计算) ,端口取值见上文"端口规则"

资源关系

系统自带域名

需要泛域名支持,这里假设泛域名为 *.cube-studio.local.com

  • 生产域名:http://$服务名.service.cube-studio.local.com
  • 测试环境域名:http://test.$服务名.service.cube-studio.local.com
  • 调试环境域名:http://debug.$服务名.service.cube-studio.local.com

自定义域名

用户可通过 host 字段配置服务的访问域名:

  1. 配置域名,会使用该域名作为 istio-ingressgateway 的代理;
  2. 配置 url,会使用其中的域名作为代理,但是打开域名自动进入完整的 url;
  3. 配置 url path,自动生成域名,但是打开会自动进入完整 url。

多个服务可以配置相同的域名,相同域名的服务只能有一个在线,最新发布的模型会接替同域名的其他模型服务。

流量复制和分流

多个服务(可以是相同模型或者不同模型间)配置相同的域名:

  1. "分流"字段控制分配多少流量到其他服务上,剩余流量归属于当前服务;
  2. "流量复制"字段控制复制多少流量到其他服务上,但只会将当前服务的响应返回给客户端。

流量分流

灰度升级

  1. 同一个服务灰度升级,只需要修改服务的配置,重新部署,服务会自动滚动升级 pod;
  2. 不同服务进行灰度升级(比如同一个模型的不同版本之间),多个服务使用相同的域名,新部署的服务上线正常后,会自动下线同域名的旧服务。

弹性伸缩容

"弹性伸缩容"字段可配置触发条件,可使用自定义指标,使用其中一个或多个指标,示例:cpu:50%,mem:50%,gpu:50%

服务优先级

"优先级"字段可配置服务优先级,优先满足高优先级的资源需求。

sidecar

通过"Sidecar"字段配置,通过 sidecar 的配置,推理服务将自动添加伴随容器,使得 IP 形式访问的推理服务也能获得负载统计数据。

环境变量

系统会向推理服务容器注入以下环境变量(见 view_inferenceserving.py:1122-1136):

KUBEFLOW_ENV=<test/debug/...>     # 当前部署环境
KUBEFLOW_MODEL_PATH=
KUBEFLOW_MODEL_VERSION=
KUBEFLOW_MODEL_IMAGES=
KUBEFLOW_MODEL_NAME=
KUBEFLOW_INFERENCE_ID=            # 推理服务 id
KUBEFLOW_RUN_ID=                  # 本次部署随机 id
RESOURCE_CPU=
RESOURCE_MEMORY=
RESOURCE_MIN_REPLICAS=
RESOURCE_MAX_REPLICAS=
RESOURCE_GPU=
MODEL_PATH=
MODEL_NAME=
INFERENCE_NAME=

以及由 k8s downward API 注入的 pod 信息(见 myapp/utils/py/py_k8s.py:1122-1126):

K8S_NODE_NAME=        # spec.nodeName
K8S_POD_NAMESPACE=    # metadata.namespace
K8S_POD_IP=           # status.podIP
K8S_HOST_IP=          # status.hostIP
K8S_POD_NAME=         # metadata.name

内存、CPU、GPU、VGPU

推理服务中,允许用户调整推理服务的内存、CPU、GPU 占用以及选择 GPU 卡型。其中 GPU 的占用支持独占、共享、VGPU。可以设置 GPU 占用方式为虚拟 GPU,比如设置 GPU 时填写 0.2(T4),表示一个推理服务占 0.2 张 T4 卡,从而实现单卡上部署多个推理服务的 pod。

GPU/VGPU 配置

推理服务的内存、GPU、CPU 都可以在"更多"中修改。

配置文件,启动目录,启动命令

  1. 配置文件以 configmap 形式挂载进去,挂载到容器 /config/ 目录下。留空时将被自动重置,格式:
---文件名
多行文件内容
---文件名
多行文件内容

配置文件

代码中需要读取 /config 目录下挂载进去的文件。

  1. 启动目录和启动命令会覆盖镜像中的启动目录和命令。注意如果之前的环境中使用 ~/.bashrc 进行了环境初始化,在使用 k8s 时不存在这个文件,需要在代码中手动 source 环境。

端口

端口最多只能设置 2 个,用逗号分隔,比如 PORT1,PORT2

端口配置

开放的端口会启动两种代理方式:

  1. 通过配置的泛域名生成的服务域名进行访问:第一个端口由 istio-ingressgateway 的 80 端口代理,第二个端口由 istio-ingressgateway 的 8080 端口代理。访问地址为 service1.example.oa.com:80service1.example.oa.com:8080
  2. 生成 ip 和端口的访问形式 xx.xx.xx.xx:EXPORT_PORT1xx.xx.xx.xx:EXPORT_PORT2,其中 EXPORT_PORT1/EXPORT_PORT2 按上文"端口规则"中的 INFERENCE_PORT(默认 20000+2*ID)及其后续未屏蔽端口计算。

指标

请求指标采集,配置端口 + url,示例:8080:/metrics

按照 prometheus 采集数据的要求提供 /metrics,然后在此处配置端口和地址,配置后会自动被 prometheus 采集,需要自行配置看板,解析自己的指标进行查看。

健康检查

需要业务在代码中提供可用于健康检查的接口,用于阻隔损坏的容器或重启损坏的容器。接口返回 200 表示正常,其他会阻隔流量或重启容器。检查周期为 60s。

调试环境/测试环境/生产环境

三者的主要区别:

  1. 调试环境会重置启动命令为 sleep infinity,会自动进入命令行,自己手动启动命令,查看日志;
  2. 调试环境和测试环境不会启动 hpa;
  3. 调试环境会自动在生产环境域名前添加 debug.,测试环境会自动在生产环境域名前添加 test.

服务负载监控

在每个推理服务后面点击监控按钮,可以查看每个服务的资源使用和流量负载情况。

服务负载监控

自定义镜像服务

往往后端推理服务需要特殊的业务处理逻辑。这个时候我们可以选择 serving 类型的推理服务,自己配置镜像和其他参数。

tfserving / torch-server / triton 的服务类型也可以修改镜像名,但是其他的配置(比如配置文件、端口、环境变量等)会自动生成,以实现 0 代码推理发布的目的。

服务测试

可以在推理服务列表对已部署的服务发起测试。

服务测试

大模型(LLM)测试使用对话界面;ml-servertfservingtorch-servertriton-server 类型测试会打开 notebook,使用测试脚本测试(见 view_inferenceserving.py:2111 起的测试接口)。


推理框架导航

不同推理框架的 0 代码发布细节、模型目录约定与测试方式,可参考本目录下各专题文档:

onnxruntime 暂无独立专题文档;开源仓库 wiki 总览见 https://github.com/data-infra/cube-studio/wiki/%E6%A8%A1%E5%9E%8B%E6%8E%A8%E7%90%86

大模型 OpenAI 兼容网关的认证、限流等见同目录 服务网关.md

最后更新 2026-06-30完整文档以官方仓库为准:GitHub Wiki