基於單機最高能效270億參數GPT模型的文本生成與理解

語言: CN / TW / HK

 作者:李鵬,王瑋,陳嘉樂,黃鬆芳,黃俊

單位:阿里雲智能機器學習平台PAI & 達摩院自然語言基礎技術

概述

GPT模型能較好的處理文本生成領域的各種任務,比如文本補全,自由問答,完形填空,寫作文,寫摘要,寫小説,寫詩歌等等。最近火爆全網的人工智能產品ChatGPT也是以GPT文本生成模型為底座。雖然GPT大模型作用在這些應用領域的效果很好,但是訓練成本非常高。以OpenAI推出的1750億的GPT-3為例,在1024張A100GPU上預估需要34天,一萬億參數的GPT-3在3072張A100顯卡上也至少需要84天;微軟/英偉達聯合推出的5300億的NLG模型,在2048張A100顯卡上耗時了3個月的訓練時間才能達到比較好的收斂效果。

針對GPT基礎模型參數量大,訓練&推理硬件資源消耗過高等問題,基於MoE的稀疏化訓練是目前最具競爭力的降本增效途徑。MoE的全稱是Mixture of Experts,其中的Expert對應的是Transfomrer模型的MLP層,在訓練的時候從多個MLP中選取一個MLP進行激活(如下圖所示)。這意味着模型可以在不增加計算強度(FLOPS/Bytes)的情況下,通過增加MLP模塊的數量來增加模型參數量級,進而提升模型在下游任務上的泛化性能。採用MoE後的稀疏Transformer模型和同等質量(驗證集loss以及zeroshot nlu下游任務性能)的稠密模型相比有將近1.2倍的訓練吞吐性能提升,1.3倍的推理吞吐性能提升。我們在稀疏架構總體設計的時候,選擇讓MoE跟純Transformer Decoder架構的GPT進行有機結合。原因是MoE跟Decoder結合效果通常會好於跟Encoder的結合效果。具體來講,Encoder是通過隨機masking的方式學習語言模型,而這種被隨機masked的token會讓expert的路由選擇出現不均衡。另一方面,考慮到Decoder類的GPT模型比Encoder類的Bert模型有更廣泛使用場景,因此我們採用GPT+MoE的技術架構路線,探索單機最高能效的綠色低碳GPT大模型訓練&推理軟硬一體化適配技術在中文文本生成場景的落地可行性。

基於當前比較成熟的分佈式MoE專家路由選擇技術,採用Switch Transformer[2]中的top-1路由機制。每個Expert根據如下的softmax函數被賦予一個概率值,取概率最高(top-1)的那個Expert當作網絡的FFN層。其中W_r是做路由選擇時需要學習的參數。

GPT-MoE訓練&推理能效分析

基礎預訓練模型訓練&推理性能分析

任何一種稠密(Dense)的GPT模型,都有一種效果與之對應的訓練&推理速度更快的稀疏(MoE)GPT模型。我們的目標是在受限硬件比如單機條件下找到這種GPT-MoE模型配置,然後通過對MoE算法進行改進來進一步提升它的訓練能效。我們通過對比稠密&稀疏模型的訓練&推理性能,來發現與稠密模型等價的高能效稀疏模型。

8種GPT模型的參數量,模型結構,訓練超參數如下表所示:

如下圖所示,1.3B+MoE32/64模型在相同的step下對比1.3B dense表現出更低的驗證集loss,其中1.3B+MoE-64模型的loss甚至低於2.7B dense模型

5個模型中,0.35B+MoE-64的訓練吞吐速度最快,是其他模型的2倍左右。其餘四個模型中,吞吐速度較高的是1.3B dense和1.3B+MoE-32,1.3B+MoE-64和2.7B dense的速度相近。如下圖所示:

推理吞吐速度方面,1.3B Dense的顯存消耗最少,0.35B+MoE64的延遲最低。

input_len = 20

output_len = 128

batch_size = 1

