最近優化的是一個人臉偽造檢測的專案,一些人臉檢測的技術其實也都用得到,想總結一下有過的一些思路,很多東西我并不方便說的特別細,包括一些圖,大概說一下就行,其實大家都不缺查資料學習的能力,查一下就知道了,我也是第一次做,沒人問,這些可能都很常用,而且有很多想法也要驗證,沒想清楚,麻煩輕點噴,
專案介紹
整個專案我認為是一個典型的CV類應用的一個推理優化,一開始是一個基于pytorch的串行的程式,跑在intel的cpu和Nvidia GPU上,整個流程大致上可以分為下列幾個部分
- 資料讀取,資料包括圖片或者視頻,
- 資料處理,這里我指的比較寬泛,資料輸入一個GPU端模型之前所作的資料前處理或者后處理我都總包在這一塊里面,舉個例子,CV里面會有PriorBox、NMS、decode這些演算法用來做圖片處理的演算法,我感覺這部分操作都是訪存型別的操作,有很多都是向量拼接啥的,
- 模型,這里主要指的是專案所用到的神經網路模型比如人臉檢測常用的efficientNet、mobileNet
優化方向
主要是優化了這么一些東西,
- 資料讀取層面的話我做profiling的時候,單張圖片占比其實并不大,因此并沒有做多執行緒讀取,只是后期做流水的時候考慮了一下這個問題,
- 資料處理這一塊其實問題挺多的,整個專案除開GPU端模型,很多作業都是在CPU端做的,比如說視頻抽幀、解碼、圖片人臉框選取、過濾等等,這些時間占比很高,那其實可以考慮把這些python實作的演算法通過cython調c的方式(呼叫C的方式很多,ctypes、c-ext等,但是我覺得這個是最好的,從開發成本和加速效果來說),然后在C代碼里面通過openMP和向量化來做,或者也可以在這里直接封裝cuda kernel,但是我沒試過,我覺得也沒必要,這部分演算法都是一些訪存密集型的操作我感覺
- 資料處理這一塊還包括之前說到過的用到了openCV和一些專門用來做視頻解碼的加速庫例如decord,這一塊我覺得可以看看這篇文章吧:視頻訓練加速方法,這一塊我沒有深入的去做過,
- 還是在資料處理這一塊,我發現寫演算法的那幫人一但用了pytorch就恨不得全部都用tensor,其實我覺得很多可以用Numpy來做的還是用這個來做,一方面,針對numpy有一個叫Numba的加速手段,挺方便的,另一方面,Tensor這個型別我是沒有找到一個好的辦法通過Cython把其指標傳遞給C函式,但是我這里有兩個方法可以一試,一個是考慮Tensor.data_ptr,但是這個是int型別,可以在C函式那里強制轉成指標試一下,另一方面,可以用Tensor.numpy(),這里我自己測驗是和Tensor共享記憶體的,開銷并不大,而意思就是說,cython介面那里的的引數可以寫成Tensor.numpy()就行,
- 模型這一塊的話其實在N卡上我覺得大家都是TensorRT吧感覺,主要是兩個,一個是op不支持的問題,可以通過tensorRT plugin的方式,另一個,可以用一些量化的方法,TensorRT也支持int8 的QAT,需要懂一些量化的基本原理,實在不行半精度也是可以的,另外如果TensorRT轉模型也覺得麻煩,也有一些工具例如說TRTTorch的開源工具,直接兩句話就搞定了,我有一個正在試的想法,可以試試Taso轉完,再丟回到TensorRT,沒準效果不錯,不清楚,
- 整個流程并行上其實用過這么一些方法、多行程資料拆分、MPS、affinity CPU綁核、batch推理,以及把功能做拆分,通過生產者-消費者的方式做流水,
- 然后是我這里并不是一次CPU處理->GPU模型計算的模式,CPU端和GPU端Tensor轉移很頻繁,這一部分原因也是因為給我的代碼里面搞演算法的經常動不動就.cuda(),然后又.cpu,一些Tensor操作其實pytorch既支持CPU端也支持GPU端的Tensor,而且不是計算型別的我自己覺得是沒必要特意丟到GPU上做的,為此我測驗過一些代碼,分別用的GPU端的Tensor和CPU端Tensor,CPU端反而快點,而且沒準還能減少.cuda()的次數,說回正題,這里一方面可以用pin_memory,進一步的話可以試試speedTorch,
現在大概就這么一些,我想深入做的其實包括模型優化那一塊,感覺TensorRT就是一個黑盒子,沒啥子意思,另一方面,一些openCV和視頻解碼的庫也不好直接改,感覺其實時間占比也不少,值得了解一下原理自己實作,最后其實做優化最重要的就是性能測驗,但是這種專案我感覺NV的兩個profiling工具并沒有那么好使,可以參考一下這個 profiling總結
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/356201.html
標籤:其他
