해결된 질문
작성
·
657
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
좋은 하루되세요~.
감사합니다.
-1
안녕하세요, 인프런 AI 인턴입니다. hare님 질문해주셔서 감사합니다.
파인튜닝한 모델에서 embedding vector
를 추출하는 문제는 종종 발생할 수 있는 문제인데요, 원본 모델이 ‘last_hidden_state’를 리턴하는 반면에 파인튜닝 모델에서는 ‘logits’만 리턴되기 때문에 발생하는 문제로 보입니다.
파인튜닝 모델에서도 last_hidden_state
나 중간 히든 레이어의 아웃풋을 가져오는 방법은 모델의 설정이나 사용하는 프레임워크에 따라 달라질 수 있습니다. 특히, 사용하신 PeftModelForCausalLM
이나 LoraModel
과 같은 커스텀 모델의 경우, 당연히 존재하던 출력값들이 변경될 수 있습니다.
구현하신 코드에서 단순 ‘logits’만 리턴되는 것이 아니라, 내부적으로는 여전히 last_hidden_state
가 계산되고 있을 수 있습니다. 이를 확인하기 위해 모델의 전방 패스 함수(forward function)를 수정하거나 또는 적절한 훅(hook)을 설정하여 히든 스테이트를 추출해야 할 수 있습니다.
model.merge_and_unload()
를 사용하셨다고 하셨는데, 이는 일반적으로 모델의 불필요한 파라미터를 제거하여 최적화하는 데 사용되며, 다른 출력을 얻고자 할 때 사용하는 함수는 아닙니다.
임베딩 벡터를 추출하기 위하여 다음과 같은 방법을 시도해볼 수 있습니다:
사용자 정의 모델 정의 시에 forward
함수 안에서 ‘last_hidden_state’를 출력으로 추가합니다. 이때 커스텀 모델 내부에 접근할 수 있어야 합니다.
만약 소스 코드를 수정하기 어렵다면, PyTorch의 register_forward_hook
기능을 사용하여 해당 레이어의 출력을 캡쳐할 수 있습니다. 이를 위해서는 해당 레이어의 식별이 가능해야 합니다.
PeftModelForCausalLM
또는 LoraModel
개발자에게 문의하여 해당 모델에서 ‘last_hidden_state’에 접근할 수 있는 방법이 있는지 확인해보세요.
마지막으로는 학습을 진행한 환경(프레임워크, 라이브러리 버전 등)과 함께 문제를 명확하게 설명하여 인프런이나 모델 제공자의 공식 지원 채널 또는 커뮤니티에 질문을 올리는 것도 하나의 방법이 될 수 있습니다.
자세한 상황 파악이 필요하며, 아래의 링크를 통해 추가적인 문의를 해보시길 권장드립니다.
마무리하며, 해당 모델이나 프레임워크에 대한 세부적인 내부 구현을 알아봐야 할 수도 있으니 참고하세요. 도움이 되었으면 좋겠습니다!
감사합니다! 한방에 해결이 되었네요!
output에 대한것도 공부가되었습니다