You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在SLURM集群上并行化Sklearn随机森林回归器?解决n_jobs失效问题

在SLURM集群上并行运行Scikit-learn随机森林的解决方案

首先,你遇到的n_jobs=-1在SLURM环境下失效的问题,通常是因为Scikit-learn默认的loky并行后端没正确感知SLURM分配的CPU资源,或者作业提交时没明确指定可用核数。而ipyparallel的错误则是因为你没有预先在SLURM集群上启动对应的IPython控制器和引擎进程,这个流程在集群环境中配置繁琐,不推荐作为首选。下面给你几个更易用的替代方案:


方案1:修复默认n_jobs的使用方式

先确保你的SLURM作业脚本正确分配了CPU资源,示例脚本如下:

#!/bin/bash
#SBATCH --job-name=rf_parallel
#SBATCH --nodes=1
#SBATCH --cpus-per-task=16  # 根据需求分配CPU核数
#SBATCH --mem=32G
#SBATCH --time=1:00:00

python your_script.py

然后在代码里,不要直接用n_jobs=-1,而是通过SLURM环境变量获取分配的核数,避免资源冲突或被SLURM限制:

from sklearn.ensemble import RandomForestRegressor
import os

def fit_predict(X_train, y, X_test):
    # 从SLURM环境变量读取分配的CPU核数,默认1核兜底
    n_cpus = int(os.environ.get('SLURM_CPUS_PER_TASK', 1))
    regr = RandomForestRegressor(n_jobs=n_cpus)
    try:
        regr.fit(X_train, y)
        pred = regr.predict(X_test)
        return pred
    except Exception as e:
        print(f"训练过程出错:{e}")
        return None

方案2:使用Joblib + Dask分布式后端

Dask能很好适配SLURM集群,支持单节点/跨节点并行,适合处理大规模数据集。

步骤1:安装依赖

pip install dask distributed joblib

步骤2:SLURM作业脚本(单节点示例)

#!/bin/bash
#SBATCH --job-name=dask_rf
#SBATCH --nodes=1
#SBATCH --cpus-per-task=16
#SBATCH --mem=32G
#SBATCH --time=1:00:00

python your_script.py

步骤3:代码实现

from sklearn.ensemble import RandomForestRegressor
from joblib import parallel_backend
from dask.distributed import Client
import os

def fit_predict(X_train, y, X_test):
    # 启动Dask本地集群,使用SLURM分配的所有核
    client = Client(n_workers=int(os.environ.get('SLURM_CPUS_PER_TASK', 1)))
    print(f"Dask客户端已连接:{client}")
    
    regr = RandomForestRegressor(n_jobs=-1)
    try:
        with parallel_backend('dask'):
            regr.fit(X_train, y)
            pred = regr.predict(X_test)
        client.close()
        return pred
    except Exception as e:
        print(f"训练过程出错:{e}")
        client.close()
        return None

如果需要跨节点并行,可以使用dask-jobqueue包自动在SLURM上启动Dask worker,配置更灵活。


方案3:使用Ray分布式框架

Ray是轻量且强大的分布式计算框架,对Scikit-learn的支持友好,适配SLURM环境的成本低。

步骤1:安装依赖

pip install ray scikit-learn

步骤2:SLURM作业脚本

#!/bin/bash
#SBATCH --job-name=ray_rf
#SBATCH --nodes=1
#SBATCH --cpus-per-task=16
#SBATCH --mem=32G
#SBATCH --time=1:00:00

python your_script.py

步骤3:代码实现

from sklearn.ensemble import RandomForestRegressor
from joblib import parallel_backend
import ray
from ray.util.joblib import register_ray
import os

def fit_predict(X_train, y, X_test):
    # 初始化Ray集群,使用SLURM分配的CPU核数
    ray.init(num_cpus=int(os.environ.get('SLURM_CPUS_PER_TASK', 1)))
    register_ray()
    
    regr = RandomForestRegressor(n_jobs=-1)
    try:
        with parallel_backend('ray'):
            regr.fit(X_train, y)
            pred = regr.predict(X_test)
        ray.shutdown()
        return pred
    except Exception as e:
        print(f"训练过程出错:{e}")
        ray.shutdown()
        return None

Ray会自动管理集群资源,无需手动配置控制器和进程,使用起来更省心。


关于ipyparallel错误的补充说明

如果一定要用ipyparallel,你需要先在SLURM上完成两步前置操作:

  1. 启动IPython控制器:ipcontroller --profile=myprofile
  2. 通过SLURM提交引擎作业:srun ipengine --profile=myprofile
  3. 再运行你的训练代码

但这个流程需要手动管理控制器和引擎的生命周期,在集群环境中维护成本高,所以优先推荐前面三个方案。

内容的提问来源于stack exchange,提问作者Fangzhou Li

火山引擎 最新活动