首页/AI/大模型部署与运维速查/单卡多实例:先做减法再分配

单卡多实例:先做减法再分配

同卡跑多个实例时先切分总量:每实例显存上限 ÷ n,再各自扣权重与 KV;各实例 gpu-memory-utilization 之和要小于 1。

单卡跑多个实例的前提

在一张卡上跑多个推理实例,本质是对显存做静态切分:每个实例通过显存利用率参数声明自己期望占用的上限,所有实例的比例之和必须小于整卡可分配额度。切分之后每个实例要独立扣除权重、工作区和缓存预算,因此小模型多实例的并发上限更依赖缓存精算。不声明上限时,引擎默认按较高比例预留,第二个实例往往直接启动失败。

基本信息

切分参数显存利用率(gpu-memory-utilization),按整卡可分配显存的百分比
设备指定通过 CUDA_VISIBLE_DEVICES 把实例绑定到具体卡
启动方式多进程,各自监听不同端口,前端由网关统一路由
约束条件各实例比例之和须小于 1,并给驱动与显示占用留出余量
适用对象显存需求小、业务隔离要求高的场景

典型使用场景

  • 小模型多实例:多个小模型共享一张卡,按业务线隔离部署
  • 新旧版本并行:灰度期间同一张卡同时跑两个版本,随时切流与回滚
  • 多租户共用硬件:不同团队各占一个实例,配额与显存互不干扰
  • 冷热模型混部:小流量模型与主力模型共存,提高硬件利用率
  • 开发测试占用:测试实例与线上实例分卡内配额,避免测试把线上挤掉

双实例切分示意

双实例切分示意
CUDA_VISIBLE_DEVICES=0 python serve_a.py --port 8001 --gpu-memory-utilization 0.45 &
CUDA_VISIBLE_DEVICES=0 python serve_b.py --port 8002 --gpu-memory-utilization 0.45 &   # 两实例合计 0.9
sleep 10
nvidia-smi --query-compute-apps=pid,used_memory --format=csv    # 核对实际占用
curl -s localhost:8001/v1/models >/dev/null && echo A_OK
curl -s localhost:8002/v1/models >/dev/null && echo B_OK         # 两个实例各自探活

分配与表现对照

配置现象结论
两实例各 0.9后启动的实例启动失败或运行中显存不足比例之和超卖,必须做减法
两实例各 0.45均正常启动,各自留有缓存空间接近合理上限,仍需按负载微调
一实例 0.8 一实例 0.15小实例并发很低但稳定按业务量差异分配,比例不必平均
单实例 0.95无余量,长上下文请求容易被拒预留空间过少,缓存写入失败
小模型多实例的并发上限更依赖缓存精算:权重占比小的时候,决定并发的是每个实例还能分到多少缓存,比例要按各自模型与业务量分别确定。
显存利用率是启动时的静态声明,不是运行时动态调度:它决定引擎预留多少显存,实际占用取决于请求分布,两者不要混为一谈。
在共享卡上混部线上与测试实例时,测试侧的异常请求会占用同一张卡的内存带宽,可能拖慢线上实例,隔离要求高时优先分卡而不是分局。

易错点

  • 两个实例都按 0.9 开:显存超卖,后启动的实例随时因内存不足而失败
  • 只改端口不改绑定设备:两个实例实际落到同一张卡,与规划不符
  • 按显存比例平均分配而不看业务量:小流量实例浪费配额,主力实例缓存不足
  • 忽略驱动与显示占用:预留比例算得太满,第一个长上下文请求就会触发分配失败

数据来源与参考

  • vLLM 官方文档:gpu-memory-utilization(docs.vllm.ai)
  • NVIDIA CUDA 环境变量文档(docs.nvidia.com/cuda)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