前言
我創(chuàng)作這篇博客的目的是記錄學(xué)習(xí)技術(shù)過程中的筆記。希望通過分享自己的學(xué)習(xí)經(jīng)歷,能夠幫助到那些對相關(guān)領(lǐng)域感興趣或者正在學(xué)習(xí)的人們。
理論
1.參考資源
1.神經(jīng)網(wǎng)絡(luò)的壓縮算法:6種神經(jīng)網(wǎng)絡(luò)的壓縮方法
2.深度學(xué)習(xí)推理架構(gòu):主流的深度學(xué)習(xí)推理架構(gòu)、AI模型部署落地綜述(ONNX/NCNN/TensorRT)
3.TensorFlow 模型優(yōu)化:TensorFlow 模型優(yōu)化工具包
2.其他
1.將深度學(xué)習(xí)模型移植到嵌入式端時(shí),提高推理速度的方法
- 硬件加速:使用專用芯片(例如GPU、NPU等)或FPGA進(jìn)行硬件加速可以大幅提升推理速度。
- 模型壓縮:對于已經(jīng)訓(xùn)練好的模型,可以通過減少參數(shù)量、降低精度等方式來達(dá)到壓縮的效果。常見的方法包括剪枝、量化和蒸餾等。
- 網(wǎng)絡(luò)結(jié)構(gòu)優(yōu)化:優(yōu)化網(wǎng)絡(luò)結(jié)構(gòu)也是一種有效地提高推理速度的方式。比如改變網(wǎng)絡(luò)層數(shù)、調(diào)整通道數(shù)目和內(nèi)存消耗等。
- 編譯器優(yōu)化:針對不同平臺(tái)開發(fā)相應(yīng)編譯器,并且在編譯過程中嘗試各種技巧以最大限度地利用處理器功能單元和內(nèi)存帶寬,進(jìn)行代碼自動(dòng)向量化。
2.深度學(xué)習(xí)模型移植到嵌入式端的主要流程
- 對原始模型進(jìn)行剪枝/壓縮/轉(zhuǎn)換等操作以適配嵌入式設(shè)備。
- 針對特定平臺(tái)編寫底層驅(qū)動(dòng)程序。
- 針對特定平臺(tái)編寫適配深度學(xué)習(xí)模型的推理引擎。
- 進(jìn)行端到端的測試和優(yōu)化,不斷調(diào)整以實(shí)現(xiàn)最佳性能。
3.假設(shè)將已經(jīng)訓(xùn)練好的目標(biāo)檢測模型(比如YOLOv3)移植到樹莓派4B這樣一款嵌入式設(shè)備上,并且需要保證推理速度達(dá)到實(shí)時(shí)。具體流程如下
- 模型壓縮:為了適應(yīng)樹莓派4B較低的算力和存儲(chǔ)容量,可以使用剪枝、量化等技術(shù)對原始模型進(jìn)行壓縮處理。
- 硬件加速:由于樹莓派4B內(nèi)置GPU并不強(qiáng)大,因此可以考慮使用外部NPU芯片來提高推理速度。
- 軟硬件協(xié)同優(yōu)化:針對特定平臺(tái)編寫底層驅(qū)動(dòng)程序和適配深度學(xué)習(xí)模型的推理引擎。在軟硬件協(xié)同優(yōu)化方面,可以借助TensorFlow Lite或ONNX Runtime等工具進(jìn)行開發(fā)。
- 端到端測試和優(yōu)化:通過不斷地調(diào)整參數(shù)、修改網(wǎng)絡(luò)結(jié)構(gòu)以及采用更高效率的算法來實(shí)現(xiàn)最佳性能表現(xiàn)。同時(shí)也需要注意內(nèi)存消耗情況以及功耗限制等因素。
4.在樹莓派上使用ncnn推理引擎,可以采取以下措施提高推理速度
- 優(yōu)化ncnn環(huán)境配置:確保您的樹莓派上已經(jīng)安裝了所有必要的依賴,并且ncnn環(huán)境配置正確。
- 編譯ncnn
- 模型轉(zhuǎn)換:使用ncnn提供的工具將YOLO3模型從其原始格式(通常是.cfg和.weights文件)轉(zhuǎn)換為ncnn支持的格式。
- 模型優(yōu)化
- 硬件優(yōu)化
- 使用更輕量級(jí)的模型
- 減少圖像分辨率
- 并行處理:如果您的應(yīng)用程序允許,可以在樹莓派上使用多線程或多進(jìn)程來并行處理多個(gè)任務(wù),以此來提高整體效率。
5.先進(jìn)行模型壓縮再用推理模型部署是一種常見的深度學(xué)習(xí)模型部署方式,可以有效地減小模型大小并提高推理性能。
6.量化實(shí)際上發(fā)生在模型壓縮階段,是獨(dú)立于推理引擎之外的一步。它的作用是生成更小更快的量化模型。推理引擎只是基于此量化模型進(jìn)行推理。但是推理引擎轉(zhuǎn)化模型過程中支持量化,例如tensorRT INT8、tensorflow lite等等。
7.在多核CPU中,可以使用線程并發(fā)來加速推理過程。將推理任務(wù)分配給多個(gè)線程同時(shí)處理,可以利用CPU的多核能力,加速推理速度。
8.硬件以及推薦的推理引擎
- 英特爾神經(jīng)網(wǎng)絡(luò)棒2代:openvino推理引擎
- 在 Intel 的 CPU/GPU 上就使用 OpenVINO,在 Arm 的 CPU/GPU 上使用 NCNN/MNN 等,在 Nvidia GPU 上使用 TensorRT。
Python加速方案
1.參考資源
1.Python量化策略的算法性能提升指南
2.其他
1.numba 數(shù)值計(jì)算加速 上百倍提升 性價(jià)比最高的優(yōu)化方案
- 用于加速Python數(shù)值計(jì)算的開源庫
- 使用LLVM編譯器將Python代碼編譯為本地機(jī)器碼
- 將處理numpy數(shù)組的Python函數(shù)JIT編譯成機(jī)器碼執(zhí)行
在使用Numba加速Python數(shù)值計(jì)算時(shí),需要注意以下幾點(diǎn):
-
Numba只能加速一部分Python代碼,特別是那些涉及到數(shù)值計(jì)算的部分。因此,需要仔細(xì)分析代碼,選擇合適的部分進(jìn)行加速,以獲得最大的加速效果。
-
Numba只支持一部分Python語法和標(biāo)準(zhǔn)庫函數(shù),因此需要注意使用的Python語法和函數(shù)是否在Numba的支持范圍內(nèi)。一般來說,Numba支持大多數(shù)基本數(shù)據(jù)類型和NumPy數(shù)組操作,但是不支持Python標(biāo)準(zhǔn)庫中的一些模塊和函數(shù),如math模塊、random模塊等。
-
在使用Numba加速函數(shù)時(shí),需要使用@jit裝飾器將函數(shù)標(biāo)記為JIT(Just-In-Time)編譯函數(shù)。這樣,Numba就會(huì)對函數(shù)進(jìn)行編譯,從而提高其執(zhí)行速度。需要注意的是,Numba只能對一部分函數(shù)進(jìn)行加速,因此需要根據(jù)實(shí)際情況選擇要加速的函數(shù)。
-
在使用Numba加速函數(shù)時(shí),需要將函數(shù)的參數(shù)和返回值類型聲明為Numba支持的數(shù)據(jù)類型。Numba支持大多數(shù)基本數(shù)據(jù)類型和NumPy數(shù)組類型,但是不支持Python標(biāo)準(zhǔn)庫中的一些類型,如list、tuple等??梢允褂胣umba.types模塊中的數(shù)據(jù)類型來聲明函數(shù)參數(shù)和返回值類型,例如:
import numba as nb @nb.jit(nb.float32(nb.float32, nb.float32)) def add(x, y): return x + y
-
在使用Numba加速函數(shù)時(shí),需要注意函數(shù)內(nèi)部調(diào)用其他模塊的情況。如果被調(diào)用的模塊中的函數(shù)不是Numba支持的函數(shù),那么這部分代碼將無法被加速。此時(shí),可以將這部分代碼提取出來,單獨(dú)編寫一個(gè)Numba加速的函數(shù),然后在主函數(shù)中調(diào)用該函數(shù),從而實(shí)現(xiàn)對整個(gè)程序的加速。即如果在使用Numba加速的函數(shù)中調(diào)用了Numba不支持的math模塊中的函數(shù),會(huì)導(dǎo)致Numba編譯錯(cuò)誤。因此,如果要使用Numba加速的話,需要使用Numba支持的函數(shù)替代math模塊中的函數(shù)。
2.Numpy 使用ndarray代替Python自帶的list 支持大型多維數(shù)組和矩陣計(jì)算 10倍以上提升
3.Cython 麻煩 優(yōu)先找已有C庫或者numba加速或者撰寫C庫 比numba快幾倍
- 需要學(xué)專門的Cython語言
- 允許用戶以非常接近Python的語法來實(shí)現(xiàn)非常接近C的性能。
- 將Python代碼轉(zhuǎn)換為C語言代碼的工具
- 使用了Cython語言編寫,其實(shí)現(xiàn)方式和C語言非常類似,因?yàn)镃ython是一種基于Python語言的C擴(kuò)展語言,它可以將Python代碼轉(zhuǎn)換為C語言或C++代碼,然后通過編譯器進(jìn)行編譯和鏈接,生成可執(zhí)行代碼。因此,Cython代碼可以獲得接近于C語言的性能,并且可以與Python語言進(jìn)行交互。也就是說實(shí)現(xiàn)它要用Cpython語言,不能直接使用Python語言。
- Cython適用于需要高性能的Python代碼,并且可以使用C語言的庫和工具進(jìn)行擴(kuò)展的場景。需要注意的是,使用Cython進(jìn)行加速需要編寫一些額外的類型聲明和C語言代碼,因此相對于Numba而言,Cython的使用難度較高。
4.使用C庫
相關(guān)的工具包括ctypes、cffi、Swig、Boost.Python等
python調(diào)用C代碼方法與加速效果
5.多線程
- 代碼中存在一些可以并行執(zhí)行的任務(wù)。如果您的代碼中沒有這樣的任務(wù),那么多線程并不能給您帶來任何性能上的提升。
- 可以考慮使用多進(jìn)程來利用多個(gè)CPU核心同時(shí)處理幀。由于Python的全局解釋鎖(Global Interpreter Lock,GIL)會(huì)限制線程在同一時(shí)間只能在一個(gè)CPU核心上運(yùn)行,因此使用多線程并不能真正利用多個(gè)CPU核心。這意味著在任何時(shí)間點(diǎn)只有一個(gè)線程可以處于執(zhí)行狀態(tài)。即使在使用多線程的情況下,也只能有一個(gè)線程執(zhí)行 Python 代碼,而其他線程將被阻塞。因此,使用多線程來處理 CPU 密集型任務(wù)可能不會(huì)提高性能,甚至可能會(huì)降低性能。而使用多進(jìn)程可以避開這個(gè)限制,實(shí)現(xiàn)真正的并行處理。
什么是Python全局解釋器鎖GIL
Python 多進(jìn)程、多線程效率比較 - massquantity - 博客園 (cnblogs.com)
6.PyPy 比Cpython更快的解釋器 也就是換個(gè)解釋器運(yùn)行 5-10倍提升 CPython 是 Python 官方的標(biāo)準(zhǔn)解釋器
PyPy是一個(gè)Python解釋器,它通過即時(shí)編譯(JIT)技術(shù)對Python代碼進(jìn)行加速,從而獲得比CPython更高的性能表現(xiàn)。PyPy可以運(yùn)行大部分的Python代碼,而且通常不需要對代碼進(jìn)行修改,因此可以輕松地將現(xiàn)有的Python代碼遷移到PyPy上。
7.學(xué)習(xí)如何降低算法復(fù)雜度和編寫更高效的算法——最有效但最麻煩
使用8位無符號(hào)整型處理圖像數(shù)據(jù)比使用64位浮點(diǎn)型數(shù)據(jù)要快。這是因?yàn)椋?位無符號(hào)整型數(shù)據(jù)類型需要的內(nèi)存和計(jì)算資源比64位浮點(diǎn)型數(shù)據(jù)類型少得多,而且處理8位整型數(shù)據(jù)的硬件部件也更加普遍和成熟,因此可以實(shí)現(xiàn)更快的計(jì)算速度。文章來源:http://www.zghlxwxcb.cn/news/detail-861367.html
8.其他
許多第三方模塊是使用 C 擴(kuò)展編寫的,這些擴(kuò)展可以通過 Python 的 C API 與 CPython 解釋器進(jìn)行交互。這些擴(kuò)展可以提供比純 Python 代碼更高的性能,并且可以訪問底層操作系統(tǒng)和硬件的功能。也就是說第三方模塊大多已經(jīng)使用了許多 C 語言庫和函數(shù)來加速圖像處理算法的計(jì)算。例如scikit-image (skimage)是一個(gè)Python第三方圖像處理庫,它提供了許多常用的圖像處理算法和工具。skimage庫是使用Python和Cython編寫的,它使用了許多C語言庫和函數(shù)來加速圖像處理算法的計(jì)算。文章來源地址http://www.zghlxwxcb.cn/news/detail-861367.html
到了這里,關(guān)于算法在嵌入式端的部署與優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!