윈도우 환경에서 로컬 Gemma 3 + LoRA + 4bit 양자화 기반 LLM 파인튜닝 가이드입니다.
개요
대규모 언어모델(LLM)의 활용이 점차 확대됨에 따라, 개인 또는 소규모 팀에서도 효율적으로 모델을 커스터마이징할 수 있는 기법이 주목받고 있습니다. 이 글에서는 Google의 Gemma 3 12B 모델을 기반으로, 4bit 양자화 + LoRA + TRL의 SFTTrainer를 이용하여 파인튜닝하는 전체 과정을 정리합니다.
이번 글에서는 파인튜닝된 모델을 Ollama에서 사용할 수 있도록 GGUF 형식으로 변환하는 방법도 포함되어 있습니다. 이를 통해 로컬 환경에서 LLM을 효율적으로 활용할 수 있는 기반을 마련할 수 있습니다.
LLM 파인튜닝을 통해 특정 도메인에 최적화된 모델을 구축하거나, 기존 모델의 성능을 향상시킬 수 있습니다. 또한, LLM의 응답 방향이나 어조를 조정하여 특정 업무에 맞는 모델을 만들 수 있습니다.
나만의 데이터셋을 활용하여 LLM을 커스터마이징함으로써, 더 나은 사용자 경험을 제공할 수 있습니다.
Warning
로컬에서 개인적으로 사용할 때에는 학습 데이터셋의 윤리적인 문제나 정치/사회적 이슈에 대한 고려가 크게 중요하지 않지만, 모델을 공개할 경우, 반드시 가이드 라인이나 정책을 준수해야 합니다. 또한, 모델의 응답이 특정 도메인에 편향되지 않도록 주의해야 합니다.
target_modules는 Transformer의 핵심 모듈들로, 선택적으로 LoRA 적용을 통해 메모리 효율을 높입니다. 모델에 따라 다를 수 있으며, q_proj, o_proj, k_proj, v_proj 등은 일반적으로 사용되는 모듈입니다. 이번 가이드에서는 Gemma3 모델에 최적화된 모듈을 선택했습니다.
lora_alpha는 LoRA의 스케일링 파라미터로, LoRA의 효과를 조절합니다. 일반적으로 r과 lora_alpha의 비율을 맞추는 것이 좋습니다. r과 lora_alpha는 보통 r=8~64, alpha=r*2 비율이 적절합니다.
모델 로딩 및 사전 처리
model = AutoModelForCausalLM.from_pretrained( MODEL_NAME, device_map="auto", quantization_config=bnb_config, attn_implementation="eager",)model = prepare_model_for_kbit_training(model)model.gradient_checkpointing_enable()model.enable_input_require_grads()model.resize_token_embeddings(len(tokenizer))
gradient_checkpointing을 사용해 GPU 메모리 사용량을 줄입니다.
prepare_model_for_kbit_training는 PEFT에서 LoRA를 4bit 모델에 적용할 수 있도록 해줍니다.
<start_of_turn>과 <end_of_turn> 토큰은 대화의 시작과 끝을 명시적으로 표시합니다. <bos>와 <eos> 토큰은 대화의 시작과 끝을 나타내며, 모델이 응답을 생성할 때 이 토큰들을 인식할 수 있도록 합니다. 이 태그를 지정하지 않으면, 모델이 응답을 무한히 생성할 수 있습니다.
위 코드를 train.py 파일로 저장하고, 필요한 라이브러리를 설치한 후 실행하면 학습이 진행됩니다. 준비된 훈련 데이터셋의 양에 따라 학습 시간은 달라질 수 있습니다. 보통 유의미한 데이터셋에 대해 4-8시간 정도 소요되며, 데이터셋이 많을 경우 며칠까지 소요될 수 있습니다.
LoRA 병합 및 저장
위의 학습이 완료되었다면, LoRA adapter를 병합하여 최종 모델을 저장할 수 있습니다.
한번에 병합하는 코드는 다음과 같습니다.
merge_lora.py
import osfrom transformers import AutoModelForCausalLM, AutoTokenizerfrom peft import PeftModelBASE_MODEL_PATH = "../gemma-3-12b-it" # 원본 Gemma3 모델 경로LORA_ADAPTER_PATH = "./output/final" # 학습 완료된 LoRA 어댑터 경로OUTPUT_DIR = "./output/merged" # 병합 결과 저장 폴더def merge_lora_and_save(base_path, lora_path, output_path): # Base 모델 로드 base_model = AutoModelForCausalLM.from_pretrained(base_path) # LoRA 어댑터 적용 lora_model = PeftModel.from_pretrained(base_model, lora_path) # merge_and_unload 메서드를 사용하여 LoRA 어댑터 병합 merged_model = lora_model.merge_and_unload() # 모델 저장 os.makedirs(output_path, exist_ok=True) merged_model.save_pretrained(output_path) # 토크나이저 로드 및 저장 tokenizer = AutoTokenizer.from_pretrained(base_path) tokenizer.save_pretrained(output_path)if __name__ == "__main__": merge_lora_and_save(BASE_MODEL_PATH, LORA_ADAPTER_PATH, OUTPUT_DIR)
양자화 및 GGUF 파일 변환
최종 병합된 모델을 이제 Ollama에서 사용할 수 있도록 GGUF 형식으로 변환해 주어야 합니다.
이번 가이드에서는 Q4_K_M 옵션을 사용하여 4bit 양자화를 수행합니다. 이 과정은 모델의 크기를 줄이고, Ollama에서 더 빠르게 로드할 수 있도록 합니다.
컴퓨터의 사양에 따라 Q4_K_S, Q4_K_M, Q8_0 등의 옵션을 선택할 수 있습니다.
Ollama에 모델 탑재
Ollama 명령어를 통해 먼저 기존에 임포트 된 Gemma3 모델의 modelfile을 확인합니다.
아래와 같이 ollama show 명령어를 사용하면 모델 적재 시 사용된 modelfile의 내용을 확인할 수 있습니다.
C:\>ollama show --modelfile gemma3:12b# .. 중략 ...TEMPLATE """{{- range $i, $_ := .Messages }}{{- $last := eq (len (slice $.Messages $i)) 1 }}{{- if or (eq .Role "user") (eq .Role "system") }}<start_of_turn>user{{ .Content }}<end_of_turn>{{ if $last }}<start_of_turn>model{{ end }}{{- else if eq .Role "assistant" }}<start_of_turn>model{{ .Content }}{{ if not $last }}<end_of_turn>{{ end }}{{- end }}{{- end }}"""PARAMETER stop <end_of_turn>PARAMETER temperature 1PARAMETER top_k 64PARAMETER top_p 0.95LICENSE """Gemma Terms of Use
위 파일 내용에서 TEMPLATE 부분과 PARAMETER 부분을 참고하여 파인 튜닝된 모델에 대한 modelfile을 작성합니다.
FROM ./gemma3-q4k.ggufTEMPLATE """{{- range $i, $_ := .Messages }}{{- $last := eq (len (slice $.Messages $i)) 1 }}{{- if or (eq .Role "user") (eq .Role "system") }}<start_of_turn>user{{ .Content }}<end_of_turn>{{ if $last }}<start_of_turn>model{{ end }}{{- else if eq .Role "assistant" }}<start_of_turn>model{{ .Content }}{{ if not $last }}<end_of_turn>{{ end }}{{- end }}{{- end }}<eos>"""PARAMETER stop <end_of_turn>PARAMETER stop <eos>PARAMETER temperature 1PARAMETER top_k 64PARAMETER top_p 0.95PARAMETER repeat_penalty 1.2PARAMETER num_ctx 4096
FROM 부분은 양자화된 모델 파일의 경로를 지정합니다. PARAMETER 부분은 모델의 동작 방식을 조정하는 파라미터들입니다. stop 파라미터는 모델이 응답을 중단할 조건을 지정합니다. temperature 파라미터는 모델의 응답 다양성을 조절하는데, 값이 높을수록 더 창의적인 응답을 생성합니다. top_k와 top_p는 샘플링 전략을 조정하여 모델의 응답 품질을 향상시킵니다.
위 파일 내용을 Modelfile 이름으로 저장합니다.
이제 아래 명령어로 Ollama에 모델을 임포트합니다.
ollama create gemma3-q4k -f Modelfile
모델의 이름과 파일명은 개인 취향에 맞춰 변경하시면 됩니다.
이렇게 하면 Ollama에서 파인튜닝된 나만의 모델을 사용할 수 있습니다.
맺음말
Gemma 3 12B 모델에 대해 LoRA + 4bit 양자화 + SFT 학습으로 LLM 모델을 파인튜닝하는 방법에 대해 알아보았습니다. 윈도우 로컬 학습을 기반으로 설명을 하였으나, 리눅스/맥은 물론 클라우드 환경(예: Colab, A100)에서도 약간의 수정을 통해 동일하게 학습이 가능합니다.
더 나아가 멀티 GPU 환경에서의 학습, 데이터 증강 및 샘플 필터링, LoRA 구성 변경(다른 target module 추가), inference 최적화 및 Deployment 전략 설계 등 다양한 확장 가능성이 있습니다.