้กน็›ฎๆ–‡ไปถๅคน

ๆ–‡ไปถ
wehub-resource-sync e06fe8e8c6
Secret Leaks / trufflehog (push) Failing after 1s
Build documentation / build (push) Failing after 1s
Build documentation / build_other_lang (push) Failing after 0s
CodeQL Security Analysis / CodeQL Analysis (push) Failing after 0s
PR CI / pr-ci (push) Failing after 1s
Slow tests on important models (on Push - A10) / Get all modified files (push) Failing after 1s
Slow tests on important models (on Push - A10) / Model CI (push) Has been skipped
Self-hosted runner (benchmark) / Benchmark (aws-g5-4xlarge-cache) (push) Has been cancelled
New model PR merged notification / Notify new model (push) Has been cancelled
Update Transformers metadata / build_and_package (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 11:57:37 +08:00

11 KiB

SigLIPsiglip

PyTorch FlashAttention SDPA

๊ฐœ์š”overview

SigLIP ๋ชจ๋ธ์€ Xiaohua Zhai, Basil Mustafa, Alexander Kolesnikov, Lucas Beyer์˜ Sigmoid Loss for Language Image Pre-Training ๋…ผ๋ฌธ์—์„œ ์ œ์•ˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. SigLIP์€ CLIP์—์„œ ์‚ฌ์šฉ๋œ ์†์‹ค ํ•จ์ˆ˜๋ฅผ ๊ฐ„๋‹จํ•œ ์Œ๋ณ„ ์‹œ๊ทธ๋ชจ์ด๋“œ ์†์‹ค(pairwise sigmoid loss)๋กœ ๋Œ€์ฒดํ•  ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ImageNet์—์„œ ์ œ๋กœ์ƒท ๋ถ„๋ฅ˜ ์ •ํ™•๋„ ์ธก๋ฉด์—์„œ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ๋ณด์ž…๋‹ˆ๋‹ค.

๋…ผ๋ฌธ์˜ ์ดˆ๋ก์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

์šฐ๋ฆฌ๋Š” ์–ธ์–ด-์ด๋ฏธ์ง€ ์‚ฌ์ „ ํ•™์Šต(Language-Image Pre-training, SigLIP)์„ ์œ„ํ•œ ๊ฐ„๋‹จํ•œ ์Œ๋ณ„ ์‹œ๊ทธ๋ชจ์ด๋“œ ์†์‹ค์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์†Œํ”„ํŠธ๋งฅ์Šค ์ •๊ทœํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ‘œ์ค€ ๋Œ€์กฐ ํ•™์Šต๊ณผ ๋‹ฌ๋ฆฌ, ์‹œ๊ทธ๋ชจ์ด๋“œ ์†์‹ค์€ ์ด๋ฏธ์ง€-ํ…์ŠคํŠธ ์Œ์—๋งŒ ์ž‘์šฉํ•˜๋ฉฐ ์ •๊ทœํ™”๋ฅผ ์œ„ํ•ด ์Œ๋ณ„ ์œ ์‚ฌ์„ฑ์˜ ์ „์—ญ์  ๊ด€์ ์„ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹œ๊ทธ๋ชจ์ด๋“œ ์†์‹ค์€ ๋ฐฐ์น˜ ํฌ๊ธฐ๋ฅผ ๋”์šฑ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋™์‹œ์— ์ž‘์€ ๋ฐฐ์น˜ ํฌ๊ธฐ์—์„œ๋„ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ๋ณด์ž…๋‹ˆ๋‹ค. Locked-image Tuning๊ณผ ๊ฒฐํ•ฉํ•˜์—ฌ, ๋‹จ 4๊ฐœ์˜ TPUv4 ์นฉ๋งŒ์œผ๋กœ ์ดํ‹€ ๋งŒ์— 84.5%์˜ ImageNet ์ œ๋กœ์ƒท ์ •ํ™•๋„๋ฅผ ๋‹ฌ์„ฑํ•˜๋Š” SigLiT ๋ชจ๋ธ์„ ํ•™์Šตํ–ˆ์Šต๋‹ˆ๋‹ค. ์†์‹ค ํ•จ์ˆ˜์—์„œ ๋ฐฐ์น˜ ํฌ๊ธฐ๋ฅผ ๋ถ„๋ฆฌํ•จ์œผ๋กœ์จ ์˜ˆ์ œ ๋Œ€ ์Œ์˜ ์˜ํ–ฅ๊ณผ Negative ๋Œ€ Positive ๋น„์œจ์„ ์—ฐ๊ตฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ์šฐ๋ฆฌ๋Š” ๋ฐฐ์น˜ ํฌ๊ธฐ๋ฅผ 100๋งŒ ๊ฐœ๊นŒ์ง€ ๊ทน๋‹จ์ ์œผ๋กœ ๋Š˜๋ ค๋ณด์•˜๊ณ , ๋ฐฐ์น˜ ํฌ๊ธฐ ์ฆ๊ฐ€์˜ ์ด์ ์ด ๋น ๋ฅด๊ฒŒ ๊ฐ์†Œํ•˜๋ฉฐ 32k์˜ ๋” ํ•ฉ๋ฆฌ์ ์ธ ๋ฐฐ์น˜ ํฌ๊ธฐ๋กœ๋„ ์ถฉ๋ถ„ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ํŒusage-tips

  • SigLIP์˜ ์‚ฌ์šฉ๋ฒ•์€ CLIP๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์š” ์ฐจ์ด์ ์€ ํ•™์Šต ์†์‹ค ํ•จ์ˆ˜๋กœ, ๋ฐฐ์น˜ ๋‚ด ๋ชจ๋“  ์ด๋ฏธ์ง€์™€ ํ…์ŠคํŠธ ๊ฐ„์˜ ์Œ๋ณ„ ์œ ์‚ฌ์„ฑ์— ๋Œ€ํ•œ ์ „์—ญ์  ๊ด€์ ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์†Œํ”„ํŠธ๋งฅ์Šค ๋Œ€์‹  ๋กœ์ง“์— ์‹œ๊ทธ๋ชจ์ด๋“œ ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ํ•™์Šต์€ ์ง€์›๋˜์ง€๋งŒ torch.distributed ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„ ๋ฐฐ์น˜ ํฌ๊ธฐ์˜ ํ™•์žฅ์„ฑ์ด ์ œํ•œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹จ์ผ ๋…ธ๋“œ ๋‹ค์ค‘ GPU ์„ค์ •์—์„œ๋Š” DDP์™€ FDSP๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
  • ๋…๋ฆฝํ˜• [SiglipTokenizer] ๋˜๋Š” [SiglipProcessor]๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋ชจ๋ธ์ด ๊ทธ๋ ‡๊ฒŒ ํ•™์Šต๋˜์—ˆ์œผ๋ฏ€๋กœ padding="max_length"๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ํŒŒ์ดํ”„๋ผ์ธ๊ณผ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋ฉด "This is a photo of {label}."์˜ ํ”„๋กฌํ”„ํŠธ ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

drawing

CLIP๊ณผ ๋น„๊ตํ•œ SigLIP ํ‰๊ฐ€ ๊ฒฐ๊ณผ. ์›๋ณธ ๋…ผ๋ฌธ์—์„œ ๋ฐœ์ทŒ.

์ด ๋ชจ๋ธ์€ nielsr๊ฐ€ ๊ธฐ์—ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์›๋ณธ ์ฝ”๋“œ๋Š” ์—ฌ๊ธฐ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์˜ˆ์‹œusage-example

SigLIP์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค: ๋ชจ๋“  ๋ณต์žก์„ฑ์„ ์ถ”์ƒํ™”ํ•˜๋Š” ํŒŒ์ดํ”„๋ผ์ธ API๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ์ง์ ‘ SiglipModel ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„๋ผ์ธ APIpipeline-API

ํŒŒ์ดํ”„๋ผ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋กœ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

>>> from transformers import pipeline
>>> from PIL import Image
>>> import requests

>>> # ํŒŒ์ดํ”„๋ผ์ธ ๋กœ๋“œ
>>> image_classifier = pipeline(task="zero-shot-image-classification", model="google/siglip-base-patch16-224")

>>> # ์ด๋ฏธ์ง€ ๋กœ๋“œ
>>> url = 'http://images.cocodataset.org/val2017/000000039769.jpg'
>>> image = Image.open(requests.get(url, stream=True).raw)

>>> # ์ถ”๋ก 
>>> candidate_labels = ["2 cats", "a plane", "a remote"]
>>> outputs = image_classifier(image, candidate_labels=candidate_labels)
>>> outputs = [{"score": round(output["score"], 4), "label": output["label"] } for output in outputs]
>>> print(outputs)
[{'score': 0.1979, 'label': '2 cats'}, {'score': 0.0, 'label': 'a remote'}, {'score': 0.0, 'label': 'a plane'}]

์ง์ ‘ ๋ชจ๋ธ ์‚ฌ์šฉํ•˜๊ธฐusing-the-model-yourself

์ „์ฒ˜๋ฆฌ์™€ ํ›„์ฒ˜๋ฆฌ๋ฅผ ์ง์ ‘ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:

>>> from PIL import Image
>>> import requests
>>> from transformers import AutoProcessor, AutoModel
>>> import torch

>>> model = AutoModel.from_pretrained("google/siglip-base-patch16-224")
>>> processor = AutoProcessor.from_pretrained("google/siglip-base-patch16-224")

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> image = Image.open(requests.get(url, stream=True).raw)

>>> candidate_labels = ["2 cats", "2 dogs"]
# ํŒŒ์ดํ”„๋ผ์ธ ํ”„๋กฌํ”„ํŠธ ํ…œํ”Œ๋ฆฟ์„ ๋”ฐ๋ผ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค
>>> texts = [f'This is a photo of {label}.' for label in candidate_labels]
# ์ค‘์š”: ๋ชจ๋ธ์ด ์ด๋ ‡๊ฒŒ ํ•™์Šต๋˜์—ˆ์œผ๋ฏ€๋กœ `padding=max_length`๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค
>>> inputs = processor(text=texts, images=image, padding="max_length", return_tensors="pt")

>>> with torch.no_grad():
...     outputs = model(**inputs)

>>> logits_per_image = outputs.logits_per_image
>>> probs = torch.sigmoid(logits_per_image) # ์‹œ๊ทธ๋ชจ์ด๋“œ ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•œ ํ™•๋ฅ ์ž…๋‹ˆ๋‹ค
>>> print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'")
19.8% that image 0 is '2 cats'

๋ฆฌ์†Œ์Šคresources

SigLIP์„ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๊ณต์‹ Hugging Face ๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ(๐ŸŒŽ๋กœ ํ‘œ์‹œ) ๋ฆฌ์†Œ์Šค ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ํฌํ•จ๋  ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ์ถœํ•˜๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์žˆ์œผ์‹œ๋ฉด Pull Request๋ฅผ ์—ด์–ด์ฃผ์‹œ๋ฉด ๊ฒ€ํ† ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! ๋ฆฌ์†Œ์Šค๋Š” ์ด์ƒ์ ์œผ๋กœ ๊ธฐ์กด ๋ฆฌ์†Œ์Šค๋ฅผ ๋ณต์ œํ•˜๋Š” ๋Œ€์‹  ์ƒˆ๋กœ์šด ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

SigLIP๊ณผ Flash Attention 2 ๊ฒฐํ•ฉํ•˜๊ธฐcombining-siglip-with-flash-attention-2

๋จผ์ € Flash Attention 2์˜ ์ตœ์‹  ๋ฒ„์ „์„ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

pip install -U flash-attn --no-build-isolation

๋˜ํ•œ Flash-Attention 2์™€ ํ˜ธํ™˜๋˜๋Š” ํ•˜๋“œ์›จ์–ด๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. flash-attn ์ €์žฅ์†Œ์˜ ๊ณต์‹ ๋ฌธ์„œ์—์„œ ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”. ๋˜ํ•œ ๋ชจ๋ธ์„ ๋ฐ˜์ •๋ฐ€๋„(์˜ˆ: torch.float16)๋กœ ๋กœ๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Flash Attention 2๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋ธ์„ ๋กœ๋“œํ•˜๊ณ  ์‹คํ–‰ํ•˜๋ ค๋ฉด ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”:

>>> import torch
>>> import requests
>>> from PIL import Image
>>> from transformers import SiglipProcessor, SiglipModel
>>> device = "cuda" # ๋ชจ๋ธ์„ ๋กœ๋“œํ•  ์žฅ์น˜

>>> model = SiglipModel.from_pretrained(
...     "google/siglip-so400m-patch14-384",
...     attn_implementation="flash_attention_2",
...     dtype=torch.float16,
...     device_map=device,
... )
>>> processor = SiglipProcessor.from_pretrained("google/siglip-so400m-patch14-384")

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> image = Image.open(requests.get(url, stream=True).raw)

>>> candidate_labels = ["2 cats", "2 dogs"]
# ํŒŒ์ดํ”„๋ผ์ธ ํ”„๋กฌํ”„ํŠธ ํ…œํ”Œ๋ฆฟ์„ ๋”ฐ๋ผ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค
>>> texts = [f'This is a photo of {label}.' for label in candidate_labels]
# ์ค‘์š”: ๋ชจ๋ธ์ด ์ด๋ ‡๊ฒŒ ํ•™์Šต๋˜์—ˆ์œผ๋ฏ€๋กœ `padding=max_length`๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค
>>> inputs = processor(text=texts, images=image, padding="max_length", return_tensors="pt").to(device)

>>> with torch.no_grad():
...     with torch.autocast(device):
...         outputs = model(**inputs)

>>> logits_per_image = outputs.logits_per_image
>>> probs = torch.sigmoid(logits_per_image) # ์‹œ๊ทธ๋ชจ์ด๋“œ ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•œ ํ™•๋ฅ ์ž…๋‹ˆ๋‹ค
>>> print(f"{probs[0][0]:.1%} that image 0 is '{candidate_labels[0]}'")
19.8% that image 0 is '2 cats'

Scaled Dot Product Attention(SDPA) ์‚ฌ์šฉํ•˜๊ธฐ[using-scaled-dot-product-attention(SDPA)]]

