<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          PyTorch模型量化工具學(xué)習(xí)

          共 5378字,需瀏覽 11分鐘

           ·

          2020-09-02 18:25

          ↑ 點(diǎn)擊藍(lán)字?關(guān)注極市平臺(tái)

          作者丨Ironboy@知乎
          來(lái)源丨h(huán)ttps://zhuanlan.zhihu.com/p/144025236
          編輯丨極市平臺(tái)

          極市導(dǎo)讀

          ?

          通過(guò)減少原始模型參數(shù)的數(shù)量或比特?cái)?shù),模型量化技術(shù)能降低深度學(xué)習(xí)對(duì)內(nèi)存和計(jì)算的需求。本文主要介紹了這種量化技術(shù)的方法、流程和工具,并預(yù)測(cè)了數(shù)個(gè)有潛力的研究方向。


          官方教程(英文)
          https://pytorch.org/docs/stable/quantization.htmlpytorch.org
          官方教程(中文)
          https://pytorch.apachecn.org/docs/1.4/88.htmlpytorch.apachecn.org
          目前很多高精度的深度學(xué)習(xí)模型所需內(nèi)存、計(jì)算量和能耗巨大,并不適合部署在一些低成本的嵌入式設(shè)備中。為了解決這個(gè)矛盾,模型壓縮技術(shù)應(yīng)運(yùn)而生,其主要是通過(guò)減少原始模型參數(shù)的數(shù)量或比特?cái)?shù)來(lái)實(shí)現(xiàn)對(duì)內(nèi)存和計(jì)算需求的降低,從而進(jìn)一步降低能耗。目前性能最穩(wěn)定的就是INT8的模型量化技術(shù),相對(duì)于原始模型的FP32計(jì)算相比,INT8量化可將模型大小減少 4 倍,并將內(nèi)存帶寬要求減少 4 倍,對(duì) INT8 計(jì)算的硬件支持通常快 2 到 4 倍。值得注意的是量化主要是一種加速前向推理的技術(shù),并且絕大部分的量化算子僅支持前向傳遞。
          注:目前PyTorch的量化工具僅支持1.3及以上版本。

          應(yīng)用范圍

          數(shù)據(jù)類型:
          • weight的8 bit量化 :data_type = qint8,數(shù)據(jù)范圍為[-128, 127]
          • activation的8 bit量化:data_type = quint8,數(shù)據(jù)范圍為[0, 255]
          bias一般是不進(jìn)行量化操作的,仍然保持float32的數(shù)據(jù)類型,還有一個(gè)需要提前說(shuō)明的,weight在浮點(diǎn)模型訓(xùn)練收斂之后一般就已經(jīng)固定住了,所以根據(jù)原始數(shù)據(jù)就可以直接量化,然而activation會(huì)因?yàn)槊看屋斎霐?shù)據(jù)的不同,導(dǎo)致數(shù)據(jù)范圍每次都是不同的,所以針對(duì)這個(gè)問題,在量化過(guò)程中專門會(huì)有一個(gè)校準(zhǔn)過(guò)程,即提前準(zhǔn)備一個(gè)小的校準(zhǔn)數(shù)據(jù)集,在測(cè)試這個(gè)校準(zhǔn)數(shù)據(jù)集的時(shí)候會(huì)記錄每一次的activation的數(shù)據(jù)范圍,然后根據(jù)記錄值確定一個(gè)固定的范圍。
          支持后端:
          • 具有 AVX2 支持或更高版本的 x86 CPU:fbgemm
          • ARM CPU:qnnpack
          通過(guò)如下方式進(jìn)行設(shè)置:
          q_backend = "qnnpack" # qnnpack or fbgemmtorch.backends.quantized.engine = q_backendqconfig = torch.quantization.get_default_qconfig(q_backend)
          打印輸出可得:
          QConfig(activation=functools.partial(, reduce_range=False), weight=functools.partial(, dtype=torch.qint8, qscheme=torch.per_tensor_symmetric))
          可以看出qnnpack 的量化方式:activation量化的數(shù)據(jù)范圍是通過(guò)記錄每次運(yùn)行數(shù)據(jù)的最大最小值的統(tǒng)計(jì)直方圖導(dǎo)出的,weight為per-layer的對(duì)稱量化,整型數(shù)據(jù)范圍為[-128,127],直接用最后收斂的浮點(diǎn)數(shù)據(jù)的最大最小值作為范圍進(jìn)行量化,其他信息僅從這個(gè)打印信息暫時(shí)還得不到。

          量化方法

          1、Post Training Dynamic Quantization:這是最簡(jiǎn)單的一種量化方法,Post Training指的是在浮點(diǎn)模型訓(xùn)練收斂之后進(jìn)行量化操作,其中weight被提前量化,而activation在前向推理過(guò)程中被動(dòng)態(tài)量化,即每次都要根據(jù)實(shí)際運(yùn)算的浮點(diǎn)數(shù)據(jù)范圍每一層計(jì)算一次scale和zero_point,然后進(jìn)行量化;
          2、Post Training Static Quantization:第一種不是很常見,一般說(shuō)的Post Training Quantization指的其實(shí)是這種靜態(tài)的方法,而且這種方法是最常用的,其中weight跟上述一樣也是被提前量化好的,然后activation也會(huì)基于之前校準(zhǔn)過(guò)程中記錄下的固定的scale和zero_point進(jìn)行量化,整個(gè)過(guò)程不存在量化參數(shù)_(_scale和zero_point)的再計(jì)算;
          3、Quantization Aware Training:對(duì)于一些模型在浮點(diǎn)訓(xùn)練+量化過(guò)程中精度損失比較嚴(yán)重的情況,就需要進(jìn)行量化感知訓(xùn)練,即在訓(xùn)練過(guò)程中模擬量化過(guò)程,數(shù)據(jù)雖然都是表示為float32,但實(shí)際的值的間隔卻會(huì)受到量化參數(shù)的限制。
          至于為什么不在一開始訓(xùn)練的時(shí)候就模擬量化操作是因?yàn)?bit精度不夠容易導(dǎo)致模型無(wú)法收斂,甚至直接使用16bit進(jìn)行from scrach的量化訓(xùn)練都極其容易導(dǎo)致無(wú)法收斂,不過(guò)目前已經(jīng)有了一些tricks去緩解這個(gè)問題,但不在本文討論之列。

          量化流程

          以最常用的Post Training (Static) Quantization為例:
          1、準(zhǔn)備模型:準(zhǔn)備一個(gè)訓(xùn)練收斂了的浮點(diǎn)模型,用QuantStub和DeQuantstub模塊指定需要進(jìn)行量化的位置;
          2、模塊融合將一些相鄰模塊進(jìn)行融合以提高計(jì)算效率,比如conv+relu或者conv+batch normalization+relu,最常提到的BN融合指的是conv+bn通過(guò)計(jì)算公式將bn的參數(shù)融入到weight中,并生成一個(gè)bias;
          3. 確定量化方案:這一步需要指定量化的后端(qnnpack/fbgemm/None),量化的方法(per-layer/per-channel,對(duì)稱/非對(duì)稱),activation校準(zhǔn)的策略(最大最小/移動(dòng)平均/L2Norm(這個(gè)不太清楚,是類似TensorRT的校準(zhǔn)方式嗎???));
          4. activation校準(zhǔn):利用torch.quantization.prepare() 插入將在校準(zhǔn)期間觀察激活張量的模塊,然后將校準(zhǔn)數(shù)據(jù)集灌入模型,利用校準(zhǔn)策略得到每層activation的scale和zero_point并存儲(chǔ);
          5. 模型轉(zhuǎn)換:使用 torch.quantization.convert()函數(shù)對(duì)整個(gè)模型進(jìn)行量化的轉(zhuǎn)換。這其中包括:它量化權(quán)重,計(jì)算并存儲(chǔ)要在每個(gè)激活張量中使用的scale和zero_point,替換關(guān)鍵運(yùn)算符的量化實(shí)現(xiàn);

          量化工具

          torch.quantization:最基礎(chǔ)的量化庫(kù),里面包含模型直接轉(zhuǎn)換函數(shù)torch.quantization.quantize,量化訓(xùn)練函數(shù)torch.quantization.quantize_qat,準(zhǔn)備校準(zhǔn)函數(shù)torch.quantization.prepare等一系列工具
          quantize_per_tensor():per-ayer量化,需要手動(dòng)指定scale, zero_point和數(shù)據(jù)類型dtype;
          quantize_per_channel():per-channel量化,除了需要指定上述三個(gè)參數(shù)之外,還需要額外指定執(zhí)行per-channel量化的維度;
          torch.nn.intrinsic.quantized:提供了很多已經(jīng)融合好的模塊,如ConvBn2d,ConvBnReLU2d,直接對(duì)這些模型進(jìn)行量化
          其余的如torch.nn.quantized,torch.nn.quantized.functional......

          Quantization-Aware Training相關(guān)模塊

          torch.nn.qat:支持全連接和二維卷積操作;
          torch.nn.intrinsic.qat:對(duì)融合好的層進(jìn)行量化訓(xùn)練;
          torch.nn.qat:可以實(shí)現(xiàn)在float32數(shù)據(jù)中模仿量化的操作,即量化+反量化折騰一下。

          總結(jié)

          以上這些工具感覺是不同團(tuán)隊(duì)做的,有點(diǎn)冗余和混亂,使用上不是很(非常不)友好,限制很多,而且整套量化過(guò)程手動(dòng)部分比較多,每換一個(gè)模型都需要事先對(duì)模型的細(xì)節(jié)了解非常清楚,包括需要進(jìn)行融合模塊的名字。然而實(shí)際生產(chǎn)過(guò)程需要的是一套可以針對(duì)特定硬件平臺(tái)自動(dòng)進(jìn)行量化,并且結(jié)合相應(yīng)的深度學(xué)習(xí)編譯器進(jìn)行優(yōu)化,最終部署到移動(dòng)端/嵌入式設(shè)備中,在保證精度要求的前提下有加速效果(最好能達(dá)到實(shí)時(shí))。之前因?yàn)榻M里的項(xiàng)目需要也自己寫了一套自動(dòng)的量化工程,當(dāng)時(shí)的計(jì)劃是只需要給我提供pth文件我就能給你量化后的pth
          然而在實(shí)際研究和coding過(guò)程中發(fā)現(xiàn)了各種問題,比如:
          pth在沒有model類定義的情況下是無(wú)法單獨(dú)load的,即使是torch.save的完整模型,這個(gè)和TensorFlow的pb文件還不一樣,之前TensorFlow用的多,所以不太了解這部分,夸下了只需要pth文件的海口;
          BN的自動(dòng)融合很難cover所有的模型,因?yàn)椴粡牡讓佑?jì)算圖上進(jìn)行conv層和bn層的融合都需要去自動(dòng)識(shí)別兩個(gè)模塊,然后將兩層參數(shù)進(jìn)行融合計(jì)算,原始conv層變成一個(gè)有bias的conv層,bn層變成identity(不能完全去掉),因?yàn)榫幊谭绞降牟煌赃@種自動(dòng)識(shí)別十分困難,我目前實(shí)現(xiàn)的只能覆蓋pytorchcv這個(gè)庫(kù)里面的模型(歡迎嘗試)
          https://github.com/Ironteen/Batch-Normalization-fusiongithub.com
          我嘗試添加適應(yīng)不同方式,但是發(fā)現(xiàn)很難做到,Captain Jack大佬對(duì)這個(gè)有一些比較好的理解:https://zhuanlan.zhihu.com/p/143664360
          很難自動(dòng)去做qat,即量化感知訓(xùn)練,我自己寫了一個(gè)Conv+BN融合的層,并加入了模仿量化的操作,暫時(shí)命名為Conv_Bn_Quant,但是給我一個(gè)官方預(yù)訓(xùn)練好的pth和模型類定義文件,我需要對(duì)每個(gè)模塊做個(gè)name的映射才能將原始參數(shù)load進(jìn)我寫好的Conv_Bn_Quant中,這一步基本上就要非常了解這個(gè)模型的名字細(xì)節(jié)然后手動(dòng)寫了(說(shuō)好的智能呢,怎么還停留在人工的階段)。
          總的來(lái)說(shuō),模型的8bit量化在學(xué)術(shù)研究上剩余空間已經(jīng)不多了,因?yàn)橐恍┠P驮趐er-layer無(wú)法達(dá)到很好結(jié)果時(shí),per-channel往往可以解決這個(gè)問題,當(dāng)硬件不支持per-channel操作時(shí),用qat訓(xùn)練一下量化模型就行,所以目前再去研究如何提升量化后的精度就很難了,但在實(shí)際工程部署上面發(fā)現(xiàn)實(shí)現(xiàn)問題比較多,很難做一套完全自動(dòng)化的流程,實(shí)現(xiàn)絕大多數(shù)模型的快速部署。
          我根據(jù)查閱的資料和自己閱讀過(guò)的論文,覺得以下方向還可以繼續(xù)進(jìn)行研究(肯定不全面而且理解上存在一定誤區(qū),希望大佬多多指點(diǎn)):
          8bit的from scracth訓(xùn)練,這樣就可以實(shí)現(xiàn)訓(xùn)練加速,前段時(shí)間研讀了商湯的一篇相關(guān)論文,很有意思;
          full-quantized method,去掉中間大量的quantize和de-quantize操作,bias也進(jìn)行量化,這樣不可避免會(huì)喪失一定的靈活性(研究一下add這塊怎么對(duì)scale進(jìn)行對(duì)齊就能感受到),但整個(gè)過(guò)程中沒有float32參與了,硬件運(yùn)行是更高效的,尤其對(duì)于FPGA這種對(duì)float不是很友好的硬件;
          將乘除法用移位來(lái)代替,在保證精度的前提下進(jìn)一步提升硬件運(yùn)行效率;這個(gè)論文目前比較多,之前在ICCV2019的poster現(xiàn)場(chǎng)看到不少。
          無(wú)需提供數(shù)據(jù)或只需極少量數(shù)據(jù)就能對(duì)每一層的activation進(jìn)行校準(zhǔn),這一步對(duì)精度影響還是蠻大的,但是對(duì)于一些比較隱私的數(shù)據(jù)(如醫(yī)學(xué)),提供數(shù)據(jù)還是比較難的,所以如果能夠從模型本身獲取得到activation相關(guān)的信息然后進(jìn)行校準(zhǔn)是很有意義的,前段時(shí)間看過(guò)CVPR一篇論文就是解決這個(gè)問題,立意很好:
          https://arxiv.org/abs/2001.00281
          模型量化向其他任務(wù)上的遷移,如目標(biāo)檢測(cè),語(yǔ)義分割,人體位姿檢測(cè),NLP任務(wù),如何在不進(jìn)行量化訓(xùn)練的前提下保持較高精度(可以實(shí)現(xiàn)快速部署)。


          推薦閱讀



          添加極市小助手微信(ID : cvmart2),備注:姓名-學(xué)校/公司-研究方向-城市(如:小極-北大-目標(biāo)檢測(cè)-深圳),即可申請(qǐng)加入極市目標(biāo)檢測(cè)/圖像分割/工業(yè)檢測(cè)/人臉/醫(yī)學(xué)影像/3D/SLAM/自動(dòng)駕駛/超分辨率/姿態(tài)估計(jì)/ReID/GAN/圖像增強(qiáng)/OCR/視頻理解等技術(shù)交流群:月大咖直播分享、真實(shí)項(xiàng)目需求對(duì)接、求職內(nèi)推、算法競(jìng)賽、干貨資訊匯總、與?10000+來(lái)自港科大、北大、清華、中科院、CMU、騰訊、百度等名校名企視覺開發(fā)者互動(dòng)交流~

          △長(zhǎng)按添加極市小助手

          △長(zhǎng)按關(guān)注極市平臺(tái),獲取最新CV干貨

          覺得有用麻煩給個(gè)在看啦~??


          瀏覽 188
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级少妇A片在线观看浪莎八Av | www.亚洲黄色 | 免费看黄色片国产馆 | 日本男人天堂 | 一几毛片 |