Ir para o conteúdo

19. CLIP

Mais sobre PLN

Veja o curso de PLN do Tiago Tavares, que cobre Transformers e outros tópicos avançados: https://tiagoft.github.io/nlp_course/.

Todo modelo generativo dos capítulos anteriores conseguia produzir uma imagem. Nenhum deles conseguia produzir a imagem que você pediu, porque nenhum deles fazia ideia do que uma frase significa. O CLIP é onde isso muda e é por isso que este capítulo fica no meio de um módulo sobre geração apesar de não ser, de forma alguma, um modelo generativo.

A ideia2 é quase agressivamente simples. Pegue 400 milhões de pares (imagem, legenda) da internet. Treine um encoder de imagem e um encoder de texto — separados, sem pesos compartilhados — sob uma única instrução: coloque uma imagem e a legenda dela perto uma da outra e todo o resto longe.

É o objetivo inteiro. O que sai disso é um único espaço vetorial no qual imagens e frases habitam e portanto uma interface: agora dá para fazer perguntas que atravessam a fronteira entre modalidades. "O quão perto esta figura está da frase uma foto de um cachorro?" vira um produto escalar.

Os componentes

  • Encoder de imagem — um ViT, ou, no artigo original, uma ResNet modificada, produzindo um embedding de tamanho fixo.
  • Encoder de texto — um Transformer, produzindo um embedding da mesma dimensionalidade. Essa igualdade é todo o compromisso arquitetural.
  • Uma projeção e uma normalização L2 de cada lado, para que todo embedding fique na esfera unitária e a similaridade de cosseno seja apenas um produto escalar.
  • Uma perda contrastiva (InfoNCE simétrica) sobre um lote: a diagonal da matriz de similaridade imagem×texto está certa, todo o resto está errado.

Treinamento. Dois encoders, uma matriz de similaridade e uma perda que diz que só a diagonal está correta. Do artigo do CLIP da OpenAI2.

O que a perda de fato pede

Repare no que o CLIP não é solicitado a fazer. Ele nunca reconstrói uma imagem, nunca gera uma legenda, nunca prevê um rótulo. Só lhe pedem que distinga pares que casam de pares que não casam — e o espaço que sai de fazer isso em escala acaba codificando uma quantidade enorme de informação sobre como as coisas parecem e como são chamadas. Discriminar é um objetivo muito mais barato que gerar e esta é uma das demonstrações mais claras de que ele é quase tão informativo.

A perda e as duas decisões de projeto dentro dela

\[ \mathcal{L} = \tfrac{1}{2}\Big( \underbrace{\text{CE}\big(\tfrac{I K^\top}{\tau},\; \text{diag}\big)}_{\text{imagem} \to \text{texto}} + \underbrace{\text{CE}\big(\tfrac{K I^\top}{\tau},\; \text{diag}\big)}_{\text{texto} \to \text{imagem}} \Big) \]

A temperatura \(\tau\) escala as similaridades antes do softmax. Um \(\tau\) pequeno afia a distribuição e a perda se concentra no negativo mais difícil; um \(\tau\) grande trata todos os negativos por igual e a representação para de afiar. O CLIP aprende o \(\tau\) em vez de fixá-lo, de modo que o modelo faz o annealing da própria dificuldade. Arraste-o no painel: repare que a acurácia de recuperação não muda — o \(\tau\) afeta a perda, não o ranking.

O tamanho do lote faz parte do objetivo. Toda outra legenda do lote é um negativo, então um lote de 32.768 dá a cada exemplo 32.767 negativos. Isto não é decisão de velocidade de treino; é o que determina quão difícil a tarefa é. Também significou espalhar a matriz de similaridade por centenas de aceleradores e essa restrição de engenharia moldou o aprendizado contrastivo por anos.

SigLIP: o que o substituiu

