文章目录

定位问题

我们在使用tensorflow+pycharm或者PyTorch写程序的时候, 有时候会在控制台终止掉正在运行的程序,但是有时候程序已经结束了,nvidia-smi也看到没有程序了,但是GPU的内存并没有释放,这是怎么回事呢?

使用PyTorch设置多线程(threads)进行数据读取(DataLoader),其实是假的多线程,他是开了N个子进程(PID都连着)进行模拟多线程工作,所以你的程序跑完或者中途kill掉主进程的话,子进程的GPU显存并不会被释放,需要手动一个一个kill才行,具体方法描述如下:

  1. 先关闭ssh(或者shell)窗口,退出重新登录

  2. 查看运行在gpu上的所有程序:

    fuser -v /dev/nvidia*
    
  3. kill掉所有(连号的)僵尸进程

具体操作步骤如下: 我们可以用如下命令查看 nvidia-smi看不到的GPU进程。 nvidia-smi

发现内存泄露问题,即没有进程时,内存被占用,0号GPU上运行的python程序已经退出,但是显存没有被释放

root@k8s:~# nvidia-smi
Thu Mar 21 09:55:06 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.39       Driver Version: 418.39       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 00000000:04:00.0 Off |                    0 |
| N/A   55C    P0    59W / 149W |  11000MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla K80           Off  | 00000000:05:00.0 Off |                    0 |
| N/A   58C    P0   133W / 149W |   4544MiB / 11441MiB |     90%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla K80           Off  | 00000000:08:00.0 Off |                    0 |
| N/A   62C    P0   144W / 149W |   8901MiB / 11441MiB |    100%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla K80           Off  | 00000000:09:00.0 Off |                    0 |
| N/A   33C    P8    31W / 149W |      0MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   4  Tesla K80           Off  | 00000000:84:00.0 Off |                    0 |
| N/A   33C    P8    26W / 149W |      0MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   5  Tesla K80           Off  | 00000000:85:00.0 Off |                    0 |
| N/A   31C    P8    29W / 149W |      0MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   6  Tesla K80           Off  | 00000000:88:00.0 Off |                    0 |
| N/A   35C    P8    26W / 149W |      0MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   7  Tesla K80           Off  | 00000000:89:00.0 Off |                    0 |
| N/A   29C    P8    30W / 149W |      0MiB / 11441MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    1      5771      C   python                                      4531MiB |
|    2     30774      C   python                                      8888MiB |
+-----------------------------------------------------------------------------+

执行fuser -v /dev/nvidia* 发现僵尸进程(连号的)

查看具体这个进程调用GPU的情况

pmap -d PID

强行关掉所有当前并未执行的僵尸进程

kill -9 PID

根本解决办法

解决问题的根本办法是在python多进程编程时如何避免主进程意外退出子进程变成孤儿进程,解决办法如下:

《主进程被杀死时,如何保证子进程同时退出,而不变为孤儿进程(一)》

《主进程被杀死时,如何保证子进程同时退出,而不变为孤儿进程(二)》

《主进程被杀死时,如何保证子进程同时退出,而不变为孤儿进程(三)》