Я новичок 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
Я так запутался ... Я совершенно не могу понять, что с этим произошло? хотя я закрываю этот терминал и снова открываю его, он все равно не удался. единственный способ избежать этой ошибки - загрузить предыдущую версию этого кода.
поэтому мой вопрос:
- что случилось с этой ошибкой, когда я повторил свою модификацию?
- Я изменил форму label_ids на правильную, почему возникает ошибка?
большое спасибо