PaliGemma – 谷歌尖端開放視覺語言模型
更新於 2024 年 5 月 23 日:我們對 Transformers PaliGemma 的微調實現進行了一些更改,您可以在此 notebook 中找到。
PaliGemma 是谷歌新推出的視覺語言模型系列。PaliGemma 可以接收影像和文字並輸出文字。
谷歌團隊釋出了三種類型的模型:預訓練(pt)模型、混合模型和微調(ft)模型,每種模型都具有不同的解析度,並提供多種精度以方便使用。
所有模型都發布在 Hugging Face Hub 模型倉庫中,並附帶模型卡和許可證,並集成了 Transformers。
什麼是 PaliGemma?
PaliGemma (Github) 是一個視覺語言模型家族,其架構由 SigLIP-So400m 作為影像編碼器,Gemma-2B 作為文字解碼器。SigLIP 是一個能夠理解影像和文字的最新模型。與 CLIP 類似,它由一個影像編碼器和文字編碼器共同訓練而成。類似於 PaLI-3,組合的 PaliGemma 模型在影像-文字資料上進行預訓練,然後可以輕鬆地在下游任務(如影像字幕或指稱分割)上進行微調。Gemma 是一個僅解碼器模型,用於文字生成。將 SigLIP 的影像編碼器與 Gemma 結合使用線性介面卡,使得 PaliGemma 成為一個強大的視覺語言模型。
PaliGemma 釋出了三種類型的模型
- PT 檢查點:可以微調到下游任務的預訓練模型。
- 混合檢查點:微調到混合任務的 PT 模型。它們適用於自由文字提示的通用推理,並且僅可用於研究目的。
- FT 檢查點:一組微調模型,每個模型專門針對不同的學術基準。它們提供各種解析度,並且僅可用於研究目的。
這些模型有三種不同的解析度(`224x224`、`448x448`、`896x896`)和三種不同的精度(`bfloat16`、`float16` 和 `float32`)。每個倉庫都包含給定解析度和任務的檢查點,每個可用精度有三個修訂版本。每個倉庫的 `main` 分支包含 `float32` 檢查點,而 `bfloat16` 和 `float16` 修訂版本包含相應的精度。模型相容 🤗 Transformers 和原始 JAX 實現的倉庫是分開的。
正如後面詳細解釋的,高解析度模型需要更多的記憶體才能執行,因為輸入序列更長。它們可能有助於 OCR 等精細任務,但對於大多數任務而言,質量提升很小。224 版本對於大多數用途來說已經足夠了。
您可以在此 集合 中找到所有模型和空間。
模型能力
PaliGemma 是一個單輪視覺語言模型,不適用於對話式使用,並且在微調到特定用例時效果最佳。
您可以透過使用任務字首(如“detect”或“segment”)對模型進行條件化來配置模型將解決的任務。預訓練模型就是以這種方式訓練的,以使其具備豐富的R能力集(問答、字幕、分割等)。然而,它們並非設計用於直接使用,而是透過(微調)轉移到使用類似提示結構特定任務。對於互動式測試,您可以使用已在混合任務上進行微調的“mix”模型家族。
以下示例使用混合檢查點來演示一些功能。
影像字幕
PaliGemma 可以在被提示時為影像新增字幕。您可以使用混合檢查點嘗試各種字幕提示,以檢視它們如何響應。
視覺問答
PaliGemma 可以回答關於影像的問題,只需將您的問題和影像一起傳遞即可。
檢測
PaliGemma 可以使用 `detect [entity]` 提示來檢測影像中的實體。它將以特殊 `
指稱表示式分割
PaliGemma 混合檢查點在給定 `segment [entity]` 提示時,也可以分割影像中的實體。這被稱為指稱表示式分割,因為我們使用自然語言描述來指代感興趣的實體。輸出是位置和分割標記的序列。位置標記表示如上所述的邊界框。分割標記可以進一步處理以生成分割掩碼。
文件理解
PaliGemma 混合檢查點具有出色的文件理解和推理能力。
混合基準
您可以在下方找到混合檢查點的分數。
模型 | MMVP 準確率 | POPE 準確率 (隨機/流行/對抗) |
---|---|---|
mix-224 | 46.00 | 88.00 86.63 85.67 |
mix-448 | 45.33 | 89.37 88.40 87.47 |
微調檢查點
除了預訓練模型和混合模型,谷歌還發布了已經轉移到各種任務的模型。它們對應於學術基準,研究界可以使用它們來比較它們的效能。下面,您可以找到一些精選的模型。這些模型也提供不同的解析度。您可以檢視任何模型的模型卡以獲取所有指標。
模型名稱 | 資料集/任務 | 在轉移任務中的得分 |
---|---|---|
paligemma-3b-ft-vqav2-448 | 圖表理解 | VQAV2 上的準確率 85.64% |
paligemma-3b-ft-cococap-448 | COCO 影像標題 | 144.6 CIDEr |
paligemma-3b-ft-science-qa-448 | 科學問答 | ScienceQA Img 子集(無 CoT)準確率 95.93% |
paligemma-3b-ft-refcoco-seg-896 | 理解影像中特定物件的引用 | refcoco 上的平均 IoU 為 76.94,refcoco+ 上的平均 IoU 為 72.18,refcocog 上的平均 IoU 為 72.22 |
paligemma-3b-ft-rsvqa-hr-224 | 遙感視覺問答 | 測試準確率 92.61%,測試 2 準確率 90.58% |
演示
作為此次釋出的一部分,我們提供了一個 演示,它封裝了 big_vision 倉庫中的參考實現,並提供了一種簡單的方式來試用混合模型。
我們還提供了 相容 Transformers 的演示版本,以展示如何使用 PaliGemma Transformers API。
如何執行推理
要訪問 PaliGemma 模型,您需要接受 Gemma 的許可條款和條件。如果您已經擁有 Hugging Face 中其他 Gemma 模型的訪問許可權,則無需額外操作。否則,請訪問任何 PaliGemma 模型,如果您同意,請接受許可證。獲得訪問許可權後,您需要透過 notebook_login 或 huggingface-cli login 進行身份驗證。登入後,即可開始使用!
您也可以立即 在此筆記本中 嘗試推理。
使用 Transformers
您可以使用 `PaliGemmaForConditionalGeneration` 類對任何已釋出的模型進行推理。只需使用內建處理器預處理提示和影像,然後將預處理後的輸入傳遞給生成器即可。
from transformers import AutoProcessor, PaliGemmaForConditionalGeneration
model_id = "google/paligemma-3b-mix-224"
model = PaliGemmaForConditionalGeneration.from_pretrained(model_id)
processor = AutoProcessor.from_pretrained(model_id)
prompt = "What is on the flower?"
image_file = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg?download=true"
raw_image = Image.open(requests.get(image_file, stream=True).raw)
inputs = processor(prompt, raw_image, return_tensors="pt")
output = model.generate(**inputs, max_new_tokens=20)
print(processor.decode(output[0], skip_special_tokens=True)[len(prompt):])
# bee
您還可以按如下方式以 4 位載入模型。
from transformers import BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16
)
model = PaliGemmaForConditionalGeneration.from_pretrained(
model_id,
quantization_config=bnb_config,
device_map={"":0}
)
除了 4 位(或 8 位)載入,Transformers 整合還允許您利用 Hugging Face 生態系統中的其他工具,例如
- 訓練和推理指令碼及示例
- 序列化為安全檔案 (safetensors)
- 與 PEFT (引數高效微調) 等工具整合
- 實用工具和輔助函式,用於使用模型執行生成
詳細推理過程
如果您想編寫自己的預處理或訓練程式碼,或者想更詳細地瞭解 PaliGemma 的工作原理,以下是輸入影像和文字所經歷的步驟。
輸入文字照常進行分詞。在開頭新增一個 `
請注意,更大的影像會導致更長的輸入序列,因此需要更多的記憶體來處理模型的語言部分。在考慮使用哪種模型時請牢記這一點。對於 OCR 等更精細的任務,更大的影像可能有助於獲得更好的結果,但對於絕大多數任務而言,質量增益很小。在決定使用更大解析度之前,請務必在您的任務上進行測試!
這個完整的“提示”透過語言模型的文字嵌入層,並生成每個標記 2048 維的標記嵌入。
與此同時,輸入影像使用雙三次插值法調整大小到所需的輸入尺寸(對於解析度最小的模型是 224x224)。然後它透過 SigLIP 影像編碼器生成每個補丁 1152 維的影像嵌入。線性投影器在此發揮作用:影像嵌入被投影以獲得每個補丁 2048 維的表示,與從文字標記獲得的表示相同。最終的影像嵌入與 `
所有這些細節都在處理器和模型類中自動處理,因此可以使用前面示例中所示的熟悉的高階 Transformers API 執行推理。
微調
使用 big_vision
PaliGemma 在 big_vision 程式碼庫中進行了訓練。該程式碼庫已用於開發 BiT、原始 ViT、LiT、CapPa、SigLIP 等眾多模型。
專案配置資料夾 configs/proj/paligemma/ 包含一個 `README.md` 檔案。預訓練模型可以透過執行 transfers/ 子資料夾中的配置檔案進行遷移,我們所有的遷移結果都是透過執行其中提供的配置獲得的。如果您想遷移自己的模型,請複製示例配置 transfers/forkme.py 並按照註釋中的說明進行修改以適應您的用例。
還有一個 Colab `finetune_paligemma.ipynb`,它運行了一個可以在免費 T4 GPU 執行時上執行的*簡化微調*。為了適應有限的主機和 GPU 記憶體,Colab 中的程式碼只更新注意力層(1.7 億引數)中的權重,並使用 SGD(而不是 Adam)。
使用 Transformers
PaliGemma 的微調非常容易,這得益於 Transformers。還可以進行 QLoRA 或 LoRA 微調。在此示例中,我們將簡要微調解碼器,然後展示如何切換到 QLoRA 微調。我們將安裝最新版本的 Transformers 庫。
pip install transformers
就像在推理部分一樣,我們將使用 `notebook_login()` 進行身份驗證以訪問模型。
from huggingface_hub import notebook_login
notebook_login()
在此示例中,我們將使用 VQAv2 資料集,並微調模型以回答有關影像的問題。讓我們載入資料集。我們只使用 question、multiple_choice_answer 和 image 列,因此我們也將刪除其餘列。我們還將拆分資料集。
from datasets import load_dataset
ds = load_dataset('HuggingFaceM4/VQAv2', split="train")
cols_remove = ["question_type", "answers", "answer_type", "image_id", "question_id"]
ds = ds.remove_columns(cols_remove)
ds = ds.train_test_split(test_size=0.1)
train_ds = ds["train"]
val_ds = ds["test"]
現在我們將載入包含影像處理和分詞部分的處理器,並預處理我們的資料集。
from transformers import PaliGemmaProcessor
model_id = "google/paligemma-3b-pt-224"
processor = PaliGemmaProcessor.from_pretrained(model_id)
我們將建立一個提示模板,以 PliGemma 條件化以回答視覺問題。由於分詞器會填充輸入,我們需要將標籤中的填充設定為分詞器中填充標記之外的其他內容,以及影像標記。
import torch
device = "cuda"
image_token = processor.tokenizer.convert_tokens_to_ids("<image>")
def collate_fn(examples):
texts = ["answer " + example["question"] for example in examples]
labels= [example['multiple_choice_answer'] for example in examples]
images = [example["image"].convert("RGB") for example in examples]
tokens = processor(text=texts, images=images, suffix=labels,
return_tensors="pt", padding="longest")
tokens = tokens.to(torch.bfloat16).to(device)
return tokens
您可以直接載入模型,也可以以 4 位載入模型用於 QLoRA。下面您可以看到如何直接載入模型。我們將載入模型,並凍結影像編碼器和投影器,僅微調解碼器。如果您的影像屬於特定領域,而該領域可能不在模型預訓練的資料集中,您可能希望跳過凍結影像編碼器。
model = PaliGemmaForConditionalGeneration.from_pretrained(model_id, torch_dtype=torch.bfloat16).to(device)
for param in model.vision_tower.parameters():
param.requires_grad = False
for param in model.multi_modal_projector.parameters():
param.requires_grad = True
如果您想以 4 位載入模型進行 QLoRA,可以新增以下更改。
from transformers import BitsAndBytesConfig
from peft import get_peft_model, LoraConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_type=torch.bfloat16
)
lora_config = LoraConfig(
r=8,
target_modules=["q_proj", "o_proj", "k_proj", "v_proj", "gate_proj", "up_proj", "down_proj"],
task_type="CAUSAL_LM",
)
model = PaliGemmaForConditionalGeneration.from_pretrained(model_id, quantization_config=bnb_config, device_map={"":0})
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
#trainable params: 11,298,816 || all params: 2,934,634,224 || trainable%: 0.38501616002417344
我們現在將初始化 Trainer 和 TrainingArguments。如果您將進行 QLoRA 微調,請將最佳化器設定為 `paged_adamw_8bit`。
from transformers import TrainingArguments
args=TrainingArguments(
num_train_epochs=2,
remove_unused_columns=False,
per_device_train_batch_size=16,
gradient_accumulation_steps=4,
warmup_steps=2,
learning_rate=2e-5,
weight_decay=1e-6,
adam_beta2=0.999,
logging_steps=100,
optim="adamw_hf",
save_strategy="steps",
save_steps=1000,
push_to_hub=True,
save_total_limit=1,
bf16=True,
report_to=["tensorboard"],
dataloader_pin_memory=False
)
初始化 `Trainer`,傳入資料集、資料整理函式和訓練引數,然後呼叫 `train()` 開始訓練。
trainer = Trainer(
model=model,
train_dataset=train_ds,
eval_dataset=val_ds,
data_collator=collate_fn,
args=args
)
trainer.train()
額外資源
- 視覺語言模型詳解
- 模型文件
- 推理筆記本
- Big vision PaliGemma 演示
- 🤗 Transformers PaliGemma 演示
- 所有 PaliGemma 模型的集合
- 所有 PaliGemma 微調模型的集合
- 原始實現
我們衷心感謝 Omar Sanseviero、Lucas Beyer、Xiaohua Zhai 和 Matthias Minderer 對本部落格文章的詳細審閱。我們感謝 Peter Robicheaux 在 Transformers 微調更改方面的幫助。