iT邦幫忙

2025 iThome 鐵人賽

DAY 24
0
生成式 AI

VLM系列 第 24

Day 24 :VLM QLoRA Fine-Tuning (1/2)

  • 分享至 

  • xImage
  •  

由於 VLM(視覺語言模型)通常非常大,我們需要結合 LoRA 和 4-bit 量化 (4-bit Quantization),也就是 QLoRA 技術,才能在 Google Colab 的免費 GPU上進行微調。

什麼是 VLM QLoRA Fine-Tuning

QLoRA 是 Quantized LoRA(量化低秩適應)的縮寫。它是 LoRA 技術的進階版本,專門為在計算資源有限(例如 Colab 的單一 T4 GPU)的情況下,微調極大型模型(例如 VLM 或 LLM)而設計。

QLoRA 的運作原理

QLoRA 實現高效能主要來自以下兩點的巧妙結合:

  1. 4-bit Base Model (量化基底模型)
  • 核心: NF4 (NormalFloat 4-bit) 量化。
    如何工作: 它將預訓練 VLM 的數十億個參數從標準的 float16(每個參數 2 Bytes)壓縮到只有 4-bit(每個參數 0.5 Bytes)。
  • 結果: 模型在 GPU 記憶體中的佔用空間減少約 8 倍。這使得原本需要 80GB VRAM 才能加載的模型,可以在 16GB 或 24GB 的消費級 GPU 上運行。
  • 注意: 模型的推理和反向傳播都是在量化後的權重上進行,但在實際計算時,會動態地解量化(De-quantization)到更高的精度(通常是 bfloat16),以確保計算精度的損失最小。
  1. LoRA Adapters (訓練適配器)
  • 核心: 低秩分解。
  • 如何工作:在量化後的 VLM 模型上,凍結所有 4-bit 的權重。只在模型的關鍵 Attention 層(如 Q,V,K 投影矩陣)旁,添加一組極小的 A 和 B 矩陣(即 LoRA 適配器)。
  • 結果: 整個訓練過程中,只有這些微小的 A 和 B 矩陣在學習。訓練所需的 VRAM 和時間都大幅減少。

動手玩 LLaVA VLM QLoRA Fine-Tuning

除了trl, 其他套件在Colab均有了,但運行時有出現錯誤,重新安裝與error相關的套件後就順利執行了

!pip install -q -U transformers bitsandbytes accelerate
!pip install -q git+https://github.com/huggingface/peft.git
!pip install -q git+https://github.com/huggingface/trl.git

載入套件

import torch
from transformers import AutoTokenizer, BitsAndBytesConfig, LlavaForConditionalGeneration, LlavaProcessor
from trl import SFTTrainer
from peft import LoraConfig
from datasets import Dataset
import requests
from PIL import Image
import io
import json
import os
# --- 模型設定 ---
model_id = "llava-hf/llava-1.5-7b-hf"

# --- 4-bit 量化設定 ---
# 載入 4-bit 模型: 使用 `bitsandbytes` 的 `BitsAndBytesConfig` 設定
# load_in_4bit=True,這會將模型權重從 32-bit 或 16-bit 浮點數轉換為 4-bit 整數,記憶體佔用變為原來的 1/4 或 1/8。
# bnb_4bit_quant_type="nf4", 是一種更適合神經網路權重的 4-bit 量化類型。
# bnb_4bit_compute_dtype=torch.bfloat16,雖然模型以 4-bit 儲存,但在計算時(如矩陣乘法)會短暫轉回 `bfloat16` 以維持精度。
quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_quant_type="nf4"
)

# --- 載入模型 ---
# device_map="auto" 會自動將模型分佈到可用的硬體上(這裡是 T4 GPU)
model = LlavaForConditionalGeneration.from_pretrained(
    model_id,
    quantization_config=quantization_config,
    device_map="auto",
)

# --- 載入 Tokenizer ---
# Tokenizer 負責將文字轉換成數字 ID
tokenizer = AutoTokenizer.from_pretrained(model_id)
# LLaVA 使用 PAD token 來對齊序列長度,但預設模型沒有設定,我們將其設為 UNK token
tokenizer.pad_token = tokenizer.unk_token

# --- 載入 Processor ---
# Processor 整合了圖片前處理和文字 Tokenization,是處理多模態輸入的關鍵
processor = LlavaProcessor.from_pretrained(model_id)
processor.tokenizer = tokenizer # 確保 processor 使用我們修改過的 tokenizer

print("模型、Tokenizer 與 Processor 載入完成!")

目前執行到這裡,是可以正常運作的部分,其他仍在debug中,明天繼續!


上一篇
Day 23 :LoRA (Low-Rank Adaptation)
系列文
VLM24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言