[pytorch]无法初始化类型“_CudaDeviceProperties”错误

2024-03-20 793 views
0

有时在运行 pytorch 代码时我会收到这样的错误

Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/home/olha/arabidopsis_genomes/script_test_model_gradients_chromosome.py", line 97, in process_batch
    model = torch.load(os.path.join(base_directory, model_folder, 'model.pt'))
  File "/home/olha/.local/lib/python3.6/site-packages/torch/serialization.py", line 367, in load
    return _load(f, map_location, pickle_module)
  File "/home/olha/.local/lib/python3.6/site-packages/torch/serialization.py", line 538, in _load
    result = unpickler.load()
  File "/home/olha/.local/lib/python3.6/site-packages/torch/serialization.py", line 504, in persistent_load
    data_type(size), location)
  File "/home/olha/.local/lib/python3.6/site-packages/torch/serialization.py", line 113, in default_restore_location
    result = fn(storage, location)
  File "/home/olha/.local/lib/python3.6/site-packages/torch/serialization.py", line 95, in _cuda_deserialize
    return obj.cuda(device)
  File "/home/olha/.local/lib/python3.6/site-packages/torch/_utils.py", line 68, in _cuda
    with torch.cuda.device(device):
  File "/home/olha/.local/lib/python3.6/site-packages/torch/cuda/__init__.py", line 229, in __enter__
    _lazy_init()
  File "/home/olha/.local/lib/python3.6/site-packages/torch/cuda/__init__.py", line 162, in _lazy_init
    torch._C._cuda_init()
RuntimeError: generic_type: cannot initialize type "_CudaDeviceProperties": an object with that name is already defined

我无法弄清楚到底是什么导致了错误,也许它以某种方式与线程有关。文档、问题或论坛中没有提及此行为。我能找到的唯一提及该错误的资源是 pybind 中的以下问题:

我正在使用 pytorch 1.0.0 和 CUDA 10

回答

3

pytorch 1.0.1 和 cuda 10 中存在相同问题

0

这听起来像是某种竞争条件。@ezyang 有什么想法吗?

1

有问题的注册似乎受 GIL 保护,所以我不认为这是一场竞赛。

@olyaromanyuk @hitlk 您能否将 pip list 的输出粘贴到存在此问题的环境中?我想知道您是否安装了 PyTorch 的多个副本。

6

@ezyang

这是我的环境:

正在收集环境信息... PyTorch 版本:1.0.1.post2 是调试版本:没有用于构建 PyTorch 的 CUDA:10.0.130

操作系统:Ubuntu 16.04.5 LTS GCC版本:(Ubuntu 5.4.0-6ubuntu1~16.04.11)5.4.0 20160609 CMake版本:版本3.5.1

Python 版本:3.5 CUDA 是否可用:是 CUDA 运行时版本:10.0.130 GPU 型号和配置:GPU 0:GeForce RTX 2080 Nvidia 驱动程序版本:410.79 cuDNN 版本:/usr/lib/x86_64-linux-gnu/libcudnn.so。 7.4.1

相关库的版本: [pip3] numpy==1.14.5 [pip3] torch==1.0.1.post2 [pip3] torchvision==0.2.2.post3

并且模型是在多线程中转发的。

5

@ezyang我最近没有经常使用pytorch进行训练,所以我上次遇到这个问题是在帖子发布的日期左右,所以版本信息可能已经过时,但CUDA和驱动程序绝对与@hitlk相同。显卡不同,我使用 4 个 GTX 1080 ti。我在 Ubuntu 上为我的用户安装了 pytorch,同一台计算机上的另一个用户有他自己的安装

2

你们中的任何一个人都可以粘贴 的输出吗pip list

7
absl-py              0.7.0
astor                0.7.1
chardet              2.3.0
Cython               0.29.5
easydict             1.9
gast                 0.2.2
grpcio               1.18.0
h5py                 2.9.0
Keras-Applications   1.0.7
Keras-Preprocessing  1.0.9
Markdown             3.0.1
mock                 2.0.0
numpy                1.14.5
opencv-python        4.0.0.21
pbr                  5.1.2
Pillow               5.4.1
pip                  19.0.3
protobuf             3.6.1
pycurl               7.43.0
pygobject            3.20.0
pytesseract          0.2.6
python-apt           1.1.0b1+ubuntu0.16.4.2
PyYAML               3.13
requests             2.9.1
setuptools           39.1.0
six                  1.12.0
ssh-import-id        5.5
tensorboard          1.13.1
tensorflow-estimator 1.13.0
tensorflow-gpu       1.13.1
termcolor            1.1.0
torch                1.0.1.post2
torchvision          0.2.2.post3
ujson                1.35
urllib3              1.13.1
Werkzeug             0.14.1
wheel                0.29.0
2

