AI服务器GPU资源配额:容器与MIG的分配和限制实战
GPU资源配额不是给显卡装一个全局限速开关,而是分两层控制:底层让每个容器或作业只能看到被分配的GPU或MIG切片,上层用调度器决定谁能拿到这些资源。
只做其中一层,通常会出现“显存被抢”或“卡被占满但利用率很低”的情况。
先确认驱动和MIG能力
配额方案取决于GPU是否支持MIG(Multi-Instance GPU,把一张物理卡切成多个独立小卡)。
A100、H100等数据中心卡支持,消费卡一般不支持。
登录AI服务器执行:
nvidia-smi
nvidia-smi -L
输出中能看到GPU型号和UUID。
如果型号支持MIG,再检查MIG模式:
nvidia-smi mig -lgip
没有输出或报错说明当前未启用MIG。
启用前需要确认没有训练任务占用GPU,并备份驱动和容器运行时配置。
容器层:用NVIDIA_VISIBLE_DEVICES做整卡配额
最直接的配额方式是让容器只看到指定GPU。
Docker运行参数:
docker run --gpus '"device=0,1"' -it pytorch/pytorch:latest nvidia-smi
或使用环境变量:
docker run --gpus all -e NVIDIA_VISIBLE_DEVICES=0 -it pytorch/pytorch:latest nvidia-smi
预期结果是容器内nvidia-smi只列出GPU 0。
如果仍看到全部卡,检查/etc/docker/daemon.json是否配置了nvidia运行时,并重启Docker。
整卡配额适合一人一卡或一任务多卡的场景,但无法把一张卡拆给多个小任务。
用MIG切片做细粒度配额
需要把一张A100拆成多个7g.40gb或3g.20gb实例时,先启用MIG模式:
nvidia-smi -mig 1
然后创建GPU实例和计算实例(具体profile以nvidia-smi mig -lgip输出为准):
nvidia-smi mig -cgi 1g.10gb,1g.10gb -C
创建后执行nvidia-smi -L会看到MIG 1g.10gb Device 0这类条目。
容器运行时通过MIG UUID指定切片:
docker run --gpus '"device=MIG-GPU-xxxx"' -it pytorch/pytorch:latest nvidia-smi
MIG的优点是显存和算力硬隔离,缺点是切片规格固定,调整需要销毁重建,且部分消费级框架对MIG支持不完整。
生产环境建议先在测试卡上验证训练框架能否识别MIG设备。
作业层:Kubernetes与Slurm的准入控制
如果多用户通过Kubernetes提交任务,安装NVIDIA device plugin后,Pod中声明资源:
resources:
limits:
nvidia.com/gpu: 1
调度器只会把Pod放到有可用GPU的节点。
MIG场景下资源名可能是nvidia.com/mig-1g.10gb,具体以节点kubectl describe node输出的Capacity为准。
Slurm集群则通过gres.conf和--gres=gpu:1控制,配额体现在分区和QOS限制上。
无论哪种调度器,都要避免“容器内可见全部GPU但只申请一张”的配置,否则配额形同虚设。
常见坑与验证方式
- 只限制显存不限制算力:用
CUDA_VISIBLE_DEVICES只能隐藏设备,不能阻止进程占满算力,需要结合MIG或调度器。 - MIG模式下nvidia-smi显示不全:部分旧版驱动和容器工具链对MIG枚举不完整,升级驱动和nvidia-container-toolkit后再试。
- 配额生效验证:进入容器执行
nvidia-smi -L,确认只看到被分配的卡或切片;同时提交一个显存占用略超配额的任务,观察是否按预期失败而不是拖垮整卡。
配额规则改完后,建议用一个小型训练或推理任务跑通全流程,再放量给业务使用。
遇到容器内看不到GPU时,优先检查NVIDIA_VISIBLE_DEVICES、运行时配置和MIG UUID是否写错。