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統計函數好使啊!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM