Video-Language Models: Temporal Tokens and Grounding
Video is not a stack of photos. A 5-second clip has causal ordering, action verbs, and event timing that an image model cannot represent. Video-LLaMA (Zhang et al., June 2023) shipped the first open video-LLM with audio-visual grounding, and VideoChat and Video-LLaVA scaled the pattern. By 2025 Qwen2.5-VL's TMRoPE had closed much of the gap with frontier proprietary models. Each system handles temporal tokens differently: a Q-former per clip, concat-pool per frame, TMRoPE per token. This lesson reads those patterns, builds a uniform and a dynamic frame sampler, and scores temporal grounding with IoU.
Learning Objectives
- Explain why temporal positional encoding changes video VLM performance independently of the vision encoder.
- Compare uniform, dynamic-FPS, and event-driven frame sampling on tokens-per-second vs grounding accuracy.
- Describe Q-former-per-clip (Video-LLaMA) vs pooled-per-frame (Video-LLaVA) vs M-RoPE-per-token (Qwen2.5-VL) designs.
- Name the four video benchmarks: VideoMME, TempCompass, EgoSchema, Video-MMMU.
The Problem
A 1-minute video at 30 FPS is 1800 frames. At 196 visual tokens per frame (ViT-B at 224), that is 352k tokens, more than most 2024-era LLMs could take in.
Three reduction strategies exist:
- Subsample frames (1-8 FPS depending on content).
- Pool each frame's patch tokens aggressively (3x3 or 4x4 bilinear pool).
- Compress via a Q-former that takes a 16-frame clip and outputs 64 tokens.
Each one costs you something different. Subsampling loses temporal detail, pooling loses spatial detail, and a Q-former loses a little of both but saves tokens.
Temporal position encoding is the other axis. How does the model know frame 5 came before frame 6? Video-LLaMA uses a simple 1D temporal RoPE, Video-LLaVA uses learned temporal embeddings, and Qwen2.5-VL uses TMRoPE, a full 3D scheme.
The Concept
Video-LLaMA: Q-former per clip + audio branch
Video-LLaMA (2023) was the first open video-LLM. Architecture:
- 16-frame clips at 2 FPS (so 8 seconds).
- Per-frame ViT features -> Video Q-former that cross-attends over all 16 frames -> 32 learned queries -> LLM.
- Parallel audio branch: waveform -> ImageBind audio encoder -> Audio Q-former -> 32 queries -> LLM.
The strength is audio-visual joint reasoning. The weakness is a fixed clip length and no arbitrary time grounding.
VideoChat and Video-LLaVA
VideoChat kept the Video-LLaMA idea but dropped audio and simplified. Video-LLaVA (Lin et al., 2023) trained a single visual encoder on both images and video frames ("alignment before projection"), which gives a unified representation. Both are a frozen CLIP encoder, an MLP, and an LLM.
Neither handles long video. Both are 8-16 frame systems.
Qwen2.5-VL and TMRoPE
Qwen2.5-VL introduced TMRoPE (Temporal-Modality Rotary Position Embedding), where each patch token carries a (t, h, w) position and t is the actual timestamp, not the frame index.
Three things separate it from a simple temporal embedding:
- Absolute time, not index. The model sees "at 4.2 seconds" instead of "at frame 15."
- Per-token rotation, not per-clip. Each visual token rotates independently by its timestamp.
- Compatibility with dynamic FPS. If you sample at 2 FPS here and 4 FPS there, TMRoPE handles the uneven spacing natively.
That is what makes "at what second does the cat jump?" answerable. The model can output "at 4.2 seconds," where Video-LLaMA could only say "early in the clip."
Frame sampling strategies
Uniform: sample N frames evenly over the duration. Simple, but it misses motion peaks.
Dynamic FPS: sample adaptively based on motion intensity. Optical flow or frame differencing picks the high-motion segments for denser sampling. Qwen2.5-VL trains on this.
Event-driven: run a lightweight detector and sample more where action happens. VideoAgent uses this.
Keyframe + context: sample at shot boundaries plus a few adjacent frames. Used for cinematic content.
Pooling per frame
At 1 FPS and 576 tokens per frame, a 5-minute clip is 172,800 tokens. That is more than Qwen2.5-VL-72B's 128k context, so you have to cut it down first, and it is expensive either way.
A 3x3 bilinear pool reduces each frame to 64 tokens, so 5 minutes comes to 19,200 tokens. That is the sweet spot for most tasks.
Pool harder (6x6 -> 16 tokens per frame) for agent workflows, where spatial detail matters less.
The four video benchmarks
- VideoMME: comprehensive video understanding, short + medium + long.
- TempCompass: fine-grained temporal reasoning, "before" / "after" questions.
- EgoSchema: long-horizon first-person video.
- Video-MMMU: multimodal multi-discipline video questions.
A full video-VLM evaluation hits all four because they stress different axes. TempCompass is about ordering, EgoSchema is about reasoning over 3+ minutes, and VideoMME spans durations.
Grounding output formats
Temporal grounding can come out in three formats:
- Free text: "The cat jumps around the 4-second mark." Easy to read but imprecise.
- Structured JSON:
{"event": "jump", "start": 4.1, "end": 4.3}. Qwen2.5-VL trains this. - Token-based: special
<time>4.1</time>tokens interleaved with the answer. This is Qwen2.5-VL's internal format.
Token-based output is the most accurate for downstream use, and Qwen2.5-VL's JSON output parses directly.
2026 best practice
For video VLMs in 2026:
- Encoder: SigLIP 2 with M-RoPE or TMRoPE (Qwen2.5-VL).
- Frame sampling: dynamic FPS (1-4 depending on motion) with a max-frame cap.
- Per-frame pooling: 3x3 bilinear.
- Output: structured JSON with time + event fields.
- Benchmarks: VideoMME + TempCompass for general; EgoSchema for long-horizon.
Use It
code/main.py includes:
- Uniform and dynamic-FPS frame samplers.
- A toy temporal-grounding evaluator: each ground-truth event is matched by name to a predicted event, scored with IoU on the time interval, and counted as a hit at IoU 0.3 or above. It reports recall.
- A printed table comparing Video-LLaMA (16 frames, Q-former), Video-LLaVA (8 frames, MLP), VILA-1.5, Qwen2.5-VL (dynamic FPS + TMRoPE), and LLaVA-OV-1.5 (pool, 32 frames).
Ship It
This lesson produces outputs/skill-video-vlm-frame-planner.md. Given a video task (monitoring, action recognition, temporal grounding, summarization), it picks the frame sampler, pooling factor, output format, and expected accuracy tier.
I'd run main.py before trusting any of the architecture talk above. There is no model in it, only the two samplers and the IoU scorer, and that is enough to see where the real decisions live.
Look at the dynamic sampler output first. I asked for a budget of 12 frames and it returned 15, because max(1, round(raw)) gives every low-motion second at least one sample on top of whatever the high-motion seconds earn. If you need a hard token cap, you have to enforce it after sampling.
The grounding eval is the other thing I'd stare at. With the threshold at IoU 0.3, the turn prediction scores 0.29 and the sit prediction scores 0.27, so recall comes out at 0.33 even though the turn prediction is off by 0.2 to 0.3 seconds and the sit prediction by under a second. Short events punish small timing errors hard. I'd pick the tolerance with the event length in mind before comparing two models on one number.
One caveat: the architecture table in main.py is just printed rows. Nothing there implements a Q-former or TMRoPE, so treat it as a summary of the reading and not as a benchmark.
Exercises
-
For a 3-minute cooking demo, pick uniform vs dynamic FPS. Justify with a token count.
-
TMRoPE adds what specifically that a simple temporal embedding table cannot do?
-
Write a JSON schema for temporal grounding that a VLM can learn to emit. Include error cases.
-
Read Video-LLaVA's Section 3 on "Alignment Before Projection." Why is this better than training separate image and video encoders?
-
Given the VideoMME leaderboard, what is the gap between the top open model and the top proprietary model as of 2026? How much of that gap is attributable to temporal encoding vs base LLM scale?
Key Terms
| Term | What people say | What it actually means |
|---|---|---|
| Temporal grounding | "Time-localized answers" | VLM outputs a specific timestamp range for when an event happens |
| TMRoPE | "Time-Multimodal RoPE" | 3D rotary position with absolute timestamps, used by Qwen2.5-VL |
| Dynamic FPS | "Motion-aware sampling" | Sample more frames in high-motion segments, fewer in static ones |
| Frame pooling | "Spatial compress per frame" | Reduce patches per frame with bilinear interpolation before the LLM |
| Video Q-former | "Clip compressor" | Cross-attention bottleneck mapping N frames to K learned queries |
| VideoMME | "Video bench" | Comprehensive short/medium/long video benchmark, 2500+ samples |
Code
- main.py (python, 142 lines)