Together AI Blog

Configuring Dedicated Model Inference

8.5内容质量

TL;DR · AI 摘要

Together AI平台通过端点/部署/配置三元组与容量感知路由实现模型推理配置,支持零停机变更和流量实验。

核心要点

  • 配置由端点(固定身份)、部署(模型+硬件组合)、配置(运行配方)三部分构成
  • 权重×就绪副本数决定流量分配,确保每副本负载均衡而非流量均分
  • 部署可丢弃设计支持零停机变更,通过绑定0/0副本数实现停止

结构提纲

按章节快速跳转。

  1. 端点/部署/配置构成基础架构,通过容量感知路由实现动态绑定

  2. 配置定义不可变运行配方,部署绑定模型与自动扩展策略,端点管理流量分割

  3. 权重×就绪副本数计算有效容量,实现动态负载均衡和自动扩展

  4. 通过调整部署权重实现A/B测试、影子实验、零停机变更等场景

  5. 所有实体通过proj_/ml_/cr_/dep_等前缀实现自文档化标识

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • 专用模型推理配置
    • 架构三元组
      • 端点(固定身份)
      • 部署(模型+硬件)
      • 配置(运行配方)
    • 核心机制
      • 容量感知路由
      • 权重×就绪副本计算
    • 高级功能
      • A/B测试
      • 影子实验
      • 零停机变更

金句 / Highlights

值得收藏与分享的关键句。

#模型推理#部署配置#流量管理#AI平台
打开原文

配置专用模型推理

概览

Together AI 平台上的专用模型推理包含三个部分:端点(您或您的客户调用的稳定名称)、部署(在端点后运行副本的具体模型 + 硬件组合)和配置(模型运行方式的配方)。一个容量感知的流量分割将这三个实体联系在一起。这种架构使得各种其他功能成为可能,例如发布、A/B 测试、影子实验、零停机时间更改等。下面我们将展示容量感知路由如何在具有测量流量的实时端点上工作。

资源模型的工作原理

  • 配置是一种配方,用于指定引擎、GPU 类型和数量以及并行性和优化配置文件(吞吐量、延迟、平衡)。配置是不可变的,每个配置都有一个类似 cr_... 的 ID。您的部署始终指向经过测试的配置。
  • 部署将一个模型(特定修订版)绑定到一个配置,为其分配一个自动扩展策略,并运行副本。部署按设计是临时的,创建和销毁应被视为常规操作。
  • 端点是一个固定身份:一个限定名称(<project_slug>/<endpoint_name>),您的应用程序在普通推理 API 中将其作为模型参数传递。端点有一个流量分割,用于确定其部署上的请求路由。

理解这一点的一个简单方法是通过 ID,系统中的每个 ID 都通过前缀告诉您它是什么,这使得日志和脚本具有自文档功能:proj_(项目)、ml_(模型)、cr_(配置版本)、endpoint_、dep_(部署)、rol_(发布)。

平台上的每个高级操作都只是“添加一个部署,并为其分配流量路由权重”。A/B 测试是具有群体分配的部署。影子实验是一个权重为零的部署,接收镜像流量。停止部署是将最小和最大副本数绑定到 0/0。

基于权重的流量分割

流量分割是一个包含 {deployment_id, weight} 条目的列表,其中权重是每个就绪副本的 路由器计算每个部署的有效容量为 weight × ready_replicas,并按此容量进行比例路由。

通过上面的图表进行说明:两个部署的权重都是 1,但部署 A 有 1 个就绪副本(容量 1),部署 B 有 3 个(容量 3),因此流量按照 25%/75% 的比例分配。相等的权重意味着每个副本的负载相等,而不是流量份额相等。

我们这样设计是因为它使路由和扩展成为同一对话:

  • 自动扩展可以免费组合。当部署 A 从 1 个副本扩展到 3 个时,其容量增加三倍,并自动吸收成比例更多的流量。使用简单的百分比,一个固定在“25%”的部署在扩展时会饱和,在扩展时会处于空闲状态。
  • 每个副本的负载是您控制的。权重 1 与权重 2 表示“B 的每个副本应比 A 的每个副本多工作两倍”。
  • 未就绪的副本不计入计算。一个正在冷启动或降级到 0 个就绪副本的部署贡献零容量,因此流量流向实际可以服务的部分。

