最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

大規(guī)模 Transformer 模型 8 比特矩陣乘簡(jiǎn)介

2023-04-25 23:23 作者:HuggingFace  | 我要投稿


引言

語(yǔ)言模型一直在變大。截至撰寫本文時(shí),PaLM 有 5400 億參數(shù),OPT、GPT-3 和 BLOOM 有大約 1760 億參數(shù),而且我們?nèi)栽诶^續(xù)朝著更大的模型發(fā)展。下圖總結(jié)了最近的一些語(yǔ)言模型的尺寸。

LLM

由于這些模型很大,因此它們很難在一般的設(shè)備上運(yùn)行。舉個(gè)例子,僅推理 BLOOM-176B 模型,你就需要 8 個(gè) 80GB A100 GPU (每個(gè)約 15,000 美元)。而如果要微調(diào) BLOOM-176B 的話,你需要 72 個(gè)這樣的 GPU!更大的模型,如 PaLM,還需要更多資源。

由于這些龐大的模型需要大量 GPU 才能運(yùn)行,因此我們需要找到降低資源需求而同時(shí)保持模型性能的方法。目前已有一些試圖縮小模型尺寸的技術(shù),比如你可能聽說過的量化和蒸餾等技術(shù)。

完成 BLOOM-176B 的訓(xùn)練后,Hugging Face 和 BigScience 一直在尋找能讓這個(gè)大模型更容易在更少的 GPU 上運(yùn)行的方法。通過我們的 BigScience 社區(qū),我們了解到一些有關(guān) Int8 推理的研究,它不會(huì)降低大模型的預(yù)測(cè)性能,而且可以將大模型的內(nèi)存占用量減少 2 倍。很快我們就開始合作進(jìn)行這項(xiàng)研究,最終將其完全整合到 Hugging Face?transformers?中。本文我們將詳述我們集成在 Hugging Face 中的 LLM.int8() 方案,它適用于所有 Hugging Face 模型。如果你想了解更多研究細(xì)節(jié),可以閱讀我們的論文 LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale。

本文將主要介紹 LLM.int8() 量化技術(shù),討論將其納入?transformers?庫(kù)的過程中經(jīng)歷的困難,并對(duì)后續(xù)工作進(jìn)行了計(jì)劃。

在這里,你將了解到究竟是什么讓一個(gè)大模型占用這么多內(nèi)存?是什么讓 BLOOM 占用了 350GB 內(nèi)存?我們先從一些基礎(chǔ)知識(shí)開始,慢慢展開。

機(jī)器學(xué)習(xí)中常用的數(shù)據(jù)類型

我們從理解不同浮點(diǎn)數(shù)據(jù)類型開始,這些數(shù)據(jù)類型在機(jī)器學(xué)習(xí)中也被稱為“精度”。

模型的大小由其參數(shù)量及其精度決定,精度通常為 float32、float16 或 bfloat16 之一 (下圖來源)。

Summary

Float32 (FP32) 是標(biāo)準(zhǔn)的 IEEE 32 位浮點(diǎn)表示。使用該數(shù)據(jù)類型,可以表示大范圍的浮點(diǎn)數(shù)。在 FP32 中,為“指數(shù)”保留了 8 位,為“尾數(shù)”保留了 23 位,為符號(hào)保留了 1 位。因?yàn)槭菢?biāo)準(zhǔn)數(shù)據(jù)類型,所以大部分硬件都支持 FP32 運(yùn)算指令。

而在 Float16 (FP16) 數(shù)據(jù)類型中,指數(shù)保留 5 位,尾數(shù)保留 10 位。這使得 FP16 數(shù)字的數(shù)值范圍遠(yuǎn)低于 FP32。因此 FP16 存在上溢 (當(dāng)用于表示非常大的數(shù)時(shí)) 和下溢 (當(dāng)用于表示非常小的數(shù)時(shí)) 的風(fēng)險(xiǎn)。

