使用 BLIP-2 進行零樣本影像到文字生成

釋出於 2023 年 2 月 15 日
在 GitHub 上更新

本指南介紹 Salesforce Research 的 BLIP-2,它實現了一套最先進的視覺-語言模型,現已在 🤗 Transformers 中可用。我們將向您展示如何將其用於影像描述、帶提示的影像描述、視覺問答和基於聊天的提示。

目錄

  1. 引言
  2. BLIP-2 內部機制解析
  3. 使用 Hugging Face Transformers 執行 BLIP-2
    1. 影像字幕
    2. 帶提示的影像描述
    3. 視覺問答
    4. 基於聊天的提示
  4. 結論
  5. 致謝

引言

近年來,計算機視覺和自然語言處理領域取得了快速發展。然而,許多現實世界問題本質上是多模態的——它們涉及多種不同形式的資料,例如影像和文字。視覺-語言模型面臨著結合模態的挑戰,以便它們能夠為廣泛的應用開啟大門。視覺語言模型可以解決的一些影像到文字任務包括影像描述、影像-文字檢索和視覺問答。影像描述可以幫助視障人士,建立有用的產品描述,識別文字之外的不當內容等。影像-文字檢索可以應用於多模態搜尋,以及自動駕駛等應用。視覺問答可以幫助教育,實現多模態聊天機器人,並協助各種領域特定的資訊檢索應用。

現代計算機視覺和自然語言模型的能力更強;然而,與它們的先輩相比,它們的規模也顯著增加。雖然預訓練單一模態模型耗費資源且成本高昂,但端到端視覺和語言預訓練的成本變得越來越高。 BLIP-2 透過引入一種新的視覺-語言預訓練正規化來解決這一挑戰,該正規化可以潛在地利用預訓練視覺編碼器和 LLM 的任何組合,而無需端到端預訓練整個架構。這使得在多個視覺-語言任務上獲得最先進的結果,同時顯著減少了可訓練引數的數量和預訓練成本。此外,這種方法為多模態 ChatGPT 類模型鋪平了道路。

BLIP-2 內部機制解析

BLIP-2 透過在現成的凍結預訓練影像編碼器和凍結大型語言模型之間新增一個輕量級查詢 Transformer(Q-Former),彌合了視覺和語言模型之間的模態差距。Q-Former 是 BLIP-2 中唯一可訓練的部分;影像編碼器和語言模型都保持凍結。

Overview of BLIP-2's framework

Q-Former 是一個 Transformer 模型,由兩個共享相同自注意力層的子模組組成

  • 一個影像 Transformer,與凍結的影像編碼器互動以進行視覺特徵提取
  • 一個文字 Transformer,可以兼作文字編碼器和文字解碼器

Q-Former architecture

影像 Transformer 從影像編碼器中提取固定數量的輸出特徵,與輸入影像解析度無關,並接收可學習的查詢嵌入作為輸入。查詢還可以透過相同的自注意力層與文字互動。

Q-Former 分兩個階段進行預訓練。在第一階段,影像編碼器被凍結,Q-Former 透過三個損失進行訓練

  • 影像-文字對比損失:計算每個查詢輸出和文字輸出的 CLS 標記之間的成對相似度,並選擇最高的一個。查詢嵌入和文字彼此“不可見”。
  • 影像-基礎文字生成:查詢可以相互關注,但不能關注文字標記,並且文字具有因果掩碼,可以關注所有查詢。
  • 影像-文字匹配損失:查詢和文字可以相互可見,並獲得一個邏輯值以指示文字是否與影像匹配。為了獲得負樣本,使用了硬負取樣。

在第二個預訓練階段,查詢嵌入現在具有與文字相關的視覺資訊,因為它已透過資訊瓶頸。這些嵌入現在用作 LLM 輸入的視覺字首。此預訓練階段有效地涉及使用因果 LM 損失的影像-基礎文字生成任務。

作為視覺編碼器,BLIP-2 使用 ViT,而對於 LLM,論文作者使用了 OPT 和 Flan T5 模型。您可以在 Hugging Face Hub 上找到 OPT 和 Flan T5 的預訓練檢查點。然而,如前所述,所引入的預訓練方法允許將任何視覺骨幹與任何 LLM 結合使用。

使用 Hugging Face Transformers 執行 BLIP-2

使用 Hugging Face Transformers,您可以輕鬆下載並在您的影像上執行預訓練的 BLIP-2 模型。如果您想跟隨本部落格文章中的示例,請確保使用具有高 RAM 的 GPU 環境。

讓我們從安裝 Transformers 開始。由於該模型最近才新增到 Transformers 中,我們需要從原始碼安裝 Transformers

pip install git+https://github.com/huggingface/transformers.git

接下來,我們需要一張輸入影像。每週《紐約客》都會在其讀者中舉辦一次漫畫配文比賽,所以讓我們拿其中一張漫畫來測試 BLIP-2。

import requests
from PIL import Image

