国产chinese男男gaygay视频,高清freexxxx性国产,成人久久久久久久久久久,88微拍福利,97影院在线午夜

天天實時:地平線楊志剛:基于征程5芯片的Transformer量化部署實踐與經(jīng)驗

  • 發(fā)表于: 2023-04-12 11:30:27 來源:愛卡汽車網(wǎng)

3月28日,智東西公開課組織的「自動駕駛新青年講座」第16講順利完結(jié)。在這一講中,地平線工具鏈核心開發(fā)者楊志剛以《基于征程5芯片的Transformer量化部署實踐與經(jīng)驗》為主題進行了直播講解。

楊志剛首先介紹了Transformer發(fā)展趨勢及在嵌入式智能芯片上部署的問題,之后重點講解了以征程5為例的嵌入式智能芯片的算法開發(fā)流程,并對以SwinT為例的量化精度提升和部署性能優(yōu)化做了詳細解讀,最后分析了如何在征程5上既快又好地部署Transformer模型。


(資料圖)

本次講座分為主講和Q&A兩個環(huán)節(jié),以下則是主講回顧:

大家好,我叫楊志剛,在地平線主要負責天工開物工具鏈的開發(fā),比如征程2、征程3、征程5上的系列量化工具和算法工具的一些開發(fā)和驗證工作。因此和我們公司內(nèi)部的算法團隊、編譯器團隊都有比較深入的接觸。

今天我分享的主題是《基于征程5芯片的Transformer量化部署實踐與經(jīng)驗》,然后也會從量化和部署兩個方面分析如何讓Swin-Transformer在征程5上跑得既快又好。

以下是本次講座的主要內(nèi)容,大概分為4個部分:

1、Transformer發(fā)展趨勢及在嵌入式智能芯片上部署的問題

2、以征程5為例的嵌入式智能芯片的算法開發(fā)流程

3、以SwinT為例的量化精度提升和部署性能優(yōu)化

4、如何在征程5上既快又好地部署Transformer模型

01

Transformer發(fā)展趨勢

及在嵌入式智能芯片上部署的問題

第一部分是Transformer的發(fā)展趨勢以及它在嵌入式智能芯片上的部署問題。最近,我估計大家都對Transformer勢不可擋的趨勢有所了解,它確實已經(jīng)在NLP領域甚至在圖像領域都起到了不可替代的作用。比如從2017年Transformer被提出來以后,因為它超強的序列建模和全局建模的能力,所以Transformer模型結(jié)構(gòu)其實已經(jīng)在整個智能模型結(jié)構(gòu)里有著越來越重要的地位。

一方面,它引領了一個大模型的潮流(當然這個潮流主要是指NLP領域),比如最近比較火的BERT、GPT等這樣以Transformer為基礎的模型其實在NLP領域已經(jīng)起到了一些根本性的變革,還有像GPT這種模型的參數(shù)量從億級別到千億級別,我們能看到 Transformer的容量還有模型發(fā)展的趨勢都朝著越來越大的方向發(fā)展。當然越來越大的前提是我們可以通過更大的模型去獲取更高的精度,所以這個量級基本上已經(jīng)從億級別到了千億級別、萬億級別。

另外一方面,Transformer不僅在NLP領域引領了大模型的潮流,而且在圖像領域也有著越來越重要的地位。我這里截的圖(如圖一所示)主要是它在Backbone也就是分類ImageNet上面的一個趨勢圖,可以看到隨著它的計算量、參數(shù)量越來越大,它的正確率也會越來越高。

事實上它在常見的基礎任務中(比如說常見的檢測、分割、跟蹤等這樣的任務)制作刷榜的時候,可以看到前幾名里基本上已經(jīng)遍地都是Transformer的影子了。所以比如常見的以Swin-Transformer為例的encoder,以DETR為例的decoder,還有時序、BEV等這種用Transformer做特征融合的,不管在圖像領域的哪一個階段,我們都可以把Transformer的特性和CNN結(jié)合,甚至替代CNN的模型結(jié)構(gòu)。無論是替代CNN還是和CNN結(jié)合,這兩個發(fā)展方向都已經(jīng)成為視覺領域的常用做法,所以整體上來說Transformer在現(xiàn)在的圖像領域里已經(jīng)是無法繞開的模型結(jié)構(gòu)了。

其實我在標題里面新加了一句話“通向通用人工智能的一扇門”,當然這個話我不敢說,我也是在一些別的信息上看到的?,F(xiàn)在基本上認為,在我們做特征提取的階段中,Transformer是通用人工智能的一種組件,所以也被稱為一扇門,不過這個不是我們今天要分享的重點。

