Repository navigation
[None][fix] MiniMax-M3 VL: forward video metadata so videos get timestamps #20695
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2050,6 +2050,32 @@ def _video_frames(video: Any) -> List[Any]: | |||||||||||||||||||||||||||||||||||||||
| return list(video.frames) | ||||||||||||||||||||||||||||||||||||||||
| return list(video) if isinstance(video, (list, tuple)) else [video] | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| @staticmethod | ||||||||||||||||||||||||||||||||||||||||
| def _video_metadata(video: Any, num_frames: int) -> Dict[str, Any]: | ||||||||||||||||||||||||||||||||||||||||
| """Timing of one raw video item, in the form the HF video processor takes. | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| ``VideoData.metadata`` carries the source ``fps`` and the indices of | ||||||||||||||||||||||||||||||||||||||||
| the sampled frames. With both, the processor writes a | ||||||||||||||||||||||||||||||||||||||||
| ``]<]{t} seconds[>[`` timestamp before each temporal group. A video | ||||||||||||||||||||||||||||||||||||||||
| without usable timing (no metadata, ``fps`` missing or not positive, | ||||||||||||||||||||||||||||||||||||||||
| no frame indices) gets ``fps=None`` and no timestamps. Only the keys | ||||||||||||||||||||||||||||||||||||||||
| transformers' ``VideoMetadata`` accepts are passed, and | ||||||||||||||||||||||||||||||||||||||||
| ``total_num_frames`` is the number of frames delivered, because the | ||||||||||||||||||||||||||||||||||||||||
| media loader has already sampled them. | ||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||
| metadata = getattr(video, "metadata", None) | ||||||||||||||||||||||||||||||||||||||||
| metadata = metadata if isinstance(metadata, Mapping) else {} | ||||||||||||||||||||||||||||||||||||||||
| fps = metadata.get("fps") | ||||||||||||||||||||||||||||||||||||||||
| frames_indices = metadata.get("frames_indices") | ||||||||||||||||||||||||||||||||||||||||
| if fps is None or fps <= 0 or frames_indices is None or len(frames_indices) == 0: | ||||||||||||||||||||||||||||||||||||||||
| fps, frames_indices = None, range(num_frames) | ||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||
| "total_num_frames": num_frames, | ||||||||||||||||||||||||||||||||||||||||
| "fps": None if fps is None else float(fps), | ||||||||||||||||||||||||||||||||||||||||
| "duration": metadata.get("duration"), | ||||||||||||||||||||||||||||||||||||||||
| "frames_indices": [int(i) for i in frames_indices], | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+2070
to
+2076
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Require one timing index per delivered video frame.
Suggested fix
Committable suggestion
|
||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| def _video_bracket_count(self, video: Any) -> int: | ||||||||||||||||||||||||||||||||||||||||
| """Temporal patches of a video item: one framed bracket each. | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
@@ -2273,6 +2299,15 @@ def call_with_text_prompt( | |||||||||||||||||||||||||||||||||||||||
| frame_iter = iter(flat_frames) | ||||||||||||||||||||||||||||||||||||||||
| videos = [[next(frame_iter) for _ in frames] for frames in videos] | ||||||||||||||||||||||||||||||||||||||||
| processor_kwargs["videos_kwargs"] = {"do_resize": True, **video_kwargs} | ||||||||||||||||||||||||||||||||||||||||
| # Frame timing goes in only when some video has it; the others get | ||||||||||||||||||||||||||||||||||||||||
| # fps=None, so the processor gives timestamps to exactly the videos | ||||||||||||||||||||||||||||||||||||||||
| # with timing. The token-ID fast path does not add timestamps. | ||||||||||||||||||||||||||||||||||||||||
| video_metadata = [ | ||||||||||||||||||||||||||||||||||||||||
| self._video_metadata(video, len(frames)) | ||||||||||||||||||||||||||||||||||||||||
| for video, frames in zip(video_inputs, videos) | ||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||
| if any(m["fps"] is not None for m in video_metadata): | ||||||||||||||||||||||||||||||||||||||||
| processor_kwargs["videos_kwargs"]["video_metadata"] = video_metadata | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+2309
to
+2310
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preserve video timing on the token-ID path. When a request supplies timed video with
|
||||||||||||||||||||||||||||||||||||||||
| processed = self.processor( | ||||||||||||||||||||||||||||||||||||||||
| text=[templated_text], | ||||||||||||||||||||||||||||||||||||||||
| images=images if images else None, | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reject non-finite FPS before forwarding timing.
If
metadata["fps"]isfloat("nan")orfloat("inf"), thefps <= 0check does not select the no-timing fallback. The processor then receives non-finite FPS and can producenanorinftimestamp text. Require a finite, positive FPS before using the frame indices. Add NaN and infinity cases totest_video_without_timing_passes_no_metadata.