Video
video qa
video captioning
action recognition

Video Understanding

Comprehending video content — captioning, Q&A, action recognition. Multimodal video LLMs like Qwen2.5-VL handle this.

Capability notes

Video understanding is the ability to answer questions about what happens in a video — identifying objects, actions, text, people, and temporal events across frames. Unlike [image understanding](/tasks/image-understanding) which processes static frames, video understanding must track objects across time, reason about motion, and understand sequential events. Two models define the local landscape: Llama 3.2 Vision (11B/90B) processes video as keyframe sequences, and Qwen2-VL (7B/72B) uses native temporal attention across frames. Llama 3.2 11B Vision samples ~1fps (one frame per second), encodes each independently, then applies temporal cross-attention across frames. This approach works well for scene-level reasoning ("what is happening in this video") but misses fast motion (sub-second events between samples). Qwen2-VL uses native 3D position encoding with dense frame processing — better at action recognition and temporal localization ("at what timestamp does the person pick up the glass"). On Video-MME benchmarks, Qwen2-VL 72B scores 71.2% (with audio), Llama 3.2 90B scores 66.8%. For longer videos (30-60 min vs 1-5 min clips), both degrade: accuracy drops 10-15 points as temporal context thins. **Input formats**: Most vision LLMs accept video files (MP4, AVI) or frame sequences. Frame count limits: Llama 3.2 90B processes up to 64 frames at once, Qwen2-VL 72B handles 768 frames with dynamic FPS sampling. For a 5-minute video at 30fps (9,000 frames), Qwen samples ~2.5fps to fit 768 frames — sufficient for scene-level questions but sub-frame action can be missed. For [mobile edge vision](/tasks/mobile-edge-ai), tiny vision LLMs (Llama-3.2-1B-Vision, ~1 GB) handle basic scene classification on-device. **When to use video understanding vs frame extraction**: If you just need "what store is in this video" — a single frame from a text-to-image model works. If you need "did the person turn left or right after entering the store" — you need temporal reasoning that only video understanding provides.

If you just want to try this

Lowest-friction path to a working setup.

Start with Llama 3.2 11B Vision on [Ollama](/tools/ollama) — the simplest path for trying video understanding locally. Install Ollama, run `ollama pull llama3.2-vision:11b`, then use the Ollama Python/JS client to send video frames. The 11B model fits ~8 GB VRAM at Q4 — runs on [RTX 3060 12GB](/hardware/rtx-3060-12gb), [RTX 4060 Ti 16GB](/hardware/rtx-4060-ti-16gb), or any modern GPU at 10-20 tok/s output. For your first test: record a 30-second phone video of a simple scene (making coffee, walking through a room), extract 2 frames/second (60 frames total), and ask "describe what happens in this video step by step." The model returns a chronological description with timestamps. Start with short videos (<2 min) — the model's frame budget handles this comfortably before context limits hit. If you want a GUI for video Q&A without coding, [LM Studio](/tools/lm-studio) supports llama3.2-vision-11b as a local server with a chat UI. Import video → LM Studio auto-samples keyframes → ask questions in chat. This is the lowest-friction entry point — no Python, no CLI, no API wrangling. Important reality check: open-weight video understanding is significantly behind closed APIs. Gemini 1.5 Pro and GPT-4V process native video at 1fps with 2-3× higher accuracy on temporal reasoning. Open-weight models work for classification and description, but struggle on forensic-level questions ("what did page 3 of the document shown at 2:14 say"). Accept this gap when setting expectations.

For production deployment

Operator-grade recommendation.

