试错:
在服务器训练好的参数直接被pycharm映射给覆盖了!
记得把这里取消掉! 如果在py文件中修改了代码,手动上传! 就是上面的upload!
运行结果:
运行train的结果
评估阶段:
出错了: 但是我改了
尝试并行! 只是将model改为了并行!但是还是有问题,貌似是自己训练的时候没有使用并行,所以导致!
出错了:
出问题了!
第二次运行:
如果出现路径问题的话,要edit configuration!
但是在运行期间,出现这样的情况! 不知何解!
其中num_words是需要更改的!
还是报这个错误:
出问题了
改来改去,感觉方向走偏了! 是只有在to_device()的地方才需要修改! 而没有这些的地方是不需要的!
因为它压根不需要你特意放入cuda中!
试来试去,终归不行啊!
三种方法都试了! 包括改成DistributedDataParallel()!
但是突然谋生想法, 为什么我不弄懂它的原理呢! 这样就会懂了!
现在开始懂它的源码! 包括并行的原理!
首先看李沐的书!!
最终发现了问题所在:
就是查看你的模型参数是不是在GPU
代码如下:
for param in next(model.parameters()):print(param, param.device)
print(next(model.parameters()).device)
所有的模型参数都是在CPU上的!!那还训练个锤子!
那人家报这个错误也就不离奇了:
查看DataParallel源码:
在模块级(module level)实现数据并行性。
该容器通过在 batch dimension中分块(每个设备复制一次其他对象)将指定模块的应用程序并行化。在前向传递中,module被复制到每个设备上,每个副本处理输入的一部分。在向后传递过程中,每个副本的梯度被求和到原始模块中。批处理大小应大于实际使用的gpu数量。
警告:
建议使用distributeddataparh列,而不是这个类,来进行多gpu训练,即使只有一个节点。请参阅:使用nn. parallel.distributeddataparparallel来代替multiprocessing或nn。数据并行和分布式数据并行。
允许将任意位置和关键字输入传递给DataParallel,但有些类型需要特殊处理。张量将分散在指定的dim上(默认为0)。元组、列表和dict类型将被浅层复制。其他类型将在不同的线程之间共享,如果在模型的forward pass中写入,则可能被损坏。
并行化的模块必须在device_ids[0]上有它的参数和缓冲区,然后才能运行这个datparallel模块。
警告:
在每个forward中,模块被复制到每个设备上,因此任何对forward中正在运行的模块的更新都将丢失。例如,如果模块有一个计数器属性,在每次forward中递增,它将始终保持初始值,因为更新是在forward后销毁的副本上完成的。但是,dataparhles保证设备[0]上的副本将有它的参数和缓冲区与基本并行化模块共享存储。因此,设备[0]上的参数或缓冲区的就地更新将被记录。例如,BatchNorm2d和spectral_norm()依赖于此行为来更新缓冲区。
警告:
在模块及其子模块上定义的前向和后向钩子将被调用len(device_ids)次,每个钩子的输入都位于特定的设备上。特别地,钩子只能保证按照相应设备上操作的正确顺序执行。例如,不能保证通过register_forward_pre_hook()设置的钩子会在所有len(device_ids) forward()调用之前执行,但是每个这样的钩子都会在该设备相应的forward()调用之前执行。
警告:
当module在forward()中返回一个标量(即0维张量)时,包装器将返回一个长度向量,该向量等于数据并行中使用的设备数量,包含来自每个设备的结果。
>>> net = torch.nn.DataParallel(model, device_ids=[0, 1, 2])
>>> output = net(input_var) # input_var can be on any device, including CPU
人家说输入变量可以在任何设备上,包括CPU!!
Torch.device:
torch.device代表将torch.Tensor分配到的设备的对象。torch.device包含一个设备类型(‘cpu’或‘cuda’)和可选的设备序号。如果设备序号不存在,则为当前设备。如:torch.Tensor用设备构建‘cuda’的结果等同于‘cuda:X’,其中X是torch.cuda.current_device()的结果。
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
这句话需要写的次数等于需要保存GPU上的tensor变量的个数;一般情况下这些tensor变量都是最开始读数据时的tensor变量,后面衍生的变量自然也都在GPU上.
如果是多个GPU
在代码中的使用方法为
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = Model()
if torch.cuda.device_count() > 1:model = nn.DataParallel(model,device_ids=[0,1,2])
pytorch中model=model.to(device)用法
device=torch.device(“cpu”)代表的使用cpu,而device=torch.device(“cuda”)则代表的使用GPU。
当我们指定了设备之后,就需要将模型加载到相应设备中,此时需要使用model=model.to(device),将模型加载到相应的设备中。将由GPU保存的模型加载到CPU上。
这次再次看这个错误:
在设备1上的副本1出错了!! 所以我们的代码原理没有问题! 不知道哪里出错了!
再品一下这句话:
模块必须在cuda:0上有参数和缓存! 但是参数却在cpu上! 那么必须将参数放入到GPU上!
这也说明模型的缓存和参数是独立放入的???