Phase 04 - Lesson 25
Modelos de Visão-Linguagem — O Padrão ViT-MLP-LLM
Um codificador de visão converte uma imagem em tokens. Um projetor MLP mapeia esses tokens para o espaço de embeddings do LLM. Um modelo de linguagem faz o resto. Esse padrão — ViT-MLP-LLM — é todo VLM de produção em 2026.
Tipo: Aprender + Usar Linguagens: Python Pré-requisitos: Fase 4 Lição 14 (ViT), Fase 4 Lição 18 (CLIP), Fase 7 Lição 02 (Self-Attention) Tempo: ~75 minutos
Objetivos de Aprendizagem
- Enunciar a arquitetura ViT-MLP-LLM e explicar o que cada um dos três componentes contribui
- Comparar Qwen3-VL, InternVL3.5, LLaVA-Next e GLM-4.6V em contagem de parâmetros, comprimento de contexto e desempenho em benchmarks
- Explicar o DeepStack: por que características multi-nível do ViT melhoram o alinhamento visão-linguagem mais do que uma única característica da última camada
- Medir alucinação de VLM em produção com a Cross-Modal Error Rate (CMER) e agir sobre o sinal
O Problema
O CLIP (Fase 4 Lição 18) lhe dá um espaço de embeddings compartilhado para imagens e texto, o que é suficiente para classificação zero-shot e recuperação. Ele não consegue responder "quantos carros vermelhos há nesta imagem?" porque o CLIP não gera texto — ele apenas pontua similaridades.
Modelos de Visão-Linguagem (VLMs) — Qwen3-VL, InternVL3.5, LLaVA-Next, GLM-4.6V — acoplam um codificador de imagem da família CLIP a um modelo de linguagem completo. O modelo vê uma imagem mais uma pergunta e gera uma resposta. Em 2026 os VLMs open-source rivalizam ou superam o GPT-5 e o Gemini-2.5-Pro em benchmarks multimodais (MMMU, MMBench, DocVQA, ChartQA, MathVista, OSWorld).
O trio de peças (ViT, projetor, LLM) é o padrão. As diferenças entre modelos estão em qual ViT, qual projetor, qual LLM, os dados de treinamento e a receita de alinhamento. Uma vez que você entende o padrão, trocar qualquer componente é mecânico.
O Conceito
A arquitetura ViT-MLP-LLM
flowchart LR
IMG["Imagem<br/>(H x W x 3)"] --> ViT["Codificador de visão<br/>(ViT, CLIP-L,<br/>SigLIP, DINOv3)"]
ViT --> FEATS["Tokens de imagem<br/>(N, d_vit)"]
FEATS --> PROJ["Projetor<br/>(MLP de 2-4 camadas<br/>ou Q-former)"]
PROJ --> VTOK["Tokens de imagem<br/>no espaco do LLM<br/>(N, d_llm)"]
TXT["Prompt de texto"] --> TOK["Tokenizador do LLM"]
TOK --> TTOK["Tokens de texto<br/>(M, d_llm)"]
VTOK --> CONCAT["Intercalar<br/>ou concatenar"]
TTOK --> CONCAT
CONCAT --> LLM["LLM decoder<br/>(Qwen3, LLaMA, etc.)"]
LLM --> OUT["Resposta em texto"]
style ViT fill:#dbeafe,stroke:#2563eb
style PROJ fill:#fef3c7,stroke:#d97706
style LLM fill:#dcfce7,stroke:#16a34a
- Codificador de visão — um ViT pré-treinado (CLIP-L/14, SigLIP, DINOv3 ou uma variante ajustada). Produz tokens de patch.
- Projetor — um pequeno módulo (MLP de 2-4 camadas, ou um Q-former) que mapeia tokens de visão para a dimensão de embedding do LLM. É aqui que ocorre a maior parte do fine-tuning.
- LLM — um modelo de linguagem decoder-only (Qwen3, Llama, Mistral, GLM, InternLM). Lê os tokens de visão + texto em sequência e gera texto.
Todas as três peças são, em princípio, treináveis. Na prática, o codificador de visão e o LLM ficam em sua maioria congelados enquanto o projetor é treinado — alguns bilhões de parâmetros de sinal por um custo baixo.
DeepStack
A projeção convencional usa apenas a última camada do ViT. O DeepStack (Qwen3-VL) amostra características de múltiplas profundidades do ViT e as empilha. Camadas mais profundas carregam semântica de alto nível; camadas mais rasas carregam informação espacial e de textura de granularidade fina. Alimentar ambas no LLM fecha a lacuna entre "o que a imagem contém" (semântica) e "onde exatamente" (ancoragem espacial).
Três estágios de treinamento
VLMs modernos treinam em estágios:
- Alinhamento — congele o ViT e o LLM. Treine apenas o projetor em pares imagem-legenda. Ensina o projetor a mapear o espaço de visão para o espaço de linguagem.
- Pré-treinamento — descongele tudo. Treine em dados imagem-texto intercalados em larga escala (mais de 500M de pares). Constrói o conhecimento visual do modelo.
- Instruction tuning — faça fine-tune em triplas curadas de (imagem, pergunta, resposta). Ensina comportamento conversacional e formatos de tarefa. É isso que transforma um "LM com consciência visual" em um assistente utilizável.
A maioria dos fine-tunes com LoRA mira o estágio 3 com um pequeno conjunto de dados rotulado.
Comparação da família de modelos (início de 2026)
| Modelo | Params | Codificador de visão | LLM | Contexto | Pontos fortes |
|---|---|---|---|---|---|
| Qwen3-VL-235B-A22B (MoE) | 235B (22B ativos) | ViT custom + DeepStack | Qwen3 | 256K | SOTA geral, agente de GUI |
| Qwen3-VL-30B-A3B (MoE) | 30B (3B ativos) | ViT custom + DeepStack | Qwen3 | 256K | Alternativa MoE menor |
| Qwen3-VL-8B (dense) | 8B | ViT custom | Qwen3 | 128K | Padrão dense de produção |
| InternVL3.5-38B | 38B | InternViT-6B | Qwen3 + GPT-OSS | 128K | Forte em MMBench / MMVet |
| InternVL3.5-241B-A28B | 241B (28B ativos) | InternViT-6B | Qwen3 | 128K | Competitivo com GPT-4o |
| LLaVA-Next 72B | 72B | SigLIP | Llama-3 | 32K | Aberto, fácil de fazer fine-tune |
| GLM-4.6V | ~70B | custom | GLM | 64K | Open-source, OCR forte |
| MiniCPM-V-2.6 | 8B | SigLIP | MiniCPM | 32K | Amigável para edge |
Agentes visuais
O Qwen3-VL-235B alcança desempenho global de topo no OSWorld — um benchmark para agentes visuais que operam GUIs (desktop, mobile, web). O modelo vê uma captura de tela, entende a UI e emite ações (clicar, digitar, rolar). Combinado com ferramentas, ele fecha o ciclo em tarefas comuns de desktop. É isso que a maioria dos demos de "AI PC" de 2026 roda por baixo dos panos.
Capacidades agênticas + variantes de RoPE
VLMs precisam saber quando um quadro está em um vídeo. O Qwen3-VL evoluiu do T-RoPE (temporal rotary position embeddings) para o alinhamento temporal baseado em texto — tokens de texto de timestamp explícitos intercalados com quadros de vídeo. O modelo vê "<timestamp 00:32> quadro, prompt" e consegue raciocinar sobre relações temporais.
O problema de alinhamento
12% dos pares imagem-texto em um dataset coletado da web contêm descrições não totalmente ancoradas na imagem. Um VLM treinado nisso silenciosamente aprende a alucinar — fabricar objetos, ler números incorretamente, inventar relações. Em produção, este é o modo de falha dominante.
A Skywork.ai introduziu a Cross-Modal Error Rate (CMER) para rastreá-lo:
CMER = fracao de saidas onde a confianca do texto e alta mas a similaridade imagem-texto (via um verificador da familia CLIP) e baixa
Uma CMER alta significa que o modelo está afirmando com confiança coisas não ancoradas na imagem. Monitorar a CMER e tratá-la como um KPI de produção reduziu a taxa de alucinação em ~35% na implantação deles. O truque não é "consertar o modelo", mas "rotear saídas de CMER alta para revisão humana."
Fine-tuning com LoRA / QLoRA
O fine-tuning completo de um VLM de 70B está fora do alcance da maioria das equipes. LoRA (rank 16-64) nas camadas de atenção + projetor, ou QLoRA com pesos base de 4 bits, cabe em um único A100 / H100. Custo: 5.000-50.000 exemplos,
O raciocínio espacial ainda é fraco
Os VLMs atuais pontuam 50-60% em benchmarks de raciocínio espacial (acima-abaixo, esquerda-direita, contagem, distância). Se seu caso de uso depende de "qual objeto está em cima de qual", valide intensamente — o desempenho de VLM genérico está abaixo do humano. Alternativas melhores que VLMs para tarefas puramente espaciais: um estimador especializado de keypoint / pose, um modelo de profundidade, ou um modelo de detecção com geometria de bounding box pós-processada.
Construa
Passo 1: O projetor
A parte que você treinará com mais frequência. MLP de 2-4 camadas com GELU.
import torch
import torch.nn as nn
class Projector(nn.Module):
def __init__(self, vit_dim=768, llm_dim=4096, hidden=4096):
super().__init__()
self.net = nn.Sequential(
nn.Linear(vit_dim, hidden),
nn.GELU(),
nn.Linear(hidden, llm_dim),
)
def forward(self, x):
return self.net(x)
A entrada é um tensor de tokens (N_patches, d_vit). A saída é (N_patches, d_llm). O LLM trata cada linha de saída apenas como mais um token.
Passo 2: Montar o ViT-MLP-LLM de ponta a ponta
Esqueleto do forward pass para um VLM mínimo. Código real usa transformers; este é o layout conceitual.
class MinimalVLM(nn.Module):
def __init__(self, vit, projector, llm, image_token_id):
super().__init__()
self.vit = vit
self.projector = projector
self.llm = llm
self.image_token_id = image_token_id # placeholder token in text prompt
def forward(self, image, input_ids, attention_mask):
# 1. vision features
vision_tokens = self.vit(image) # (B, N_patches, d_vit)
vision_embeds = self.projector(vision_tokens) # (B, N_patches, d_llm)
# 2. text embeddings
text_embeds = self.llm.get_input_embeddings()(input_ids) # (B, M, d_llm)
# 3. replace image placeholder tokens with vision embeds
merged = self._merge(text_embeds, vision_embeds, input_ids)
# 4. run LLM
return self.llm(inputs_embeds=merged, attention_mask=attention_mask)
def _merge(self, text_embeds, vision_embeds, input_ids):
out = text_embeds.clone()
expected = vision_embeds.size(1)
for b in range(input_ids.size(0)):
positions = (input_ids[b] == self.image_token_id).nonzero(as_tuple=True)[0]
if len(positions) != expected:
raise ValueError(
f"batch item {b} has {len(positions)} image tokens but vision_embeds has {expected} patches."
" Every sample in the batch must be pre-padded to the same number of image placeholder tokens.")
out[b, positions] = vision_embeds[b]
return out
O token placeholder <image> no texto é substituído por embeddings reais de imagem — mesmo padrão que LLaVA, Qwen-VL e InternVL usam.
Passo 3: Cálculo da CMER
Uma verificação leve em tempo de execução.
import torch.nn.functional as F
def cross_modal_error_rate(image_emb, text_emb, text_confidence, sim_threshold=0.25, conf_threshold=0.8):
"""
image_emb, text_emb: embeddings of image and generated text (normalised internally)
text_confidence: mean per-token probability in [0, 1]
Returns: fraction of high-confidence outputs with low image-text alignment
"""
image_emb = F.normalize(image_emb, dim=-1)
text_emb = F.normalize(text_emb, dim=-1)
sim = (image_emb * text_emb).sum(dim=-1) # cosine similarity
high_conf_low_sim = (text_confidence > conf_threshold) & (sim < sim_threshold)
return high_conf_low_sim.float().mean().item()
Trate a CMER como um KPI de produção. Monitore-a por endpoint, por tipo de prompt, por cliente. Uma CMER crescente indica que o modelo está começando a alucinar em alguma distribuição de entrada.
Passo 4: Classificador VLM de brinquedo (executável)
Demonstra que o projetor treina. "Características de ViT" falsas entram; um pequeno token estilo LLM prevê uma classe.
class ToyVLM(nn.Module):
def __init__(self, vit_dim=32, llm_dim=64, num_classes=5):
super().__init__()
self.projector = Projector(vit_dim, llm_dim, hidden=64)
self.head = nn.Linear(llm_dim, num_classes)
def forward(self, vision_tokens):
projected = self.projector(vision_tokens)
pooled = projected.mean(dim=1)
return self.head(pooled)
É possível ajustar isso em pares sintéticos (característica, classe) em menos de 200 passos — o suficiente para mostrar que o padrão do projetor funciona.
Use
Três maneiras pelas quais equipes de produção usam VLMs em 2026:
- API hospedada — OpenAI Vision, Anthropic Claude Vision, Google Gemini Vision. Zero infraestrutura, risco de fornecedor.
- Self-host open-source — Qwen3-VL ou InternVL3.5 via
transformersevllm. Controle total, maior esforço inicial. - Fine-tune no domínio — carregue Qwen2.5-VL-7B ou LLaVA-1.6-7B, faça LoRA em 5k-50k exemplos custom, sirva com
vllmouTGI.
from transformers import AutoProcessor, AutoModelForVision2Seq
import torch
from PIL import Image
model_id = "Qwen/Qwen3-VL-8B-Instruct"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModelForVision2Seq.from_pretrained(model_id, torch_dtype=torch.bfloat16, device_map="auto")
messages = [{
"role": "user",
"content": [
{"type": "image", "image": Image.open("plot.png")},
{"type": "text", "text": "What does this chart show?"},
],
}]
inputs = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt").to("cuda")
generated = model.generate(**inputs, max_new_tokens=256)
answer = processor.decode(generated[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
O apply_chat_template esconde a tokenização do placeholder <image>; o modelo lida com o merge internamente.
Entregue
Esta lição produz:
outputs/prompt-vlm-selector.md— escolhe Qwen3-VL / InternVL3.5 / LLaVA-Next / API dadas acurácia, latência, comprimento de contexto e orçamento.outputs/skill-cmer-monitor.md— emite o código para instrumentar um endpoint de VLM de produção com cross-modal error rate, dashboards por endpoint e limiares de alerta.
Exercícios
- (Fácil) Rode três prompts ("o que é isto?", "conte os objetos", "descreva a cena") através de qualquer VLM aberto em cinco imagens. Pontue cada resposta como correta / parcialmente correta / alucinada à mão. Calcule uma taxa de primeira passagem semelhante à CMER.
- (Médio) Faça fine-tune do Qwen2.5-VL-3B ou LLaVA-1.6-7B com LoRA (rank 16) em 500 imagens de um domínio-alvo com legendas. Compare a acurácia estilo MMBench zero-shot vs. com fine-tune.
- (Difícil) Substitua o codificador de imagem do VLM por DINOv3 em vez de seu SigLIP/CLIP padrão. Re-treine apenas o projetor (LLM congelado + DINOv3 congelado). Meça se as tarefas de predição densa (contagem, raciocínio espacial) melhoram.
Termos-Chave
| Termo | O que as pessoas dizem | O que realmente significa |
|---|---|---|
| ViT-MLP-LLM | "O padrão VLM" | Codificador de visão + projetor + modelo de linguagem; todo VLM de 2026 |
| Projetor | "A ponte" | MLP de 2-4 camadas (ou Q-former) que mapeia tokens de visão para o espaço de embedding do LLM |
| DeepStack | "O truque de características do Qwen3-VL" | Características multi-nível do ViT empilhadas em vez de apenas a última camada |
| Token de imagem | "Placeholder |
Token especial no fluxo de texto substituído por embeddings de visão projetados |
| CMER | "KPI de alucinação" | Cross-Modal Error Rate; alta quando a confiança do texto é alta mas a similaridade imagem-texto é baixa |
| Agente visual | "VLM que clica" | VLM operando GUIs (OSWorld, mobile, web) com chamadas de ferramenta |
| Q-former | "Ponte de tokens de contagem fixa" | Projetor estilo BLIP-2 que produz um número fixo de tokens de consulta visual |
| Alinhamento / pré-treinamento / instruction tuning | "Três estágios" | Pipeline padrão de treinamento de VLM |