Transformer確實在模型結(jié)構(gòu)上起著越來越重要的作用,但是另一方面,它在嵌入式端部署的問題也會受到越來越多的重視。具體來說,Transformer越來越大和嵌入式智能芯片部署這兩個方向的出發(fā)點是有區(qū)別的,比如說Transformer模型在發(fā)展上是越做越大、越做越寬,但是嵌入式智能芯片因為受到成本、功耗等方面的限制,導致它在算力、帶寬等很多功能方面受限,這就導致當前的嵌入式智能芯片不管是部署稍微大一點的還是小一點的Transformer模型,都會有一些吃力。

這里我講三個主要的例子。第一個因為嵌入式智能芯片受到成本和功耗的限制,所以它的算力、帶寬、內(nèi)存等方面都會受到一定的限制,這就直接導致像Transformer這樣的大模型的部署會受到限制。因為如果用一個大模型去部署一個小算力的平臺,就算不是Transformer哪怕只是普通的CNN,性能顯而易見的可能會極差,更何況是Transformer這樣的大模型在小算力平臺上的部署很明顯會有一些缺陷。

第二個特征是目前市面上比較流行的嵌入式智能芯片通常都會以低精度的方式來處理部署的模型。當然低精度之外也會少量的去支持一定精度的浮點,這個原因和算力、帶寬受限是一樣的,主要還是從成本、功耗等這方面的情況考慮的,所以這就直接導致了如果想要在嵌入式智能芯片上部署的話,那么這個模型可能要經(jīng)過一些量化,但同時量化不能有一定的精度損失。否則如果精度損失比較大的話,這個部署就是沒有意義的。

第三點是芯片的發(fā)展其實是滯后于算法的。關(guān)于這一點,在我們公司羅老師之前的分享當中(地平線羅恒博士:如何打造一顆好的自動駕駛AI芯片)有比較詳細的描述,大家如果有興趣可以去看一下。簡單來說,就是芯片從設計到正式量產(chǎn)需要經(jīng)過一個漫長的過程,這個過程可能是2-4年。因此現(xiàn)在市面上流行的嵌入式智能芯片基本上是源自于1-2年甚至更長時間之前的設計,而那時候設計的嵌入式智能芯片很大概率沒有考慮Transformer的情況,因為那時候可能大部分市面上流行的還是以CNN為主的模型,所以這樣就會造成現(xiàn)在大部分嵌入式智能芯片對CNN的部署非常友好,但是對Transformer的部署存在一定的gap。今天我們就要討論這個gap到底來自哪里。

下面我們詳細拆解一下剛剛講到的問題:Transformer部署過程中會遇到哪些問題?

第一個是量化問題,其實Transformer的量化問題現(xiàn)在我們能在很多社區(qū)的論文或者一些博客當中看到。首先,它為什么要經(jīng)過量化?我剛剛簡單講了一下,它是從成本、功耗等方面考慮的。如果用int8或者低比特的量化部署,它的好處是顯而易見的,比如可以降低功耗、提高計算速度、減少內(nèi)存和存儲的占用。這里有個數(shù)據(jù)對比,Transformer部署的時候其實會有一些常見的問題,如果熟悉量化訓練的同學應該比較清楚,Transformer模型當中有大量的非線性函數(shù),比如說像GeLU、LayerNorm這樣的東西。所以它激活值的輸出和高斯分布會有比較大的差異,這就直接導致了很大一部分之前在CNN中最常用的對稱量化的方法,可能會出現(xiàn)很明顯的精度問題。

如果要解決Transformer的量化精度問題,社區(qū)有很多常見的經(jīng)驗。我這里舉兩個例子,比如用非對稱量化等方法去處理分布不均衡或高斯分布差異較大的情況,還有一些情況可能會直接在硬件上使用浮點的SoftMax或LayerNorm,這種情況肯定是可以解決量化問題的,但實際上我們需要和硬件結(jié)合,而硬件上到底能不能支持浮點或者能不能支持非對稱性量化是我們需要考慮的另一個問題。我們今天要講的征程5的平臺,它就是一個純int8的嵌入式智能平臺,如果要在一個純int8的嵌入式智能平臺上去部署一個浮點的SoftMax或者LayerNorm顯然是不合理的。甚至有一些情況就算它是純int8的,可能也不支持非對稱量化,所以我們?nèi)绻鉀QTransformer量化不友好的問題,還需要結(jié)合硬件的特點來考慮。

Transformer模型部署的第二個問題是Transformer對算力的要求比較高。開始也講到,Transformer是近年來最受關(guān)注的神經(jīng)網(wǎng)絡模型,而Transformer在機器視覺領域最重要也是最徹底的應用就是Swin Transformer,這個工作也得到了機器視覺領域最高的獎項,馬爾獎。這里我們以Swin-Transformer為例。我們考慮Swin-Transformer這個最小的模型,它的計算量大概是4.5G左右。

