【[QRNN搭建][pynvrtc库] 记录解决“OSError: [WinError 126] 找不到指定的模块”问题】

导航:如果你同在搭建QRNN时遇到问题,不妨从问题1按顺序阅读
   如果搭建其他项目中遇到[WinError 126]问题,可尝试直接跳转问题2,希望能带去一些启发。


  最近在做时间序列处理,需要用到Quasi-Recurrent Neural Networks(QRNN),源码地址。但遇到了各种各样的问题,其中最主要的是标题中的问题[WinError 126]
  鉴于当前论坛中关于[WinError 126]的相关问题较少且回答较为单一,写下了第一篇博客。
 

问题1:非静态方法的forward不再支持

  先前配置:torch==1.8.1cuda==11.1。直接运行,往往会出现以下错误:

RuntimeError: Legacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method.

  原因:pytorch版本高于1.3会出现该问题。当前版本要求forward过程是静态的,所以需要将原代码进行修改。解决方法有两个:
一、修改代码(推荐)
  简单的自定义Function函数较为简单(例如常见的梯度反转,仅包含forward和backward两个函数),网上的例子也有很多。但QRNN源码中的forget_mult.py下,类GPUForgetMult中包含了自定义的编译函数compiler(self)。对于我这种没有系统学过类的人,改变量近乎不可能,调了多半天还是报错,放弃了。(其实后来发现,根本原因还是[WinError 126],其实改成功了hh)
二、torch降级
  其实根本没有“降级”一说,就是将高版本torch卸掉再装。由于高版本的cuda又和低版本的torch不匹配,加之各种冲突报错,后来干脆重新搭了个新环境。所以,如果你对python的“类”比较熟悉,同时也在用QRNN源码,建议按照“Legacy autograd function”的官方指引,将forward修改为静态的即可,不建议为了跑一个QRNN,把原环境都推倒重建。
  重新搭建了环境,当前配置为:torch==1.4.0cuda==10.1,同时安装所需的cupypynvrtc库。

  然后,就来到了标题中的问题:
 

问题2:[WinError 126] 找不到指定的模块

File "C:/XXX/pytorch-qrnn-master/torchqrnn/forget_mult.py", line 199, in <module>
    resulta = ForgetMult()(forget, a, last_h, use_cuda=True)
  File "D:\Anaconda3\envs\XXX\lib\site-packages\torch\nn\modules\module.py", line 532, in __call__
    result = self.forward(*input, **kwargs)
  File "C:/XXX/pytorch-qrnn-master/torchqrnn/forget_mult.py", line 178, in forward
    return GPUForgetMult()(f, x, hidden_init) if use_cuda else CPUForgetMult()(f, x, hidden_init)
  File "C:/XXX/pytorch-qrnn-master/torchqrnn/forget_mult.py", line 119, in forward
    self.compile()
  File "C:/XXX/pytorch-qrnn-master/torchqrnn/forget_mult.py", line 101, in compile
    program = Program(kernel, 'recurrent_forget_mult.cu')
  File "D:\Anaconda3\envs\XXX\lib\site-packages\pynvrtc\compiler.py", line 49, in __init__
    self._interface = NVRTCInterface(lib_name)
  File "D:\Anaconda3\envs\XXX\lib\site-packages\pynvrtc\interface.py", line 87, in __init__
    self._load_nvrtc_lib(lib_path)
  File "D:\Anaconda3\envs\XXX\lib\site-packages\pynvrtc\interface.py", line 110, in _load_nvrtc_lib
    self._lib = cdll.LoadLibrary(name)
  File "D:\Anaconda3\envs\XXX\lib\ctypes\__init__.py", line 426, in LoadLibrary
    return self._dlltype(name)
  File "D:\Anaconda3\envs\XXX\lib\ctypes\__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 126] 找不到指定的模块。

  “Win”的模块是指.dll文件,即找不到某个.dll文件。但请注意:这个“找不到”分两种情况:1. 真的没有该.dll文件  2. 存在该.dll文件,但没有被正确找到。
  一开始以为是情况1(即真的缺某个文件),但又论坛中类似的帖子不一样,报错没有告诉你具体缺哪个.dll,于是各种盲目重装C++运行库,还是于事无补。
  注意到报错中可能和pynvrtc库有关,就去github上的pynvrtc-issue中挨个找相关问题,终于先后找到了两个有联系的回答:回答1回答2
  结论:层层寻找,在pynvrtc库中interface.py文件下的NVRTCInterface类中,将第96行附近的:

            if system() == 'Windows':
                def_lib_name = 'nvrtc64_92.dll'

