Error when using IterableDataset as train_dataset for Trainer
Author: yeounyi
Pull request: no

Hi, I'm using large train data (parquet format) and want to pass this as `IterableDataset` to `Trainer`.
I managed to make custom `IterableDataset`, but sadly it doesn't work.

```python
import torch
import pyarrow.parquet as pq
from transformers import BatchEncoding

class CustomIterableData(torch.utils.data.dataset.IterableDataset):
    def __init__(self, file_path, tokenizer, with_labels=False):
        super().__init__()
        self.file_path = file_path
        self.tokenizer = tokenizer
        self.with_labels = with_labels

    def process(self, row):
        inputs = str(row[2])
        labels = str(row[4])

        inputs = self.tokenizer(inputs, return_tensors="pt", padding=True, truncation=True)
        self.input_ids = [i.clone().detach() for i in inputs.input_ids]
        self.attention_mask = [i.clone().detach() for i in inputs.attention_mask]

        if self.with_labels:
            yield BatchEncoding({'input_ids': self.input_ids, 'attention_mask': self.attention_mask, 'labels': labels})
        
        yield BatchEncoding({'input_ids': self.input_ids, 'attention_mask': self.attention_mask})
                
    def __iter__(self):
        df = pq.read_table(source = self.file_path)
        for batch in df.to_batches():
            return map(self.process, zip(*batch.columns))

    def __len__(self):
        # yield one row at a time
        return 1 

```

This dataset gives me the error below.

```
File "main10m.py", line 128, in main
    trainer.train()
  File "/opt/conda/lib/python3.7/site-packages/transformers/trainer.py", line 1246, in train
    for step, inputs in enumerate(epoch_iterator):
  File "/opt/conda/lib/python3.7/site-packages/torch/utils/data/dataloader.py", line 517, in __next__
    data = self._next_data()
  File "/opt/conda/lib/python3.7/site-packages/torch/utils/data/dataloader.py", line 557, in _next_data
    data = self._dataset_fetcher.fetch(index)  # may raise StopIteration
  File "/opt/conda/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py", line 35, in fetch
    return self.collate_fn(data)
  File "/opt/conda/lib/python3.7/site-packages/transformers/data/data_collator.py", line 54, in default_data_collator
    features = [vars(f) for f in features]
  File "/opt/conda/lib/python3.7/site-packages/transformers/data/data_collator.py", line 54, in <listcomp>
    features = [vars(f) for f in features]
TypeError: vars() argument must have __dict__ attribute
```

I would appreciate any help!

@sgugger 

Comments:
Can you print the elements you get when iterating through your dataset (and their types)? It seems like there is something wrong here. I'm not familiar with parquet but your iter is only going to return the result of the first of `df.to_batches()`, is that expected?

Note that the `__len__` should not be implemented if possible as it will probably trigger other issues in the Trainer when it sees it.

If I run code below

```python3
ds = CustomIterableData(file_path, tokenizer, cat_info_path = cat_info_path)

features = []
for i, result in enumerate(ds.__iter__()):
    features.append(result)
    if i >= 5:
        break
```

It gives this features

```
[{'input_ids': tensor([    2, 12861, 10824, 12861,  2967,  8574,  4036,  4052,  7473,  3721,
         12861, 23637, 12861,  3346, 11109,  2967, 11109, 10824, 11109,  3346,
             3,  3813, 24928,  3346,     3,     3,     3,     3,  3425,  4431,
          4109, 16853,     3,     3]), 'attention_mask': tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 'label': 3408},
 {'input_ids': tensor([    2, 15991,  4051, 17692,  6399,  2967,  6426, 11620,  2720,  4104,
          4183, 26227,    25,  3308,     3,  6426, 12527, 14794,     3, 26227,
             3,  6701, 26227,     3,  6426, 26227,     3,    38,  4276,  4091,
             3,    38,  4276,  4091,     3]), 'attention_mask': tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 'label': 3318},
 {'input_ids': tensor([    2, 23687,  8027,    86, 15136, 15994,  7413, 11620,  4712,  9350,
         15955, 31870, 11177, 16601, 18535,  3280,     3,  9477, 10532,     3,
          2298,  4525,  4566, 16601,     3,     3,     3,     3,     3]), 'attention_mask': tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1]), 'label': 2742},
 {'input_ids': tensor([    2,  3213, 11761,  9853,  2290,  8103, 12854,  2136, 10359, 18847,
         22156,  4009,  4036, 10456,  4273,    78,  4184,  4011,    81,  4020,
            76,  4097,    71,  4012,    69,  4037,     3, 10439, 10921,     3,
          8103, 12873,  4031,  2136,     3,  8103, 12854,  2136,     3,     3,
             3,  3213, 11761,     3]), 'attention_mask': tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 'label': 2560},
 {'input_ids': tensor([    2,  9204,  8006,  6988,  2744,  4162,  3283,    91,  7940, 16908,
          9863, 18117, 16420, 16545, 12793, 25385, 28539, 25942,  8023,  4010,
         11976, 27499,  6329,    70,  8193,    90, 16926, 13323, 23626,  4121,
            87,     3,  7058,  6482,     3, 10921, 33648,     3,  8006, 16635,
         10762,  3735,     3,  9420,     3,  3191,  4923,  4266, 14841,     3,
          3191,  4923,  4266, 14841,     3]), 'attention_mask': tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1]), 'label': 2419},
 {'input_ids': tensor([    2,  8471,    24,  4060,    80, 15994, 11704,  9651,  7998,  7388,
         11903, 15962,  8022,  9668,  3283, 18806,  6223,  2348,  5032,  3802,
          4007,  3081, 33036,  4257,  7018,  9651,  7998,     3,  6677,  7084,
          2114,     3,  6718,  6951,  8705,     3, 11791,     3,     3,     3,
             3]), 'attention_mask': tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 'label': 4097}]
```


