некоторая ошибка при использовании Берта, хотя я переделал все свои модификации до правильной версии - PullRequest
0 голосов
/ 09 июля 2020

Я новичок ie в НЛП. Я использую Берта для классификации новостей, но проблема не в этом. проблема, с которой я столкнулся, очень странная ....

Я использую пакет "transformers", как указано ниже

from transformers import BertForSequenceClassification
preTrainedModel = "bert-base-chinese"
model = BertForSequenceClassification.from_pretrained( preTrainedModel, num_labels=5)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = model.to(device)

и токен, загрузчик данных и некоторые функции, как указано ниже:

tokenizer = BertTokenizer.from_pretrained(preTrainedModel)
trainset = prepareData("train", tokenizer=tokenizer)
trainloader = DataLoader(trainset, batch_size=10, collate_fn=createBatch)

class prepareData(Dataset):
    def __init__(self, mode, tokenizer):
        self.mode       = mode
        self.df         = pd.read_csv(mode + ".csv").fillna("").iloc[:]
        self.len        = len(self.df)
        self.tokenizer  = tokenizer  
        self.label_map  = {'xxxx1' : 0, 
                           'xxxx2' : 1, 
                           'xxxx3' : 2,
                           'xxxx4' : 3,
                           'xxxx5' : 4, 
                           'xxxx6' : 5}

    def __getitem__(self, idx):
        if self.mode == "test":
            content,label = self.df.iloc[idx, :].values
            label_id = self.label_map[label]
            label_tensor = None
        else:
            content,label = self.df.iloc[idx, :].values
            label_id = self.label_map[label]
            label_tensor = torch.tensor(label_id)

        word_pieces = ["[CLS]"] + self.tokenizer.tokenize(content)
        ids = self.tokenizer.convert_tokens_to_ids(word_pieces)
        tokens_tensor = torch.tensor(ids)
        segments_tensor = torch.tensor([0] , dtype=torch.long)

        return (tokens_tensor, segments_tensor, label_tensor)

    def __len__(self):
        return self.len


def createBatch(samples):
    tokens_tensors = [s[0] for s in samples]
    segments_tensors = [s[1] for s in samples]


    if samples[0][2] is not None:
        label_ids = torch.stack([s[1] for s in samples])
    else:
        label_ids = None

    tokens_tensors = pad_sequence(tokens_tensors, batch_first=True)
    segments_tensors = pad_sequence(segments_tensors, batch_first=True)
    masks_tensors = torch.zeros(tokens_tensors.shape, dtype=torch.long)
    masks_tensors = masks_tensors.masked_fill( tokens_tensors != 0,1)
    return tokens_tensors,segments_tensors, masks_tensors, label_ids

этот код прошел хорошо, но получил ложный результат из-за опечатки в моей функции «createBatch»

if samples[0][2] is not None:
    label_ids = torch.stack([s[1] for s in samples])

, но это будет:

if samples[0][2] is not None:
    label_ids = torch.stack([s[2] for s in samples])

Я думаю, что форма of label_ids должен быть в первой форме, например,

torch.Size([1581, 1])

, однако во второй форме это просто так:

torch.Size([1581])

, поэтому я изменил эту строку следующим образом:

if samples[0][2] is not None:
    label_ids = torch.stack([s[2] for s in samples])
    label_ids = torch.unsqueeze(label_ids, 1)

и получил ту же форму, что и первый вид:

torch.Size([1581, 1])

однако все пошло не так. после этой модификации я обучил свою модель этой функции:

class training_routine():
    def __init__(self, n_epochs, dataloader):
        self.n_epochs = n_epochs
        self.dataloader = dataloader
        self._run()

    def _run(self):
        for epoch in range(self.n_epochs):
            running_loss = 0.0
            for data in self.dataloader:
                tokens_tensors, segments_tensors, \
                masks_tensors, labels = [t.to(device) for t in data]
                optimizer.zero_grad()
                outputs = model(input_ids=tokens_tensors, token_type_ids=segments_tensors, attention_mask=masks_tensors, labels=labels)
                loss = outputs[0]
                loss.backward()
                optimizer.step()
                running_loss += loss.item()

            _, acc = get_predictions(model, trainloader, compute_acc=True)

            print('[epoch %d] loss: %.3f, acc: %.3f' %(epoch + 1, running_loss, acc))
        self.model = model

