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

Roberta Model을 활용한 Seq2Seq Model 만들기 #34

Open
sangHa0411 opened this issue Dec 13, 2021 · 0 comments
Open

Roberta Model을 활용한 Seq2Seq Model 만들기 #34

sangHa0411 opened this issue Dec 13, 2021 · 0 comments
Labels
report Sharing information or results of analysis

Comments

@sangHa0411
Copy link
Contributor

sangHa0411 commented Dec 13, 2021

  1. 개요 및 목표
    1. Roberta는 아래 이미지와 같이 Transformers 구조를 사용하고 있고 Encoder로써 Pretraining 이 되었습니다.
    2. 하지만 아래 이미지와 같이 Transformers 구조를 사용하여서 Encoder, Decoder 구조가 거의 유사하기 때문에 Roberta 모델을 Decoder로써 활용이 가능하다고 생각하였습니다.
    3. 결론적으로 BART 모델과 같은 Seq2Seq 모델을 만들 때 Encoder, Decoder 모두 Roberta pretrained 모델을 사용해서 만드는 것을 목표로 하였습니다.

  1. 제작 과정
    1. Robert Model 안에서 Roberta Encoder Class가 있고 Roberta Encoder Class는 아래와 같은 Roberta Layer가 있는 구조입니다.
    2. 따라서 Decoder로 사용하는 Roberta에서는 이 is_decoder 항목을 True로 지정을 해주어야 했습니다.
    3. 또한 위에 사진과 같이 Decoder에서는 Cross Attention을 하는 Layer가 더 존재하였기 때문에 이러한 항목들을 Config에 추가해주었어야 했습니다.

스크린샷 2021-12-13 오후 3 05 42

스크린샷 2021-12-13 오후 3 01 00

class RobertaModelForSeq2Seq(RobertaPreTrainedModel):
    def __init__(self, model_name:str, config: RobertaConfig):
        super().__init__(config)
        self.config = config
        decoder_config = copy.deepcopy(config)
        decoder_config.is_decoder=True
        decoder_config.add_cross_attention=True
        
        self.encoder = RobertaModel.from_pretrained(model_name, config=config)
        self.decoder = RobertaModel.from_pretrained(model_name, config=decoder_config)
  1. 코드

    1. Bart 구조와 거의 유사하게 갈려고 하였습니다.
      • BartForConditionalGeneration --> BartModel --> BartEncoder & BartDecoder
      • RobertaForConditionalGeneration --> RobertaModel --> RobertEncoder & RobertaDecoder
    2. RobertaForConditionalGeneration
      • lm_head는 nn.Linear를 사용해도 되지만 RobertaLMHead 내에서 그러한 요소가 이미 있기 때문에 이미 구현되어 있는 것을 불러왔습니다.
    3. RobertaModel
      • Seq2Seq Trainer 안에서 training_args.predict_with_generate 요소를 적용시키기 위해서는 내부적으로 encoder, decoder를 불러오는 함수가 필요했습니다. -> (get_encoder, get_decoder)
      • RobertaModel 안에서는 BartModel과 같이 encoder, decoder 항목이 있으면서 각각 동일한 checkpoint의 모델을 불러왔습니다.
  2. 결과

    1. Roberta는 Encoder로 Pretraining 되었기 때문에 decoder에서 추가한 attention은 사전에 학습이 되지 않았습니다.
    2. klue/roberta-base 기준으로 각각의 layer가 12개 12개 이기 때문에 kobart 보다 모델의 크기가 약 2배 컸습니다. (용량 : 3.1G)
    3. 학습을 진행할 때 처음에는 성능이 잘 안나왔지만 시간이 지날수록 성능이 많이 향상 되는 것을 확인할 수 있었습니다.

스크린샷 2021-12-13 오후 3 33 00

스크린샷 2021-12-13 오후 3 39 44

  1. 결론
    1. 모델의 크기가 많이 커서 그런지 모델의 성능이 나쁘지 않았습니다.
    2. 제가 구현한 모델의 한계점은 동일한 모델만 encoder, decoder로 붙일 수 있다는 점입니다.
    3. encoder 는 roberta, decoder는 GPT2를 붙이면 훨씬 더 좋을 것으로 예상됩니다.
    4. 3번 과 같은 것은 huggingface에서 이미 구현이 되어있는 듯 합니다.
  • 코드 1
class RobertaForConditionalGeneration(RobertaPreTrainedModel):
    base_model_prefix = "model"
    _keys_to_ignore_on_load_missing = [r"lm_head\.bias", r"lm_head\.weight"]

    def __init__(self, model_name: str, config: RobertaConfig):
        super().__init__(config)
        self.model = RobertaModelForSeq2Seq(model_name, config)
        self.lm_head = RobertaLMHead(config)
  • 코드 2
class RobertaModelForSeq2Seq(RobertaPreTrainedModel):
    def __init__(self, model_name:str, config: RobertaConfig):
        super().__init__(config)
        self.config = config
        decoder_config = copy.deepcopy(config)
        decoder_config.is_decoder=True
        decoder_config.add_cross_attention=True
        
        self.encoder = RobertaModel.from_pretrained(model_name, config=config)
        self.decoder = RobertaModel.from_pretrained(model_name, config=decoder_config)

    def get_encoder(self):
        return self.encoder

    def get_decoder(self):
        return self.decoder

    def set_encoder(self, encoder):
        assert isinstance(encoder, RobertaModel)
        self.encoder = encoder

    def set_decoder(self, decoder):
        assert isinstance(decoder, RobertaModel)
        self.decoder = decoder
@sangHa0411 sangHa0411 added the report Sharing information or results of analysis label Dec 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
report Sharing information or results of analysis
Projects
None yet
Development

No branches or pull requests

1 participant