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;

--------------------------2021年07月01日09:54:39 更新----
cudaDeviceSynchronize();
这个放置的位置有问题把。这句话应该放在结束时间之前!
正确的代码如下:

#include<cuda.h>
#include<cuda_runtime.h>

auto t_3 = std::chrono::steady_clock::now();
// 一段代码

cudaDeviceSynchronize();//这句话应该放在结束时间之前!
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统计函数好使啊!

posted @ 2020-05-12 16:13  无左无右  阅读(4589)  评论(1编辑  收藏  举报