Skip to content

Commit c8a082e

Browse files
[fix] Fixes Qwen3-VL prompt expansion for multiple videos (#10518)
Co-authored-by: gemini-code-assist <200291788+gemini-code-assist@users.noreply.github.com>
1 parent a48af5c commit c8a082e

2 files changed

Lines changed: 28 additions & 21 deletions

File tree

src/llamafactory/data/mm_plugin.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2379,16 +2379,13 @@ def process_messages(
23792379

23802380
image_grid_thw = mm_inputs.get("image_grid_thw", [])
23812381
video_grid_thw = mm_inputs.get("video_grid_thw", [])
2382-
num_frames = video_grid_thw[0][0] if len(video_grid_thw) > 0 else 0 # hard code for now
23832382
video_metadata = mm_inputs.get("video_metadata", [])
23842383

23852384
else:
23862385
image_grid_thw = [None] * len(images)
23872386
video_grid_thw = [None] * len(videos)
2388-
num_frames = 0
2389-
timestamps = [0]
23902387

2391-
for idx, message in enumerate(messages):
2388+
for message in messages:
23922389
content = message["content"]
23932390
while IMAGE_PLACEHOLDER in content:
23942391
image_seqlen = (
@@ -2403,19 +2400,17 @@ def process_messages(
24032400

24042401
while VIDEO_PLACEHOLDER in content:
24052402
if self.expand_mm_tokens:
2406-
metadata = video_metadata[idx]
2403+
video_grid = video_grid_thw[num_video_tokens]
2404+
num_frames = int(video_grid[0].item())
2405+
metadata = video_metadata[num_video_tokens]
24072406
timestamps = processor._calculate_timestamps(
24082407
metadata.frames_indices,
24092408
metadata.fps,
2410-
video_processor.merge_size,
2409+
getattr(video_processor, "temporal_patch_size", 2),
24112410
)
24122411
video_structure = ""
2412+
video_seqlen = int((video_grid[1:].prod() // video_merge_length).item())
24132413
for frame_index in range(num_frames):
2414-
video_seqlen = (
2415-
video_grid_thw[num_video_tokens][1:].prod() // video_merge_length
2416-
if self.expand_mm_tokens
2417-
else 1
2418-
)
24192414
timestamp_sec = timestamps[frame_index]
24202415
frame_structure = (
24212416
f"<{timestamp_sec:.1f} seconds>"

tests/data/test_mm_plugin.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -424,19 +424,31 @@ def test_qwen3_vl_plugin():
424424
tokenizer_module = _load_tokenizer_module(model_name_or_path="Qwen/Qwen3-VL-30B-A3B-Instruct")
425425
qwen3_vl_plugin = get_mm_plugin(name="qwen3_vl", video_token="<|video_pad|>")
426426
check_inputs = {"plugin": qwen3_vl_plugin, **tokenizer_module}
427+
video_token = "<|video_pad|>" * frame_seqlen
428+
first_video = (
429+
f"<0.2 seconds><|vision_start|>{video_token}<|vision_end|>"
430+
f"<1.2 seconds><|vision_start|>{video_token}<|vision_end|>"
431+
)
432+
second_video = first_video + f"<2.2 seconds><|vision_start|>{video_token}<|vision_end|>"
433+
videos = [
434+
[Image.new("RGB", (32, 32), (255, 255, 255))] * 4,
435+
[Image.new("RGB", (32, 32), (255, 255, 255))] * 6,
436+
]
437+
messages = [
438+
{"role": "user", "content": "Compare these videos: <video> and <video>."},
439+
{"role": "assistant", "content": "They are different."},
440+
]
427441
check_inputs["expected_mm_messages"] = [
428-
{
429-
key: value.replace(
430-
"<video>", # little different with original processor for default `fps=2` in our repo
431-
"<0.2 seconds><|vision_start|>{}<|vision_end|><1.2 seconds><|vision_start|>{}<|vision_end|>".format(
432-
"<|video_pad|>" * frame_seqlen, "<|video_pad|>" * frame_seqlen
433-
),
434-
)
435-
for key, value in message.items()
436-
}
437-
for message in VIDEO_MESSAGES
442+
{key: value.replace("<video>", first_video) for key, value in message.items()} for message in VIDEO_MESSAGES
438443
]
439444
_check_plugin(**check_inputs)
445+
assert qwen3_vl_plugin.process_messages(messages, NO_IMAGES, videos, NO_AUDIOS, tokenizer_module["processor"]) == [
446+
{
447+
"role": "user",
448+
"content": f"Compare these videos: {first_video} and {second_video}.",
449+
},
450+
{"role": "assistant", "content": "They are different."},
451+
]
440452

441453

442454
@pytest.mark.runs_on(["cpu", "mps"])

0 commit comments

Comments
 (0)