| """
|
| Performance optimization module for SeedVR2
|
| Contains optimized tensor operations and video processing functions
|
|
|
| Extracted from: seedvr2.py (lines 1633-1730)
|
| """
|
|
|
| import torch
|
| from typing import List
|
|
|
|
|
| def optimized_channels_to_last(tensor):
|
| """π Optimized replacement for rearrange(tensor, 'b c ... -> b ... c')
|
| Moves channels from position 1 to last position using PyTorch native operations.
|
| """
|
| if tensor.ndim == 3:
|
| return tensor.permute(0, 2, 1)
|
| elif tensor.ndim == 4:
|
| return tensor.permute(0, 2, 3, 1)
|
| elif tensor.ndim == 5:
|
| return tensor.permute(0, 2, 3, 4, 1)
|
| else:
|
|
|
| dims = list(range(tensor.ndim))
|
| dims = [dims[0]] + dims[2:] + [dims[1]]
|
| return tensor.permute(*dims)
|
|
|
|
|
| def optimized_channels_to_second(tensor):
|
| """π Optimized replacement for rearrange(tensor, 'b ... c -> b c ...')
|
| Moves channels from last position to position 1 using PyTorch native operations.
|
| """
|
| if tensor.ndim == 3:
|
| return tensor.permute(0, 2, 1)
|
| elif tensor.ndim == 4:
|
| return tensor.permute(0, 3, 1, 2)
|
| elif tensor.ndim == 5:
|
| return tensor.permute(0, 4, 1, 2, 3)
|
| else:
|
|
|
| dims = list(range(tensor.ndim))
|
| dims = [dims[0], dims[-1]] + dims[1:-1]
|
| return tensor.permute(*dims)
|
|
|
|
|
| def optimized_video_rearrange(video_tensors: List[torch.Tensor]) -> List[torch.Tensor]:
|
| """
|
| π OPTIMIZED version of video rearrangement
|
| Replaces slow loops with vectorized operations
|
|
|
| Transforms:
|
| - 3D: c h w -> t c h w (with t=1)
|
| - 4D: c t h w -> t c h w
|
|
|
| Expected gains: 5-10x faster than naive loops
|
|
|
| Args:
|
| video_tensors: List of video tensors to rearrange
|
|
|
| Returns:
|
| List of rearranged tensors in t c h w format
|
|
|
| Raises:
|
| ValueError: If video tensor has invalid dimensions (not 3D or 4D)
|
| """
|
| if not video_tensors:
|
| return []
|
|
|
|
|
| videos_3d = []
|
| videos_4d = []
|
| indices_3d = []
|
| indices_4d = []
|
|
|
| for i, video in enumerate(video_tensors):
|
| if video.ndim == 3:
|
| videos_3d.append(video)
|
| indices_3d.append(i)
|
| elif video.ndim == 4:
|
| videos_4d.append(video)
|
| indices_4d.append(i)
|
| else:
|
| raise ValueError(f"Video tensor at index {i} has invalid dimensions: {video.ndim}. Expected 3D or 4D.")
|
|
|
|
|
| samples = [None] * len(video_tensors)
|
|
|
|
|
| if videos_3d:
|
|
|
|
|
| batch_3d = torch.stack([v.unsqueeze(1) for v in videos_3d])
|
| batch_3d = batch_3d.permute(0, 2, 1, 3, 4)
|
|
|
| for i, idx in enumerate(indices_3d):
|
| samples[idx] = batch_3d[i]
|
|
|
|
|
| if videos_4d:
|
|
|
| shapes = [v.shape for v in videos_4d]
|
| if len(set(shapes)) == 1:
|
|
|
|
|
| batch_4d = torch.stack(videos_4d)
|
| batch_4d = batch_4d.permute(0, 2, 1, 3, 4)
|
|
|
| for i, idx in enumerate(indices_4d):
|
| samples[idx] = batch_4d[i]
|
| else:
|
|
|
| for i, idx in enumerate(indices_4d):
|
|
|
| samples[idx] = videos_4d[i].permute(1, 0, 2, 3)
|
|
|
| return samples
|
|
|
|
|
| def optimized_single_video_rearrange(video: torch.Tensor) -> torch.Tensor:
|
| """
|
| π OPTIMIZED version for single video tensor
|
| Replaces rearrange() with native PyTorch operations
|
|
|
| Transforms:
|
| - 3D: c h w -> 1 c h w (add temporal dimension)
|
| - 4D: c t h w -> t c h w (permute dimensions)
|
|
|
| Expected gains: 2-5x faster than rearrange()
|
|
|
| Args:
|
| video: Input video tensor
|
|
|
| Returns:
|
| Rearranged tensor with temporal dimension first
|
| """
|
| if video.ndim == 3:
|
|
|
| return video.unsqueeze(0)
|
| else:
|
|
|
| return video.permute(1, 0, 2, 3)
|
|
|
|
|
| def optimized_sample_to_image_format(sample: torch.Tensor) -> torch.Tensor:
|
| """
|
| π OPTIMIZED version to convert sample to image format
|
| Replaces rearrange() with native PyTorch operations
|
|
|
| Transforms:
|
| - 3D: c h w -> 1 h w c (add temporal dimension + permute to image format)
|
| - 4D: t c h w -> t h w c (permute to image format)
|
|
|
| Expected gains: 2-5x faster than rearrange()
|
|
|
| Args:
|
| sample: Input sample tensor
|
|
|
| Returns:
|
| Tensor in image format (channels last)
|
| """
|
| if sample.ndim == 3:
|
|
|
| return sample.unsqueeze(0).permute(0, 2, 3, 1)
|
| else:
|
|
|
| return sample.permute(0, 2, 3, 1)
|
|
|
|
|
|
|
|
|