1 系统环境
硬件环境(Ascend/GPU/CPU): Ascend/GPU/CPU
MindSpore版本: mindspore=2.0.0
执行模式(PyNative/ Graph):不限
Python版本: Python=3.7
操作系统平台: 不限
#2 报错信息
2.1 问题描述
将pytorch转换成mindspore代码的过程中报错AttributeError: The ‘Controller’ object has no attribute ‘to’.。
2.2 脚本信息
self.controller = Controller(self.args).to(device)
其中Controller定义为:
class Controller(nn.Module):
3 根因分析
根据文档https://www.mindspore.cn/docs/zh-CN/r2.0/migration_guide/typical_api_comparision.html?highlight=device
pytorch与mindspore device的不同
PyTorch 在构建模型时,通常会利用 torch.device 指定模型和数据绑定的设备,是在 CPU 还是 GPU 上,如果支持多 GPU,还可以指定具体的 GPU 序号。绑定相应的设备后,需要将模型和数据部署到对应设备,代码如下:
import os
import torch
from torch import nn
# bind to the GPU 0 if GPU is available, otherwise bind to CPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # 单 GPU 或者 CPU
# deploy model to specified hardware
model.to(device)
# deploy data to specified hardware
data.to(device)
# distribute training on multiple GPUs
if torch.cuda.device_count() > 1:
model = nn.DataParallel(model, device_ids=[0,1,2])
model.to(device)
# set available device
os.environ['CUDA_VISIBLE_DEVICE']='1'
model.cuda()
而在 MindSpore 中,我们通过 context 中 的 device_target 参数 指定模型绑定的设备,device_id 指定设备的序号。与 PyTorch 不同的是,一旦设备设置成功,输入数据和模型会默认拷贝到指定的设备中执行,不需要也无法再改变数据和模型所运行的设备类型。代码如下:
import mindspore as ms
ms.set_context(device_target='Ascend', device_id=0)
# define net
Model = ..
# define dataset
dataset = ..
# training, automatically deploy to Ascend according to device_target
Model.train(1, dataset)
此外,网络运行后返回的 Tensor 默认均拷贝到 CPU 设备,可以直接对该 Tensor 进行访问和修改,包括转成 numpy 格式,无需像 PyTorch 一样需要先执行 tensor.cpu 再转换成 numpy 格式。
pytorch与mindspore Module的不同
使用 PyTorch 构建网络结构时,我们会用到nn.Module 类,通常将网络中的元素定义在__init__ 函数中并对其初始化,将网络的图结构表达定义在forward 函数中,通过调用这些类的对象完成整个模型的构建和训练。nn.Module 不仅为我们提供了构建图接口,它还为我们提供了一些常用的 API ,来帮助我们执行更复杂逻辑。
MindSpore 中的 nn.Cell 类发挥着和 PyTorch 中 nn.Module 相同的作用,都是用来构建图结构的模块,MindSpore 也同样提供了丰富的 API 供开发者使用,虽然名字不能一一对应,但 nn.Module 中常用的功能都可以在nn.Cell 中找到映射。
4 解决方案
首先 torch.nn.Module => mindspore.nn.Cell
import mindspore as ms
from mindspore import ops, nn
ms.set_context(device_target='GPU', device_id = 0)
class Controller(nn.Cell):
def __init__(self):
super().__init__()
self.dense = nn.Dense(2, 3)
def construct(self, x):
return self.dense(x)
net = Controller()
print(net(ops.ones((1,2))))
[[0.00981624 0.00829783 0.00173066]]