model_id = "google/flan-t5-small"
tokenizer = AutoTokenizer.from_pretrained(model_id)
max_source_len = 31
max_target_len = 50
train_ds = train_ds.map(actual_encoding, fn_kwargs={"tokenizer": tokenizer, "max_source_len":max_source_len, "max_target_len":max_target_len}, batched=True, num_proc=2)
valid_ds = valid_ds.map(actual_encoding, fn_kwargs={"tokenizer": tokenizer, "max_source_len": max_source_len, "max_target_len": max_target_len}, batched=True, num_proc=2)
test_ds = test_ds.map(actual_encoding, fn_kwargs={"tokenizer": tokenizer, "max_source_len": max_source_len, "max_target_len": max_target_len}, batched=True, num_proc=2)
for ds in [train_ds, valid_ds, test_ds]:
ds_in_lens = [len(ex["input_ids"]) for ex in ds.iter(batch_size=1)]
ds_lab_lens = [len(ex["labels"]) for ex in ds.iter(batch_size=1)]
check = np.array([l == ds_in_lens[0] for l in ds_in_lens[1:]]).all() and np.array([l == ds_lab_lens[0] for l in ds_lab_lens[1:]]).all()
assert check, "check lengths in {ds}"
Я загружаю модель и связанный с ней токенизатор, затем токенизирую три набора данных с помощью fact_encoding с заранее определенной максимальной длиной для input_ids и меток. Цикл for в конце проверяет, что все поля, используемые при обучении, имеют одинаковую длину.
Затем я обучаю модель, выполняя этап проверки в конце каждого обучения. эпоха. Проверка основана на сгенерированных token_id, а не на логитах (
def compute_metrics_validation(self, eval_preds):
predictions = eval_preds.predictions
labels = eval_preds.label_ids
try:
labels = self.clean_labels(labels)
predictions = self.tokenizer.batch_decode(predictions, skip_special_tokens=True)
labels = self.tokenizer.batch_decode(labels, skip_special_tokens=True)
except Exception as e:
print(e)
print("PREDS")
print(predictions)
print("LABELS")
print(labels)
for i, pred in enumerate(predictions):
if -100 in pred:
print(f"preds[{i}]: {pred}")
assert False
res = {"metric":1.0}
return res
Метки очищаются, а их значение заполнения -100 заменяется токеном заполнения, предоставленным токенизатором. Затем токенизатор декодирует и предсказания, и метки.
Проблема в том, что токенизатор находит значение -100 в предсказанных токенах:
Trainer.tokenizer is now deprecated. You should use Trainer.processing_class instead.
[[repeated for every validation sample]]
out of range integral type conversion attempted
[...]
preds[0]: [ 0 3 9 28376 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 -100]
[...]
preds[199]: [ 0 328 1944 3 9 467 13 3 2951 7 16 8 3 2951
7 5892 5 1 0 0 -100]
Как вы можете видеть:
Trainer.tokenizer используется, но я не вижу, где, потому что я явно вызывать токенизатор, когда мне это нужно.
Каждый прогноз проверки имеет конечное значение -100, которого там быть не должно.
Я уверен, что ошибка вызвано очень глупым шагом, который я сделал в своем коде, но я не могу понять, какой именно.
Кто-нибудь может мне помочь?
Я подготовил блокнот в Colab, но не уверен, что он работает нормально, так как не могу получить доступ к среде выполнения с графическим процессором. https://colab.research.google.com/drive ... sp=sharing
for ds in [train_ds, valid_ds, test_ds]: ds_in_lens = [len(ex["input_ids"]) for ex in ds.iter(batch_size=1)] ds_lab_lens = [len(ex["labels"]) for ex in ds.iter(batch_size=1)] check = np.array([l == ds_in_lens[0] for l in ds_in_lens[1:]]).all() and np.array([l == ds_lab_lens[0] for l in ds_lab_lens[1:]]).all() assert check, "check lengths in {ds}"
model = AutoModelForSeq2SeqLM.from_pretrained(model_id) model = model.to(torch.device("cuda:0"))
trainer.train() [/code] Что я объясняю здесь: [code]# download Bilkies/QuestionGeneration from HF hub # https://huggingface.co/datasets/Bilkies/QuestionGeneration
ds_name = 'Bilkies/QuestionGeneration' ds_builder = load_dataset_builder(ds_name) print(ds_builder.info) dataset = load_dataset(ds_name) display(dataset) train_ds = dataset['train'] print("number of original training point", len(train_ds)) # subsample train_ds train_ds = train_ds.select(range(1000)) print("after sampling", len(train_ds)) test_ds = dataset['validation'].select(range(500)) # split training_ds in 80/20 for training and validation train_ds = train_ds.train_test_split(test_size=0.2) valid_ds = train_ds['test'] train_ds = train_ds['train'] [/code] После загрузки набора данных Bilkies/QuestionGeneration я сохраняю только первые 1000 примеров в целях «скорости». Я создаю три раздела данных: [list] [*]набор тестовых данных test_ds, который соответствует допустимому разделу набора данных HF [code]train_ds[/code] и valid_ds, которые соответствуют 80 % и 20 % обучающих данных соответственно. [/list] [code]model_id = "google/flan-t5-small" tokenizer = AutoTokenizer.from_pretrained(model_id)
for ds in [train_ds, valid_ds, test_ds]: ds_in_lens = [len(ex["input_ids"]) for ex in ds.iter(batch_size=1)] ds_lab_lens = [len(ex["labels"]) for ex in ds.iter(batch_size=1)] check = np.array([l == ds_in_lens[0] for l in ds_in_lens[1:]]).all() and np.array([l == ds_lab_lens[0] for l in ds_lab_lens[1:]]).all() assert check, "check lengths in {ds}" [/code] Я загружаю модель и связанный с ней токенизатор, затем токенизирую три набора данных с помощью fact_encoding с заранее определенной максимальной длиной для input_ids и меток. Цикл for в конце проверяет, что все поля, используемые при обучении, имеют одинаковую длину. Затем я обучаю модель, выполняя этап проверки в конце каждого обучения. эпоха. Проверка основана на сгенерированных token_id, а не на логитах ([code]predict_with_generate=True[/code]) [code]bs = 1
trainer.train() [/code] Модель оценивается с помощью QGenMetrics, в частности, с помощью метода Compute_metrics_validation: [code]def compute_metrics_validation(self, eval_preds): predictions = eval_preds.predictions labels = eval_preds.label_ids
try: labels = self.clean_labels(labels) predictions = self.tokenizer.batch_decode(predictions, skip_special_tokens=True) labels = self.tokenizer.batch_decode(labels, skip_special_tokens=True) except Exception as e: print(e) print("PREDS") print(predictions) print("LABELS") print(labels) for i, pred in enumerate(predictions): if -100 in pred: print(f"preds[{i}]: {pred}") assert False
res = {"metric":1.0} return res [/code] Метки очищаются, а их значение заполнения -100 заменяется токеном заполнения, предоставленным токенизатором. Затем токенизатор декодирует и предсказания, и метки. Проблема в том, что токенизатор находит значение -100 в предсказанных токенах: [code]Trainer.tokenizer is now deprecated. You should use Trainer.processing_class instead. [[repeated for every validation sample]]
[/code] Как вы можете видеть: [list] [*]Trainer.tokenizer используется, но я не вижу, где, потому что я явно вызывать токенизатор, когда мне это нужно.
[*]Каждый прогноз проверки имеет конечное значение -100, которого там быть не должно.
[/list] Я уверен, что ошибка вызвано очень глупым шагом, который я сделал в своем коде, но я не могу понять, какой именно. Кто-нибудь может мне помочь? Я подготовил блокнот в Colab, но не уверен, что он работает нормально, так как не могу получить доступ к среде выполнения с графическим процессором. https://colab.research.google.com/drive/1Ms_gcI_loWXKDPVkEtjG_W3xnsZH0YTT?usp=sharing