You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地多进程执行模型拟合脚本时n>1出现巨幅性能下降的问题求助

本地多进程执行模型拟合脚本时n>1出现巨幅性能下降的问题求助

我正在开发一个作业提交脚本,用于在Torque、Slurm集群以及本地硬件上处理并行化模型拟合(基于scipy.optimize)。前两者运行正常,但本地执行时遇到了棘手的问题。

我的处理思路如下:
给定模型配置和包含M个响应变量(RVs)的数据,我需要拟合M个模型:

  1. 将数据拆分为n个块,每个块对应M个RVs的均等部分,然后保存到磁盘。
  2. 创建一个.sh脚本,加载数据并对其拟合模型。

问题仅出现在本地机器且n>1的场景下:当n==1时运行完美,但n>1时,进程速度会慢几个数量级,并且会占用所有CPU。我猜测这是因为存在某个共享资源导致进程竞争,但想不出具体是什么——毕竟所有资源都单独存在磁盘上,而且我理解脚本创建的Python进程有自己的GIL。

我已经尝试过这些解决方法,但都没奏效:

  • 使用multiprocess替代bash脚本运行可调用对象。但这也不管用(要么是不可序列化对象的问题,要么是任务莫名消失没有结果),而且我想坚持用作业脚本的方式,因为这样更容易重新运行失败的模型,也和批处理作业的运行方式更一致。
  • 尝试使用内部基于dill或cloudpickle的multiprocess分支,同样没有解决问题。
  • 通过自定义preexec_fn限制每个作业的可用核心数,结果报错:'fork' resource unavailable。

我对multiprocess的经验有限,虽然看过很多相关问题,但还是没搞清楚我的情况有什么特殊之处。如果有人能提供见解,我会非常感激。

问题细节

  • 我尝试的操作:用multiprocess运行bash脚本,该脚本执行一个处理磁盘保存文件的Python脚本。
  • 预期结果:进程正常运行,速度和不使用multiprocess时差不多。
  • 实际结果:速度慢了大约5个数量级。

举个直观的例子说明性能下降有多严重:

  • 当n==1时,拟合2个模型不到1秒。
  • 当n==2时,拟合2个模型要一整晚。

编辑1

这个问题出现在M3处理器的Macbook和Ubuntu系统的联想Thinkpad上。我尝试在HPC计算节点上运行完全相同的脚本(不提交为单独作业,只是在交互式作业中运行本地并行任务),那里运行没有任何问题。


编辑2:最小可复现示例

import subprocess
import sys
def test_parallel_fitting(n_covariates, n_models, n_processes):
    # Create two identical but independent processes
    processes = []
    n_covariates = int(n_covariates)
    n_models = int(n_models)
    n_processes = int(n_processes)
    n_models_per_process = n_models // n_processes
    for i in range(n_processes):
        command = ["python", "-c", f"""
import numpy as np
import time
from scipy import optimize
# Simple model fitting that shouldn't interact with other processes
for f in range({n_models_per_process}):
    start_time = time.time()
    X = np.random.rand(1500, {n_covariates})
    y = np.random.rand(1500)
    def model(params, X, y):
        return np.sum((y - np.dot(X, params)) ** 2)
    result = optimize.minimize(model, x0=np.ones({n_covariates}), args=(X, y))
    print(f"Process {i}:",f," finished in ", time.time() - start_time, " seconds")
"""]
        p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        processes.append(p)
    
    # Wait for completion and time it
    for p in processes:
        p.wait()
        output, error = p.communicate()
        print(output.decode())
        print(error.decode())
    print("Parallel fitting completed")

if __name__ == "__main__":
    args = sys.argv[1:]
    test_parallel_fitting(*args)

测试情况

运行流畅的命令:

python script.py 6 6 3
python script.py 6 120 10
python script.py 7 120 1

运行极慢的命令:

python script.py 7 6 3
python script.py 7 120 10
python script.py 7 120 2

看起来协变量的数量是关键问题——可能当矩阵乘法超过某个规模时,会由某个后台进程处理,导致并行工作进程都在等待这个进程释放资源?想问问大家这个脚本在你们那里的运行情况如何?


编辑3

已调整格式并移除了冗余文本。

备注:内容来源于stack exchange,提问作者Augustijn de Boer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 09:27:59