и получил это сообщение об ошибке

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-5-5ec126c7952e> in <module>()
     26 
     27     print('訓練開始')
---> 28     t = training_routine(n_epochs=2, dataloader=trainloader)
     29 
     30 

3 frames
<ipython-input-4-411f1f1e11c1> in __init__(self, n_epochs, dataloader)
    122         self.n_epochs = n_epochs
    123         self.dataloader = dataloader
--> 124         self._run()
    125 
    126     def _run(self):

<ipython-input-4-411f1f1e11c1> in _run(self)
    132                 outputs = model(input_ids=tokens_tensors, token_type_ids=segments_tensors, attention_mask=masks_tensors, labels=labels)
    133                 loss = outputs[0]
--> 134                 loss.backward()
    135                 optimizer.step()
    136                 running_loss += loss.item()

/usr/local/lib/python3.6/dist-packages/torch/tensor.py in backward(self, gradient, retain_graph, create_graph)
    196                 products. Defaults to ``False``.
    197         """
--> 198         torch.autograd.backward(self, gradient, retain_graph, create_graph)
    199 
    200     def register_hook(self, hook):

/usr/local/lib/python3.6/dist-packages/torch/autograd/__init__.py in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables)
     98     Variable._execution_engine.run_backward(
     99         tensors, grad_tensors, retain_graph, create_graph,
--> 100         allow_unreachable=True)  # allow_unreachable flag
    101 
    102 

RuntimeError: transform: failed to synchronize: cudaErrorAssert: device-side assert triggered

, поэтому я отменяю все свои модификации исходного кода. но код не работает .... Я больше не могу использовать этот код. эта ошибка произошла в другой строке, как показано ниже:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-7-5ec126c7952e> in <module>()
     15     model           = BertForSequenceClassification.from_pretrained( preTrainedModel, num_labels=5)
     16     device          = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
---> 17     model           = model.to(device)
     18 
     19     # print('計算初始準確率')

5 frames
/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in to(self, *args, **kwargs)
    441             return t.to(device, dtype if t.is_floating_point() else None, non_blocking)
    442 
--> 443         return self._apply(convert)
    444 
    445     def register_backward_hook(self, hook):

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in _apply(self, fn)
    201     def _apply(self, fn):
    202         for module in self.children():
--> 203             module._apply(fn)
    204 
    205         def compute_should_use_set_data(tensor, tensor_applied):

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in _apply(self, fn)
    201     def _apply(self, fn):
    202         for module in self.children():
--> 203             module._apply(fn)
    204 
    205         def compute_should_use_set_data(tensor, tensor_applied):

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in _apply(self, fn)
    201     def _apply(self, fn):
    202         for module in self.children():
--> 203             module._apply(fn)
    204 
    205         def compute_should_use_set_data(tensor, tensor_applied):

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in _apply(self, fn)
    223                 # `with torch.no_grad():`
    224                 with torch.no_grad():
--> 225                     param_applied = fn(param)
    226                 should_use_set_data = compute_should_use_set_data(param, param_applied)
    227                 if should_use_set_data:

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in convert(t)
    439             if convert_to_format is not None and t.dim() == 4:
    440                 return t.to(device, dtype if t.is_floating_point() else None, non_blocking, memory_format=convert_to_format)
--> 441             return t.to(device, dtype if t.is_floating_point() else None, non_blocking)
    442 
    443         return self._apply(convert)

RuntimeError: CUDA error: device-side assert triggered

Я так запутался ... Я совершенно не могу понять, что с этим произошло? хотя я закрываю этот терминал и снова открываю его, он все равно не удался. единственный способ избежать этой ошибки - загрузить предыдущую версию этого кода.

поэтому мой вопрос:

  1. что случилось с этой ошибкой, когда я повторил свою модификацию?
  2. Я изменил форму label_ids на правильную, почему возникает ошибка?

большое спасибо

...