权重是正数,没有总和限制,因此 0.7/0.3 和 700/300 描述相同的路由。如果您希望无论副本数量如何都固定流量份额,可以设置 A/B 测试群体,允许整数百分比总和为 100%。

设置分割只需一个 PATCH 请求,使用字段掩码:

code
tg beta endpoints update $DEPLOYMENT_A --traffic-weight 1
tg beta endpoints update $DEPLOYMENT_B --traffic-weight 1

# 将某个部署移出流量分配但不缩减规模
tg beta endpoints update $DEPLOYMENT_B --traffic-weight 0
code
⚠️ 重要
全新部署在出现在端点的流量分配中之前不会获得任何流量。如果你创建了一个端点和部署并标记为 `READY`,发送请求却收到 `routing_error`,很可能是因为未指定流量分配且路由器尚未被告知该部署应接收流量。CLI 的 `tg beta endpoints deploy` 会为你设置分配比例,这也是为什么快速入门"开箱即用",而原始 API/SDK 路径需要手动设置的原因。

内部机制:选择配置

你无需从零开始编写配置。支持模型目录中的每个模型都附带了经过验证的部署配置文件,这些是经过基准测试并持续优化的认证模型+配置组合:

code
tg beta models public zai-org/GLM-5.2 --json | jq '.data[0].deploymentProfiles[]'

# 或者在获取模型ID后,直接列出其可部署配置:
tg beta models configs ml_CcEtnFUbitJYNja6TTR6U
code
{
  "profileId": "profile-cabcbcec874c",
  "certifiedConfigRevisionId": "cr_Cd35DNpQuHM3RihtCkN59",
  "certifiedModelRevisionId": "rv_CcEuPu4Gk6c4M7v4PTYuG",
  "gpuType": "NVIDIA-B200",
  "gpuCount": 4,
  "quantization": "FP4",
  "performanceBenchmarks": {},
  "config": "projects/proj_CbdXDuLRFhUPv1mGfxwUc/configs/cr_Cd35DNpQuHM3RihtCkN59",
  "model": "projects/proj_CbdXDuLRFhUPv1mGfxwUc/models/ml_CcEtnFUbitJYNja6TTR6U/revisions/rv_CcEuPu4Gk6c4M7v4PTYuG",
  "parallelism": "TP4"
}

你可以将模型和配置资源名称复制到部署创建命令中:

code
tg beta endpoints deploy zai-org/GLM-5.2 \
  --endpoint my-glm-endpoint \
  --config cr_Cd35DNpQuHM3RihtCkN59 \
  --traffic-weight 1

在选择配置时,选择器会告诉你每个配置方案优化了哪些指标:

选择器

对应的权衡

accelerator_type

H100, H200, B200, …

成本 vs 内存带宽 vs 可用性

accelerator_count

1, 2, 4, 8

模型 + KV缓存的容量适配

optimization

latency / throughput / balanced

基础服务的权衡(见下文)

topology

例如 aggregated/disaggregated

模型在GPU间的分布方式

优化维度是你需要花最多时间选择的参数。

  • 延迟优化配置专注于首字生成时间:使用更小批次、激进调度,每个请求更快获得关注,但会牺牲每GPU的总token/秒。
  • 吞吐优化配置使用更大批次:最大化每GPU小时的总token数,单个请求需要等待更久加入批次。如果是构建交互式聊天应用,建议选择延迟优化;离线流水线和批量摘要可以使用吞吐配置。
  • balanced 是默认推荐选项,适用于同时包含交互和批量请求的流量。

配置是不可变的,因为 cr_ 版本从不更改,即部署行为不会因为有人"随意修改共享配置的某个标志"而漂移。任何变更都会产生新版本;旧版本仍作为有效、经过测试的回滚目标存在。此处也可以触发推测解码,因为草稿模型是配置的属性。

特殊情况

  1. 部署在流量分配中但没有可用副本。

因为容量 = 权重 × 0 = 0,所以不会收到任何流量;其他部署会吸收这部分流量。当副本恢复后,流量会自动且按比例重新分配。

  1. 我可以删除仍在流量分割中的部署吗?

