多模型推理算力调度,GPU资源动态分配
多模型推理场景中,GPU资源往往被单个模型独占,导致显存和算力浪费。
本文面向零基础运维人员,讲解如何通过容器化和调度策略实现多模型推理算力调度与GPU资源动态分配,最终让多个模型共享同一张显卡并稳定运行。
一、先确认你的硬件和驱动状态
在开始配置前,需要先确认GPU型号、驱动版本和CUDA支持情况。
登录服务器后执行以下命令:
nvidia-smi
输出中重点看三个信息:GPU型号(如A100、RTX 3090)、驱动版本(Driver Version)、CUDA版本(CUDA Version)。
如果命令不存在,说明驱动未安装,需要先安装对应驱动。
接着检查Docker是否已安装并支持GPU:
docker info | grep -i runtime
如果输出中没有nvidia,需要安装NVIDIA Container Toolkit。
以Ubuntu为例:
sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
安装完成后重新执行docker info,看到nvidia运行时即表示容器可以调用GPU。
判断条件:如果nvidia-smi能正常显示显卡信息,且Docker运行时包含nvidia,就可以进入下一步调度配置。
二、用MIG或时间片实现GPU动态切分
多模型共享GPU有两种主流方式:NVIDIA MIG(多实例GPU)和时间片调度。
MIG适合A100、H100等高端卡,能把一张卡切成多个独立实例;
时间片调度适合消费级显卡,通过CUDA上下文切换让多个进程轮流使用GPU。
以MIG为例,启用前需要先开启MIG模式:
sudo nvidia-smi -mig 1
然后创建GPU实例。
具体切分方案需要根据模型显存需求决定。
例如每个模型需要10GB显存,可以在A100 40GB上创建3个10GB实例:
sudo nvidia-smi mig -cgi 10g.40gb -C
创建完成后用nvidia-smi -L查看实例列表。
每个实例会显示为MIG 10g.40gb Device 0之类的标识。
如果使用时间片调度,不需要切分硬件,而是在容器启动时通过环境变量控制:
docker run --gpus all -e CUDA_VISIBLE_DEVICES=0 -e NVIDIA_VISIBLE_DEVICES=0 your-image
多个容器同时指定同一张卡即可共享。
但要注意,时间片调度下显存是竞争关系,容易出现OOM。
关键结论:MIG提供硬件级隔离,显存和算力独立,适合生产环境;
时间片调度配置简单,但稳定性依赖显存监控。
三、在Kubernetes中配置GPU调度
如果使用Kubernetes管理推理服务,需要先部署NVIDIA设备插件:
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yml
部署完成后检查节点GPU资源:
kubectl describe node <节点名> | grep nvidia.com/gpu
输出中应显示可分配的GPU数量。
如果使用MIG,还需要在设备插件配置中启用MIG策略:
apiVersion: v1
kind: ConfigMap
metadata:
name: nvidia-device-plugin-config
data:
config.yaml: |
flags:
migStrategy: mixed
然后在Pod的resources中声明GPU需求:
resources:
limits:
nvidia.com/gpu: 1
这样调度器会自动把Pod分配到有可用GPU的节点。
多个模型可以分别声明不同数量的GPU,实现动态分配。
四、避坑指南:显存泄漏与调度冲突
多模型共享GPU时最容易遇到两个问题。
第一是显存泄漏。
某个模型推理结束后没有释放显存,导致后续模型无法加载。
排查方法是在容器内执行nvidia-smi查看进程占用,确认是否有僵尸进程。
建议在推理服务退出时显式调用torch.cuda.empty_cache()或对应框架的清理接口。
第二是调度冲突。
多个Pod同时申请同一张GPU的时间片时,可能出现某个Pod长时间得不到资源。
可以在Kubernetes中设置优先级和抢占策略,或者直接使用MIG实例,让每个Pod绑定独立实例。
另外注意,MIG实例创建后需要重启相关服务才能被容器识别。
如果nvidia-smi -L能看到实例但Docker无法使用,尝试重启Docker服务:
sudo systemctl restart docker
操作结果验证:启动两个推理容器,分别指定不同MIG实例或同一张卡,用nvidia-smi观察显存占用是否独立或叠加,确认调度生效。
五、监控与效果验证
配置完成后,需要持续监控GPU利用率和显存变化。
推荐使用nvidia-smi dmon实时查看:
nvidia-smi dmon -s u -d 5
该命令每5秒输出一次利用率和显存数据。
如果发现某张卡利用率长期低于30%,说明调度粒度太粗,可以考虑进一步切分MIG或增加模型并发。
对于Kubernetes环境,可以部署DCGM Exporter采集指标:
helm install dcgm-exporter gpu-helm-charts/dcgm-exporter
然后在Grafana中查看GPU利用率、显存使用和温度。
判断标准:多模型推理场景下,单卡GPU利用率稳定在60%以上,且没有频繁OOM,说明动态分配策略有效。
常见疑问
MIG实例创建后可以动态调整吗?
MIG实例的切分方案在创建时确定,运行中不能直接调整大小。
需要先销毁实例再重新创建。
建议根据模型显存需求提前规划。
消费级显卡能用MIG吗?
MIG目前主要支持A100、H100、A30等数据中心GPU。
消费级显卡如RTX系列不支持MIG,只能使用时间片调度或显存限制。
多个模型共享GPU时如何限制单个模型的显存?
可以在推理框架中设置显存上限。
例如PyTorch中通过torch.cuda.set_per_process_memory_fraction(0.5)限制使用50%显存。
Kubernetes中GPU资源不足时Pod会怎样?
如果节点没有可分配的GPU,Pod会处于Pending状态。
可以通过kubectl describe pod查看事件,确认是资源不足还是调度策略问题。
多模型推理算力调度和GPU资源动态分配的核心是隔离与监控。
先用MIG或时间片把物理卡切分,再通过容器和调度器按需分配,最后用监控工具验证利用率。
遇到OOM优先检查显存泄漏,遇到调度失败优先检查设备插件状态。
按本文步骤执行后,可以根据实际模型负载微调切分比例。