在进行分布式机器学习的训练时,遇到一个非常奇怪的BUG,上一个版本的代码还能够正常运行,然而在这一个版本,只要运行,就会报错'NoneType' object has no attribute 'copy'
在这里插入图片描述

发生错误的代码是一个pytorch加载模型参数的句子,ue.model.load_state_dict(final_model_param),但是我仔细分析,发现前面也同样有过load_state_dict()函数,但并没有报错,我就怀疑是函数返回值的问题:
变量final_model_param是通过一个函数返回得到的,函数如下:

@Decorator.timer  # 这个装饰器让我修了半天bug
def aggregate_with_base_value(source_list: list, out: Net):
    out_param = out.state_dict()
    for source in source_list:  # source_list就是UE
        param = source.model.state_dict()
        data_size = Param_compression(param, 4)
        print(data_size)
        source.trans_delay = Trans_delay(source, data_size)
        for var in param:  # 这里又将param的元素转成gpu上了
            out_param[var] = (param[var].cuda() + out_param[var])/2
    out.load_state_dict(out_param)
    return(out_param)

装饰器是一个计时器代码,用途是记录函数运行所需的时间,代码如下:

class Decorator:
    def __init__(self):
        pass

    @staticmethod
    def timer(func):
        def wrapper(*args, **kw):
            start = time.time()
            func(*args, **kw)
            last = time.time()-start
            print("\n----Function{} cost time :{:.3f}----".format(func.__name__, last))
        return wrapper

结果在调试的时候发现,函数aggregate_with_base_value在返回前,参数out_param都正常,但是在回到主程序的时候,变量final_model_param变成了空None
究其原因,只能说一个:装饰器把函数应有的返回值吞掉了!导致真正的返回值没有到达主函数的变量空间就被释放了。而NoneType' object has no attribute 'copy' 正是这样的报错。
事实上,NoneType报错有很多个版本,并且经常在路径错误、返回值错误这样的场合发生,其它的博文都是说在做cv的时候自己的图片路径配置错了导致类似的报错,我想提醒大家遇到这样的,首先应该耐心通过调试器去查看变量,进而快速找到原因!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