LLM.int8() 和 QLoRA 是兩種深度學習模型量化技術,能有效降低模型大小和計算成本,提升推理速度。LLM.int8() 將模型權重和啟用函式分為 fp16 的異常值和 int8 的常規值兩部分計算,兼顧效能和效率。QLoRA 則結合了 LoRA(低秩自適應)和量化技術,將基礎模型量化為 4 位元並凍結,再以 bfloat16 訓練 LoRA 介面卡,實作高效微調。這些技術的應用能顯著降低硬體需求,讓更多開發者能夠參與模型訓練和佈署。
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained("mistral-7b", quantization_config=quantization_config)
LLM.int8() 量化技術
LLM.int8()是一種特殊的量化技術,允許我們在不犧牲效能的情況下進行8位元量化。這種技術的基本思想是將模型的權重和啟用函式分為兩部分:一部分是使用fp16進行計算的outlier(異常值),另一部分是使用int8進行計算的常規值。這樣做可以保證模型的效能不會下降太多,而記憶體需求卻大大減少。
量化的優點和缺點
量化技術有許多優點,包括:
- 減少模型大小和記憶體需求
- 加快推理速度
- 減少能耗
然而,量化技術也有一些缺點,包括:
- 可能導致模型效能下降
- 需要額外的計算資源和記憶體來進行量化和反量化
QLoRA 量化技術
QLoRA是一種新的量化技術,結合了LoRA(Low-Rank Adaptation)和量化技術。這種技術首先將基礎模型量化為4位元,並凍結它。然後,新增LoRA介面卡(兩個矩陣),並保持在bfloat16中。當微調時,QLoRA使用4位元儲存基礎模型和16位元模型進行計算。
使用 4 位元量化
要使用 4 位元量化,只需改變 load_in_4bit 引數即可。以下是使用 Mistral 7B 模型的示例程式碼:
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained("mistral-7b", quantization_config=quantization_config)
實作對話式生成模型的細節
對話式生成模型是一種可以進行簡單對話的模型,以下是實作這種模型的步驟。
基礎模型
我們使用Mistral模型作為基礎模型。Mistral是一個高品質的7B模型,我們使用load_in_4bit和device_map="auto"來進行4-bit量化。
資料集
我們使用Guanaco資料集,該資料集包含10,000個高品質的人類和OpenAssistant模型之間的對話。
PEFT組態
我們指定了一個LoraConfig,具有良好的初始預設值:rank(r)為8,alpha是其兩倍的值。
訓練引數
我們可以組態訓練引數(例如評估頻率和epoch數)以及模型超引數(學習率、權重衰減或epoch數)。
使用trl函式庫
trl函式庫提供了SFTConfig和SFTTrainer類別,這些類別是TrainingArguments和Trainer的包裝器,最佳化了文字生成。它們提供了以下功能:
- 易於使用的資料載入和處理工具
- 支援常見的對話和指令範本
- 可以直接傳遞任何PeftConfig給SFTTrainer以使用PEFT技術
訓練模型
我們可以傳遞已量化的模型和資料集(我們傳遞300個樣本以進行快速訓練)。SFTTrainer已經帶有有用的預設collators和資料集工具,因此無需對資料進行tokenizing和預處理。
from trl import SFTConfig, SFTTrainer
dataset = load_dataset("timdettmers/openassistant-guanaco", split="train")
peft_config = LoraConfig(
r=8,
lora_alpha=16,
lora_dropout=0.05,
task_type="CAUSAL_LM",
)
sft_config = SFTConfig(
"fine_tune_e2e",
push_to_hub=True,
per_device_train_batch_size=8,
weight_decay=0.1,
lr_scheduler_type="cosine",
learning_rate=5e-4,
num_train_epochs=2,
eval_strategy="steps",
eval_steps=200,
logging_steps=200,
gradient_checkpointing=True,
max_seq_length=512,
dataset_text_field="text",
packing=True,
)
trainer = SFTTrainer(
model,
args=sft_config,
train_dataset=dataset.select(range(300)),
peft_config=peft_config,
)
trainer.train()
trainer.push_to_hub()
使用模型
訓練完成後,我們可以使用模型和介面卡進行推理。
# 我們載入基礎模型
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.3")
圖表翻譯:
flowchart TD
A[開始] --> B[載入基礎模型]
B --> C[載入資料集]
C --> D[組態PEFT]
D --> E[訓練模型]
E --> F[推理]
內容解密:
以上程式碼展示瞭如何實作對話式生成模型。首先,我們載入基礎模型和資料集。然後,我們組態PEFT並訓練模型。最後,我們使用模型和介面卡進行推理。
自然語言處理中的對話模型
對話模型(Conversational Models)是一種能夠進行自然語言對話的AI模型。它們的設計目的是模擬人類之間的對話,透過對話來理解使用者的需求並提供有用的回應。
對話模型的優點
- 提高使用者經驗:對話模型可以提供更自然、更人性化的互動體驗,讓使用者感覺像是在與真實的人對話。
- 增強理解能力:透過對話,模型可以更好地理解使用者的需求和意圖,從而提供更準確的回應。
- 提高效率:對話模型可以自動化許多重複性的任務,例如客服、技術支援等,從而節省時間和成本。
對話模型的挑戰
- 語言理解:對話模型需要能夠理解自然語言的複雜性和歧義性,包括語法、語義、語用等方面。
- 知識圖譜:對話模型需要有一個龐大的知識圖譜來支援其回答問題和進行對話的能力。
- 評估標準:對話模型的評估標準往往是主觀的,需要人工評估其對話品質和相關性。
Hugging Face Transformers
Hugging Face Transformers是一個流行的自然語言處理函式庫,提供了許多預訓練好的模型和工具,可以用於構建對話模型。其中包括了對話模型的基礎架構、tokenizer、評估工具等。
實踐對話模型
實踐對話模型需要以下步驟:
- 選擇模型:選擇一個合適的預訓練好的模型作為基礎。
- 定義對話流程:定義對話流程,包括使用者輸入、模型回應等。
- 訓練模型:訓練模型以適應特定的對話任務。
- 評估模型:評估模型的效能和品質。
chat_template
chat_template是一種簡單的方式,可以用於構建對話模型。它提供了一個預先定義好的對話方塊架,可以用於簡化對話模型的構建過程。
評估語言模型的方法
評估語言模型的效能是一個複雜的任務,需要考慮多個方面。以下是幾種常用的評估方法:
Perplexity
Perplexity是一種衡量語言模型預測能力的指標。它計算了模型對給定資料集的預測機率分佈的熵值。Perplexity值越低,表示模型對資料集的預測能力越好。
BLEU
BLEU(Bilingual Evaluation Understudy)是一種評估機器翻譯系統的指標。它計算了生成文字和參考文字之間的相似度。BLEU重視精確度,但可能無法捕捉自然語言的多樣性和語義相似性。
ROUGE
ROUGE(Recall-Oriented Understudy for Gisting Evaluation)是一種評估自動摘要系統的指標。它計算了生成文字和參考文字之間的重疊度。ROUGE重視召回率,但可能無法捕捉語義相似性和長度偏差。
評估語言模型的挑戰
評估語言模型的效能存在多個挑戰:
- 缺乏語義理解:BLEU和ROUGE等指標僅考慮詞彙層面的相似性,可能無法捕捉語義相似性。
- 長度偏差:ROUGE等指標可能偏向長度更長的生成文字。
- 多樣性:自然語言具有多樣性,評估指標可能無法捕捉這種多樣性。
人工評估
人工評估是評估語言模型的一種重要方法。人工評估可以提供更為主觀和細膩的評估結果,幫助評估語言模型的效能和可用性。
基準測試
基準測試是評估語言模型的一種方法。基準測試可以提供一個基準線,幫助評估語言模型的效能和可用性。
專案時間:檢索增強生成
檢索增強生成(RAG)是一種技術,允許語言模型存取外部知識函式庫。RAG可以幫助語言模型生成更為準確和相關的文字。
以下是RAG管道的步驟:
- 使用者輸入問題。
- 管道檢索最相似的檔案。
- 管道將問題和檢索檔案傳遞給語言模型。
- 管道生成回應。
實作檢索增強生成
實作檢索增強生成需要以下步驟:
- 匯入檔案:使用句子轉換器模型將檔案編碼為向量。
- 儲存檔案:將檔案向量儲存在向量資料函式庫中。
- 搜尋檔案:使用最近鄰搜尋演算法查詢最相似的檔案。
- 生成回應:使用語言模型生成回應。
以下是實作檢索增強生成的示例程式碼:
import torch
from sentence_transformers import SentenceTransformer
# 匯入檔案
def embed_documents(documents):
# 使用句子轉換器模型將檔案編碼為向量
model = SentenceTransformer('distilbert-base-nli-mean-tokens')
embeddings = model.encode(documents)
return embeddings
# 儲存檔案
def store_documents(embeddings):
# 將檔案向量儲存在向量資料函式庫中
db = {}
for i, embedding in enumerate(embeddings):
db[i] = embedding
return db
# 搜尋檔案
def retrieve_documents(query, db):
# 使用最近鄰搜尋演算法查詢最相似的檔案
query_embedding = embed_documents([query])[0]
similarities = []
for i, embedding in db.items():
similarity = torch.cosine_similarity(query_embedding, embedding)
similarities.append((i, similarity))
similarities.sort(key=lambda x: x[1], reverse=True)
return [db[i] for i, _ in similarities[:10]]
# 生成回應
def generate_response(query, documents):
# 使用語言模型生成回應
model = torch.load('model.pth')
input_ids = torch.tensor([query])
attention_mask = torch.tensor([[1]])
outputs = model.generate(input_ids, attention_mask=attention_mask)
response = torch.argmax(outputs.logits, dim=-1)
return response
# 管道
def pipeline(query):
documents = retrieve_documents(query, store_documents(embed_documents(['file1', 'file2'])))
response = generate_response(query, documents)
return response
這個示例程式碼實作了檢索增強生成管道,包括匯入檔案、儲存檔案、搜尋檔案和生成回應。
第7章:微調Stable Diffusion模型
在前一章中,我們介紹瞭如何使用微調技術教導語言模型(LLM)以特定的風格或領域知識來生成文字。同樣的原理也可以應用於文字到影像的模型,從而使我們能夠使用單個GPU來定製模型,而不需要多個GPU節點來預訓練像Stable Diffusion這樣的模型。
在這一章中,我們將使用第5章中介紹的預訓練Stable Diffusion模型作為基礎,並延伸它以學習新的風格和概念,例如「你的寵物」或特定的繪畫風格。同時,我們也將學習如何給予模型新的能力,例如繪製和根據新的條件生成影像。
與其從頭開始撰寫程式碼,不如我們深入瞭解和執行現有的為微調模型而建立的指令碼。為此,我們建議您複製diffusers函式庫,因為大多數範例都在函式庫的examples目錄中。
完整Stable Diffusion微調
完整模型是一種微調的限定語,出現在特定模型定製技術的發展之後,例如LoRA、文字反轉和DreamBooth。這些技術不會完全微調整個模型,而是提供了一種高效的微調方法(如第6章中所學的LLM的LoRA),或提供了新的方法來「教導」模型新的概念。我們將在本章進一步討論這些技術。
在這些技術出現之前,完整模型這種限定語並不存在,因為那時候簡單地稱之為微調。微調在這個語境中意味著進一步訓練diffusion模型,如第3章和第4章所學,但目的是使其朝向您想要新增的特定知識方向發展。您可以使Stable Diffusion學習一個風格或主題,這些是透過提示或在模型發布後才發明的東西(見圖7-1)。當模型被微調後,它將在您引入的風格或主題上表現良好,並可能主要生成這型別的內容。
本文將使用預製指令碼進行完整微調。我們將使用diffusers函式庫中的指令碼diffusers/examples/text_to_image/train_text_to_image.py。
準備資料集
資料集的品質是最重要的部分。過濾資料集以保留僅高品質樣本並移除低品質示例,可以顯著影響微調的品質。
相對較大的資料集(500+影像)可能需要用於高品質的完整模型微調。雖然這可能聽起來很多,但與用於訓練整個Stable Diffusion模型的數十億影像相比,幾百張影像仍然是一個很小的比例。在本章後面將要討論的特定模型定製技術中,我們將學習如何使用少至四張影像來定製模型。
回到完整模型微調。當我們引導文字到影像模型時,我們必須向它展示一個包含影像及其描述性字幕的資料集,就像模型在預訓練過程中所見到的那樣。
如果您需要靈感,以下是一些示例:
- 重新演繹文藝復興繪畫以進行文藝復興風格微調
- 使用您最喜歡的建築風格的建築圖片來進行建築風格微調
…(剩餘內容)
使用 Stable Diffusion 進行細節調整
Stable Diffusion 是一種強大的影像生成模型,透過對其進行細節調整,可以用於生成高品質的影像。以下是使用 Stable Diffusion 進行細節調整的步驟:
步驟 1:準備資料集
首先,您需要準備一個資料集,該資料集包含您想要生成的影像型別。例如,如果您想要生成風景影像,您可以收集一組風景照片。您可以使用 Hubble Telescope 的公共資料集,或者建立自己的資料集。
步驟 2:載入資料集
載入資料集可以使用 load_dataset 函式,該函式可以從資料夾中載入影像和後設資料。後設資料應該包含每個影像的描述。
from datasets import load_dataset
dataset = load_dataset("imagefolder", data_dir="/path/to/folder")
步驟 3:推播資料集到 Hugging Face Hub
如果您想要分享您的資料集,您可以使用 push_to_hub 函式將其推播到 Hugging Face Hub。
dataset.push_to_hub("my-hf-username/my-incredible-dataset")
步驟 4:細節調整模型
要進行細節調整,您需要一個預訓練的模型和一個訓練指令碼。您可以使用 diffusers 函式庫提供的訓練指令碼和預訓練的 Stable Diffusion 模型。
accelerate launch train_text_to_image.py \
--pretrained_model_name_or_path="stable-diffusion-v1-5/stable-diffusion-v1-5" \
--dataset_name="Supermaxman/esa-hubble" \
--use_ema \
--mixed_precision="fp16"
步驟 5:訓練模型
開始訓練模型之前,請確保您有一個具有至少 16 GB VRAM 的 GPU,或者使用 Google Colab Pro 等服務。您可以根據自己的需求自定義超引數。
進一步瞭解Stable Diffusion微調引數
在進行Stable Diffusion微調的過程中,瞭解各個超引數的作用至關重要。以下是對於上述訓練指令碼中出現的部分超引數的詳細解釋:
1. --resolution=512:模型輸出的影像解析度
此引數控制了生成影像的尺寸。設定為512表示生成的影像將是512x512畫素。
2. --center_crop:中心裁剪
啟用此選項後,模型將從原始影像中裁剪出中心部分,以便進行訓練。這有助於去除影像邊緣可能存在的噪聲或不相關資訊。
3. --random_flip:隨機翻轉
此引數使模型在訓練過程中隨機水平翻轉影像,以增加訓練資料的多樣性,從而提高模型的泛化能力。
4. --train_batch_size=1:訓練批次大小
設定批次大小為1表示每次迭代只使用一張影像進行訓練。雖然這可能會減慢訓練速度,但對於某些模型或硬體組態可能是必要的。
5. --gradient_checkpointing:梯度檢查點
啟用梯度檢查點可以節省記憶體使用,但可能會增加計算時間。這是一種在模型訓練過程中儲存和還原梯度的方法,尤其對於大型模型或記憶體有限的裝置很有用。
6. --gradient_accumulation_steps=4:梯度累積步數
此引數設定了在進行權重更新之前累積梯度的步數。設為4表示每4個批次累積一次梯度後才進行權重更新。
7. --use_8bit_adam:使用8位Adam最佳化器
啟用此選項可以減少記憶體使用,但可能會影響模型的收斂速度或準確度。8位Adam是一種壓縮最佳化器,使用8位整數表示權重和梯度。
8. --checkpointing_steps=1000:檢查點間隔
設定模型儲存檢查點的間隔步數。每1000步,模型將儲存一次檢查點,以便於斷點續訓或還原訓練。
9. --num_train_epochs=50:訓練epoch數
設定了模型進行訓練的epoch數。一個epoch表示模型已經看過一次整個訓練集。
LLM.int8() 與 Stable Diffusion 微調技術總結
深入探討 LLM.int8() 量化技術和 Stable Diffusion 微調方法後,我們可以發現,降低模型大小和加速推理速度是當前深度學習模型發展的關鍵方向。LLM.int8() 的混合精確度量化策略,巧妙地平衡了效能和效率,為大語言模型的佈署提供了可行的方案。而 QLoRA 技術的出現,更進一步結合了低秩自適應和量化技術,展現出在有限資源下微調大型模型的巨大潛力。
分析不同量化技術的優缺點,可以看出,雖然量化可能帶來些許效能損失,但其在降低模型大小、加快推理速度和減少能耗方面的優勢,使其成為移動端和邊緣裝置佈署深度學習模型的重要技術。尤其在資源受限的環境下,QLoRA 等新興技術的應用價值更加凸顯。
展望未來,隨著硬體和軟體的協同發展,預計量化技術將持續演進,出現更高效、更精確的量化演算法。同時,結合其他模型壓縮技術,例如剪枝和知識蒸餾,將進一步提升深度學習模型的佈署效率,推動 AI 技術更廣泛地應用於各個領域。對於追求高效能和低功耗的應用場景,積極探索和應用先進的量化技術將至關重要。
至於 Stable Diffusion 微調,從完整模型微調到 LoRA、Textual Inversion 和 DreamBooth 等新興技術,我們觀察到降低訓練成本和提升模型個人化定製能力的趨勢。完整模型微調雖然效果出色,但資源消耗巨大。LoRA 等技術則提供了更輕量級的方案,允許使用者在單一 GPU 上高效地定製模型。
技術的發展也伴隨著挑戰。資料集的品質、超引數的調整以及評估指標的選擇都對微調效果有著顯著影響。此外,如何平衡模型的泛化能力和個人化定製程度也是一個需要持續探索的議題。
展望未來,隨著技術的成熟和社群的發展,預計 Stable Diffusion 微調技術將更加便捷易用,同時出現更多創新的定製化方案。這將進一步降低影像生成技術的門檻,激發更多創意應用,並推動 AI 藝術的蓬勃發展。密切關注新技術和工具的發展,將有助於更好地掌握 Stable Diffusion 的強大功能,創造出更具個人化和藝術性的影像作品。 我們建議持續關注 diffusers 函式庫的發展,並積極探索新的微調技術,以充分利用 Stable Diffusion 的潛力。