說4.5G可能很多人沒有直觀概念,我做了兩個簡單的對比,這就約等于我們常用模型里的EffcientNetB4和ResNet50。說到ResNet50,很多人就有概念了,如果我們用ResNet50的水平去做部署的話,其實市面上很多算力稍微低一點的嵌入式智能芯片部署就會有點吃力了。如果有人知道地平線的歷史,比如地平線的上一代芯片跑ResNet50是可以跑的,但它的效率不是很高,而且這還是CNN的部署效率,如果在Transformer上效率會進一步降低。這樣考慮的話,整個SwinT部署的前提條件就是芯片的算力達到一定的要求。

除了剛才提到的SwinT的基礎還有量化問題之外,還有一個比較重要的問題就是我們一直在講的Transformer和CNN模型到底有哪些區(qū)別?為什么說我的芯片可以部署ResNet50,但是沒法部署Transformer呢?其實這就是CNN模型和Transformer模型之間一個比較重要的區(qū)別。如果我們比較熟悉CNN模型,就會知道CNN基本上從頭到尾只有一個卷積,或者有少量的非卷積算子,如RoiAlign。所以整個CNN模型實際上是以卷積和矩陣乘為主的。換句話說,這類算子的特征是以計算密集型算子為主。我們早期的智能芯片為什么并發(fā)能力強,因為智能芯片設計之初就是以這樣的CNN模型為出發(fā)點的,它的重點是利用并發(fā)去解決計算密集型的問題。

但在Transformer里情況是不一樣的,Transformer里除了我們剛剛說到的卷積和矩陣乘以外,還有大量像Elementwise、Reduce這樣的訪存密集型算子。訪存密集型算子和計算密集型會有明顯的區(qū)別,會要求我的訪存帶寬或者訪存本身的存儲容量比較高,同時不規(guī)則的數(shù)據(jù)搬運比較多,不像CNN中,一個4d-tensor可以從頭到尾,而且我的4d-tensor的規(guī)則可能非常明顯:W/H維度做下載樣,C維度做特征變長,這種4d-tensor的特征對整個嵌入式智能平臺是非常友好的。

但Transformer中不規(guī)則的數(shù)據(jù)搬運會明顯多很多,比如像Swin-Transformer,我們做window partition和window reverse時會有很多Reshape和Transpose的操作,這種操作帶來的問題是效率會進一步降低。事實上這個問題是整個Transformer或者說整個芯片行業(yè)都會遇到的一個問題,不僅是嵌入式智能芯片會有這樣的問題,訓練芯片也會有類似的問題。

我記得早幾年前英偉達在測試上做過一個OPS的簡單統(tǒng)計,這個細節(jié)就不說了,大體上的結(jié)論是純粹計算型的算子,比如卷積和矩陣乘這樣的算子在計算量上占比大概99.8%,但實際上它在英偉達芯片(就訓練芯片上而言)的執(zhí)行時間只有60%。換句話說,訓練芯片本身有大量的占比很低的非計算型算子,但這些算子卻花費了40%的時間。這個問題在Transformer部署嵌入式智能芯片時,會被很大程度的放大。常見的嵌入式智能芯片可能會有大量的時間浪費在訪存算子和不規(guī)則數(shù)據(jù)搬運上面。

總結(jié)一下第一部分,就是嵌入式智能芯片由于受到成本、功耗等方面的限制,設計思路和實際上需要部署的Transformer模型之間有較大的區(qū)別。

02

以征程5為例的

嵌入式智能芯片的算法開發(fā)流程

第二部分重點講一下嵌入式智能芯片的開發(fā)流程,這里雖然是以征程5為例,但實際上我們通過目前的調(diào)研或者就目前大部分嵌入式智能芯片總體上看,開發(fā)流程基本上是一致的,所以換句話說,大家要解決的問題基本上類似。

首先簡單講一下征程5的基本情況,這在之前的系列課里有比較充分的描述,是講征程5是怎么設計出來的,然后針對智駕平臺有怎樣的創(chuàng)新或者怎樣的用處,我就不多講了,這里我主要講這幾個基本情況是如何符合Transformer部署的前提條件的。然后這個也和我們剛才說的常見的嵌入式智能芯片部署的缺陷對應上。

第一點是大算力計算平臺,首先我們得有一個大算力計算平臺作為前提,才有可能去部署Transformer系列模型。如果是小算力的話,剛剛也講了,比如上一代征程3想部署Transformer可能就比較困難。

第二個重點是豐富的算子支持。我們在剛才Transformer的結(jié)構(gòu)圖中也能看到這點為什么比較重要,CNN模型的主體是以卷積為主,配合少量其他算子,如RoiAlign等。但Transformer中其實有很多很雜的算子,比如說像LayerNorm、SoftMax,還有Reshape、Transpose等,所以說智能芯片部署Swin-Transformer或者其他Transformer的前提條件除了大算力之外,還需要非常豐富的算子知識。

另外是最強的計算性能,我覺得在我們Transformer的部署中其實沒有太多的參考價值,因為它是以CNN為基礎的模型進行統(tǒng)計的,也就是以計算密集型的模型統(tǒng)計的,但Transformer的能力跟這個還是有比較明顯的差距。

