Benchmarking script for image pipeline - #1441
Conversation
Greptile OverviewGreptile SummaryThis PR adds a comprehensive benchmarking script for the image curation pipeline and renames the Key Changes
The benchmark script properly addresses all previous feedback by including Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant BF as Benchmark Framework
participant Script as image_pipeline_benchmark.py
participant Ray as RayClient
participant Exec as Executor (Xenna/RayData)
participant Pipeline as Image Pipeline
participant FP as FilePartitioningStage
participant IR as ImageReaderStage
participant IE as ImageEmbeddingStage
participant AF as AestheticFilterStage
participant IW as ImageWriterStage
participant Utils as utils.write_benchmark_results
BF->>Script: Execute with --benchmark-results-path
Script->>Ray: start()
Script->>Script: parse arguments
Script->>Script: run_image_pipeline_benchmark(args)
Script->>Exec: setup_executor(args.executor)
Exec-->>Script: executor instance
Script->>Pipeline: create_image_curation_pipeline(args)
Pipeline->>FP: add FilePartitioningStage
Pipeline->>IR: add ImageReaderStage (dali_batch_size)
Pipeline->>IE: add ImageEmbeddingStage
Pipeline->>AF: add ImageAestheticFilterStage
Pipeline->>IW: add ImageWriterStage
Pipeline-->>Script: pipeline instance
Script->>Pipeline: pipeline.run(executor)
Pipeline->>FP: process tar files
FP->>IR: ImageBatch with tar paths
IR->>IE: ImageBatch with image_data
IE->>AF: ImageBatch with embeddings
AF->>IW: Filtered ImageBatch
IW-->>Pipeline: output_tasks
Pipeline-->>Script: output_tasks
Script->>Script: Calculate metrics (num_images_processed, throughput)
Script->>Utils: write_benchmark_results(results, path)
Utils->>BF: Write params.json, metrics.json, tasks.pkl
Script->>Ray: stop()
Script-->>BF: Exit code (0=success, 1=failure)
|
Additional Comments (1)
Other benchmark entries define these to properly configure resources and validate results. |
Additional Comments (1)
|
|
/ok to test 96098b2 |
|
/ok to test d316259 |
| num_threads=16, # More threads for I/O | ||
| num_gpus_per_worker=0.25, |
There was a problem hiding this comment.
hardcoded num_threads=16 and num_gpus_per_worker=0.25 - consider making these configurable via command-line arguments for flexibility
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
abhinavg4
left a comment
There was a problem hiding this comment.
Overall, Looks good to me.
|
|
||
| from loguru import logger | ||
| from utils import setup_executor, write_benchmark_results |
There was a problem hiding this comment.
[P0] utils import likely fails when invoked by the benchmarking runner
This script uses from utils import setup_executor, write_benchmark_results, but in this repo utils.py lives at benchmarking/scripts/utils.py and isn't a package. If the benchmark runner executes image_pipeline_benchmark.py without setting the working directory / PYTHONPATH to include benchmarking/scripts, this will raise ModuleNotFoundError: No module named 'utils'.
This is environment-dependent: it will work if cwd is benchmarking/scripts/ (or that dir is on PYTHONPATH), and fail otherwise. Consider importing via an explicit module path (or otherwise aligning with how the benchmarking harness invokes scripts).
| """Main entry point for image pipeline benchmark.""" | ||
| ray_client = RayClient() | ||
| ray_client.start() |
There was a problem hiding this comment.
[P2] Ray is started unconditionally even for non-Ray executors
main() always does ray_client.start()/stop(), even when --executor=xenna. If the benchmark framework runs multiple entries back-to-back or Ray is already started externally, this can add overhead and may error depending on Ray configuration. Consider starting/stopping Ray only when the selected executor needs it (or making it idempotent).
| # Calculate metrics from output tasks | ||
| # Count total images processed (sum of images in each ImageBatch) | ||
| num_images_processed = sum( | ||
| len(task.data) for task in output_tasks if task.data is not None | ||
| ) |
There was a problem hiding this comment.
[P2] num_images_processed is derived from output tasks, which may undercount total processed
The benchmark reports num_images_processed as sum(len(task.data) for task in output_tasks ...). If later stages filter/drop items (e.g., aesthetic filter), the final output tasks may represent kept/written images rather than read/processed images. This makes the metric ambiguous and could regress silently if filter thresholds change.
If the intention is “images written”, it may be worth naming it accordingly or also emitting a separate “images_read/seen” metric from an earlier stage.
| otherwise falls back to CPU decoding. | ||
| """ | ||
|
|
||
| batch_size: int = 100 | ||
| dali_batch_size: int = 100 | ||
| verbose: bool = True |
There was a problem hiding this comment.
[P2] Renaming batch_size to dali_batch_size may break external call sites
Within this repo you updated tests/tutorials, but any downstream users instantiating ImageReaderStage(batch_size=...) will now get an unexpected keyword argument error. If this is intended, ignore; otherwise consider keeping batch_size as a deprecated alias (or documenting the breaking change in release notes).
|
/ok to test 6c2ce9a |
|
/ok to test ae0b502 |
|
/ok to test c859e54 |
| ray_client = RayClient() | ||
| ray_client.start() |
There was a problem hiding this comment.
Wont this start the ray cluster, dont we assume cluster is started somewhere else in the framework ? THis seems incorrect to me.
There was a problem hiding this comment.
Right.
This is redundant.
As I understand from here, link, ray_client.start() will be skipped when there is an already running Ray, so it wouldn't affect the run.
But I will remove this in the amendment PR.
| "aesthetic_batch_size": args.aesthetic_batch_size, | ||
| "aesthetic_gpus_per_worker": args.aesthetic_gpus_per_worker, | ||
| "aesthetic_threshold": args.aesthetic_threshold, | ||
| "images_per_tar": args.images_per_tar, |
There was a problem hiding this comment.
We dont track reader_num_threads on the reader here . Benchmark is dependent on reader_num_threads. Please track that too.
Can you add "args": vars(args) too , to catch problems
There was a problem hiding this comment.
I can add this into an amendment PR.
Description
Usage
# Add snippet demonstrating usageChecklist