Planner 指南

以 Markdown 格式查看

Dynamo Planner 是一个自动扩缩容控制器,会在运行时调整 prefill 和 decode 引擎的副本数,以满足延迟 SLA。它读取流量信号(Prometheus 指标或负载预测器输出)和引擎性能模型,用于决定何时扩容或缩容。

如需快速概览,请参阅 Planner overview。如需了解架构内部机制,请参阅 Planner 设计

扩缩容模式

planner 支持四个优化目标,这些目标决定扩缩容决策的方式:

  • throughput(默认):基于队列深度和 KV cache 利用率使用静态阈值。不需要 SLA 目标或 profiling。开箱即用。
  • latency:与 throughput 采用相同方法,但使用更激进的阈值,即更早扩容并容忍更少排队。适合对延迟敏感的工作负载。
  • load:使用用户定义的 prefill 队列 token 阈值和 decode KV 利用率阈值,进行反应式的基于负载扩缩容。
  • sla:使用 Rust 引擎性能模型 shim;原生 AIC 可用时直接使用 AIC 估算,并结合在线 FPM 调优,否则回退到 FPM 回归模型。支持基于吞吐量(预测式)和基于负载(反应式)的扩缩容模式。适合需要精确 SLA 控制的高级用户。

何时使用哪种模式:

  • throughput(默认)开始,它无需配置即可立即工作。
  • 如果工作负载有严格的延迟要求,并且你更倾向于过度预配置而不是排队,请切换到 latency
  • 当你希望通过 prefill 队列和 decode KV 利用率阈值直接控制扩缩容时,请使用 load
  • 当你有部署前 profiling 数据,并希望以特定 TTFT/ITL 值为目标时,请使用 sla

PlannerConfig 参考

planner 通过 PlannerConfig JSON/YAML 对象进行配置。使用 profiler 时,该对象位于 DGDR 规范的 features.planner 部分下:

1features:
2 planner:
3 mode: disagg
4 backend: vllm
5 # optimization_target defaults to "throughput" — works out of the box

对于基于 SLA 的扩缩容:

1features:
2 planner:
3 optimization_target: sla
4 enable_throughput_scaling: true
5 enable_load_scaling: false
6 pre_deployment_sweeping_mode: rapid
7 mode: disagg
8 backend: vllm

若要在不改变副本数的情况下评估 Planner 行为,请启用 advisory 模式:

1features:
2 planner:
3 advisory: true

advisory 模式仅提供建议。Planner 会计算建议副本数、记录日志、将其导出为诊断信息,并显示在 HTML 报告中。这些建议不会作为扩缩容决策应用:Planner 不会执行扩缩容操作,也不会更改部署。

优化目标

字段类型默认值说明
optimization_targetstringthroughputthroughput:基于队列/利用率阈值扩缩容。latency:激进的低延迟阈值。load:用户定义的 prefill 队列和 decode KV 利用率阈值。sla:使用 Rust 引擎性能模型,并以 ttft_ms/itl_ms 为目标扩缩容。

optimization_targetthroughputlatencyload 时,会自动启用基于负载的扩缩容,并禁用基于吞吐量的扩缩容。ttft_ms/itl_ms 字段会被忽略。

扩缩容模式字段(SLA 模式)

字段类型默认值说明
enable_throughput_scalingbooltrue启用基于吞吐量的扩缩容。仅在 optimization_target: sla 时使用。
enable_load_scalingboolfalse启用基于负载的扩缩容。仅在 optimization_target: sla 时使用。

使用 optimization_target: sla 时,必须至少启用一种扩缩容模式。

部署前扫描

字段类型默认值说明
pre_deployment_sweeping_modestringrapid如何生成可选的性能模型启动数据:rapid(AIC 仿真,约 30 秒)、thorough(真实 GPU,2-4 小时)或 none(跳过)。

SLA 模式使用 Rust 引擎性能模型 shim。如果配置了 aic_perf_model,planner 会用原生 AIC 模型身份和引擎上限初始化 shim;如果该模型不被原生 AIC 支持,shim 会自动回退到基于观测 FPM 的回归模型。如果没有配置 aic_perf_model,shim 会从 FPM 回归模型启动,并在自基准测试或在线 FPM 观测足够后变为可用。