通過以上的圖表分析,我們能大致判斷出2.7B-Dense模型對應的高能效的稀疏模型是以1.3B的dense模型為底座,同時配置32或者64個專家的MoE模型。下面我們重點分析下1.3B+MoE-32/64和2.7B dense模型的性價比。在單機A100上預訓練200個小時後,藉助Tensorboard畫出預訓練驗證集loss曲線。我們發現在驗證集loss到達2.16時,1.3B+MoE-64模型的收斂速度是2.7B dense的1.17,1.3B+MoE-32的收斂速度落後於2.7B dense模型15%,如下圖所示:

從下圖中的基於Faster Transformer的單級單卡推理性能上看。1.3B+MoE-32和1.3B+MoE64的吞吐速度差不多且都高於2.6B dense模型,這是符合預期的,因為他們的底座大小都只有1.3B。

inference_speed_3.png

中文ZeroShot-NLU效果評測

中文文本生成效果評測

文本補全

詩歌生成

在線體驗地址:http://www.modelscope.cn/models/PAI/nlp_gpt3_text-generation_0.35B_MoE-64/summary

廣告文案生成

在線體驗地址:http://www.modelscope.cn/models/PAI/nlp_gpt3_text-generation_1.3B_MoE-32/summary

輸入prompt 類型#裙顏色#白色風格#清新圖案#刺繡裙下襬#花邊裙長#連衣裙裙領型#v領*裙款式#抽褶 類型#褲*材質#羊毛
達摩院 1.3B Dense (51200) 這款連衣裙採用了清新的白色調,給人一種清爽的感覺,同時,還帶來了清爽的視覺感。裙身上的刺繡圖案,精緻美觀,盡顯浪漫的氣息。而v領的設計,則為其增添了幾分優雅的氣息。再加上褶皺的裙襬,更是增添了靈動的感覺。 這款羊毛褲,採用了羊毛的材質,手感柔軟,穿着舒適,且不易變形,且不易變形,耐穿性強。褲子的版型是有點微微的,可以很好的修飾腿型,拉長腿部比例,顯得腿部更加修長。
達摩院 2.7B Dense (51200) 連衣裙是每個女們的必備,這款連衣裙採用了清新的綠色調,帶來一種清新淡淡雅的氣質,同時也帶來清新的視覺效果。v領的設計,更能襯托出優美的天鵝頸,還可以很好的修飾臉型和臉型,更好的展現出女性的柔美。>裙子上的花朵刺繡花邊裝飾,更具時尚氣息,更是讓人眼前一亮。 針織衫採用優質的純棉,手感柔軟,穿着舒適透氣,穿上身不勒身形。褲身採用了彈力的針織面料,手感舒適,穿着舒適親膚。褲腿處的側邊採用的開口設計,不僅可以起到修飾腿部的作用,又能夠更加的顯腿長,同時也能讓你輕鬆擁有型。
PAI 0.35B+MoE-64 (70k) 這款連衣裙採用了清新的白色調,搭配精緻的刺繡花邊,盡顯甜美氣質。v領的設計,修飾臉型,襯托出精緻的臉龐。褶皺花邊的袖口,更顯甜美氣質。 這款褲子採用了羊毛的面料,具有較好的彈性和透氣性,穿着起來舒適。褲子的版型設計,能夠很好的修飾腿型,讓你看起來更加的修長。褲子的版型設計,能夠很好的修飾腿型,讓你的腿部看起來更加的修長。
PAI 1.3B+MoE-32 (70k) 這一款碎花連衣裙採用了精緻的刺繡花朵,清新的氣息。清新的花邊,更加的清新穎,讓你在春季節的感覺。 經典百搭的一款針織衫,在視覺上的設計,讓你的同時也很好的穿搭。這款牛仔褲子的褲子採用了經過的設計,更是很好的修飾身體的腿型,穿着舒適又不緊。
PAI 1.3B+MoE-64 (70k) 清新的粉紅色連衣裙,穿上身後能夠襯托出女性的柔美。領口處採用的是花邊的設計,讓整體的層次感更加的精緻,更能凸顯甜美。圓領的領口設計,更加的修飾臉型,更顯精緻,而且不挑人的臉蛋糕裙襬,更能凸顯女性的精緻魅力 這款褲子的版型設計,可以説是腿部的位置,可以很好的拉長了身材比例,而且不會有緊繃的效果,讓人看起來更加的有型。而且有着很高的剪裁設計,能夠很好的修飾腿型,還能很好的遮肉,讓腿部的肉肉,還能很好的展現你的腿部的曲線。