例如,當(dāng)你執(zhí)行?10k * 10k?時(shí),最終結(jié)果應(yīng)為?100M,F(xiàn)P16 無法表示該數(shù),因?yàn)?FP16 能表示的最大數(shù)是?64k。因此你最終會(huì)得到?NaN?(Not a Number,不是數(shù)字),在神經(jīng)網(wǎng)絡(luò)的計(jì)算中,因?yàn)橛?jì)算是按層和 batch 順序進(jìn)行的,因此一旦出現(xiàn)?NaN,之前的所有計(jì)算就全毀了。一般情況下,我們可以通過縮放損失 (loss scaling) 來緩解這個(gè)問題,但該方法并非總能奏效。

于是我們發(fā)明了一種新格式 Bfloat16 (BF16) 來規(guī)避這些限制。BF16 為指數(shù)保留了 8 位 (與 FP32 相同),為小數(shù)保留了 7 位。這意味著使用 BF16 我們可以保留與 FP32 相同的動(dòng)態(tài)范圍。但是相對(duì)于 FP16,我們損失了 3 位精度。因此,在使用 BF16 精度時(shí),大數(shù)值絕對(duì)沒有問題,但是精度會(huì)比 FP16 差。

在 Ampere 架構(gòu)中,NVIDIA 還引入了 TensorFloat-32(TF32) 精度格式,它使用 19 位表示,結(jié)合了 BF16 的范圍和 FP16 的精度。目前,它僅在某些操作的內(nèi)部使用 [譯者注: 即 TF32 是一個(gè)計(jì)算數(shù)據(jù)類型而不是存儲(chǔ)數(shù)據(jù)類型]。

在機(jī)器學(xué)習(xí)術(shù)語(yǔ)中,F(xiàn)P32 稱為全精度 (4 字節(jié)),而 BF16 和 FP16 稱為半精度 (2 字節(jié))。除此以外,還有 Int8 (INT8) 數(shù)據(jù)類型,它是一個(gè) 8 位的整型數(shù)據(jù)表示,可以存儲(chǔ)??個(gè)不同的值 (對(duì)于有符號(hào)整數(shù),區(qū)間為 [-128, 127],而對(duì)于無符號(hào)整數(shù),區(qū)間為 [0, 255])。

雖然理想情況下訓(xùn)練和推理都應(yīng)該在 FP32 中完成,但 FP32 比 FP16/BF16 慢兩倍,因此實(shí)踐中常常使用混合精度方法,其中,使用 FP32 權(quán)重作為精確的 “主權(quán)重 (master weight)”,而使用 FP16/BF16 權(quán)重進(jìn)行前向和后向傳播計(jì)算以提高訓(xùn)練速度,最后在梯度更新階段再使用 FP16/BF16 梯度更新 FP32 主權(quán)重。

在訓(xùn)練期間,主權(quán)重始終為 FP32。而在實(shí)踐中,在推理時(shí),半精度權(quán)重通常能提供與 FP32 相似的精度 —— 因?yàn)橹挥性谀P吞荻雀聲r(shí)才需要精確的 FP32 權(quán)重。這意味著在推理時(shí)我們可以使用半精度權(quán)重,這樣我們僅需一半 GPU 顯存就能獲得相同的結(jié)果。

Model-storage

以字節(jié)為單位計(jì)算模型大小時(shí),需要將參數(shù)量乘以所選精度的大小 (以字節(jié)為單位)。例如,如果我們使用 BLOOM-176B 模型的 Bfloat16 版本,其大小就應(yīng)為?字節(jié)!如前所述,這個(gè)大小需要多個(gè) GPU 才能裝得下,這是一個(gè)相當(dāng)大的挑戰(zhàn)。

但是,如果我們可以使用另外的數(shù)據(jù)類型來用更少的內(nèi)存存儲(chǔ)這些權(quán)重呢?深度學(xué)習(xí)社區(qū)已廣泛使用的方法是量化。

模型量化簡(jiǎn)介

通過實(shí)驗(yàn),我們發(fā)現(xiàn)不使用 4 字節(jié) FP32 精度轉(zhuǎn)而使用 2 字節(jié) BF16/FP16 半精度可以獲得幾乎相同的推理結(jié)果,同時(shí)模型大小會(huì)減半。這促使我們想進(jìn)一步削減內(nèi)存,但隨著我們使用更低的精度,推理結(jié)果的質(zhì)量也開始急劇下降。

