o problema
Um modelo de visão nascia preso a uma lista. A ResNet do ImageNet prevê 1.000 categorias e ponto; qualquer conceito visual novo exige dados rotulados novos e uma cabeça de saída nova. Pior: o rótulo precisa estar no formato canônico de 1-de-N por maioria de votos, que só existe porque alguém pagou anotador. O NLP já tinha saído disso — objetivo agnóstico de tarefa em texto cru da internet, interface text-to-text, transferência zero-shot sem cabeça especializada. Em visão, o padrão continuava sendo pré-treinar em dataset rotulado à mão.
Aprender de legenda não era ideia nova: existe trabalho nessa direção desde 1999. O que faltava era resultado. Visual N-Grams, o melhor ponto de comparação em zero-shot no ImageNet, chegava a 11,5% — abaixo até dos 50% de abordagens clássicas de visão. O meio-termo pragmático era supervisão fraca em escala: prever hashtags do Instagram, prever as classes ruidosas do JFT-300M. Funcionava, mas devolvia o mesmo problema pela porta dos fundos, porque a supervisão volta a ser um conjunto fechado — 1.000 e 18.291 classes nesses dois casos — com softmax estático e nenhuma saída dinâmica. A diferença decisiva entre as duas linhas era compute: quem aprendia de linguagem natural rodava dias de acelerador em centenas de milhares de imagens, enquanto quem usava supervisão fraca rodava anos de acelerador em bilhões.
a ideia
Fechar essa lacuna de escala e, ao fazer isso, mudar a pergunta. Prever as palavras exatas da legenda é tarefa dura, porque o texto que acompanha uma imagem na web é comentário, descrição, ruído. Prever apenas qual texto, inteiro, pertence a qual imagem dentro de um batch é uma proxy mais fácil e mede-se bem: um transformer de 63 milhões de parâmetros prevendo a legenda aprende ImageNet 3 vezes mais devagar que um baseline bobo de bag-of-words, e trocar esse objetivo preditivo pelo contrastivo dá mais 4 vezes de eficiência. O dataset é novo — 400 milhões de pares (imagem, texto) coletados a partir de 500.000 queries de busca, com teto de 20.000 pares por query.
O segundo movimento é o que dá o zero-shot. Se o text encoder aprendeu a mapear frase para o mesmo espaço da imagem, ele pode gerar, na hora do teste, o classificador de qualquer dataset: basta embutir os nomes das classes. O encoder de imagem é o backbone; o encoder de texto vira uma hypernetwork que escreve os pesos de um classificador linear a partir de uma descrição em português — ou em inglês, no caso.
como funciona
Dado um batch de N pares, o modelo calcula N embeddings de imagem e N de texto, projeta cada um linearmente no espaço multimodal (projeção linear, não a MLP não-linear popularizada pelo SimCLR), normaliza em L2 e monta a matriz N×N de similaridades cosseno, escalada por uma temperatura τ. A perda é cross-entropy simétrica: a diagonal é o alvo, uma vez sobre as linhas e uma vez sobre as colunas. Os N²−N pares errados são os negativos, de graça, sem mineração.
I_f = image_encoder(images) # [n, d_i]
T_f = text_encoder(texts) # [n, d_t]
I_e = l2_normalize(I_f @ W_i) # [n, d_e]
T_e = l2_normalize(T_f @ W_t) # [n, d_e]
logits = (I_e @ T_e.T) * exp(t) # t aprendido
labels = arange(n)
loss = (ce(logits, labels, axis=0) + ce(logits, labels, axis=1)) / 2
Detalhes que importam. τ é parâmetro treinável, log-parametrizado, inicializado em 0,07 e clipado para não escalar os logits mais que 100 — sem isso o treino instabiliza. O batch é de 32.768, o que faz cada passo parecer um dataset de 32.768 classes com um exemplo por classe; as similaridades são calculadas de forma shardeada entre GPUs. Nada de inicialização com pesos do ImageNet ou de um LM pré-treinado: tudo do zero, 32 épocas. A única augmentation é crop quadrado aleatório. Foram treinados 5 ResNets e 3 ViTs; a RN50x64 levou 18 dias em 592 V100, e o maior ViT, 12 dias em 256 V100. O text encoder é um transformer de 63M, 12 camadas, largura 512, 8 heads, BPE de 49.152 tokens, sequência limitada a 76, e a ativação no token [EOS] é a representação da frase. O melhor modelo é um ViT-L/14 com uma época extra a 336 pixels.
Na inferência, o classificador de texto é computado uma vez e cacheado — o custo de gerá-lo se dilui em todas as predições do dataset. Ensemble de prompts também é gratuito, porque se faz no espaço de embedding: 80 templates viram uma média, não 80 forward passes.
o que isso custou
O paper é honesto sobre o tamanho do buraco. Zero-shot CLIP empata, na média, com uma regressão logística sobre features de ResNet-50 — baseline que já estava bem abaixo do estado da arte da época. Para o zero-shot alcançar o SOTA geral, os autores estimam 1.000 vezes mais compute, o que declaram inviável no hardware existente.
A distribuição de acertos é irregular. Zero-shot vence esse baseline em 16 de 27 datasets, mas é fraco em fine-grained — Flowers102 e FGVCAircraft ficam mais de 10 pontos abaixo — e perto do aleatório em tarefas abstratas ou especializadas: contar objetos no CLEVR, distância até o carro mais próximo no KITTI, placas de trânsito, imagem de satélite, tumor em linfonodo. Na maioria dos datasets, o zero-shot fica 10 a 25 pontos abaixo do linear probe sobre as mesmas features.
O caso do MNIST é o mais desconfortável: 88%, perdendo para regressão logística em pixels crus. Busca por vizinhos próximos confirma que quase não há dígito manuscrito no pré-treino. A conclusão dos próprios autores é que o CLIP não resolve a generalização frágil do deep learning, apenas aposta que um dataset grande o bastante torna tudo in-distribution — e o MNIST mostra que é fácil violar essa aposta.
A eficiência de dados também não melhorou: 12,8 bilhões de imagens vistas ao longo do treino, o equivalente a 405 anos a uma imagem por segundo. E há o efeito contraintuitivo do few-shot: zero-shot iguala um classificador de 4 exemplos por classe e, ao passar de zero para um exemplo, a performance cai, porque o linear probe não usa o classificador de linguagem como prior. Humanos, nas mesmas 37 raças de cachorro e gato do Oxford-IIIT Pets, vão de 54% para 76% com um exemplo por classe.
Metodologicamente, os autores admitem duas coisas: consultaram repetidamente validation sets completos para guiar o desenvolvimento, o que não é cenário zero-shot de verdade, e a suíte principal de 27 datasets foi montada de forma admitidamente co-adaptada ao CLIP.
E há o viés, que vem inteiro da web sem curadoria. Em sondagem no FairFace, 4,9% das imagens caíram em classes não-humanas (‘animal’, ‘gorila’, ‘chimpanzé’, ‘orangotango’), com imagens de pessoas negras na taxa mais alta, perto de 14%. Classes ligadas a crime pegaram 16,5% das imagens de homens contra 9,8% das de mulheres, e pessoas de 0 a 20 anos eram as mais afetadas — adicionar a classe ‘child’ ao conjunto de rótulos derrubou drasticamente esse número. É a demonstração mais concreta do risco central do modelo: como qualquer pessoa define as classes por texto, o design das classes vira parte do sistema, e um design ruim produz dano.
onde isso aparece hoje
Código e pesos foram liberados junto com o paper, e o formato virou padrão de fato: dois encoders, um espaço de embedding compartilhado, similaridade cosseno. É a arquitetura por trás de busca semântica de imagem por texto e de classificação por lista de prompts, sem fine-tuning. O text encoder do CLIP também foi reaproveitado como condicionamento em geradores de imagem — o Stable Diffusion usa exatamente isso.
Duas práticas nascidas aqui ficaram além da visão. Uma é medir capacidade por transferência zero-shot em suítes amplas, e não por accuracy em um dataset só — o argumento do paper é que a accuracy in-distribution passou a ser uma medida enganosa, já que 9,2 pontos ganhos no ImageNet não viraram nenhum ganho sob distribution shift. A outra é prompt engineering em visão: o texto que descreve a classe é hiperparâmetro, e caro de ignorar.