NLP實踐——VQA/Caption生成模型BLIP-2的應用介紹
- 1. 簡介
- 2. 模型下載下傳
- 3. 運作環境
- 4. 模型應用
1. 簡介
今天介紹一個跨模态模型,也是最近比較火的一個工作,叫做BLIP-2。很久很久之前我寫過一個簡單的image caption項目的介紹,那個模型原理比較簡單,就是encode-decode模式,但是項目卻不怎麼好運作,而現在,随着技術的疊代更新,還有huggingface社群的加持,想實作圖文生成變得友善了許多。
BLIP模型是一個對圖像部分和文字部分分别編碼,然後再深度互動的模型,對于模型的技術細節,本文不做過多的介紹,可以直接閱讀論文,總的來說沒有什麼難以了解的點。
利用這個模型,你可以一鍵生成對圖像的描述,或者詢問圖像中的資訊,與模型進行對話等。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNyZuBnL0IDMkJGNzIjMilTNmNGMiZDO2QTNlZmNkRWYzczY5Y2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
下面是項目和論文的位址。
項目位址:https://github.com/salesforce/LAVIS/tree/main/projects/blip2
論文位址:https://arxiv.org/abs/2301.12597
本文将介紹如何利用huggingface的transformers子產品,實作BLIP-2的調用。
2. 模型下載下傳
目前HF上開源出來的BLIP-2有好幾個模型,這裡選擇
Salesforce/blip2-opt-6.7b
作為例子進行介紹,我們進入該項目的位址:
https://huggingface.co/Salesforce/blip2-opt-6.7b/tree/main
把檔案清單裡的所有檔案全都下載下傳下來,放在一個目錄裡。因為檔案比較大,是以不建議直接聯網下載下傳到hf的預設緩存區,可以像我這樣下載下傳到自定義的位址,在加載模型的時候手動指定目錄即可。
如果你迫不及待地想要體驗一下線上版,可以直接進入space,直接線上操作:
https://huggingface.co/spaces/Salesforce/BLIP2
3. 運作環境
運作BLIP-2,需要最新版本的transformers子產品,截至目前,已經釋出的transformers的最高版本是4.26.1,我嘗試使用這個版本,發現仍然沒有BLIP2相關的模型,是以到git上找到開發中的版本4.27-dev。
截至目前(2023-02-16),進入git上官方transformers,你看到的transformers版本即為4.27的開發版,如果當你體驗這個項目的時候,正式版已經更新,就可以跳過這一步,直接通過pip安裝4.27及以上的版本:
如果安裝失敗了,說明它還沒有上線,那你需要手動安裝。
-
- 通過git clone或者download zip,下載下傳官方transformers,然後解壓它,并且激活你的使用的python環境,
-
- 直接執行python setup.py,即可完成安裝。
-
- 此時進入你相應地python環境,就可以成功地引用BLIP-2相關的子產品了。
4. 模型應用
首先import所需的子產品:
import torch
from PIL import Image
from transformers import Blip2Processor, Blip2ForConditionalGeneration
然後是模組化,除了模型之外,有一個processor,起到類似tokenizer的作用,既可以對文本進行tokenize,也可以将圖像劃分為patch:
# 其中這個路徑是上文中介紹的下載下傳的模型所存放的路徑
processor = Blip2Processor.from_pretrained("your_path_to/BLIP-2-opt/")
model = Blip2ForConditionalGeneration.from_pretrained("your_path_to/BLIP-2-opt/")
我們随便讀取一張圖檔,這裡我用了一張之前我自己用disco-diffusion生成的一張圖檔(原本準備給自己寫的小說做配圖的)。
對于image caption,我們隻需要對圖像進行操作,因為文本部分完全是由模型生成的:
# 注意,由于模型過大,我并沒有把它放到GPU上
# 是以相應地在生成inputs的時候,也不要放在GPU上或者使用16精度計算
inputs = processor(images=image, return_tensors="pt") # .to(device, torch.float16)
generated_ids = model.generate(**inputs)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0].strip()
print(generated_text)
# 'a rocky cliff with trees and water in the background'
可以看到生成的描述是比較貼切的。
然後來問它一個問題,比起caption,隻需要對prompt進行tokenize:
prompt = "Question: What tree is it in the picture? Answer:"
inputs = processor(images=image, text=prompt, return_tensors="pt") #.to(device, torch.float16)
# 注意這個時候的inputs.keys()包括了'pixel_values', 'input_ids', 'attention_mask'
inputs = processor(images=image, text=prompt, return_tensors="pt") #.to(device, torch.float16)
generated_ids = model.generate(**inputs)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0].strip()
print(generated_text)
# "It's a pine tree"
雖說它回答成了’a tree’,但是樹的類型應該是對了。
參考文檔:https://huggingface.co/docs/transformers/main/en/model_doc/blip-2#transformers.Blip2ForConditionalGeneration.forward.example
以上就是本文的全部内容了,如果你覺得還不錯,歡迎點個一鍵三連加關注,我們下期再見。