启动时,planner 总会先尝试从 get_perf_metrics Dynamo 端点获取自基准测试结果。如果不可用,则在配置存在时回退到 rapid 模式 AIC interpolation 数据或 profile_results_dir 中 profiler 生成的数据(npz 或 JSON)。这些数据都会转换为 ForwardPassMetrics,并用于调优或启动性能模型。当 pre_deployment_sweeping_mode: none 时,planner 仍然可以启动;吞吐量决策会在原生 AIC 可用或在线 FPM 足够之前报告 model_not_ready

手动配置原生 AIC 性能模型:

1features:
2 planner:
3 optimization_target: sla
4 aic_perf_model:
5 hf_id: nvidia/Llama-3.1-8B-Instruct-FP8
6 system: h200_sxm
7 backend: vllm
8 prefill_pick: {tp: 1, pp: 1, dp: 1, moe_tp: 1, moe_ep: 1}
9 decode_pick: {tp: 1, pp: 1, dp: 1, moe_tp: 1, moe_ep: 1}

基于吞吐量的扩缩容设置

字段类型默认值说明
throughput_adjustment_interval_secondsint180基于吞吐量的扩缩容决策之间的秒数。
throughput_metrics_sourcestringfrontend用于吞吐量扩缩容的 Prometheus 流量来源:frontend 从公共 Frontend 读取 dynamo_frontend_* 指标;router 从 LocalRouter 读取 dynamo_component_router_* 指标。在 GlobalPlanner 部署中,为池本地 Planner 使用 router
min_endpointint1要维持的引擎端点最小数量。
max_gpu_budgetint8planner 可以分配的 GPU 总数上限。
ttft_msfloat500.0用于扩缩容决策的 TTFT SLA 目标(毫秒)。
itl_msfloat50.0用于扩缩容决策的 ITL SLA 目标(毫秒)。

基于负载的扩缩容设置

字段类型默认值说明
load_adjustment_interval_secondsint5FPM 调优更新和基于负载的扩缩容决策之间的秒数。即使只启用了吞吐量扩缩容,实时 FPM 观测也会按此间隔输入到性能模型中。必须短于 throughput_adjustment_interval_seconds
max_num_fpm_samplesint64为在线调优或回归保留的 FPM 观测最大数量。
fpm_sample_bucket_sizeint16用于观测淘汰的 bucket 数量(必须是完全平方数)。
load_scaling_down_sensitivityint80缩容敏感度 0-100(0=永不,100=激进)。
load_min_observationsint5做出扩缩容决策前所需的最少观测数。

通用设置

字段类型默认值说明
modestringdisaggPlanner 模式:disaggprefilldecodeagg
backendstringvllmBackend:vllmsglangtrtllmmocker
environmentstringkubernetes运行时环境:kubernetesvirtualglobal-planner
namespacestringenv DYN_NAMESPACE部署的 Kubernetes namespace。
advisoryboolfalse仅建议模式。计算、记录、导出并报告建议副本数,但不执行扩缩容操作,也不更改部署。

流量预测设置

字段类型默认值说明
load_predictorstringarima用于 request count、ISL 和 OSL 的预测方法:constantarimakalmanprophet。KV hit rate 和 speculative decode accept length 等运行时元数据会使用最新的有效观测值。
load_predictor_log1pboolfalse对被预测的 request count、ISL 和 OSL 数据应用 log1p 变换。
prophet_window_sizeint50Prophet predictor 的窗口大小(秒)。
load_predictor_warmup_tracestringnull用于引导预测的 warmup trace 文件路径。

KV hit rate 和 speculative decode accept length 是引擎/Router 运行时信号,不是流量形状。Planner 会保存每个信号最新的有效观测值,并在新的有效值到达前复用它。冷启动时,缺失的 KV hit rate 表示不做 prefix-cache discount,缺失的 accept length 表示 1.0

Kalman Filter 设置

字段类型默认值说明
kalman_q_levelfloat1.0level 组件的 process noise。
kalman_q_trendfloat0.1trend 组件的 process noise。
kalman_rfloat10.0measurement noise。
kalman_min_pointsint5Kalman 预测激活前所需的最少数据点数。

诊断报告

字段类型默认值说明
report_interval_hoursfloat or null24.0每 N 小时(模拟时间)生成一份 HTML 诊断报告。设置为 null 可禁用周期性报告生成。
report_output_dirstring./planner_reportsHTML 诊断报告的目录。
live_dashboard_portint8080实时诊断 dashboard HTTP 服务器的端口。设置为 0 可禁用。启用后,访问 http://host:port/ 查看累积快照的实时 Plotly 报告。