作文生成

在線體驗地址:http://www.modelscope.cn/models/PAI/nlp_gpt3_text-generation_1.3B_MoE-64/summary

輸入prompt 信任老闆商店還給氣喘吁吁 美麗成為現實忘不了逼真
達摩院 1.3B Dense (51200) 回到家,我和老媽氣喘吁吁地趕到附近的小店去買了一張賀卡。我把寫得一片“對聯”的紙貼在“商店”的牆上,還給老闆20元錢。老闆還給我做了一個“會飛”的郵局董事長呢!我還在紙上寫了一些祝福語。老闆還誇我是一個誠實的好孩子呢!最後,我還當上了董事 誰不曾有過那種夢呢?誰不曾有過那種美麗,讓人嚮往的美麗呢?當你忘不了那些令人嚮往的夢時,那是一種多麼誘惑而又美麗的夢啊!在那裏人們可以大肆的陶醉一番,而在那裏人們也可以過目不忘,可為什麼呢?夢總是那麼深遠大,而又有多遠大的吸引力。
達摩院 2.7B Dense (51200) 回到家,我急不可待地把這件事説給了他們,他們聽,我剛説完還感動萬分,立刻向商店去買了盒方便麪。誰知>商店裏的老闆娘火冒三丈,拿起了那盒快就準備好的方便麪。“還給?”我急得心都快跳了出來。這時,走進商店,媽媽拿起一件外套心儀已是生了。 誰不曾有過那樣的夢呢?誰不曾有過那樣的理想呢?這畢竟是過去,而將來又會成為現實,忘不了的事,成為記憶中的一頁記憶。這其中當然包含了許多道理,也有很多無法用言的東西,但它們都會成為我心中最美麗的夢境,我迷戀着美麗而令我向往的夢!
PAI 0.35B+MoE-64 (70k) 回到家,我把我做的手工事一五一十地告訴了他,老闆氣喘吁吁地説:“你怎麼可以這樣做!你這樣做是不對的,我們應該把你的信任還給你,你看行不行?”聽完後,我心情舒暢多了,心想:我以後做事一定要細心。於是,我便把信任還給店裏,到了商店,把我買下的信 誰不曾有過美麗的夢?誰不曾有過夢的歷險?誰不曾有過美麗的夢?誰不曾有過夢的迷茫?誰都不曾有過夢的逼真?我忘不了我的夢,我的夢是成為一名畫家;我忘不了我偉大的夢:成為一名作家;我忘不了我的夢是成為一名畫家;我更忘不了我的美麗中國
PAI 1.3B+MoE-32 (70k) 回到家,我便氣喘吁吁地衝到商店,把錢還給老闆説:“老闆,你,你,我説話算數,還剩15元錢,夠本就行了!”老闆仍然不信任我,問道:“怎麼回事?”“把錢拿去還給老闆。”我只好硬着頭皮罷了。 誰不曾有過這樣的夢呢?似乎很逼真,讓人忘不了,也很難想象;似乎很難想象,但它終究是現實,夢終究是美麗的, 即使夢不是想象,它終究是逼真,因為美麗的事物總有被我們忽略的一面而不被我們忽略存而已。夢永遠在身邊,卻不在身邊,只要隨心走
PAI 1.3B+MoE-64 (70k) 回到家,老闆氣喘吁吁地説:“我還給你買了一件衣服,你快去商店給老闆買一件衣服吧!我還給你買了一件衣服,你快去商店吧!”老闆還不停地點着頭。老闆不信任他,他就把錢還給了老闆。 誰不曾有過那種夢呢?我想,那一定是美麗的夢,可是現實卻逼真的夢,成為了現實中真實的夢,讓人難以忘卻。我想,這就是我夢中的美麗夢。我的夢,成真而又真實的夢,讓人忘不了。

