Skip to content
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

Add benchmark on video #18

Merged
merged 7 commits into from
Mar 11, 2025
Merged

Add benchmark on video #18

merged 7 commits into from
Mar 11, 2025

Conversation

ternaus
Copy link
Contributor

@ternaus ternaus commented Mar 11, 2025

Addresses: #10

Summary by Sourcery

Adds video benchmarking capabilities to the project, including video loading, transformation implementations for Albumentations, Torchvision and Kornia, and benchmark running. It also includes scripts to run the benchmarks and compare the results.

New Features:

  • Introduces video benchmarking capabilities, allowing for performance evaluation of different augmentation libraries on video data.
  • Adds video loading functionality using OpenCV and TorchVision.
  • Provides video transformation implementations for Albumentations, Torchvision, and Kornia.
  • Includes scripts for running video benchmarks and comparing results.
  • Adds a tool to compare video benchmark results and generate a markdown table.
  • Adds video-specific requirements files for each library.
  • Adds video implementations for Albumentations, Torchvision, and Kornia

Tests:

  • Adds video implementations for Albumentations, Torchvision, and Kornia

Copy link

sourcery-ai bot commented Mar 11, 2025

Reviewer's Guide by Sourcery

This pull request introduces video benchmarking capabilities to the image augmentation benchmark suite. It includes video loading, applying transformations, and measuring performance for Albumentations, TorchVision, and Kornia. The changes involve adding new video implementations for each library, updating transform specifications, and providing scripts for running benchmarks and comparing results. The implementation uses float16 precision for TorchVision and Kornia on GPU to improve performance. Additionally, the PR includes scripts for running benchmarks and generating comparison tables.

Sequence diagram for video loading and transformation with Kornia

sequenceDiagram
    participant User
    participant VideoBenchmarkRunner
    participant KorniaVideoImpl
    participant KorniaLibrary
    participant GPU

    User->>VideoBenchmarkRunner: run()
    VideoBenchmarkRunner->>VideoBenchmarkRunner: load_videos()
    VideoBenchmarkRunner->>KorniaLibrary: read_video_kornia(path)
    activate KorniaLibrary
    KorniaLibrary->>GPU: Load video frames and convert to float16
    activate GPU
    GPU-->>KorniaLibrary: Returns video frames (float16)
    deactivate GPU
    KorniaLibrary-->>VideoBenchmarkRunner: Returns video tensor (T, C, H, W)
    deactivate KorniaLibrary
    VideoBenchmarkRunner->>KorniaVideoImpl: __call__(transform, video)
    activate KorniaVideoImpl
    KorniaVideoImpl->>GPU: Apply transform to video tensor (float16)
    activate GPU
    GPU-->>KorniaVideoImpl: Returns transformed video tensor (float16)
    deactivate GPU
    KorniaVideoImpl-->>VideoBenchmarkRunner: Returns transformed video tensor (T, C, H, W)
    deactivate KorniaVideoImpl
    VideoBenchmarkRunner-->>User: Returns benchmark results
Loading

Updated class diagram for AlbumentationsVideoImpl

classDiagram
    class AlbumentationsVideoImpl {
        +Resize(params: dict) BasicTransform
        +RandomCrop128(params: dict) BasicTransform
        +RandomResizedCrop(params: dict) BasicTransform
        +CenterCrop128(params: dict) BasicTransform
        +HorizontalFlip(params: dict) BasicTransform
        +VerticalFlip(params: dict) BasicTransform
        +Pad(params: dict) BasicTransform
        +Rotate(params: dict) BasicTransform
        +Affine(params: dict) BasicTransform
        +Perspective(params: dict) BasicTransform
        +Elastic(params: dict) BasicTransform
        +ColorJitter(params: dict) BasicTransform
        +ChannelShuffle(params: dict) BasicTransform
        +Grayscale(params: dict) BasicTransform
        +RGBShift(params: dict) BasicTransform
        +GaussianBlur(params: dict) BasicTransform
        +GaussianNoise(params: dict) BasicTransform
        +Invert(params: dict) BasicTransform
        +Posterize(params: dict) BasicTransform
        +Solarize(params: dict) BasicTransform
        +Sharpen(params: dict) BasicTransform
        +AutoContrast(params: dict) BasicTransform
        +Equalize(params: dict) BasicTransform
        +Normalize(params: dict) BasicTransform
        +Erasing(params: dict) BasicTransform
        +JpegCompression(params: dict) BasicTransform
        +RandomGamma(params: dict) BasicTransform
        +PlankianJitter(params: dict) BasicTransform
        +MedianBlur(params: dict) BasicTransform
        +MotionBlur(params: dict) BasicTransform
        +CLAHE(params: dict) BasicTransform
        +Brightness(params: dict) BasicTransform
        +Contrast(params: dict) BasicTransform
        +CoarseDropout(params: dict) BasicTransform
        +Blur(params: dict) BasicTransform
        +HSV(params: dict) BasicTransform
        +ChannelDropout(params: dict) BasicTransform
        +LinearIllumination(params: dict) BasicTransform
        +CornerIllumination(params: dict) BasicTransform
        +GaussianIllumination(params: dict) BasicTransform
        +Hue(params: dict) BasicTransform
        +PlasmaBrightness(params: dict) BasicTransform
        +PlasmaContrast(params: dict) BasicTransform
        +PlasmaShadow(params: dict) BasicTransform
        +Rain(params: dict) BasicTransform
        +SaltAndPepper(params: dict) BasicTransform
        +Saturation(params: dict) BasicTransform
        +Snow(params: dict) BasicTransform
        +OpticalDistortion(params: dict) BasicTransform
        +Shear(params: dict) BasicTransform
        +ThinPlateSpline(params: dict) BasicTransform
        +__call__(transform: BasicTransform, video: np.ndarray) np.ndarray
    }

    note for AlbumentationsVideoImpl "Applies Albumentations augmentations to video arrays, utilizing CPU."