為了解決這個(gè)問題,我們引入了 8 位量化。僅用四分之一精度,因此模型大小也僅需 1/4!但這次,我們不能簡(jiǎn)單地丟棄另一半位寬了。

基本上講,量化過程是從一種數(shù)據(jù)類型“舍入”到另一種數(shù)據(jù)類型。舉個(gè)例子,如果一種數(shù)據(jù)類型的范圍為?0..9,而另一種數(shù)據(jù)類型的范圍為?0..4,則第一種數(shù)據(jù)類型中的值?4?將舍入為第二種數(shù)據(jù)類型中的?2?。但是,如果在第一種數(shù)據(jù)類型中有值?3,它介于第二種數(shù)據(jù)類型的?1?和 ?2?之間,那么我們通常會(huì)四舍五入為?2。也就是說,第一種數(shù)據(jù)類型的值?4?和?3?在第二種數(shù)據(jù)類型中具有相同的值?2。這充分表明量化是一個(gè)有噪過程,會(huì)導(dǎo)致信息丟失,是一種有損壓縮。

兩種最常見的 8 位量化技術(shù)是零點(diǎn)量化 (zero-point quantization) 和最大絕對(duì)值 (absolute maximum quantization,absmax) 量化。它們都將浮點(diǎn)值映射為更緊湊的 Int8 (1 字節(jié)) 值。這些方法的第一步都是用量化常數(shù)對(duì)輸入進(jìn)行歸一化縮放。

在零點(diǎn)量化中,如果我的數(shù)值范圍是?-1.0…1.0,我想量化到?-127…127,我需要先縮放?127倍,然后四舍五入到?8?位精度。要恢復(fù)原始值,我需要將 Int8 值除以相同的量化因子?127。在這個(gè)例子中,值?0.3?將縮放為?0.3*127 = 38.1。四舍五入后得到值?38。恢復(fù)時(shí),我們會(huì)得到?38/127=0.2992?—— 因此最終會(huì)有?0.008?的量化誤差。這些看似微小的誤差在沿著模型各層傳播時(shí)往往會(huì)累積和增長(zhǎng),從而導(dǎo)致最終的精度下降。

譯者注: 這個(gè)例子舉得不好,因?yàn)楦↑c(diǎn)范圍和整型范圍都是對(duì)稱的,所以不存在零點(diǎn)調(diào)整了,而零點(diǎn)調(diào)整是零點(diǎn)量化中最能體現(xiàn)其命名原因的部分。簡(jiǎn)而言之,零點(diǎn)量化分為兩步,第一步值域映射,即通過縮放將原始的數(shù)值范圍映射為量化后的數(shù)值范圍; 第二步零點(diǎn)調(diào)整,即通過平移將映射后的數(shù)據(jù)的最小值對(duì)齊為目標(biāo)值域的最小值

quantization

(圖源)

現(xiàn)在我們?cè)倏聪?absmax 量化的細(xì)節(jié)。要計(jì)算 absmax 量化中 fp16 數(shù)與其對(duì)應(yīng)的 int8 數(shù)之間的映射,你必須先除以張量的最大絕對(duì)值,然后再乘以數(shù)據(jù)類型的最大可表示值。

例如,假設(shè)你要用 absmax 對(duì)向量?[1.2, -0.5, -4.3, 1.2, -3.1, 0.8, 2.4, 5.4]?進(jìn)行量化。首先需要計(jì)算該向量元素的最大絕對(duì)值,在本例中為?5.4。Int8 的范圍為?[-127, 127],因此我們將?127?除以?5.4,得到縮放因子?23.5。最后,將原始向量乘以縮放因子得到最終的量化向量?[28, -12, -101, 28, -73, 19, 56, 127]。

out-quant.gif

要恢復(fù)原向量,可以將 int8 量化值除以縮放因子,但由于上面的過程是“四舍五入”的,我們將丟失一些精度。

quant-freeze

對(duì)于無符號(hào) Int8,我們可以先減去最小值然后再用最大絕對(duì)值來縮放,這與零點(diǎn)量化的做法相似。其做法也與最小 - 最大縮放 (min-max scaling) 類似,但后者在縮放時(shí)會(huì)額外保證輸入中的?0?始終映射到一個(gè)整數(shù),從而保證?0?的量化是無誤差的。

