자연어처리

[Hugging Face] PEFT에 대해 알아보자

4n3mone 2023. 2. 16. 15:37

본 포스트에서는 자연어처리 분야에서 입지전적인 위치를 가지고 있는 Hugging Face에서 새로이 개발한 🤗PEFT :Parameter-Efficient Fine-Tuning of Billion-Scale Models on Low-Resource Hardware의 설명 문서를 번역하여 소개하겠습니다.

 

원문 링크 

 


PEFT의 등장배경

GPT, t5, bert와 같은 트랜스포머 기반의 거대 언어 모델은 현재 다양한 자연어처리 작업에서 가장 좋은 성능을 보이고 있습니다. 그리고 트랜스포머 구조는 VIT, Stable diffusion, LayoutLM과 같은 컴퓨터 비전 분야, whisper, XLS-R과 같은 음성 분야에도 진출하기도 했습니다. 기존의 패러다임은 거대한 단위의 웹 데이터를 사전학습(pre-train)하고, downstream task에 따라 파인튜닝하는 것이었습니다. 사전학습된 LLM(Large Language Model)을 다운스트림 데이터셋에 따라서 파인튜닝하는것은 사전학습 모델을 그대로 사용하는것보다 확실한 성능의 향상을 보여줍니다.

 

하지만 모델이 점점 커짐에 따라 시판 그래픽카드로 모델 전체를 파인튜닝하는것은 불가능해져가고 있습니다. 또한  파인튜닝된 모델이 파인튜닝하기 이전의 사전학습된 모델과 똑같은 크기이기 때문에 파인튜닝된 모델을 저장하고 사용하는 것 또한 (시간, 경제적으로) 비용이 많이 드는 일입니다. PEFT(parameter-efficient fine tuning)은 이 두 가지의 문제를 해결하고자 등장했습니다.

 

PEFT는 사전학습된 LLM의 대부분의 파라미터를 프리징하고 일부의 파라미터만을 파인튜닝함으로써 저장공간과 계산능력을 대폭 줄였습니다. 파인튜닝할때 발생하는 문제점중 하나인 catastrophic forgetting또한 극복했습니다. PEFT는 또한 *적은 데이터 체제(low-data-regime)에서 파인튜닝할때나 도메인 밖의 데이터(out-of-domain scenario)를 일반화할때 더욱 좋은 성능을 보여주었습니다. (예를 들면 이미지 분류, stable diffusion의 dreambooth)

 

또한 PEFT 방법을 사용하여 모델을 조정하여 전체 파인튜닝에서 만들어지는 큰 크기의 체크포인트 파일과 달리 수 메가바이트의 작은 체크포인트 파일을 얻을 수 있기 때문에  저장 공간 관리에도 도움이 됩니다. 예를 들어, Hugging Face의 bigscience/mt0-xl은 40GB의 저장 공간을 차지하고 전체 파인튜닝으로 인해 각 다운스트림 데이터 세트에 대해 40GB의 체크포인트 파일이 생성되지만 PEFT를 사용하면  다운스트림 데이터 세트에 대해 몇개의 적은 용량을 가진 체크포인트 파일을 제공하는 동시에 전체 파인 튜닝과 유사한 성능을 달성합니다. PEFT를 통해 학습된 적은 양의 가중치는 사전학습된 LLM모델 레이어의 가장 윗부분에 위치하게 됩니다. 그렇기 때문에 모델 전체를 대체할 필요 없이 조금의 가중치만 추가하는 작업으로 같은 모델로 여러 작업을 수행할 수 있게 됩니다.

 

한마디로, PEFT는 적은 수의 파라미터를 학습하는것만으로 모델 전체를 파인튜닝하는 것과 유사한 효과를 누릴 수 있도록 해줍니다.  

 

 

🤗PEFT 라이브러리에서는 최신 PEFT 기술들을 허깅페이스의 🤗transformers 라이브러리와 🤗accelerate 라이브러리와 연동해서 사용할 수 있도록 해줍니다. 현재 사용 가능한 PEFT방법들은 다음과 같습니다.(추가 예정)

 

  1. LoRA: LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS
  2. Prefix Tuning: P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks
  3. Prompt Tuning: The Power of Scale for Parameter-Efficient Prompt Tuning
  4. P-Tuning: GPT Understands, Too    

 

 


용례

🤗Hugging Face 깃허브에서 🤗PEFT 라이브러리의 여러 사용법들을 접할 수 있습니다. 다음은 가장 흥미로웠던 몇 가지 사용법입니다. 

 

1. 🤗PEFT LoRa와 🤗Accelerate의 deepspeed를 사용해 bioscience/t0_3B모델을 11기가 vram을 가진 RTX 2080이나 RTX 3080으로 파인튜닝하기 : 이것은 당신이 거대 LLM들을 구글 코랩에서 파인튜닝할 수 있다는 것을 의미합니다. 

코드 링크 

 

