久久亚洲国产精品视频,中国AV片,最近中文字幕免费大全,国产亚洲精品久久久999功能介绍,欧美色女人

金融情報局網(wǎng)_中國金融門戶網(wǎng)站 讓金融財經(jīng)離的更近

大模型微調(diào)技術(shù)LoRA與QLoRA_全球觀速訊

當前位置:金融情報局網(wǎng)_中國金融門戶網(wǎng)站 讓金融財經(jīng)離的更近>資訊 > 獨家 > 正文  2023-06-27 11:45:56 來源:博客園
LoRA: Low-Rank Adaptation of Large Language Models動機

大模型的參數(shù)量都在100B級別,由于算力的吃緊,在這個基礎(chǔ)上進行所有參數(shù)的微調(diào)變得不可能。LoRA正是在這個背景下提出的解決方案。

原理

雖然模型的參數(shù)眾多,但其實模型主要依賴低秩維度的內(nèi)容(low intrinsic dimension),由此引出低秩自適應方法lora,通過低秩分解來模擬參數(shù)的改變量,從而以極小的參數(shù)量來實現(xiàn)大模型的間接訓練。

LoRA的思想也很簡單,在原始PLM旁邊增加一個旁路,做一個降維再升維的操作,來模擬所謂的intrinsic rank。


(資料圖片)

訓練的時候固定PLM的參數(shù),只訓練降維矩陣A與升維矩陣B。而模型的輸入輸出維度不變,輸出時將BA與PLM的參數(shù)疊加。

用隨機高斯分布初始化A,用0矩陣初始化B,保證訓練的開始此旁路矩陣依然是0矩陣。

這種思想有點類似于殘差連接,同時使用這個旁路的更新來模擬full finetuning的過程。并且,full finetuning可以被看做是LoRA的特例(當r等于k時)

LoRA詳細過程在原模型旁邊增加一個旁路,通過低秩分解(先降維再升維)來模擬參數(shù)的更新量;訓練時,原模型固定,只訓練降維矩陣A和升維矩陣B;推理時,可將BA加到原參數(shù)上,不引入額外的推理延遲;初始化,A采用高斯分布初始化,B初始化為全0,保證訓練開始時旁路為0矩陣;可插拔式的切換任務,當前任務W0+B1A1,將lora部分減掉,換成B2A2,即可實現(xiàn)任務切換;秩的選?。簩τ谝话愕娜蝿眨瑀ank=1,2,4,8足矣,而對于一些領(lǐng)域差距比較大的任務可能需要更大的rank。

總的來說,lora就是凍結(jié)預先訓練的模型權(quán)重,并將可訓練的秩分解矩陣注入Transformer架構(gòu)的每一層。

目前對于大多數(shù)實驗只在 WqWq">和 WvWv">使用LoRA,可訓練參數(shù)的數(shù)量由秩r和原始權(quán)值的形狀決定。

代碼

源碼:https://github.com/microsoft/LoRA

LoRALayer層

class LoRALayer():    def __init__(        self,         r: int,         lora_alpha: int,         lora_dropout: float,        merge_weights: bool,    ):        self.r = r        self.lora_alpha = lora_alpha        # Optional dropout        if lora_dropout > 0.:            self.lora_dropout = nn.Dropout(p=lora_dropout)        else:            self.lora_dropout = lambda x: x        # Mark the weight as unmerged        self.merged = False        self.merge_weights = merge_weights

Linear層

class Linear(nn.Linear, LoRALayer):    # LoRA implemented in a dense layer    def __init__(        self,         in_features: int,         out_features: int,         r: int = 0,         lora_alpha: int = 1,         lora_dropout: float = 0.,        fan_in_fan_out: bool = False, # Set this to True if the layer to replace stores weight like (fan_in, fan_out)        merge_weights: bool = True,        **kwargs    ):        nn.Linear.__init__(self, in_features, out_features, **kwargs)        LoRALayer.__init__(self, r=r, lora_alpha=lora_alpha, lora_dropout=lora_dropout,                           merge_weights=merge_weights)        self.fan_in_fan_out = fan_in_fan_out        # Actual trainable parameters        if r > 0:            self.lora_A = nn.Parameter(self.weight.new_zeros((r, in_features)))            self.lora_B = nn.Parameter(self.weight.new_zeros((out_features, r)))            self.scaling = self.lora_alpha / self.r            # Freezing the pre-trained weight matrix            self.weight.requires_grad = False        self.reset_parameters()        if fan_in_fan_out:            self.weight.data = self.weight.data.transpose(0, 1)    def reset_parameters(self):        nn.Linear.reset_parameters(self)        if hasattr(self, "lora_A"):            # initialize A the same way as the default for nn.Linear and B to zero            nn.init.kaiming_uniform_(self.lora_A, a=math.sqrt(5))            nn.init.zeros_(self.lora_B)    def train(self, mode: bool = True):        def T(w):            return w.transpose(0, 1) if self.fan_in_fan_out else w        nn.Linear.train(self, mode)        if mode:            if self.merge_weights and self.merged:                # Make sure that the weights are not merged                if self.r > 0:                    self.weight.data -= T(self.lora_B @ self.lora_A) * self.scaling                self.merged = False        else:            if self.merge_weights and not self.merged:                # Merge the weights and mark it                if self.r > 0:                    self.weight.data += T(self.lora_B @ self.lora_A) * self.scaling                self.merged = True           def forward(self, x: torch.Tensor):        def T(w):            return w.transpose(0, 1) if self.fan_in_fan_out else w        if self.r > 0 and not self.merged:            result = F.linear(x, T(self.weight), bias=self.bias)            if self.r > 0:                result += (self.lora_dropout(x) @ self.lora_A.transpose(0, 1) @ self.lora_B.transpose(0, 1)) * self.scaling            return result        else:            return F.linear(x, T(self.weight), bias=self.bias)