當(dāng)進(jìn)行矩陣乘法時(shí),我們可以通過組合各種技巧,例如逐行或逐向量量化,來獲取更精確的結(jié)果。舉個(gè)例子,對(duì)矩陣乘法?,我們不會(huì)直接使用常規(guī)量化方式,即用整個(gè)張量的最大絕對(duì)值對(duì)張量進(jìn)行歸一化,而會(huì)轉(zhuǎn)而使用向量量化方法,找到 A 的每一行和 B 的每一列的最大絕對(duì)值,然后逐行或逐列歸一化 A 和 B 。最后將 A 與 B 相乘得到 C。最后,我們?cè)儆?jì)算與 A 和 B 的最大絕對(duì)值向量的外積,并將此與 C 求哈達(dá)瑪積來反量化回 FP16。有關(guān)此技術(shù)的更多詳細(xì)信息可以參考 LLM.int8() 論文 或 Tim 的博客上的 關(guān)于量化和涌現(xiàn)特征的博文。

雖然這些基本技術(shù)能夠幫助我們量化深度學(xué)習(xí)模型,但它們通常會(huì)導(dǎo)致大模型準(zhǔn)確性的下降。我們集成到 Hugging Face Transformers 和 Accelerate 庫(kù)中的 LLM.int8() 是第一個(gè)適用于大模型 (如 BLOOM-176B) 且不會(huì)降低準(zhǔn)確性的量化技術(shù)。

簡(jiǎn)要總結(jié) LLM.int8(): 大語(yǔ)言模型的零退化矩陣乘法

在 LLM.int8() 中,我們已經(jīng)證明理解 transformer 模型表現(xiàn)出的與模型規(guī)模相關(guān)的涌現(xiàn)特性對(duì)于理解為什么傳統(tǒng)量化對(duì)大模型失效至關(guān)重要。我們證明性能下降是由離群特征 (outlier feature) 引起的,下一節(jié)我們會(huì)詳細(xì)解釋。LLM.int8() 算法本身如下。

本質(zhì)上,LLM.int8() 通過三個(gè)步驟完成矩陣乘法計(jì)算:

  1. 從輸入的隱含狀態(tài)中,按列提取異常值 (即大于某個(gè)閾值的值)。

  2. 對(duì) FP16 離群值矩陣和 Int8 非離群值矩陣分別作矩陣乘法。

  3. 反量化非離群值的矩陣乘結(jié)果并其與離群值矩陣乘結(jié)果相加,獲得最終的 FP16 結(jié)果。

該過程可以總結(jié)為如下動(dòng)畫:

Mixed-int8.gif

離群特征的重要性

超出某個(gè)分布范圍的值通常稱為離群值。離群值檢測(cè)已得到廣泛應(yīng)用,在很多文獻(xiàn)中也有涉及,且獲取特征的先驗(yàn)分布對(duì)離群值檢測(cè)任務(wù)很有助益。更具體地說,我們觀察到對(duì)于參數(shù)量大于 6B 的 transformer 模型,經(jīng)典的量化方法會(huì)失效。雖然離群值特征也存在于較小的模型中,但在大于 6B 的 transformer 模型中,我們觀察到幾乎每層都會(huì)出現(xiàn)超出特定閾值的離群點(diǎn),而且這些離群點(diǎn)呈現(xiàn)出一定的系統(tǒng)性模式。有關(guān)該現(xiàn)象的更多詳細(xì)信息,請(qǐng)參閱 LLM.int8() 論文 和 涌現(xiàn)特征的博文。

如前所述,8 位精度的動(dòng)態(tài)范圍極其有限,因此量化具有多個(gè)大值的向量會(huì)產(chǎn)生嚴(yán)重誤差。此外,由于 transformer 架構(gòu)的固有特性,它會(huì)將所有元素互相關(guān)聯(lián)起來,這樣的話,這些誤差在傳播幾層后往往會(huì)混雜在一起。因此,我們發(fā)明了混合精度分解的方法,以對(duì)此類極端離群值進(jìn)行有效量化。接下來我們對(duì)此方法進(jìn)行討論。

MatMul 內(nèi)部