Troque o objetivo do painel para SigLIP5 e o softmax desaparece. Cada uma das \(N^2\) células vira uma pergunta binária independente — estes dois casam? — sob uma perda sigmoide comum com um viés aprendido:

\[ \mathcal{L} = \frac{1}{N}\sum_{i}\sum_{j} \log\Big(1 + e^{\,-y_{ij}\,(\,t\,\langle I_i, K_j\rangle + b\,)}\Big), \qquad y_{ij} = \begin{cases} +1 & i = j \\ -1 & i \neq j\end{cases} \]

Nada é normalizado sobre o lote. Sem all-gather, sem softmax distribuído, lotes pequenos funcionam e ele treina melhor em toda escala. Todo modelo recente de visão-linguagem usa um encoder da família SigLIP, então, se você for escolher uma torre de imagem hoje, é esta — não o CLIP.

Classificação zero-shot e o que ela realmente é

Inferência: codifique a imagem uma vez, codifique um prompt por classe, pegue o mais próximo. Do artigo do CLIP2.

Escreva uma frase por classe — "uma foto de um {classe}" — codifique-as, codifique a imagem, pegue a maior similaridade de cosseno. Sem treino, sem exemplos rotulados e com qualquer conjunto de classes que você consiga descrever em palavras.

Para aplicar o CLIP a uma tarefa nova, tudo que precisamos é "dizer" ao encoder de texto do CLIP os nomes dos conceitos visuais da tarefa e ele produz um classificador linear das representações visuais do CLIP. A acurácia desse classificador é frequentemente competitiva com a de modelos totalmente supervisionados.1

'Zero-shot' está trabalhando demais nessa frase

O CLIP viu 400 milhões de imagens legendadas. Se as suas classes foram descritas em algum lugar daqueles dados — e, para objetos comuns, foram, muitas vezes — isto não é zero-shot em nenhum sentido forte; é recuperação de um conjunto de treino enorme com um índice em linguagem natural. A parte genuinamente surpreendente não é que funcione com cachorros. É que a interface é linguagem, de modo que o conjunto de classes é definido na inferência por quem estiver digitando.

As limitações honestas

  • Contagem e relações espaciais


    "Três gatos" e "um gato" ficam próximos no espaço do CLIP. Assim como "a xícara sobre o livro" e "o livro sobre a xícara". Quase aleatório em benchmarks de contagem.

  • Ele se comporta como saco de palavras


    Embaralhe as palavras de uma legenda e o embedding do CLIP quase não se move7. Estrutura composicional — qual objeto tem qual atributo, quem fez o quê a quem — é largamente ausente e esta é a limitação mais profunda conhecida de toda a família.

  • Sensibilidade ao prompt


    "uma foto de um {classe}" bate "{classe}" por vários pontos de acurácia. O artigo original entrega 80 modelos de prompt escritos à mão e faz média dos embeddings. Isso é um remendo, não uma propriedade.

  • :material-scale-unbalanced-variant:{ .lg .middle } Ele aprendeu as associações da internet


    Inclusive as que você não gostaria. Falhas documentadas em raça e gênero, ocupação e aparência. São herdadas por todo modelo a jusante — incluindo geradores de imagem condicionados a embeddings de texto do CLIP.

Onde o CLIP fica neste curso

Este capítulo está aqui porque geração condicionada a texto precisa de um encoder de texto e o CLIP é de onde um deles veio.

Uso O que o CLIP fornece
Condicionar um modelo de difusão O Stable Diffusion faz atenção cruzada com embeddings de texto do CLIP (capítulo 20). O SDXL usa dois encoders de texto; SD3 e FLUX acrescentam um encoder T5, porque a torre de texto do CLIP é pequena e seu comportamento de saco de palavras limita prompts longos e composicionais.
O encoder de imagem de um VLM A torre de visão que alimenta um modelo de linguagem costuma ser um encoder da família SigLIP (capítulo 13).
Busca Busca texto-para-imagem e imagem-para-imagem, em escala, com um produto escalar por candidato.
Avaliação O CLIPScore — o quanto a imagem gerada casa com o prompt? — é a métrica padrão de aderência ao prompt (capítulo 8.3) e herda todas as limitações acima, inclusive a cegueira à ordem das palavras.
Curadoria de dados Filtrar conjuntos imagem-texto de bilhões de itens por similaridade do CLIP. O LAION foi construído assim, o que significa que modelos posteriores herdam o julgamento do CLIP sobre o que é um bom par.

