Cheat sheets

Vision-Language Model Architectures

ViT, bridge, LLM. Projector, Q-Former, Perceiver, gated cross-attention, training stages and recipe numbers.

  • Concepts and terms
  • Tasks and commands
  • Annotated code
  • Diagrams
  • Defaults and numbers
  • Troubleshooting
  • Questions and tips

Source

The ViT-MLP-LLM pattern#

(N, d_vit)(N, d_llm)clientImageH x W x 3modelVision encoderCLIP-L, SigLIP,DINOv3processProjector2-4 layer MLP orQ-formerclientText promptprocessLLM tokenizertext tokens (M,d_llm)processInterleave orconcatimage tokens inLLM spacemodelDecoder LLMgenerates thetext answer(N, d_vit)(N, d_llm)clientImageH x W x 3modelVision encoderCLIP-L, SigLIP,DINOv3processProjector2-4 layer MLP orQ-formerclientText promptprocessLLM tokenizertext tokens (M,d_llm)processInterleave orconcatimage tokens in LLMspacemodelDecoder LLMgenerates the textanswer

From Lesson 04.25

Bridge mechanisms#

MLP projector
Linear, GELU, Linear. Maps (N_patches, d_vit) to (N_patches, d_llm).
Q-Former
32 learnable queries cross-attend to frozen ViT patches. Output is 32 visual tokens.
Perceiver resampler
K = 64 learnable latents. Any patch count exits as 64 tokens.
Gated cross-attention
y = \tanh(\alpha) \cdot \mathrm{cross} + x. Alpha starts at 0.
Cross-attention
Q comes from the text stream. K and V come from the image stream.
Cosine alignment loss
1 - \cos(\mathrm{image}, \mathrm{text}). 0 is aligned, 2 is opposite.
DeepStack
stacks features from several ViT depths, not the last layer only.
CMER
share of outputs with high text confidence and low image-text similarity.

From Lesson 04.25, Lesson 12.03, Lesson 12.04, Lesson 19.60, Lesson 19.61

Three training stages#

1Alignmentfreeze ViT and LLM. Train only the projector onimage-caption pairs.2LLaVA stage 1558k image-caption pairs, LM loss on thecaption, a few hours.3Pre-trainingunfreeze everything. Train on 500M+ interleavedimage-text pairs.4Instruction tuningfine-tune on (image, question, answer) triples.5LLaVA stage 2projector and LLM train on 158kvisual-instruction turns.

From Lesson 04.25, Lesson 12.05

Tasks in code#

TaskCode
Build a projectorProjector(vit_dim=768, llm_dim=4096, hidden=4096)
Stack ViT depthsdeepstack_features(per_layer_features)
Measure CMERcross_modal_error_rate(image_emb, text_emb, text_confidence)
Resample patches to fixed latentsperceiver_resampler(patches, num_latents=8, num_blocks=2)
Gated step, closed gategated_cross_attention_step(text_hidden, visual, alpha=0.0)
One image per text tokeninterleaved_mask(seq)
LLaVA prompt with 576 tokensbuild_llava_prompt(system, user, image_tokens=576)
Self-attention maskcausal_mask(length)

From Lesson 04.25, 04.25 code/main.py, 12.04 code/main.py, 12.05 code/main.py, 19.61 code/main.py

Merge image tokens into the text#

vision_tokens = self.vit(image)(B, N_patches, d_vit)
vision_embeds = self.projector(vision_tokens)(B, N_patches, d_llm)
text_embeds = self.llm.get_input_embeddings()(input_ids)(B, M, d_llm)
out = text_embeds.clone()copy, then fill
for b in range(input_ids.size(0)):one sample at a time
positions = (input_ids[b] == self.image_token_id).nonzero(as_tuple=True)[0]
out[b, positions] = vision_embeds[b]<image> slots get vision

From Lesson 04.25

Train only the projection#

cfg = AlignConfig()768 -> 1024 -> 512, 200 steps
encoder = VisionEncoder(encoder_cfg).eval()
freeze(encoder)requires_grad_(False)
projector = MLPProjector(cfg.vision_hidden, cfg.projection_hidden, cfg.text_hidden)
with torch.no_grad():
_, cls = encoder(img)CLS pool, no encoder grads
text_emb = text(ids)frozen MockTextEmbedding
image_emb = projector(cls)
loss = cosine_alignment_loss(image_emb, text_emb)

From 19.60 code/main.py

Bridge numbers#

SettingDefaultNote
Q-Former queries32188M trained params in BLIP-2
Perceiver latents K64After 6 resampler blocks
Gated block every M layers4Flamingo, alpha init 0
LLaVA tokens per image57624x24 grid, MLP 1024 → 4096 → 4096
AnyRes tokens per image2880Tiles of 336x336 plus a thumbnail
Token sweet spot576-102464 is too few for OCR
Dynamic resolutionmin 256, max 1280Pixels per long side

From Lesson 12.03, Lesson 12.04, Lesson 12.05, Lesson 12.07

Troubleshooting#

SymptomCauseFix
ValueError on image tokensPlaceholder count differs from patchesPre-pad each sample to the same count
Confident wrong objects12% of crawled pairs are not groundedTrack CMER, route high CMER to review
Above, below, count wrongVLMs score 50-60% on spatial testsUse a pose, depth or detection model
Text skill drops after tuningThe gate got too wide too fastStart alpha at 0, check the gate schedule
Weak OCRToo few visual tokensUse 576-1024 tokens or AnyRes
Context fills fast576 tokens per image, more per frameUse a Q-Former at 32 tokens

From Lesson 04.25, Lesson 12.04, Lesson 12.07, Lesson 12.03, Lesson 19.61

Abbreviations#

VLM
Vision-Language Model. Image encoder plus a full language model.
ITC
image-text contrastive. CLIP-style loss on pooled queries and text CLS.
ITM
image-text matching. Binary classifier on hard negatives.
ITG
image-grounded text generation. Causal LM loss on the queries.
CMER
Cross-Modal Error Rate. The hallucination KPI.
AnyRes
split a high-res image into tiles and concatenate their tokens.

From Lesson 04.25, Lesson 12.03, Lesson 12.05, Lesson 19.61

Questions#

Q-Former or MLP?
Q-Former when token budget matters. MLP when quality per token matters.
BLIP-2 or Flamingo?
BLIP-2 for single-image VQA on a budget. Flamingo for few-shot and many images.
Why init alpha at 0?
At step 0 the model is the pretrained LLM on text.
Why no mask on cross-attention?
The whole image is visible before any text.
Why two layers, not one?
GELU gives one non-linear bend. One linear layer only rotates and scales.
What to ablate first?
Visual-token count explains ~60% of variance. Encoder ~20%. Connector ~5%.

From Lesson 12.03, Lesson 12.04, Lesson 12.07, Lesson 19.61, Lesson 19.60

Default open-VLM recipe#

  • Encoder: SigLIP 2 SO400m/14. Add DINOv2 ViT-g/14 for segmentation or grounding.
  • Connector: 2-layer MLP on patch tokens. Skip Q-Former unless you are token-constrained.
  • LLM: 7B for cost, 70B for quality. LLM size sets the ceiling.
  • Data: PixMo + ShareGPT4V + Cauldron. Dense human captions beat distillation.
  • Train Stage 1 at 384 fixed. Ramp to dynamic resolution up to 1280 for OCR.
  • Swap the encoder before the connector. SigLIP over CLIP added 3+ points MMMU.

From Lesson 12.07