自研GPT-MoE算法創新&實驗分析

背景

Top-1 Gating 是目前最主流也最有效的 Routing 算法,但是也有着明顯的缺點。例如,在 Top-1 Gating 中,每一個 Token 僅會被交給一個 expert 處理,因此,時常會出現某些 expert 需要處理很多 token,而有些 expert 僅需處理極少數量的 token 的情況,這導致處理極少 token 的 expert 無法獲得足夠多的信息,無法得到充分的利用。

高能效專家路由選擇

因此,我們自研了新的路由算法,如下圖所示。我們的算法讓 expert 主動選擇固定數量(capacity)的 token,同一個 token 可以同時被不同的 expert 處理,從而使每一個 expert 都能得到充分的訓練。

最後生成的 token 的表示,則採用 weighted sum 的方式,將來自不同 expert 生成的表示加權求和並經過Expert Residual模塊,以獲得最終的 token 表示。這樣的表示,由於有多個 expert 的共同作用,因此更加魯棒。

  1. 計算 expert 對 token 的偏好:

\(S=X∗We\)

其中 \(X \in \mathbb{R}^{nd}\)是輸入的 tokens 的表示, \(W_{e} \in \mathbb{R}^{de}\)是 experts 的權重,\(n\)表示輸入 token 的數量,\(e\)表示 expert 的數量,\(d\)表示隱藏特徵的維度,\(S \in \mathbb{R}^{n*e} \)為每一個 expert 對輸入的每一個 token 的偏好程度;

  1. L-Softmax 算法訓練expert權重

訓練過程中利用 L-Softmax loss 優化 experts 的權重\(W_{e}\),實現每一個expert對token都具有可區分的的偏好。

  1. 每個 expert 選取固定數量的 token:

\(I = \text{Topk}(S, k) \)

其中,\(k\)就是我們預先確定的,每個 expert 可以處理的最多 token 的數量,\(I \in \mathbb{R}^{e*k}\)記錄了每個 expert 需要處理的 tokens 的索引;

4.計算最後的輸出:

\(Xout=a∗ExpertResidual(Experts(X,I))+(1−a)∗Experts(X,I)\)

每一個 expert 根據索引計算出對應 tokens 的表示,並將不同 expert 對同一 token 生成的表示加權求和,最後通過 Expert Residual 模塊生成最終的輸出 \(Xout \)。 

實驗分析

下圖是採用自研算法與 Top-1 Gating、s-BASE 算法的驗證集 loss 隨訓練 step 變化的曲線圖,我們可以發現,採用自研算法的驗證集 loss 始終低於 top-1 gating 和 s-BASE 算法的驗證集 loss,證明了我們自研算法的有效性。

image.png

同時,我們觀察到,驗證集 loss 首次低於 2.7 的時間,自研算法的速度是 s-BASE 的 1.48 倍,極大的減少了模型訓練的開銷。

image.png

此外,我們也分析了自研算法和 Top-1 Gating、s-BASE 的訓練吞吐,如下圖所示,採用自研算法相比於 s-BASE 的訓練吞吐提升了 1.17 倍。

image.png

基於PAI DLC的GPT-MoE預訓練

Rapidformer為EasyNLP中各種Transformer模型提供訓練加速能力,這是通過有機整合微軟的DeepSpeed,英偉達的Megatron來做到的,如下圖所示:

在GPT-MoE大模型的預訓練中,我們用到的主要訓練加速核心技術包括:

混合精度訓練(Mixed Precision Training) 採用混合精度訓練的好處主要有以下兩點:1. 減少顯存佔用,由於FP16的內存佔用只有FP32的一半,自然地就可以幫助訓練過程節省一半的顯存空間。2. 加快訓練和推斷的計算,FP16除了能節約內存,還能同時節省模型的訓練時間。具體原理如下圖所示,核心是在反向傳播參數更新的時候需要維護一個FP32的備份來避免舍入誤差,另外會通過Loss Scaling來緩解溢出錯誤。