O resultado que importou mais que a arquitetura

Reproduções abertas — o OpenCLIP e o benchmark DataComp — mantiveram a arquitetura fixa e variaram os dados6. Filtrar com cuidado um conjunto menor bateu um maior sem filtro, com folga. A lição duradoura do CLIP talvez nem seja o aprendizado contrastivo: é que, nesta escala, construir o conjunto de dados é a arquitetura do modelo.

Pontos principais

  1. O CLIP treina dois encoders para colocar uma imagem e sua legenda no mesmo espaço. Esse espaço compartilhado é uma interface entre visão e linguagem, não um modelo generativo.
  2. A perda é contrastiva: a diagonal da matriz de similaridade do lote está certa, todo o resto está errado. Discriminação, não reconstrução.
  3. A temperatura decide o quanto a perda liga para o negativo mais difícil e o CLIP a aprende. O tamanho do lote faz parte do objetivo — toda outra legenda é um negativo.
  4. O SigLIP o substituiu: um sigmoide independente por par, sem normalização sobre o lote, melhor em toda escala. Hoje, use um encoder da família SigLIP.
  5. Classificação zero-shot é recuperação com um índice em linguagem. Impressionante e não mágica.
  6. O CLIP é próximo de um saco de palavras: contagem, relações espaciais e composicionalidade são fracas e isso flui para todo modelo condicionado nele.
  7. Neste curso o CLIP é a ponte: é o que permite que do capítulo 20 em diante se condicione numa frase.
  8. Curadoria de dados importou mais que a arquitetura. Essa é a lição duradoura.

Simulação Numérica da Perda Contrastiva do CLIP

Para ilustrar como o CLIP funciona numericamente, vamos simular um pequeno batch com 3 pares imagem-texto. Assumiremos embeddings pré-computados (na prática, eles vêm dos codificadores). Cada embedding é um vetor 3D por simplicidade (o CLIP real usa dimensões maiores como 512).

Configuração:

  • Embeddings de imagem (I):

    \( I_1 = [1.0, 0.0, 0.0] \) (ex: para "gato")
    \( I_2 = [0.0, 1.0, 0.0] \) (ex: para "cachorro")
    \( I_3 = [0.0, 0.0, 1.0] \) (ex: para "pássaro")

  • Embeddings de texto (T):

    \( T_1 = [0.9, 0.1, 0.0] \) (próximo a \(I_1\))
    \( T_2 = [0.1, 0.8, 0.1] \) (próximo a \(I_2\))
    \( T_3 = [0.0, 0.3, 0.7] \) (próximo a \(I_3\))

  • Tamanho do batch (\(N\)): \(3\)

  • Temperatura (\(\tau\)): \(0.07\) (hiperparâmetro para escalar logits; comum no CLIP).