計(jì)算隱含狀態(tài)后,我們使用自定義閾值提取離群值,并將矩陣分解為兩部分,如上所述。我們發(fā)現(xiàn),以這種方式提取所有幅度大于等于 6 的離群值可以完全恢復(fù)推理精度。離群值部分使用 FP16 表示,因此它是一個(gè)經(jīng)典的矩陣乘法,而 8 位矩陣乘法是通過使用向量量化將權(quán)重和隱含狀態(tài)分別量化為 8 位精度 - 即按行量化權(quán)重矩陣,并按列量化隱含狀態(tài),然后再進(jìn)行相應(yīng)向量乘加操作。最后,將結(jié)果反量化至半精度,以便與第一個(gè)矩陣乘法的結(jié)果相加。

Matmul.png

0 退化是什么意思?

我們?nèi)绾握_評(píng)估該方法是否會(huì)對(duì)性能造成下降?使用 8 位模型時(shí),我們的生成質(zhì)量損失了多少?

我們使用?lm-eval-harness?在 8 位和原始模型上運(yùn)行了幾個(gè)常見的基準(zhǔn)測(cè)試,結(jié)果如下。

對(duì) OPT-175B 模型:

對(duì) BLOOM-176 模型:

我們切實(shí)地看到上述這些模型的性能下降為 0,因?yàn)橹笜?biāo)的絕對(duì)差異均低于原始模型的標(biāo)準(zhǔn)誤差 (BLOOM-int8 除外,它在 lambada 上略好于原始模型)。如果想要知道 LLM.int8() 與當(dāng)前其他先進(jìn)方法的更詳細(xì)的性能比較,請(qǐng)查看 論文!

比原始模型更快嗎?

LLM.int8() 方法的主要目的是在不降低性能的情況下降低大模型的應(yīng)用門檻。但如果速度非常慢,該方法用處也不會(huì)很大。所以我們對(duì)多個(gè)模型的生成速度進(jìn)行了基準(zhǔn)測(cè)試。

我們發(fā)現(xiàn)使用了 LLM.int8() 的 BLOOM-176B 比 FP16 版本慢了大約 15% 到 23% —— 這應(yīng)該是完全可以接受的。我們發(fā)現(xiàn)較小模型 (如 T5-3B 和 T5-11B) 的降速幅度更大。我們還在努力優(yōu)化這些小模型的推理速度。在一天之內(nèi),我們可以將 T5-3B 的每詞元推理延遲從 312 毫秒降低到 173 毫秒,將 T5-11B 從 45 毫秒降低到 25 毫秒。此外,我們 已經(jīng)找到原因,在即將發(fā)布的版本中,LLM.int8() 在小模型上的推理速度可能會(huì)更快。下表列出了當(dāng)前版本的一些性能數(shù)據(jù)。

上表中的 3 個(gè)模型分別為 BLOOM-176B、T5-11B 和 T5-3B。

Hugging Face?Transformers?集成細(xì)節(jié)

接下來讓我們討論在 Hugging Face?transformers?集成該方法的細(xì)節(jié),向你展示常見的用法及在使用過程中可能遇到的常見問題。

用法

所有的操作都集成在?Linear8bitLt?模塊中,你可以輕松地從?bitsandbytes?庫(kù)中導(dǎo)入它。它是?torch.nn.modules?的子類,你可以仿照下述代碼輕松地將其應(yīng)用到自己的模型中。

下面以使用?bitsandbytes?將一個(gè)小模型轉(zhuǎn)換為 int8 為例,并給出相應(yīng)的步驟。

  1. 首先導(dǎo)入模塊,如下。

  1. 然后就可以定義自己的模型了。請(qǐng)注意,我們支持將任何精度的 checkpoint 或模型轉(zhuǎn)換為 8 位 (FP16、BF16 或 FP32),但目前,僅當(dāng)模型的輸入張量數(shù)據(jù)類型為 FP16 時(shí),我們的 Int8 模塊才能工作。因此,這里我們稱模型為 fp16 模型。

  1. 假設(shè)你已經(jīng)在你的數(shù)據(jù)集和任務(wù)上訓(xùn)完了你的模型!現(xiàn)在需要保存模型:

  1. 至此,state_dict?已保存,我們需要定義一個(gè) int8 模型:

