ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

PyTorch 高配CPU跑深度学习反而更慢(线程爆炸)

PyTorch 高配CPU跑深度学习反而更慢(线程爆炸)

PyTorch 高配CPU跑深度学习反而更慢(线程爆炸)

在Pytorch中,默认的算子内并行线程数(torch.set_num_threads)是根据系统的物理核心数而非超线程后的逻辑核心数来设置的。例如64个物理核心的CPU,PyTorch默认的算子内并行线程数就是64。

现象

同一个数据集、同一个算法在除了CPU物理核心数之外无差异的两台机器上训练或者推理时,64核机器比4核机器要慢了十倍以上。

4核64核
训练耗时150s3600s

问题原因

“高配CPU跑深度学习反而更慢”,这种现象在行业内被称为“超额订阅或线程爆炸”。

在核心数很多的处理器(如64核、128核的服务器级的CPU)上,如果不对PyTorch线程进行手动限制,主要会因为以下两个致命原因导致性能暴跌:

  1. 线程上下文切换开销(Context Switching )
    当PyTorch 默认启动64或128个线程去处理一个矩阵运算时,操作系统需要不断地在这些线程之间切换,分配CPU时间片。

结果:CPU的大量算力并没有用来算模型,而是全部浪费在了“管理和切换这些线程”的内部消耗上。核心越多,这种所谓的内耗就呈指数级上升。

  1. 内存带宽与缓存瓶颈(Cache Thrashing )
    深度学习是极其消耗内存带宽的。当几百个线程同时试图从CPU的三级缓存(L3 Cache)或系统内存中读取权重和张量时,会导致严重的内存通道拥堵。

结果:线程都在“排队”等待数据跑,CPU核心大部分时间在原地“踏步”(CPU Stalling),导致实际计算效率反而不如只有4核或8核的普通处理器。

特别要注意,如果是部署在k8s上的服务,即使在deployment限制了CPU数为4核心,在Pod里面获取到的CPU数量仍然是节点主机的CPU数量64核。

解决方法

importtorch torch.set_num_threads(2)torch.set_num_interop_threads(1)

注意:在导入torch之后立即进行设置,否则后续设置可能会不生效。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进