From a321b95a8a324ec4c868e3f3f4398fb0a82eab77 Mon Sep 17 00:00:00 2001 From: Jinzhe Pan <48981407+Eigensystem@users.noreply.github.com> Date: Fri, 6 Feb 2026 12:33:08 +0800 Subject: [PATCH] [Fix] remove video ratio limitation (#1069) --- fastvideo/dataset/preprocessing_datasets.py | 71 +-------------------- fastvideo/workflow/preprocess/components.py | 25 +------- 2 files changed, 3 insertions(+), 93 deletions(-) diff --git a/fastvideo/dataset/preprocessing_datasets.py b/fastvideo/dataset/preprocessing_datasets.py index 15ed7723c..cba721ce4 100644 --- a/fastvideo/dataset/preprocessing_datasets.py +++ b/fastvideo/dataset/preprocessing_datasets.py @@ -148,62 +148,6 @@ class DataValidationStage(DatasetFilterStage): return batch -class ResolutionFilterStage(DatasetFilterStage): - """Stage for filtering data items based on resolution constraints.""" - - def __init__(self, - max_h_div_w_ratio: float = 17 / 16, - min_h_div_w_ratio: float = 8 / 16, - max_height: int = 1024, - max_width: int = 1024): - self.max_h_div_w_ratio = max_h_div_w_ratio - self.min_h_div_w_ratio = min_h_div_w_ratio - self.max_height = max_height - self.max_width = max_width - - def should_keep(self, batch: PreprocessBatch, **kwargs) -> bool: - """ - Check if data item passes resolution filtering. - - Args: - batch: Dataset batch with resolution information - - Returns: - True if passes filter, False otherwise - """ - # Only apply to videos - if not batch.is_video: - return True - - if batch.resolution is None: - return False - - height = batch.resolution.get("height", None) - width = batch.resolution.get("width", None) - if height is None or width is None: - return False - - # Check aspect ratio - aspect = self.max_height / self.max_width - hw_aspect_thr = 1.5 - - return self.filter_resolution( - height, - width, - max_h_div_w_ratio=hw_aspect_thr * aspect, - min_h_div_w_ratio=1 / hw_aspect_thr * aspect, - ) - - def process(self, batch: PreprocessBatch, **kwargs) -> PreprocessBatch: - """Process does nothing for resolution filtering - filtering is handled by should_keep.""" - return batch - - def filter_resolution(self, h: int, w: int, max_h_div_w_ratio: float, - min_h_div_w_ratio: float) -> bool: - """Filter based on height/width ratio.""" - return h / w <= max_h_div_w_ratio and h / w >= min_h_div_w_ratio - - class FrameSamplingStage(DatasetFilterStage): """Stage for temporal frame sampling and indexing.""" @@ -328,11 +272,6 @@ class VideoTransformStage(DatasetStage): video = rearrange(video, "t c h w -> c t h w") video = video.to(torch.uint8) - h, w = video.shape[-2:] - assert ( - h / w <= 17 / 16 and h / w >= 8 / 16 - ), f"Only videos with a ratio (h/w) less than 17/16 and more than 8/16 are supported. But video ({batch.path}) found ratio is {round(h / w, 2)} with the shape of {video.shape}" - video = video.float() / 127.5 - 1.0 batch.pixel_values = video return batch @@ -489,8 +428,6 @@ class VideoCaptionMergedDataset(torch.utils.data.IterableDataset, tokenizer) -> None: """Initialize all processing stages.""" self.validation_stage = DataValidationStage() - self.resolution_filter_stage = ResolutionFilterStage( - max_height=args.max_height, max_width=args.max_width) self.frame_sampling_stage = FrameSamplingStage( num_frames=args.num_frames, train_fps=args.train_fps, @@ -543,7 +480,6 @@ class VideoCaptionMergedDataset(torch.utils.data.IterableDataset, # Initialize counters filter_counts = { "validation_failed": 0, - "resolution_failed": 0, "frame_sampling_failed": 0 } sample_num_frames: list[int] = [] @@ -579,10 +515,6 @@ class VideoCaptionMergedDataset(torch.utils.data.IterableDataset, filter_counts["validation_failed"] += 1 return False - if not self.resolution_filter_stage.should_keep(batch): - filter_counts["resolution_failed"] += 1 - return False - if not self.frame_sampling_stage.should_keep(batch): filter_counts["frame_sampling_failed"] += 1 return False @@ -594,10 +526,9 @@ class VideoCaptionMergedDataset(torch.utils.data.IterableDataset, after_count: int): """Log filtering statistics.""" logger.info( - "validation_failed: %d, resolution_failed: %d, frame_sampling_failed: %d, " + "validation_failed: %d, frame_sampling_failed: %d, " "Counter(sample_num_frames): %s, before filter: %d, after filter: %d", filter_counts['validation_failed'], - filter_counts['resolution_failed'], filter_counts['frame_sampling_failed'], Counter(sample_num_frames), before_count, after_count) diff --git a/fastvideo/workflow/preprocess/components.py b/fastvideo/workflow/preprocess/components.py index 22e5a8526..ddcfda9a9 100644 --- a/fastvideo/workflow/preprocess/components.py +++ b/fastvideo/workflow/preprocess/components.py @@ -26,24 +26,18 @@ class PreprocessingDataValidator: def __init__(self, max_height: int = 1024, max_width: int = 1024, - max_h_div_w_ratio: float = 17 / 16, - min_h_div_w_ratio: float = 8 / 16, num_frames: int = 16, train_fps: int = 24, speed_factor: float = 1.0, video_length_tolerance_range: float = 5.0, - drop_short_ratio: float = 0.0, - hw_aspect_threshold: float = 1.5): + drop_short_ratio: float = 0.0): self.max_height = max_height self.max_width = max_width - self.max_h_div_w_ratio = max_h_div_w_ratio - self.min_h_div_w_ratio = min_h_div_w_ratio self.num_frames = num_frames self.train_fps = train_fps self.speed_factor = speed_factor self.video_length_tolerance_range = video_length_tolerance_range self.drop_short_ratio = drop_short_ratio - self.hw_aspect_threshold = hw_aspect_threshold self.validators: dict[str, Callable[[dict[str, Any]], bool]] = {} self.filter_counts: dict[str, int] = {} @@ -86,26 +80,11 @@ class PreprocessingDataValidator: def _validate_resolution(self, batch: dict[str, Any]) -> bool: """Validate resolution constraints""" - aspect = self.max_height / self.max_width if batch["resolution"] is not None: height = batch["resolution"].get("height", None) width = batch["resolution"].get("width", None) - if height is None or width is None: - return False - - return self._filter_resolution( - height, - width, - max_h_div_w_ratio=self.hw_aspect_threshold * aspect, - min_h_div_w_ratio=1 / self.hw_aspect_threshold * aspect, - ) - - def _filter_resolution(self, h: int, w: int, max_h_div_w_ratio: float, - min_h_div_w_ratio: float) -> bool: - """Filter based on aspect ratio""" - return (min_h_div_w_ratio <= h / w <= max_h_div_w_ratio) and ( - self.min_h_div_w_ratio <= h / w <= self.max_h_div_w_ratio) + return not (height is None or width is None) def _validate_frame_sampling(self, batch: dict[str, Any]) -> bool: """Validate frame sampling constraints"""