選擇性激活重算(Selective Activation Recomputation)在神經網絡中間設置若干個檢查點(checkpoint),檢查點以外的中間結果全部捨棄,反向傳播求導數的時間,需要某個中間結果就從最近的檢查點開始計算,這樣既節省了顯存,又避免了從頭計算的繁瑣過程。實際使用時,有些layers產生的激活值大但是計算量小,需要選擇性的過濾掉這一部分的激活值,保留重要的激活值,以節省重計算量。

Zero優化器狀態切分 (The Zero Redundancy Optimizer)是一種用於大規模分佈式深度學習的新型內存優化技術。ZeRO具有三個主要的優化階段分別對應於優化器狀態,梯度和參數的劃分。我們這裏使用的是Zero-1優化器狀態分區。

序列並行 (Sequence Parallelism)是一種對長序列進行切分從而加速訓練的技術,在Tensor Parallelism的基礎上,將Transformer核的LayerNorm以及Dropout層的輸入按Sequence Length維度進行了切分,使得各個設備上面只需要做一部分的Dropout和LayerNorm即可。這樣做的好處有兩個:1. LayerNorm和Dropout的計算被平攤到了各個設備上,減少了計算資源的浪費;2. LayerNorm和Dropout所產生的激活值也被平攤到了各個設備上,進一步降低了顯存開銷。

接下來我們通過PAI-DLC產品來演示如何執行GPT-MoE的基礎預訓練。

環境準備

首先通過阿里雲產品機器學習平台PAI頁進入容器訓練DLC創建新的訓練任務,如下圖所示。

有三個關鍵的地方需要配置,分別是專屬鏡像,數據集以及執行命令。節點鏡像地址配置為:http://pai-image-manage-registry.cn-shanghai.cr.aliyuncs.com/pai/pai-rf-image-poc-moe:0.2。執行命令配置為:

cd /workspace/RapidformerPro/examples/megatron &&
bash dlc_run_pretrain_megatron_gpt.sh run 1 jiebabpe 0.125B 8 0 1 1 sel none 10000

其中dlc_run_pretrain_megatron_gpt.sh可以從EasyNLP的github中獲取:http://github.com/alibaba/EasyNLP/blob/master/examples/rapidformer/gpt_moe/run_pretrain_megatron_gpt.sh 傳遞給dlc_run_pretrain_megatron_gpt.sh的主要有以下11個參數,分別是:

MODE=$1                     #run or debug
GPUS_PER_NODE=$2            #申請的卡數
TOKENIZER=$3                #中文jiebabpe,英文gpt2bpe
MODEL_SIZE=$4               #0.125B, 0.35B, 1.3B, 3.6B 等等
MOE=$5                      #專家數量
RT=$6                       #路由類型
BATCH_SIZE=$7               #batch size
TP=$8                       #模型並行度
AC=$9                       #激活檢查點類型
ZERO=${10}                  #是否打開zero-1
SAVE_INTERVAL=${11}         #報錯ckpt的step數

資源&數據準備

由於預訓練數據集體積比較大,採用下載的方式不是很方便。藉助於DLC提供的OSS路徑的掛載功能,可以很方便的直接使用存儲在OSS上的大規模預訓練數據集。

任務資源配置建議使用單機八卡A100來訓練1.3B以上的GPT-MoE模型。

任務創建

任務創建完成後,進入任務監控頁面觀察任務執行狀態,如下所示:

點擊日誌查看運行狀態,如下所示:

基於PAI DSW的GPT-MoE微調詩歌生成

使用DLC完成GPT-MoE的基礎預訓練後,還需要對模型進行微調才能在下游任務生成領域比如詩歌,小説,文等領域獲得比較好的生成效果。接下來我們通過PAI-DSW產品來演示如何執行GPT-MoE的下游任務微調。我們以0.35B+MoE64的GPT大模型為例,嘗試對詩歌生成任務進行微調來獲得比較好的生成效果。

