3

我有一个关于“即时”标记化的问题。这个问题是通过阅读此处的“如何使用 Transformers 和 Tokenizers 从头开始​​训练新的语言模型”引发的。最后有这句话:“如果您的数据集非常大,您可以选择动态加载和标记示例,而不是作为预处理步骤”。datasets我尝试提出一个将和结合起来的解决方案tokenizers,但没有找到一个好的模式。

我想解决方案需要将数据集包装到 Pytorch 数据集中。

作为文档中的一个具体示例

import torch

class SquadDataset(torch.utils.data.Dataset):
    def __init__(self, encodings):
        # instead of doing this beforehand, I'd like to do tokenization on the fly
        self.encodings = encodings 

    def __getitem__(self, idx):
        return {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}

    def __len__(self):
        return len(self.encodings.input_ids)

train_dataset = SquadDataset(train_encodings)

如何利用标记器的矢量化功能通过“即时”标记化来实现这一点?

4

1 回答 1

2

2021 年 2 月更新

从 v1.3.0 开始,数据集支持通过该set_transform方法对函数进行惰性求值。因此,您可以像此处所示直接应用即时标记化。


旧答案

最后我选择了这个解决方案。我不喜欢现在在数据集级别控制 batch_size。但是,它完成了它的工作。

通过这种方式,我们利用了两个好处:

  • 快速索引 HuggingFace 数据集

  • HuggingFace 标记器的矢量化功能

class CustomPytorchDataset(Dataset):
    """
    This class wraps the HuggingFace dataset and allows for 
    batch indexing into the dataset. This allows exploiting
    the capabilities of the tokenizer to work on batches.

    NOTE: now we control batch_size at the Dataset level, not
    in the DataLoader therefore the DataLoader should always be
    used with `batch_size=1`.
    """

    def __init__(self, batch_size: int):
        self.batch_size = batch_size
        self.dataset = train_ds          # HuggingFace dataset
        self.tokenizer = bert_tokenizer  # HuggingFace tokenizer

    def __getitem__(self, batch_idx: List[int]):
        instance = self.dataset[batch_idx]

        # tokenize on-the-fly
        tokenized_instance = self.tokenizer(
            instance[text_col], 
            truncation=True, 
            padding=True
        )
        
        return tokenized_instance

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

    def sampler(self):
        # shuffling can be controlled by the sampler, 
        # without touching the dataset
        return BatchSampler(
            SequentialSampler(self), 
            batch_size=self.batch_size, 
            drop_last=True
        )

    @staticmethod
    def collate_fn(batches: List[Dict[str, int]]):
        return {
            k: torch.tensor(v, dtype=torch.int64) 
            for k, v in batches[0].items()
        }
于 2020-12-08T21:55:52.917 回答