zoukankan      html  css  js  c++  java
  • libtorch 报错与解决

    1.error: conversion from ‘at::TensorAccessor<float, 2ul, at::DefaultPtrTraits, long int>’ to non-scalar type ‘at::Tensor’ requested

         torch::Tensor result_data = result_.accessor<float,2>();//        torch::Tensor result_data = result_.cpu().accessor<float,2>();
    

    定位到代码中的语句

     torch::Tensor result_data = result_.accessor<float,2>();
    

    各种试,result是二维的啊,是float的啊!!!
    转到了cpu了啊!!
    奔溃~~,我看别人也是这么写的啊!!
    例子:

    torch::Tensor one = torch::randn({9,6});
    auto foo_one=one.accessor<float,2>();
    for(int i=0,sum=0;i<foo_one.size(0);i++)
     for(int j=0;j<foo_one.size(1);j++)
         sum+=foo_one[i][j];
    

    然后的然后,我把 torch::Tensor result_data = result_.accessor<float,2>();改成

     auto result_data = result_.accessor<float,2>();
    

    编译通过了!!!!ヾ(。`Д´。)!!!!!
    这个问题找了我半个小时多!!!!原来已经不是torch::Tensor类型了,需要用auto啊!!

    2. pytorch转到libtorch显存偏多问题

    一般用测试代码直接加两句话就可以转成功libtorch模型

    output = model(image)
    traced_script_module = torch.jit.trace(model, image)
    traced_script_module.save("/data_2/v3+resnet.pt")
    

    就是这个测试代码流程一般就是定义模型,加载模型,数据处理,模型推理,后处理这些部分组成

    model = DeepLab(num_classes=num_classes_,
                    backbone=backbone_,
                    output_stride=output_stride_,
                    sync_bn=sync_bn_,
                    freeze_bn=freeze_bn_)
    model = model.cuda()
    
    checkpoint = torch.load(model_path)
    model.load_state_dict(checkpoint['state_dict'])
    del checkpoint
    
    dataload_test = make_data_loader_my_test(path_txt,crop_size,batch_size)
    for i, sample in enumerate(dataload_test):
        print(i)
        image = sample[0]
        if cuda:
            image = image.cuda()
        with torch.no_grad():
            model = model.eval() ####重要!! 测试的时候一定要加上 要不然bn层还会重新计算  是test模式就直接用
            output = model(image)
    
            traced_script_module = torch.jit.trace(model, image)
            traced_script_module.save("/data_2/v3+resnet.pt")
            break
    
        pred = output.data.cpu().numpy()
        pred = np.argmax(pred, axis=1)
    

    一般就是上面的这段代码,在pytorch端一点问题都没有,可以在libtorch端显存变2倍啊!pytorch端900M,libtorch端1800M!!

    几天后,然后对比了之前没有问题的脚本,实验了一下果真可以!多了的话如下:

    model = DeepLab(num_classes=num_classes_,
                    backbone=backbone_,
                    output_stride=output_stride_,
                    sync_bn=sync_bn_,
                    freeze_bn=freeze_bn_)
    
    for param in model.parameters():
            param.requires_grad = False
    
    model = model.cuda()
    

    原来转libtorch需要自己加上这句话啊!!!

    3

    ValueError: Auto nesting doesn't know how to process an input object of type int. Accepted types: Tensors, or lists/tuples of them

    在pytorch1.1 cuda10上是可以的,但是在pytorch1.0 cuda8上面就报上面的错误。trace的时候
    traced_script_module = torch.jit.trace(self.dla, x)
    折腾几个小时已经解决,把class IDAUP的forward
    def forward(self, layers, startp, endp):
    startp, endp是int形的,转成tensor,再在forward里面解析出int
    endp = endp.cpu().numpy()[0]
    解决方案如上,在此记录一下!
    https://github.com/xi11xi19/CenterNet2TorchScript/issues/5

    4 libtorch 运行时间问题

    一般情况下,我们用c++或者opencv自带的函数统计函数运行时间

    auto t_3 = std::chrono::steady_clock::now();
    // 一段代码
    auto ttt = std::chrono::duration_cast<std::chrono::milliseconds>
                (std::chrono::steady_clock::now() - t_3).count();
        std::cout << "-step3--(--)consume time="<<ttt<<"ms"<<std::endl;
    

    可是一个很诡异的现象是在一个函数中我调用同一个libtorch函数torch::nonzero(ind_mask.squeeze(0));,刚进来的时候耗时50ms,然后该函数调用torch::nonzero(ind_mask.squeeze(0));5次,只有第一次的时候显示50ms,
    然后后面4次0ms,下张图片进来还是这个现象。。。这么说每张都是这样了??
    找了很久很久原因。。。未果。。然后去问同事,同事告诉我需要加cuda同步

    #include<cuda.h>
    #include<cuda_runtime.h>
    
    
    cudaDeviceSynchronize();
    auto t_3 = std::chrono::steady_clock::now();
    // 一段代码
    auto ttt = std::chrono::duration_cast<std::chrono::milliseconds>
                (std::chrono::steady_clock::now() - t_3).count();
        std::cout << "-step3--(--)consume time="<<ttt<<"ms"<<std::endl;
    

    如此,就可以了!!
    但是后面又遇到问题了,就是我需要看哪个函数耗时,然后把每个函数时间运行前运行后统计,然后发现总时间大于各个函数时间运行之和,而且是大于2倍!!!
    同事说我是不是有些函数没有统计到?不是的,我都统计了,然后我再各个函数里面刚开始加上cudaDeviceSynchronize();也不行。。。。
    目前还没有即=解决,先在这里记录一下!!!。。
    解决了,jiamin让我在
    auto out_center = process_centernet(input_tensor);后面加
    sleep(1);
    一开始是这样的:

     cudaDeviceSynchronize();
        auto t_2 = std::chrono::steady_clock::now();
    
        auto out_center = process_centernet(input_tensor);///////////////////////////////
    //    sleep(1);
        torch::Tensor out_ct_hm = std::get<0>(out_center);
        torch::Tensor out_wh = std::get<1>(out_center);
        torch::Tensor out_cnn_feature = std::get<2>(out_center);
    
        ttt = std::chrono::duration_cast<std::chrono::milliseconds>
                (std::chrono::steady_clock::now() - t_2).count();
        std::cout << "-step2--centernet consume time="<<ttt<<"ms"<<std::endl;
    

    统计出来的是23ms左右
    然后就了sleep(1)就变成了1089ms这样子,!!!!说还有统计时间的先提前出来了。加 cudaDeviceSynchronize();也没有用。
    然后用cuda的统计函数,

    #include<cuda.h>
    #include<cuda_runtime.h>
    #include <cuda_runtime_api.h>
    
    
     cudaEvent_t e_start, e_stop;
        //创建事件
        cudaEventCreate(&e_start);
        cudaEventCreate(&e_stop);
        //记录事件,开始计算时间
        cudaEventRecord(e_start, 0);
    
    // 运行代码
    
      //记录结束时事件
        cudaEventRecord(e_stop, 0);// 0 代表CUDA流0
        //等待事件同步后
        cudaEventSynchronize(e_stop);
        //计算对应的时间,评估代码性能
        float elapsedTime;
        cudaEventElapsedTime(&elapsedTime, e_start, e_stop);
        std::cout << " --##cuda center all time = ##-- ="<<elapsedTime<<"s"<<std::endl;
    

    这个统计出来就是89ms!!!原来还是用cuda统计函数好使啊!

  • 相关阅读:
    JavaScript语言基础
    IP地址分类及CIDR划分方法
    Python静态方法实现单实例模式
    【转载】http和socket之长连接和短连接
    DDoS攻击
    Vue自定义过滤器
    解决跨域问题
    微信菜单创建
    canvas标签(1)--线条、矩形、圆形、文本、阴影、抛小球
    Bootstrap CSS概览代码文字标注篇
  • 原文地址:https://www.cnblogs.com/yanghailin/p/12876899.html
Copyright © 2011-2022 走看看