单卡跑多个实例的前提
在一张卡上跑多个推理实例,本质是对显存做静态切分:每个实例通过显存利用率参数声明自己期望占用的上限,所有实例的比例之和必须小于整卡可分配额度。切分之后每个实例要独立扣除权重、工作区和缓存预算,因此小模型多实例的并发上限更依赖缓存精算。不声明上限时,引擎默认按较高比例预留,第二个实例往往直接启动失败。
基本信息
| 切分参数 | 显存利用率(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 | 无余量,长上下文请求容易被拒 | 预留空间过少,缓存写入失败 |
小模型多实例的并发上限更依赖缓存精算:权重占比小的时候,决定并发的是每个实例还能分到多少缓存,比例要按各自模型与业务量分别确定。
显存利用率是启动时的静态声明,不是运行时动态调度:它决定引擎预留多少显存,实际占用取决于请求分布,两者不要混为一谈。
在共享卡上混部线上与测试实例时,测试侧的异常请求会占用同一张卡的内存带宽,可能拖慢线上实例,隔离要求高时优先分卡而不是分局。