環境準備

首先創建DSW任務,資源類型選擇單機八卡V100-32G,如下所示:

由於預訓練checkpoint體積比較大,採用下載的方式不是很方便。藉助於DSW提供的OSS路徑的掛載功能,可以很方便的直接使用存儲在OSS上的預訓練模型來進行下游任務微調,配置方法如下圖所示。

接着配置鏡像,採用和DLC中同樣的鏡像地址:http://pai-image-manage-registry.cn-shanghai.cr.aliyuncs.com/pai/pai-rf-image-poc-moe:0.2

創建好後,點擊打開進入到DSW交互式開發環境

數據準備

首先,您需要下載用於本示例的訓練和測試集,並創建保存模型的文件夾,命令如下:

!wget http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/text_generation_datasets/poetry/train.tsv
!wget http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/text_generation_datasets/poetry/dev.tsv
--2023-01-05 06:45:39--  http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/text_generation_datasets/poetry/train.tsv
Resolving atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com (atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com)... 47.101.88.27
Connecting to atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com (atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com)|47.101.88.27|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 43411824 (41M) [text/tab-separated-values]
Saving to: ‘train.tsv’

train.tsv           100%[===================>]  41.40M  33.2MB/s    in 1.2s    

2023-01-05 06:45:40 (33.2 MB/s) - ‘train.tsv’ saved [43411824/43411824]

--2023-01-05 06:45:41--  http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/text_generation_datasets/poetry/dev.tsv
Resolving atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com (atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com)... 47.101.88.27
Connecting to atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com (atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com)|47.101.88.27|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 208167 (203K) [text/tab-separated-values]
Saving to: ‘dev.tsv’

dev.tsv             100%[===================>] 203.29K  --.-KB/s    in 0.1s    

2023-01-05 06:45:41 (1.69 MB/s) - ‘dev.tsv’ saved [208167/208167]

數據下載完成後,可以通過以下代碼查看第一條數據。在訓練集驗證集中,每一行為一條詩歌數據。

print('Training data sample:')
! head -n 1 train.tsv
print('Development set data sample:')
! head -n 1 dev.tsv
Training data sample:
半生長以客為家,罷直初來瀚海槎。始信人間行不盡,天涯更復有天涯。
Development set data sample:
雲髻高梳鬢不分,掃除虛室事元君。新糊白紙屏風上,盡畫蓬萊五色雲。

初始化

在EasyNLP專屬鏡像環境下,我們首先引入模型運行需要的各種庫,並做一些初始化。在本教程中,我們使用gpt-moe-0.35B+MoE64作為預訓練模型底座。

from functools import partial
import torch
from megatron import get_args
from megatron.model import ModelType
from megatron.utils import (average_losses_across_data_parallel_group,
get_ltor_masks_and_position_ids)
from rapidformer.application.zeroshot_nlu.zeroshot_gpt_finetuner import \
GPTFinetuner
from rapidformer.dataset.gpt_dataset import GPTDataset
from rapidformer.engine.engine import RapidformerEngine
from rapidformer.engine.initialize import get_tokenizer
from rapidformer.model.transformer.gpt_model import GPTModel

模型訓練&評估

finetuner = MegatronGPTMoEFinetuner(engine=engine)
finetuner.train()

一步執行

值得一提的是,上述所有訓練/評估,都已經被集成到EasyNLP/examples/rapidformer/gpt_moe/finetune_megatron_gpt.py中,可採用直接執行腳本文件EasyNLP/examples/rapidformer/gpt_moe/run_finetune_text_generation_gpt.sh的方式,一步執行上述所有訓練/評估。根據腳本run_finetune_text_generation_gpt.sh,需要設置的具體參數如下:

