Paper · 2023-06-08 · cs.CV
Video-ChatGPT: Towards Detailed Video Understanding via Large Vision and Language Models
Video-ChatGPT feeds frames through a frozen CLIP ViT-L/14 encoder, pools them into temporal and spatial tokens, and maps them into Vicuna-7B with one trainable linear layer. That layer is tuned on 100K video-instruction pairs from human and GPT-assisted annotation. Author-reported: 2.40 correctness on a 1-5 GPT-judged benchmark, the top score among the compared video chat models.
Multimodal language modelVisual instruction tuningVision Transformer (ViT) backbonesvideomultimodalvision-languageinstruction-tuningevaluation
arXivPDFCodeMarkdown10 min read
AI-compiled by claude-haiku-5-5 on 2026-10-18, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
Language models that chat well can read text but cannot watch a video. This paper gives one such model a view of the video. A standard image model looks at each frame, its output is condensed into a short list of vectors, and a single simple layer translates those vectors into the chatbot's own input format. The chatbot is then trained on a set of about 100,000 questions and answers about videos. Some were written by people and some were generated with other AI tools.
The authors also propose a way to grade video chat answers. Another AI model acts as the judge and scores answers on aspects such as correctness, level of detail and consistency.
TL;DR
- Video-ChatGPT = frozen CLIP ViT-L/14 frame encoder, spatiotemporal pooling, one trainable linear projection, Vicuna-7B language model §3.1 fig. 1.
- Only the projection is trained, on 100K video-instruction pairs §3.2 §4 §5.1.
- The paper also proposes a GPT-3.5-judged benchmark with five aspects, plus zero-shot video QA §5.2.
- All numbers are author-reported. The judge is a closed API model.
Problem
Image-based vision-language models are the usual base for multimodal chat, but they generally do not consider video input §1. Training a video model from scratch needs video-caption data that is scarce, and substantial compute §3. The paper also notes that no quantitative benchmark existed for judging video conversation models §1.
Method
Overview
The model starts from LLaVA, which joins a CLIP image encoder to Vicuna and is trained on generated instruction data §3 fig. 1. Video-ChatGPT adapts that design to video: the encoder runs on every frame, and the frame features are pooled along two axes. The result is a fixed-layout token sequence with a temporal part and a spatial part. The encoder and language model stay frozen. Only the linear projection learns §3.1 §3.2.
Steps
- Frame encoding. Each of the T frames is encoded independently by CLIP ViT-L/14 into an h x w grid of D-dimensional patch features, with patch size p = 14 and h = H/p, w = W/p §3.1. The grid has N = h x w patches.
- Temporal tokens. Average over the spatial grid, giving one vector per frame (T vectors of size D) §3.1.
- Spatial tokens. Average over frames, giving one vector per patch position (N vectors of size D) §3.1.
- Concatenation. Stack temporal and spatial tokens into the video feature matrix of shape (T+N) x D §3.1 eq. 1.
- Projection. A single trainable linear layer g maps each row into the language model's embedding space of width K §3.1 eq. 2. The paper calls g an adapter and says more complex designs are possible §3.1.
- Concatenation with text. The projected video tokens are concatenated with the embedded text query, whose length is L, and fed to the language model §3.1.
- Instruction tuning. The prompt has the form
USER: <Instruction> <video tokens> Assistant:. The loss is the autoregressive likelihood of the answer tokens. Only g is updated §3.2.
# Build video tokens for one clip [§3.1] [eq. 1] [eq. 2]
# Input: frames (T, H, W, 3)
# Output: video tokens (T+N, K) in the language model's embedding space
def encode_video(frames):
# Frozen CLIP ViT-L/14 patch features per frame [§3.1]
frame_features = clip_vit_l14(frames) # (T, h, w, D)
# Average over the spatial grid: one vector per frame [§3.1]
temporal_tokens = mean(frame_features, over=(h, w)) # (T, D)
# Average over frames: one vector per patch position [§3.1]
spatial_tokens = mean(frame_features, over=T) # (N, D)
# Stack both kinds of tokens [§3.1] [eq. 1]
video_features = concat(temporal_tokens, spatial_tokens) # (T+N, D)
# Single trainable linear layer g [§3.1] [eq. 2]
return linear_g(video_features) # (T+N, K)# One instruction-tuning step [§3.2]
# Frozen: CLIP encoder, language model. Trained: linear layer g only.
# Input: frames, instruction text, answer text
def training_step(frames, instruction, answer):
# Prompt template: USER: <instruction> <video tokens> Assistant: [§3.2]
text_tokens = tokenize(instruction)
video_tokens = encode_video(frames)
prompt = concat(text_tokens, video_tokens)
# Next-token loss on the answer tokens [§3.2]
return cross_entropy(language_model(prompt, answer), answer)Data: video instruction pairs
The dataset has 100,000 video-instruction pairs §4. Two annotation routes are used, and they are mixed in the final set §5.3.
- Human-assisted. Annotators enrich ActivityNet-200 ground-truth captions with appearance, spatial and temporal details §4.1 fig. 2. The paper describes the annotators as being told to neutralise tone and bias §10.
- Semi-automatic. BLIP-2 produces frame captions, GRiT produces dense captions for objects, and Tag2Text produces tags for each key frame §4.2 fig. 3. Dense captions are kept only when their vocabulary words agree with the Tag2Text tags. GPT-3.5 then merges the frame captions into one video-level caption and drops details that are inconsistent across frames §4.2 fig. 4.
- GPT-assisted post-processing. GPT-3.5, prompted with in-context examples, writes question-answer pairs covering detailed descriptions, summaries, creative tasks and conversation §4.3.
# Keep a dense frame caption only when it agrees with the frame's tags [§4.2]
# Input: dense_caption (text), tags (set of strings)
# Output: filtered caption text, or nothing when it is dropped
def keep_dense_caption(dense_caption, tags):
# Only the words before the first colon are checked
# [code: data/generate_instruction_qa_semi_automatic.py#L33]
caption_words = split_words(before_first_colon(dense_caption))
# Keep only the words that belong to the tag vocabulary
# [code: data/generate_instruction_qa_semi_automatic.py#L35]
vocab_words = [w for w in caption_words if w in tag_vocabulary]
# Drop the caption if any kept word is missing from the tags
# [code: data/generate_instruction_qa_semi_automatic.py#L37]
if all(w in tags for w in vocab_words):
return join(vocab_words)
return nothingHyperparameters
| Name | Value | Where | Notes |
|---|---|---|---|
| Visual encoder | CLIP ViT-L/14, frozen | §3.1 save_spatio_temporal_clip_features.py | Features are precomputed offline in training. |
| Patch size p | 14 | §3.1 | Stated in text. |
| Patch grid N | 256 for 224 x 224 input | save_spatio_temporal_clip_features.py | Paper gives N = h x w but does not state the input size. Derived from code. |
| Visual feature width D | 1024 | video_chatgpt.py | Paper does not state D. |
| Feature layer | Penultimate hidden layer, CLS token removed | save_spatio_temporal_clip_features.py | Not stated in paper. |
| Frames per video | Up to 100, uniformly sampled | save_spatio_temporal_clip_features.py save_spatio_temporal_clip_features.py | Not stated in paper. Shorter videos give fewer frames. |
| Frame resolution | 224 x 224 | save_spatio_temporal_clip_features.py | Not stated in paper. |
| Temporal token count | Zero-padded to 100 | save_spatio_temporal_clip_features.py | Not stated in paper. |
| Total visual tokens | 356 (100 temporal + 256 spatial) | train.py | Hard-coded in the dataset class. |
| Projection g | One linear layer, with bias | §3.1 eq. 2 video_chatgpt.py | Bias is set by the nn.Linear default. Paper does not mention a bias. |
| Language model | Vicuna-v1.1, 7B, initialised from LLaVA weights | fig. 1 train_video_chatgpt.md | |
| Training data | 100K video-instruction pairs; 30% human, 70% semi-automatic | §4 §5.3 | |
| Epochs | 3 | §5.1 train_video_chatgpt.md | |
| Learning rate | 2e-5 | §5.1 train_video_chatgpt.md | |
| Overall batch size | 32 | §5.1 train_video_chatgpt.md | 4 per GPU on 8 GPUs. |
| Hardware and time | 8 x A100 40GB, about 3 hours | §5.1 | |
| Training precision | bf16 | train_video_chatgpt.md | Not stated in paper. |
| Weight decay | 0 | train_video_chatgpt.md | Not stated in paper. |
| Warmup ratio | 0.03 | train_video_chatgpt.md | Not stated in paper. |
| LR schedule | Cosine | train_video_chatgpt.md | Not stated in paper. |
| Optimizer | AdamW (torch) | train.py | Not stated in paper. |
| Max sequence length | 2048 | train_video_chatgpt.md | Not stated in paper. |
| Inference precision | FP16 | §5.1 model_utils.py | |
| Inference decoding | Sampling, temperature 0.2, max 1024 new tokens | single_video_inference.py | Not stated in paper. |
| Keyframe extraction | Katna | §5.1 | Not in the repository. |
| Tag2Text | Swin-B, 384 x 384 input, confidence threshold 0.7 | §5.1 | Not in the repository. |
| GRiT | ViT-B with CenterNet2 | §5.1 | Not in the repository. |
| Benchmark scoring model | GPT-3.5, 1-5 scale | §5.2 evaluate_benchmark_1_correctness.py | Code uses model gpt-3.5-turbo with a 0-5 integer scale. See Paper vs code. |
| Ablation scoring model | Vicuna-1.5 (13B) | §5.3 tab. 4 |
Results
Author-reported. Setup: a test set based on ActivityNet-200, with dense captions and QA pairs from human annotations §5.2. Judge: GPT-3.5 §5.2. All models are 7B variants tab. 1 tab. 2.
Video-based generative benchmark (1-5 scale, higher is better) tab. 1
| Evaluation aspect | Video Chat | LLaMA Adapter | Video-LLaMA | Video-ChatGPT |
|---|---|---|---|---|
| Correctness of information | 2.23 | 2.03 | 1.96 | 2.40 |
| Detail orientation | 2.50 | 2.32 | 2.18 | 2.52 |
| Contextual understanding | 2.53 | 2.30 | 2.16 | 2.62 |
| Temporal understanding | 1.94 | 1.98 | 1.82 | 1.98 |
| Consistency | 2.24 | 2.15 | 1.79 | 2.37 |
Zero-shot question answering (accuracy in %, and score on a 1-5 scale) tab. 2
| Model | MSVD-QA acc / score | MSRVTT-QA acc / score | TGIF-QA acc / score | ActivityNet-QA acc / score |
|---|---|---|---|---|
| FrozenBiLM | 32.2 / -- | 16.8 / -- | 41.0 / -- | 24.7 / -- |
| Video Chat | 56.3 / 2.8 | 45.0 / 2.5 | 34.4 / 2.3 | 26.5 / 2.2 |
| LLaMA Adapter | 54.9 / 3.1 | 43.8 / 2.7 | - / - | 34.2 / 2.7 |
| Video-LLaMA | 51.6 / 2.5 | 29.6 / 1.8 | - / - | 12.4 / 1.1 |
| Video-ChatGPT | 64.9 / 3.3 | 49.3 / 2.8 | 51.4 / 3.0 | 35.2 / 2.8 |
Ablation: training data mix (same benchmark as tab. 1) tab. 3
| Metric | Human only (30%) | Automatic only (70%) | Combined |
|---|---|---|---|
| Correctness | 2.27 | 2.35 | 2.40 |
| Detail orientation | 2.49 | 2.49 | 2.52 |
| Contextual understanding | 2.50 | 2.56 | 2.62 |
| Temporal understanding | 1.85 | 1.92 | 1.98 |
| Consistency | 2.21 | 2.38 | 2.37 |
| Average | 2.28 | 2.34 | 2.38 |
Ablation: open-source judge (Vicuna-1.5 13B as the judge) tab. 4
| Metric | Video Chat | Video-LLaMA | Video-ChatGPT |
|---|---|---|---|
| Correctness | 2.32 | 2.10 | 2.49 |
| Detail orientation | 2.50 | 2.18 | 2.52 |
| Contextual understanding | 2.76 | 2.41 | 2.85 |
| Temporal understanding | 2.27 | 2.17 | 2.38 |
| Consistency | 2.95 | 2.67 | 3.09 |
The paper reports no variance, seeds or significance tests for these numbers.
Qualitative examples are described in §11 and shown in fig. 5 to fig. 11. The paper does not give them numerical results.
Paper vs code
Code: official repository at commit 8d54ebf README.md. The paper
links the repository in its abstract.
- Frame count and sampling. Paper does not state how many frames are used §3.1. Code samples at most 100 frames, at the midpoints of equal segments save_spatio_temporal_clip_features.py save_spatio_temporal_clip_features.py. Inference uses the same rule model_utils.py model_utils.py.
- Temporal tokens are padded to 100. The paper's token count is T+N §3.1 eq. 1. Code zero-pads the temporal tokens to 100 before the projection save_spatio_temporal_clip_features.py single_video_inference.py. The padded slots pass through the projection, so they become the projection's bias vector rather than zeros. Training fixes the total at 356 train.py.
- Start and end tokens. The paper's prompt template has no boundary tokens
§3.2. Code wraps the visual tokens in
<vid_start>and<vid_end>single_video_inference.py train_video_chatgpt.md. Their embeddings are initialised to the mean of the existing embeddings video_chatgpt.py. - Which parameters train. The paper says only the linear layer is trained
§3.2. With
--tune_mm_mlp_adapter Trueand--mm_use_vid_start_end, the code also marks the whole input embedding matrix as trainable video_chatgpt.py train_video_chatgpt.md. The forward pass detaches most text embeddings in the video path video_chatgpt.py, so the gradient in practice seems to reach only the boundary-token rows. This is inferred from reading the code and was not run. - Question placement in training data. The paper's template puts the
instruction before the video tokens §3.2. The conversion script alternates
the question before and after
<video>by example index convert_instruction_json_to_training_format.py. Inference puts the video tokens after the question single_video_inference.py. - Conversation template. Training uses
vicuna_v1_1train.py with the system prompt in video_conversation.py. Inference defaults tovideo-chatgpt_v1with a different system prompt single_video_inference.py video_conversation.py. - Scoring scale. Paper says 1-5 §5.2. The correctness prompt asks for an integer from 0 to 5 evaluate_benchmark_1_correctness.py. The ActivityNet-QA prompt asks for a yes/no and a 0-5 score evaluate_activitynet_qa.py.
- Semi-automatic filter. Paper says captions containing words outside the tag set are removed §4.2. Code returns only the tag-vocabulary words from the part of the caption before the first colon generate_instruction_qa_semi_automatic.py. It does not return the original caption.
- Dataset and prompts. Paper says the dataset and prompts "will be made publicly available" §4.2. The repository does not contain them; the docs link external download locations train_video_chatgpt.md.
- Evaluator model. Paper says GPT-3.5 §5.2. Code calls
gpt-3.5-turboevaluate_benchmark_1_correctness.py. No dated snapshot is pinned.
No discrepancies found in: the projection formula, the mean pooling directions, the learning rate, the epoch count, or the overall batch size of 32.
Pitfalls
- Frame budget is not in the paper. The 100-frame cap, the segment-midpoint sampling and the 224 x 224 resize all come from code. Implement them from the code, or your features will not match the released weights.
- Padding changes the layout. Zero-padding the temporal tokens to 100 happens before the projection. Implementations that pad after projection get different vectors.
- Layer choice matters. The features come from the penultimate CLIP layer with the CLS token dropped save_spatio_temporal_clip_features.py. Using the final layer or keeping CLS is a silent change.
- Boundary tokens and template. Training and inference use different system prompts and different question placement (see Paper vs code). Pick one convention and apply it at both ends.
- Trainable parameters. The paper's claim that only the projection trains does not hold for the code's configuration (see Paper vs code). Decide explicitly whether the embedding matrix is trainable.
- The judge is a closed model. Tables 1 and 2 rely on GPT-3.5 §5.2. The ablation with Vicuna-1.5 13B shows the same ordering tab. 4, but absolute scores move (for example Video-ChatGPT correctness is 2.40 in tab. 1 and 2.49 in tab. 4). Compare numbers only under the same judge.
- Small score gaps. Differences of a few hundredths on a 1-5 judge scale are reported without variance. For example the temporal-understanding row in tab. 1 is a tie at 1.98 between Video-ChatGPT and LLaMA Adapter.
- Blind-test result is near chance. The human-versus-automatic QA test used 50 videos and reached 52% §5.3. That is close to 50%, the chance level for a two-way choice. The paper reads it as evidence the automatic data is reliable.
- Inference setup is unstated in the paper. Sampling at temperature 0.2, FP16 and up to 1024 new tokens come from code only single_video_inference.py.
- Long videos and small objects. The authors report difficulty with subtle temporal relations in videos longer than two minutes and with small-object details §7.
- Cost. Training took about 3 hours on 8 A100 40GB GPUs §5.1. Data generation depends on GPT-3.5 and three off-the-shelf captioning or tagging models §4.2.
- Data licence. The paper says the dataset is built on ActivityNet, which it describes as MIT-licensed, and that the authors will release their data under MIT §9. We have not verified those terms, and the videos are not in this repository.
Lineage
- Builds on: LLaVA, "Visual Instruction Tuning" [arXiv:2304.08485], which supplies the CLIP-plus-Vicuna design and the initial weights §3 fig. 1.
- Compared against: Video Chat, LLaMA Adapter and Video-LLaMA, and FrozenBiLM for zero-shot QA §5.2 tab. 1 tab. 2.
Source and license
Adapted from “Video-ChatGPT: Towards Detailed Video Understanding via Large Vision and Language Models” by Muhammad Maaz, Hanoona Rasheed, Salman Khan, Fahad Shahbaz Khan (arXiv:2306.05424), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/mbzuai-oryx/Video-ChatGPT at commit 8d54ebfcb049 (CC BY 4.0). Any quoted code is shown under that license.