Loading

File-Level Changes

Change Details Files
Added video reading functionalities for OpenCV, TorchVision, and Kornia, including float16 conversion for TorchVision and Kornia.
  • Added read_video_cv2 to read videos using OpenCV.
  • Added read_video_torch to read videos using TorchVision.
  • Added read_video_torch_float16 to read videos using TorchVision and convert to float16.
  • Added read_video_kornia to read videos using Kornia.
  • Modified read_img_kornia to convert to float16.
  • Added get_video_loader to select the appropriate video loader based on the library.
  • Updated error message for unsupported libraries in get_video_loader.
benchmark/utils.py
Added video benchmark runner.
  • Created VideoBenchmarkRunner class to handle video benchmarking.
  • Implemented video loading, transform application, and performance measurement.
  • Added adaptive warmup to stabilize performance measurements.
  • Included metadata collection for system info, library versions, and benchmark parameters.
  • Added command-line interface for running video benchmarks.
  • Added logic to skip problematic transforms for Kornia and TorchVision due to compatibility issues.
benchmark/video_runner.py
Added video transform implementations for Albumentations, Kornia, and TorchVision.
  • Created AlbumentationsVideoImpl class with implementations of various transforms.
  • Created KorniaVideoImpl class with implementations of various transforms, including device handling and float16 conversion.
  • Created TorchvisionVideoImpl class with implementations of various transforms, including device handling and float16 conversion.
  • Implemented the __call__ method in each class to apply the transform to a video tensor or NumPy array.
benchmark/transforms/albumentations_video_impl.py
benchmark/transforms/kornia_video_impl.py
benchmark/transforms/torchvision_video_impl.py
Updated transform specifications to be compatible with both images and videos.
  • Modified RandomResizedCrop transform spec to use size instead of separate height and width.
  • Reused TRANSFORM_SPECS for both images and videos.
benchmark/transforms/specs.py
Updated transform implementations to use the size parameter for RandomResizedCrop and removed pad_if_needed from CenterCrop.
  • Modified RandomResizedCrop in torchvision_impl.py to use size.
  • Removed pad_if_needed from CenterCrop128 in torchvision_impl.py.
  • Modified RandomResizedCrop in kornia_impl.py to use size.
  • Removed pad_if_needed from CenterCrop128 in kornia_impl.py.
  • Modified RandomResizedCrop in albumentations_impl.py to use size.
benchmark/transforms/torchvision_impl.py
benchmark/transforms/kornia_impl.py
benchmark/transforms/albumentations_impl.py
Added scripts for running video benchmarks and comparing results.
  • Created run_video_single.sh to run a single video benchmark for a given library.
  • Created run_video_all.sh to run video benchmarks for all supported libraries.
  • Created compare_video_results.py to compare video benchmark results and generate a markdown table.
run_video_single.sh
run_video_all.sh
tools/compare_video_results.py
Added video-specific requirements files and updated the main requirements file.
  • Created kornia-video.txt with Kornia-specific video dependencies.
  • Created torchvision-video.txt with TorchVision-specific video dependencies.
  • Created video.txt with common video dependencies.
  • Updated pyproject.toml to ignore new linting errors.
requirements/kornia-video.txt
requirements/torchvision-video.txt
requirements/video.txt
pyproject.toml
Updated pre-commit configuration and added type stubs for setuptools.
  • Updated ruff pre-commit hook to version v0.9.10.
  • Updated pyproject-fmt pre-commit hook to version v2.5.1.
  • Added types-setuptools as an additional dependency for mypy pre-commit hook.
.pre-commit-config.yaml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @ternaus - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider adding a script to automatically download sample videos for benchmarking.
  • It might be helpful to include a README file explaining how to run the video benchmarks and interpret the results.
Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

return torch.tensor(data, device=device, dtype=dtype)


class KorniaVideoImpl:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider using a mapping of transform names to factory lambdas to reduce code duplication and improve maintainability by replacing static methods with calls to a central transform creation function, handling special cases separately if needed .

Consider reducing duplication by using a mapping of transform names to their corresponding factory lambdas. For example:

AUG_MAP: dict[str, Callable[[dict[str, Any]], Kaug.AugmentationBase2D]] = {
    "ColorJitter": lambda p: Kaug.ColorJitter(
        brightness=p["brightness"],
        contrast=p["contrast"],
        saturation=p["saturation"],
        hue=p["hue"],
        p=1,
        same_on_batch=True
    ).to(device),
    "AutoContrast": lambda p: Kaug.RandomAutoContrast(p=1, same_on_batch=True).to(device),
    # ... add other mappings similarly ...
}

def create_transform(name: str, params: dict[str, Any]) -> Kaug.AugmentationBase2D:
    try:
        return AUG_MAP[name](params)
    except KeyError:
        raise ValueError(f"Unknown transform: {name}")

You can then replace the many static methods with calls to create_transform. For transforms with special logic, consider overriding or handling those cases separately. This approach preserves functionality while reducing the boilerplate and complexity.

Comment on lines 33 to 35
if std is not None:
return f"{time_ms:.2f} ± {std:.2f}"
return f"{time_ms:.2f}"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): We've found these issues:

Suggested change
if std is not None:
return f"{time_ms:.2f} ± {std:.2f}"
return f"{time_ms:.2f}"
return f"{time_ms:.2f} ± {std:.2f}" if std is not None else f"{time_ms:.2f}"

@ternaus ternaus merged commit 97fa607 into main Mar 11, 2025
1 check passed
@ternaus ternaus deleted the add_benchmark_on_video branch March 11, 2025 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant