Hy3 这类 MoE 服务端调参,显存上限、专家并行度和批大小不建议分三轮去试。可行的做法是先按卡数把显存拆成权重、KV 缓存、通信缓冲三块预算,再把专家切分固定下来,最后用剩余显存反推批大小。顺序反过来,每改一次专家并行度,之前算出的批大小上限就作废——日志里看到的那个上限,其实是上一版切分的残留。
适用场景:单机多卡或多机多卡部署 Hy3,显存吃紧,需要在专家并行度与批大小之间做取舍。操作动作:先固定 expert_parallel_size,再按模型结构算 KV 缓存每 token 占用,用显存余量反推 max_batch_size,最后一次性写入配置文件。验证方式:启动日志里的切分字段、KV 缓存块数、最大并发数与配置文件一致,再用一次接近上限的并发请求确认不 OOM。风险边界:字段名和默认值随框架版本变化,一律以实际启动日志为准;不要用 swap 或 CPU offload 当调优结论。
把显存上限拆成权重、缓存、通信缓冲三块预算
显存上限不是一个整体数字,它是三块预算之和:常驻的模型权重、随请求增长的 KV 缓存、以及并行通信与算子 workspace 的缓冲。三块被不同参数牵动,先分清谁动谁不动,后面推批大小时才有稳定分母。
| 预算块 | 估算骨架 | 量化档位变化方向 | 上下文长度变化方向 | 并行度变化方向 |
|---|---|---|---|---|
| 权重 | 参数量 × 每参数字节数 ÷ 权重切分份数 | 量化越激进,每参数字节数越小,权重越低 | 基本无关 | 专家并行度升高,每卡权重下降 |
| KV 缓存 | 层数 × 2 × kv_heads × head_dim × 字节数 × 序列长度 × 并发序列数 | 取决于是否量化 KV,不量化时基本不变 | 随长度近似线性增长 | 切分 KV heads 的并行度升高,每卡缓存下降 |
| 通信与 workspace 缓冲 | 与 all-to-all 桶大小、单轮 token 数、并行组规模相关 | 影响较小 | 影响较小 | 并行度升高,缓冲通常上升 |
需要注意的是,专家并行只切专家权重,如果同时没开 KV 头切分,KV 缓存不会因此变小;反过来,把上下文长度从 4K 提到 32K,吃掉的往往是整块 KV 预算。先按上表逐项估一遍,心里要有一个「权重固定、KV 弹性、通信缓冲保守留」的划分。
按并行度先固定专家切分,再反推可承载批大小
推荐顺序是:先根据卡数和专家总数定切分,之后整轮调参不再改动它;再算 KV 缓存上限;最后反推批大小。原因是切分一变,每卡权重和通信缓冲同时变,KV 可用显存跟着变,批大小上限必然重算。先调批大小再调切分,只会重复推翻。
# 字段名以实际框架为准,这里只表示取值来源
expert_parallel_size: 8 # 先定,本轮调参内固定
expert_count: 64 # 每卡专家数 = expert_count / expert_parallel_size
max_model_len: 8192 # 上下文上限,决定 KV 每序列占用
gpu_memory_utilization: 0.90 # 显存使用水位,留出通信缓冲余量
kv_cache_bytes_per_token: 由层数、kv_heads、head_dim 计算
max_batch_size: 待反推 # = 剩余显存 / (每 token KV × 平均序列长度)反推时不要用最大长度乘最大批大小一步到位,那样会把批大小压得过低。通常按平均序列长度估一个值,再留一档余量给长请求;如果线上长请求占比高,就把 max_model_len 和批大小一起下调,而不是单改一个。
改配置后逐项验证服务是否真的生效
配置改了但没加载,是这类调参最容易踩的坑,后面所有判断都会建立在错误前提上。启动阶段先在日志里核对切分字段,例如 expert_parallel_size、num_local_experts、tensor_parallel_size 是否与文件一致;再核对批大小与缓存字段,例如 max_num_seqs、max_batch_size、kv_cache_blocks 或等价命名。判断依据很简单:日志里的数值必须等于配置值,出现「clamped to」「adjusted to」这类字样,说明框架已经按显存上限改过你的取值,这时应以日志中的实际值为准,回头修正配置。
运行阶段再用指标页确认一次。常见字段包括当前运行请求数、KV 缓存使用水位、缓存块总数。把并发压到接近 max_batch_size,观察缓存水位是否逼近上限、是否出现显存不足或请求排队;如果水位长期很低,说明批大小还有上探空间,但每次只调一档,调完重走一遍日志核对。
配置改错导致启动失败时的回滚步骤
- 备份原配置:在修改前把当前生效的配置文件复制成一份带版本后缀的副本。确认点是副本内容与线上一致,可用 diff 复核,避免备份到已经被改坏的版本。
- 用副本恢复:把副本覆盖回原路径,重启服务。确认点是日志重新出现加载成功与显存分配完成的段落,且切分字段回到备份时的取值。
- 最小请求验证:发一条短请求跑通。确认点是请求正常返回、无显存报错、指标页缓存水位回到常规区间。三步都过了,再讨论是否重新试新配置。
回滚的价值在于把试错成本压到一次重启。每次只改一组参数,失败就退回上一份可用配置,不要在同一轮里既调切分又调批大小,否则失败时无法判断是谁引起的。
把最终参数组写成可复用的配置文件
调完一轮后,把结论固化成一份文件,下次换机器或换版本直接比对,而不是凭记忆重调。骨架如下,每行后面写清取值理由,字段名仍以实际框架为准。
# hy3-serving.yaml 配置骨架(字段名以实际框架为准)
expert_parallel_size: 8 # 由卡数与专家总数决定,本轮固定不动的基准
max_model_len: 8192 # 覆盖线上主流请求长度,超出部分由业务侧截断
max_batch_size: 48 # 由剩余显存反推,留一档余量给长请求
gpu_memory_utilization: 0.90 # 给通信缓冲与碎片留出空间
kv_cache_quant: 关闭 # 开启前先单独验证一次显存与精度影响
enable_prefix_cache: true # 前缀命中高时开启,可减少实际 KV 占用这份文件的使用方式是:改任何一行之前先备份,改完按启动日志核对字段,再用接近批大小上限的并发做一次验证。只要切分仍固定,批大小和缓存相关的取值都可以在这份文件里小步调整,不必重新推一遍整套预算。