最后一點是超低功耗,這點也需要多講,因為它本身也是征程5的亮點之一。地平線的征程5和天工開物工具鏈,其實已經(jīng)積累了一套比較完善的軟件工具,這套軟件工具從用戶訓練的浮點模型開始,然后做量化、訓練、編譯、部署、優(yōu)化等,最終部署到嵌入式端。以量化為例,基本上整個芯片工具鏈會提供PTQ的后量化和QAT的量化訓練這兩種量化方式。在優(yōu)化編譯階段,可以提供Checker、Calibrator和分析、仿真等工具,最終可以保證用戶的模型經(jīng)過量化、優(yōu)化后,能部署到嵌入式端。這里需要說一下早期的天工開物整個工具鏈的積累其實是基于CNN模型的,后面我也會講為什么基于CNN模型積累下的整個芯片工具鏈在處理Transformer模型時,不管是量化還是優(yōu)化部署方面都有一定缺陷。

下面是如何利用整個天工開物工具鏈幫助用戶把浮點模型快速部署到嵌入式芯片上。這就是我一開始講的,各家的芯片工具鏈、各家的嵌入式智能芯片的部署流程已經(jīng)趨于相同了,整體上都是從算法遷移代價足夠小的角度考慮,所以基本上已經(jīng)是一個標準流程了。然后我們來看一下這個流程,從浮點訓練開始,經(jīng)過PTQ后量化的校準,如果后量化的精度滿足要求我們就可以直接編譯優(yōu)化、最終部署;如果不滿足要求可以反過來去做量化感知訓練,量化感知訓練的目的是使精度達到要求,并最終去做模型定義。那么如果我們要處理這種Transformer部署優(yōu)化的流程,要處理的兩個重點就是量化調(diào)優(yōu)和編譯優(yōu)化,主要是利用量化公式去提升量化精度。第二個是在編譯過程中,用手動或自動的方式去獲取更好的部署性能。

天工開物工具鏈首次把Swin-Transformer部署在征程5上,其實沒有遇到太多困難,當然這個前提我剛剛已經(jīng)講了,首先它有大算力,然后豐富的算子知識,這兩點我們在征程5上的部署過程比較簡單。這里簡單講一下支持哪些算子,其實了解Swin-Transformer的人應該都了解,比如說有Reshape、roll、LayerNorm、matmul等。這里為什么需要算子完全支持?我們一開始做這個事情的時候發(fā)現(xiàn) ONNX opset上面沒有完全支持roll,所以當時測Swin-Transformer在其他品牌上的結(jié)果時,還需要單獨處理roll的情況。最近,我們發(fā)現(xiàn)opset上已經(jīng)支持roll了,但另一個方面說明一些嵌入式智能芯片的平臺不管是由于使用的工具還是最后部署的芯片的限制,想做到算子完全支持有一定的門檻。

第二點就是量化精度,總體上來看,量化精度經(jīng)過QAT之后,大體上量化精度損失了4個點,這里需要說明一下就是量化損失4個點可能看起來不是那么糟糕,但是我們在之前的工具鏈當中已經(jīng)沉淀了一系列的精度debug工具和提升方法。不過它的局限性可能是以CNN為主的模型,而CNN模型我們通??梢钥焖俣ㄎ怀鏊牧炕瘬p失來自哪里,但是當有一些經(jīng)驗映射到Transformer上時沒那么通用。因此在CNN經(jīng)驗積累的基礎上,我們才得到了損失4個點的結(jié)果。

最后一個是首次部署的FPS小于1,可以說性能極低,基本上不可以用。這里我們參考一下征程5上其他一些CNN的模型數(shù)據(jù),比如ResNet50大概會超過600FPS,EffcientNet LiteB4大概會超過1000FPS。實際上如果是地平線自己設計的高效模型這個數(shù)字還會更大。但我們要解決的不是CNN的問題,而是CNN和Transformer之間的gap沒有解決的問題,所以Transformer部署的瓶頸顯然不能直接使用CNN的經(jīng)驗。

第二部分總結(jié)來說就是在征程5上沉淀出的天工開物工具鏈的標準流程,雖然可以很好的解決CNN的問題,但并不能完整的解決Transformer量化部署的問題。所以接下來以Swin-Transformer為例,講解如何結(jié)合征程5平臺做量化精度提升和部署性能優(yōu)化。

03

以SwinT為例的

量化精度提升和部署性能優(yōu)化

首先第一點是我們說在CNN上積累了一套基礎配置或者說標準流程,那這個標準流程到底是指什么?這就需要講一下天工開物中量化訓練的基礎配置,不過這里不需要講PTQ的后量化,因為PTQ后量化除了方法的選擇上有一些空間外,訓練的空間不是很大,所以我們重點講一下量化訓練的技術(shù)配置。在之前的演示中,我們把PTQ跟QAT分開看,即要么執(zhí)行PTQ的后量化,要么使用 QAT的量化訓練。

