前言
為了使用開放權重的LLM(大語言模型),基于自己的訓練集,微調模型,會涉及到如下一些技術要點:
- 配置運行環(huán)境
- 下載、加載基礎模型
- 收集語料、微調訓練
- 檢驗訓練效果
在實施過程中,遇到不少困難,因此寫下這篇文檔,做為記錄。
環(huán)境配置
1. 模型加載 - icetk報錯
(1) 問題描述
在huggingface的模型庫中,大模型會被分散為多個bin
文件,在加載這些原始模型時,有些模型(如Chat-GLM)需要安裝icetk
。
這里遇到了第一個問題,使用pip
安裝icetk
和torch
兩個包后,使用from_pretrained
加載模型時會報缺少icetk
的情況。
但實際情況是這個包已經安裝了。
查資料的過程中,有人說出現(xiàn)該錯誤的原因是icetk依賴cpu版torch2.0,需要先裝icetk再裝GPU版torch。
但我嘗試該方案后并不成功,之后在github上看到一條相同的issue,下方的回答中提到的方法,成功解決了我的問題。
(2) 解決方案
- 啟動python環(huán)境,執(zhí)行
import icetk
會報錯,并指向lzma.py中的引用錯誤 - 根據(jù)錯誤提示,定位到lzma.py文件及相關代碼的位置
- 按如下方式修改源代碼
修改前
from _lzma import *
from _lzma import _encode_filter_properties, _decode_filter_properties
修改后
try:
from _lzma import *
from _lzma import _encode_filter_properties, _decode_filter_properties
except ImportError:
from backports.lzma import *
from backports.lzma import _encode_filter_properties, _decode_filter_properties
2. 安裝指定版本 - transformers安裝
(1) 問題描述
截止到目前(2023-04-06),Meta官方仍未對LLaMa模型開源,網上流傳的為泄露版。因此,正式版transformers沒有該模型的Model或Tokenizer庫。
在查找資料的過程中,有人說使用
pip install git+某版本transformer
安裝dev版transformers。
但由于當我使用該指令安裝時,這里指定的分支已經被刪除了,所以無法安裝成功。
(2) 解決方案
因為無法通過pip install的方式安裝,所以這里考慮用編譯源碼的方式安裝。
git clone https://github.com/huggingface/transformers.git
pip install -e .
因為模型目前還未開源,所以使用這種方式解決。未來Meta正式開源該模型后,transformers肯定會提供支持。
屆時,直接使用pip install transformers
即可。
微調訓練
1. 并行計算 - bitsandbytes報錯
(1) 問題描述
安裝bitsandbytes
,可以在加載模型時,設置load_in_8bit=True, device_map='auto'
降低顯存,并將模型分布到GPU上計算。
但在引用時會出現(xiàn)警告: UserWarning: The installed version of bitsandbytes was compiled without GPU support.
。
并在模型加載時會報有關"libsbitsandbytes_cpu.so"的編譯錯誤。
(2) 解決方案
- 正確安裝cuda、cuda-tookit
- 在.bashrc中配置LD_LIBRARY_PATH
詳細情況可參考這篇博客:bitsandbytes報錯解決方案
可能是因為Nvidia針對浮點型計算進行過優(yōu)化,使用
load_in_8bit=True
讓參數(shù)以整型進行計算,反而會降低計算速度。
因此,在顯存足夠時,建議不使用該設置。
2. 模型微調 - 使用PEFT
Lora技術提出之后,huggingface提供了PEFT框架支持,可通過pip install peft
安裝。
使用時分為如下步驟:
- 參數(shù)設置 - 配置Lora參數(shù),通過
get_peft_model
方法加載模型。 - 模型訓練 - 此時只會微調模型的部分參數(shù)、而其他參數(shù)不變。
- 模型保存 - 使用
model.save_pretrained("output_dir")
方法保存模型。 - 模型加載 - 讀取保存peft模型及相關配置,使用
PeftModel.from_pretrained(model, peft_model_id)
方法加載模型。
(1) 模型訓練、保存
from transformers import AutoModel
from peft import get_peft_model, LoraConfig
# Lora參數(shù)設置
peft_config = LoraConfig(
r=lora_r,
lora_alpha=lora_alpha,
target_modules=lora_target_modules,
lora_dropout=lora_dropout,
bias="none",
task_type="CAUSAL_LM",
)
# 模型加載
model = AutoModel.from_pretrained("model_name_or_path")
model = get_peft_model(model, peft_config)
# output: trainable params: 4194304 || all params: 6742609920 || trainable%: 0.06220594176090199
model.print_trainable_parameters()
# 模型訓練
...
# 模型保存
model.save_pretrained("output_dir")
(2) 模型加載、計算
以下是官方給出的樣例,但是按該方式加載模型,在計算時會出現(xiàn)AttributeError: 'NoneType' object has no attribute 'device'
報錯。
from transformers import AutoModel, AutoTokenizer
from peft import PeftModel, PeftConfig
# 加載peft配置
peft_model_id = "output_dir"
peft_config = PeftConfig.from_pretrained(peft_model_id)
# 加載tokenizer
tokenizer = AutoTokenizer.from_pretrained(peft_config.base_model_name_or_path)
# 結合基礎模型和微調結果,加載模型
model = AutoModel.from_pretrained(peft_config.base_model_name_or_path)
model = PeftModel.from_pretrained(model, peft_model_id)
model = model.to(device)
model.eval()
# 模型計算
...
在查找資料后,發(fā)現(xiàn)這是PEFT在遇到GPU加載模型時會產生的bug。
根據(jù)使用環(huán)境是單GPU或多GPU,分別按以下兩種方式使用,即可解決上述問題。
解決方案 - 單GPU
# 加載基礎模型
base_model = AutoModel.from_pretrained(
model_path,
load_in_8bit=True,
torch_dtype=torch.float16,
# device_map="{'': 0}"
device_map="auto"
)
peft_model = PeftModel.from_pretrained(
base_model,
peft_model_id,
torch_dtype=torch.float16,
# device_map="{'': 0}"
device_map="auto"
)
解決方案 - 多GPU
# 加載基礎模型
base_model = AutoModel.from_pretrained(
model_path,
load_in_8bit=True,
torch_dtype=torch.float16,
device_map="auto"
)
# 獲取模型參數(shù)分配表
device_map = {f"base_model.model.{k}": v for k, v in model.hf_device_map.items()}
# 按相同的參數(shù)分配加載peft model
peft_model = PeftModel.from_pretrained(
base_model,
peft_model_id,
device_map=device_map,
torch_dtype=torch.float16
)
在查找資料的過程中,我先看到的是單GPU的解決方案,但是該方案對多GPU不適用。
應該是因為自動分配參數(shù)時,無法保證peft_model和base_model的分配方法一致。
因此,在多GPU環(huán)境下,需通過device_map
綁定二者參數(shù)的分配方式。
吐槽
在查資料的過程中,建議大家多用谷歌、少用百度。
上述這幾個問題,都在github對應倉庫的issue里有人提出過,我也都是從下方的答復中找到的解決方案。
但是在用百度和谷歌搜報時,百度卻從沒給出github上的回答。文章來源:http://www.zghlxwxcb.cn/news/detail-484305.html
百度 | 谷歌 |
---|---|
![]() |
![]() |
參考文檔
icetk報錯 - https://github.com/THUDM/ChatGLM-6B/issues/323
bitsandbytes報錯 - https://github.com/oobabooga/text-generation-webui/issues/147#issuecomment-1456040134
peft使用說明 - https://huggingface.co/blog/peft
peft加載模型 - https://github.com/tloen/alpaca-lora/issues/77文章來源地址http://www.zghlxwxcb.cn/news/detail-484305.html
到了這里,關于大模型微調踩坑記錄 - 基于Alpaca-LLaMa+Lora的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!