TASK_NAME=$1                    #任務名稱,這裏是poetry
TRAIN_DATASET_PATH=$2           #訓練集路徑
VALID_DATASET_PATH=$3           #驗證集路徑
PRETRAIN_CHECKPOINT_PATH=$4     #預訓練模型路徑
MODEL_SIZE=$5                   #預訓練模型大小
MOE=$6                          #專家數量
RT=$7                           #路由類型
BATCH_SIZE=$8                   #batch size
EPOCH=$9                        #訓練輪次
TP=${10}                        #模型並行度
AC=${11}                        #激活檢查點類型
ZERO=${12}                      #降顯存類型
SEQ_LEN=${13}                   #序列長度
sh run_finetune_text_generation_gpt.sh
poetry
/mnt/workspace/train.tsv
/mnt/workspace/train.tsv
/workspace/checkpoints/wudao-megatron-gpt-moe-64-0.35B-lr-3e-4-bs-4-gbs-256-tp-1-ac-sel-zero-none
0.35B
64
0 
16
2
1
sel
none
128

分析Tensorboard

分析Tensorboard,對比不同實驗參數設置,比如我們選擇調試訓練輪次分別是2和5,觀察收斂曲線的變化,如下所示:

從上圖可以看出,訓練輪次越大,驗證集loss越低,收斂效果越好。於是我們選擇訓練5個epoch後的ckpt來做詩歌生成的預測

模型預測

文本生成效果預測已經被集成到EasyNLP/examples/rapidformer/gpt_moe/generate_text_gpt.py中,可採用直接執行腳本文件EasyNLP/examples/rapidformer/gpt_moe/run_text_generation_gpt.sh的方式,一步執行詩歌生成和預測。首先按照如何格式準備預測用的數據集。

[
    {
        "id": 0,
        "txt": "大漠孤煙直"
    },
    {
        "id": 1,
        "txt": "江上歸帆天際開"
    }
]

然後根據腳本run_finetune_text_generation_gpt.sh裏面的參數設置,運行命令:sh run_text_generation_gpt.sh

CHECKPOINT_PATH=$1           #微調後的模型路徑
MODEL_SIZE=$2                #模型大小
MOE=$3                       #專家數量
SEQ_LEN=$4                   #序列長度
TOP_K=$5                     #topk
INPUT_SEQ_LEN=$6             #輸入最大長度
OUTPUT_SEQ_LEN=$7            #輸出最大長度
INPUT_FILE=$8                #輸入文件路徑
OUTPUT_FILE=$9               #輸出文件路徑
sh run_text_generation_gpt.sh
/workspace/checkpoints/finetune-poetry-ckpts
0.35B
64
128
5
20
128
input_poetry
output_poetry

生成結果如下:

{
	"id": 0,
	"prompt": "大漠孤煙直",
	"output_poetry": "大漠孤煙直,雄哉太山岑。萬古長松樹,青青如碧玉。"
}
{
	"id": 1,
	"prompt": "江上歸帆天際開",
	"output_poetry": "江上歸帆天際開,一帆秋色望中來。何當一洗三千丈,萬里風風盡下來。"
}

基於PAI EAS的在線推理部署

使用DSW完成GPT-MoE在下游任務上的微調後,就可以在線部署下游文本生成任務的服務了。接下來我們通過PAI-EAS產品來演示如何執行GPT-MoE的下游任務服務的在線部署。

開發基於FasterTransformer的Processor

首先使用Faster Transformer Converter將微調後的詩歌模型進行格式轉換

cd ~/RapidformerPro/examples/fastertransformer

sh run_convert.sh

model_type=$1             #模型類型:dense or moe
tokenizer=$2              #分詞器類型:gpt2bpe or jiebabpe
infer_gpu_num=$3          #推理用的卡數
INPUT_DIR=$4              #微調後的模型路徑名
SAVED_DIR=$5              #轉換後的模型路徑名