但事實上我們在一些經(jīng)驗中發(fā)現(xiàn),如果我們使用PTQ的后量化參數(shù)去給QAT做初始化時,就可以給QAT的初始狀態(tài)提供一個更高的起點,這也可以保證QAT的量化訓練收斂的更快。所以目前的量化訓練,不管是CNN還是Transformer都是PTQ+QAT這樣的流程,這基本上已經(jīng)變成一種標準化操作了。另外,常見的一些CNN配置,比如全局使用int8,只在輸出階段使用int32。還有像QAT過程中有一些超參的配置,比如說Lr我們一般是10?3、10??,Epoch大概是浮點的10%-20%,這個我不需要多講,如果有量化訓練經(jīng)驗的同學,可能對這個比較了解。

然后講一下量化精度如何進行調(diào)優(yōu),其實我們非常不建議在PTQ嘗試更多的方法或者盲目的調(diào)整QAT的參數(shù),而是使用更加合理的可以快速分析出是什么導致量化損失誤差的方法。比如說我們內(nèi)部一般會把量化損失的誤差從工具角度分為三個部分,比如說是算子誤差、模型誤差還是精度誤差?可能大家都比較了解單純的一個算子經(jīng)過量化標準之后的誤差是怎樣的。模型誤差是指,比如在相同的輸入情況下,我們?nèi)プR別出有一些FeatureMap比較大或者說分布非常不均衡,這種FeatureMap其實對量化會非常不友好。還有包括模型本身的誤差,可能還包括weight這些參數(shù),比如訓練下來如果也有一些比較大的weight,其實這樣對量化也是不友好的。另外就是精度誤差,我們一般使用分布量化的方式,看模型中哪一個模塊對最終整個數(shù)據(jù)集+模型的誤差最大,這就是精度誤差。

下面這兩個圖是我們量化損失分析工具提供的一個可視化結(jié)果,我們可以從非常直觀的角度看到算子或模型本身的誤差,還有一些weight分布的誤差。第二個問題是如果我們識別出誤差比較大的計算應該怎么處理?簡單的方法是我一開始講的浮點操作,但如果芯片不支持浮點操作的話,那就應該尋求其他更高精度的表達,比如征程5上是支持一些少量int16的,但int16可能不是原生支持,因為我們可以通過簡單的操作用一些int8拼湊出來一個int16。所以如果我們想對一些算子做更高精度的表達時,優(yōu)先采取的就是int16。

另一方面,如果我們要在下一代芯片或者一個對Transformer部署友好的嵌入式智能芯片上更好的部署Transformer,可能有些算子用浮點會有更好的結(jié)果。我們這里面主要使用int16的方法來解決量化誤差的問題。以LayerNorm為例,在量化過程中我們其實是將LayerNorm拆成具體的算子,比如加減乘除、開方、add等操作,然后所有的中間結(jié)果除了輸入輸出之外,像mean、加減乘除等全部采用int16的方法,這樣可以使LayerNorm或SoftMax這兩個誤差較大的算子獲得更高的精度表達。

可能很多人會說SoftMax和LayerNorm不需要我們這樣做,也能識別出量化損失誤差,因為我一開始就講了,他們在輸出分布范圍方面就明顯不符合高斯分布,或者說像之前GeLU的情況。但其實我們在后來的一些檢測實驗中得出一些結(jié)論,一些特殊的linear或者matmul,如果有針對性地使用int16,比如在linear輸入的情況下使用int16,在有些matmul輸出的情況下使用int16,其實可以得到更好的精度結(jié)果。

第二部分是量化精度解決之后,編譯部署優(yōu)化的問題。這里我放出一些基本的統(tǒng)計數(shù)據(jù),這是編譯器或Swin-Transformer首次在征程5上部署時的基本情況。第一個是張量Tensor和向量Vector的計算比例大概是218:1,所謂的張量計算、張量Tensor實際上是指矩陣乘、卷積等操作,而向量Vector的計算,其實是指Normalization等操作,它的計算比大概是218:1。

直觀的看這個數(shù)字可能看不出來,但我們可以對比CNN的情況,如果絕大部分模型都是張量Tensor的計算結(jié)果,那這個比例其實可以接近無窮大,而在無窮大的情況下,專門針對并發(fā)設計的嵌入式智能計算平臺其實可以更好的發(fā)揮它的并行效率。而這樣一個比例,可能就需要芯片本身有更多的時間去處理向量Vector。另一方面,Reshape和Transpose的數(shù)據(jù)搬運算子占比比較高,這個可能也和一些歷史遺留問題有關(guān),比如在之前的CNN中其實都沒有遇到這類算子本身的實踐方式,所以它的功能或者性能優(yōu)化等做的不是特別完善,這也是導致Swin-Transformer部署效率極低的原因之一。

