Генерация текста с использованием моделей distilbert huggingface
Я уже некоторое время борюсь с моделью DistilBERT от huggingface, так как документация кажется очень неясной и их примеры (например, https://github.com/huggingface/transformers/blob/master/notebooks/Comparing-TF-and-PT-models-MLM-NSP.ipynb и https://github.com/huggingface/transformers/tree/master/examples/distillation) очень толстые, и то, что они демонстрируют, не кажется хорошо документированным.
Мне интересно, есть ли у кого-нибудь здесь опыт и знает ли какой-нибудь хороший пример кода для базового использования своих моделей в Python. А именно:
Как правильно декодировать вывод модели в фактический текст (независимо от того, как я меняю его форму, токенизатор, похоже, готов декодировать его и всегда дает некоторую последовательность
[UNK]
жетоны)Как на самом деле использовать их планировщики + оптимизаторы для обучения модели для простой задачи преобразования текста в текст.
1 ответ
Чтобы декодировать вывод, вы можете сделать
prediction_as_text = tokenizer.decode(output_ids, skip_special_tokens=True)
output_ids
содержит сгенерированные идентификаторы токенов. Это также может быть пакет (выходные идентификаторы в каждой строке), тогда
prediction_as_text
также будет 2D-массив, содержащий текст в каждой строке.
skip_special_tokens=True
отфильтровывает специальные токены, используемые в обучении, такие как (конец предложения), (начало предложения) и т. д. Эти специальные токены, конечно, различаются от модели к модели, но почти каждая модель имеет такие специальные токены, используемые во время обучения и вывода.
Нет простого способа избавиться от неизвестных токенов [UNK]. У моделей ограниченный словарный запас. Если модель встречает подслово, которого нет в ее словарном запасе, оно заменяется специальным неизвестным токеном, и модель обучается с этими токенами. Итак, он также учится генерировать [UNK]. Есть разные способы справиться с этим, например, заменить его вторым по величине вероятным токеном или использовать поиск луча и выбрать наиболее вероятное предложение, не содержащее каких-либо неизвестных токенов. Однако, если вы действительно хотите избавиться от них, вам лучше использовать модель, которая использует кодирование пар байтов. Это полностью решает проблему неизвестных слов. Как вы можете прочитать по этой ссылке, Bert и DistilBert используют токенизацию подзадач и имеют такое ограничение. https://huggingface.co/transformers/tokenizer_summary.html
Чтобы использовать планировщики и оптимизаторы, вы должны использовать класс
Trainer
а также
TrainingArguments
. Ниже я разместил пример из одного из моих собственных проектов.
output_dir=model_directory,
num_train_epochs=args.epochs,
per_device_train_batch_size=args.batch_size,
per_device_eval_batch_size=args.batch_size,
warmup_steps=500,
weight_decay=args.weight_decay,
logging_dir=model_directory,
logging_steps=100,
do_eval=True,
evaluation_strategy='epoch',
learning_rate=args.learning_rate,
load_best_model_at_end=True, # the last checkpoint is the best model wrt metric_for_best_model
metric_for_best_model='eval_loss',
lr_scheduler_type = 'linear'
greater_is_better=False,
save_total_limit=args.epochs if args.save_total_limit == -1 else args.save_total_limit,
)
trainer = Seq2SeqTrainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=val_dataset,
optimizers=[torch.optim.Adam(params=model.parameters(),
lr=args.learning_rate), None], // optimizers
tokenizer=tokenizer,
)
Для других типов планировщиков см. Эту ссылку: https://huggingface.co/transformers/main_classes/optimizer_schedules.html