# 1. 개발 환경 설정¶ # 1.1 필수 라이브러리 설치하기¶ !pip3 install -q -U transformers==4.38.2 !pip3 install -q -U datasets==2.18.0 !pip3 install -q -U bitsandbytes==0.42.0 !pip3 install -q -U peft==0.9.0 !pip3 install -q -U trl==0.7.11 !pip3 install -q -U accelerate==0.27.2 # 1.2 Import modules¶ import torch from datasets import Dataset, load_dataset from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig, pipeline, TrainingArguments from peft import LoraConfig, PeftModel from trl import SFTTrainer # 1.3 Huggingface 로그인¶ from huggingface_hub import notebook_login notebook_login() # 2. Dataset 생성 및 준비¶ # 2.1 데이터셋 로드¶ from datasets import load_dataset dataset = load_dataset("daekeun-ml/naver-news-summarization-ko") # 2.2 데이터셋 탐색¶ dataset # 2.3 데이터셋 예시¶ dataset['train'][0] # 3. Gemma 모델의 한국어 요약 테스트¶ # 3.1 모델 로드¶ BASE_MODEL = "google/gemma-2b-it" model = AutoModelForCausalLM.from_pretrained(BASE_MODEL, device_map={"":0}) tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL, add_special_tokens=True) # 3.2 Gemma-it의 프롬프트 형식¶ doc = dataset['train']['document'][0] pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512) messages = [ { "role": "user", "content": "다음 글을 요약해주세요 :\n\n{}".format(doc) } ] prompt = pipe.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) prompt # 3.3 Gemma-it 추론¶ outputs = pipe( prompt, do_sample=True, temperature=0.2, top_k=50, top_p=0.95, add_special_tokens=True ) print(outputs[0]["generated_text"][len(prompt):]) # 4. Gemma 파인튜닝¶ 주의: Colab GPU 메모리 한계로 이전장 추론에서 사용했던 메모리를 비워 줘야 파인튜닝을 진행 할 수 있습니다. notebook 런타임 세션을 재시작 한 후 1번과 2번의 2.1 항목까지 다시 실행하여 로드 한 후 아래 과정을 진행합니다 !nvidia-smi # 4.1 학습용 프롬프트 조정¶ def generate_prompt(example): prompt_list = [] for i in range(len(example['document'])): prompt_list.append(r"""user 다음 글을 요약해주세요: {} model {}""".format(example['document'][i], example['summary'][i])) return prompt_list train_data = dataset['train'] print(generate_prompt(train_data[:1])[0]) # 4.2 QLoRA 설정¶ lora_config = LoraConfig( r=6, target_modules=["q_proj", "o_proj", "k_proj", "v_proj", "gate_proj", "up_proj", "down_proj"], task_type="CAUSAL_LM", ) bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.float16 ) BASE_MODEL = "google/gemma-2b-it" model = AutoModelForCausalLM.from_pretrained(BASE_MODEL, device_map="auto", quantization_config=bnb_config) tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL, add_special_tokens=True) tokenizer.padding_side = 'right' # 4.3 Trainer 실행¶ trainer = SFTTrainer( model=model, train_dataset=train_data, max_seq_length=512, args=TrainingArguments( output_dir="outputs", # num_train_epochs = 1, max_steps=3000, per_device_train_batch_size=1, gradient_accumulation_steps=4, optim="paged_adamw_8bit", warmup_steps=0.03, learning_rate=2e-4, fp16=True, logging_steps=100, push_to_hub=False, report_to='none', ), peft_config=lora_config, formatting_func=generate_prompt, ) trainer.train() # 4.4 Finetuned Model 저장¶ ADAPTER_MODEL = "lora_adapter" trainer.model.save_pretrained(ADAPTER_MODEL) !ls -alh lora_adapter model = AutoModelForCausalLM.from_pretrained(BASE_MODEL, device_map='auto', torch_dtype=torch.float16) model = PeftModel.from_pretrained(model, ADAPTER_MODEL, device_map='auto', torch_dtype=torch.float16) model = model.merge_and_unload() model.save_pretrained('gemma-2b-it-sum-ko') !ls -alh ./gemma-2b-it-sum-ko # 5. Gemma 한국어 요약 모델 추론¶ 주의: 마찬가지로 Colab GPU 메모리 한계로 학습 시 사용했던 메모리를 비워 줘야 파인튜닝을 진행 할 수 있습니다. notebook 런타임 세션을 재시작 한 후 1번과 2번의 2.1 항목까지 다시 실행하여 로드 한 후 아래 과정을 진행합니다 !nvidia-smi # 5.1 Fine-tuned 모델 로드¶ BASE_MODEL = "google/gemma-2b-it" FINETUNE_MODEL = "./gemma-2b-it-sum-ko" finetune_model = AutoModelForCausalLM.from_pretrained(FINETUNE_MODEL, device_map={"":0}) tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL, add_special_tokens=True) # 5.2 Fine-tuned 모델 추론¶ pipe_finetuned = pipeline("text-generation", model=finetune_model, tokenizer=tokenizer, max_new_tokens=512) doc = dataset['test']['document'][10] messages = [ { "role": "user", "content": "다음 글을 요약해주세요:\n\n{}".format(doc) } ] prompt = pipe_finetuned.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) outputs = pipe_finetuned( prompt, do_sample=True, temperature=0.2, top_k=50, top_p=0.95, add_special_tokens=True ) print(outputs[0]["generated_text"][len(prompt):])