| |
| |
| |
| |
| |
|
|
| from functools import partial |
| from typing import Callable, Optional |
|
|
| import torch |
| from data.dataset import build_flickr, build_gqa, collate_fn |
| from data.transforms import MDETRTransform |
| from pytorch_lightning import LightningDataModule |
| from torch.utils.data import DataLoader, DistributedSampler |
| from transformers import RobertaTokenizerFast |
|
|
|
|
| class FlickrDataModule(LightningDataModule): |
| def __init__(self, dataset_config, tokenizer: Optional[Callable] = None): |
| super().__init__() |
| self.dataset_config = dataset_config |
| self.distributed = dataset_config.distributed |
| self.batch_size = dataset_config.batch_size |
| self.tokenizer = tokenizer |
|
|
| def setup(self, stage: Optional[str] = None): |
| if self.tokenizer is None: |
| self.tokenizer = RobertaTokenizerFast.from_pretrained("roberta-base") |
| self.transform = MDETRTransform(self.tokenizer, is_train=False) |
| self.val = build_flickr( |
| "val", self.tokenizer, self.transform, self.dataset_config |
| ) |
|
|
| def val_dataloader(self): |
| if self.distributed: |
| sampler = DistributedSampler(self.val, shuffle=False) |
| else: |
| sampler = torch.utils.data.SequentialSampler(self.val) |
|
|
| data_loader_val = DataLoader( |
| self.val, |
| batch_size=self.batch_size, |
| sampler=sampler, |
| drop_last=False, |
| collate_fn=partial(collate_fn, self.tokenizer), |
| ) |
| return data_loader_val |
|
|
|
|
| class GQADataModule(LightningDataModule): |
| def __init__(self, dataset_config, tokenizer: Optional[Callable] = None): |
| super().__init__() |
| self.dataset_config = dataset_config |
| self.distributed = dataset_config.distributed |
| self.batch_size = dataset_config.batch_size |
| self.epoch_chunks = dataset_config.epoch_chunks |
| self.tokenizer = tokenizer |
|
|
| def setup(self, stage: Optional[str] = None): |
| if self.tokenizer is None: |
| self.tokenizer = RobertaTokenizerFast.from_pretrained("roberta-base") |
| self.train_transform = MDETRTransform(self.tokenizer, is_train=True) |
| self.val_transform = MDETRTransform(self.tokenizer, is_train=False) |
|
|
| if stage == "train": |
| self.train = build_gqa( |
| stage, self.tokenizer, self.train_transform, self.dataset_config |
| ) |
| if stage == "val": |
| self.val = build_gqa( |
| stage, self.tokenizer, self.val_transform, self.dataset_config |
| ) |
|
|
| def train_dataloader(self): |
| |
| if self.epoch_chunks > 0: |
| print( |
| f"Splitting the training set into {self.epoch_chunks} chunks of size approximately " |
| f" {len(self.train) // self.epoch_chunks}" |
| ) |
| chunks = torch.chunk(torch.arange(len(self.train)), self.epoch_chunks) |
| datasets = [ |
| torch.utils.data.Subset(self.train, chunk.tolist()) for chunk in chunks |
| ] |
| if self.distributed: |
| self.samplers_train = [ |
| DistributedSampler(ds, shuffle=True) for ds in datasets |
| ] |
| else: |
| self.samplers_train = [ |
| torch.utils.data.RandomSampler(ds) for ds in datasets |
| ] |
|
|
| batch_samplers_train = [ |
| torch.utils.data.BatchSampler( |
| sampler_train, self.batch_size, drop_last=True |
| ) |
| for sampler_train in self.samplers_train |
| ] |
| assert len(batch_samplers_train) == len(datasets) |
| train_dataloaders = [ |
| DataLoader( |
| ds, |
| batch_sampler=batch_sampler_train, |
| collate_fn=partial(collate_fn, self.tokenizer), |
| ) |
| for ds, batch_sampler_train in zip(datasets, batch_samplers_train) |
| ] |
| return train_dataloaders |
| else: |
| if self.distributed: |
| self.sampler_train = DistributedSampler(self.train, shuffle=True) |
| else: |
| self.sampler_train = torch.utils.data.RandomSampler(self.train) |
| batch_sampler_train = torch.utils.data.BatchSampler( |
| self.sampler_train, self.batch_size, drop_last=True |
| ) |
| train_dataloader = DataLoader( |
| self.train, |
| batch_sampler=batch_sampler_train, |
| collate_fn=partial(collate_fn, self.tokenizer), |
| ) |
| return train_dataloader |
|
|
| def val_dataloader(self): |
| if self.distributed: |
| sampler = DistributedSampler(self.val, shuffle=False) |
| else: |
| sampler = torch.utils.data.SequentialSampler(self.val) |
|
|
| data_loader_val = DataLoader( |
| self.val, |
| batch_size=self.batch_size, |
| sampler=sampler, |
| drop_last=False, |
| collate_fn=partial(collate_fn, self.tokenizer), |
| ) |
| return data_loader_val |
|
|