Optimizing FFCV cho Tải Dữ Liệu Hình Ảnh Lớn

FFCV là một hệ thống tải dữ liệu trực tiếp giúp tăng đáng kể tốc độ truyền dữ liệu trong quá trình huấn luyện mô hình:

  • Đào tạo mô hình ImageNet trên một GPU mất 35 phút (chi phí khoảng 98 cent mỗi mô hình trên AWS)
  • Đào tạo mô hình CIFAR-10 trên một GPU mất 36 giây (chi phí khoảng 2 cent mỗi mô hình trên AWS)

Cài Đặt Môi Trường

Theo tài liệu chính thức: https://docs.ffcv.io/

1. conda-forge

conda create -n ffcv python=3.10 pkg-config opencv -c conda-forge --override-channels
conda activate ffcv

Lưu ý: pkg-config giúp tìm thấy opencv4.pc, cần thiết để biên dịch ffcv.

2. torch

conda install pytorch==2.4.0 torchvision==0.19.0 torchaudio==2.4.0 pytorch-cuda=11.8 -c pytorch -c nvidia

3. ffcv

pip install ffcv

Quy Trình Chi Tiết

Dưới đây là một số bước tôi đã tổng hợp từ tài liệu chính thức.

1. Lưu trữ Dữ Liệu dưới Định dạng FFCV

from ffcv.writer import DatasetWriter
from ffcv.fields import RGBImageField
from torchvision import transforms
from PIL import Image
from torch.utils.data import Dataset
import os

class ImagePairSet(Dataset):
    def __init__(self, source_folder, target_folder, transform=None):
        self.source_folder = source_folder
        self.target_folder = target_folder
        self.transform = transform
        self.file_names = sorted(os.listdir(source_folder))

    def __len__(self):
        return len(self.file_names)

    def __getitem__(self, index):
        source_path = os.path.join(self.source_folder, self.file_names[index])
        target_path = os.path.join(self.target_folder, self.file_names[index])
        source_image = Image.open(source_path).convert('RGB')
        target_image = Image.open(target_path).convert('RGB')

        if self.transform:
            source_image = self.transform(source_image)
            target_image = self.transform(target_image)

        return source_image, target_image

source_folder = 'xx/source/'
target_folder = 'xx/target/'

dataset = ImagePairSet(source_folder, target_folder, transform=None)
writer = DatasetWriter('data.beton', {
    'source': RGBImageField(write_mode='smart'),
    'target': RGBImageField(write_mode='smart')
})
writer.from_indexed_dataset(dataset)

2. Kiểm Tra Việc Chuyển Đổi

from ffcv.loader import Loader, OrderOption

loader = Loader('data.beton', batch_size=32, num_workers=4, order=OrderOption.RANDOM)

for batch in loader:
    print(type(batch))
    source_images, target_images = batch[0], batch[1]
    print(source_images.shape, target_images.shape)
    break

3. Thay Thế DataLoader của PyTorch

training_loader = Loader(
    dataset_config["beton_file"],
    batch_size=args.batch_size,
    num_workers=4,
    order=OrderOption.RANDOM,
    pipelines={
        'source': [SimpleRGBImageDecoder(), ToTensor(), ToTorchImage(), Convert(torch.float32),
                   torchvision.transforms.Normalize(CIFAR_MEAN, CIFAR_STD), ToDevice(torch.device('cuda:0'))],
        'target': [SimpleRGBImageDecoder(), ToTensor(), ToTorchImage(), Convert(torch.float32),
                   torchvision.transforms.Normalize(CIFAR_MEAN, CIFAR_STD), ToDevice(torch.device('cuda:0'))],
    },
    drop_last=True
)

4. Tạo Các Thao Tác Pipeline Tùy Chỉnh

Ngoài các thao tác được cung cấp sẵn, đôi khi chúng ta cần triển khai các thao tác tiền xử lý và tăng cường dữ liệu riêng.

  • Khai báo phương thức `declare_state_and_memory` sau mỗi hàm
  • Kế thừa từ `Operation` trong `ffcv.pipeline.operation`

Ví dụ đơn giản về một thao tác chuẩn hóa:

class NormalizeFirstChannel(Operation):
    def __init__(self, mean_value, std_value):
        super().__init__()
        self.mean = mean_value
        self.std = std_value

    def generate_code(self):
        mean = self.mean
        std = self.std
        def normalize(images, *_):
            B, C, H, W = images.shape
            for i in range(B):
                images[i, 0, :, :] = (images[i, 0, :, :] - mean) / std
            return images

        return normalize

    def declare_state_and_memory(self, previous_state: State):
        return previous_state, 0

Thẻ: FFCV ImageDataLoading PerformanceOptimization

Đăng vào ngày 21 tháng 6 lúc 04:04