Production video understanding requires choosing between frame-sampling and dense-processing pipelines based on accuracy needs and latency tolerance. **Frame-sampling pipeline** (fast, lower accuracy): [Ollama](/tools/ollama) or [vLLM](/tools/vllm) serving Llama 3.2 11B Vision. Architecture: video ingest → keyframe extractor (1fps for short, 0.5fps for long) → base64 encode → POST to vision model endpoint → structured output (JSON schema via constrained decoding). Latency: 5-15s for a 2-min video on [RTX 4090](/hardware/rtx-4090). Use case: content moderation, scene classification, thumbnail selection. One GPU handles 5-10 concurrent video analysis requests. **Dense-processing pipeline** (slower, high accuracy): [vLLM](/tools/vllm) serving Qwen2-VL 72B with 768-frame capacity. Architecture: video ingest → FPS-adaptive sampler (target 200-768 frames based on clip length) → batched processing (split video into temporal chunks if needed, with overlapping windows) → LLM synthesis (separate LLM combines per-chunk descriptions into coherent analysis). Latency: 30-120s for a 5-min video on [RTX 4090](/hardware/rtx-4090), depending on frame count. Use case: legal document review in video, surveillance forensics, sports analysis. **Multi-model pipeline** (specialized): combine fast classifier + detailed analyzer. Stage 1: tiny model (Llama-3.2-1B-Vision) scans all frames at 2fps → classify into coarse categories (person present, indoor/outdoor, text visible). Stage 2: route relevant segments to Qwen2-VL 72B for deep analysis. Reduces compute 60-80% vs full-dense on all content. **Storage and indexing**: Store per-video analysis as structured JSON + vector embeddings in [pgvector](/tools/pgvector) or [Qdrant](/tools/qdrant). Embed video descriptions (via [bge-m3](/models/bge-m3)) → semantic search across video archives ("find all clips where someone enters a building"). One video description (~500 tokens) embeds to ~1024 floats. **Cost**: API (Gemini 1.5 Pro video understanding): ~$0.0025-0.005/min of video. Self-hosted on [RTX 4090](/hardware/rtx-4090): ~$0.0005-0.002/min (GPU amortized). Break-even at ~2,000-5,000 video minutes/month. Self-hosting wins at scale, API wins for burst and quality.

What breaks

Failure modes operators see in the wild.

**Frame-sampling misses critical events.** Symptom: the model describes a person entering a room and leaving but misses that they picked up an object in between. Cause: 1fps sampling skipped the intermediate frame where the action occurred. Mitigation: increase sampling rate to 2-3fps for security/forensic use cases, or use a dense-processor (Qwen2-VL) for action-heavy content. **Spatial hallucination across frames.** Symptom: the model positions objects incorrectly across time — "the car was on the left, then moved to the right" when it stayed in place. Cause: self-attention across independently-encoded frames fails to lock spatial coordinates across time. Mitigation: use models with native 3D positional encoding (Qwen2-VL) rather than concatenated-frame approaches (Llama 3.2). Accept 10-15% spatial error on long videos. **Temporal compression in long videos.** Symptom: 30-min video analysis produces a 3-sentence summary missing all mid-video events. Cause: context window compression — earlier frames are summarized/forgotten as later frames enter. Mitigation: chunk video into 2-5 min segments, analyze each independently, synthesize with a separate LLM. Map-reduce pattern — adds latency but preserves detail. **OCR in video fails on scrolling/subtitles.** Symptom: text visible in video is misread or missed entirely when it's moving/subtitled. Cause: vision models expect static text; scrolling credits or moving subtitles produce motion-blurred text. Mitigation: extract text-dominant frames at motion-minima (detect inter-frame difference, sample when difference is low), run dedicated OCR via [OCR pipeline](/tasks/ocr) on those frames separately. **Audio-video misalignment.** Symptom: model reports "person says X" based on captions but the action in video contradicts the spoken content. Cause: most open-weight vision models are video-only (no audio). The text model hallucinates audio content from visual context. Mitigation: if audio matters, run [speech-to-text](/tasks/speech-to-text) separately on audio track, inject transcript as text context alongside video frames. This is a pipeline, not a single-model solution.

Hardware guidance