另外講一下我們整個編譯器部署的優(yōu)化,總的前提是我們不應該改變整個模型結(jié)構(gòu)和計算邏輯,這樣不管我們怎么優(yōu)化,用戶都不需要重新訓練浮點模型和量化模型。如果這個成本降下來的話,不管用戶怎么改變,我們只要等價替換就可以了。優(yōu)化方向是編譯器優(yōu)化常見的思路,比如提高數(shù)據(jù)復用,減少數(shù)據(jù)加載的帶寬,然后還有一些算子合并等。

下面重點講一下具體有哪些操作,我們大概總結(jié)了5個優(yōu)化方向,有一些需要算法側(cè)感知,有一些由編譯器側(cè)直接完成不需要算法感知。在說明過程中我們也會一一提到這些。

第一個是算子的映射優(yōu)化,簡單來說,是編譯器端去豐富算子實現(xiàn)的功能,這樣對于他們來說,每個計算單元、計算組件可以覆蓋更多的功能。這樣對部署而言,單獨的算子就可以完成多個功能,從而在算子內(nèi)部增加并行的機會。比如以matmul為例,一般來說,我們做QAT這種自注意力時會用matmul,然后在matmul前后會配合一些Transpose來使用。在這種情況下,從編譯器的角度來說,matmul可以把Transpose吃進去,這樣就是Transpose+matmul,即可以通過一個matmul算子來完成并且提高了算子并行的機會。

另一個LayerNorm的例子中也是類似的,LayerNorm前后如果有view或者Transpose操作的話,可以把前后維度變化融合到上層內(nèi)部,這樣我們就可以通過一個自定義的算子支持豐富的維度,那么view操作可以達到前后加Transpose的效果。這樣的話,這個接口的修改需要用戶感知,比如使用天工開物工具鏈對外釋放的包中提供的算子接口,才可以使用這樣的功能。當然這里其實是單純?yōu)榱藘?yōu)化性能而做的,使用原來的接口支持或部署是沒有障礙的。

第二個部分是算子融合。算子融合其實比較簡單,整個征程5的數(shù)據(jù)排布是一種多維的表示,而Reshape和Transpose操作是對CPU和GPU的數(shù)字行為作描述,所以如果我想在征程5上做多次的、連續(xù)的、線性的重排布,理論上征程5可以一次性統(tǒng)一排布。

這里比較明顯的是window partition和window reverse這兩個算子,這兩個算子內(nèi)部主要是一些Reshape、view、permute等操作,簡單來說就是不規(guī)則的數(shù)據(jù)搬運。對于征程5來說,我們優(yōu)化的方向就是把這些東西融合成一個算子去操作完成,這樣我們?nèi)プ远x一個window partition的時候,內(nèi)部就不需要感知view、permute等這樣細致的邏輯。對于編譯器來說,一條指令就可以完成window partition的操作。換句話說,像這種多個算子融合在一起的操作能不能用圖優(yōu)化或者編譯器默認去做,而不在算法側(cè)去做感知?理論上是可以的。

但圖優(yōu)化的另一個問題是需要維護大量pattern,也就是說只有在這樣的優(yōu)化規(guī)則下我才能得到最終的優(yōu)化效果。我們大概看一下window partition的維度信息和多種格式的變化,這我可以衍生出一堆的寫法。這種寫法如果要在后面的編譯階段把所有的pattern都維護起來,對于自動的圖優(yōu)化來說還不如直接在算子層面使用一個固定格式、提供參數(shù)的方式讓用戶使用,而且這種替換幾乎沒有成本,也不需要重訓。除了window partition和window reverse之外,還有一些常見的圖優(yōu)化,比如連續(xù)的Reshape和連續(xù)的Transpose的融合,這就可以直接用自動的圖優(yōu)化來做而不需要用戶側(cè)來感知。

另外一個重點是算子的實現(xiàn)優(yōu)化,這看起來可能不是那么重要,但它對性能的提升是非常有效的。我們剛才講,有一些歷史遺留因素比如Reshape、Transpose之前在CNN模型中用的比較少,所以早期征程5上是使用DDR方式去實現(xiàn)算子的。為了性能的提升,把DDR的實現(xiàn)挪到SRAM的時候,可以發(fā)現(xiàn)整個Transformer部署有比較明顯的性能提升,后面我們有詳細的數(shù)據(jù)去說明。

另外一個特征是Batch MatMul的優(yōu)化是普通循環(huán)做的tile優(yōu)化。除此之外,還有一些其他比較瑣碎的圖優(yōu)化,比如做elementwise算子或者concat/split算子。如果涉及到我前后需要用Reshape和Transpose得到一個具體維度的時候,而且只是GPU或者CPU上需要得到這個維度,但對于編譯器或者對于征程5來說,這個維度信息可以穿透到需要計算的算子內(nèi)部。比如我concat某一個維度,需要通過Reshape得到這個維度的話,其實Reshape的操作有可能只需要融合到concat,然后一次性做完就可以了。

