Skip to main content

Tencent Cloud deployment plugin for MLflow

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mlflow_tcdeploy_plugin-1.0.2.tar.gz (28.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mlflow_tcdeploy_plugin-1.0.2-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

Details for the file mlflow_tcdeploy_plugin-1.0.2.tar.gz.

File metadata

  • Download URL: mlflow_tcdeploy_plugin-1.0.2.tar.gz
  • Upload date:
  • Size: 28.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for mlflow_tcdeploy_plugin-1.0.2.tar.gz
Algorithm Hash digest
SHA256 1e554c58df8ed4f21d13604d4b1bc6b0440cbd6b781091d407e8c5804b7a3f60
MD5 6190145b3d5f20e536d51e784248564b
BLAKE2b-256 6509e5fbfaaaf1eed14a75d07da78bb65ec885d7cf8d518cf362884cacf4cb89

See more details on using hashes here.

File details

Details for the file mlflow_tcdeploy_plugin-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for mlflow_tcdeploy_plugin-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 42074a0e53f6b7e8ec793047780b2214d9815d067de82f121dbc668001ece55f
MD5 1572fac65ac3f51017b4d2da646115e2
BLAKE2b-256 c31badf0a6eb9e409c1308ed66bdaefc73f4751b3b7855f83a5188159e3ee1df

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page