#pytorch #huggingface-transformers #huggingface-tokenizers
Вопрос:
У меня возникли трудности с пониманием tokenizer.pad
метода из библиотеки трансформаторов huggingface. Чтобы оптимизировать обучение, я выполняю маркировку в наборе данных таким образом, чтобы во время загрузки данных не выполнялось никаких сложных операций. Мой набор данных выглядит так:
class DatasetTokenized(Dataset):
def __init__(self, data: pd.DataFrame, text_column: str,
label_columns: List[str], tokenizer_name: str):
super(DatasetTokenized, self).__init__()
self.data = data
self.text_column = text_column
self.label_columns = label_columns
self.tokenizer = BertTokenizer.from_pretrained(tokenizer_name)
self.tokenized_data = self.tokenize_data(data)
def __len__(self) -> int:
return len(self.tokenized_data)
def __getitem__(self, index: int) -> Dict:
return self.tokenized_data[index]
def tokenize_data(self, data: pd.DataFrame):
tokenized_data = []
print('Tokenizing data:')
for _, row in tqdm(data.iterrows(), total=len(data)):
text = row[self.text_column]
labels = row[self.label_columns]
encoding = self.tokenizer(text,
add_special_tokens=True,
max_length=512,
padding=False,
truncation=True,
return_attention_mask=True,
return_tensors='pt')
tokenized_data.append({
'text': text,
'encoding': encoding,
'labels': torch.FloatTensor(labels)
})
return tokenized_data
и мой коллатор выглядит так:
class BertCollatorTokenized:
def __init__(self, tokenizer_name: str):
super(BertCollatorTokenized, self).__init__()
self.tokenizer = BertTokenizer.from_pretrained(tokenizer_name)
def __call__(self, batch: List[Any]):
text, encodings, labels = zip(
*[[sample['text'], sample['encoding'], sample['labels']]
for sample in batch])
encodings = list(encodings)
encodings = self.tokenizer.pad(encodings,
max_length=512,
padding='longest',
return_tensors='pt')
return {
'text': text,
'input_ids': encodings['input_ids'],
'attention_mask': encodings['attention_mask'],
'labels': torch.FloatTensor(labels)
}
Я подтвердил, что encodings
это список BatchEncoding
того, что требуется tokenizer.pad
. Однако я получаю следующую ошибку:
Ошибка значения: Не удается создать тензор, вам, вероятно, следует активировать усечение и/или заполнение с помощью «заполнение=Истина «»усечение=Истина», чтобы иметь пакетные тензоры одинаковой длины.
Что немного сбивает с толку, поскольку в этом и должен быть весь смысл использования tokenizer.pad
. У кого-нибудь есть представление о том, что происходит?
Комментарии:
1. Кодовая база HuggingFace в полном беспорядке, что плохого в использовании собственных факельных операций для pad? Если вы хотите придерживаться реализации HF, может ли это быть тот случай, который вам нужен
encode
, а неtokenize
вDatasetTokenized.tokenize_data
?2. Я использую
__call__
метод токенизатора, который в фоновом режиме вызоветencode
илиbatch_encode
автоматически. Нет ничего плохого в использовании собственных функций факела, но я хотел выяснить, как это сделать с помощью API HF.3. Ты прав, я неправильно понял (извинения).