mps

3 minute read

Published:

本文回顾mps 相关技术。

MPS(Multi-Process Service)是一种支持多任务模式的方法,它跟网络、训练框架(PyTorch/Tensorflow/others)无关,只跟任务数量以及硬件相关。 https://docs.nvidia.com/deploy/pdf/CUDA_Multi_Process_Service_Overview.pdf

mps_ro_not

GPU利用率到底是什么吗?

在运行任务时,大部分人通过 nvidia-smi 来查看GPU的利用率“Volatile GPU Util”, (或用 nvidia-smi pmon ,对于tegra 产品用户,使用 tegrastats )

NVIDIA官方对利用率(utilization)定义:

Percent of time over the past sample period during which one or more kernels was executing on the GPU.The sample period may be between 1 second and 1/6 second depending on the product.

https://developer.download.nvidia.com/compute/DCGM/docs/nvidia-smi-367.38.pdf

中文是:采样时间段内,1个或更多的核(kernel)运行的时间的占比。这个采样时间段取多长,跟产品相关,可能值1/6s~1s。

注意:“one or more kernels”。这个意味着里面只要有1个kernel在执行,你的GPU利用率也可以很高。 而1个kernel不是一定让GPU内部的运算单元(core)都工作的。

因此,要注意了下面两个错误认识:

  • GPU的利用率 = GPU内计算单元干活的比例。 利用率越高,算力就必然发挥得越充分。
  • 同条件下,利用率越高,耗时一定越短。

只要记住一个事实:GPU利用率99%,并不能说明你的GPU就拿出了99%的算力。这个利用率只能说明,有kernel在运算,至于算得怎么样,算力发挥出来了没有,sm 中的core 是否都处在计算状态,光看这个利用率是判断不出来的。你可以使用一个空kernel 也会造成GPU利用率达到很高的假象。

__global__ void warmup_kernel() {
  while(1){

  }
}

void gpu_warmup() {
  warmup_kernel<<<1, 1>>>();
  CheckCudaErrors(cudaDeviceSynchronize());
}

并不是利用率越高,耗时就会越短,反之亦然。举个例子,用了MPS后,利用率降低了,运行反而更快了。
所以在同条件下,应该是GPU算力用得越充分,耗时才会越短。

提升sm真正利用率

GPU-Util 并不可信。
提升利用率的方法可以从任务本身着手,比如

  • 增加数据大小(更大的batch_size、网络)
  • 缩减I/O时间
  • 提前加载数据等手段
  • 同时送入多个任务给GPU,多个任务操作互补(有些操作不需要GPU工作),让GPU运算不闲着

这些方法都是在宏观维度从时间以及空间上压榨算力,接下来说个微观维度的手段:多任务模式。

mps

如果GPU有两个及以上的任务一起运行,那么你就可以考虑用多任务模式来继续压榨GPU算力,目前我们能接触的工具 MPS。

简单介绍一下原理,一般GPU上运行多个任务,都是采用”单任务”的工作模式,既同一个时刻只有一个任务(用不同的context区分)在GPU中运行。通俗一点,假如你起了两个任务A和B
单任务模式下,A和B是排队干活的,(“我怎么感受不到这个排队过程?” — 这个时间非常小,是一种并发的操作,感觉在好像在一起工作); single

多任务模式,就是A和B 可以同时干活
single
由于共用了context,同一时刻两个可以一起跑。这样更加充分的利用了GPU的算力。有了MPS,原来闲置的sm-core就被调用起来了,这样GPU的算力发挥得更充分了。

需要注意的是:MPS的service下,只要里面一个任务出错/失败,可能使得所有在里面的任务都运行失败。

# ====== 启动 =========
export CUDA_VISIBLE_DEVICES=0         # 这里以GPU0为例,其他卡类似
nvidia-smi -i 0 -c EXCLUSIVE_PROCESS  # 让GPU0变为独享模式。
nvidia-cuda-mps-control -d            # 开启mps服务,之后启动的任务类型Type都是”M+C“,说明MPS用上了