修改为:对应你的cuda版本号,我是10.1,所以是_101_0)

            if system() == 'Windows':
                def_lib_name = 'nvrtc64_101_0.dll'  # 对应你的cuda版本号

  同时,需检查你的环境目录X:\XXX\Anaconda3\envs\环境名\Library\bin中有该nvrtc64_101_0.dll文件,名称需与以上代码块中刚刚修改的语句完全一致。如果没有,自行百度下载对应cuda版本的nvrtc64.dll文件即可。
  至此,最大的问题终于解决了。距离运行forget_mult.py就只剩下一些小问题,简单列出一个:
 

问题3: ‘bytes’ object has no attribute ‘encode’

  此时若直接运行forget_mult.py,大概率会出现如下错误:

AttributeError: 'bytes' object has no attribute 'encode'

AttributeError: 'Program' object has no attribute '_program'

  溯源具体报错,推测出现了重复编码(.encode())的问题。定位GPUForgetMult类下的compile(self)函数(方法),将103行附近的:

program = Program(kernel.encode(), 'recurrent_forget_mult.cu'.encode())

两个变量的.encode()后缀删去,即改为:

 program = Program(kernel, 'recurrent_forget_mult.cu')

即可解决。
  剩下便是些小细节,例如输出维度等等,便不再一一列举。
 

总结

  当出现”[WinError 126] 找不到指定的模块“的错误时,基本可以断定和.dll文件有关。具体可能有两种情况
  1. 指定位置中确实没有该.dll文件。
  2. 该.dll文件存在,但没有被正确定位和调用(本例)
 
  还有,就是出了问题之后不能只会把报错的最后一行粘贴到百度或者Google上,要静下心来逐行查看出错提示,往往能推断出出错位置,再结合论坛和自身经验完成debug。
  (第一篇blog,希望后面有机会多多记录,帮到更多的人吧)

好的,我可以帮你介绍如何用Python实现QRNN。 QRNN (Quasi-Recurrent Neural Network) 是一种新型的深度学习模型,能够有效地处理时间序列数据。相比于传统的循环神经网络 (RNN),QRNN 在处理长序列时具有更好的性能和可扩展性。 下面是使用Python实现QRNN的步骤: 1. 首先,导入必要的,包括Keras、TensorFlow等。 ```python import keras import tensorflow as tf ``` 2. 定义模型的输入和输出。对于QRNN模型,输入通常是一个形状为 `(batch_size, time_steps, input_dim)` 的张量,其中 `batch_size` 表示每个批次的样本数量,`time_steps` 表示时间步数,`input_dim` 表示每个时间步的特征维数。输出通常是一个形状为 `(batch_size, output_dim)` 的张量,其中 `output_dim` 表示输出的维数。 ```python inputs = keras.layers.Input(shape=(time_steps, input_dim)) x = keras.layers.QRNN(units=64, window_size=3, dropout=0.2)(inputs) outputs = keras.layers.Dense(output_dim, activation='softmax')(x) ``` 在这里,我们使用 `keras.layers.QRNN()` 函数来定义一个具有 `64` 个隐藏单元、窗口大小 `3` 和 `dropout` 概率 `0.2` 的QRNN层。 3. 编译模型。在这一步中,我们需要为模型指定优化器、损失函数和评估指标。 ```python model = keras.models.Model(inputs=inputs, outputs=outputs) optimizer = keras.optimizers.Adam(lr=0.001) model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy']) ``` 在这里,我们使用 `Adam` 优化器,`categorical_crossentropy` 损失函数和 `accuracy` 评估指标。 4. 训练模型。在这一步中,我们需要使用 `model.fit()` 函数来训练模型,并指定训练数据和相关的参数。 ```python history = model.fit(x_train, y_train, batch_size=32, epochs=10, validation_data=(x_val, y_val)) ``` 在这里,我们使用 `x_train` 和 `y_train` 表示训练数据和训练标签,`x_val` 和 `y_val` 表示验证数据和验证标签。我们还指定每个批次的大小为 `32`,训练 `10` 个周期。 5. 评估模型。在这一步中,我们需要使用 `model.evaluate()` 函数来评估模型的性能。 ```python test_loss, test_acc = model.evaluate(x_test, y_test) print('Test loss: %.4f, test accuracy: %.4f' % (test_loss, test_acc)) ``` 在这里,我们使用 `x_test` 和 `y_test` 表示测试数据和测试标签。我们将输出模型的测试损失和测试精度。 以上就是使用Python实现QRNN的全部步骤。希望能对您有所帮助!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值