应先将其从分割中移除,然后再删除。拆除流程包括:排空流量 → 停止 → 删除,API 会引导你按照这个顺序操作。

  1. 流量分割 vs. A/B 成员百分比 vs. 金丝雀发布步骤百分比

流量分割权重(基于容量的稳定状态路由)、A/B 成员百分比(整数群体份额,总和为 100 且与副本数量无关)、金丝雀发布步骤百分比(发布过程的过渡时间表)。这三种工具分别用于不同场景,按固定顺序组合使用:首先路由根据权重分割(通过容量选择候选部署),然后 A/B 实验若候选部署是对照组会重新抽样(将对照组份额细分到各实验组),接着若候选部署是发布源则根据当前步骤百分比重新抽样(在源和目标之间分割),最后在胜出部署中选择集群。发布流程会代表你管理各阶段的转换。

  1. 客户端使用的名称是什么?

类似 <project_slug>/<endpoint_name> 的端点可通过标准推理 API 的模型字符串参数传递。即使你选择执行发布、更换硬件或运行 A/B 测试,这个名称始终保持不变。

展示容量感知路由的实验

我们针对一个实时端点进行了测试,使用两个单 H100 部署来演示权重模型的流量分割效果。两个部署权重均为 1,初始各有一个可用副本。我们发送了 599 个带标签的请求并记录每个请求的服务部署,随后将 A 从 1 个副本扩展到 2 个副本并发送了 599 个更多请求,各部署观察到的路由情况如下:

阶段

副本数(A : B)

预期份额

实际份额

样本量 n

1

1 : 1

50 / 50

47.6 / 52.4

599

2

2 : 1

66.7 / 33.3

69.4 / 30.6

由于路由遵循容量,而容量又取决于副本数量。在部署 A 内部,其两个 Pod 各承载了约 30-40% 的总流量(39.6% 和 29.9%),路由器也会在 Pod 之间进行负载均衡。

为了具体说明性能权衡,我们对演示端点的两个认证配置文件进行了测试,每个配置文件使用 1 个副本,在并发数为 4/8/16 的情况下进行 60 秒闭环测试,生成 200 个 token,数据取自 API 的使用字段:

配置文件

c=4

c=8

c=16

c=16 时 TTFT p95

A · Qwen3.5-9B (BF16, TP1)

362 tok/s

789 tok/s

1,464 tok/s

368 ms

B · Qwen3-VL-8B (BF16, TP1)

495 tok/s

243 tok/s

240 tok/s

323 ms

这张表格充分说明了测量的重要性:B 在低并发时表现优异,但随后急剧下降。A 在并发数从 4 到 16 时吞吐量达到 4 倍,TTFT p95 仅上升约 17%。B 在并发数为 4 时比 A 快,但随后达到饱和:当并发数超过约 4 时,有效请求速率停止增长,总吞吐量减半,每分钟有少量请求开始完全停滞。如果你只在并发数为 4 的情况下进行负载测试,可能会选择 B 来处理高并发工作负载,但直到生产环境中才会发现这种行为。

两种配置方案没有对错之分,它们只是服务前沿上不同的位置,你的模型配置也会有各自的曲线。初始配置为你提供了测试起点的方式;像这样的一个小时扫描可以告诉你哪种配置更符合你的流量需求。

亲自尝试!

仅需五个命令即可完成整个模型部署:

code
# 1. 身份:我是谁 / 我的项目
tg whoami

# 2. 为你的模型选择一个认证配置
tg beta models public --product dedicated

# 3. 一条命令:端点 + 部署 + 流量分配 + 等待
tg beta endpoints deploy $MODEL --endpoint my-endpoint --traffic-weight 1

# 4. 调用它 — 合格名称即为模型字符串
resp = client.chat.completions.create(
model="my-project/my-endpoint",   # 端点的合格名称就是模型字符串
messages=[{"role": "user", "content": "Hello!"}],
)

# 5. 查看你的部署成果
together beta endpoints get $ENDPOINT_ID

从这里开始,本系列的其余内容都只需一次更多部署即可实现。

📚 文档:专用模型推理 → 快速入门 · 概念 · 流量路由