此處標(biāo)志變量?has_fp16_weights?非常重要。默認(rèn)情況下,它設(shè)置為?True,用于在訓(xùn)練時(shí)使能 Int8/FP16 混合精度。但是,因?yàn)樵谕评碇形覀儗?duì)內(nèi)存節(jié)省更感興趣,因此我們需要設(shè)置?has_fp16_weights=False。

  1. 現(xiàn)在加載 8 位模型!

  1. 請(qǐng)注意,一旦將模型的設(shè)備設(shè)置為 GPU,量化過程就會(huì)在第二行代碼中完成。如果在調(diào)用?.to?函數(shù)之前打印?int8_model[0].weight,你會(huì)看到:

而如果你在第二行之后打印它,你會(huì)看到:

正如我們?cè)谇懊娌糠纸忉屃炕椒〞r(shí)所講,權(quán)重值被“截?cái)唷绷?。此外,這些值的分布看上去在 [-127, 127] 之間。

你可能還想知道如何獲取 FP16 權(quán)重以便在 FP16 中執(zhí)行離群值的矩陣乘?很簡(jiǎn)單:

你會(huì)看到:

這跟第一次打印的原始 FP16 值很接近!

  1. 現(xiàn)在你只需將輸入推給正確的 GPU 并確保輸入數(shù)據(jù)類型是 FP16 的,你就可以使用該模型進(jìn)行推理了:

你可以查看 示例腳本,獲取完整的示例代碼!

多說一句,?Linear8bitLt?與 ?nn.Linear?模塊略有不同,主要在?Linear8bitLt?的參數(shù)屬于?bnb.nn.Int8Params?類而不是?nn.Parameter?類。稍后你會(huì)看到這給我們帶來了一些小麻煩!

現(xiàn)在我們開始了解如何將其集成到?transformers?庫(kù)中!

accelerate?足矣

在處理大模型時(shí),?accelerate?庫(kù)包含許多有用的工具。init_empty_weights?方法特別有用,因?yàn)槿魏文P停瑹o論大小,都可以在此方法的上下文 (context) 內(nèi)進(jìn)行初始化,而無需為模型權(quán)重分配任何內(nèi)存。

初始化過的模型將放在 PyTorch 的 ?meta?設(shè)備上,這是一種用于表征向量的形狀和數(shù)據(jù)類型而無需實(shí)際的內(nèi)存分配的超酷的底層機(jī)制。

最初,我們?cè)?.from_pretrained?函數(shù)內(nèi)部調(diào)用?init_empty_weights,并將所有參數(shù)重載為?torch.nn.Parameter。這不是我們想要的,因?yàn)樵谖覀兊那闆r中,我們希望為?Linear8bitLt?模塊保留?Int8Params?類,如上所述。我們最后成功使用 此 PR 修復(fù)了該問題,它將下述代碼:

修改成:

現(xiàn)在這個(gè)問題已經(jīng)解決了,我們可以輕松地在一個(gè)自定義函數(shù)中利用這個(gè)上下文管理器將所有?nn.Linear?模塊替換為?bnb.nn.Linear8bitLt?而無需占用內(nèi)存!

此函數(shù)遞歸地將?meta?設(shè)備上初始化的給定模型的所有?nn.Linear?層替換為?Linear8bitLt?模塊。這里,必須將?has_fp16_weights?屬性設(shè)置為?False,以便直接將權(quán)重加載為?Int8,并同時(shí)加載其量化統(tǒng)計(jì)信息。

我們放棄了對(duì)某些模塊 (這里時(shí)?lm_head) 進(jìn)行替換,因?yàn)槲覀兿M3州敵鰧拥脑季纫垣@得更精確、更穩(wěn)定的結(jié)果。

但還沒完!上面的函數(shù)在?init_empty_weights?上下文管理器中執(zhí)行,這意味著新模型將仍在?meta?設(shè)備中。

對(duì)于在此上下文管理器中初始化的模型,?accelerate?將手動(dòng)加載每個(gè)模塊的參數(shù)并將它們拷貝到正確的設(shè)備上。因此在?bitsandbytes?中,設(shè)置?Linear8bitLt?模塊的設(shè)備是至關(guān)重要的一步 (感興趣的讀者可以查看 此代碼),正如你在我們上面提供的腳本中所見。

