LLM 엔지니어링4장 · LLM 을 완성하는 3단계와 Hugging Face8 / 23← 이전목차다음 →MetaContents

4장. LLM 을 완성하는 3단계와 Hugging Face

Hugging Face 생태계

스마트폰에서 앱이 필요하면 앱 장터에서 찾아 받고, 설명과 별점을 본 뒤 설치합니다. Hugging Face 의 Hub 는 모델과 데이터의 앱 장터이고, 파이썬 라이브러리는 받아 온 모델을 돌리는 도구입니다.

Hub, transformers, datasets, tokenizers 의 네 가지 Hugging Face 도구를 카드로 놓은 그림

카드 넷이 이 장에서 쓰는 도구입니다. Hub 는 모델과 데이터를 올리고 받는 곳, transformers 는 모델을 불러와 학습하고 글을 만드는 라이브러리, datasets 는 데이터를 읽고 나누고 바꾸는 라이브러리, tokenizers 는 토크나이저를 빠르게 학습하는 라이브러리입니다. 여기서 앱 장터가 Hub, 앱이 모델입니다.

도구마다 맡은 일

도구설치 이름이 장에서 쓰는 것실습
Hub(누리집)모델 이름으로 내려받기실습 1, 2
transformerstransformersAutoTokenizer, AutoModelForCausalLM, GPT2Config, Trainer실습 1, 2, 5, 6
datasetsdatasetsDataset.from_dict, map, train_test_split실습 4, 5, 6
tokenizerstokenizersByteLevelBPETokenizer실습 3
accelerateaccelerateTrainer 가 GPU 를 쓸 때 안에서 쓴다실습 5, 6

datasets 맛보기

datasets 의 Dataset 은 pandas 의 표와 비슷하지만, map 으로 큰 데이터를 묶음 단위로 빠르게 바꾸는 데 특화되어 있습니다.

Python
from datasets import Dataset

ds = Dataset.from_dict({"질문": ["배송비는?", "환불은 언제?", "쿠폰 몇 장?"]})

# map: 행마다(또는 묶음마다) 함수를 적용해 새 열을 만든다
ds = ds.map(lambda row: {"글자수": len(row["질문"])})
print(ds)
print(ds[0])

열이 ['질문', '글자수'] 인 3행짜리 데이터가 되고, 첫 행은 {'질문': '배송비는?', '글자수': 5} 입니다. 실습 4에서 이 map 으로 글을 토큰으로 바꿉니다.

코드에 나오는 함수

코드쉬운 뜻
Dataset.from_dict({...})열 이름과 값 목록을 담은 사전으로 데이터 표를 만든다. dict 는 dictionary(사전)의 줄임말이다
ds.map(함수)표의 행마다 함수를 적용하고, 함수가 돌려준 사전을 새 열로 붙인다. map 은 "하나하나 대응시키다"라는 뜻이다
lambda row: {...}이름 없이 한 줄로 쓰는 작은 함수다. 행 하나(row)를 받아 새 열의 값을 돌려준다
print(ds)표의 열 이름(features)과 행 수(num_rows)를 요약해 보여 준다
ds[0]첫 행을 사전 꼴로 꺼낸다

이 코드가 뜻하는 것

엑셀에서 옆 칸에 =LEN(A1) 을 적고 아래로 쭉 끌어 채우는 것과 같습니다. map 이 "아래로 끌어 채우기"를 대신해 줍니다.

줄하는 일쉽게 말하면
Dataset.from_dict({"질문": [...]})질문 세 개를 한 열로 담은 표를 만든다A 열에 질문 세 개를 적는다
ds.map(lambda row: {"글자수": len(row["질문"])})행마다 질문의 글자 수를 세어 새 열에 적는다B 열에 =LEN(A1) 을 적고 끌어 채운다
print(ds), print(ds[0])표의 생김새와 첫 행을 본다표 전체와 첫 줄을 훑어본다

map 은 원래 표를 고치지 않고 새 표를 돌려주므로 ds = ds.map(...) 처럼 다시 받아야 합니다. 실행하면 Map: 100% 같은 진행 막대가 함께 찍힐 수 있는데, 오류가 아니라 몇 행을 바꿨는지 보여 주는 표시입니다.

작게 줄여서 눈으로 보기

실습 4, 5에서는 map 에 batched=True 를 주고, 학습용과 검증용을 train_test_split 으로 나눕니다. 질문 네 개로 두 가지를 미리 써 봅니다.

Python
from datasets import Dataset, disable_progress_bars

disable_progress_bars()                 # 진행 막대를 끄고 결과만 본다
ds = Dataset.from_dict({"질문": ["배송비는?", "환불은 언제?", "쿠폰 몇 장?", "교환 되나요?"]})

# batched=True: 행 하나씩이 아니라 여러 행을 묶음(목록)으로 받아 한 번에 바꾼다
ds = ds.map(lambda batch: {"글자수": [len(q) for q in batch["질문"]]}, batched=True)
print(list(ds["글자수"]))

# 학습용과 검증용으로 나눈다. seed 를 고정하면 다시 돌려도 같게 나뉜다
parts = ds.train_test_split(test_size=0.25, seed=42)
print("학습용:", list(parts["train"]["질문"]))
print("검증용:", list(parts["test"]["질문"]))
출력
[5, 7, 7, 7]
학습용: ['쿠폰 몇 장?', '환불은 언제?', '배송비는?']
검증용: ['교환 되나요?']
결과읽는 법
[5, 7, 7, 7]질문 네 개의 글자 수입니다. 띄어쓰기와 물음표도 한 글자로 셉니다. batched=True 라서 함수는 질문 목록을 한꺼번에 받고, 값도 목록으로 돌려줍니다
학습용test_size=0.25(4분의 1을 검증용으로) 이라 네 개 가운데 세 개가 학습용입니다. 순서는 섞여 있습니다
검증용나머지 하나 "교환 되나요?"가 검증용입니다. seed=42 를 고정해 두어 다시 돌려도 같은 질문이 뽑힙니다

train_test_split 은 "학습용(train)과 시험용(test)으로 나누기"라는 뜻이고, 결과는 "train", "test" 두 이름으로 꺼냅니다.

주의할 점

  • Hub 에는 누구나 모델을 올릴 수 있습니다. 내려받기 전에 올린 곳(회사나 단체)과 내려받은 수, 모델 카드를 확인합니다.
  • 모델 파일은 처음 한 번만 내려받고 C:\Users\사용자이름\.cache\huggingface 에 저장됩니다. 디스크가 부족하면 이 폴더를 정리합니다.
← 이전 절4장 · 정렬다음 절 →4장 · 모델 카드와 라이선스