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