r""" Sampler that samples indices in a way that groups together features of the dataset of roughly the same length while keeping a bit of randomness.
| 109 | |
| 110 | # modified from https://github.com/haotian-liu/LLaVA/blob/main/llava/train/llava_trainer.py#L99 |
| 111 | class LengthGroupedSampler(Sampler): |
| 112 | r""" |
| 113 | Sampler that samples indices in a way that groups together features of the dataset of roughly the same length while |
| 114 | keeping a bit of randomness. |
| 115 | """ |
| 116 | |
| 117 | def __init__( |
| 118 | self, |
| 119 | batch_size: int, |
| 120 | world_size: int, |
| 121 | dataset: Optional[Dataset] = None, |
| 122 | lengths: Optional[List[int]] = None, |
| 123 | model_input_name: Optional[str] = None, |
| 124 | generator=None, |
| 125 | ): |
| 126 | if dataset is None and lengths is None: |
| 127 | raise ValueError('One of dataset and lengths must be provided.') |
| 128 | |
| 129 | self.batch_size = batch_size |
| 130 | if lengths is None: |
| 131 | model_input_name = model_input_name if model_input_name is not None else 'input_ids' |
| 132 | if ( |
| 133 | not (isinstance(dataset[0], dict) or isinstance(dataset[0], BatchEncoding)) |
| 134 | or model_input_name not in dataset[0] |
| 135 | ): |
| 136 | raise ValueError( |
| 137 | 'Can only automatically infer lengths for datasets whose items are dictionaries with an ' |
| 138 | f"'{model_input_name}' key." |
| 139 | ) |
| 140 | lengths = [len(feature[model_input_name]) for feature in dataset] |
| 141 | elif isinstance(lengths, torch.Tensor): |
| 142 | logger.info( |
| 143 | 'If lengths is a torch.Tensor, LengthGroupedSampler will be slow. Converting lengths to List[int]...' |
| 144 | ) |
| 145 | lengths = lengths.tolist() |
| 146 | self.world_size = world_size |
| 147 | self.lengths = lengths |
| 148 | self.generator = generator |
| 149 | |
| 150 | def __len__(self): |
| 151 | return len(self.lengths) |
| 152 | |
| 153 | def __iter__(self): |
| 154 | indices = get_length_grouped_indices(self.lengths, self.batch_size, self.world_size, generator=self.generator) |
| 155 | return iter(indices) |
| 156 | |
| 157 | # patch trainer |
| 158 | def _get_train_sampler(self) -> Optional[torch.utils.data.Sampler]: |
no outgoing calls
no test coverage detected