您好,我遇到了与 OP 相同的问题,尝试在两个工作线程中运行相同的对象检测任务(在不同的输入上),并且只有一个 GPU。当初始化两个工作线程的网络时,我使用 将它们移动到 GPU net = net.to(device),这就是出现相同错误的地方。

目前使用 pytorch 1.0.1 和 cuda 9.0。

4

运行多线程且每个线程只有一个 GPU 时也会出现同样的问题。我使用的是pytorch0.4.1和cuda9

7

此处相同,pytorch1.0.1 cuda9.0 虽然我找到了解决方法:在多线程 GPU 代码之前执行此操作

for i in range(num_gpu):
    with torch.cuda.device(i):
        torch.tensor([1.]).cuda()

应该能够消除错误

1

@senhuiguo 我同意这个解决方法,手动强制 CUDA 初始化应该有助于解决这个问题。我不确定问题的根本原因是什么。

2

1.1.0-cuda10 仍然存在问题。在主线程中预初始化 CUDA 可以缓解这个问题,但很混乱。

6

此线程上的任何人都有重现该问题的片段吗?我们可以开始寻找

9

@soumith 给你

import torch
import threading

def worker(rank):
    torch.tensor([1.]).cuda(rank)

# to fix the isuue, uncomment the following
# torch.tensor([1.]).cuda(0)
# torch.tensor([1.]).cuda(1)

t1 = threading.Thread(target=worker, args=(0,))
t2 = threading.Thread(target=worker, args=(1,))
t1.start()
t2.start()
3

@senhuiguo 我在 ubuntu 16.04 上使用 pytorch 1.1.0 二进制文件,我无法用你的代码片段重现。

In [2]: print(torch.__config__.show())
PyTorch built with:
  - GCC 4.9
  - Intel(R) Math Kernel Library Version 2019.0.3 Product Build 20190125 for Intel(R) 64 architecture applications
  - Intel(R) MKL-DNN v0.18.1 (Git Hash 7de7e5d02bf687f971e7668963649728356e0c20)
  - OpenMP 201307 (a.k.a. OpenMP 4.0)
  - NNPACK is enabled
  - CUDA Runtime 9.0
  - NVCC architecture flags: -gencode;arch=compute_35,code=sm_35;-gencode;arch=compute_50,code=sm_50;-gencode;arch=compute_60,code=sm_60;-gencode;arch=compute_70,code=sm_70;-gencode;arch=compute_50,code=compute_50
  - CuDNN 7.5.1
  - Magma 2.5.0
  - Build settings: BLAS=MKL, BUILD_TYPE=Release, CXX_FLAGS=  -Wno-deprecated -fvisibility-inlines-hidden -fopenmp -O2 -fPIC -Wno-narrowing -Wall -Wextra -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -Wno-unused-but-set-variable -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math, DISABLE_NUMA=1, PERF_WITH_AVX=1, PERF_WITH_AVX2=1, USE_CUDA=True, USE_EXCEPTION_PTR=1, USE_GFLAGS=OFF, USE_GLOG=OFF, USE_MKL=ON, USE_MKLDNN=ON, USE_MPI=OFF, USE_NCCL=True, USE_NNPACK=True, USE_OPENMP=ON,

关于您的环境还有其他提示吗?

0

@soumith

In [1]: import torch 
   ...: import threading 
   ...:  
   ...: def worker(rank): 
   ...:     torch.tensor([1.]).cuda(rank) 
   ...:  
   ...: # to fix the isuue, uncomment the following 
   ...: # torch.tensor([1.]).cuda(0) 
   ...: # torch.tensor([1.]).cuda(1) 
   ...:  
   ...:  
   ...: t1 = threading.Thread(target=worker, args=(0,)) 
   ...: t2 = threading.Thread(target=worker, args=(1,)) 
   ...: t1.start() 
   ...: t2.start() 
   ...:                                                                                                                               

