• 카테고리

    질문 & 답변
  • 세부 분야

    자연어 처리

  • 해결 여부

    해결됨

autotrain로 fine tuning 후 embedding vector 구하는 방법이 있을까요?

23.12.13 12:35 작성 조회수 401

0

안녕하세요.

 

mistral 과 llama2를 사용해서 embedding vector를 통해 챗봇을 구현하고 있습니다.

기존 모델로 embedding vector를 구하면 답변 검색이 잘 되지 않아서 파인튜닝을 한 후에 embedding vector를 구하려고 합니다.

 

학습과정에서 알려주신 대로 mistral 과 llama2의 fine tuning을 완료 했습니다.
fine tuning한 모델에서 generate는 잘 동작하나, embedding vector가 생성이 되질 않아 질문 드립니다.

기존 모델을 통한 임베딩 방식은 다음과 같습니다.

 

seq_ids = tokenizer(text, return_tensors='pt')["input_ids"]

embedding = model(seq_ids)["last_hidden_state"].mean(axis=[0,1]).detach().numpy()


기존 원본 모델에서는 'last_hidden_state' 값을 통해서 계산하지만

fine tuning한 모델에서는 'logits' 값만 존재 합니다. 

 

- 원본 모델 리턴값 :             odict_keys(['last_hidden_state'])

- fine tuning 모델 리턴값 : odict_keys(['logits'])

 

 

그래서 파인튜닝한 모델을 보면 Peft 와 Lora로 한번 레이어로 감싼 형태로 리턴되서 그럴꺼라 추측하는데요.

기존 모델

MistralForCausalLM(
  (model): MistralModel(
    (embed_tokens): Embedding(46081, 4096, padding_idx=2)
    (layers): ModuleList(
      (0-31): 32 x MistralDecoderLayer(
        (self_attn): MistralAttention(
          (q_proj): Linear(in_features=4096, out_features=4096, bias=False)
          (k_proj): Linear(in_features=4096, out_features=1024, bias=False)
          (v_proj): Linear(in_features=4096, out_features=1024, bias=False)
          (o_proj): Linear(in_features=4096, out_features=4096, bias=False)
          (rotary_emb): MistralRotaryEmbedding()
        )
        (mlp): MistralMLP(
          (gate_proj): Linear(in_features=4096, out_features=14336, bias=False)
          (up_proj): Linear(in_features=4096, out_features=14336, bias=False)
          (down_proj): Linear(in_features=14336, out_features=4096, bias=False)
          (act_fn): SiLUActivation()
        )
        (input_layernorm): MistralRMSNorm()
        (post_attention_layernorm): MistralRMSNorm()
      )
    )
    (norm): MistralRMSNorm()
  )
  (lm_head): Linear(in_features=4096, out_features=46081, bias=False)
)

 

파인튜닝한 모델

PeftModelForCausalLM(
  (base_model): LoraModel(
    (model): MistralForCausalLM(
      (model): MistralModel(
        (embed_tokens): Embedding(46081, 4096, padding_idx=2)
        (layers): ModuleList(
          (0-31): 32 x MistralDecoderLayer(
            (self_attn): MistralAttention(
              (q_proj): Linear4bit(
                in_features=4096, out_features=4096, bias=False
                (lora_dropout): ModuleDict(
                  (default): Dropout(p=0.05, inplace=False)
                )
                (lora_A): ModuleDict(
                  (default): Linear(in_features=4096, out_features=16, bias=False)
                )
                (lora_B): ModuleDict(
                  (default): Linear(in_features=16, out_features=4096, bias=False)
                )
                (lora_embedding_A): ParameterDict()
                (lora_embedding_B): ParameterDict()
              )
              (k_proj): Linear4bit(in_features=4096, out_features=1024, bias=False)
              (v_proj): Linear4bit(
                in_features=4096, out_features=1024, bias=False
                (lora_dropout): ModuleDict(
                  (default): Dropout(p=0.05, inplace=False)
                )
                (lora_A): ModuleDict(
                  (default): Linear(in_features=4096, out_features=16, bias=False)
                )
                (lora_B): ModuleDict(
                  (default): Linear(in_features=16, out_features=1024, bias=False)
                )
                (lora_embedding_A): ParameterDict()
                (lora_embedding_B): ParameterDict()
              )
              (o_proj): Linear4bit(in_features=4096, out_features=4096, bias=False)
              (rotary_emb): MistralRotaryEmbedding()
            )
            (mlp): MistralMLP(
              (gate_proj): Linear4bit(in_features=4096, out_features=14336, bias=False)
              (up_proj): Linear4bit(in_features=4096, out_features=14336, bias=False)
              (down_proj): Linear4bit(in_features=14336, out_features=4096, bias=False)
              (act_fn): SiLUActivation()
            )
            (input_layernorm): MistralRMSNorm()
            (post_attention_layernorm): MistralRMSNorm()
          )
        )
        (norm): MistralRMSNorm()
      )
      (lm_head): Linear(in_features=4096, out_features=46081, bias=False)
    )
  )
)

 