2. Google Colab에서 🤗PEFT LoRa와 butandbytes를 이용해 OPT-6.7b 모델(파라미터 6.7억개)의 **INT8 튜닝을 활성화하여 1번 예제를 한 단계 업그레이드하기

구글 코랩 노트북 링크 

 

3. 🤗PEFT를 통해 11기가 vram을 가진 rtx 2080, rtx 3080 등으로 stable diffusion dream booth 이용하기 

데모 사이트 링크 

 

 


🤗PEFT로 자신의 모델 학습시키기

 

LoRa 방법을 이용해서 허깅 페이스가 제공하는 사전학습된 모델  bigscience/mt0-large 를 파인튜닝한다고 생각봅시다.

 

1. 필수 모듈 임포트

  from transformers import AutoModelForSeq2SeqLM
+ from peft import get_peft_model, LoraConfig, TaskType
  model_name_or_path = "bigscience/mt0-large"
  tokenizer_name_or_path = "bigscience/mt0-large"

 

2. 해당하는 PEFT방법에 맞는 config 만들기

peft_config = LoraConfig(
    task_type=TaskType.SEQ_2_SEQ_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1
)

3. get_peft_model 함수 안에 베이스가 되는 허깅페이스 모델와 설정해둔 config 넣어주기

  model = AutoModelForSeq2SeqLM.from_pretrained(model_name_or_path)
+ model = get_peft_model(model, peft_config)
+ model.print_trainable_parameters()
# output: trainable params: 2359296 || all params: 1231940608 || trainable%: 0.19151053100118282

 

됐습니다! 나머지 학습과정은 보통 모델과 다르지 않습니다. 처음부터 끝까지 과정을 보려면 다음 예시 파일을 참고해주세요. peft_lora_seq2seq.ipynb 

 

4. 추론을 하기 위해 모델을 저장하고 싶다면 다음과 같이 하시면 됩니다.

model.save_pretrained("output_dir") 
# model.push_to_hub("my_awesome_peft_model") also works

이 코드를 사용하면 PEFT방법을 통해 추가로 학습된 파라미터들만 저장합니다.

 

예를 들어, smangrul/twitter_complaints_bigscience_T0_3B_LORA_SEQ_2_SEQ_LM 에서 확일할 수 있는 LoRa를 사용해서 트위터 불만 데이터셋으로 파인튜닝한 T0-3B모델의 모델 파일은 adapter_config.json,  adapter_model.bin인데 용량이 19MB밖에 되지 않는 것을 확인할 수 있습니다. 

 

5. 저장한 모델을 불러와 추론하려면 다음과 같이 하세요.

  from transformers import AutoModelForSeq2SeqLM
+ from peft import PeftModel, PeftConfig

  peft_model_id = "smangrul/twitter_complaints_bigscience_T0_3B_LORA_SEQ_2_SEQ_LM"
  config = PeftConfig.from_pretrained(peft_model_id)
  model = AutoModelForSeq2SeqLM.from_pretrained(config.base_model_name_or_path)
+ model = PeftModel.from_pretrained(model, peft_model_id)
  tokenizer = AutoTokenizer.from_pretrained(config.base_model_name_or_path)

  model = model.to(device)
  model.eval()
  inputs = tokenizer("Tweet text : @HondaCustSvc Your customer service has been horrible during the recall process. I will never purchase a Honda again. Label :", return_tensors="pt")

  with torch.no_grad():
      outputs = model.generate(input_ids=inputs["input_ids"].to("cuda"), max_new_tokens=10)
      print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0])
# 'complaint'

 


PEFT가 나아갈 방향

🤗Hugging Face에서는 거대 언어 모델을 downstream task와 도메인에 따라 효율적으로 파인튜닝하기 위한 방법을 제시했고, 이를 통해 계산 능력과 저장 공간을 모델 전체를 파인튜닝했던 기존 방법에 비해 크게 절약할 수 있었습니다. 앞으로는 ***(IA)^3이나 ****bottleneck adapter와 같은 추가적인 PEFT방법을 탐색할 것이며, whisper-large 을 구글 코랩에서 INT8 학습시키거나 PEFT를 사용해서 정책, 순위매기기등과 같은 *****RLHF(Reinforcement Learning from Human Feedback)을 구현해보는등 새로운 사용법들을 제시할 것입니다.

 

PEFT에 대한 질문이나 피드백이 있다면 GitHub repo 🤗에 이슈로 남겨주세요!

 


참고자료

* Low-data-regime : Object detection in the low data regime

** INT8 Tuning : NVIDIA TensorRT를 통한 양자화 인식 학습을 사용하여 INT8 추론에 대한 FP32 정확도 달성 ,

What Is int8 Quantization and Why Is It Popular for Deep Neural Networks?

*** (IA)^3 : Irregular Applications:From Architectures to Algorithms   

**** RLHF(Reinforcement Learning from Human Feedback) : Illustrating Reinforcement Learning from Human Feedback (RLHF)