ps -ef | grep mps                     # 启动成功后能看到相应的进程

# ====== 停止 =========
nvidia-smi -i 0 -c DEFAULT            # 让GPU恢复为默认模式
echo quit | nvidia-cuda-mps-control   # 关闭mps服务    

ps -ef | grep mps                     # 启动成功后能看到相应的进程

root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# export CUDA_VISIBLE_DEVICES=0
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# echo $CUDA_VISIBLE_DEVICES
0
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# nvidia-smi -i 0 -c EXCLUSIVE_PROCESS
Set compute mode to EXCLUSIVE_PROCESS for GPU 00000000:01:00.0.
All done.
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# nvidia-smi
Sat Aug 30 12:10:40 2025       
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.230.02             Driver Version: 535.230.02   CUDA Version: 12.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  NVIDIA RTX 2000 Ada Gene...    Off | 00000000:01:00.0 Off |                  N/A |
| N/A   38C    P8               2W /  40W |      8MiB /  8188MiB |      0%   E. Process |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+
                                                                                         
+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|    0   N/A  N/A      2594      G   /usr/lib/xorg/Xorg                            4MiB |
+---------------------------------------------------------------------------------------+
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# nvidia-cuda-mps-control -d
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# nvidia-smi
Sat Aug 30 12:11:05 2025       
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.230.02             Driver Version: 535.230.02   CUDA Version: 12.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  NVIDIA RTX 2000 Ada Gene...    Off | 00000000:01:00.0 Off |                  N/A |
| N/A   39C    P4              N/A /  40W |      8MiB /  8188MiB |      0%   E. Process |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+
                                                                                         
+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|    0   N/A  N/A      2594      G   /usr/lib/xorg/Xorg                            4MiB |
+---------------------------------------------------------------------------------------+
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# ps -ef | grep mps
root       17238    2453  0 12:10 ?        00:00:00 nvidia-cuda-mps-control -d
root       17248   17190  0 12:11 pts/2    00:00:00 grep --color=auto mps
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# nvidia-smi -i 0 -c DEFAULT
Set compute mode to DEFAULT for GPU 00000000:01:00.0.
All done.
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# echo quit | nvidia-cuda-mps-control
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# nvidia-smi
Sat Aug 30 12:11:54 2025       
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.230.02             Driver Version: 535.230.02   CUDA Version: 12.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  NVIDIA RTX 2000 Ada Gene...    Off | 00000000:01:00.0 Off |                  N/A |
| N/A   40C    P4              N/A /  40W |      8MiB /  8188MiB |      0%      Default |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+
                                                                                         
+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|    0   N/A  N/A      2594      G   /usr/lib/xorg/Xorg                            4MiB |
+---------------------------------------------------------------------------------------+
root@SHJS-PF4ZKYLL:/home/github/lix19937.github.io# 

  • 执行
    nvidia-smi -i 0 -c EXCLUSIVE_PROCESS  # 让GPU0变为独享模式。
    

    表示独享模式 e

  • 执行
    nvidia-cuda-mps-control -d            # 开启mps服务 
    

    之后的任务类型Type都是”M+C“,说明MPS用上了
    e

通常,在多任务的情况下,速度变快了,尤其是在GPU利用率已很高的情况下,给你带来的收益更多。

  • 执行 ```bash nvidia-smi -i 0 -c DEFAULT # 让GPU恢复为默认模式 echo quit | nvidia-cuda-mps-control # 关闭mps服务

``` 表示默认模式下启动一个任务
c

Ref

https://www.nvidia.cn/content/dam/en-zz/zh_cn/assets/webinars/31oct2019c/20191031_MPS_davidwu.pdf
https://docs.nvidia.com/deploy/pdf/CUDA_Multi_Process_Service_Overview.pdf
https://developer.download.nvidia.com/compute/DCGM/docs/nvidia-smi-367.38.pdf
https://docs.nvidia.com/datacenter/dcgm/2.0/dcgm-user-guide/feature-overview.html#profiling-metrics