然後基於EAS提供的開發參考http://help.aliyun.com/document_detail/130248.html,開發文本生成processor。核心process方法參考如下

    def process(self, data):
        """ process the request data
        """
        data_str = data.decode('utf-8')
        data_json = json.loads(data_str)
        data = self.pre_proccess(data)

        contexts = [data_json['inputs'][0]]
        user_parameters = data_json['parameters']
        max_length = int(user_parameters['max_length'])
        seed = 42
        top_k = int(user_parameters['top_k'])
        self.top_k = top_k
        self.output_len = max_length
        start_ids = [
            torch.IntTensor(
                self.tokenzer.tokenize(
                    c.replace('\n', '\n').replace('\"', '"')))
            for c in contexts
        ]

        start_lengths = [len(ids) for ids in start_ids]
        start_ids = pad_sequence(start_ids,
                                 batch_first=True,
                                 padding_value=self.end_id)
        start_lengths = torch.IntTensor(start_lengths)
        torch.manual_seed(seed)
        random_seed_tensor = torch.zeros([1], dtype=torch.int64)

        with torch.no_grad():
            tokens_batch = self.gpt(
                start_ids, start_lengths, self.output_len, self.beam_width,
                self.top_k *
                torch.ones(size=[self.max_batch_size], dtype=torch.int32),
                self.top_p *
                torch.ones(size=[self.max_batch_size], dtype=torch.float32),
                self.beam_search_diversity_rate *
                torch.ones(size=[self.max_batch_size], dtype=torch.float32),
                self.temperature *
                torch.ones(size=[self.max_batch_size], dtype=torch.float32),
                self.len_penalty *
                torch.ones(size=[self.max_batch_size], dtype=torch.float32),
                self.repetition_penalty *
                torch.ones(size=[self.max_batch_size], dtype=torch.float32),
                random_seed_tensor, self.return_output_length,
                self.return_cum_log_probs)

            if self.return_cum_log_probs > 0:
                tokens_batch, _, cum_log_probs = tokens_batch
                print('[INFO] Log probs of sentences:', cum_log_probs)
            outputs = []
            batch_size = min(len(contexts), self.max_batch_size)
            outputs_token = np.ones([batch_size, self.output_len], dtype=int)
            tokens_batch = tokens_batch.cpu().numpy()
            for i, (context, tokens) in enumerate(zip(contexts, tokens_batch)):
                for beam_id in range(self.beam_width):
                    token = tokens[beam_id][:start_lengths[i] +
                                            self.output_len]
                    token = token[~np.isin(token, torch.tensor([7]))]
                    output = self.tokenzer.detokenize(token)
                    outputs.append(output)
                    print(f'[INFO] batch {i}, beam'
                          f' {beam_id}:'
                          f' \n[Context]\n{context}\n\n[Output]\n{output}\n')
                    output_token = tokens[beam_id][
                        start_lengths[i]:start_lengths[i] + self.output_len]
                    outputs_token[i] = output_token

            outputs = [o.replace('\n', '\n') for o in outputs]

        result_dict = {'text': outputs[0]}

        return get_result_str(result_dict=result_dict)

搭建在線服務

基於ModelScope的在線文本生成演示

我們已經搭建了詩歌,廣告文案,作文三個文本生成服務,具體的在線體驗地址是:http://www.modelscope.cn/organization/PAI

我們可以修改modelscope頁面上的README.md信息來設計應用樣式

tasks:
- text-generation
widgets:
- examples:
- name: 1
title: 詩歌生成
inputs:
- name: text
data: 大漠孤煙直
parameters:
- name: max_length
type: int
value: 128
- name: top_k
type: int
value: 5

在modelscope上呈現出來的效果如下所示:

參考文獻

[1] . Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer

[2]. GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding

[3]. Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity

[4]. BASE Layers: Simplifying Training of Large, Sparse Models

[5]. Hash Layers For Large Sparse Models

[6]. TAMING SPARSELY ACTIVATED TRANSFORMER WITH STOCHASTIC EXPERTS

[7]. GLaM: Efficient Scaling of Language Models with Mixture-of-Experts

[8]. Unified Scaling Laws for Routed Language Models

[9]. Designing Effective Sparse Expert Models

[10]. Large Margin Deep Networks for Classification

相關閲讀

阿里靈傑:中文稀疏GPT大模型落地 — 通往低成本&高性能多任務通用自然語言理解的關鍵里程碑