PyTorch๋Š” torch.nn.functional์˜ ์ผ๋ถ€๋กœ ์Šค์ผ€์ผ๋œ ์ ๊ณฑ ์–ดํ…์…˜(SDPA) ์—ฐ์‚ฐ์ž๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์ž…๋ ฅ๊ณผ ์‚ฌ์šฉ ์ค‘์ธ ํ•˜๋“œ์›จ์–ด์— ๋”ฐ๋ผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ๋Ÿฌ ๊ตฌํ˜„์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹ ๋ฌธ์„œ ๋˜๋Š” GPU ์ถ”๋ก  ํŽ˜์ด์ง€๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

from_pretrained()์—์„œ attn_implementation="sdpa"๋ฅผ ์„ค์ •ํ•˜์—ฌ SDPA๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. torch>=2.1.1์ด ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

>>> from transformers import SiglipModel

>>> model = SiglipModel.from_pretrained(
...     "google/siglip-so400m-patch14-384",
...     attn_implementation="sdpa",
...     dtype=torch.float16,
...     device_map=device,
... )

์ตœ์ƒ์˜ ์†๋„ ํ–ฅ์ƒ์„ ์œ„ํ•ด ๋ชจ๋ธ์„ ๋ฐ˜์ •๋ฐ€๋„(์˜ˆ: torch.float16 ๋˜๋Š” torch.bfloat16)๋กœ ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์˜ˆ์ƒ ์†๋„ ํ–ฅ์ƒexpected-speedups