Exception in thread Thread-51:
Traceback (most recent call last):
  File "/mnt/lustre/guosenhui/anaconda3/envs/mixed3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/mnt/lustre/guosenhui/anaconda3/envs/mixed3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "<ipython-input-1-e07912d6ffaf>", line 5, in worker
    torch.tensor([1.]).cuda(rank)
  File "/mnt/lustre/guosenhui/anaconda3/envs/mixed3.7/lib/python3.7/site-packages/torch/cuda/__init__.py", line 163, in _lazy_init
    torch._C._cuda_init()
RuntimeError: generic_type: cannot initialize type "_CudaDeviceProperties": an object with that name is already defined

In [2]: print(torch.__config__.show())                                                                                                
PyTorch built with:
  - GCC 4.9
  - Intel(R) Math Kernel Library Version 2019.0.3 Product Build 20190125 for Intel(R) 64 architecture applications
  - Intel(R) MKL-DNN v0.18.1 (Git Hash 7de7e5d02bf687f971e7668963649728356e0c20)
  - OpenMP 201307 (a.k.a. OpenMP 4.0)
  - NNPACK is enabled
  - CUDA Runtime 9.0
  - NVCC architecture flags: -gencode;arch=compute_35,code=sm_35;-gencode;arch=compute_50,code=sm_50;-gencode;arch=compute_60,code=sm_60;-gencode;arch=compute_70,code=sm_70;-gencode;arch=compute_50,code=compute_50
  - CuDNN 7.5.1
  - Magma 2.5.0
  - Build settings: BLAS=MKL, BUILD_TYPE=Release, CXX_FLAGS=  -Wno-deprecated -fvisibility-inlines-hidden -fopenmp -O2 -fPIC -Wno-narrowing -Wall -Wextra -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -Wno-unused-but-set-variable -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math, DISABLE_NUMA=1, PERF_WITH_AVX=1, PERF_WITH_AVX2=1, USE_CUDA=True, USE_EXCEPTION_PTR=1, USE_GFLAGS=OFF, USE_GLOG=OFF, USE_MKL=ON, USE_MKLDNN=ON, USE_MPI=OFF, USE_NCCL=True, USE_NNPACK=True, USE_OPENMP=ON,
3

@senhuiguo 你使用的是什么操作系统,以及什么 NVIDIA 驱动程序?我至少会在 docker 上尝试重现

3

@soumith CentOS Linux 版本 7.2.1511(核心),驱动程序版本:384.90

5

我遇到了同样的问题。看起来如果您尝试在线程中创建 CUDA 张量,则会产生此错误。

4

当我在一个 GPU 中使用多线程和一个线程时遇到同样的问题

0

我在随机内部遇到同样的问题。

  • ubuntu 18.04
  • 蟒蛇3.6.8
  • 火炬1.2.0
  • 驱动程序版本:418.87.00
  • CUDA版本:10.1
  • libcudnn.so.7.6.3 它似乎与线程/工作人员恕我直言有关,因为我有一个自定义数据加载器,当我使用并发 future 或线程(或分叉)时,我会收到此错误。在我运行单个线程从磁盘加载图像并将其上传到 GPU 的一个实例中,我没有收到此错误(在重复测试中)。
1

进一步证明这是与线程相关的(至少在我的情况下)是当我尝试以下操作时:

    futures = []
    with concurrent.futures.ThreadPoolExecutor(max_workers=12) as executor:
        for i in range(len(self.images)):
            file        = self.images[i]
            (co, label) = self.labels[i]
            idx         = self.index.index((co,label))
            future = executor.submit(self.__load__, (file, idx, label_size))
            futures.append(future)
    for f in futures:
       # wait for all futures in order to capture results
       # do something with f.result()
       # which essentially contains the (t_in, t_out) placed in GPU MEM

以上是我的自定义数据加载程序的一部分。下面是实际的加载迭代

def __load__(self, args):
        (file, idx, out_size) = args
        image = Image.open(file).convert('RGB')
        t_out       = torch.zeros((out_size,), dtype=torch.long)
        t_out[idx]  = 1
        t_in        = self.tf(image)
        return (t_in.cuda().float(), t_out.cuda().long())

此行为被触发。我会假设复制张量的线程上下文存在同步问题?一旦上述代码被删除并仅在主线程中执行,该行为就会消失。请记住,我在这一切之前已经完成了:

use_cuda = torch.cuda.is_available()
assert use_cuda == True
device = torch.device("cuda:0")
2

我可以用@senhuiguo 的例子重现这个问题。调试。

3