**Hobbyist ($0-600)**: [RTX 3060 12GB](/hardware/rtx-3060-12gb) or [RTX 4060 Ti 16GB](/hardware/rtx-4060-ti-16gb). Runs Llama 3.2 11B Vision at Q4 (~8 GB VRAM), 10-20 tok/s output. Processes 2-min videos in 5-15s. Also runs Qwen2-VL 7B at Q4 (~6 GB) with better temporal reasoning. CPU-only with [llama.cpp](/tools/llama-cpp): llama3.2-vision-11b at Q4 runs on 16 GB RAM at 3-8 tok/s — usable for batch overnight analysis. **SMB ($1,000-2,500)**: [RTX 4070 Ti Super 16GB](/hardware/rtx-4070-ti-super) or [RTX 5070 Ti 16GB](/hardware/rtx-5070-ti). Runs Llama 3.2 11B Vision at Q6 (~12 GB) or Qwen2-VL 7B at Q6. Handles 10-20 concurrent video analysis requests via [vLLM](/tools/vllm) with continuous batching. [Apple M3 Ultra 64GB](/hardware/apple-m3-ultra): runs Qwen2-VL 72B at Q4 with 64 GB unified memory — viable for max-open-weight quality without multi-GPU. **Enterprise ($1,500-10,000)**: [RTX 4090 24GB](/hardware/rtx-4090) or [RTX 5090 32GB](/hardware/rtx-5090). Runs Qwen2-VL 72B at Q4 (~40 GB with offload) or Llama 3.2 90B Vision at Q4. For 72B+: [NVIDIA L40S](/hardware/nvidia-l40s) 48GB fits Qwen2-VL 72B Q4 entirely. [NVIDIA H100 PCIe](/hardware/nvidia-h100-pcie) 80GB or 2× [RTX 5090](/hardware/rtx-5090) for Qwen2-VL 72B FP8 (~44-48 GB). **Edge/mobile**: Llama-3.2-1B-Vision at Q4 (~1.2 GB) runs on [Apple A18 Pro](/hardware/apple-a18-pro) via CoreML, or on Android via [llama.cpp](/tools/llama-cpp) Vulkan backend. Handles basic scene/task classification: "is the camera pointed at a document, a face, or an empty desk?" Used for pre-filtering before cloud/desktop processing.

Runtime guidance

**If you want the simplest GPU-accelerated server** → [Ollama](/tools/ollama) with llama3.2-vision:11b or qwen2-vl:7b. Any OpenAI-compatible client can send video frames as base64 images. Ollama handles quantization, GPU offload, and the vision preprocessing pipeline. One CLI command: `ollama run llama3.2-vision:11b`, then send image arrays. **If you need high-throughput production inference** → [vLLM](/tools/vllm) with its vision language model support. vLLM's PagedAttention + continuous batching gives 3-5× throughput over Ollama for concurrent vision requests. Serves Llama 3.2 Vision and Qwen2-VL with proper KV-cache management for long frame sequences. Requires manual model download + config but pays for itself at >10 concurrent users. **If you're on CPU or edge** → [llama.cpp](/tools/llama-cpp) with its vision model support. Runs llama3.2-vision-11b at Q4_K_M on CPU with frame-wise attention. Install via `git clone && make`, download GGUF, run `./llama-cli -m model.gguf --mmproj mmproj.gguf --image frame1.jpg --image frame2.jpg`. 5-10 tok/s on modern CPU for 11B. The only viable path for CPU-only or mobile video understanding. **If processing high-volume video archives** → batch pipeline: [Ollama](/tools/ollama) or [vLLM](/tools/vllm) behind a job queue. Architecture: S3/local video storage → frame extractor (FFmpeg, 1fps) → batch submit to model server → structured output → [pgvector](/tools/pgvector) for searchable archive. Python-based with Celery + Redis for job management. Handles 1,000+ hours of surveillance/archival footage per day with 4× [RTX 4090](/hardware/rtx-4090). **Timestamped analysis for legal/forensic use** → Qwen2-VL 72B with WhisperX for audio transcription. Pipeline: WhisperX ([speech-to-text](/tools/whisper-cpp) with word timestamps) + Qwen2-VL (frame-level description with frame timestamps) → merge audio + visual into unified timeline. Output: "At 2:14-2:18, speaker says X while holding up document Y." [faster-whisper](/tools/faster-whisper) for audio, [Qwen2-VL](/models/qwen-3-235b-a22b) for video.