另外,我們一直在說征程5對CNN模型是非常友好的,但是到Transformer模型上的話除了上面的圖優(yōu)化之外,還有一些比較明顯的gap:征程5上以CNN為基礎的模型仍然是最高效的模型,這一點表現(xiàn)在規(guī)則的4d-Tensor仍然是最高效的支持方式。為什么要講規(guī)則的4d-Tensor呢?因為像CNN中的一些維度信息,比如W/H是做2倍下載樣,C維度做4倍的擴充等,這些是非常有規(guī)則的。

所以在常見的嵌入式智能芯片平臺上,我們會有一些基本的對齊操作,而征程5上做的是4d-Tensor的對齊。簡單來說,我們支持三維的方式就是把一個非四維Tensor轉(zhuǎn)成四維Tensor,我們也可以把一些不是特別重要的維度或者用來判定的維度使用一來做,然后4d-Tensor再結(jié)合嵌入式智能芯片常見的對齊操作。比如Conv的話我后面會講,再比如征程5上channel維度基本上是8對齊,W維度是16對齊,如果這兩個是非4d-Tensor轉(zhuǎn)成4d-Tensor,結(jié)合對齊的情況來看,很可能在一些維度上做復雜對齊,這就會導致計算的效率極致降低,也會導致多了很多無用的計算。

所以我們基本上建議,如果可能性比較高的話可以使用一些4d的計算邏輯去替代任意維度上的操作,但這一點不是必須的,因為理論上目前在征程5上也是支持任意維度的操作的。如果想手動獲取更高性能的話,可以使用目的性比較強的對齊4d-Tensor的規(guī)則去替換原來任意維度的計算。這里舉個例子,比如我們可以用nn.Conv2d去替換nn.Linear,這個替換是等價的。比如我們把weight做一些Reshape操作,然后把2D、3D或者任意維度的東西去做一些維度融合或者維度擴充,經(jīng)過Conv也是等價的,其他像BatchNorm、LayerNorm等是要結(jié)合Conv來看的。

最后是SwinT在征程5上優(yōu)化的一個結(jié)論。通過上面一系列優(yōu)化,可以把Swin-Transformer的量化損失降低到1%左右,同時部署的效率可以達到143FPS。我們可以看一下這里的優(yōu)化選項,我們 Reshape和Transpose的優(yōu)化非常明顯,當然其他一些優(yōu)化也是重要的,因為相對于FPS小于1的情況, Reshape和Transpose可能只是跨出了第一步而已。這里需要說明一下143這個數(shù)字可能跟之前在微信公眾號發(fā)布的一些文檔里的133有些區(qū)別,不過還是以143為主,因為經(jīng)過我們在其他一些Transformer上面的探索發(fā)現(xiàn)這個數(shù)字在最近的最新版本上其實有一定的提升,相對來說可能比原來多了10FPS。然后我們也做了一個對比,這個數(shù)字跟端側(cè)最強的GPU相比不會差太多。但另一方面,我們的功耗大概只有端側(cè)最強GPU功耗的50%,這個數(shù)字還是非??捎^的。

04

如何在征程5上既快又好地

部署Transformer模型

最后講一下如何在征程5上既快又好地部署Transformer模型,并且把Swin-Transformer的經(jīng)驗推廣到其它所有Transformer模型當中。

第一部分是量化精度的調(diào)優(yōu),其實剛剛已經(jīng)講到一些了,比如我們非常不建議盲目的使用PTQ方法,而建議使用一些量化工具、分析工具來分析誤差本身的來源。另外,我們也非常不建議QAT本身的調(diào)參,因為對于工具本身的誤差來源我們可以分析算子誤差、模型誤差、精度誤差等這些方面。

我們后來發(fā)現(xiàn),在Swin-Transformer模型當中一般的模型誤差可能很難分析。這里可以舉一個最簡單的format的例子:比如我們在CNN模型當中,Conv+BN其實已經(jīng)是一個標準的format了。Conv+BN的量化一般會在Conv前面和BN后面插入量化節(jié)點,這會導致如果Conv的輸出范圍比較大,那這個范圍就不需要量化。因為整體上經(jīng)過BN之后的Normalization就可以做量化了,這部分其實是不需要考慮的。但實際上這部分在Transformer里會出現(xiàn)一個很奇怪的現(xiàn)象,就是Linear的輸出分布非常大,然后后面接的Normalization的方法是LayerNorm,而LayerNorm本身又不能和Linear一起去做量化。