fine tuning을 한 모델에서는 embedding vector 를 구하는게 불가능한건가요?

 

+추가 model.merge_and_unload() 를 써봤지만 소용없었습니다.

 

답변 2

·

답변을 작성해보세요.

1

안녕하세요~. 반갑습니다.

모델을 불러올때 아래와 같이 인자값으로 output_hidden_states=True를 추가해서 모델을 로드한뒤

model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=bnb_config, device_map={"":0}, output_hidden_states=True)

인풋에 대한 모델의 출력결과에서 .hidden_states로 값을 접근해서 임베딩을 사용해보세요.

 

불러온 모델은 CausalLMOutputWithPast 클래스를 사용합니다.

아래 문서의 CausalLMOutputWithPast 클래스 부분을 참조하세요.

https://huggingface.co/docs/transformers/main_classes/output

 

좋은 하루되세요~.

감사합니다.

 

hare님의 프로필

hare

질문자

2023.12.15

감사합니다! 한방에 해결이 되었네요!
output에 대한것도 공부가되었습니다

 

-1

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.12.15

안녕하세요, 인프런 AI 인턴입니다. hare님 질문해주셔서 감사합니다.

파인튜닝한 모델에서 embedding vector를 추출하는 문제는 종종 발생할 수 있는 문제인데요, 원본 모델이 ‘last_hidden_state’를 리턴하는 반면에 파인튜닝 모델에서는 ‘logits’만 리턴되기 때문에 발생하는 문제로 보입니다.

파인튜닝 모델에서도 last_hidden_state나 중간 히든 레이어의 아웃풋을 가져오는 방법은 모델의 설정이나 사용하는 프레임워크에 따라 달라질 수 있습니다. 특히, 사용하신 PeftModelForCausalLM이나 LoraModel과 같은 커스텀 모델의 경우, 당연히 존재하던 출력값들이 변경될 수 있습니다.

구현하신 코드에서 단순 ‘logits’만 리턴되는 것이 아니라, 내부적으로는 여전히 last_hidden_state가 계산되고 있을 수 있습니다. 이를 확인하기 위해 모델의 전방 패스 함수(forward function)를 수정하거나 또는 적절한 훅(hook)을 설정하여 히든 스테이트를 추출해야 할 수 있습니다.

model.merge_and_unload()를 사용하셨다고 하셨는데, 이는 일반적으로 모델의 불필요한 파라미터를 제거하여 최적화하는 데 사용되며, 다른 출력을 얻고자 할 때 사용하는 함수는 아닙니다.

임베딩 벡터를 추출하기 위하여 다음과 같은 방법을 시도해볼 수 있습니다:

  1. 사용자 정의 모델 정의 시에 forward 함수 안에서 ‘last_hidden_state’를 출력으로 추가합니다. 이때 커스텀 모델 내부에 접근할 수 있어야 합니다.

  2. 만약 소스 코드를 수정하기 어렵다면, PyTorch의 register_forward_hook 기능을 사용하여 해당 레이어의 출력을 캡쳐할 수 있습니다. 이를 위해서는 해당 레이어의 식별이 가능해야 합니다.

  3. PeftModelForCausalLM 또는 LoraModel 개발자에게 문의하여 해당 모델에서 ‘last_hidden_state’에 접근할 수 있는 방법이 있는지 확인해보세요.

마지막으로는 학습을 진행한 환경(프레임워크, 라이브러리 버전 등)과 함께 문제를 명확하게 설명하여 인프런이나 모델 제공자의 공식 지원 채널 또는 커뮤니티에 질문을 올리는 것도 하나의 방법이 될 수 있습니다.

자세한 상황 파악이 필요하며, 아래의 링크를 통해 추가적인 문의를 해보시길 권장드립니다.

마무리하며, 해당 모델이나 프레임워크에 대한 세부적인 내부 구현을 알아봐야 할 수도 있으니 참고하세요. 도움이 되었으면 좋겠습니다!