問題描述:我有一個程式(app),需要用到顯示卡來跑。原本的部署方式 是直接修改程式的配置檔案來指定要用到的顯示卡。

這是我伺服器的顯示卡資訊:總共3卡 分別是 0卡 ,1卡和2卡。

[root@k8s-rancher1 etc]# nvidia-smi
Sat Sep 4 12:50:17 2021
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.84 Driver Version: 460.84 CUDA Version: 11.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 GeForce GTX 1070 Off | 00000000:02:00.0 Off | N/A |
| 21% 37C P0 37W / 180W | 0MiB / 8119MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
| 1 GeForce GTX 1070 Off | 00000000:03:00.0 Off | N/A |
| 24% 46C P5 13W / 180W | 0MiB / 8119MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
| 2 GeForce GTX 1070 Off | 00000000:04:00.0 Off | N/A |
| 24% 48C P5 16W / 180W | 0MiB / 8119MiB | 2% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+

這是程式的配置檔案a.conf修改顯示卡使用的地方:注意這裡我啟用了0卡和1卡

原始的程式啟動命令 ./app -c ./a.conf。程式啟動後執行nvidia-smi,觀察到0卡和1卡都已經被佔用,我就不貼圖了。

我想做的是直接在docker指定要啟用的顯示卡,擺脫配置檔案,這樣在後續封裝pyhon-docker介面的時候就不用再動態的修改配置檔案然後再掛載進容器內。

現在,我把程式打包成映象檔案,下面是我容器啟動命令:

[root@k8s-rancher1 /]# docker run -it --rm -p 2021:2021 -v /root/a.conf:/root/a.conf  --gpus all 192.168.9.102:2021/example/app:latest

這裡我用 --gpus all 使用全部顯示卡(總共3卡),容器啟動後會根據掛載的a.conf來選定要使用的卡,也就是0卡和1卡會被佔用,2卡會空閒起來。這並沒有問題,我們可以這麼理解為,docker run 顯示卡指定all的時候,程式會根據自身的配置檔案來啟用對應的顯示卡。

那麼,問題來了,如果我在docker run 指定要用的一個或多個顯示卡,那麼容器啟動時,顯示卡佔用情況是怎麼樣的呢?

實驗1:

  1. a.conf 配置0卡和1卡

2. docker run 指定顯示卡為2卡

[root@k8s-rancher1 /]# docker run -it --rm -p 2021:2021  -v /root/a.conf:/root/a.conf  --gpus '"device=2"' 192.168.9.102:2021/example/app:latest

結果:

結果程式啟用的是2卡,也就是說可以不可以理解為docker run 指定顯示卡和配置檔案不一致時,會以docker分配的顯示卡為主。

實驗2:

  1. a.conf 配置0卡

2. docker run 指定顯示卡為1卡和2卡

[root@k8s-rancher1 /]# docker run -it --rm -p 2021:2021  -v /root/a.conf:/root/a.conf  --gpus '"device=1,2"' 192.168.9.102:2021/example/app:latest

結果顯示卡1被佔用,2卡沒被佔用,0卡也沒被佔用,這我就沒弄明白是什麼情況。

後續我又把配置檔案改成1卡,docker指定1,2卡,結果被佔用的只有2卡。如此反覆,毫無規律。

後面我又測試了很多次,網上也找不到任何相關的資料,最終找到了一個完美的辦法,可以完全不對配置檔案做任何修改,也不用掛載配置檔案了,過程就不說了。

解決方案:

我們在對程式做映象的時候把a.conf配置檔案顯示卡配置那塊全部拉滿,把所有卡都配置進去!。這裡考慮到了四卡情況,雖然當前伺服器只有3卡。

測試:

[root@k8s-rancher1 /]# docker run -it --rm -p 2021:2021  -v /root/a.conf:/root/a.conf  --gpus '"device=1,2"' 192.168.9.102:2021/example/app:latest

[root@k8s-rancher1 /]# docker run -it --rm -p 2021:2021  -v /root/a.conf:/root/a.conf  --gpus '"device=0,2"' 192.168.9.102:2021/example/app:latest

[root@k8s-rancher1 /]# docker run -it --rm -p 2021:2021  -v /root/a.conf:/root/a.conf  --gpus '"device=0"' 192.168.9.102:2021/example/app:latest

驗證沒有任何問題。

有沒有docker大佬告訴我一下具體是什麼原理呢?