Peft實現(xiàn)

from peft import LoraConfig, get_peft_model, prepare_model_for_int8_training, TaskType# Define LoRA Configlora_config = LoraConfig( r=16, lora_alpha=32, target_modules=["q", "v"], lora_dropout=0.05, bias="none", task_type=TaskType.SEQ_2_SEQ_LM)# prepare int-8 model for trainingmodel = prepare_model_for_int8_training(model)# add LoRA adaptormodel = get_peft_model(model, lora_config)model.print_trainable_parameters()# trainable params: 18874368 || all params: 11154206720 || trainable%: 0.16921300163961817

參考鏈接:

https://zhuanlan.zhihu.com/p/631077870

https://zhuanlan.zhihu.com/p/636759194

https://zhuanlan.zhihu.com/p/514033873

QLoRA:Efficient Finetuning of Quantized LLMs動機

微調(diào)非常大的模型的成本過高;對650億參數(shù)的LLaMA模型進行進行16位微調(diào)需要超過780GB的GPU內(nèi)存,QLORA使用一種新的高精度技術(shù)將預訓練模型量化為int4,然后添加一小組可學習的低秩適配器權(quán)重。它是通過量化權(quán)重反向傳播梯度來調(diào)整的。QLORA將65B參數(shù)模型進行微調(diào)的平均內(nèi)存需求從 >780GB 的 GPU 內(nèi)存減少到 <48GB,而不會降低運行時間或預測性能。這標志著LLM微調(diào)可訪問性的顯著轉(zhuǎn)變:現(xiàn)在最大的公開可用的模型,迄今為止在單個GPU上進行微調(diào)。

創(chuàng)新

首先分析下LoRA微調(diào)中的痛點:

參數(shù)空間小:LoRA中參與訓練的參數(shù)量較少,解空間較小,效果相比全量微調(diào)有一定的差距。

微調(diào)大模型成本高:對于上百億參數(shù)量的模型,LoRA微調(diào)的成本還是很高。

精度損失:針對第二點,可以采用int8或int4量化,進一步對模型基座的參數(shù)進行壓縮。但是又會引發(fā)精度損失的問題,降低模型性能。

今天的主角QLoRA優(yōu)點:

4-bit NormalFloat:提出一種理論最優(yōu)的4-bit的量化數(shù)據(jù)類型,優(yōu)于當前普遍使用的FP4與Int4。對于正態(tài)分布權(quán)重而言,一種信息理論上最優(yōu)的新數(shù)據(jù)類型,該數(shù)據(jù)類型對正態(tài)分布數(shù)據(jù)產(chǎn)生比 4 bit整數(shù)和 4bit 浮點數(shù)更好的實證結(jié)果。QLORA包含一種低精度存儲數(shù)據(jù)類型(通常為4-bit)和一種計算數(shù)據(jù)類型(通常為BFloat16)。在實踐中,QLORA權(quán)重張量使用時,需要將將張量去量化為BFloat16,然后在16位計算精度下進行矩陣乘法運算。模型本身用4bit加載,訓練時把數(shù)值反量化到bf16后進行訓練。

Double Quantization:對第一次量化后的那些常量再進行一次量化,減少存儲空間。相比于當前的模型量化方法,更加節(jié)省顯存空間。每個參數(shù)平均節(jié)省0.37bit,對于65B的LLaMA模型,大約能節(jié)省3GB顯存空間。

Paged Optimizers:使用NVIDIA統(tǒng)一內(nèi)存特性,該特性可以在在GPU偶爾OOM的情況下,進行CPU和GPU之間自動分頁到分頁的傳輸,以實現(xiàn)無錯誤的 GPU 處理。該功能的工作方式類似于 CPU 內(nèi)存和磁盤之間的常規(guī)內(nèi)存分頁。使用此功能為優(yōu)化器狀態(tài)(Optimizer)分配分頁內(nèi)存,然后在 GPU 內(nèi)存不足時將其自動卸載到 CPU 內(nèi)存,并在優(yōu)化器更新步驟需要時將其加載回 GPU 內(nèi)存。

增加Adapter:4-bit的NormalFloat與Double Quantization,節(jié)省了很多空間,但帶來了性能損失,作者通過插入更多adapter來彌補這種性能損失。在LoRA中,一般會選擇在query和value的全連接層處插入adapter。而QLoRA則在所有全連接層處都插入了adapter,增加了訓練參數(shù),彌補精度帶來的性能損失。

參考:

https://zhuanlan.zhihu.com/p/632164305

https://zhuanlan.zhihu.com/p/636215898

https://zhuanlan.zhihu.com/p/634256206

https://zhuanlan.zhihu.com/p/632229856

https://blog.csdn.net/qq_39970492/article/details/131048994

總結(jié)

QLORA 可以使用 4 位基礎(chǔ)模型和低秩適配器 (LoRA) 復制 16 位完全微調(diào)性能。QLORA將微調(diào)65B參數(shù)模型的平均內(nèi)存需求從>780GB的GPU內(nèi)存降低到<48GB,與完全微調(diào)的16位基準相比,既不降低運行時間也不降低預測性能,這意味著可以在單個GPU上微調(diào)迄今為止最大的公開可用模型。

關(guān)鍵詞:

相關(guān)內(nèi)容