본문 바로가기
TechStudy/LLM

Fine-tuned model 독립 및 견고성(robust) 검증

목적: LoRA로 파인튜닝한 모델을 스스로 참조하는 형태로 독립시키는 것.

-> LoRA로 파인튜닝했어도 원본 모델과 merge를 함으로써 참조가 불필요하도록 모델 독립

 

원인: 효율적인 속도 및 연산을 위해 조절, 변경한 LoRA matrices만 저장되기 때문

 

 

 

 

○ huggingface에 모델을 (비공개) 업로드하면 모델 독립이 자동으로 이뤄질까?

-> _name_or_path에 아무 문자열이나 넣어도 정상 작동하므로 모델 독립이라 판단 가능

- 로드 시간: 6초 이내로 로드 완료

- 모델 작동 여부: 허깅 기반 로드이므로 답변 속도는 10초 이내로 빠름

-> 문제점: 허깅에 공개적으로 업로드했다는 것(로컬 모델 개발 목적에서..)

(* , 허깅에 업로드한 모델은 private로 비공개 설정이 가능하다.)

 

 

LoraConfig를 조절하는 옵션을 담은 Peft 라이브러리에 방법이 있을까?

-> 공식 문서에 따르면 modules_to_save라는 옵션이 있음. 그러나 본 노트의 목적과 다른 용도로 판단됨

 

 

KULLM()이 사용한 merge 방법 시도

- KULLM: 고려대학교에서 만든 GPT_NeoX 구조의 LLM 모델

-> 결과: Llama3이 GPT_NeoX 구조가 아니므로 실패

 

 

모델 merge kit를 사용해야 할까?

- model merge: 2개 이상의 LLMGPU없이 하나의 모델로 합치는 것 -> 일단 참고용으로 인지

참조 링크: https://github.com/arcee-ai/mergekit, 설명문서

 

 

model.save_pretrainedsafe_serialization=True로 옵션 설정하여 적용하기

- 과정: 저장과정에서 생긴 config.json, adapter_config.json 두 파일의 base model path

학습 base modelbllossom이 아니라 자기 자신 (Llama-3 ORPO) 참조하도록 변경

-> safetensor와 함께 저장되어 안정적인 파인튜닝 모델 로드(6) 가능

-> 기존 참조 Bllossom 모델의 파일명을 변경(경로변경)하여도 정상 작동

-> Bllossom 모델로부터 독립한 파인튜닝 모델로 판단됨

 

 

 

 

 

[특이사항]

기존 Bllossom 모델의 생성 시간보다 빠른 경우는 기존 모델의 safetensor7(31GB)
100개 농사로를 학습한 튜닝 모델은 2(8GB) 정도로 모델 용량이 줄어들었을 때 나타남.

-> 모델이 경량화 되었는지, loss가 커진 것인지는 판단 불가.

-> 이 덕분에 메시지 생성시간이 매우 빨라진 것으로 추정

 

tokenizermodel를 다시 로드하는 재정의 작업을 거치고 merge하면 약 16GB로 저장됨

 

 

 

검증

의문점: 30GB에서 16GB로 용량이 약 절반으로 줄어든 100sample ORPO 튜닝 모델은
원본 모델의 성능 저하 없이 용량만 줄어든 것일까?

 

모델 구조 비교: print(model) 방식으로 구조 출력하여 비교

base model(llama-3-8b-KrBllossom) ORPO tuned model
LlamaForCausalLM(
(model): LlamaModel(
(embed_tokens): Embedding(145088, 4096)
(layers): ModuleList(
(0-31): 32 x LlamaDecoderLayer(
(self_attn): LlamaSdpaAttention(
(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): LlamaRotaryEmbedding()
)
(mlp): LlamaMLP(
(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): SiLU()
)
(input_layernorm): LlamaRMSNorm()
(post_attention_layernorm): LlamaRMSNorm()
)
)
(norm): LlamaRMSNorm()
)
(lm_head): Linear(in_features=4096, out_features=145088, bias=False
)













LlamaForCausalLM(
(model): LlamaModel(
(embed_tokens): Embedding(145088, 4096)
(layers): ModuleList(
(0-31): 32 x LlamaDecoderLayer(
(self_attn): LlamaSdpaAttention(
(q_proj): lora.Linear(
(base_layer): Linear(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): lora.Linear(
(base_layer): Linear(in_features=4096, out_features=1024, bias=False)
(lora_dropout): ModuleDict(
(default): Dropout(p=0.05, inplace=False)
)


... <<v_proj, o_proj, mlp의 로라 구조 중략>>


(norm): LlamaRMSNorm()
)
(lm_head): Linear(in_features=4096, out_features=145088, bias=False)
)

- 차이점: ORPO는 단순 linear 사용이 아닌 LoRA 기반의 linear 레이어를 사용함

-> 일부만 파인튜닝한 모델이므로 LoRA가 사용됨

 

 

 

 각종 평가지표를 곁들인 비교
- 평가에 사용된 text 데이터: 문장 3 (영어 문장 2개, 한글 문장 1개)

평가지표 base model(llama-3-8b-KrBllossom) ORPO tuned model
Model Size
모델 파일 크기
30GB 16GB
Inference Time
추론 시간
평균 4.6668 ± 0.2050 평균 5.2161 ± 0.2462
Memory usage
메모리 사용량
12131.52 MB 12131.52 MB
Perplexity score 72.2782211303711 72.26553344726562

- 파일 크기: 새 모델 용량이 적음 -> 저장 공간 절약 및 모델 메모리 로드와 네트워크 전송 시간 단축 효과

- 추론 시간: 10번 추론에 대한 평균 시간을 기록하였다. -> 기존 모델이 더 빠르다.

- 메모리 사용량: 차이 없음

- Perplexity: 이는 엄밀히 따지면 튜닝모델이 미세하게나마 더 좋음.

그러나 두 모델 성능 차이가 없다는 해석도 가능

 

유의점: 평가에 사용된 text 데이터가 매우 단순하여 제대로 된 평가가 아닐 수 있음

 

 

 

 

 

[참고: Perplexity score(PPL)]

정의: 모델이 주어진 텍스트를 얼마나 잘 예측하는지 측정하는 지표.
Perplexity is a measure of how well a probability distribution or probability model predicts a sample. It's a widely used metric in natural language processing (NLP) and information theory.

해석 방법: 낮을수록 예측 성능이 좋음을 의미. 점수가 1인 경우, 모든 단어를 100% 예측한 이상적인 상태

주로 절대 평가보다는 모델 비교를 통한 상대 평가로 사용되는 지표.

계산 방법: 문장(W)에 대한 generation probability 역수의 기하평균

, 문장 생성 확률의 역수를 단어의 수(N)으로 정규화

한계점: 일관성, 관련성 또는 맥락 이해와 같은 측면을 평가하지 못함

 

 

 

결론

ORPO tuned sample 모델은 단순한 sample text 데이터 기반 평가 기준으로 볼 때,

   LoRA가 원본 모델의 성능을 최대한 보존하면서 모델을 압축한 결과로 판단됨

 

Unsloth 환경에서 작업하는 경우에 원본 모델 저장 방법은 다음 코드를 실행

model.save_pretrained_merged("경로/모델이 저장될 파일 이름", tokenizer, safe_serialization = None)

 

, 저장 과정에서 GPU 사용이 적지 않으므로 GPU 여유가 없는 상태에서 실행시 에러 발생.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형