4장. LLM 을 완성하는 3단계와 Hugging Face
모델 카드와 라이선스
마트에서 처음 보는 식품을 살 때 성분표와 유통기한부터 봅니다. Hub 의 모델에도 성분표가 있습니다. 모델 카드입니다.
모델 카드에서 먼저 볼 것은 셋입니다. 상업적으로 써도 되는지(라이선스), 무엇으로 얼마나 배웠는지(학습 데이터와 크기), 무엇에 쓰라고 만들었고 어떤 약점이 있는지(쓰임과 한계)입니다. 여기서 식품의 성분표가 모델 카드입니다.
자주 보는 라이선스
| 라이선스 | 상업적 사용 | 조건 | 이 과정의 예 |
|---|---|---|---|
| Apache 2.0 | 된다 | 라이선스 문구를 함께 남긴다 | Qwen2.5-0.5B, Qwen2.5-0.5B-Instruct |
| MIT | 된다 | 저작권 표시를 남긴다 | 여러 작은 도구 |
| CC-BY 4.0 | 된다 | 출처를 밝힌다 | 3장 번역 모델 |
| CC-BY-NC | 안 된다 | 비영리로만 | 일부 연구용 모델 |
| 회사별 라이선스 | 조건부 | 사용자 수나 쓰임에 제한이 있다 | 일부 대형 공개 모델 |
라이선스 문구의 해석은 회사의 법무 담당과 확인합니다. 이 표는 대략의 성격만 정리한 것입니다.
코드로 모델 정보 보기
모델 카드의 일부와 설정은 코드로도 볼 수 있습니다. config.json 은 모델과 함께 내려받아지는 설정 파일입니다.
from transformers import AutoConfig
# 모델 전체가 아니라 설정 파일만 받아 크기를 확인한다(몇 KB)
cfg = AutoConfig.from_pretrained("Qwen/Qwen2.5-0.5B")
print("층 수:", cfg.num_hidden_layers)
print("좌표 수:", cfg.hidden_size)
print("헤드 수:", cfg.num_attention_heads)
print("어휘 크기:", cfg.vocab_size)층 24개, 좌표 896개, 헤드 14개, 어휘 151,936개로 나옵니다. 3장의 GPT-1 표와 같은 항목입니다. 모델 전체(1GB 쯤)를 받기 전에 설정만 보고 우리 GPU 에 맞을지 어림할 수 있습니다.
코드에 나오는 함수
| 코드 | 쉬운 뜻 |
|---|---|
AutoConfig.from_pretrained("Qwen/Qwen2.5-0.5B") | Hub 에서 그 모델의 config.json 만 받아 설정 객체로 만든다. from_pretrained 는 "미리 학습된 것에서 불러오기"라는 뜻이다 |
cfg.num_hidden_layers | 층(Transformer 블록)의 수다. hidden layer 는 입력과 출력 사이에 숨은 층이라는 뜻이다 |
cfg.hidden_size | 토큰 하나를 나타내는 좌표 수(벡터의 길이)다 |
cfg.num_attention_heads | 멀티헤드 어텐션의 헤드 수다 |
cfg.vocab_size | 어휘 크기, 곧 토크나이저가 아는 토큰의 가짓수다. vocab 은 vocabulary(어휘)의 줄임말이다 |
이 코드가 뜻하는 것
가구를 사기 전에 상품 설명서의 치수만 먼저 보는 것과 같습니다. 가구(모델 가중치, 1GB 쯤)를 집에 들이기 전에 치수(설정, 몇 KB)만 보고 방(GPU)에 들어갈지 어림합니다.
| 줄 | 하는 일 | 쉽게 말하면 |
|---|---|---|
cfg = AutoConfig.from_pretrained(...) | 모델 이름으로 설정 파일만 받는다 | 설명서만 먼저 받아 본다 |
cfg.num_hidden_layers 등 네 줄 | 층 수, 좌표 수, 헤드 수, 어휘 크기를 찍는다 | 가로, 세로, 높이, 칸 수를 읽는다 |
이 코드는 인터넷으로 Hub 에서 파일을 받으므로 처음 한 번은 인터넷이 있어야 합니다. 찍힌 네 숫자가 클수록 파라미터가 많아지고, 그만큼 GPU 메모리도 많이 듭니다.
작게 줄여서 눈으로 보기
설정 객체는 내려받지 않고 직접 만들 수도 있습니다. 실습 5의 작은 GPT 와 같은 크기의 GPT2Config 를 만들어 같은 항목을 읽고, 빈 모델을 만들어 파라미터 수까지 세어 봅니다. 내려받기가 없어 인터넷 없이 돌아갑니다.
from transformers import GPT2Config, GPT2LMHeadModel
# 실습 5의 작은 GPT 와 같은 크기의 설정을 내려받기 없이 직접 만든다
config = GPT2Config(
vocab_size=1162, # 실습 3에서 만든 어휘 크기
n_positions=128, # 한 번에 보는 최대 토큰 수
n_embd=256, n_layer=4, n_head=4, # 좌표 수, 층 수, 헤드 수
pad_token_id=0, bos_token_id=1, eos_token_id=1, # 특수 토큰 번호(설명용)
)
print("층 수:", config.num_hidden_layers)
print("좌표 수:", config.hidden_size)
print("헤드 수:", config.num_attention_heads)
print("어휘 크기:", config.vocab_size)
model = GPT2LMHeadModel(config) # 설정대로 빈 모델을 만든다
print(f"파라미터 수: {sum(p.numel() for p in model.parameters()):,}")층 수: 4
좌표 수: 256
헤드 수: 4
어휘 크기: 1162
파라미터 수: 3,489,792| 결과 | 읽는 법 |
|---|---|
| 층 수, 좌표 수, 헤드 수 | 우리가 n_layer, n_embd, n_head 로 준 4, 256, 4 가 Qwen 과 같은 이름(num_hidden_layers 등)으로도 읽힙니다. GPT-2 는 설정 이름이 달라도 같은 항목을 이렇게 맞춰 줍니다 |
| 어휘 크기 | 1,162 로 Qwen 의 151,936 보다 훨씬 작습니다 |
| 파라미터 수 | 3,489,792 개로, 실습 5에서 센 값과 같습니다. Qwen2.5-0.5B(약 4억 9,400만 개)의 140분의 1쯤입니다 |
n_embd 는 number of embedding dimensions(임베딩 좌표 수), n_layer 는 number of layers(층 수), n_head 는 number of heads(헤드 수), n_positions 는 number of positions(자리 수)의 줄임말입니다. p.numel() 은 number of elements 의 줄임말로, 가중치 묶음 하나에 든 숫자 개수를 셉니다.
주의할 점
- 모델의 라이선스와 별개로, 그 모델로 만든 서비스가 다루는 데이터의 개인정보와 저작권도 따로 챙깁니다.
- 모델 카드에 적힌 성능 숫자는 그 회사가 고른 시험의 결과입니다. 우리 데이터로 직접 시험해 봐야 합니다(3장 실습 5의 번역 모델처럼).