klue_baseline/models/named_entity_recognition.py 에 validation_epoch_step 에 버그가 있습니다.
khel-kim opened this issue · 0 comments
Abstract(요약) 🔥
unk 토큰이 있는 경우 제대로 character_preds 리스트가 제대로 생성되지 않는 문제가 있습니다.
How to Reproduce(재현 방법) 🤔
예를 들어 "전문성운줄알았어여~ᄏ"를 토크나이징하면 (sample id : klue-ner-v1_dev_00236-nsmc)
['전문',
'##성',
'##운',
'##줄',
'##알',
'##았',
'##어',
'##여',
'~',
'[UNK]']
이런 결과가 나오는데요.
이러한 input이 https://github.com/KLUE-benchmark/KLUE-baseline/blob/main/klue_baseline/models/named_entity_recognition.py#L98-L129 이 if문을 타게 되면,
character_preds가 원하는 형태로 생성되지 않게 됩니다.
이유는 unk가 있는 공백기준으로 분리뒨 어절에 unk가 아닌 단어는 모두 기호일거라고 가정되어 코드작성이 되었기 때문인 것 같습니다.
이 때문에 '전문' 같은 경우에는 char 이 2개임에도 subword_pred가 캐릭터 하나에 대한 pred만 append 되는 상황이 됩니다.
(https://github.com/KLUE-benchmark/KLUE-baseline/blob/main/klue_baseline/models/named_entity_recognition.py#L125)
How to solve (어떻게 해결할 수 있을까요) 🙋♀
if self.tokenizer.unk_token in subwords: # 뻥튀기가 필요한 case!
unk_aligned_subwords = self.tokenizer_out_aligner(
word, subwords, strip_char
) # [UNK] -> [UNK, +UNK]
add_char_preds_idx = 0 # 추가된 부분
unk_flag = False
for subword in unk_aligned_subwords:
if character_preds_idx >= self.hparams.max_seq_length - 1:
break
subword_pred = subword_preds[character_preds_idx].tolist()
subword_pred_label = label_list[subword_pred]
if subword == self.tokenizer.unk_token:
unk_flag = True
character_preds.append(subword_pred)
add_char_preds_idx += 1 # 추가된 부분
continue
elif subword == self.in_unk_token:
if subword_pred_label == "O":
character_preds.append(subword_pred)
else:
_, entity_category = subword_pred_label.split("-")
character_pred_label = "I-" + entity_category
character_pred = label_list.index(character_pred_label)
character_preds.append(character_pred)
add_char_preds_idx += 1 # 추가된 부분
continue
else:
if unk_flag:
character_preds_idx += 1
subword_pred = subword_preds[character_preds_idx].tolist()
subword_pred = [subword_pred] * len(subword.lstrip(strip_char)) # 추가된 부분
character_preds.extend(subword_pred) # 추가된 부분
unk_flag = False
else:
subword_pred = [subword_pred] * len(subword.lstrip(strip_char)) # 추가된 부분
character_preds.extend(subword_pred) # 추가된 부분
character_preds_idx += 1 # `+UNK`가 끝나는 시점에서도 += 1 을 해줘야 다음 label로 넘어감
character_preds_idx += add_char_preds_idx # 추가된 부분
코드를 우선 려프하게 작성하게 되었는데, 해당 부분을 검토해주셔서 더 좋은 코드(?)로 업데이트 되면 좋을 것 같습니다!
좋은 finetuning system을 만들어주셔서 감사합니다 🙇♂️