Setup walkthrough

  1. Install Ollama → ollama pull qwen2.5-vl:7b (~5 GB — strong video understanding model).
  2. Extract keyframes from your video: pip install opencv-python → ffmpeg -i input.mp4 -vf "fps=1" frames/frame_%04d.jpg (one frame per second).
  3. Python script to analyze video frames:
import ollama, glob
frames = sorted(glob.glob("frames/*.jpg"))
for i, frame in enumerate(frames):
    with open(frame, "rb") as f:
        img = f.read()
    resp = ollama.chat(model="qwen2.5-vl:7b", messages=[{
        "role": "user",
        "content": f"Frame {i+1}/{len(frames)}: Describe what's happening. Focus on actions, people, and scene changes.",
        "images": [img]
    }])
    print(f"Frame {i+1}: {resp['message']['content']}")
  1. For a 1-minute video: 60 frames, ~5-10 minutes total processing on 12 GB GPU.
  2. For temporal understanding (action sequences, events): Qwen2.5-VL supports video input natively — feed the video file directly (it auto-samples frames). Use ollama with video file path.
  3. Use cases: security footage review, sports analysis, content moderation, video search.

The cheap setup

Used RTX 3060 12 GB (~$200-250, see /hardware/rtx-3060-12gb). Runs Qwen2-VL 7B at 5-10 seconds per frame — a 1-minute video (60 frames at 1 fps) takes 5-10 minutes to analyze. For longer videos (10-60 minutes), process overnight. Pair with Ryzen 5 5600 + 32 GB DDR4 + 2TB NVMe (video storage). Total: ~$420-490. For CPU-only: MiniCPM-V via llama.cpp at 30-60 seconds per frame — 30-60 minutes for a 1-minute video, functional for occasional use.

The serious setup

Used RTX 3090 24 GB ($700-900, see /hardware/rtx-3090). Runs Qwen2-VL 72B at 10-20 seconds per frame — highest-quality local video understanding. For production video analysis (surveillance, content moderation), use Qwen2-VL 7B on 2× RTX 3060 in parallel — analyze 2 videos simultaneously. Total: ~$1,500-2,200. For the best quality-to-speed ratio: Qwen2-VL 7B on RTX 4090 ($2,000) at 1-3 seconds per frame. Video understanding scales linearly with frame count — faster GPU = more frames processed per hour.

Common beginner mistake

The mistake: Feeding a 10-minute video directly to a VLM and asking "Summarize this video." Why it fails: VLMs have context limits — Qwen2-VL supports video input but typically samples 16-64 frames total. A 10-minute video at 1 fps has 600 frames. The model either samples sparsely (missing key moments) or exceeds its context window. You get a summary of whatever random frames were sampled. The fix: Always extract keyframes yourself with ffmpeg at a frame rate that captures your use case. For sports: 10 fps (action is fast). For surveillance: 1 fps (changes are slow). For lectures: scene-change detection (only process frames when slides change). Feed the model individual frames with timestamps. Control your sampling rate — don't trust the model's default video loader. The model sees what you show it; if you miss a frame, the model misses the event.

Reality check

Local video gen is genuinely possible in 2026 (LTX-Video, Mochi) but VRAM-hungry. 24 GB is the working minimum; 32 GB is the comfort zone for long-form workflows. Below 24 GB, video gen isn't realistic with current models.

Common mistakes

  • Trying video gen on 16 GB cards (model + KV cache doesn't fit)
  • Underestimating runtime VRAM (peak draw 1.5x model size on long sequences)
  • Mixing video gen with concurrent LLM serving on same GPU
  • Using Mac Silicon for video gen — viable but 30-50% slower than CUDA

What breaks first

The errors most operators hit when running video understanding locally. Each links to a diagnose+fix walkthrough.

Before you buy

Verify your specific hardware can handle video understanding before committing money.

Specialized buyer guides
Updated 2026 roundup