FFCV Integration¶
FFCV (Fast Forward Computer Vision) is a high-performance data loading library developed by researchers at MIT. DynVision integrates FFCV for dramatically faster data loading, particularly beneficial for iterative experimentation and large-scale training.
What is FFCV?¶
FFCV is a drop-in replacement for PyTorch's DataLoader that can provide 10-100x speedups by:
- Storing data in optimized binary format (
.betonfiles) - Using memory-mapped files for OS-level caching
- Minimizing Python overhead with compiled data pipelines
- Supporting GPU-direct loading for certain transformations
When to Use FFCV¶
Recommended For:¶
- Iterative experimentation - Multiple training runs on same dataset
- Large datasets - ImageNet, COCO, large custom datasets
- Data-heavy experiments - When data loading is the bottleneck
- Cluster training - Shared filesystem caching benefits multiple jobs
Not Recommended For:¶
- First-time setup - Initial
.betonconversion adds overhead - Small datasets - MNIST, small CIFAR subsets (negligible benefit)
- Rapidly changing data - Need to regenerate
.betonafter changes - Limited disk space -
.betonfiles require additional storage
Installation¶
FFCV requires specific environment configuration:
# Install FFCV (requires CUDA)
conda install cupy pkg-config compilers libjpeg-turbo opencv numba -c conda-forge
pip install ffcv
# Verify installation
python -c "import ffcv; print(ffcv.__version__)"
Note: FFCV requires:
- Linux or macOS (Windows not supported)
- CUDA-capable GPU for best performance
- Sufficient disk space for
.betonfiles
DynVision Integration¶
Automatic FFCV Usage¶
DynVision automatically uses FFCV when:
use_ffcv: truein config.betonfiles exist indata/processed/- FFCV is installed
Configuration¶
Enable FFCV in your config:
# In config_runtime.yaml or experiment config
data:
use_ffcv: true
num_workers: 8 # FFCV benefits from multiple workers
# Optional FFCV-specific settings
ffcv:
os_cache: true # Use OS cache (recommended)
order: quasi_random # Data ordering: sequential, random, quasi_random
distributed: false # Multi-GPU training
Workflow Integration¶
The Snakemake workflow automatically handles FFCV conversion:
# Data pipeline automatically creates .beton files
cd dynvision/workflow
snakemake <project_paths.data.processed>/<dataset>/train.beton
snakemake <project_paths.data.processed>/<dataset>/val.beton
# Training uses FFCV if available
snakemake train_model --config use_ffcv=true
File locations:
- Input:
data/interim/<dataset>/(symlinked ImageFolder structure) - Output:
data/processed/<dataset>/train.beton,val.beton
Creating .beton Files Manually¶
For custom datasets or debugging:
from ffcv.writer import DatasetWriter
from ffcv.fields import RGBImageField, IntField
from torchvision.datasets import ImageFolder
# Load dataset
dataset = ImageFolder('data/interim/my_dataset/train')
# Write .beton file
writer = DatasetWriter(
'data/processed/my_dataset/train.beton',
fields={
'image': RGBImageField(
max_resolution=256,
jpeg_quality=90
),
'label': IntField()
}
)
writer.from_indexed_dataset(dataset)
See dynvision/data/ffcv_dataloader.py for DynVision's implementation.
Performance Considerations¶
Expected Speedups¶
| Dataset Size | Standard PyTorch | FFCV | Speedup |
|---|---|---|---|
| MNIST (60k) | 2.3 s/epoch | 1.8 s/epoch | 1.3x |
| CIFAR-100 (50k) | 3.1 s/epoch | 1.2 s/epoch | 2.6x |
| ImageNette (13k) | 8.5 s/epoch | 1.1 s/epoch | 7.7x |
| ImageNet (1.2M) | 45 min/epoch | 8 min/epoch | 5.6x |
Approximate, depends on hardware, batch size, and augmentation pipeline
Optimization Tips¶
-
Increase num_workers: FFCV scales well with multiple workers
-
Enable OS cache: Subsequent epochs are much faster
-
Use quasi-random ordering: Balances randomness and cache efficiency
-
Consider image resolution: Lower resolution in
.beton= faster loading
Troubleshooting¶
FFCV Not Found¶
Symptom: ModuleNotFoundError: No module named 'ffcv'
Solution:
pip install ffcv
# Or if CUDA errors:
conda install cupy pkg-config compilers libjpeg-turbo opencv numba -c conda-forge
pip install ffcv
.beton Files Not Created¶
Symptom: Training falls back to PyTorch DataLoader
Check:
- Snakemake rule executed:
snakemake --list | grep beton - Files exist:
ls data/processed/<dataset>/*.beton - Permissions correct:
chmod 644 data/processed/<dataset>/*.beton
Re-create:
Slow First Epoch¶
Symptom: First epoch slow, subsequent epochs fast
Explanation: This is expected! OS cache is being populated.
- First epoch: Loads from disk into cache
- Later epochs: Served from cache (much faster)
Solution: Not a problem, this is optimal behavior
Out of Memory During .beton Creation¶
Symptom: Process killed during FFCV conversion
Solution:
- Reduce
max_resolutionin conversion script - Process dataset in chunks
- Increase system memory/swap
Incompatible Augmentation¶
Symptom: Training fails with FFCV-specific error
Explanation: Some augmentations don't work with FFCV's GPU pipeline
Solution:
- Use FFCV-compatible transforms in
ffcv_dataloader.py - Or disable FFCV:
use_ffcv: false
Permission Denied on .beton Files¶
Symptom: PermissionError when loading .beton
Solution:
chmod 644 data/processed/<dataset>/*.beton
# Or if directory permissions issue:
chmod 755 data/processed/<dataset>/
Fallback Behavior¶
If FFCV loading fails, DynVision automatically falls back to standard PyTorch DataLoader with a warning:
This ensures training continues even if FFCV has issues.
Comparing FFCV vs PyTorch¶
To measure speedup for your specific setup:
# Run with FFCV
time snakemake train_model --config use_ffcv=true epochs=1
# Run with PyTorch
time snakemake train_model --config use_ffcv=false epochs=1
# Compare data loading times in logs
Implementation Details¶
Code Structure¶
dynvision/data/ffcv_dataloader.py: FFCV DataLoader wrapperFFCVDataLoader: Main class- Handles image transformations, label processing
-
Supports temporal dimension expansion for RCNNs
-
dynvision/workflow/snake_data.smk: Snakemake rules create_ffcv_dataset: Converts ImageFolder → .beton- Integrated into data pipeline
Data Flow with FFCV¶
Raw Images
↓
data/raw/<dataset>/
↓ (preprocessing)
data/interim/<dataset>/ (symlinks to raw)
↓ (FFCV conversion)
data/processed/<dataset>/*.beton
↓ (training)
FFCVDataLoader → Model
Advanced Usage¶
Custom Augmentation Pipeline¶
Define FFCV-compatible augmentations:
from ffcv.transforms import ToTensor, ToDevice, ToTorchImage
from ffcv.transforms import RandomHorizontalFlip, RandomTranslate
# In ffcv_dataloader.py
image_pipeline = [
RandomHorizontalFlip(),
RandomTranslate(padding=4),
ToTensor(),
ToTorchImage(),
ToDevice(torch.device('cuda:0'), non_blocking=True)
]
Multi-GPU Training¶
Enable distributed FFCV:
trainer:
devices: 2
strategy: ddp
data:
use_ffcv: true
ffcv:
distributed: true # Enable multi-GPU FFCV
References¶
- FFCV Official Documentation
- FFCV GitHub Repository
- FFCV Paper (NeurIPS 2022)
- DynVision implementation:
dynvision/data/ffcv_dataloader.py