I changed the code as following and passed a tokenizer to Trainer to use DataCollatorWithPadding.

if I remove `__len__` method it gives this error 
`"train_dataset does not implement __len__, max_steps has to be specified"`

Now Trainer works fine but it only trains with 1 sample, maybe the first one.
I don't know why.. Why all the data is not getting read? 


```python
import torch
import pyarrow.parquet as pq
from transformers import BatchEncoding

class CustomIterableData(torch.utils.data.dataset.IterableDataset):
    def __init__(self, file_path, tokenizer, with_labels=False):
        super().__init__()
        self.file_path = file_path
        self.tokenizer = tokenizer
        self.with_labels = with_labels

    def process(self, row):
        inputs = str(row[2])
        labels = self.str2label(str(row[4]))

        inputs = self.tokenizer(inputs, return_tensors="pt", padding=True, truncation=True)
        self.input_ids = [i.clone().detach() for i in inputs.input_ids]
        self.attention_mask = [i.clone().detach() for i in inputs.attention_mask]

        if self.with_labels:
            # indexing to squeeze(0)
            return BatchEncoding({'input_ids': self.input_ids[0], 'attention_mask': self.attention_mask[0], 'label': labels})
        
        return BatchEncoding({'input_ids': self.input_ids[0], 'attention_mask': self.attention_mask[0]})
                
    def __iter__(self):
        df = pq.read_table(source = self.file_path)
        for batch in df.to_batches():
            for row in zip(*batch.columns):
                yield self.process(row)

    def __len__(self):
        # yield one row at a time
        return 1 

    def str2label(self, string):
        ....

```



This code works fine. I referred to [this post](https://medium.com/speechmatics/how-to-build-a-streaming-dataloader-with-pytorch-a66dd891d9dd).
`__len__` method wasn't necessary if positive `max_steps` is passed to `TrainingArguments`

```python3
class CustomIterableData(torch.utils.data.dataset.IterableDataset):
    def __init__(self, file_path, tokenizer, with_labels=False):
        super().__init__()
        self.file_path = file_path
        self.tokenizer = tokenizer
        self.with_labels = with_labels

    def parse_file(self):
        df = pq.read_table(source = self.file_path)
        for batch in df.to_batches():
            for row in zip(*batch.columns):  
                yield self.process(row)

    def process(self, row):
        inputs = str(row[2])
        labels = self.str2label(str(row[4]))

        inputs = self.tokenizer(inputs, return_tensors="pt", padding=True, truncation=True)
        self.input_ids = [i.clone().detach() for i in inputs.input_ids]
        self.attention_mask = [i.clone().detach() for i in inputs.attention_mask]

        if self.with_labels:
            # indexing to squeeze(0)
            return BatchEncoding({'input_ids': self.input_ids[0], 'attention_mask': self.attention_mask[0], 'label': labels})
        
        return BatchEncoding({'input_ids': self.input_ids[0], 'attention_mask': self.attention_mask[0]})
                
    def get_stream(self):
        return cycle(self.parse_file())

    def __iter__(self):
        return self.get_stream()

    def str2label(self, string):
        ....
 ```