TAI BUI
Back to curriculum
LearnPython

Qwen-VL Family and Dynamic-FPS Video

Qwen-VL went through four generations (Qwen-VL in 2023, Qwen2-VL in 2024, Qwen2.5-VL and Qwen3-VL in 2025), and most generations made one architectural bet that other open VLMs went on to copy: native dynamic resolution via M-RoPE, dynamic-FPS sampling with absolute time alignment, window attention in the ViT, and structured agent output. By Qwen3-VL the recipe had settled: a 2D-RoPE ViT encoder taking native-aspect-ratio inputs, an MLP projector into a large Qwen3 language base, and training stages that treat OCR, grounding, and agent behavior as first-class targets. Read the family in order and you can see why each knob sits where it does.

TIME: ~120 minutesPREREQUISITES: Phase 12 · 06 (patch-n'-pack)

Learning Objectives

  • Compute M-RoPE's three-axis rotations (temporal, height, width) and explain why all three are needed.
  • Pick a dynamic-FPS sampling strategy for a video and reason about tokens-per-second vs event-detection accuracy.
  • Name the four Qwen-VL generational upgrades in order and what each enabled.
  • Wire a Qwen2.5-VL-style JSON agent output format and parse structured tool calls from a VLM response.

The Problem

Qwen-VL shipped in August 2023 as a direct response to LLaVA-1.5 and BLIP-2. The gap the Qwen team targeted was threefold: resolution, video, and structured output.

Resolution: LLaVA-1.5 ran at 336x336. Fine for photos, too coarse for a Chinese-language invoice or a dense spreadsheet screenshot. Qwen-VL's first innovation was 448x448 and grounded bounding-box output, letting the model point at things.

Video: Video-LLaMA stacked per-frame encoders and fed them to the LLM. It worked for short clips, not for multi-minute videos where the temporal axis is the signal. The Qwen team wanted a single encoder that understood time.

Structured output: LLaVA emitted free-form text. An agent needs JSON. Qwen-VL trained on explicit JSON output formats including bounding-box coordinates as text.

Each Qwen-VL generation pushes on at least one of these three axes.

Warm-up0/4
1. A batch mixes a 1120x672 screenshot and a 336x336 photo. In patch-n'-pack, how do both go through the encoder in one sequence?Warm-up
A 1120 by 672 screenshot and a 336 by 336 photo, both drawn at relative scale, each with an arrow into a box labelled ViT encoder, one sequence.
Schematic. Sizes are the ones in the stem.
2. Which is a failure mode of resizing every image to a fixed square before encoding?Warm-up
A wide 1120 by 672 screenshot with text lines and a square 336 by 336 photo, with arrows into a box labelled encoder input, N by N square.
Schematic. N is left open on purpose; the stem names no size.
3. Why does a Transformer need positional information added to its token inputs?Warm-up
Two rows of five word tokens, the dog bit the man and the man bit the dog, both arrows going into one box labelled attention, no position added.
Schematic. The two sentences use the same five words in different orders.
4. A model has a fixed context window. You feed it the same video, then again at double the frame rate. What changes?Warm-up
A video timeline with 5 sampled frames at rate r and 10 sampled frames at rate 2r, next to a box labelled context window, fixed size.
Schematic. Frame counts are illustrative; the stem gives only the doubling.
Check: The Problem0/2
1. What three gaps did the Qwen team target with the original Qwen-VL (August 2023)?Define
Three earlier models named LLaVA-1.5, BLIP-2 and Video-LLaMA, with an arrow to a highlighted box reading Qwen-VL, August 2023.
Schematic from the lesson's Problem section.
2. Why did Video-LLaMA's design struggle with multi-minute videos?Explain
Two bars on one scale: a short clip labelled works, and a much longer multi-minute video labelled struggles.
Illustrative scale. The lesson gives no durations.

The Concept

Qwen-VL (August 2023)

The first generation: OpenCLIP ViT-bigG/14 as encoder (2.5B params), LLama-compatible Q-Former (1-step with 256 queries), Qwen-7B base. Contributions:

  • 448x448 resolution (then SOTA for an open VLM).
  • Grounding: trained on image-text pairs with explicit coordinate-token output. "The cat is at (112, 204), (280, 344)".
  • Chinese + English multilingual training from the start.

Benchmarks at the time: competitive with GPT-4V on English, strong on Chinese. The grounding supervision was the real headline.

Qwen2-VL (September 2024): M-RoPE and native resolution

Qwen2-VL replaced the fixed-resolution + Q-Former stack with a natively dynamic-resolution ViT encoder. Key changes:

  • Native dynamic resolution. The ViT accepts any HxW divisible by 28 (patch 14 with 2x spatial merge). An image at 1120x672 (40x24 merged patches) produces 960 visual tokens. No resize, no tiling, no thumbnail.
  • M-RoPE (Multimodal RoPE). Each token carries a 3D position (t, h, w) instead of 1D. For images t=0, for video t = frame_index. RoPE rotates query/key vectors by a frequency per axis. No positional embedding table.
  • MLP projector. Drop the Q-Former; use a 2-layer MLP on the merged patch tokens.
  • Video with dynamic FPS. Video sampled at 1-2 FPS by default, but the model accepts arbitrary frame counts.

Result: Qwen2-VL-7B matched GPT-4o on several multimodal benchmarks and beat it on DocVQA (94.5 vs 88.4). The architecture change did most of the work.

Qwen2.5-VL (February 2025): dynamic FPS and absolute time

Qwen2.5-VL's big shift was video. Dynamic FPS is more than "sample more frames when needed." The paper formalized several pieces:

  • Absolute time tokens. Instead of positional indices (frame 0, 1, 2...), use actual timestamps. "At 0:04, the cat jumps." The model sees <time>0.04</time> tokens interleaved with frame tokens.
  • Dynamic FPS. Sample at 1 FPS for slow footage, 4+ FPS for action. The user or trainer chooses; M-RoPE adapts.
  • Window attention in ViT. Spatial attention is windowed (local within blocks) for throughput; global attention every few layers.
  • Explicit JSON output format. Trained on tool-call data: "{"tool": "click", "coords": [380, 220]}". Agent-ready out of the box.
  • MRoPE-v2 scaling. Positions scale with max input size so a 10-minute video does not run out of frequency range.

Benchmarks: Qwen2.5-VL-72B beats GPT-4o on most video benchmarks, matches Gemini 2.0 on documents, and sets the open-model SOTA for GUI grounding (ScreenSpot: 84% accuracy vs 38% for GPT-4o).

Qwen3-VL (November 2025)

Qwen3-VL is an incremental upgrade that consolidates rather than reinvents: larger LLM backbone (Qwen3-72B), expanded training data, improved OCR, stronger reasoning via the Qwen3 "thinking mode." The ViT and M-RoPE stay. The paper focuses on data and training improvements over architecture.

The lineage takeaway: by 2025 the Qwen-VL architecture had stabilized. Additional generations scale compute and data, not primitives.

M-RoPE mathematically

Classical RoPE rotates a query q of dimension d by position m using paired coordinates:

q_rot[2i]   = q[2i]   * cos(m * theta_i) - q[2i+1] * sin(m * theta_i)
q_rot[2i+1] = q[2i]   * sin(m * theta_i) + q[2i+1] * cos(m * theta_i)
theta_i     = 10000^(-2i/d)

M-RoPE splits the hidden dim into three bands. Say d = 96. Assign 32 dims to temporal, 32 to height, 32 to width. Each band rotates by its own axis position. A patch at (t=5, h=10, w=20) gets rotations R_t(5), R_h(10), R_w(20) applied to its three bands.

Text tokens use t = text_index, h = 0, w = 0 (or a normalized choice), keeping compatibility. Video frames use t = frame_time, h = row, w = col. Single images use t = 0.

The benefit: one position encoding handles text, image, and video without branching code or different position tables.

Dynamic-FPS sampling logic

Given a video of duration T seconds and a target-tokens budget B:

  1. Compute the maximum FPS you can afford: fps_max = B / (T * tokens_per_frame).
  2. Pick a candidate FPS list from the motion level. High motion searches [8, 4, 2, 1, 0.5, 0.25], medium searches [4, 2, 1, 0.5, 0.25], and low searches [1, 0.5, 0.25, 0.1]. Motion can come from an optical-flow heuristic or an explicit user request.
  3. Take the first candidate with fps <= fps_max. If none fits, fall back to the lowest one.
  4. Sample uniformly at the chosen FPS; in Qwen2.5-VL, <time>t</time> tokens go between frames.

Qwen2.5-VL trains this logic implicitly; at inference the user controls via fps parameter. A 60-second action sequence at 4 FPS with 81 tokens per frame = 19440 tokens, manageable in a 32k context.

Structured agent output

Qwen2.5-VL's agent training explicitly targets structured tool calls:

{
  "tool": "mouse_click",
  "coords": [1024, 512],
  "button": "left",
  "modifier": null
}

Parsing is one JSON.parse call over the model's output, provided the output is valid JSON. Compare to free-form "click at (1024, 512)" which required regex and ambiguity handling. That shift is part of why Qwen2.5-VL's ScreenSpot score jumped from Qwen2-VL's 55% to 84%.

Check: The Concept0/23
1. What is dynamic FPS?Define
Two clips of 3 seconds, one of slow footage and one of action footage, each with an arrow into a box labelled frame sampler, fps = ?.
Typed schematic. No sampling rate is shown.
2. What is an absolute time token in Qwen2.5-VL?Define
Four sampled video frames of a cat, a model reply reading At 0:04, the cat jumps, and below them an input sequence of four blocks of frame tokens.
Schematic. The reply text is the lesson's example.
3. What is structured agent output in Qwen2.5-VL?Define
A mock-up GUI screenshot with a text field and a Submit button, an arrow to a reply box that shows only a question mark, next to the instruction click Submit.
Typed mock-up. The reply is left blank on purpose.
4. What do min_pixels and max_pixels control in a Qwen2.5-VL request?Define
A typed request listing an image plus min_pixels and max_pixels fields, a 1120 by 672 image, and an arrow to a box labelled Qwen2.5-VL, model.
Typed schematic. 1120 x 672 is the lesson's example image size.
5. What does window attention do in Qwen2.5-VL's ViT?Define
An 8 by 6 grid of image patches with one patch marked q, and the text asking which patches q can read in one ViT layer.
Schematic grid. Patch counts are illustrative.
6. How does M-RoPE rotate a 96-dim hidden vector?Define
A single bar labelled 96 numbers from dim 0 to dim 95, with a patch at position t 5, h 10, w 20.
Schematic. Position values are the lesson's example.
7. What is grounding in Qwen-VL, and what made it distinctive at launch?Define
A 448 by 448 image with a cat, the question Where is the cat, and an empty Qwen-VL reply box.
Typed schematic. The cat sits at the lesson's example coordinates.
8. Which stack did the original Qwen-VL use, before Qwen2-VL replaced the bridge and the fixed input size?Define
Two boxes: Qwen-VL from August 2023 with stack unknown, and Qwen2-VL from September 2024 which replaced the bridge and the fixed input size.
Schematic from the stem.
9. What replaced the Q-Former and the fixed 448x448 input in Qwen2-VL?Define
Qwen-VL pipeline: a fixed 448 by 448 input, an encoder, a highlighted Q-Former, and an LLM; below, a line saying Qwen2-VL dropped the Q-Former and the fixed input.
Schematic from the stem.
10. What does Qwen3-VL change relative to Qwen2.5-VL?Define
Four boxes in a row: Qwen-VL August 2023, Qwen2-VL September 2024, Qwen2.5-VL February 2025, and a highlighted Qwen3-VL November 2025.
Dates from the lesson's headings.
11. Qwen2-VL-7B scored 94.5 on DocVQA against GPT-4o's 88.4. What does the lesson credit for the result?Explain
Bar chart with GPT-4o at 88.4 and Qwen2-VL-7B at 94.5 on DocVQA.
Scores from the stem.
12. Why does M-RoPE give every token a (t, h, w) position instead of a single 1D index?Explain
Three 4 by 4 patch grids for frames 0, 1, 2 with one patch highlighted in frame 1, and a row of 48 flattened cells with the same patch at index 22.
Schematic. Grid sizes are illustrative.
13. In M-RoPE, how are positions assigned to a video patch versus a text token?Explain
Four tokens: the text tokens Describe, the and clip, and a video patch from frame 4, row 1, column 4, each labelled position (?, ?, ?).
Schematic. The video patch location is illustrative.
14. What problem does MRoPE-v2 scaling solve in Qwen2.5-VL?Explain
A list of five Qwen2.5-VL features: absolute time tokens, dynamic FPS, window attention in ViT, explicit JSON output format, and a highlighted MRoPE-v2 scaling.
Feature names from the lesson's Qwen2.5-VL section.
15. How does the sampler in the Concept section ('Dynamic-FPS sampling logic') choose FPS beyond fitting the token budget?Explain
A terminal-style box listing three sampler inputs T, tokens_per_frame and B, with an arrow to a box reading fps = ?.
Inputs named as in the lesson's Dynamic-FPS sampling logic.
16. What happened to ScreenSpot GUI-grounding accuracy from Qwen2-VL to Qwen2.5-VL, and what is given as part of the reason?Explain
Empty bar slots with question marks for Qwen2-VL and Qwen2.5-VL on a 0 to 100 percent ScreenSpot axis.
Values withheld on purpose.
17. Why is JSON tool-call output easier to use than free-form text like 'click at (1024, 512)'?Explain
Two terminal-style boxes: a free-form reply click at (1024, 512) and a JSON tool call with tool mouse_click and coords 1024, 512.
Typed examples from the lesson's Structured agent output section.
18. A 60-second clip is sampled at 4 FPS with 81 tokens per frame. How many visual tokens is that, and does it fit?Apply
A 60 second timeline marked 0 to 60 s with frame ticks at 4 FPS, a note that each frame costs 81 tokens, and an empty bar for a 32k context.
Schematic. Tick spacing is to scale.
19. A teammate says M-RoPE's t = frame_index makes absolute time tokens redundant. Where does that break once FPS varies per video?Analyze
Two rows of nine frames numbered 0 to 8, one for a video sampled at rate a and one at rate b, each noting that t equals the frame index.
Schematic. Rates a and b are left symbolic.
20. A user passes fps=8 for the 10-minute security loop at 81 tokens per frame and overflows a 32k context. Which step of the sampling logic did they bypass?Analyze
A card listing a 10-minute security loop, 81 tokens per frame, and user passes fps=8, with an arrow into a model box with a 32k context window.
Inputs from the stem.
21. A 10-minute security feed has rare 1-second events that 0.5 FPS can miss. If each request has a 32768-token budget, which design keeps more FPS?Design
A 10 second excerpt of a feed with sampled frames every 2 seconds and a 1 second event falling between two of them.
Illustrative event timing. The 0.5 FPS rate and 1 s event come from the stem.
22. You are building a click-and-type agent on Qwen2.5-VL. Which output design fits the lesson?Design
A mock-up screen with a text field and a Submit button feeds Qwen2.5-VL, whose output feeds an agent code box that needs an action.
Typed schematic.
23. A service gets dense invoice scans and tiny thumbnails and must keep per-request token cost predictable. Which approach fits?Design
A dense 1120 by 672 invoice scan and a tiny 336 by 336 thumbnail, with the goal that per-request token cost stays predictable.
Schematic. Sizes are the lesson's two example image sizes.

Use It

main.py implements:

  • M-RoPE position computation for a packed sequence mixing text, image patches, and video frames.
  • Dynamic-FPS sampler: given (duration, budget, motion_level), pick FPS and emit frame timestamps.
  • A toy Qwen2.5-VL JSON-output parser that handles tool-call responses with coordinate fields.

Run it and read the sampler table. The same 32768-token budget gives a 30-second tennis rally a much higher FPS than a 10-minute security loop.

Check: Use It0/7
1. You run main.py's sampler on a 10-minute low-motion security loop with 81 tokens per frame and a 32768-token budget. What plan does it produce?Apply
A terminal-style card with duration 600 s, motion low, 81 tokens per frame, budget 32768, and an arrow to a box reading plan: fps, frames, tokens = ?.
Inputs from the stem.
2. With hidden=48 and 16 dims per band, what first-pair angles (t, h, w) does mrope_angles return for a video patch at t=3, h=5, w=7?Apply
Three equal bands of 16 dims named temporal, height and width, a video patch at t 3, h 5, w 7, the angle formula, and three first pair cells marked ?.
Layout from the stem and the lesson's code.
3. main.py's sampler gets a 30-second medium-motion recipe demo at 81 tokens per frame with a 32768 budget. What plan does it choose?Apply
A 30 second timeline for a recipe demo, a card with motion medium, 81 tokens per frame, budget 32768, and an arrow to a box plan: fps, frames, tokens = ?.
Inputs from the stem.
4. parse_tool_call receives 'Sure, clicking at {"tool": "mouse_click", "coords": [800, 400]} now.' What does it return?Apply
The source of parse_tool_call from main.py, with the input string Sure, clicking at followed by a JSON tool call with coords 800, 400 and the word now.
Source copied from main.py. The input is the stem's string, shown on two lines.
5. Your GUI agent receives the truncated reply '{"tool": "type_text", "text": "hello"'. What should the agent loop do?Apply
An agent loop: screenshot into Qwen2.5-VL, whose reply is the JSON start tool type_text, text hello, with no closing brace, feeding a box asking what the agent loop does next.
Reply text is the stem's string.
6. Someone forces the 10-minute security loop to 1 FPS at 81 tokens per frame with a 32768-token budget. What happens?Apply
A 600 second bar with a frame tick for every 10 seconds drawn, a note that each frame costs 81 tokens, and an empty bar for a 32768 token budget.
Schematic. One drawn tick stands for 10 sampled frames.
7. A 2-hour low-motion lecture (7,200 s) goes through the sampler at 81 tokens per frame with a 32768 budget, so fps_max is about 0.056. What happens?Analyze
A 2 hour timeline, a card with duration 7200 s, motion low, 81 tokens per frame, budget 32768, and an arrow to a box plan: fps, frames, tokens = ?.
Inputs from the stem.

Ship It

This lesson produces outputs/skill-qwen-vl-pipeline-designer.md. Given a video task (monitoring, agent, action recognition, accessibility), it emits the Qwen2.5-VL configuration (frame budget, FPS strategy, window-attention flag, agent-output mode) and a latency estimate. Use this whenever you deploy a Qwen-VL-family model for a video product.

Author's Note

I'd run main.py and read the sampler table before the M-RoPE math. It prints four videos against one 32768-token budget: the 30-second tennis rally lands on 8 FPS (240 frames, 19440 tokens), while the 10-minute security loop lands on 0.5 FPS (300 frames, 24300 tokens). The budget sets the ceiling and the motion level picks which candidate list you search, so a low-motion video can still use most of the budget if it is long enough.

The sampler in main.py matches the candidate lists in the Concept section, including the fractional rates like 0.5 and 0.25. One gap remains: frame_times() only returns timestamps. It never builds the interleaved <time>t</time> sequence, so the absolute-time idea is described here but not run.

In the M-RoPE demo the first-pair angles equal the position itself, because theta_0 = 1. That makes them easy to check by hand for exercise 1, but the later pairs in each band are where the frequencies spread out.

For the parser, the fallback slices from the first { to the last }, which rescues the chatty reply and gives up on the truncated one with a PARSE_ERROR. In an agent loop I'd treat that error as a reason to re-ask the model, not as something to guess around.

Exercises

  1. Compute M-RoPE rotations for a patch at (t=3, h=5, w=7) with hidden 48 (16 per band, base theta 10000). Show the rotation angles for the first three pairs in each band.

  2. A 10-minute security-camera recording at 1 FPS produces how many frames? At 384 resolution with 3x pool, how many total tokens? Does Qwen2.5-VL's default 32k context handle it?

  3. Pick FPS for a 30-second tennis rally vs a 30-second recipe demo vs a 30-second UI-agent recording. Justify each with the dynamic-FPS logic.

  4. Qwen2.5-VL drops the Q-Former entirely. Why does a simple MLP work in 2025 but not in 2023? (Hint: data scale and encoder quality.)

  5. Parse three Qwen2.5-VL JSON tool-call outputs into Python dicts. What fails for malformed JSON and what recovery strategy does the Qwen cookbook recommend?

Key Terms

TermWhat people sayWhat it actually means
M-RoPE"Multimodal RoPE"3D rotary position embedding with temporal, height, and width bands in the hidden dim
Dynamic FPS"Smart sampling"Frame sampling rate chosen per video based on motion, duration, and token budget
Absolute time token"Timestamp token"<time>t</time> interleaved in the sequence so the model sees actual seconds not frame index
Window attention"Local attention"Spatial self-attention restricted to small windows for speed; global attention added periodically
Structured agent output"JSON mode"Training data supervision teaching the VLM to emit parseable JSON with coords and tool names
min_pixels / max_pixels"Resolution bounds"Per-request Qwen2.5-VL controls bounding total pixel count and therefore token count
Grounding"Point-at-it"Outputting bounding-box coordinates as text tokens; used since Qwen-VL v1

Further Reading

Code

Ships With