LLM 에 대한 연구를 하는 사람이라면 누구나 disk 용량 관리에 어려움을 겪었을거라 생각한다.
sLLM 이라도 16bf 인 7~8B 모델의 size 가 14~16GB 가 되기 때문이다.
모델을 4개만 저장해도 50GB 가 넘는다.
데이터셋 또한 Pretrain 용 Corpus 는 GB 단위이기에 모델뿐만 아니라 데이터셋도 관리해줘야 한다.
이번 포스팅은 점점 커지는 Size 의 모델과 데이터셋을 HF(HuggingFace) HUB 로 관리하는 방법을 설명하고자 한다.
※ sLLM 에 대한 연구를 하는 사람에게 도움이 되는 글임을 유의하길 바란다.
목차
1. Model 을 HF HUB 에 저장하고 불러오기
2. 서버의 cache 관리하기
3. Dataset 을 HF HUB 에 저장하고 불러오기
1. Model 을 HF HUB 에 저장하고 불러오기
HF HUB 에는 모델의 크기가 아무리 커도 전부 저장된다. (신기신기 👀)
만약 사용하고 있는 서버의 disk 가 부족하다면 HUB 에 모델을 저장해두고 필요할 때 사용하는걸 추천한다.
HF HUB 에 업로드하기 전에 disk 에 학습한 모델을 저장해야 한다.
저장하는 코드는 다음과 같다. (LoRA 로 학습한 뒤, adapter 를 저장했다는 가정 하에 adapter 를 모델의 weight 에 추가해주는 코드도 있으니 참고 바란다.)
from transformers import AutoTokenizer
from transformers import AutoModelForCausalLM
from peft import PeftConfig
from peft import PeftModel
# 학습한 LoRA adapter 를 Foundation 모델(or Instruct 모델)에 더하여 저장하고 싶을 때 사용
add_lora_adapter = True
if add_lora_adapter:
peft_model_id = lora_adapter_name # disk 에 저장했다면 path 입력
base_model = base_model_name # in huggingface hub
output_dir = "output_dir"
tokenizer = AutoTokenizer.from_pretrained(base_model)
# 모델은 웬만하면 bf16 으로 저장하자. load 할 때를 위함.
model = AutoModelForCausalLM.from_pretrained(base_model, device_map="auto", torch_dtype=torch.bfloat16)
if add_lora_adapter:
tokenizer = AutoTokenizer.from_pretrained(peft_model_id) # 학습할때 사용한 chat_template 적용을 위함
model = PeftModel.from_pretrained(model, peft_model_id) # lora adapter 를 model weight 에 add 해줌
model = model.merge_and_unload() # merge
# save model > bf16
tokenizer.save_pretrained(output_dir)
model.save_pretrained(output_dir)
# 모델 사이즈를 확인하고 싶을 때
tot_params = sum(p.numel() for p in model.parameters())
print(tot_params) # 전체 parameters 수 확인
print(f"{tot_params * 2} byte") # bf16 기준 모델 사이즈 확인
- 물론 lora adapter 도 HUB 에 저장한 뒤 사용해도 된다.
필자는 lora adapter 는 size 가 얼마 안 되기에 귀찮으니 그렇게 하지 않는다. - 만약 모델을 HUB 에 Save 만 할거라면 device_map = "cpu" 로 설정하는걸 추천한다.
- 모델을 bf16 으로 저장하는 이유는 나중에 load 했을 때 bf16 으로 사용하기 편하기 위해서이다.
추세는 fp32 보다 bf16 이다. sLLM 도 빌리언 단위로 매우 큰 Size 의 모델이기 때문이다.
disk 에 모델을 저장했으면 저장한 모델을 HUB 에 upload 해주자.
from huggingface_hub import login, HfApi
login(token=f"hf_{your_token}")
# save folder
api = HfApi()
api.upload_folder(
folder_path=saved_model_path,
path_in_repo=saved_model_path,
repo_id=f"{HF_id}/{model_name_foramt}",
repo_type="model",
)
# delete folder
from huggingface_hub import delete_repo
delete_repo(repo_id=f"{yoru_hf_id}/{model_name_foramt}", repo_type="model")
- model card 는 별도로 작성해야 함을 기억하길 바란다.
모델에 대한 정보를 충분히 card 에 작성해야 관리하기 용이하다. - model_name_format 에 맞춰 model name 을 입력한 뒤, 저장하기 바란다.
- 만약 HUB 에서 모델을 삭제하고자 한다면 delete_repo 를 사용하자.
2. 서버의 cache 관리하기
HUB 에 저장된 모델을 불러와서 사용하다보면 어느샌가 서버의 disk 가 부족하다는 메세지를 보곤 할 것이다.
어?? 나는 모델을 서버에 저장한 적이 없는데??
생각할 수도 있다.
이러한 이슈가 발생하는 이유는 HUB 에 저장된 모델 or 데이터셋을 불러와서 사용하기 위해 cache 에 해당 폴더가 저장되기 때문이다.
아래 사진을 참고하기 바란다.
hub 라는 폴더가 59G 나 먹고 있다.
이는 필자가 HUB 에서 모델을 불러와 사용했기 때문이다.
(AutoModelForCausalLM class 를 사용해서 모델을 불러오면 hub 에 저장되기 때문)
때문에 주기적으로 cache 를 관리해줘야 한다.
3. Dataset 을 HF HUB 에 저장하고 불러오기
모델링을 해본 사람이라면 누구나 공감하겠지만 좋은 성능의 모델을 위해서는 양질의 학습 데이터가 필요하다.
때문에 학습 데이터 및 검증 데이터의 관리는 필수적이다.
현업에서 실험을 하다보면 플젝에 의해 많아지는 데이터셋, 관리 되지 않는 데이터셋 때문에 골치 아팠던 경험이 있을 거다. (내가 그렇다...)
특히 sLLM 을 Instruct tuning 하는 실험을 하다보면 동일한 데이터셋인데도 DataFrame 의 형태가 바뀌는 경우가 있다.
이를 관리하기 위해 필자는 HUB 에서 데이터셋을 관리한다.
HUB 에 데이터셋을 load 했을 때 Dataset Viewer 를 통해 DataFrame 의 형태로 확인할 수 있는 방법은 다음과 같다.
바로 데이터셋을 parquet format 으로 저장하는 거다.
저장하는 코드는 매우 간단하다.
import pandas as pd
from datasets import Dataset
df = pd.read ~~~
repo_id = "{your_hf_id}/{dataset_name_format}"
dataset = Dataset.from_pandas(df)
dataset.push_to_hub(repo_id)
- DataFrame 을 Dataset format 으로 변경한 뒤 push_to_hub 를 사용하여 HUB 에 load 할 수 있다.
그렇게 되면 parquet format 으로 데이터셋이 저장된다. - Dataset card 는 별도로 작성해야 함을 기억하길 바란다.
데이터셋에 대한 정보를 충분히 card 에 작성해야 관리하기 용이하다. - parquet format 으로 저장된 데이터셋은 Dataset Viewer 를 통해 DataFrame 을 HUB 에서 확인할 수 있다.
아래 예시 사진을 참고하자.
만약 데이터셋(모델도 마찬가지)을 다른 사람에게 배포하고 싶지 않다면 Settings 에서 Private 으로 설정하면 된다.
단, 데이터셋의 경우, Viewer 는 Private 에서는 HF pro 를 사용해야(돈 내야됨..) Private 에서 Viewer 가 동작한다.
즉, pro 를 사용하지 않으면 Private 에서는 Viewer 가 동작하지 않는다는 의미이다.
마무리,,
오늘은 HF HUB 에 모델 또는 데이터를 올리고 관리하는 방법에 대해 알아봤다.
필자의 경험상 가장 중요한건 Model card or Dataset card 를 어떻게 작성하는지라고 생각한다.
card 에 최대한 상세하게 정보를 담아놔야 나중에 찾기 편하다.
모델 또는 데이터셋의 name format 을 알아보기 편하게 구성한다 해도 결국 관리해야 할 양이 많아지면 중요해지는건 card 이다. 얼마나 상세한 정보를 card 에 담아두느냐가 관건이다.
다음 포스팅으로는 모델이 생성한 답변을 RAGAS 와 LangSmith 를 활용하여 어떻게 정량적인 성능 지표를 뽑아낼 수 있는지, 그리고 해당 성능지표의 근거는 무엇인지 파악하는 방법에 대해 다루도록 하겠다.
'Natural Language Processing > HuggingFace 훑어보기' 카테고리의 다른 글
[Code review] Transformers Trainer class 기능 정리 (0) | 2023.02.17 |
---|
댓글