而且,第二次調(diào)用量化過程時(shí)會(huì)失??!我們必須想出一個(gè)與?accelerate?的 ?set_module_tensor_to_device?函數(shù)相應(yīng)的實(shí)現(xiàn) (稱為?set_module_8bit_tensor_to_device),以確保我們不會(huì)調(diào)用兩次量化。我們將在下面的部分中詳細(xì)討論這個(gè)問題!

在 ?accelerate?設(shè)置設(shè)備要當(dāng)心

這方面,我們對(duì)?accelerate?庫(kù)進(jìn)行了精巧的修改,以取得平衡!

在模型被加載且設(shè)置到正確的設(shè)備上后,有時(shí)你仍需調(diào)用?set_module_tensor_to_device?以便向所有設(shè)備分派加了 hook 的模型。該操作在用戶調(diào)用?accelerate?的 ?dispatch_model?函數(shù)時(shí)會(huì)被觸發(fā),這意味著我們有可能多次調(diào)用?.to,我們需要避免該行為。

我們通過兩個(gè) PR 實(shí)現(xiàn)了目的,這里 的第一個(gè) PR 破壞了一些測(cè)試,但 這個(gè) PR 成功修復(fù)了所有問題!

總結(jié)

因此,最終我們完成了:

  1. 使用正確的模塊在?meta?設(shè)備上初始化模型。

  2. 不重不漏地對(duì)目標(biāo) GPU 逐一設(shè)置參數(shù),確保不要對(duì)同一個(gè) GPU 重復(fù)設(shè)置!

  3. 將新加的參數(shù)變量更新到所有需要的地方,并添加好文檔。

  4. 添加高覆蓋度的測(cè)試!你可以從 此處 查看更多關(guān)于測(cè)試的詳細(xì)信息。

知易行難,在此過程中,我們經(jīng)歷了許多艱難的調(diào)試局,其中很多跟 CUDA 核函數(shù)有關(guān)!

總而言之,這次集成的過程充滿了冒險(xiǎn)和趣味; 從深入研究并對(duì)不同的庫(kù)做一些“手術(shù)”,到整合一切并最終使其發(fā)揮作用,每一步都充滿挑戰(zhàn)!

現(xiàn)在,我們看看如何在?transformers?中成功使用它并從中獲益!

如何在?transformers?中使用它

硬件要求

CPU 不支持 8 位張量核心 [*]。bitsandbytes 可以在支持 8 位張量核心的硬件上運(yùn)行,這些硬件有 Turing 和 Ampere GPU (RTX 20s、RTX 30s、A40-A100、T4+)。例如,Google Colab GPU 通常是 NVIDIA T4 GPU,而最新的 T4 是支持 8 位張量核心的。我們后面的演示將會(huì)基于 Google Colab!

*: 譯者注: Intel 最新的 Sapphire Rapids CPU 已支持 8 位張量指令集: AMX

安裝

使用以下命令安裝最新版本的庫(kù) (確保你的 python>=3.8)。

演示示例 - 在 Google Colab 上運(yùn)行 T5 11B

以下是運(yùn)行 T5-11B 的演示。T5-11B 模型的 checkpoint 精度為 FP32,需要 42GB 內(nèi)存,Google Colab 里跑不動(dòng)。使用我們的 8 位模塊,它僅需 11GB 內(nèi)存,因此能輕易跑通:

T5-11B 的 Colab 演示:https://colab.research.google.com/drive/1YORPWx4okIHXnjW7MSAidXN29mPVNT7F?usp=sharing

或者,你還可以看看下面這個(gè)使用 8 位 BLOOM-3B 模型進(jìn)行推理的演示!

BLOOM-3B 的 Colab 演示:https://colab.research.google.com/github/huggingface/blog/blob/main/notebooks/HuggingFace_int8_demo.ipynb

影響范圍

我們認(rèn)為,該方法讓超大模型不再是陽(yáng)春白雪,而是人人皆可觸及。在不降低性能的情況下,它使擁有較少算力的用戶能夠使用以前無法使用的模型。

我們已經(jīng)發(fā)現(xiàn)了幾個(gè)可以在繼續(xù)改進(jìn)的領(lǐng)域,以使該方法對(duì)大模型更友好!

