文章目录
- 前言
- 开启一个训练进程
- 查看当前进程
- 推测 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 示例命令
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 设置 小一些
- 检查是不是测试图片太大了
- 选用一个 剩余资源多的显卡做为 主卡