Skip to main content

mlflow-tcdeploy-plugin

PyPI version Python License: MIT

腾讯云模型服务部署插件 —— 将腾讯云 WeData 在线推理服务对接为 MLflow Deployments 后端。

mlflow-tclake-plugin(Model Registry)配套使用:

插件 职责 后端
mlflow-tclake-plugin 模型注册与版本管理 TCLake
mlflow-tcdeploy-plugin 模型在线部署与推理 腾讯云 WeData 推理服务

目录


特性

  • ✅ 完整的 MLflow Deployments 生命周期:创建 / 更新 / 删除 / 查询 / 列举
  • ✅ 在线推理调用(predict
  • ✅ 实例规格查询(直连 TIone SDK)
  • ✅ Pod 运维:日志查看、Pod 重启、调试 Shell
  • ✅ 三段式 Model URI 解析(models:/Catalog.Schema.Model/Version
  • ✅ 自动 TC3 请求签名
  • ✅ SSRF 防护:endpoint 域名白名单 + 请求路径严格校验
  • ✅ snake_case ↔ PascalCase 自动转换

架构

┌─────────────────────────────────────────────────────┐
│  用户代码                                            │
│  client = get_deploy_client("tcdeploy")             │
│  client.create_deployment(...)                      │
└──────────────────┬──────────────────────────────────┘
                   │
    ┌──────────────▼──────────────┐
    │  TcDeploymentClient         │  ← MLflow BaseDeploymentClient
    │  (client.py)                │
    │  - 参数校验 / SSRF 防护     │
    │  - snake_case ↔ PascalCase  │
    └──────────────┬──────────────┘
                   │
    ┌──────────────▼──────────────┐
    │  ModelServiceApiClient      │  ← 封装 WeData 云 API
    │  (api_client.py)            │
    │  - TC3 签名 (AbstractClient)│
    │  - 错误码 → MlflowException │
    └──────────────┬──────────────┘
                   │ HTTPS (TC3-HMAC-SHA256)
    ┌──────────────▼──────────────┐
    │  WeData API                 │
    │  (tencentcloudapi.com)      │
    └─────────────────────────────┘

核心模块说明:

模块 文件 说明
Client client.py 实现 BaseDeploymentClient,对外暴露所有操作方法
API Client api_client.py 封装 WeData / TIone 云 API 调用,继承腾讯云 SDK 的 AbstractClient 实现 TC3 签名
Config config.py 环境变量 / 参数配置管理,含 endpoint 域名白名单校验
Models models.py 请求体构建(Create/Update)、Model URI 解析、大小写转换

安装

pip install mlflow-tcdeploy-plugin

依赖:

  • mlflow >= 3.10.0, < 3.11.0
  • tencentcloud-sdk-python >= 3.0.1478
  • Python >= 3.10

配置

插件通过环境变量获取配置(通常由 wedata-pre-execute 自动注入),也支持构造时直接传参:

环境变量 说明 必填 默认值
KERNEL_WEDATA_CLOUD_SDK_SECRET_ID 腾讯云 SecretId
KERNEL_WEDATA_CLOUD_SDK_SECRET_KEY 腾讯云 SecretKey
WEDATA_WORKSPACE_ID WeData 工作空间 ID
KERNEL_WEDATA_REGION 地域 ap-guangzhou
TENCENTCLOUD_ENDPOINT WeData API endpoint wedata.internal.tencentcloudapi.com
KERNEL_WEDATA_CLOUD_SDK_SECRET_TOKEN 临时凭证 Token(STS)
KERNEL_LOGIN_UIN 子账号 UIN
QCLOUD_UIN 主账号 UIN

安全提示TENCENTCLOUD_ENDPOINT 受域名白名单保护,仅允许 *.tencentcloudapi.com*.tencentcloud.com 后缀。


快速上手

from mlflow.deployments import get_deploy_client

# 初始化客户端(自动读取环境变量)
client = get_deploy_client("tcdeploy")

# 1. 查询可用规格
specs = client.list_instance_types(spec_type="CPU")
available = [s for s in specs if s["available"]]
print(available[0]["spec_name"])  # e.g. "TI.SA5.2XLARGE32.POST"

# 2. 创建部署
result = client.create_deployment(
    name="my-service",
    model_uri="models:/default.default.MyModel/1",
    config={
        "instance_type": "TI.SA5.2XLARGE32.POST",
        "replicas": 1,
    },
)
print(result["service_id"])

# 3. 查询部署详情(name 传入的是 ServiceId,非服务名称)
info = client.get_deployment(name="svc-xxxx")
print(info["status"])

# 4. 在线推理
response = client.predict(
    deployment_name="grp-xxxx",
    inputs={"text": "Hello, world!"},
)
print(response)

# 5. 更新部署(扩容到 2 副本,name = ServiceId)
client.update_deployment(name="svc-xxxx", config={"replicas": 2})

# 6. 删除部署(幂等,name = ServiceId)
client.delete_deployment(name="svc-xxxx")

API 参考

⚠️ 重要说明:在 update_deploymentdelete_deploymentget_deployment 等方法中,name 参数传入的是腾讯云 ServiceId(如 svc-xxxx),而不是服务名称。这是因为 MLflow BaseDeploymentClient 接口规范使用 name 作为参数名,但在本插件的上下文中它对应的是 ServiceId —— 服务的唯一标识符。

create_deployment — 创建服务

client.create_deployment(
    name="my-service",                              # 服务名称
    model_uri="models:/Catalog.Schema.Model/1",     # MLflow Model URI
    config={                                         # 部署配置
        "instance_type": "TI.SA5.2XLARGE32.POST",  # 必填:实例规格
        "replicas": 1,                              # 副本数(默认 1)
        "charge_type": "POSTPAID_BY_HOUR",          # 计费模式(默认按量后付费)
        "scale_mode": "MANUAL",                     # 伸缩模式(默认手动)
        "log_enable": False,                        # 是否启用日志
        "authorization_enable": False,              # 是否启用鉴权
        "service_description": "...",               # 服务描述
        "log_config": {...},                        # 日志配置
        "scheduled_action": {...},                  # 定时伸缩配置
        "service_limit": {...},                     # 限流配置
    },
    endpoint="grp-xxxx",                            # 可选:服务组 ID
)

调用的云 APICreateMLModelServices


update_deployment — 更新服务

client.update_deployment(
    name="svc-xxxx",                                # ⚠️ ServiceId(非服务名称)
    model_uri="models:/Catalog.Schema.Model/2",     # 可选:更新模型版本
    config={                                         # 仅发送需更新的字段
        "replicas": 3,
        "instance_type": "TI.SA5.4XLARGE64.POST",
        "service_port": 8080,
        "status": "RUNNING",
    },
)

注意name 参数对应腾讯云的 ServiceId(如 svc-xxxx),而非服务名称。受 MLflow BaseDeploymentClient 接口约束,参数名为 name,但语义上是服务唯一标识。

调用的云 APIUpdateMLModelService(扁平结构,非嵌套 Services 数组)

ServiceAction — 特殊更新行为

config 中可以通过 service_action 字段触发特殊操作。⚠️ 当指定 ServiceAction 时,请求中的其他更新字段会被服务端忽略。

service_action 含义 说明
"STOP" 停止服务 将运行中的服务停止
"RESUME" 重启服务 将已停止的服务恢复运行
"SCALE" 扩缩容 触发服务扩缩容操作

示例:停止服务

client.update_deployment(
    name="svc-xxxx",
    config={"service_action": "STOP"},
)

示例:恢复服务

client.update_deployment(
    name="svc-xxxx",
    config={"service_action": "RESUME"},
)

示例:触发扩缩容

client.update_deployment(
    name="svc-xxxx",
    config={"service_action": "SCALE"},
)

delete_deployment — 删除服务

client.delete_deployment(name="svc-xxxx")  # ⚠️ name = ServiceId;幂等:资源不存在时不报错

调用的云 APIDeleteMLModelService


get_deployment — 查询服务详情

info = client.get_deployment(name="svc-xxxx")  # ⚠️ name = ServiceId
# info 是 snake_case 字典
print(info["status"], info["service_name"])

调用的云 APIGetMLModelService


list_deployments — 列举服务组

# 列举所有服务组
groups = client.list_deployments()

# 按服务组 ID 过滤
groups = client.list_deployments(endpoint="grp-xxxx")

# 每个 item 包含 "name" 字段(= ServiceGroupId),符合 MLflow 规范
for g in groups:
    print(g["name"], g["service_group_name"])

调用的云 APIListMLModelServiceGroups


predict — 在线推理

result = client.predict(
    deployment_name="grp-xxxx",        # 服务组 ID
    inputs={"text": "classify this"},  # JSON 可序列化的输入
    endpoint="/v1/predict",            # 可选:相对路径(默认 /predict)
    config={"auth_token": "xxx"},      # 可选:鉴权 Token
)

调用的云 APIModelServiceInterfaceCallTest

endpoint 参数会经过 SSRF 安全校验,防止注入恶意 URL。


list_instance_types — 查询可用规格

# 全部规格
all_specs = client.list_instance_types()

# 仅 GPU 规格
gpu_specs = client.list_instance_types(spec_type="GPU")

# 返回结构
# [{"spec_name": "TI.SA5.2XLARGE32.POST", "spec_alias": "...",
#   "spec_type": "CPU", "available": True, "available_region": [...],
#   "gpu_type": ""}]

调用的 SDK:直连 TIone SDK DescribeInferenceSpecs


debug_pod_shell — 调试 Pod

shell_info = client.debug_pod_shell(
    service_id="svc-xxxx",
    pod_name="ms-xxxx-0",
)
# 返回 WebShell URL 等信息

调用的云 APICreateModelServicePodUrl


restart_pod — 重启 Pod

result = client.restart_pod(
    service_id="svc-xxxx",
    pod_name="ms-xxxx-0",
)
print(result["request_id"])

调用的云 APIRebuildModelServicePod


get_pod_logs — 查询 Pod 日志

result = client.get_pod_logs(
    service_id="svc-xxxx",
    pod_name="ms-xxxx-*",              # 支持通配符
    limit=100,                          # 最大条数
    start_time="2026-03-10T00:00:00+08:00",
    end_time="2026-03-10T23:59:59+08:00",
    context=None,                       # 翻页 token
)

for log in result["logs"]:
    print(f"[{log['timestamp']}] {log['pod_name']}: {log['message']}")

# 翻页
next_page = client.get_pod_logs(service_id="svc-xxxx", pod_name="ms-xxxx-*", context=result["context"])

调用的云 APIListMLServiceLogs


Model URI 格式

本插件使用 三段式 Model URI:

models:/CatalogName.SchemaName.ModelName/Version
  • CatalogName:目录名(如 default
  • SchemaName:Schema 名(如 default
  • ModelName:模型名称
  • Version:模型版本号

示例:models:/default.default.MyTextClassifier/3

当提供 api_client 时,插件会调用 ListModelVersions 自动解析模型的 IdModelPath

也支持 runs:/ 格式的 URI,此时直接将 URI 作为 ModelPath 传递。


安全机制

Endpoint 域名白名单

config.py 中对 API endpoint 实施域名白名单校验:

  • 仅允许 *.tencentcloudapi.com*.tencentcloud.com 后缀
  • 拒绝包含 scheme(https://)、路径(/api)、@ 等非法格式
  • 防止通过篡改 TENCENTCLOUD_ENDPOINT 环境变量将请求导向恶意服务器

请求路径 SSRF 防护

predict 方法的 endpoint 参数经过严格校验(_validate_relative_url):

攻击向量 示例 防御方式
绝对 URL 注入 http://evil.com 检测 ://
Protocol-relative //evil.com 检测 //\ 开头
Percent-encoded 绕过 %2f%2fevil.com unquote 解码再校验
@ host-override /legit@evil.com 拒绝含 @ 的路径
路径遍历 /../internal-api 逐段检测 .. 并拒绝
CRLF / null-byte 注入 /predict\r\nHost: evil 正则匹配控制字符

项目结构

mlflow-tcdeploy-plugin/
├── mlflow_tcdeploy_plugin/
│   ├── __init__.py          # 版本号
│   ├── client.py            # TcDeploymentClient (MLflow Deployments 接口实现)
│   ├── api_client.py        # ModelServiceApiClient (WeData 云 API 封装)
│   ├── config.py            # TcDeployConfig (环境变量配置 + endpoint 安全校验)
│   └── models.py            # 请求体构建、Model URI 解析、大小写转换
├── tests/
│   ├── test_client.py       # Client 层单元测试 (含 SSRF 防护测试)
│   ├── test_api_client.py   # API Client 层单元测试
│   ├── test_config.py       # 配置层单元测试 (含 endpoint 白名单测试)
│   └── test_models.py       # 模型层单元测试 (Create/Update 请求构建)
├── setup.py                 # 打包配置
├── build.sh                 # 构建 & 发布脚本
├── LICENSE.txt              # MIT License
└── README.md                # 本文件

开发

# 克隆并进入项目
cd mlflow-tcdeploy-plugin

# 创建虚拟环境
python3 -m venv .venv
source .venv/bin/activate

# 安装开发依赖
pip install -e ".[dev]"

# 运行单元测试
pytest tests/ -v

# 构建 & 发布
bash build.sh

License

MIT License — Tencent WeData Team

Release files for mlflow-tcdeploy-plugin 1.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mlflow-tcdeploy-plugin 1.0.3
File Size Uploaded
mlflow_tcdeploy_plugin-1.0.3.tar.gz 28.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mlflow-tcdeploy-plugin 1.0.3
File Interpreter ABI Platform
mlflow_tcdeploy_plugin-1.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 56.3 kB

Release files / mlflow_tcdeploy_plugin-1.0.3.tar.gz

Download URL mlflow_tcdeploy_plugin-1.0.3.tar.gz
Size 28.7 kB
Tags Source
SHA-256 checksum
How to use checksums
fc92c58f2cb2b17802e4522ad59cffcce22f930bd3fb898d5fb7c826859ad128
BLAKE2b-256 checksum
How to use checksums
a5b9a76eb77e94d4692bc7172db4772f55e777d480bcc1734ec4a5f83b4da513
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / mlflow_tcdeploy_plugin-1.0.3-py3-none-any.whl

Download URL mlflow_tcdeploy_plugin-1.0.3-py3-none-any.whl
Size 27.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e69a357a4e861ce392c53180e6e92940e3b1d39110339ab79bfd9a36732905e2
BLAKE2b-256 checksum
How to use checksums
d4f8ac3c3e861eb278bdd64f1758c115cd9d6a50ccf4ae184b5b8bc2a989c5ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release history Release notifications | RSS feed

This release

1.0.3 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page