这些报告中展示的同一组诊断信号也会以 dynamo_planner_* 前缀导出为 Prometheus 指标,例如估算的 TTFT/ITL(dynamo_planner_estimated_ttft_msdynamo_planner_estimated_itl_ms)、建议副本数(dynamo_planner_predicted_num_prefill_replicasdynamo_planner_predicted_num_decode_replicas)、每个引擎的容量和 FPM 队列深度,以及负载/吞吐量扩缩容决策枚举。

Replica Counts 图会将实际 prefill/decode 副本与 Planner 建议的 prefill/decode 副本的离散建议标记叠加显示。当 advisory: true 时,这些建议数量仅作为建议;Planner 会记录它本会执行的操作,但不会应用该变更。

调度 / plugin pipeline

Planner 默认通过内置 plugin pipeline 运行。基础 pipeline cadence 位于 PlannerConfigscheduling 子树;plugin 注册、transport 和认证设置位于 plugin_registration

字段类型默认值说明
scheduling.scale_interval_secondsfloat已启用 builtin interval 的最大公约数基础 pipeline cadence。Pipeline 每个 interval 唤醒一次;每个 plugin 的 execution_interval_seconds 决定该 plugin 是否在当前 tick 执行。默认值是 load_adjustment_interval_seconds 和启用 throughput scaling 时 throughput_adjustment_interval_seconds 的最大公约数,以保留现有配置的 fire time。
scheduling.tick_max_duration_secondsfloat30.0包住完整 plugin pipeline 的外层 deadline。超时会中止当前 tick;下一次 tick 从干净状态继续。
plugin_registration.transport.request_timeout_secondsfloat5.0单个 plugin RPC timeout。Plugin 超时会触发 PluginTimeoutError;该 stage 会继续处理剩余 plugin。

现有 planner 字段仍然驱动内置 plugin:

  • load_adjustment_interval_seconds 调度 builtin_load_propose。它读取 FPM 和 worker count 观测,并执行当前 load-based 算法。
  • throughput_adjustment_interval_seconds 调度 builtin_load_predictbuiltin_throughput_propose。Throughput propose 依赖同一个 tick 里的 prediction,因此只会在 predict plugin 触发的 tick 中执行。
  • 当两个 proposer 在同一个 tick 都产生目标时,load-based scaling 在 throughput-based scaling 之后运行,保留现有行为:throughput 先更新副本数下限,load-based scaling 再在该 floor 之上调整并应用全局 GPU budget clamp。
  • Plugin pipeline 结束后,planner 会对 builtin 和外部 plugin 的目标统一应用最终的 min_endpoint 和 GPU-budget safety check,然后才执行扩缩容。

DGDR 示例

1apiVersion: nvidia.com/v1beta1
2kind: DynamoGraphDeploymentRequest
3metadata:
4 name: my-deployment
5spec:
6 model: Qwen/Qwen3-0.6B
7 features:
8 planner:
9 optimization_target: sla
10 enable_load_scaling: true
11 ttft: 200.0
12 itl: 10.0
13 pre_deployment_sweeping_mode: rapid
14 scheduling:
15 tick_max_duration_seconds: 30.0
16 plugin_registration:
17 transport:
18 request_timeout_seconds: 5.0

与 Profiler 集成

当 profiler 在启用 planner 的情况下运行时,它会:

  1. 选择最佳 prefill 和 decode 引擎配置
  2. 生成可选的引擎性能启动数据(prefill TTFT vs ISL、decode ITL vs KV-cache 利用率)
  3. PlannerConfig 和可选性能数据保存到独立的 Kubernetes ConfigMaps 中
  4. 将 planner 服务添加到生成的 DGD,并配置为从这些 ConfigMaps 读取

planner 通过 --config /path/to/planner_config.json 接收其配置,该文件从 planner-config-XXXX ConfigMap 挂载。当生成 thorough 启动数据时,profiling 数据会从 planner-profile-data-XXXX ConfigMap 挂载。

请参阅 Profiler Guide,了解完整 profiling 工作流以及如何配置部署前扫描。

分层部署

如果你希望一个模型拥有一个公共端点,但同时有多个针对不同请求类别优化的私有 DGD,请使用分层部署:

  • 一个包含 FrontendGlobalRouterGlobalPlanner 的 control DGD
  • 一个或多个 prefill pool DGD
  • 一个或多个 decode pool DGD

在当前工作流中,请为每个目标 pool 独立运行 profiling,然后手动组合最终的 control DGD 和 pool DGD。请参阅 Global Planner Guide

另请参阅