url = 'https://media.newyorker.com/cartoons/63dc6847be24a6a76d90eb99/master/w_1160,c_limit/230213_a26611_838.jpg'
image = Image.open(requests.get(url, stream=True).raw).convert('RGB')  
display(image.resize((596, 437)))

New Yorker Cartoon

我們有一張輸入影像。現在我們需要一個預訓練的 BLIP-2 模型和相應的預處理器來準備輸入。您可以在 Hugging Face Hub 上找到所有可用預訓練檢查點的列表。在這裡,我們將載入一個利用 Meta AI 的預訓練 OPT 模型(具有 27 億引數)的 BLIP-2 檢查點。

from transformers import AutoProcessor, Blip2ForConditionalGeneration
import torch

processor = AutoProcessor.from_pretrained("Salesforce/blip2-opt-2.7b")
model = Blip2ForConditionalGeneration.from_pretrained("Salesforce/blip2-opt-2.7b", torch_dtype=torch.float16)

請注意,BLIP-2 是一種罕見的情況,您不能使用 Auto API(例如 AutoModelForXXX)載入模型,需要顯式使用 Blip2ForConditionalGeneration。但是,您可以使用 AutoProcessor 來獲取適當的處理器類——在這種情況下是 Blip2Processor

讓我們使用 GPU 來加快文字生成速度

device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)

影像描述

讓我們看看 BLIP-2 是否能以零樣本方式描述一幅《紐約客》漫畫。要描述影像,我們不必向模型提供任何文字提示,只需提供預處理的輸入影像。在沒有任何文字提示的情況下,模型將從 BOS(序列開始)標記開始生成文字,從而建立描述。

inputs = processor(image, return_tensors="pt").to(device, torch.float16)

generated_ids = model.generate(**inputs, max_new_tokens=20)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0].strip()
print(generated_text)
"two cartoon monsters sitting around a campfire"

對於一個未在《紐約客》風格漫畫上訓練過的模型來說,這是一個令人印象深刻的準確描述!

帶提示的影像描述

我們可以透過提供文字提示來擴充套件影像描述,模型將根據影像繼續生成。

prompt = "this is a cartoon of"

inputs = processor(image, text=prompt, return_tensors="pt").to(device, torch.float16)

generated_ids = model.generate(**inputs, max_new_tokens=20)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0].strip()
print(generated_text)
"two monsters sitting around a campfire"
prompt = "they look like they are"

inputs = processor(image, text=prompt, return_tensors="pt").to(device, torch.float16)

generated_ids = model.generate(**inputs, max_new_tokens=20)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0].strip()
print(generated_text)
"having a good time"

視覺問答

對於視覺問答,提示必須遵循特定格式:“Question: {} Answer:”

prompt = "Question: What is a dinosaur holding? Answer:"

inputs = processor(image, text=prompt, return_tensors="pt").to(device, torch.float16)

generated_ids = model.generate(**inputs, max_new_tokens=10)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0].strip()
print(generated_text)
"A torch"

基於聊天的提示

最後,我們可以透過將每個生成的響應連線到對話中來建立類似 ChatGPT 的介面。我們用一些文字(例如“恐龍拿著什麼?”)提示模型,模型會生成一個答案(“火把”),我們可以將其連線到對話中。然後我們再次這樣做,建立上下文。但是,請確保上下文不超過 512 個標記,因為這是 BLIP-2(OPT 和 T5)使用的語言模型的上下文長度。

context = [
   ("What is a dinosaur holding?", "a torch"),
   ("Where are they?", "In the woods.")
]
question = "What for?"
template = "Question: {} Answer: {}."

prompt = " ".join([template.format(context[i][0], context[i][1]) for i in range(len(context))]) + " Question: " + question + " Answer:"

print(prompt)
Question: What is a dinosaur holding? Answer: a torch. Question: Where are they? Answer: In the woods.. Question: What for? Answer:
inputs = processor(image, text=prompt, return_tensors="pt").to(device, torch.float16)

generated_ids = model.generate(**inputs, max_new_tokens=10)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0].strip()
print(generated_text)
To light a fire.

結論

BLIP-2 是一種零樣本視覺-語言模型,可用於多種影像到文字任務,支援影像和影像與文字提示。這是一種有效且高效的方法,可應用於多種場景下的影像理解,尤其是在示例稀缺時。

該模型透過在預訓練模型之間新增一個 Transformer,彌合了視覺和自然語言模態之間的鴻溝。這種新的預訓練正規化使該模型能夠跟上兩種獨立模態的進步。

如果您想了解如何為各種視覺-語言任務微調 BLIP-2 模型,請檢視Salesforce 的 LAVIS 庫,它為模型訓練提供了全面的支援。

要檢視 BLIP-2 的實際應用,請在Hugging Face Spaces 上試用其演示。

致謝

非常感謝 Salesforce Research 團隊在 BLIP-2 上的工作,Niels Rogge 將 BLIP-2 新增到 🤗 Transformers 中,以及 Omar Sanseviero 審閱了這篇部落格文章。

社群

註冊登入 發表評論

© . This site is unofficial and not affiliated with Hugging Face, Inc.