Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

klue_baseline/models/named_entity_recognition.py 에 validation_epoch_step 에 버그가 있습니다. #9

Open
khel-kim opened this issue May 6, 2022 · 0 comments

Comments

@khel-kim
Copy link

khel-kim commented May 6, 2022

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을 만들어주셔서 감사합니다 🙇‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant