在文章Firefly(流螢): 中文對話式大語言模型、中文對話式大語言模型Firefly-2b6開源,使用210萬訓練數據中,我們介紹了關于Firefly(流螢)模型的工作。對大模型進行全量參數微調需要大量GPU資源,所以我們通過對Bloom進行詞表裁剪,在4*32G的顯卡上,勉強訓練起了2.6B的firefly模型。
在本文中,我們將介紹QLoRA,由華盛頓大學提出的一種高效微調大模型的方法,可在單張A100上對LLaMA-65B進行微調。在論文中,作者的實驗表明使用QLoRA微調的LLaMA-65B,可達到ChatGPT性能水平的99.3%(由GPT-4進行評價),并且QLoRA的性能可以逼近全量參數微調。作者做了豐富的實驗證明這一結論。
在本文中我們將對QLoRA的基本原理進行介紹,并且在Firefly項目中進行實踐。我們在bloom-7b1的基礎上,使用QLoRA進行中文指令微調,獲得firefly-7b1-qlora-v0.1模型,具有不錯的效果,生成效果見第三章。QLoRA確實是一種高效訓練、效果優秀、值得嘗試和深入研究的方法。
論文地址:
https://arxiv.org/pdf/2305.14314.pdf
項目代碼:
https://github.com/yangjianxin1/Firefly
模型權重:
https://huggingface.co/YeungNLP/firefly-7b1-qlora-v0.1
01
QLoRA簡介
本章節主要對LoRA與QLoRA進行介紹,如讀者已了解本章節的內容,可直接跳過,閱讀項目實踐部分。
LoRA簡介
在介紹QLoRA之前,簡單回顧一下LoRA。LoRA的本質是在原模型的基礎上插入若干新的參數,稱之為adapter。在訓練時,凍結原始模型的參數,只更新adapter的參數。對于不同的基座模型,adapter的參數量一般為幾百萬~幾千萬。
LoRA的優勢在于能夠使用較少的GPU資源,在下游任務中對大模型進行微調。在開源社區中,開發者們使用LoRA對Stable Diffusion進行微調,取得了非常不錯的效果。隨著ChatGPT的火爆,也涌現出了許多使用LoRA對LLM進行指令微調的工作。
此前,我們也實踐過使用LoRA對LLM進行指令微調,雖然未進行定量分析,但主觀感受LoRA比全量微調還是有一定的差距。實踐下來,我們發現LoRA微調中存在以下三個痛點:
-
參數空間小:LoRA中參與訓練的參數量較少,解空間較小,效果相比全量微調有一定的差距。
-
微調大模型成本高:對于上百億參數量的模型,LoRA微調的成本還是很高。
-
精度損失:針對第二點,可以采用int8或int4量化,進一步對模型基座的參數進行壓縮。但是又會引發精度損失的問題,降低模型性能。
QLoRA簡介
接下來便引入今天的主角QLoRA。整篇論文讀下來,我們認為QLoRA中比較重要的幾個做法如下:
-
4-bit NormalFloat:提出一種理論最優的4-bit的量化數據類型,優于當前普遍使用的FP4與Int4。
-
Double Quantization:相比于當前的模型量化方法,更加節省顯存空間。每個參數平均節省0.37bit,對于65B的LLaMA模型,大約能節省3GB顯存空間。
-
Paged Optimizers:使用NVIDIA統一內存來避免在處理小批量的長序列時出現的梯度檢查點內存峰值。
-
增加Adapter:4-bit的NormalFloat與Double Quantization,節省了很多空間,但帶來了性能損失,作者通過插入更多adapter來彌補這種性能損失。在LoRA中,一般會選擇在query和value的全連接層處插入adapter。而QLoRA則在所有全連接層處都插入了adapter,增加了訓練參數,彌補精度帶來的性能損失。
通過上述優化,只需要41G顯存即可微調LLaMA-65B模型。甚至可以直接使用一張1080Ti來微調LLaMA-13B,手中的舊卡又可以繼續發揮余熱了。
作者使用GPT4對各個模型進行評價,結果顯示,使用QLoRA在OASST1數據集上微調得到的Guanaco-65B模型達到了ChatGPT的99.3%的性能。
作者進一步采用了Elo等級分制度對各個模型進行評價,裁判為人類或者GPT-4。結果顯示Guanaco-65B和Guanaco-33B均優于ChatGPT-3.5。
實驗分析
QLoRA方法是否有用,其與全量參數微調的差距有多大?作者使用LLaMA-7B和Alpaca數據集進行了實驗。下圖結果表明,通過插入更多的adapter,能夠彌補QLoRA量化帶來的性能損失,復現全量參數微調的效果。
除此之外,作者還將QLoRA應用于RoBERTA和T5,評測其在GLUE和Super-NaturalInstructions數據集上的表現。從下表中可以看到,QLoRA+NF4+DQ基本上復現了BF16全量微調的實驗指標。
下表中LoRA+BF16基本上也復現了BF16全量微調的實驗指標,如果作者能加上LoRA+FP4或者LoRA+int4的實驗結果,則可以更清晰地展現LoRA與QLoRA的性能差異。
在指令微調階段,數據質量和數據數量,哪一個更重要?作者使用三種不同的訓練集,每個數據集分別使用5萬、10萬、15萬的數據量進行訓練。對于下表,縱向來看,隨著數據量的增加,指標并沒有明顯的提升,說明數據量不是關鍵因素。橫向來看,對于不同的數據集,指標差距甚大,說明數據質量更關鍵。
值得一提的是,在論文中,作者僅使用了9千多條OASST1的數據訓練得到Guanaco-65B,這進一步驗證了,數據質量遠比數量重要,模型的知識來源于預訓練階段。
模型的知識來源于預訓練階段,指令微調目的是和人類指令進行對齊。在指令微調階段,數據的質量與豐富度,遠比數量更重要。這是最近一段時間,開源社區以及各個論文強調的一個結論,在我們的實踐中也深有體會。
02
項目實踐
在本項目中,我們使用bloom-7b1作為基座模型。數據集為moss-003-sft-no-tools,這是由MOSS項目開源的中文指令微調數據集,我們隨機抽取了29萬條作為訓練數據,訓練得到firefly-7b1-qlora-v0.1。
訓練時,我們將多輪對話拼接成如下格式,然后進行tokenize。
<s>input1s>target1s>input2s>target2s>...
我們在一張32G顯卡上使用QLoRA進行訓練,在所有全連接層處都插入adapter,最終參與訓練的參數量超過1億,相當于一個bert-base的參數量。訓練時只計算target部分的損失函數。
訓練超參數如下所示:
max length | 1024 |
lr_scheduler_type | cosine |
batch size | 16 |
lr | 2e-4 |
warmup step | 3000 |
optimizer | paged_adamw_32bit |
training step | 18萬 |
模型的訓練損失的變化趨勢如下圖所示:
firefly-7b1-qlora-v0.1的使用方式如下:
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer, LlamaTokenizer, BitsAndBytesConfig
import torch
model_name = 'bigscience/bloom-7b1'
adapter_name = 'YeungNLP/firefly-7b1-qlora-v0.1'
device = 'cuda'
input_pattern = '{}'
model = AutoModelForCausalLM.from_pretrained(
model_name,
low_cpu_mem_usage=True,
torch_dtype=torch.float16,
device_map='auto'
)
model = PeftModel.from_pretrained(model, adapter_name)
model.eval()
model = model.to(device)
tokenizer = AutoTokenizer.from_pretrained(model_name)
text = input('User:')
while True:
text = input_pattern.format(text)
input_ids = tokenizer(text, return_tensors="pt").input_ids
input_ids = input_ids.to(device)
outputs = model.generate(input_ids=input_ids, max_new_tokens=250, do_sample=True, top_p=0.75, temperature=0.35,
repetition_penalty=1.2, eos_token_id=tokenizer.eos_token_id)
rets = tokenizer.batch_decode(outputs)
output = rets[0].strip().replace(text, "").replace('', "")
print("Firefly:{}".format(output))
text = input('User:')
03
生成效果
下面的樣例均為firefly-7b1-qlora-v0.1模型所生成,未經修改,僅供參考。
多輪對話
對話示例1:
對話示例2:
郵件生成
商品文案生成
醫療問答
創意性寫作
其他例子
04
結語
在本文中,我們介紹了QLoRA的基本原理,以及論文中一些比較重要的實驗結論。并且使用QLoRA對bloom-7b1模型進行中文指令微調,獲得了非常不錯的效果。
從firefly-7b1-qlora-v0.1的生成效果來看,雖然沒有做定量的評測(對LLM做評測確實比較困難),但就生成效果來看,絲毫不遜色于全量微調的firefly-2b6-v2。
一些碎碎念:
-
論文中表明QLoRA能夠媲美全量參數微調的效果,雖然可能需要更豐富、多角度的實驗進行驗證,但如果【增大基座模型的參數量+QLoRA】能夠優于【全量微調較小的模型】,也是非常有意義的。
-
對基座模型進行量化壓縮,通過增加adapter來彌補量化導致性能損失,是一個非常不錯的idea,論文中的實驗也證實了這一點。并且從我們的實踐效果看來,確實驚艷,效果遠勝LoRA。
-
最后,如果你手邊的訓練資源不足,QLoRA非常值得一試。
-
gpu
+關注
關注
28文章
4735瀏覽量
128923 -
開源
+關注
關注
3文章
3336瀏覽量
42486 -
語言模型
+關注
關注
0文章
523瀏覽量
10274
原文標題:QLoRA實戰 | 使用單卡高效微調bloom-7b1,效果驚艷
文章出處:【微信號:zenRRan,微信公眾號:深度學習自然語言處理】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論