LLaVA and Visual Instruction Tuning
LLaVA (April 2023) became the template most open vision-language models copied. It replaced BLIP-2's Q-Former with a 2-layer MLP, replaced Flamingo's gated cross-attention with plain token concatenation, and trained on 158k visual-instruction turns that GPT-4 wrote from text-only captions. LLaVA-1.5 added academic-task data, LLaVA-NeXT added AnyRes, and LLaVA-OneVision folded image, multi-image, and video into one recipe. This lesson reads the recipe, builds the projector, and looks at why the simple design won.
Learning Objectives
- Build a 2-layer MLP projector that maps ViT patch embeddings (dim 1024) to an LLM's embedding dim (dim 4096).
- Walk the LLaVA two-stage recipe: (1) projector alignment on 558k caption pairs, (2) visual instruction tuning on 158k GPT-4-generated turns.
- Construct a LLaVA-format prompt with the image token placeholder, system prompt, and user/assistant turns.
- Explain why the community moved from Q-Former to MLP despite Q-Former's token-budget win.
The Problem
BLIP-2's Q-Former (Lesson 12.03) compresses an image to 32 tokens. It is clean, efficient, and good on benchmarks. It also has two problems.
First, the Q-Former is trainable but its loss is not the final task. Stage 1 trains ITC+ITM+ITG and stage 2 trains LM loss, so the queries learn an intermediate representation that the LLM then has to decode. Information gets lost in the bottleneck.
Second, the Q-Former has 188M params and has to be co-designed with the target LLM. Change the LLM and you retrain the Q-Former. Change the vision encoder and you retrain it again. Every combination becomes its own R&D project.
LLaVA's answer was almost embarrassingly simple. Take the ViT's 576 patch tokens, pass each through a 2-layer MLP (1024 → 4096 → 4096), and put all 576 into the LLM's input sequence. There is no bottleneck and no stage-1 pretraining on odd objectives. You train the MLP on a direct LM loss.
The data came from a second insight: use text-only GPT-4 to generate the instructions. Feed it the COCO captions and bounding boxes for an image, and ask for conversations, descriptions, and complex reasoning questions. That gives 158k instruction-response turns with no human annotation.
The result was a VLM that trained in about a day on one 8xA100 node and shipped as an open checkpoint the community could extend. Many forks followed.
The Concept
The architecture
LLaVA-1.5 at 7B:
- Vision encoder: CLIP ViT-L/14 @ 336 (frozen during stage 1, optionally unfrozen stage 2).
- Projector: 2-layer MLP with GELU activation,
1024 → 4096 → 4096. - LLM: Vicuna-7B (later Llama-3.1-8B).
Forward pass on an image + text prompt:
img -> ViT -> 576 patches of dim 1024
patches -> MLP -> 576 tokens of dim 4096
prompt: system + "<image>" placeholder + user question
replace <image> token with the 576 projected tokens
feed the full sequence to the LLM
decode response
The image occupies 576 tokens of the LLM context. At 2048 context, that leaves 1472 tokens for text. At 32k context, it is a rounding error.
Stage 1: projector alignment
Freeze ViT. Freeze LLM. Train only the 2-layer MLP. Dataset: 558k image-caption pairs (LAION-CC-SBU). Loss: language modeling on the caption, conditioned on the projected image tokens.
A single epoch at batch 128 takes a few hours. The projector learns to map ViT space into LLM space, with no task-specific supervision.
Stage 2: visual instruction tuning
Unfreeze the projector (still trainable). Unfreeze the LLM (usually fully, sometimes LoRA). Train on 158k visual-instruction turns.
The instruction data is the trick. Liu et al. generated it by:
- Take a COCO image.
- Extract the text description (5 human captions + bounding-box list).
- Send to GPT-4 with three prompt templates:
- Conversation: "Generate a back-and-forth dialogue between a user and assistant about this image."
- Detailed description: "Give a rich, detailed description of the image."
- Complex reasoning: "Ask a question that requires reasoning about the image, then answer it."
- Parse GPT-4's output into (instruction, response) pairs.
GPT-4 never sees the image, only the text description, so it invents plausible image content. That adds some noise, but 158k turns was enough to unlock dialogue.
Why the community copied this
- No stage-1-specific losses to tune. LM loss throughout.
- Projector trains in hours, not days.
- LLM can be swapped (LLaVA-Llama2, LLaVA-Mistral, LLaVA-Llama3) by retraining just the projector.
- Visual-instruction data pipeline uses GPT-4 and is cheap to regenerate for a new domain.
LLaVA-1.5 and LLaVA-NeXT
LLaVA-1.5 (October 2023) added:
- Academic-task data (VQA, OKVQA, RefCOCO) mixed into instruction tuning.
- Better system prompt.
- 2048 → 32k context.
LLaVA-NeXT (January 2024) added:
- AnyRes: split high-res images into a 2x2 or 1x2 grid of 336x336 crops, plus one global low-res thumbnail. Each crop becomes 576 tokens; total around 2880 visual tokens per image. OCR and chart tasks improved a lot.
- Better instruction data mixture with ShareGPT4V (high-quality GPT-4V captions).
- Stronger base LLMs (Mistral-7B, Yi-34B).
LLaVA-OneVision
Lesson 12.08 covers OneVision in depth. Short version: same projector, but trained with a curriculum that covers single-image, multi-image, and video in one model with shared visual-token budget.
The comparison to Q-Former
| Q-Former (BLIP-2) | MLP (LLaVA) | |
|---|---|---|
| Visual tokens per image | 32 | 576 (base) or 2880 (AnyRes) |
| Trainable params | 188M + LM | ~21M + LM |
| Stage 1 loss | ITC+ITM+ITG | LM only |
| LLM drop-in | Requires retrain | Swap with minimal retrain |
| Multi-image | Awkward | Natural (concat) |
| Video | Awkward | Natural (per-frame concat) |
| Token budget | Small | Large |
MLP wins on simplicity and token flexibility. Q-Former wins on token budget. By late 2023 the token budget was no longer the binding constraint (LLM contexts grew to 32k-128k+) and simplicity dominated.
The prompt format
A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions. USER: <image> Describe this image in detail. ASSISTANT: The image shows ...
<image> is a placeholder token. Before tokenization, it is replaced with the 576 visual tokens (or 2880 with AnyRes). The LLM sees a longer sequence than plain text would give it, and it copes because stage 1 taught it what projected image tokens look like.
Parameter economy
LLaVA-1.5-7B breakdown:
- CLIP ViT-L/14 @ 336: 303M (frozen stage 1, often unfrozen stage 2).
- Projector (2x linear): ~21M trainable.
- Llama-7B: 7B.
- Total: 7.3B params. Trainable during stage 2: full 7B + 21M projector.
Training cost for stage 2: ~20 hours on 8xA100. This is the number that matters: one day, one node, reproducible. That is a big part of why LLaVA spread.
Use It
code/main.py is a stdlib-only walkthrough of the forward pass, with no training. It has three demos:
- The 2-layer MLP projector at toy scale (16 patches of dim 16, mapped
16 → 32 → 24), with random weights, GELU written by hand, and a printed parameter count. - A prompt builder. It writes the system prompt, a
<image>placeholder, the user turn, and an empty assistant slot, then reports how many visual tokens the placeholder stands for (576). It does not splice real embeddings in. - A context-budget printout showing what share of a 2k, 8k, 32k, and 128k window the visual block takes, followed by an AnyRes table that prints the visual token count for five tile grids.
Ship It
This lesson produces outputs/skill-llava-vibes-eval.md. Given a LLaVA-family checkpoint, it runs a 10-prompt vibes-eval suite (3 captioning, 3 VQA, 2 reasoning, 2 refusal) and reports a human-readable scorecard. It is a smoke test for whether the projector and LLM are connecting, not a benchmark.
I'd run main.py first and read the AnyRes table before anything else. Exercise 3 asks for the token count of a 1344x672 image, and the table has a row for that grid, so you can check your arithmetic against it. Then compare the 2x2 row to the roughly 2880 tokens quoted for LLaVA-NeXT above. Counting the thumbnail is the part people forget.
Keep in mind how little the script does. The projector weights are random and nothing trains, so stage 1 and stage 2 exist only in the prose. The prompt builder returns a string with <image> in it and a number for how many tokens that placeholder expands to. If you want to feel the recipe, the next step is to splice the projected tokens into a real LLM's embedding sequence at the placeholder position and run the alignment loss on a handful of captions.
My bet is that the context-budget printout is the best argument for the MLP over the Q-Former. At a 2k window the visual block takes a large share of the sequence. At 32k or 128k it barely registers, and that shift is what made the extra tokens affordable.
Exercises
-
Compute the trainable-parameter count for the 2-layer MLP projector at
1024 → 4096 → 4096. With GELU and bias, what fraction of LLaVA-1.5-7B does it represent? -
Construct a LLaVA prompt for a "refusal" case where the image contains a private individual. Write the expected assistant response. Why should LLaVA refuse this zero-shot and what training data would be needed to reinforce the refusal?
-
Read the AnyRes section of the LLaVA-NeXT blog. Compute the visual token count for a 1344x672 image at AnyRes. Compare to base 576 tokens at 336x336.
-
The LLaVA stage-1 projector is trained with LM loss on captions. What happens if you skip stage 1 and go straight to stage 2 (visual instruction tuning)? Cite the Prismatic VLMs ablation (arXiv:2402.07865) for the answer.
-
LLaVA-Instruct-150k uses GPT-4 with COCO captions to generate instructions. For a new domain (medical X-rays, satellite imagery), describe the four-step data pipeline to generate domain instructions. What could go wrong at each step?
Key Terms
| Term | What people say | What it actually means |
|---|---|---|
| Projector | "MLP bridge" | 2-layer MLP with GELU mapping ViT dim to LLM dim |
| Image token | " placeholder" | Prompt marker replaced by N projected visual tokens before inference |
| Visual instruction tuning | "LLaVA stage 2" | Training on GPT-4-generated (image, instruction, response) triplets |
| Stage 1 alignment | "Projector pretraining" | Freeze ViT and LLM, train projector with LM loss on captions |
| AnyRes | "Multi-crop tiling" | Split high-res image into a tile grid and concatenate each tile's visual tokens |
| LLaVA-Instruct | "GPT-4-generated" | 158k instruction-response pairs synthesized from COCO captions + GPT-4 |
| Vision encoder freeze | "Backbone locked" | CLIP weights do not update in stage 1, sometimes not in stage 2 either |
| ShareGPT4V | "Better captions" | 1M dense captions generated by GPT-4V, used for higher-quality alignment |
| VQA | "Visual question answering" | Task of answering a free-form question about an image |
| Prismatic VLMs | "Design-space paper" | Karamcheti 2024 ablation systematically testing projector and data choices |
Further Reading
- Liu et al.: Visual Instruction Tuning (arXiv:2304.08485): the LLaVA paper.
- Liu et al.: Improved Baselines with Visual Instruction Tuning (arXiv:2310.03744): LLaVA-1.5.
- Chen et al.: ShareGPT4V (arXiv:2311.12793): dense captions dataset.
- Karamcheti et al.: Prismatic VLMs (arXiv:2402.07865): design-space ablations.
- Li et al.: LLaVA-OneVision (arXiv:2408.03326): unified single-image, multi-image, video.
Code
- main.py (python, 165 lines)