所以這時候我們又會發(fā)現(xiàn)一個非常奇怪的現(xiàn)象,當我們用相似度分析模型誤差時,會發(fā)現(xiàn)Linear前面的相似度誤差可能不高,然而Linear后面的相似度誤差急劇上升、誤差很大,但是經(jīng)過LayerNorm之后誤差又降了下來。這種情況就需要分辨原來在CNN上面的結(jié)論,比如量化節(jié)點的誤差或者模型的誤差是否對Transformer非常有效?另外,我們更建議使用一些分布量化的方法去分析整個數(shù)據(jù)集或者精度上的誤差,這樣做可能更合理。遇到比較明顯的量化誤差,我們建議使用更高精度的量化方法。其實不僅是在征程5上使用int16更加方便,如果其他平臺使用浮點或者FP16、BF16這樣的浮點操作也是一個合理的解決方法。

最后講一下,量化精度的前提是輸入的浮點模型。我們發(fā)現(xiàn)量化模型相對于浮點模型來說,并不可以做到完全無損,這主要原因是當浮點模型中有一些非常大的weight或者輸出的分布非常大甚至非常不均衡時,這本身對于量化來說就是非常不友好的。所以針對這些量化不友好的模型,我們建議對浮點模型做一定的調(diào)整,比如在分布不均衡的情況上加上一些Normalization,使它對輸出的分布更加友好。

然后第二個是部署方面的建議,我們比較建議使用已經(jīng)封裝好的算子,比如像window reverse、window partition,還有matmul、LayerNorm等算子??梢酝ㄟ^天工開物芯片工具鏈里的QAT工具或者PTQ工具相應的接口去獲取這些算子,如果有興趣之后可以嘗試使用一下。另外一個比較常用的算子天工開物工具鏈也是具備的,但是在Swin-Transformer中可能沒有用到,就是MultiHeadAttention這個算子。目前,量化工具本身也是支持算子以及算子的部署優(yōu)化的。

第三個是Tensor的對齊建議,其實我剛剛也在Swin-Transformer的部署優(yōu)化中簡單提到了,這里我們把征程5的基本情況列出來,包括Conv的一些基本運算部件、支持什么樣的對齊策略。這個對齊策略如果想用細膩度優(yōu)化去提升征程5的利用率的話,我們可以結(jié)合4d-tensor的優(yōu)化思路,再結(jié)合pattern就可以進一步提高部署的利用率。Conv一般是H/W維度是26或者 channel維度是8對齊。如果對對齊策略有興趣的話可以直接看。

另一個需要講的是,除了算子在單個計算部件內(nèi)部的對齊浪費開銷之外,不同部件切換的時候也會有一些Reorder的算子開銷。這個開銷的原理比較簡單:如果上一個計算部件的判定值比較小,比如說Conv在channel維度的判定值是8,當后面接的是一個ReduceSum算子時,channel維度的判定要求是256。所以當我們把一個Conv判定要求的算子以最小單位8塞到ReduceSum當中時,我們在很大范圍里是做無效計算的。這個分析是一個比較特殊的例子,比較建議的方法是一個Conv接一個ReduceSum,這樣正好在channel維度上有一個比較大的判定。

這樣當Conv跟ReduceSum這兩個組件切換的時候,就會有比較明顯的Reorder的開銷。有一個解決方法是我們用卷積來替代ReduceSum,這樣的話計算方法也比較簡單,其實跟我們之前做Conv替代linear這樣的操作是類似的。比如我用reduce在C維度上去做ReduceSum的話,它的kernel大小就可以用(C,1,1,1)來表示,這樣我在C維度就從原來的C變成1,而Reduce on H就是(C,C,H,1)。

最后分享一下未來的一些工作。在征程5上部署SwinT其實是我們?nèi)ツ甑墓ぷ?,隨著工具鏈參考模型的發(fā)布,我們會有更多Transformer模型發(fā)布,比如說像DETR,DETR3d,PETR等,同時我們也會有更多Transformer相關(guān)的算子,比如量化Debug工具,還有一些經(jīng)驗等也會沉淀到工具鏈當中。另外,征程5上的一些生產(chǎn)模型也會探索更多Transformer模型的可能性。

其實像Swin-Transformer更多是做了一個驗證的過程——驗證征程5的可行性,但實際在生產(chǎn)模型上,如果FPS要求極高的話,我們更建議的做法是在一些CNN操作中內(nèi)嵌一些Transformer操作,比如我們可以參考現(xiàn)在比較流行的MobileNet、ViT的優(yōu)化,或者在BEV、時序上采用Transformer的方法做一些特征融合,而不使用以前那些卷積的方法。這樣少部分使用Transformer不僅能提高模型性能,而且在征程5上的部署效率也會更高。最后推廣到其他非CV任務上,事實上我們已經(jīng)在做語音方面的Transformer在征程5上的部署。

總體上我的分享就這么多,如果大家有興趣的話,可以去訪問地平線的開發(fā)者社區(qū)(https://developer.horizon.ai/),里面會有更多工具鏈的細節(jié),開放的相關(guān)文檔與參考算法,大家如果有什么問題的話也可以在里面交流。

關(guān)鍵詞: