CLIP과 대조 학습 기반 비전-언어 사전학습(CLIP and Contrastive Vision-Language Pretraining)
OpenAI의 CLIP(2021)은 이후 5년을 밀어 올릴 만큼 큰 아이디어 하나를 증명했습니다. 노이즈가 섞인 웹 이미지-캡션 쌍(noisy web image-caption pairs)과 대조 손실(contrastive loss)만으로 이미지 인코더(image encoder)와 텍스트 인코더(text encoder)를 같은 벡터 공간(vector space)에 정렬(align)하는 방식입니다. 지도(supervised) 라벨은 0개, 쌍(pairs)은 4억 개입니다. 그 결과로 얻은 임베딩 공간(embedding space)은 제로샷 분류(zero-shot classification)와 이미지-텍스트 검색(image-text retrieval)을 수행하고, 2026년의 모든 비전-언어 모델(Vision-Language Model; VLM)에서 비전 타워(vision tower)로 꽂혀 들어갑니다. SigLIP 2(2025)는 소프트맥스(softmax)를 시그모이드(sigmoid)로 바꾸어 더 낮은 비용으로 CLIP을 넘어 확장(scale)했습니다. 이 강의에서는 InfoNCE에서 시그모이드 쌍별 손실(sigmoid pairwise loss)까지 수학을 따라가고, 표준 라이브러리(stdlib) Python으로 학습 단계(training step)를 구현합니다.
유형: Build
언어: Python (stdlib, InfoNCE + sigmoid loss 구현)
선수 지식: Phase 12 · 01 (ViT 패치), Phase 7 (Transformer)
예상 시간: 약 180분
학습 목표
- 상호정보량(mutual information)에서 InfoNCE 손실을 유도하고, 수치적으로 안정적인 벡터화 버전(numerically-stable vectorized version)을 구현합니다.
- 시그모이드 쌍별 손실(SigLIP)이 소프트맥스가 요구하는 전체 모음(all-gather) 통신 비용 없이 배치(batch) 32768 이상으로 확장되는 이유를 설명합니다.
- 텍스트 템플릿(
a photo of a {class})을 만들고 코사인 유사도(cosine similarity)에 대해 argmax를 취해 ImageNet 제로샷 분류를 실행합니다.
- CLIP과 SigLIP 사전학습이 제공하는 네 가지 조절 지점을 말합니다. 배치 크기(batch size), 온도(temperature), 프롬프트 템플릿(prompt template), 데이터 품질(data quality)입니다.
문제
CLIP 이전의 비전은 지도학습이었습니다. 라벨이 붙은 데이터셋을 모으고(ImageNet은 120만 장의 이미지와 1000개의 클래스로 구성됩니다), 합성곱 신경망(Convolutional Neural Network; CNN)을 학습시키고, 배포합니다. 라벨은 비싸고, 라벨 작업자(labeler)들이 합의할 수 있는 범위로 편향되며, 미세조정(finetuning) 없이는 새로운 과제로 잘 전이(transfer)되지 않습니다.
반면 이미지-캡션 웹에는 느슨하게 라벨링된 쌍이 10억 개 이상 무료로 흩어져 있습니다. 골든 리트리버 사진에 대체 텍스트(alt text)로 "my dog Max in the park"가 붙어 있다면, 그 텍스트가 이미지를 설명한다는 점에서 지도 신호(supervisory signal)가 들어 있는 셈입니다. 그렇다면 질문은 이렇습니다. 이 신호를 쓸 만한 학습으로 바꿀 수 있는가?
CLIP의 답은 이미지-캡션 쌍을 매칭 과제(matching task)로 다루는 것입니다. N개의 이미지와 N개의 캡션으로 이뤄진 배치가 주어졌을 때, 각 이미지를 자기 캡션과 매칭하도록 학습시키고 나머지 N-1개의 방해 후보(distractor)와는 구분하도록 합니다. 지도 신호는 "이 둘은 짝이고, 나머지 N-1은 아니다"라는 것뿐입니다. 클래스 라벨도, 사람의 주석(annotation)도 필요 없습니다. 오직 대조 손실 하나입니다.
그 결과로 만들어진 임베딩 공간은 CLIP이 직접 학습한 과제 이상의 일을 해냅니다. "a photo of a cat"이라는 텍스트의 임베딩이, 누구도 명시적으로 고양이라고 라벨링하지 않은 고양이 사진들의 임베딩 근처에 놓이기 때문에 ImageNet 제로샷이 동작합니다. 바로 이 도박이 2026년의 모든 VLM을 낳았습니다.
개념
이중 인코더(Dual Encoder)
CLIP은 두 개의 타워(tower)로 구성됩니다.
- 이미지 인코더
f: ViT 또는 ResNet이며, 이미지 한 장마다 D차원 벡터를 출력합니다.
- 텍스트 인코더
g: 작은 트랜스포머(transformer)이며, 캡션 하나마다 D차원 벡터를 출력합니다.
두 타워 모두 출력을 단위 길이(unit length)로 정규화(normalize)합니다. 둘 다 단위 노름(unit-norm)이므로 유사도는 cos(f(x), g(y)) = f(x)^T g(y)로 계산됩니다.
N개의 (이미지, 캡션) 쌍 배치에 대해 (N, N) 형태의 유사도 행렬(similarity matrix) S를 만듭니다.
S[i, j] = cos(f(x_i), g(y_j)) / tau
여기서 tau는 학습 가능한 온도(learned temperature)입니다. CLIP은 0.07로 초기화하고 로그 공간(log-space)에서 학습합니다.
InfoNCE 손실
CLIP은 행(row)과 열(column) 양쪽에 대해 대칭적인 교차 엔트로피(symmetric cross-entropy)를 사용합니다.
loss_i2t = CE(S, labels=identity) # 각 이미지의 정답 쌍은 자기 자신의 캡션
loss_t2i = CE(S^T, labels=identity) # 각 캡션의 정답 쌍은 자기 자신의 이미지
loss = (loss_i2t + loss_t2i) / 2
이것이 바로 InfoNCE입니다. 교차 엔트로피 안의 소프트맥스가 각 이미지를 배치 안의 다른 어떤 캡션보다도 자기 캡션과 더 잘 매칭되도록 강제합니다. "음성 표본(negative)"은 배치의 나머지 항목 전부입니다. 배치가 클수록 음성 표본도 많아지고 학습 신호도 강해집니다. CLIP은 배치 크기 32k로 학습했습니다. 규모가 중요합니다.
온도(Temperature)
tau는 소프트맥스의 날카로움(sharpness)을 조절합니다. tau가 낮으면 분포가 날카로워져 어려운 음성 표본 채굴(hard negative mining)과 비슷한 효과가 납니다. tau가 높으면 분포가 부드러워져 모든 표본이 더 고르게 기여합니다. CLIP은 log(1/tau)를 학습하면서 모델이 무너지지 않도록(collapse) 값을 잘라냅니다(clip). SigLIP 2는 초기 tau를 고정하고, 그 대신 학습 가능한 편향(learned bias)을 도입합니다.
시그모이드가 더 잘 확장되는 이유(SigLIP)
소프트맥스는 전체 유사도 행렬이 한 곳에서 동기화되어 있어야 합니다. 분산 학습(distributed training)에서는 모든 임베딩을 모든 복제본(replica)으로 전체 모음(all-gather)한 뒤 소프트맥스를 계산해야 합니다. 그러면 통신 비용이 월드 사이즈(world size)에 대해 제곱(quadratic)으로 늘어납니다.
SigLIP은 소프트맥스를 원소별 시그모이드(element-wise sigmoid)로 바꿉니다. 각 쌍 (i, j)에 대해 "이 둘이 매칭되는 쌍인가?"라는 이진 분류(binary classification)로 보는 것입니다. 양성(positive) 라벨은 대각(diagonal)이고, 나머지는 모두 음성(negative)입니다. 손실은 다음과 같습니다.
L = -1/N sum over (i, j) [ y_ij log sigmoid(S[i,j]) + (1-y_ij) log sigmoid(-S[i,j]) ]
y_ij = 1은 i == j일 때이고, 그 외에는 0입니다. 각 쌍의 손실은 서로 독립적이며, 전체 모음이 필요 없습니다. 각 GPU는 자신이 가진 로컬 블록(local block)을 계산해 합치기만 하면 됩니다. SigLIP 2는 CLIP이라면 통신량이 비례해서 폭증할 배치 32k~512k 영역에서도 저렴하게 확장됩니다.
제로샷 분류
N개의 클래스 이름이 주어지면, 클래스마다 텍스트 템플릿을 만듭니다.
"a photo of a {class}"
각 템플릿을 텍스트 인코더로 임베딩하고, 이미지를 이미지 인코더로 임베딩합니다. 코사인 유사도의 argmax가 예측 클래스(predicted class)가 됩니다. 대상 클래스에 대한 학습은 전혀 없습니다.
프롬프트 템플릿은 중요합니다. CLIP 원 논문은 클래스마다 80개의 템플릿(plain, artistic, photo, painting 등)을 사용하고 임베딩을 평균 냈으며, ImageNet에서 약 +3점을 얻었습니다. 요즘에는 보통 하나나 두 개의 템플릿만 고릅니다.
선형 프로브와 미세조정(Linear Probes and Finetuning)
제로샷은 기준선(baseline)입니다. 선형 프로브(linear probe)는 동결된(frozen) CLIP 특징 위에 대상 클래스용 선형 계층(linear layer) 하나만 학습시키는 방식이며, 도메인 내(in-domain) 과제에서 제로샷을 능가합니다. 전체 미세조정(full finetuning)은 도메인 내에서 선형 프로브보다 더 좋지만, 제로샷 전이 성능은 떨어뜨릴 수 있습니다. 이렇게 세 가지 모드는 각자 다른 절충점(trade-off)을 가집니다.
SigLIP 2: NaFlex와 조밀 특징(Dense Features)
SigLIP 2(2025)는 다음을 추가합니다.
- NaFlex: 단일 모델이 다양한 종횡비(aspect ratio)와 해상도(resolution)를 처리합니다.
- 분할(segmentation)이나 깊이 추정(depth estimation)을 위한 조밀 특징(dense features)이 강화되어, VLM의 동결 백본(frozen backbone)으로 쓰는 것을 목표로 합니다.
- 다국어(multilingual): CLIP이 영어 전용이었던 것과 달리 100개 이상의 언어로 학습되었습니다.
- 1B 파라미터 규모: CLIP이 400M에서 멈췄던 한계를 넘습니다.
2026년의 오픈 VLM에서는 SigLIP 2 SO400m/14가 기본 비전 타워(default vision tower)로 자리 잡았습니다. CLIP은 LAION-2B 학습 분포가 검색 쿼리(query pattern)와 잘 맞는 순수 이미지-텍스트 검색에서 여전히 기본 선택지로 남아 있습니다.
ALIGN, BASIC, OpenCLIP, EVA-CLIP
ALIGN(Google, 2021)은 CLIP과 같은 아이디어를 18억 쌍 규모에 90% 노이즈가 섞인 데이터로 밀어붙여, 노이즈가 많은 데이터도 충분히 확장됨을 보였습니다. OpenCLIP(LAION)은 LAION-400M/2B 위에서 CLIP을 오픈 소스로 재현(open reproduction)한 프로젝트이며, 여러 규모의 체크포인트(checkpoint)를 제공해 가장 많이 쓰이는 오픈 체크포인트입니다. EVA-CLIP은 마스킹된 이미지 모델링(masked image modeling)에서 초기화되어 VLM용으로 강력한 백본을 제공합니다. BASIC은 Google의 CLIP+ALIGN 하이브리드입니다. 모두 같은 계열이며, 데이터와 조정 방식만 다릅니다.
제로샷 성능의 천장(Zero-Shot Ceiling)
CLIP 계열 모델은 ImageNet 제로샷에서 약 76% 수준(CLIP-G, OpenCLIP-G)에 천장이 있습니다. 그 너머로 가려면 훨씬 더 많은 데이터(SigLIP 2는 80% 이상)나 구조 변경(지도 헤드, 더 많은 파라미터)이 필요합니다. 이 벤치마크 자체는 점점 포화(saturating)되고 있으며, 실제 가치는 다운스트림 VLM이 사용하는 임베딩 공간 그 자체에 있습니다.
사용해보기
code/main.py는 다음을 구현합니다.
- numpy 없이 InfoNCE의 모양을 눈으로 확인하기 위한 토이 이중 인코더(해시 기반 이미지 특징, 텍스트 문자 특징).
- 로그합지수(log-sum-exp)로 수치 안정성을 확보한 순수 Python InfoNCE 손실.
- 비교용 시그모이드 쌍별 손실.
- 제로샷 분류 루틴: 텍스트 프롬프트들에 대한 코사인 유사도를 계산하고 argmax로 예측.
코드를 실행하고 손실 곡선(loss curve)을 관찰해 봅니다. 절대값 자체는 토이이지만, 곡선의 형태는 실제 CLIP 학습기가 만들어 내는 모양과 동일합니다.
산출물 만들기
이 강의는 outputs/skill-clip-zero-shot.md를 만듭니다. 이미지 모음(경로 기준)과 대상 클래스 목록을 받으면, CLIP 템플릿으로 텍스트 프롬프트를 구성하고, 명시한 체크포인트(예: openai/clip-vit-large-patch14)로 양쪽을 임베딩한 다음, top-1 / top-5 예측과 유사도 점수를 반환합니다. 이 스킬(skill)은 프롬프트 목록에 없는 클래스에 대해서는 어떤 주장도 하지 않습니다.
연습문제
- 쉬움. 4쌍의 배치에 대해 InfoNCE를 손으로 구현합니다. 4x4 유사도 행렬을 만들고, 소프트맥스를 적용하고, 대각 원소를 골라 교차 엔트로피를 계산합니다. 직접 작성한 Python 구현과 손계산 결과를 대조합니다.
- 중간. SigLIP은 온도 외에 편향 파라미터
b를 사용합니다. S'[i,j] = S[i,j]/tau + b입니다. 배치 안에 클래스 불균형(class imbalance)이 커서 행마다 양성보다 음성이 훨씬 많을 때, b는 어떤 역할을 합니까? SigLIP 논문 Section 3(arXiv:2303.15343)을 읽어 답합니다.
- 중간. 고양이 대 강아지(cats vs dogs) 제로샷 분류기를 만듭니다. 두 프롬프트 템플릿
a photo of a {class}와 a picture of a {class}를 시도하고, 테스트 이미지 100장에서 정확도를 측정합니다. 템플릿 앙상블(ensemble)이 단일 템플릿보다 좋습니까?
- 어려움. 512-GPU 환경에서 배치 32k로 학습할 때, 소프트맥스 기반 InfoNCE와 시그모이드 쌍별 손실의 통신 비용을 각각 계산합니다. 어느 쪽이 O(N)이고 어느 쪽이 O(N^2)로 확장됩니까? SigLIP 논문 Section 4를 인용합니다.
- 어려움. OpenCLIP 스케일링 법칙 논문(arXiv:2212.07143, Cherti et al.)을 읽습니다. 본문 그래프에서 데이터 스케일링 결론을 재현해 봅니다. 모델 크기를 고정했을 때, ImageNet 제로샷 정확도와 학습 데이터 크기 사이의 로그-선형(log-linear) 관계는 어떤 모양입니까?
핵심 용어
| 용어 | 흔한 설명 | 실제 의미 |
|---|
| InfoNCE | "대조 손실" | 배치 유사도 행렬 위에서 계산하는 교차 엔트로피다. 각 항목의 양성 표본은 짝이 되는 항목이고, 음성 표본은 그 외 전부다. |
| Sigmoid loss | "SigLIP 손실" | 쌍별 이진 교차 엔트로피다. 소프트맥스도 전체 모음도 없어서 분산 학습에서 저렴하게 확장된다. |
| Temperature | "tau" | 소프트맥스/시그모이드 직전에 로짓(logit)을 스케일링하는 스칼라다. 분포의 날카로움을 조절한다. |
| Zero-shot | "미세조정 없는 분류" | 텍스트 프롬프트로 클래스 임베딩을 만들고 코사인 유사도로 분류하는 방식이다. 대상 클래스를 직접 학습하지 않는다. |
| Prompt template | "a photo of a ..." | 클래스 이름을 감싸는 텍스트 골격이다. 제로샷 정확도를 1~5점 정도 바꿀 수 있다. |
| Dual encoder | "이중 타워(two-tower)" | 이미지 인코더 하나와 텍스트 인코더 하나가 공유된 D차원 공간에 출력을 만든다. |
| 하드 네거티브(hard negative) | "어려운 방해 후보" | 양성과 충분히 비슷해 모델이 구분하려고 노력해야 하는 음성 표본이다. |
| Linear probe | "동결 + 한 층" | 동결된 특징 위에 선형 분류기만 학습시키는 방식이며, 특징의 품질을 측정한다. |
| NaFlex | "원본 가변 해상도(native flexible resolution)" | 리사이즈 없이 임의의 종횡비와 해상도 이미지를 그대로 입력으로 받는 SigLIP 2의 능력이다. |
| Temperature scaling | "로그 매개변수화된 tau" | CLIP은 그래디언트가 안정적으로 흐르도록 log(1/tau)로 매개변수화하고, tau가 0 근처로 무너지는 것을 막기 위해 잘라낸다. |
더 읽을거리