Canary rollouts: upgrade models in production without downtime

TL;DR · AI 摘要
Title: Canary rollouts: upgrade models in production without downtime URL Source: Published Time: 2026-09-22 Markdown Co...
核心要点
- 主题聚焦:Canary rollouts: upgrade models in production wi
- 来源:Together AI Blog,建议结合原文判断细节。
- AI 分析暂不可用,本条为保底评分与摘要。
分阶段流量提升、指标门限和专用推理的自动回滚。


摘要
发布过程通过分阶段步骤将实时流量从当前模型迁移至新检查点。流量迁移前始终执行健康检查;在金丝雀发布中,还可以添加指标门限(如p95延迟或错误率),在每个步骤后执行。如果门限触发,发布会在金丝雀分流处暂停,您可取消并反向执行。以下我们实际演示一个案例:Qwen2.5-7B → Qwen3.5-9B的金丝雀发布,其门限在10%流量时检测到137%的p95延迟回归;我们取消并反向执行了该发布,且所有实时请求均正常处理,没有出现故障。
模型切换是常见实践
如果您在生产环境中运行模型,已经了解需要切换新检查点或新模型系列的必要性:开源模型生态发展迅速,候选模型通常在评估中表现优异或承诺更高的吞吐量。您希望在不出现故障的情况下让每个用户都能使用,同时具备在表现不佳时回滚的能力。通常的选项迫使您做出权衡:
- 硬切换:将端点指向新模型,所有用户一次性暴露。如果p95延迟翻倍,您会从仪表板发现,或者更糟的是从客户处得知,然后在压力下回滚到冷启动的旧模型。
- 自定义分阶段切换:需要第二个部署加脚本,在您监控Grafana时逐步调整流量比例,同时记得在切换流量前将旧部署扩展回来。
这两种选项都依赖人工作为安全机制。发布过程将该机制纳入平台:您只需描述源、目标、步骤以及"健康"的定义,平台将在每个阶段按照此计划执行。
发布过程的工作原理
发布过程在相同端点的两个部署之间迁移流量:源(当前提供服务的模型)和目标(您希望明天提供的模型)。您可以选择以下三种策略之一:
- 金丝雀发布:按您定义的分阶段百分比迁移流量(例如10% → 50% → 100%;默认阶梯为5% → 25% → 50% → 100%),步骤之间有等待期和可选的指标检查。
- 蓝绿部署:一个0% → 100%的门限切换。可以视为单步金丝雀发布。
- 滚动更新:原地逐副本替换,保持总容量不变。在容量受限时最佳,特别是相同模型配置变更且无需流量提升时。
每个金丝雀步骤内部会发生以下过程:

我们刻意选择了这个顺序;每个步骤都能防止特定类型的故障:
- 目标在任何流量移动之前进行扩展。 新部署没有容量意味着没有重定向的请求:发布过程会先暂停。
- 健康检查门在流量转移之前运行。 流量仅到达那些引擎已加载并响应的副本,而不是仅仅启动的副本。
- 传播等待位于转移和排空之间。 在移除任何源容量之前,路由缓存会先收敛。
- 源在流量转移之后进行排空。 上升过程中容量引导流量;下降过程中流量引导容量。
- 等待时间和指标门在步骤被标记为完成之前运行。 回退的步骤永远不会被标记为通过。
通过 API 或控制台,发布会在 PENDING 状态下创建,直到你明确启动它才会执行任何操作(CLI 的 rollout 命令一次性创建并启动)。这种分两步的创建/启动流程是故意设计的,因为你可以在创建发布后进行审查(或让同事审查),并在实际监控时再启动。

上图中需要特别说明的两个状态:
- `PAUSED` 表示 _你_ 主动暂停了。发布会精确停留在当前位置,并从相同的步骤恢复。
- `SYSTEM_PAUSED` 表示 _平台_ 检测到异常(例如指标门失败、容量不足或缺失指标),并暂停等待人工批准。它会暂停、通知你并等待;取消操作始终由 _你_ 决定。
没有会导致流量悬停的 FAILED 终止状态:发布最终会以 COMPLETED(目标已就绪)或 CANCELED(拆分被冻结在当前状态,你需要反向运行发布以回退)结束。
步骤的构成
以下是对单个金丝雀步骤的分解,数据基于本文末尾的运行测试(Qwen2.5-7B → Qwen3.5-9B,每个 H100 各部署一个)。

