解读容器环境下NVIDIA_VISIBLE_DEVICES与CUDA_VISIBLE_DEVICES

在 Docker GPU 场景下,这两个环境变量作用不同,但通常会配合使用。


1. NVIDIA_VISIBLE_DEVICES

  • 来源nvidia-container-runtime

  • 作用物理层面限制容器可见 GPU

  • 值可以是

    • 单个 GPU 编号,如 "0"
    • 多个 GPU 编号,如 "0,1"
    • "all":可见所有 GPU
    • "none":不可见 GPU
  • 效果

    • 容器内部只能看到指定 GPU
    • 对 Docker/系统来说,其他 GPU 就像不存在
  • 示例

1
NVIDIA_VISIBLE_DEVICES=0

含义:容器只能访问物理 GPU0,其余 GPU 宿主机可用但容器不可见。


2.CUDA_VISIBLE_DEVICES

  • 来源:CUDA Runtime(程序层面)

  • 作用逻辑屏蔽 GPU

  • 值可以是

    • 单个 GPU 编号,如 "0"
    • 多个 GPU 编号,如 "0,1"
    • 空字符串 "":不可见任何 GPU
  • 效果

    • CUDA 程序只能访问这些 GPU
    • 容器内部编号会重新映射,即第一个在列表的 GPU 编号变成 cuda:0,第二个变成 cuda:1,与物理编号可能不同
  • 示例

1
CUDA_VISIBLE_DEVICES=1,3

容器内部:

容器编号 实际物理 GPU
cuda:0 GPU1
cuda:1 GPU3

3.为什么两者都要设置

  • NVIDIA_VISIBLE_DEVICES:限制容器访问 GPU 物理层面
  • CUDA_VISIBLE_DEVICES:控制 CUDA 程序访问 GPU 逻辑层面

组合使用可以:

  1. 容器只看到指定 GPU
  2. 容器内部程序可以按顺序编号 GPU
  3. 防止程序访问未指定的 GPU
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
services:
ocrserver01:
image: xxx
container_name: ocrserver01
ports:
- "10001:5001"
networks:
- apps
volumes:
- /etc/localtime:/etc/localtime
# deploy仅仅在swarm模式下生效,单机模式不生效.
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# capabilities: [gpu]
#runtime: nvidia
environment:
CUDA_VISIBLE_DEVICES: "0" # 程序仅仅可见gpu0
shm_size: 8g
command: /bin/bash docker/run.sh
stdin_open: true
tty: true
restart: always
networks:
apps:
external: true