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

Slurm环境下PyTorch多进程训练频繁触发PermissionError权限拒绝问题求助

Slurm环境下PyTorch多进程训练频繁触发PermissionError权限拒绝问题求助

看起来你遇到的这个问题确实挺棘手的——以前正常跑的多进程训练,现在突然在Slurm集群上频繁触发PermissionError,还都是随机的不同文件,权限检查也没问题对吧?结合你在大学计算节点用远程存储的场景,我来帮你分析下可能的原因和对应的解决办法:

先明确下你的问题场景和报错信息:
你在大学计算节点运行PyTorch训练,数据存储在学校远程文件系统,设置了num_workers>0且同时跑多个训练任务;之前相同配置能正常运行,但现在所有任务都会随机在不同时间、不同文件上触发如下权限错误:

PermissionError: Caught PermissionError in DataLoader worker process 6.
  Original Traceback (most recent call last):
    File "/root/miniconda3/envs/MASynth/lib/python3.9/site-packages/torch/utils/data/_utils/worker.py", line 308, in _worker_loop
      data = fetcher.fetch(index)  # type: ignore[possibly-undefined]
    File "/root/miniconda3/envs/MASynth/lib/python3.9/site-packages/torch/utils/data/_utils/fetch.py", line 51, in fetch
      data = [self.dataset[idx] for idx in possibly_batched_index]
    File "/root/miniconda3/envs/MASynth/lib/python3.9/site-packages/torch/utils/data/_utils/fetch.py", line 51, in <listcomp>
      data = [self.dataset[idx] for idx in possibly_batched_index]
    File "/remote/fs/users/UNet/code/mat_unet/version_4/data_3.py", line 183, in __getitem__
      sample['semantic']= to_tensor(normalize_images(np.expand_dims(cv2.resize(read_npz(semantic_dir), dsize=(256, 256), interpolation=cv2.INTER_NEAREST), axis=0), max_val=40))
    File "/remote/fs/users/users/UNet/code/mat_unet/version_4/utils.py", line 469, in read_npz
      with np.load(file) as data:
    File "/root/miniconda3/envs/MASynth/lib/python3.9/site-packages/numpy/lib/npyio.py", line 427, in load
      fid = stack.enter_context(open(os_fspath(file), "rb"))
  PermissionError: [Errno 13] Permission denied: '/remote/fs/datasets/dataset_name/version_2.0/folder1/folder2/file.npz

可能的原因及解决办法

  • 远程存储系统的并发连接配额超限
    大部分大学集群的远程存储(比如Lustre、NFS)都会限制单用户或单任务的并发文件连接数,当你同时跑多个训练任务,每个任务又有多个DataLoader worker并行读文件,很容易触发这个限制——而且有些存储系统会把“并发超限”伪装成“权限拒绝”返回给用户。
    解决办法:

    1. 先尝试降低num_workers的数值,比如从当前的数降到2或4,减少并发读取的进程数;
    2. 开启DataLoader的persistent_workers=True,让worker进程在不同epoch之间保持存活,避免重复创建进程和重复打开文件,降低对存储系统的压力。
  • 进程文件打开数达到系统上限
    集群可能最近调整了Slurm任务的资源限制,比如每个进程允许打开的最大文件数(ulimit -n)被调低了,多worker场景下很容易打满这个限制,触发权限错误。
    解决办法:在你的Slurm提交脚本里,或者训练脚本的开头添加ulimit -n 65536(或者更大的数值,具体要看集群允许的最大值),调高文件打开数的限制。

  • 远程存储元数据临时锁或故障
    有时候远程存储的元数据服务器会出现临时的锁冲突,导致短时间内无法读取文件,表现为随机的PermissionError。
    解决办法:在你的read_npz函数里添加重试逻辑,遇到PermissionError时重试几次,比如:

    import time
    def read_npz(file, retry_times=3):
        for i in range(retry_times):
            try:
                with np.load(file) as data:
                    return data
            except PermissionError:
                if i == retry_times - 1:
                    raise
                time.sleep(0.5)
    
  • 绕过远程存储的并发限制:预加载数据到本地节点
    集群的计算节点一般都有本地临时存储(比如/tmp/scratch),读写速度快且没有远程存储的并发限制。你可以在训练前把需要的数据集拷贝到本地节点的临时目录,然后从本地读取数据。
    解决办法:在Slurm提交脚本里增加预处理步骤,比如用rsynccp把数据集拷贝到本地:

    # Slurm脚本里的预处理部分
    LOCAL_DATA=/scratch/$USER/dataset
    mkdir -p $LOCAL_DATA
    rsync -av /remote/fs/datasets/dataset_name/version_2.0/ $LOCAL_DATA/
    # 然后训练脚本读取LOCAL_DATA路径下的数据
    
  • 联系集群管理员排查
    如果以上方法都没有效果,大概率是集群的存储系统最近调整了全局配额、IO调度规则,或者存储系统本身出现了故障。直接联系集群管理员,把你的报错信息和运行场景告诉他们,请他们帮忙检查存储系统的并发连接数、用户IO配额等配置是否有变化。

备注:内容来源于stack exchange,提问作者mahnoor.fatima

火山引擎 最新活动