較小模型的推理加速

正如我們?cè)?[基準(zhǔn)測(cè)試部分](# 比原始模型更快嗎?) 中看到的那樣,我們可以將小模型 (<=6B 參數(shù)) 的運(yùn)行速度提高近 2 倍。然而,雖然推理速度對(duì)于像 BLOOM-176B 這樣的大模型來說比較穩(wěn)定,但對(duì)小模型而言仍有改進(jìn)的余地。我們已經(jīng)定位到了問題并有希望恢復(fù)與 FP16 相同的性能,甚至還可能會(huì)有小幅加速。我們將在接下來的幾周內(nèi)合入這些改進(jìn)。

支持 Kepler GPU (GTX 1080 等)

雖然我們只支持過去四年的所有 GPU,但現(xiàn)實(shí)是某些舊的 GPU (如 GTX 1080) 現(xiàn)在仍然被大量使用。雖然這些 GPU 沒有 Int8 張量核心,但它們有 Int8 向量單元 (一種“弱”張量核心)。因此,這些 GPU 也可以體驗(yàn) Int8 加速。然而,它需要一個(gè)完全不同的軟件棧來優(yōu)化推理速度。雖然我們確實(shí)計(jì)劃集成對(duì) Kepler GPU 的支持以使 LLM.int8() 的應(yīng)用更廣泛,但由于其復(fù)雜性,實(shí)現(xiàn)這一目標(biāo)需要一些時(shí)間。

在 Hub 上保存 8 位 checkpoint

目前 8 位模型無法直接加載被推送到 Hub 上的 8 位 checkpoint。這是因?yàn)槟P陀?jì)算所需的統(tǒng)計(jì)數(shù)據(jù) (還記得上文提到的?weight.CB?和 ?weight.SCB?嗎?) 目前沒有存儲(chǔ)在 state_dict 中,而且 state_dict 的設(shè)計(jì)也未考慮這一信息的存儲(chǔ),同時(shí)?Linear8bitLt?模塊也還尚未支持該特性。

但我們認(rèn)為保存它并將其推送到 Hub 可能有助于提高模型的可訪問性。

CPU 的支持

正如本文開頭所述,CPU 設(shè)備不支持 8 位張量核。然而,我們能克服它嗎?在 CPU 上運(yùn)行此模塊可以顯著提高可用性和可訪問性。[譯者注: 如上文,最新的 Intel CPU 已支持 8 位張量核]

擴(kuò)展至其他模態(tài)

目前,大模型以語(yǔ)言模型為主。在超大視覺、音頻和多模態(tài)模型上應(yīng)用這種方法可能會(huì)很有意思,因?yàn)殡S著這些模型在未來幾年變得越來越多,它們的易用性也會(huì)越來越重要。

致謝

非常感謝以下為提高文章的可讀性以及在?transformers?中的集成過程做出貢獻(xiàn)的人 (按字母順序列出): JustHeuristic (Yozh), Michael Benayoun, Stas Bekman, Steven Liu, Sylvain Gugger, Tim Dettmers

英文原文:?https://hf.co/blog/hf-bitsandbytes-integration

原文作者: Younes Belkada,Tim Dettmers

譯者: Matrix Yao (姚偉峰),英特爾深度學(xué)習(xí)工程師,工作方向?yàn)?transformer-family 模型在各模態(tài)數(shù)據(jù)上的應(yīng)用及大規(guī)模模型的訓(xùn)練推理。

排版: zhongdongy (阿東)


大規(guī)模 Transformer 模型 8 比特矩陣乘簡(jiǎn)介的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
尖扎县| 淮安市| 台南市| 双峰县| 黄平县| 于都县| 洪洞县| 微山县| 松桃| 瑞昌市| 怀集县| 翁源县| 陇川县| 亚东县| 新竹市| 双峰县| 禄劝| 寿光市| 宜君县| 梁平县| 海门市| 广东省| 新化县| 桓仁| 丰顺县| 邯郸县| 怀安县| 济阳县| 福州市| 崇文区| 兰坪| 丰镇市| 九龙县| 上林县| 镇平县| 天气| 长岛县| 黄陵县| 隆化县| 久治县| 毕节市|