好吧,这确实是一场比赛。例如,这个 diff 可以“修复”它:

diff --git a/torch/cuda/__init__.py b/torch/cuda/__init__.py
index 411cfb7315..5abb645fc5 100644
--- a/torch/cuda/__init__.py
+++ b/torch/cuda/__init__.py
@@ -165,6 +165,7 @@ def _lazy_init():
     global _initialized, _cudart, _original_pid, _queued_calls
     if _initialized:
         return
+    _initialized = True
     if _in_bad_fork:
         from sys import version_info
         if version_info < (3, 4):
@@ -181,7 +182,6 @@ def _lazy_init():
     _cudart.cudaGetErrorName.restype = ctypes.c_char_p
     _cudart.cudaGetErrorString.restype = ctypes.c_char_p
     _original_pid = os.getpid()
-    _initialized = True
     # Important to do this after _initialized, since some queued calls
     # may themselves call _lazy_init()
     for queued_call, orig_traceback in _queued_calls:

如果您查看相关部分:

    torch._C._cuda_init()
    _cudart = _load_cudart()
    _cudart.cudaGetErrorName.restype = ctypes.c_char_p
    _cudart.cudaGetErrorString.restype = ctypes.c_char_p
    _original_pid = os.getpid()
    _initialized = True

问题是_cuda_init在某个时刻释放 GIL,这意味着另一个 Python 线程可以进入并触发相同的初始化(在我们设置_initialized = True.

2

系统信息:操作系统:Windows 10 GPU:1050ti RAM:16GB CUDA:9.0

这是点列表

套餐版本


attrs 19.1.0 awscli 1.16.193 回调 0.1.0 漂白剂 3.1.0 boto3 1.9.183 botocore 1.12.183 certifi 2019.6.16 chardet 3.0.4 Click 7.0 colorama 0.3.9 Cycler 0.10.0 Cython 0.29.11 装饰器 4.4 .0 defusedxml 0.6.0 docutils 0.14入口点0.3 ffmpeg-python 0.2.0 Flask 1.1.0 Flask-SQLAlchemy 2.4.0未来0.17.1 idna 2.8 ipykernel 5.1.1 ipython 7.6.1 ipython-genutils 0.2.0 ipywidgets 7.5.0 itsdangerous 1.1 .0 jedi 0.14.0 Jinja2 2.10.1 jmespath 0.9.4 joblib 0.13.2 jsonschema 3.0.1 jupyter 1.0.0 jupyter-client 5.2.4 jupyter-console 6.0.0 jupyter-core 4.5.0 kiwisolver 1.1.0 lxml 4.4 .1 MarkupSafe 1.1.1 matplotlib 3.1.1 Misune 0.8.4 nbconvert 5.5.0 nbformat 4.4.0 笔记本 5.7.8 numpy 1.16.4 对象检测 0.1 opencv-contrib-python 4.1.0.25 opencv-python 4.1.0.25 pandas 0.24 .2 pandocfilters 1.4.2 parso 0.5.0 pickleshare 0.7.5 Pillow 6.1.0 pip 19.2.1 prometheus-client 0.7.1 提示工具包 2.0.9 pyasn1 0.4.5 Pygments 2.4.2 pyparsing 2.4.0 PyQt5 5.13.0 PyQt5-sip 4.19.18 pyresist 0.15.2 python-dateutil 2.8.0 pytz 2019.1 pywinpty 0.5.5 PyYAML 5.1 pyzmq 18.0.2 qtconsole 4.5.1 请求 2.22.0 rsa 3.4.2 s3transfer 0.2.1 scikit-learn 0.21 .3 scipy 1.3.0 Send2Trash 1.5.0 setuptools 41.0.1 Shapely 1.6.4.post2 6 1.12.0 SQLAlchemy 1.3.5 terminado 0.8.2 testpath 0.4.2 torch 1.1.0 torchvision 0.3.0 龙卷风 6.0.3 特征 4.3.2 ubidots 1.6.6 urllib3 1.25.3 wcwidth 0.1.7 webencodings 0.5.1 Werkzeug 0.15.4 轮子 0.33.4 widgetsnbextension 3.5.0

我有同样的问题

在两个不同的文件中使用相同的 Yolo V3,尝试同时在同一个 GPU 上运行它们

文件

文件 1:thread1包含主函数的调用main1() 文件 2:thread2包含主函数的调用main2()

这是使用线程同时运行这两个文件的代码

from threading import Thread

from threads1 import main1
from threads2 import main2

t1 = Thread(target = main1,name='t1')
t2 = Thread(target = main2,name='t2')

t1.start()
t2.start()

t1.join()
t2.join()

我收到这个错误

C:\Users\Plato\Envs\vt\lib\site-packages\sklearn\utils\线性赋值.py:21: DeprecationWarning: 线性赋值模块在 0.21 中已弃用,将从 0.23 中删除。使用 scipy.optimize.linear_sum_assignment 代替。DeprecationWarning)正在加载网络.....正在加载网络.....网络已成功加载网络已成功加载线程t1中的异常:回溯(最近一次调用):文件“C:\ Users \ Plato \ AppData \ Local \ Programs \ Python\Python37\Lib\threading.py”,第 917 行,在 _bootstrap_inner self.run() 文件“C:\Users\Plato\AppData\Local\Programs\Python\Python37\Lib\threading.py”,第 865 行,在运行 self._target(*self._args, **self._kwargs) 文件“D:\vt\threads.py”,第 722 行,在 main1 model.cuda() 文件“C:\Users\Plato\Envs\ vtlib\site-packages\torch\nn\modules\module.py”,第 265 行,在 cuda 中返回 self._apply(lambda t: t.cuda(device)) 文件“C:\Users\Plato\Envs\vt\ lib\site-packages\torch\nn\modules\module.py”,第 193 行,在 _apply module._apply(fn) 文件“C:\Users\Plato\Envs\vt\lib\site-packages\torch\nn \modules\module.py”,第 193 行,在 _apply module._apply(fn) 文件“C:\Users\Plato\Envs\vt\lib\site-packages\torch\nn\modules\module.py”中,行193,在 _apply module._apply(fn) 文件“C:\Users\Plato\Envs\vt\lib\site-packages\torch\nn\modules\module.py”,第 199 行,在 _apply param.data = fn (param.data) 文件“C:\Users\Plato\Envs\vt\lib\site-packages\torch\nn\modules\module.py”,第 265 行,位于 return self._apply(lambda t: t.cuda(device)) 文件“C:\Users\Plato\Envs\vt\lib\site-packages\torch\cuda__init__.py”,第 163 行,位于 _lazy_init torch._C 中。 _cuda_init() 运行时错误:generic_type:无法初始化类型“_CudaDeviceProperties”:已定义具有该名称的对象

