RGB Input Pipelines: Throughput, GPU Memory, and Transformation Coverage
Organizations: Albumentations LLC
Abstract
An image-augmentation pipeline must deliver a complete batch before a model can use it. We compare seven input paths from five libraries, starting with RGB JPEG files and ending with a synchronized CUDA float16 batch. We manually matched transformation recipes and parameters across libraries to make the workloads as comparable as possible. The experiment uses 57 selected recipes, a batch size of 256, and one NVIDIA L4 machine. Throughput and peak process GPU memory are recorded together in 759 measurements. On the 11 recipes shared by all paths, DALI and AlbumentationsX have median throughputs of 5,029 and 4,679 images/s, with median peak GPU memory of 2,086 and 1,852 MiB. Broader pairwise comparisons favor AlbumentationsX on 26/26 TorchVision recipes, 50/51 Kornia recipes, and 25/26 Pillow recipes. DALI is faster than AlbumentationsX on all 22 shared recipes, with a median throughput ratio of 1.18x. A separate census reports coverage of the 118 entries in a selected AlbumentationsX RGB catalog. The study measures input preparation at fixed settings; it does not measure model training, numerical equivalence, or the best attainable configuration of each library. Benchmark code: https://github.com/albumentations-team/benchmark.
Figures & tables
| Control | Frozen setting |
|---|---|
| Input and access | 10,000 sorted ImageNet-validation JPEGs; prewarmed; shared per-seed permutation |
| Output | CUDA float16 BCHW, ; GPU normalization |
| DataLoader paths | 15 workers; persistent workers; pinned memory; prefetch factor 2 |
| DALI | 15 pipeline threads; native prefetch queue depth 2; native file reader and mixed decoder |
| Timing and repeats | One warm-up batch; 32 measured batches; seeds 137, 138, 139 |
| Machine | Standard g2-standard-16 , one NVIDIA L4; 16 vCPUs, 64 GB host memory |
| Path | Decoder | Before transfer | H2D dtype | On GPU |
|---|---|---|---|---|
| AlbumentationsX | SimpleJPEG | uint8 recipe per image | uint8 | Layout conversion and Normalize |
| Pillow CPU | Pillow | uint8 recipe per image; PILToTensor | uint8 | Normalize |
| TorchVision CPU | TorchVision I/O | uint8 recipe per image | uint8 | Normalize |
| TorchVision GPU | TorchVision I/O | Shape-forming prefix per image | uint8 | Cast to float16; remaining transforms per image; stack; Normalize |
| Kornia CPU | TorchVision I/O | float32 recipe per image; collate; cast to float16 | float16 | Normalize |
| Kornia GPU | TorchVision I/O | float32 shape prefix per image; collate; cast to float16 | float16 | Remaining transforms on batch; Normalize |
| Library | Matched AX catalog entries | Census version |
|---|---|---|
| AlbumentationsX | 118 | 2.3.7 |
| Kornia | 46 | 0.8.3 |
| TorchVision | 38 | 0.28.0 |
| Pillow | 23 | 12.3.0 |
Appendix figures & tables10 assets
Supplementary material from the paper’s appendix.
Appendix
| Implementation | Version recorded in cells |
|---|---|
| AlbumentationsX | 2.4.2 |
| Pillow CPU | 12.3.0 |
| TorchVision CPU | 0.28.0+cu130 |
| TorchVision GPU | 0.28.0+cu130 |
| Kornia CPU | 0.8.3 |
| Kornia GPU | 0.8.3 |
| Recipe prefix | Declared parameters and randomness scope |
|---|---|
| R01 Resize | Resize : target_size =224; interpolation ="bilinear". Sampling: deterministic. |
| R02 RandomCrop224 | RandomCrop224 : height =224; width =224. Sampling: per-image. |
| R03 RandomResizedCrop | RandomResizedCrop : size =[224, 224]; width =224; scale =[0.08, 1.0]; ratio =[0.75, 1.3333333333333333]; interpolation ="bilinear". Sampling: per-image. |
| R04 RandomCrop224 HorizontalFlip | RandomCrop224 : height =224; width =224. Sampling: per-image. HorizontalFlip : no parameters. Sampling: deterministic. |
| R05 RandomCrop224 VerticalFlip | RandomCrop224 : height =224; width =224. Sampling: per-image. VerticalFlip : no parameters. Sampling: deterministic. |
| R06 Pad RandomCrop224 | Pad : padding =10; fill =0; border_mode ="constant". Sampling: deterministic. RandomCrop224 : height =224; width =224. Sampling: per-image. |
| Recipe | Throughput (images/s) | GPU memory (MiB) | ||||
|---|---|---|---|---|---|---|
| Median | Min | Max | Median | Min | Max | |
| R01 | 4,751 | 3,576 | 7,759 | 1,852 | 1,852 | 1,852 |
| R02 | 4,740 | 4,488 | 4,808 | 1,852 | 1,852 | 1,852 |
| R03 | 4,785 | 4,699 | 4,903 | 1,852 | 1,852 | 1,852 |
| R04 | 4,723 | 4,640 | 4,939 | 1,852 | 1,852 | 1,852 |
| R05 | 4,907 | 4,859 | 5,060 | 1,852 | 1,852 | 1,852 |
| Recipe | Throughput (images/s) | GPU memory (MiB) | ||||
|---|---|---|---|---|---|---|
| Median | Min | Max | Median | Min | Max | |
| R01 | 2,390 | 1,858 | 2,406 | 1,814 | 1,814 | 1,814 |
| R02 | 3,768 | 3,251 | 3,799 | 1,814 | 1,814 | 1,814 |
| R03 | 2,721 | 2,662 | 2,788 | 1,814 | 1,814 | 1,814 |
| R04 | 3,759 | 3,236 | 3,818 | 1,814 | 1,814 | 1,814 |
| R05 | 3,567 | 3,510 | 3,737 | 1,814 | 1,814 | 1,814 |
| Recipe | Throughput (images/s) | GPU memory (MiB) | ||||
|---|---|---|---|---|---|---|
| Median | Min | Max | Median | Min | Max | |
| R01 | 3,671 | 3,577 | 3,736 | 1,814 | 1,814 | 1,814 |
| R02 | 4,424 | 4,328 | 4,522 | 1,814 | 1,814 | 1,814 |
| R03 | 3,518 | 3,496 | 3,667 | 1,814 | 1,814 | 1,814 |
| R04 | 4,207 | 3,247 | 4,432 | 1,814 | 1,814 | 1,814 |
| R05 | 4,319 | 4,094 | 4,363 | 1,814 | 1,814 | 1,814 |
| Recipe | Throughput (images/s) | GPU memory (MiB) | ||||
|---|---|---|---|---|---|---|
| Median | Min | Max | Median | Min | Max | |
| R01 | 3,852 | 3,526 | 3,883 | 1,814 | 1,814 | 1,814 |
| R02 | 4,375 | 4,269 | 4,495 | 1,814 | 1,814 | 1,814 |
| R03 | 3,558 | 3,509 | 3,604 | 1,814 | 1,814 | 1,814 |
| R04 | 4,374 | 4,319 | 4,498 | 1,972 | 1,972 | 1,972 |
| R05 | 4,594 | 4,525 | 4,616 | 1,972 | 1,972 | 1,972 |
| Recipe | Throughput (images/s) | GPU memory (MiB) | ||||
|---|---|---|---|---|---|---|
| Median | Min | Max | Median | Min | Max | |
| R01 | 2,063 | 1,961 | 2,636 | 1,776 | 1,776 | 1,776 |
| R02 | 2,073 | 2,050 | 2,189 | 1,776 | 1,776 | 1,776 |
| R03 | 1,776 | 1,760 | 1,814 | 1,776 | 1,776 | 1,776 |
| R04 | 2,011 | 2,007 | 2,031 | 1,776 | 1,776 | 1,776 |
| R05 | 1,980 | 1,531 | 2,007 | 1,776 | 1,776 | 1,776 |
| Recipe | Throughput (images/s) | GPU memory (MiB) | ||||
|---|---|---|---|---|---|---|
| Median | Min | Max | Median | Min | Max | |
| R01 | 1,990 | 1,944 | 2,023 | 1,776 | 1,776 | 1,776 |
| R02 | 2,107 | 2,063 | 2,172 | 1,776 | 1,776 | 1,776 |
| R03 | 1,746 | 1,446 | 1,799 | 1,776 | 1,776 | 1,776 |
| R04 | 2,084 | 2,032 | 2,142 | 1,850 | 1,850 | 1,850 |
| R05 | 2,151 | 2,086 | 2,229 | 1,850 | 1,850 | 1,850 |
| Recipe | Throughput (images/s) | GPU memory (MiB) | ||||
|---|---|---|---|---|---|---|
| Median | Min | Max | Median | Min | Max | |
| R01 | 5,070 | 5,010 | 5,076 | 1,766 | 1,766 | 1,958 |
| R02 | 5,029 | 5,025 | 5,036 | 1,958 | 1,958 | 2,022 |
| R03 | 5,091 | 5,076 | 5,121 | 2,022 | 2,022 | 2,022 |
| R04 | 4,990 | 4,985 | 5,044 | 2,022 | 2,022 | 2,022 |
| R05 | 4,992 | 4,969 | 5,041 | 2,022 | 2,022 | 2,022 |
| AX entry | Kornia | TorchVision | Pillow |
|---|---|---|---|
| AdditiveNoise | — | — | — |
| AdvancedBlur | — | — | — |
| Affine | RandomAffine / RandomShear | RandomAffine | Image.transform(AFFINE) |
| AtLeastOneBBoxRandomCrop | — | RandomIoUCrop | — |
| AtmosphericFog | — | — | — |
| AutoContrast | RandomAutoContrast | RandomAutocontrast | ImageOps.autocontrast |
Data Augmentation
Data augmentation expands or transforms training examples to improve learning, data efficiency, and robustness to distribution shifts.
See all 255 papersSingle-Thread JPEG Decoder Benchmarks Mis-Evaluate ML Data Loaders
DataLoader throughput for eligible decoders at worker counts , and decoder skip behavior. The evaluation protocol changes the supported conclusion. On Neoverse V2, imageio is ninth in single-thread throughput yet lands in the top DataLoader tier with torchvision; on Zen 4, torchvision rises from seventh single-thread to the top measured DataLoader tier; on Neoverse N1, imagecodecs is the single-thread leader but fifth at peak DataLoader throughput. We also find that worker-count conclusions differ between Zen 4 and Zen 5, TensorFlow has a large single-thread ARM penalty, and strict native JPEG decoders/wrappers reject the same rare ImageNet JPEG. For PyTorch DataLoader workloads, torchvision and simplejpeg form the strongest measured zero-skip tier: torchvision has the highest mean normalized throughput, while simplejpeg has the highest minimum. OpenCV remains a robust general-purpose fallback above 90% of the platform-local winner on every tested CPU. We release raw JSON, generated tables/figures, and an executable local/cloud benchmark framework.