Views
No views yet
1conda create -n cinecap python=3.12
2conda activate cinecap
3pip install torch==2.4.1 torchvision==0.19.1 torchaudio==2.4.1
4pip install transformers==4.57.1
5pip install qwen_vl_utils==0.0.14
6pip install accelerate
7pip install flash-attn==2.7.4.post1 --no-build-isolation
8pip install deepspeed==0.16.9
9# It's highly recommended to use `[decord]` feature for faster video loading.
10pip install "decord" -U
11pip install msgspec
12pip install -q -U google-genai
13pip install func-timeout
14pip install deepspeed==0.16.9Note: To generate high-quality captions, limit video input to around 40 seconds. Please segment longer videos into around 40-second clips before processing.
1import re
2import torch
3from transformers import AutoProcessor, AutoModelForImageTextToText
4from qwen_vl_utils import process_vision_info
5
6# 1. Configuration
7MODEL_ID = "hector-mao/CineCap-GRPO-8B"
8VIDEO_PATH = "example_video.mp4" # Replace with your video path
9
10SYSTEM_PROMPT = "You are a video cinematography expert."
11
12USER_PROMPT = (
13 "Describe the cinematic aspects in the video.\n"
14 "Cinematic aspects include: Camera Movement, Depth of Field, Camera Angle, "
15 "Subject Orientation, Shot Size, Composition, Special Shots.\n"
16 "You should firstly watch the video and get visual evidence in the <think> block "
17 "and then output the dense caption in the <answer> block."
18)
19
20
21def extract_answer_text(text: str) -> str:
22 """Extract the final caption from the <answer> block if present."""
23 if not text:
24 return ""
25
26 match = re.search(r"<answer>(.*?)</answer>", text, flags=re.DOTALL | re.IGNORECASE)
27 if match:
28 return re.sub(r"\s+", " ", match.group(1)).strip()
29
30 return re.sub(r"\s+", " ", text).strip()
31
32
33print(f"🚀 Processing video: {VIDEO_PATH}")
34
35# 2. Load model and processor
36print("⏳ Loading model...")
37
38model = AutoModelForImageTextToText.from_pretrained(
39 MODEL_ID,
40 dtype=torch.bfloat16,
41 device_map="auto",
42 trust_remote_code=True,
43 attn_implementation="flash_attention_2", # remove this line if flash-attn is not installed
44)
45
46processor = AutoProcessor.from_pretrained(
47 MODEL_ID,
48 trust_remote_code=True,
49)
50
51# 3. Construct conversation
52messages = [
53 {
54 "role": "system",
55 "content": SYSTEM_PROMPT,
56 },
57 {
58 "role": "user",
59 "content": [
60 {
61 "type": "video",
62 "video": VIDEO_PATH,
63 "fps": 2.0,
64 "max_frames": 80,
65 },
66 {
67 "type": "text",
68 "text": USER_PROMPT,
69 },
70 ],
71 },
72]
73
74# 4. Process multimodal inputs
75print("⚙️ Processing inputs...")
76
77text = processor.apply_chat_template(
78 messages,
79 tokenize=False,
80 add_generation_prompt=True,
81)
82
83image_inputs, video_inputs, video_kwargs = process_vision_info(
84 messages,
85 image_patch_size=processor.image_processor.patch_size,
86 return_video_kwargs=True,
87 return_video_metadata=True,
88)
89
90# Qwen3-VL returns video inputs as (video_tensor, video_metadata).
91if video_inputs is not None:
92 video_inputs, video_metadata = zip(*video_inputs)
93 video_inputs = list(video_inputs)
94 video_metadata = list(video_metadata)
95else:
96 video_metadata = None
97
98inputs = processor(
99 text=text,
100 images=image_inputs,
101 videos=video_inputs,
102 video_metadata=video_metadata,
103 return_tensors="pt",
104 do_resize=False,
105 **video_kwargs,
106)
107
108inputs = inputs.to(model.device)
109
110# 5. Generate cinematographic caption
111print("✨ Generating caption...")
112
113with torch.inference_mode():
114 generated_ids = model.generate(
115 **inputs,
116 max_new_tokens=4096,
117 do_sample=False,
118 )
119
120# Remove input tokens from generated output.
121generated_ids_trimmed = [
122 output_ids[len(input_ids):]
123 for input_ids, output_ids in zip(inputs.input_ids, generated_ids)
124]
125
126raw_output = processor.batch_decode(
127 generated_ids_trimmed,
128 skip_special_tokens=True,
129 clean_up_tokenization_spaces=False,
130)[0]
131
132caption = extract_answer_text(raw_output)
133
134print("\n" + "=" * 50)
135print("🎬 CINEMATOGRAPHIC CAPTION:")
136print("=" * 50)
137print(caption)
138print("=" * 50)1@misc{mao2026cinecapstructuredreasoningspatiotemporal,
2 title={CineCap: Structured Reasoning with Spatio-Temporal Anchors for Cinematographic Video Captioning},
3 author={Xinyu Mao and Yuhui Zeng and Xiaokun Liu and Wenyu Qin and Meng Wang and Xin Tao and Pengfei Wan and Xiaohan Xing and Max Meng},
4 year={2026},
5 eprint={2606.24636},
6 archivePrefix={arXiv},
7 primaryClass={cs.AI},
8 url={https://arxiv.org/abs/2606.24636},
9}