然后只有thread2开始并完成它的任务。thread1没有完成

请帮忙

我应该在哪里以及哪些方面为两者做出改变thread1thread2一起开始?

0

@olyaromanyuk 这个问题最近在 master 上得到了修复。请尝试下载一个 nightly 版本(或将 PR 应用到您的 PyTorch 副本;这只是 Python 的更改),看看是否可以解决问题。如果没有,请提交新问题。

2

@ezyang 我在这里没有看到任何针对 Windows 的夜间构建torch_nightly

只能找到Windows 版的torch_stable

您能告诉我我已经查看了哪个文件来设置吗_initialized = True

我有CUDA 9.0

所以安装

pip3 install https://download.pytorch.org/whl/cu90/torch-1.0.1-cp37-cp37m-win_amd64.whl

5

@Santhosh1509 未生成 CUDA 9.2 二进制文件,因为 CUDA 9,2 未正确安装在代理上,并且我们无法直接访问这些计算机。我们必须等待上游解决这个问题。

6

@ezyang 和 @peterjc123 好的那么这里提到的更改是否也对CUDA 9pytorch 版本进行了nightly?只是为了明确如果我这样做conda install pytorch cudatoolkit=9.0 -c pytorch-nightly 会解决我的问题吗?

8

找到了并行处理的解决方法。

由于GIL (Global Interpreter Lock)Python中在任何给定时间默认只运行一个线程。

发布了一个问题,线程在同时运行时无法减少两个函数的运行时间

这种解决方法似乎可以并行运行两个进程

这是代码

from threads import main1
from threads1 import main2

import time
from concurrent.futures import ProcessPoolExecutor

def run_in_parallel():
    with ProcessPoolExecutor(max_workers=2) as pool:
        start = time.time()
        fut1 = pool.submit(main1)
        fut2 = pool.submit(main2)
        for fut in (fut1, fut2):
            print(fut.result())
        end = time.time()
        print(f'[Parallel] Took {end-start} seconds')

if __name__ == '__main__':
    run_in_parallel()