传播等待的作用是防止过时的全局路由缓存向正在缩减的源发送请求。等待时间被扩展为指标窗口加上数据摄入延迟。冷启动主导了第一步;后续步骤会向已就绪的目标添加副本。
一瞥策略选择
所有三种策略都通过相同的引擎和相同的健康检查门运行;它们的区别在于流量移动方式、重叠带来的额外容量成本,以及是否为指标门设置等待窗口。
| | 渐进式发布 | 蓝绿部署 | 滚动更新 | | --- | --- | --- | --- | | 流量模式 | 按您选择的步骤逐步分配流量(默认 5% → 25% → 50% → 100%),每个步骤会持续等待窗口时间 | 一次切换,0% → 100%,目标实例健康后完成 | 按副本逐步进行,流量根据副本比例分配 | | 额外容量 | 接近源实例规模;目标实例在源实例释放该流量份额前增长一步 | 两个部署都保持完整规模直到源实例释放 | 每个步骤源实例的副本数;步骤中间会多一个副本 | | 典型持续时间 | 一次冷启动加上每个步骤的等待时间(每个步骤至少 390 秒,带有指标门) | 一次冷启动加上 30 秒传播时间;几分钟内完成 | 每个副本一次冷启动;大规模部署时最慢 | | 指标门 | 是,每个步骤后检查 | 否(无等待窗口) | 否 | | 如何回滚 | 取消会冻结当前流量份额,然后反向执行发布流程 | 反向执行发布流程;--final-source-replicas 1 会短暂保留旧模型以便快速回滚 | 反向执行发布流程 | | 最适合场景 | 在完全接管前通过实时流量进行验证 | 需要快速切换且能短暂承受双倍容量时 | 同型号引擎或配置变更且GPU占用保持恒定时 |
创建发布流程
以下是从当前模型部署到候选模型部署的三步渐进式发布流程,包含延迟回归指标门。CLI 工具作为 together Python 包中的 tg 提供(版本 2.34.0 或更新)。您需要传递 目标 部署;当且仅当一个部署正在接收流量时,源部署会自动推断,否则需要传递 --source:
# 1. 通过一条命令创建并启动发布流程。
# 时间间隔和窗口以秒为单位,后缀使用 "s" ("600s",而非 "10m")。
tg beta endpoints rollout $TARGET_DEPLOYMENT_ID \
--source $SOURCE_DEPLOYMENT_ID \
--canary \
--steps 10,50,100 \
--interval 600s \
--metric router_latency --metric-stat p95 \
--metric-max-regression 10 --metric-direction higher-is-worse \
--metric-window 300s
# 2. 查看进度:传递 "Active Rollout" 下打印的发布 ID,
# 或传递端点 ID 查看端点摘要
tg beta endpoints get $ROLLOUT_ID
tg beta endpoints get $ENDPOINT_ID
# 3. 控制流程:传递端点 ID 加上一个控制标志
tg beta endpoints rollout $ENDPOINT_ID --pause --reason "holding for review"
tg beta endpoints rollout $ENDPOINT_ID --resume
tg beta endpoints rollout $ENDPOINT_ID --promote
tg beta endpoints rollout $ENDPOINT_ID --cancel --reason "latency regression on target"当发布流程完成时,源实例会减少到零副本并停止(--final-source-replicas 默认为 0),目标实例会以源实例的副本数作为最低限制启动(--final-target-replicas)。CLI 为每个发布流程附加一个指标门;如需设置多个规则,请使用控制台或 API。
通过 REST API 实现方式相同,其中创建和启动是独立调用,且一个发布流程可以携带多个指标规则:
/think
# 1. 创建发布。它会返回状态为 PENDING;保存其 "id" (rol_...) 作为 $ROLLOUT_ID。
curl -s -X POST \
"https://api.together.ai/v2/projects/$PROJECT_ID/endpoints/$ENDPOINT_ID/rollouts" \
-H "Authorization: Bearer $TOGETHER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sourceDeploymentId": "'$SOURCE_DEPLOYMENT_ID'",
"targetDeploymentId": "'$TARGET_DEPLOYMENT_ID'",
"canary": {
"steps": [{"traffic": 10}, {"traffic": 50}, {"traffic": 100}],
"stepInterval": "600s"
},
"metrics": [{
"name": "router_latency",
"stat": "METRIC_STAT_TYPE_PERCENTILE",
"percentile": 95,
"regressionCheck": {
"direction": "REGRESSION_DIRECTION_HIGHER_IS_WORSE",
"maxRegressionPercent": 10
},
"window": "300s"
}]
}'
# 2. 启动它: POST .../rollouts/$ROLLOUT_ID/start -d '{}'
# 3. 查看状态: GET .../rollouts/$ROLLOUT_IDAPI 对一些内容有严格要求:percentile 是整数(95,而非 "p95"),枚举值需要完整前缀(METRIC_STAT_TYPE_*、REGRESSION_DIRECTION_*、THRESHOLD_OPERATOR_*),持续时间使用 protobuf 字符串如 "600s",而目录外的指标名称会返回 400 错误并列出支持的名称。默认会终止源流量,因此无需额外传递参数。
回归检查的含义是:_在每个阶段,将目标的 p95 路由器延迟(路由器测量的每请求持续时间,单位毫秒)过去 5 分钟的数据与源进行对比。如果目标延迟比源高 10% 以上,则停止推进。_
Python SDK
使用 together 包(2.34.0 或更新版本)在 Python 中实现相同发布。此处字段名使用 snake_case,而接口使用 camelCase;SDK 会自动转换。
from together import Together
client = Together() # 读取 TOGETHER_API_KEY
rollout = client.beta.endpoints.rollouts.create(
endpoint_id=ENDPOINT_ID,
project_id=PROJECT_ID,
source_deployment_id=SOURCE_DEPLOYMENT_ID,
target_deployment_id=TARGET_DEPLOYMENT_ID,
canary={"steps": [{"traffic": 10}, {"traffic": 50}, {"traffic": 100}], "step_interval": "600s"},
metrics=[{
"name": "router_latency", "stat": "METRIC_STAT_TYPE_PERCENTILE", "percentile": 95,
"regression_check": {"direction": "REGRESSION_DIRECTION_HIGHER_IS_WORSE", "max_regression_percent": 10},
"window": "300s",
}],
) # 状态: PENDING
client.beta.endpoints.rollouts.start(rollout.id, project_id=PROJECT_ID, endpoint_id=ENDPOINT_ID)
# 后续操作: .retrieve / .pause / .resume / .promote / .cancel 使用相同的参数 (id, project_id, endpoint_id)控制发布
每个发布都接受相同的四种控制操作。一个端点最多只有一个活动发布,因此 CLI 只需指定端点 ID,很少需要 rollout ID。每个控制操作在被接受后立即返回;需轮询 tg beta endpoints get(或 GET 接口)直到发布达到预期状态。发布激活期间(包括暂停时),端点的流量分配被锁定,源和目标部署无法停止或删除。
暂停
发布状态变为 PAUSING,允许正在进行的步骤完成,然后在当前流量分配和副本数上暂停为 PAUSED。两个部署继续提供服务。暂停可持续数天;平台不会自动恢复人工暂停。
CLI
tg beta endpoints rollout $ENDPOINT_ID --pause --reason "holding for review" REST
POST …/rollouts/$ROLLOUT_ID/pause
{"reason": "holding for review"}
### 恢复
从当前步骤继续执行,适用于 `PAUSED` 和 `SYSTEM_PAUSED` 状态。如果某个关卡触发失败,系统会基于最新数据重新评估,不会跳过该步骤。
CLI
tg beta endpoints rollout $ENDPOINT_ID --resume
REST
POST …/rollouts/$ROLLOUT_ID/resume
{}
### 提升
跳过剩余的金丝雀步骤,直接执行最终的 100% 步骤:目标实例会扩展到其目标规模,流量切换后进入传播等待和浸泡运行阶段,随后源实例开始排水。跳过的步骤会被标记为 `SKIPPED`。此操作并非瞬时完成:例如在测试运行中若步骤间隔为 10 分钟,即使在第 0 步执行提升操作,仍需经历最终步骤的完整浸泡阶段。
CLI
tg beta endpoints rollout $ENDPOINT_ID --promote
REST
POST …/rollouts/$ROLLOUT_ID/promote
{}
### 取消
将当前流量分配冻结到端点的基准权重,并将发布状态标记为 `CANCELED`。不会自动缩放资源;两个部署会继续提供其冻结的流量份额,直到你修改分配比例或执行反向发布。若在 0% 时取消目标实例,该实例将保持运行但无流量分配;若不再需要,可将其缩放至零或删除。
CLI
tg beta endpoints rollout $ENDPOINT_ID --cancel --reason "latency regression on target"
REST
POST …/rollouts/$ROLLOUT_ID/cancel
{"reason": "latency regression on target"}
### 反向发布
没有专门的回滚操作。若需将流量回退,可在取消操作或发布完成后,创建一个新的发布任务并交换源和目标实例,然后启动该任务。任何策略均可使用,且相同的关卡规则仍然适用。在取消操作后,默认的金丝雀阶梯会跳过新目标实例已通过的步骤,默认最终副本数为两者的总和。
CLI
tg beta endpoints rollout $OLD_SOURCE_ID --source $OLD_TARGET_ID --canary
REST
POST …/rollouts (交换两个实例 ID)
POST …/rollouts/$NEW_ROLLOUT_ID/start
对已完成(`COMPLETED`)或已取消(`CANCELED`)的发布任务无法执行控制操作。可通过 `tg beta endpoints rm $ROLLOUT_ID` 从历史记录中删除已完成或从未启动的发布任务;删除记录不会影响其留下的流量分配状态。
## 内部机制:配置关卡
### 指标关卡
指标关卡是金丝雀功能:蓝绿部署和滚动部署仍然会执行健康检查,但分阶段的指标对比需要金丝雀的步骤结构才能有意义。关卡基于 **封闭目录** 中的三个路由器侧指标进行评估,这些指标对源和目标的测量方式完全一致(其他指标名称在创建时会被拒绝):
* `router_error_rate`:路由器 5xx 响应数除以所有推理响应数,以 0-1 比例表示(0.02 表示 2%)
* `router_latency`:路由器端每请求持续时间,以毫秒为单位。由于存在双峰分布(中位数尝试通常是快速拒绝),建议使用 `p95` 或更高百分位数而非平均值
* `inflight_requests`:每个就绪副本的并发请求数,在窗口期内取平均值(阈值基于单个副本而非整个集群)
每条规则使用以下两种检查之一:
* **`regressionCheck`** (_相对_): "目标不能比源差超过N%"。这是延迟指标的正确默认值,因为它可以自我校准:你不需要知道绝对的p95值,只需确保新模型不会恶化它。设置 `direction` 让平台知道哪个方向是更好/更差的。
* **`thresholdCheck`** (_绝对_): "目标必须满足 `operator, value`"(例如错误率 `< 0.01`)。在你有硬性 SLO 或源本身可能不健康(相对比较会因基准不同而产生偏差)时使用此检查。
两个配方适用于大多数服务:
// 延迟敏感服务:不要部署明显更慢的版本 { "name": "router_latency", "stat": "METRIC_STAT_TYPE_PERCENTILE", "percentile": 95, "regressionCheck": { "direction": "REGRESSION_DIRECTION_HIGHER_IS_WORSE", "maxRegressionPercent": 10 }, "window": "300s" }, // 错误预算商店:无论源状态如何,都设置硬性上限 { "name": "router_error_rate", "stat": "METRIC_STAT_TYPE_AVG", "thresholdCheck": { "operator": "THRESHOLD_OPERATOR_LT", "value": 0.01 }, "window": "300s" }
### 时间窗口
三个持续时间相互作用,需同时考虑:
* **`window`**(默认 5m):平台在比较指标时回溯的时间范围。
* **`stepInterval`**(默认 3m):每个步骤在流量层级停留的时间,之后平台才会执行检查。
* **指标摄入延迟**(约 90s):请求被处理到其数据点可查询的时间间隔。
你必须等待至少 **`window + ingestion lag`** 的时间,以确保平台的回溯周期完全落在当前步骤的稳定状态内。如果你等待的时间短于 `window`,平台会将指标与上一个流量分割部分进行比较。平台会自动处理这个问题:如果你请求的等待时间过短,平台会自动延长它。但最好提前设计:5m 窗口需要 6.5m 等待时间。使用默认 5m 窗口时,平台会将默认 3m 的间隔扩展到 390s(6m 30s);如果你设置了自己的 `stepInterval`,请确保它至少为 `window + 90s`。
### 回归时会发生什么
默认情况下,触发的检查门会路由到 `SYSTEM_PAUSED`,这意味着系统 **暂停等待审查**。发布流程会停留在当前分割比例(爆炸半径保持在你设置的金丝雀百分比),然后你决定:继续(检查门重新评估)、升级或取消。
没有自动中止:确认的回归始终会将发布流程暂停等待人工处理,因为将流量回退本身也是一个需要监控的变更。可恢复的原因(如容量不足或指标管道缺口)则不同:平台会每 15 分钟重试一次,最多持续 3 小时,之后会将发布流程暂停等待你处理。平台还会防止误报:在暂停回归之前,系统会在约 90 秒内多次重新查询以确保它看到的不是摄入延迟或短暂波动。如果检查门无法获取可靠数据,它会以 `METRICS_UNAVAILABLE` 状态暂停,而不是被计为回归。
## 平台保证
所有三种策略都通过相同的步骤引擎运行,因此这些保证适用于金丝雀、蓝绿和滚动发布。
**1. 容量从不向下取整。** 目标副本数向上取整,源副本数向下取整,因此相同规模的交换操作不会导致副本数少于初始值。滚动更新会在中间步骤增加一个副本;蓝绿部署会短暂地同时以完整规模运行两个部署。自动扩展器在计划外添加的副本将被保留。
**2. 流量永远不会路由到未就绪的容量。** 每个步骤按固定顺序执行:扩展目标、检查健康状态、转移流量、等待30秒以使路由收敛、排空源、等待、评估门控、记录步骤。在等待期间出现回归的步骤不会被标记为通过。
**3. 每一方始终拥有其份额所需的副本数。** 仅当目标拥有足够就绪副本以承载新份额,且源副本数不会低于剩余份额时,流量才会转移。如果某个副本失效且无法满足分割需求,发布过程将保持最大可能的分割并暂停为 `UNDER_SERVED`。
**4. 发布过程提升下限,而非与自动扩展器对抗。** 每个步骤仅写入每个部署的最小副本数,有一个例外:目标的上限会短暂提升以承载整个端点,并保持提升状态。在排空期间,源的上限会根据其份额缩小。如果将最大值降低到步骤所需以下,发布过程会暂停为 `POLICY_INFEASIBLE` 而非覆盖您的设置。
**5. 门控始终返回判定结果。** 回归检查通过的条件是目标在源的百分比预算范围内。源数据为零时,若目标非零且指标为“越高越差”则判定失败;其他源数据为零的情况均通过。阈值检查忽略源,仅将目标与您的值进行比较。
**6. 门控仅读取当前步骤的流量,且仅读取足够部分。** 等待时间至少为指标窗口时间加上约90秒的摄入延迟,因此300秒窗口意味着390秒等待时间。p95需要窗口内20个请求,p99需要100个请求;若不足则发布过程暂停为 `METRICS_UNAVAILABLE`。错误率和未完成请求数各需至少1个。
## 特殊情况
**1. 如果目标没有GPU容量怎么办?**
发布过程会在任何操作之前预先检查整个旅程的可行性,并在每次扩容时再次检查。容量不足会将发布过程暂停为 `SYSTEM_PAUSED`,并标记为 `CAPACITY_EXHAUSTED`。此时所有内容均未移动,源保持原样。恢复后会重新检查容量,若容量释放则继续。容量问题通常是临时性的,因此暂停优于失败。
**2. 可以无限期暂停吗?**
可以。暂停不是保持连接,而是作为一等状态存在。发布过程设计为可承受多日暂停,并能从暂停处精确恢复。
当平台暂停发布时,`status.condition` 会携带一个类型化的 **失败类别** 和一个可读的 `message`。这些包括:
| 类别 | 含义 | 您应该 |
| --- | --- | --- |
| `METRIC_REGRESSION` | 指标在真实数据上触发了熔断 | 检查该步骤的指标读数;如果目标有故障,取消并反向执行部署;如果原因是外部因素,继续执行 |
| `METRICS_UNAVAILABLE` | 熔断机制无法获取可信数据 | 检查指标名称/窗口;继续执行将重新评估 |
| `CAPACITY_EXHAUSTED` | 下一步骤缺乏足够的GPU资源 | 等待/释放资源后继续执行 |
| `UNDER_SERVED` | 一侧的可用容量低于当前分流需求 | 恢复容量(自动重试);如果暂停持续,继续执行 |
| `POLICY_INFEASIBLE` | 自动扩缩容限制无法满足计划 | 提高目标的最大副本数后继续执行 |
文档列出了剩余类别及应对方案:[故障排查](https://docs.together.ai/docs/dedicated-endpoints/rollouts#troubleshooting)。
## 实际部署演示
在实际观察一次之后,上述所有内容都更容易理解。以下是在当前平台(2026年9月)的演示。我们从**Qwen2.5-7B-Instruct**升级到**Qwen3.5-9B**,每个模型都运行在单独的H100上,同时端点持续接收每秒5个请求的聊天请求,所有响应代码都被记录。较新的模型是我们目标选择的模型;部署需要回答的问题是:它是否符合旧模型设定的延迟预算。我们为其分配了25%的p95预算。
**部署设置**。7B模型已经在运行。我们以无流量、无副本的方式将9B模型作为第二个部署添加到相同端点,部署在需要时由发布流程启动。
$MODEL_ID 是 Qwen/Qwen3.5-9B-FP8。--config 在模型仅有一个服务配置时是可选的。
tg beta endpoints deploy $MODEL_ID --endpoint $ENDPOINT_ID --config $CONFIG_ID \ --min-replicas 0 --max-replicas 0 --traffic-weight 0
**启动**。一条命令创建并启动金丝雀发布:10% → 50% → 100%,每个步骤后通过5分钟窗口比较目标p95路由延迟与源的指标。
tg beta endpoints rollout $TARGET_DEPLOYMENT_ID --source $SOURCE_DEPLOYMENT_ID \ --canary --steps 10,50,100 \ --metric router_latency --metric-stat p95 \ --metric-max-regression 25 --metric-direction higher-is-worse \ --metric-window 300s

**按时间线发生的情况**(自发布启动后的时间):
* **+3:57** 9B模型完成冷启动,通过健康检查,10%的请求开始路由到它。发布流程等待30秒使路由收敛,排空7B模型的对应流量份额后开始逐步增加流量。我们保留了默认的步骤间隔,平台将其扩展到390秒以覆盖300秒窗口和数据摄入延迟。
* **+11:00** 熔断机制评估并触发。9B模型的p95路由延迟为**1,740 ms**,而7B模型为**734 ms**,达到**137%的回归**,超出25%的预算。发布流程进入`SYSTEM_PAUSED`状态,仍有10%的流量指向目标,但没有资源被销毁。`tg beta endpoints get $ROLLOUT_ID --json`返回的结果(单位为毫秒)如下:
"state": "ROLLOUT_STATE_SYSTEM_PAUSED", "currentTrafficPercent": 10, "pauseInfo": { "reason": "metrics-regression: 回归检查 router_latency 失败: target=1740.38 vs source=734.20, regression=137.05% 超过最大值=25.00% (direction=REGRESSION_DIRECTION_HIGHER_IS_WORSE)", "pausedAt": "2026-09-16T20:50:45Z" }, "status": { "condition": { "category": "ROLLOUT_FAILURE_CATEGORY_METRIC_REGRESSION", "atStep": 0, "metrics": [ { "name": "router_latency", "stat": "METRIC_STAT_TYPE_PERCENTILE", "percentile": 95, "check": "METRIC_CHECK_TYPE_REGRESSION", "sourceValue": 734.20, "targetValue": 1740.38, "maxRegressionPercent": 25, "direction": "REGRESSION_DIRECTION_HIGHER_IS_WORSE", "verdict": "METRIC_VERDICT_BREACHED" } ] } }
**决策。** 回归是真实存在的,而非短暂波动:9B 是一个推理模型,在相同 max_tokens 的情况下,每请求生成的内容更多。这是一个产品决策,而非需要恢复过去的事项,因此我们取消了部署并回退。
tg beta endpoints rollout $ENDPOINT_ID --cancel --reason "p95 延迟回归在 Qwen3.5 目标上"
分流在 90% / 10% 处冻结;两个部署继续提供服务
tg beta endpoints rollout $SOURCE_DEPLOYMENT_ID --source $TARGET_DEPLOYMENT_ID --blue-green
7B 恢复 100% 流量,9B 降为 0%
* **+11:09**`已取消`。命令发出后 0.2 秒内分流冻结在 90/10。
* **+17:00** 反向部署完成,从开始到结束耗时 5 分 49 秒:7B 恢复 100% 流量,9B 降为 0% 并停止。大部分时间用于第二个 7B 副本冷启动,因为取消后默认最终副本数为两者的总和。
**探测结果** 整个过程包括分流、暂停、取消和反向部署:**6,800 个请求,0 个非 200 响应**。
**审计追踪。** 上述所有步骤都记录在端点的事件流中,可通过部署 ID 过滤:
tg beta endpoints events $ENDPOINT_ID --subject-id $ROLLOUT_ID --json
20:39:45 rollout.created 创建金丝雀部署:dep_src → dep_tgt,3 步达到 100% 20:39:45 rollout.started 部署开始:3 步中的第 1 步,目标流量 10% 20:43:42 rollout.traffic_shifted 0% → 10% 目标流量:0% → 10% 20:50:45 rollout.system_paused 在第 1 步自动暂停:指标检查失败 20:50:54 rollout.canceled 取消请求;流量将在当前分流处冻结 20:50:54 rollout.canceled_complete 已取消:流量冻结在 90%/10%(源/目标)
7 月的一次运行中,故意设置不可能通过的阈值门限,产生了相同的模式:在 10% 流量时触发,1,198 次探测请求在恢复过程中无任何错误。
## 自己尝试!
**1. 在一个端点上部署两个版本。** 将当前部署保留为源,添加候选版本作为零流量的目标。`pip install -U together`(2.34.0 或更新版本)提供 `tg` 命令行工具:
一个已停止、零流量的目标;部署扩展时会重启它。
添加 --config cr_... 可固定特定配置版本。
tg beta endpoints deploy $MODEL --endpoint $ENDPOINT_ID \ --min-replicas 0 --max-replicas 0 --traffic-weight 0
**2. 创建并启动金丝雀** 使用默认阶梯(5% → 25% → 50% → 100%)和一个 router_latency 回归门限:
tg beta endpoints rollout $TARGET_DEPLOYMENT_ID --canary \ --metric router_latency --metric-stat p95 \ --metric-max-regression 10 --metric-direction higher-is-worse
**3. 进行观察** 使用 `tg beta endpoints get $ENDPOINT_ID`(或控制台中端点的 Rollouts 选项卡)查看其逐步推进过程。可通过 `tg beta endpoints rollout $ENDPOINT_ID --pause | --promote | --cancel` 暂停、升级或取消部署。
在整个过程中,端点 URL 和您的客户端保持不变,只有背后的模型会发生变化。
📚 **文档:**[启动部署](https://docs.together.ai/docs/dedicated-endpoints/rollouts) · [通过指标控制部署](https://docs.together.ai/docs/dedicated-endpoints/rollout-metric-gates) · [CLI 参考](https://docs.together.ai/reference/cli/endpoints-beta#rollout) · [API 参考:创建部署](https://docs.together.ai/reference/dmi/rollouts-create)
/think