์•„๋ž˜๋Š” google/siglip-so400m-patch14-384 ์ฒดํฌํฌ์ธํŠธ๋ฅผ float16 ์ •๋ฐ€๋„๋กœ ์‚ฌ์šฉํ•˜๋Š” transformers์˜ ๋„ค์ดํ‹ฐ๋ธŒ ๊ตฌํ˜„๊ณผ Flash Attention 2 / SDPA ๋ฒ„์ „์˜ ๋ชจ๋ธ์„ ๋‹ค์–‘ํ•œ ๋ฐฐ์น˜ ํฌ๊ธฐ๋กœ ๋น„๊ตํ•œ ์ถ”๋ก  ์‹œ๊ฐ„์˜ ์˜ˆ์ƒ ์†๋„ ํ–ฅ์ƒ ๋‹ค์ด์–ด๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.

SiglipConfig

autodoc SiglipConfig

SiglipTextConfig

autodoc SiglipTextConfig

SiglipVisionConfig

autodoc SiglipVisionConfig

SiglipTokenizer

autodoc SiglipTokenizer - build_inputs_with_special_tokens - get_special_tokens_mask - create_token_type_ids_from_sequences - save_vocabulary

SiglipImageProcessor

autodoc SiglipImageProcessor - preprocess

SiglipImageProcessorFast

autodoc SiglipImageProcessorFast - preprocess

SiglipProcessor

autodoc SiglipProcessor

SiglipModel

autodoc SiglipModel - forward - get_text_features - get_image_features

SiglipTextModel

autodoc SiglipTextModel - forward

SiglipVisionModel

autodoc SiglipVisionModel - forward

SiglipForImageClassification

autodoc SiglipForImageClassification - forward