使用multiprocessing.Pool(8)时CPU占用100%?PyTorch+NumPy场景求助
问题分析与解决方案
关于Pool工作机制的澄清
multiprocessing.Pool的processes参数仅限制同时运行的进程数量,不会自动按核心分配CPU资源。进程实际能占用的CPU占比,由进程内任务的线程行为和系统调度决定,和核心数没有强制绑定关系。
CPU占用100%及进程数减少后占比上升的原因
- 你的任务依赖NumPy和PyTorch,这两个库默认会开启多线程优化(比如NumPy用MKL/OpenBLAS多线程运算,PyTorch默认启用CPU多线程并行)。即使你只开8个进程,每个进程内部还会启动多个线程抢占CPU核心,最终总线程数远超16核,导致CPU被占满。
- 减少进程数后,剩余进程的内部线程能获得更多系统调度资源,单个进程的CPU占比自然上升,总占用率仍接近100%——因为线程总数没有被限制。
控制CPU占用率的具体方案
1. 限制NumPy/PyTorch的线程数(最有效)
从根源减少CPU抢占,直接限制每个进程的内部线程数:
- NumPy:设置环境变量
import os # 根据需求调整数值,比如每个进程用2个线程 os.environ["OMP_NUM_THREADS"] = "2" os.environ["MKL_NUM_THREADS"] = "2" os.environ["OPENBLAS_NUM_THREADS"] = "2" - PyTorch:代码中设置线程数
结合进程数计算总线程数(比如8进程×2线程=16线程,刚好匹配16核;若要控制在75%,则总线程数设为12,可调整为6进程×2线程或4进程×3线程)。import torch torch.set_num_threads(2) torch.set_num_interop_threads(2)
2. 调整进程数与线程数的组合
根据目标CPU占用率(50%-75%),测试最优的进程数+单进程线程数组合:
- 目标50%(8核):4进程×2线程,或2进程×4线程
- 目标75%(12核):6进程×2线程,或4进程×3线程
3. 降低进程优先级(Windows系统)
通过降低Python进程优先级,让系统优先分配CPU给其他任务:
- 手动操作:任务管理器找到Python进程,右键→设置优先级→低于标准/低
- 代码实现(需安装
pywin32库):import win32api import win32process import win32con def set_low_priority(): pid = win32api.GetCurrentProcessId() handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid) win32process.SetPriorityClass(handle, win32process.BELOW_NORMAL_PRIORITY_CLASS) # 在主进程或子进程初始化时调用 set_low_priority()
4. 替代实现方案:使用ProcessPoolExecutor
和multiprocessing.Pool逻辑一致,API更简洁,同样可结合线程数限制方案使用:
from concurrent.futures import ProcessPoolExecutor # 先设置线程数限制 import os import torch os.environ["OMP_NUM_THREADS"] = "2" torch.set_num_threads(2) with ProcessPoolExecutor(max_workers=8) as executor: results = list(executor.map(my_custom_grid_searching_function, list_of_tuples))
内容的提问来源于stack exchange,提问作者Brandon Lewallen
相关产品推荐
相关产品推荐