Cálculo Passo a Passo:

  1. Normalizar os Embeddings:

    O CLIP usa embeddings L2-normalizados para similaridade cosseno. Aqui, eles já têm comprimento unitário para simplificar (assuma que são).

  2. Calcular a Matriz de Similaridade (Logits):

    Similaridade = \( \displaystyle \frac{(I \cdot T)}{\tau} \) (produto escalar escalado por τ).

    \( \text{Logits}_{I \to T} \approx \begin{bmatrix} 12.857 & 1.4286 & 0 \\ 1.4286 & 11.4286 & 4.2857 \\ 0 & 1.4286 & 10 \end{bmatrix} \)

    Os logits de texto para imagem são a transposta: \(\text{Logits}_{T \to I} = \text{Logits}_{I \to T}^T\)

  3. Softmax para Probabilidades:

    Para cada linha (imagem), softmax sobre os logits fornece probabilidades de correspondência de textos.

    \( \text{Softmax}(I) \approx \begin{bmatrix} 0.9999 & 0 & 0 \\ 0 & 0.9992 & 0.0008 \\ 0 & 0.0002 & 0.9998 \end{bmatrix} \)

    A diagonal deve ter probabilidades altas.

  4. Perda Contrastiva:

    Log-verossimilhança negativa dos rótulos corretos (diagonal).

    \[ \mathcal{L}_{I \to T} = -\frac{1}{N} \sum_{i=1}^{N} \log(p_{i \to t}) \]

    \(\mathcal{L}_{I \to T} \approx 0.00016\) (perda muito baixa, pois os embeddings estão bem alinhados).

    O CLIP calcula perda simétrica:

    \[ \displaystyle \mathcal{L} = \frac{1}{2} \left( \mathcal{L}_{I \to T} + \mathcal{L}_{T \to I} \right). \]

Esta é uma simulação simplificada; o CLIP real lida com batches grandes (ex: 32k) e usa treinamento distribuído.


Adicional

Embeddings L2-normalizados

Embeddings L2-normalizados são vetores cujo comprimento é escalado para a unidade 1, significando que sua norma L2 (comprimento euclidiano) é igual a um. Isso é obtido dividindo cada componente do vetor original por sua norma L2 total, tornando-o um método comum para garantir magnitude consistente e melhorar a eficácia de medidas de similaridade baseadas em distância, como a similaridade cosseno4.

Como funciona

  1. Calcular a norma L2:

    Para um vetor \(v=[v_{1},v_{2},...,v_{n}]\), a norma L2 (\(||v||_{2}\)) é a raiz quadrada da soma dos quadrados de seus componentes: \(||v||_{2}=\sqrt{v_{1}^{2}+v_{2}^{2}+...+v_{n}^{2}}\).

  2. Dividir cada componente:

    Cada elemento do vetor é então dividido por esta norma L2 calculada. O vetor normalizado resultante, \(v^{\prime }\), é:

    \(v^{\prime }=[\frac{v_{1}}{||v||_{2}},\frac{v_{2}}{||v||_{2}},...,\frac{v_{n}}{||v||_{2}}]\).

Por que é usado

  • Foco na direção: Ajuda os modelos a focarem na "direção" do vetor no espaço de alta dimensionalidade, ao invés de sua magnitude.
  • Melhora medidas de similaridade: A normalização é crucial para técnicas que dependem de similaridade cosseno. Embeddings L2-normalizados tornam o score de similaridade igual ao produto escalar.
  • Previne viés de magnitude: Garante que embeddings com grandes magnitudes não dominem as comparações de similaridade.


  1. CLIP: Connecting Text and Images ↩

  2. Learning Transferable Visual Models From Natural Language Supervision, Alec Radford et al., 2021. ↩↩↩

  3. How to Normalize a Vector, Nextbridge. ↩

  4. Cosine Similarity, GeeksforGeeks. ↩

  5. Zhai, X., Mustafa, B., Kolesnikov, A., & Beyer, L. (2023). Sigmoid Loss for Language Image Pre-Training — ICCV. SigLIP; o artigo que removeu o softmax sobre o lote. ↩

  6. Gadre, S., et al. (2023). DataComp: In search of the next generation of multimodal datasets — NeurIPS. Arquitetura fixa, dados variados — e os dados vencem. ↩

  7. Yuksekgonul, M., Bianchi, F., Kalluri, P., Jurafsky, D., & Zou, J. (2023). When and why vision-language models behave like bags-of-words, and what to do about it? — ICLR. ↩