SigLIP 2:一種更優秀的全球化視覺語言編碼器

釋出日期:2025年2月21日
在 GitHub 上更新

TL;DR

今天,谷歌釋出了一個新的、更優秀的**多語言**視覺語言編碼器系列:SigLIP 2。作者在SigLIP(*sigmoid損失*)的訓練目標基礎上,增加了額外的目標,以提高語義理解、定位和密集特徵。

Objectives added
附加目標(來源:https://huggingface.co/papers/2502.14786

SigLIP 2模型在所有模型規模的核心能力上都**優於**舊的SigLIP模型,包括零樣本分類、影像-文字檢索,以及在為視覺語言模型(VLM)提取視覺表示時的遷移效能。

更棒的是動態解析度(`naflex`)變體。這對於對長寬比和解析度敏感的下游任務很有用。

以下是已釋出的所有模型列表

引言

視覺編碼器很簡單——它們接收一張影像,將其編碼成一種表示,然後這種表示被用於分類、目標檢測、影像分割以及更多視覺任務。研究人員一直在追求**密集**、**區域性感知**和**語義豐富**的視覺表示。

CLIPALIGN是影像編碼器和文字編碼器透過聯合訓練對齊的最初例子。這種方法開闢了訓練視覺模型的新途徑。SigLIP更進一步,用*sigmoid損失*取代了CLIP的*對比損失*,以獲得更好的編碼器。

從中得到的啟示是?透過更智慧的訓練目標,我們不斷構建出更結構化、更細粒度、更強大的視覺編碼器。SigLIP 2正是如此,它在SigLIP的訓練目標基礎上,應用了一系列非常有趣和智慧的訓練目標,以提供更好、更強的視覺語言編碼器。

我們將在本部落格文章中嘗試一些新的東西。我們不直接說明什麼是新的以及在哪裡可以找到它,而是將一起進行一個小練習。我們從SigLIP開始,然後集思廣益一系列問題(以🤔開頭)和答案(新的標題),逐步涵蓋SigLIP 2中的所有更新。聽起來不錯嗎?

我們將從補丁大小為**16**,影像解析度為**256**的視覺編碼器開始我們的旅程。我們有四種變體可以開始我們的訓練

  1. siglip2-base-patch16-256
  2. siglip2-large-patch16-256
  3. siglip2-so400m-patch16-256
  4. siglip2-giant-opt-patch16-256

🤔 問題1:我們可以使用什麼(低成本)輔助訓練目標來學習更好的視覺表示(在位置感知和區域性感知方面)?

新增一個解碼器(就是這麼簡單)

讓我們加入一個解碼器。現在我們有一個影像編碼器、一個文字編碼器和一個*文字解碼器*。文字解碼器將有三個目標:

  1. 預測整體影像標題
  2. 根據描述*特定*影像區域的標題預測邊界框座標
  3. 根據邊界框座標預測區域特定標題

解碼器為視覺編碼器提供了額外的訊號,使其具有位置感知能力。這標誌著SigLIP 2訓練配方的首次改進。

🤔 問題2:我們如何改進影像表示的細粒度區域性語義?

帶有全域性-區域性損失和掩碼預測的自蒸餾

為了提高影像表示的細粒度區域性語義,我們引入了兩個關鍵的訓練目標:全域性-區域性損失和掩碼預測損失。借鑑自監督學習文獻的啟發,我們使用*自蒸餾*。我們可以將一個模型用作教師模型,同時又將其用作學生模型。每次迭代時,教師模型的引數將是學生模型引數的移動平均。

  1. **全域性-區域性損失**:學生網路獲得訓練影像的部分(區域性)檢視,並被訓練以匹配教師模型從完整影像中派生出的表示。
  2. **掩碼預測損失**:學生網路中嵌入影像補丁的50%被掩碼標記遮蔽。學生需要匹配教師模型在掩碼位置的特徵。

這些目標使視覺編碼器具備空間感知能力並改善其區域性語義。作者僅在完成sigmoid和解碼器損失訓練的**80%**後才新增此損失。這樣做是為了節省計算(額外的損失相當昂貴)並且避免對編碼器產生負面影響。

🤔 問題3:如何讓模型適應不同的解析度?

適應不同解析度

眾所周知,影像模型對不同的解析度和長寬比非常敏感。這裡我們可以利用兩種不同的方法來使這些模型適應不同的解析度和補丁大小。

  1. **固定解析度變體**:從95%的訓練檢查點開始,我們可以調整位置嵌入和補丁嵌入的大小,然後繼續訓練請求的(可能更大)解析度。
  2. **動態解析度變體**:借鑑FlexiViT使用不同序列長度輸入和NaViT遵循原始長寬比的啟發,我們可以建立**NaFlex**變體。這很有趣,因為我們可以使用一個模型進行OCR(很少有長寬比失真)和文件理解(適當的解析度)。

帶有`-naflex`字尾的模型是動態解析度變體。雖然固定解析度模型可以直接使用現有的`SiglipModel`類,但您需要使用`Siglip2Model`才能使用`naflex`變體。當您使用管道API時,我們會自動處理這個問題!

至此,我們完成了從 SigLIP 到 SigLIP 2 的演進。在接下來的部分,我們將探討 SigLIP 2 的應用。

使用transformers執行推理

在模型上執行推理非常簡單。您可以複製下面的程式碼,並在免費的Colab notebook上執行推理🚀

要對 SigLIP 2 執行推理,請從 `main` 或從這個穩定分支安裝 `transformers`:`pip install git+https://github.com/huggingface/transformers@v4.49.0-SigLIP-2`

零樣本分類

在這裡,我們使用方便的`pipeline` API 來展示 SigLIP 2 的零樣本分類能力。

from transformers import pipeline

ckpt = "google/siglip2-so400m-patch14-384"
pipe = pipeline(model=ckpt, task="zero-shot-image-classification")

inputs = {
    "images": [
        "https://huggingface.co/datasets/merve/coco/resolve/main/val2017/000000000285.jpg", # bear
        "https://huggingface.co/datasets/merve/coco/resolve/main/val2017/000000000776.jpg", # teddy bear
    ],
    "texts": [
        "bear looking into the camera",
        "bear looking away from the camera",
        "a bunch of teddy bears",
        "two teddy bears",
        "three teddy bears"
    ],
}

outputs = pipe(inputs["images"], candidate_labels=inputs["texts"])

讓我們視覺化輸出。

output of zero shot classification
視覺化零樣本分類分數

為下游任務編碼影像

您也可以使用以下方法編碼影像:

import torch
from transformers import AutoModel, AutoProcessor
from transformers.image_utils import load_image

ckpt = "google/siglip2-so400m-patch14-384"
model = AutoModel.from_pretrained(ckpt, device_map="auto").eval()
processor = AutoProcessor.from_pretrained(ckpt)

image = load_image("https://huggingface.co/datasets/merve/coco/resolve/main/val2017/000000000285.jpg")
inputs = processor(images=[image], return_tensors="pt").to(model.device)

with torch.no_grad():
    image_embeddings = model.get_image_features(**inputs)    

print(image_embeddings.shape) # torch.Size([1, 1152])

SigLIP 1與SigLIP 2的比較

檢視所有已釋出的 SigLIP 2 模型表格,我們看到與 SigLIP 相比有兩個明顯的改變:

  1. SigLIP 2 引入了新的動態解析度變體 (`naflex`)。
  2. SigLIP 2 新增了 `giant` (1B) 系列模型。

SigLIP 2 的評估表證明瞭其優於 SigLIP 的效能。

evaluation table
SigLIP 2 的評估分數(來源:https://huggingface.co/papers/2502.14786

這裡有一個演示,可以比較 SigLIP 1 和 SigLIP 2 的零樣本分類結果。

將編碼器用於VLM

與文字資訊對齊的視覺編碼器在**視覺語言模型** (VLM) 的開發中變得越來越重要。構建 VLM 的常見方法是將預訓練的視覺編碼器與預訓練的 LLM 結合起來,並使用多模態資料在各種視覺語言任務中共同訓練它們。

一個利用 SigLIP 視覺編碼器系列的傑出 VLM 例子是 **PaliGemma**。您可以在這篇PaliGemma部落格文章中深入瞭解 PaliGemma 的功能。在此基礎上,最近推出的PaliGemma 2透過將 SigLIP 與先進的 Gemma 2 LLM 整合,更進一步。在一個類似 PaliGemma 的環境中,將 SigLIP 替換為 SigLIP 2,並觀察該模型的表現,將非常令人興奮。

致謝

我們衷心感謝Michael Tschannen(SigLIP 2的第一作者)、Vaibhav SrivastavSayak Paul對本部落格文章的反饋。同時,也要向Google團隊致以崇高的敬意,感謝他們釋出了這一卓越且開源的模型系列。

我們特別要感謝PavelRossPabloPedroLysandre以及Hugging Face團隊的其他成員,感謝他們對該專案的巨大支援和貢獻。

社群

可能需要檢查一下:底部演示一直停留在“Uploading 1 file...”狀態,預設示例均無法載入或執行。丟擲6個不同的Javascript控制檯錯誤。(Chrome, Mac)。

·

是的,我也看到了

感謝部落格。

Siglip2 不包含像 Siglip 那樣的“spiece.model”。這是預期的嗎?處理器報錯,指出 vocab 檔案是 NoneType 物件,這可能表明缺少 spiece 模型。有什麼想法嗎?

transformers.version : 4.49.0

·
文章作者

你能從main分支安裝`transformers`嗎?

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

如果這解決了問題,請告訴我們。🤗

我嘗試執行零樣本分類示例,結果出現`ValueError: Unable to create tensor, you should probably activate truncation and/or padding with 'padding=True' 'truncation=True' to have batched tensors with the same length. Perhaps your features (`input_ids` in this case) have excessive nesting (inputs type `list` where type `int` is expected).` transformers 版本=4.49.0.dev0

我嘗試新增`padding=True`和`truncation=True`,但都無濟於事。我還嘗試了`padding="max_length"`

編輯
如果我的標籤長度都相同,它似乎可以工作。在除錯時,我看到在`zero_shot_image_classification.py`中,提供給tokenizer的padding在這裡(L148-149)無論如何都會被強制為`max_length`

padding = "max_length" if self.model.config.model_type == "siglip" else True
text_inputs = self.tokenizer(sequences, return_tensors=self.framework, padding=padding, **tokenizer_kwargs)

然而,如果我的標籤長度可變,輸出的長度就不同,因此最終導致torch.tensor呼叫失敗
我也在我的終端中發現了這個警告
要求填充到max_length,但未提供最大長度,且模型沒有預定義的最大長度。預設不填充。

·

警告告訴你答案:傳入 max_length=64

“使用獨立的 GemmaTokenizerFast 時,請務必傳入 padding="max_length" 和 max_length=64,因為模型就是這樣訓練的。”Siglip2 是否支援更長的文字輸入?如果 max_length 設定為 256 或 512,超過 64 的文字會被截斷嗎?

·

是的。如果你想要更長的文字,我的做法是將其分成64個token的塊(可能甚至重疊),分別嵌入這些塊,然後平均它們的結尾或分別與影像嵌入點積,並根據你的用例取最大值或平均分數。

我其實很好奇你正在處理的查詢型別會超過64個token嗎?我能想到的所有siglip用例幾乎都遠低於64個。

我收到以下錯誤:

/lib/python3.10/site-packages/transformers/models/siglip/tokenization_siglip.py", line 139, in get_spm_processor
with open(self.vocab_file, "rb") as f
TypeError: expected str, bytes or os.PathLike object, not NoneType

·
文章作者

你能從主分支安裝 transformers 嗎?

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

如果這解決了問題,請告訴我們。🤗

實際上有3只貓,其中一隻懷孕了

有人知道在哪裡可以找到naflex變體的基準測試嗎?我可能瞎了,但圖表中似乎沒有它們?
編輯:沒事了,去附錄找吧

跨模態相似度

當我向模型輸入影像和文字時

def get_output(url, text):
    text = "a photo of 2 cats"
    url = "http://images.cocodataset.org/val2017/000000039769.jpg"
    image = load_image(url)
    inputs = processor(text=[text], images=image, padding="max_length", return_tensors="pt").to(model.device)
    with torch.no_grad():
        output = model(**inputs)
    return output

輸出的logits是
SiglipOutput(loss=None, logits_per_image=tensor([[-15.5217]], device='cuda:0'), logits_per_text=tensor([[-15.5217]], device='cuda:0')

sigmoid後輸出接近於0。

我該如何解決?

·

我也遇到了這個問題。

是否有提供在自定義資料集上進行微調的示例?

·
文章作者

@nielsr 有一個關於微調siglip和類似模型的出色筆記本。

https://github.com/NielsRogge/Transformers-Tutorials/tree/master/SigLIP

註冊登入以評論

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