文章目录

  • 前言
  • 开启一个训练进程
  • 查看当前进程
  • 推测 16个子(孤儿)进程的原因如下(欢迎指正)
  • 杀死 父进程
  • jobs 命令
  • 留下一堆孤儿(僵尸)进程,依然占用着GPU资源
  • kill 僵尸进程
  • 容器 杀死进程 : kill 示例命令
  • nvidia-smi 查看显卡资源详情
  • 📙 有效分享


前言

服务器 nohup 命令 后台开启模型训练任务,需要临时停掉任务

  • kill 命令杀死了主进程
  • 发现一堆的子(僵尸)进程依旧占据着显卡资源
  • 逐个 kill 掉 子进程,显卡资源才得到释放

开启一个训练进程

Docker 容器中开启的训练任务

  • 容器内部,使用 nvidia-smi 命令无法看到 GPU 资源详情
  • nvidia-smi 只能在容器外部用户下,进行查看
python train.py > log.txt  
## 或者,挂在后台运行
nohup python train.py > log.txt  &

可以使用 jobs -l 或者 ps -ef 查看容器内的进程 ID

jobs -l

## 或者

ps -ef

查看当前进程

可以看到 PID = 42183 的主进程 和 它的 16 个子进程

ps -ef


UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jun10 pts/0    00:00:00 /bin/bash
root     42183     1 99 02:08 pts/0    00:35:21 python train.py
root     42219 42183  5 02:09 pts/0    00:01:55 python train.py
root     42283 42183  5 02:09 pts/0    00:01:57 python train.py
root     42347 42183  5 02:09 pts/0    00:01:57 python train.py
root     42411 42183  5 02:09 pts/0    00:01:56 python train.py
root     42475 42183  5 02:09 pts/0    00:01:56 python train.py
root     42539 42183  5 02:09 pts/0    00:01:56 python train.py
root     42603 42183  5 02:09 pts/0    00:01:54 python train.py
root     42667 42183  5 02:09 pts/0    00:01:57 python train.py
root     42731 42183  5 02:09 pts/0    00:01:54 python train.py
root     42795 42183  5 02:09 pts/0    00:01:54 python train.py
root     42859 42183  5 02:09 pts/0    00:01:55 python train.py
root     42923 42183  5 02:09 pts/0    00:01:55 python train.py
root     42987 42183  5 02:09 pts/0    00:01:55 python train.py
root     43051 42183  5 02:09 pts/0    00:01:55 python train.py
root     43115 42183  5 02:09 pts/0    00:01:54 python train.py
root     43179 42183  5 02:09 pts/0    00:01:55 python train.py
root     57704     1  0 02:41 pts/0    00:00:00 ps -ef

推测 16个子(孤儿)进程的原因如下(欢迎指正)

代码中 num_workers=16 ,加载数据的线程数

trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True, num_workers=16)

杀死 父进程

使用 jobs 命令 查看运行的程序,可以看到主进程的 PID

jobs -l
 
[1]+ 42183 Running                 nohup python train.py > log.txt &

## 这里直接 kill 主进程 ID
root@moli# kill 42183
[1]+  Terminated              nohup python train.py > log.txt

jobs 命令

  • 先后起了两个后台运行的进程,使用jobs后都显示出来了。“+”代表最近的一个任务(当前任务),“-”代表之前的任务。
  • 在当前命令行中使用 nohup和& 时,jobs命令才能将它显示出来。如果将他们写到 .sh 脚本中,然后执行脚本,是显示不出来的

留下一堆孤儿(僵尸)进程,依然占用着GPU资源

可以发现 主进程 kill 之后,它的子进程的 PPID 变为 1,成为了 孤儿(僵尸)进程

ps -ef

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jun10 pts/0    00:00:00 /bin/bash
root     42219     1  4 02:09 pts/0    00:02:23 python train.py
root     42283     1  4 02:09 pts/0    00:02:25 python train.py
root     42347     1  4 02:09 pts/0    00:02:26 python train.py
root     42539     1  4 02:09 pts/0    00:02:23 python train.py
root     42603     1  4 02:09 pts/0    00:02:22 python train.py
root     42667     1  4 02:09 pts/0    00:02:25 python train.py
root     42731     1  4 02:09 pts/0    00:02:23 python train.py
root     42795     1  4 02:09 pts/0    00:02:23 python train.py
root     42859     1  4 02:09 pts/0    00:02:24 python train.py
root     42923     1  4 02:09 pts/0    00:02:24 python train.py
root     42987     1  4 02:09 pts/0    00:02:23 python train.py
root     43051     1  4 02:09 pts/0    00:02:23 python train.py
root     43115     1  4 02:09 pts/0    00:02:23 python train.py
root     43179     1  4 02:09 pts/0    00:02:24 python train.py
root     61395     1  0 03:07 pts/0    00:00:00 ps -ef

kill 僵尸进程

僵尸进程依旧会占用着显卡等资源,因此选择使用 kill 进程 ID 的 方式 逐个kill 子进程,然后资源就得到了释放

推荐 kill -9 容器ID

kill 42219     
kill 42347
kill 42539
kill 42603
kill 42667
..
..
kill 42731
kill 42795
kill 42859
kill 42923
kill 43179

容器 杀死进程 : kill 示例命令

扫进程 docker docker杀掉进程_环境搭建

nvidia-smi 查看显卡资源详情

把如下两行代码放在 train.py 最上面,即指定编号为 2 和 5 的两张显卡进行训练

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "2,5"

一张 GPU 卡,可以同时 运行多个 AI 模型的训练和推理任务,即 这些 GPU 资源,可以多个用户同时共用

# 查看显卡 使用情况

nvidia-smi


+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.73.01    Driver Version: 460.73.01    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. |
|===============================+======================+======================|
..
..
+-------------------------------+----------------------+----------------------+
|   2  A100-PCIE-40GB      Off  | 00000000:39:00.0 Off |                    0 |
| N/A   71C    P0   198W / 250W |  38148MiB / 40536MiB |     98%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   5  A100-PCIE-40GB      Off  | 00000000:9D:00.0 Off |                    0 |
| N/A   65C    P0   120W / 250W |  39257MiB / 40536MiB |    100%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   6  A100-PCIE-40GB      Off  | 00000000:A0:00.0 Off |                    0 |
| N/A   62C    P0    90W / 250W |  34192MiB / 40536MiB |     47%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   7  A100-PCIE-40GB      Off  | 00000000:A4:00.0 Off |                    0 |
| N/A   70C    P0   268W / 250W |  32507MiB / 40536MiB |     54%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+

# import os
# os.environ["CUDA_VISIBLE_DEVICES"] = "2,5"

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    2   N/A  N/A     46357      C   python                          20859MiB |
|————   可以看到主卡,比副卡 多 1 个 G 左右  的通信消耗 ——————————               |
|    5   N/A  N/A     46357      C   python                          19985MiB |
|    6   N/A  N/A     52253      C   python                          20219MiB |
|    7   N/A  N/A     38699      C   python                          29855MiB |
|    7   N/A  N/A     43316      C   python                           2649MiB |
+-----------------------------------------------------------------------------+

主卡GPU占用会比副卡多 1 个 G , 因此有时会遇到,显卡 剩余资源不够分配的情况

RuntimeError: CUDA out of memory. Tried to allocate 196.00 MiB
 (GPU 1; 39.59 GiB total capacity; 10.80 GiB already allocated; 82.19 MiB free; 10.91 GiB reserved in total by PyTorch)

常规解决策略如下:

  • 把 batch_size 设置 小一些
  • 检查是不是测试图片太大了
  • 选用一个 剩余资源多的显卡做为 主卡