가장 빠른 첫 실행: 노트북과 로컬에서 Gemma 불러오기
이번 장의 목표
이번 장의 목표는 단순합니다. Gemma 모델을 한 번 내려받고, 짧은 프롬프트를 넣어 응답을 받아보는 것입니다. 아직 RAG, 파인튜닝, 최적화는 생각하지 않아도 됩니다. 먼저 모델이 실제로 내 코드에서 움직이는 경험을 만드는 것이 중요합니다.
LLM 개발은 추상적인 개념이 많습니다. 토크나이저, chat template, GPU 메모리, 모델 캐시 같은 말도 처음에는 멀게 느껴집니다. 하지만 한 번 실행해 보면 이후 장에서 다룰 프롬프트 개선, 배포, 평가가 훨씬 쉽게 연결됩니다.
이 장에서는 첫 실행 모델로 google/gemma-3-1b-it를 사용합니다. 1B 규모의 소형 instruction-tuned 모델이라 실습에 부담이 적고, 대화형 지시에 맞게 조정되어 있습니다. Gemma 3 모델은 transformers 4.50.0 이상에서 지원되며, instruction-tuned 모델은 tokenizer.apply_chat_template(...)를 적용한 뒤 생성하는 흐름을 따르는 것이 기본입니다.1
AI 생성 이미지
Colab 또는 Kaggle에서 시작하기
처음 실행은 로컬보다 Colab이나 Kaggle Notebook이 쉽습니다. GPU 런타임을 선택할 수 있고, 패키지를 새로 설치해도 기존 개발 환경을 망가뜨리지 않습니다.
먼저 노트북에서 GPU를 켭니다.
Colab:
런타임→런타임 유형 변경→ 하드웨어 가속기GPUKaggle: Notebook 우측 설정 → Accelerator
GPU
그다음 Hugging Face에서 모델 접근 권한을 준비합니다. Gemma 모델 페이지에서 사용 조건에 동의하고, Hugging Face 계정의 Access Token을 생성합니다. 토큰 권한은 보통 read면 충분합니다.
토큰은 코드에 직접 쓰지 않는 편이 좋습니다. 노트북을 공유하거나 GitHub에 올릴 때 토큰이 노출될 수 있기 때문입니다. Colab에서는 Secrets 기능에 HF_TOKEN이라는 이름으로 저장하고, Kaggle에서는 Add-ons의 Secrets에 같은 이름으로 저장합니다.
Colab이라면 다음처럼 가져올 수 있습니다.
import os
from google.colab import userdata
os.environ['HF_TOKEN'] = userdata.get('HF_TOKEN')Kaggle이라면 다음 방식을 사용합니다.
import os
from kaggle_secrets import UserSecretsClient
user_secrets = UserSecretsClient()
os.environ['HF_TOKEN'] = user_secrets.get_secret('HF_TOKEN')토큰을 준비했다면 패키지를 설치합니다. Gemma 3를 쓰려면 transformers 버전을 먼저 맞추는 것이 중요합니다.
pip install -U 'transformers>=4.50.0' accelerate huggingface_hub torch설치 후에도 이상한 로딩 오류가 계속된다면 노트북 런타임을 재시작하세요. Python 프로세스가 이전 버전의 라이브러리를 이미 불러온 상태일 수 있습니다.
최소 코드로 Gemma 불러오기
이제 모델을 불러와 간단한 답변을 생성해 보겠습니다. 아래 코드는 첫 실행을 위한 최소 구조입니다.
import os
import torch
from huggingface_hub import login
from transformers import AutoTokenizer, Gemma3ForCausalLM
model_id = 'google/gemma-3-1b-it'
hf_token = os.environ.get('HF_TOKEN')
if hf_token:
login(token=hf_token)
dtype = torch.bfloat16 if torch.cuda.is_available() else torch.float32
tokenizer = AutoTokenizer.from_pretrained(
model_id,
token=hf_token,
)
model = Gemma3ForCausalLM.from_pretrained(
model_id,
token=hf_token,
device_map='auto',
torch_dtype=dtype,
).eval()
messages = [
{
'role': 'system',
'content': [
{'type': 'text', 'text': '너는 친절하고 간결한 한국어 개발 도우미다.'}
],
},
{
'role': 'user',
'content': [
{'type': 'text', 'text': 'Gemma를 처음 실행한 개발자에게 다음 단계 3가지를 알려줘.'}
],
},
]
inputs = tokenizer.apply_chat_template(
messages,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors='pt',
).to(model.device)
with torch.inference_mode():
output_ids = model.generate(
**inputs,
max_new_tokens=128,
do_sample=False,
)
new_tokens = output_ids[:, inputs['input_ids'].shape[-1]:]
answer = tokenizer.batch_decode(new_tokens, skip_special_tokens=True)[0]
print(answer)여기서 핵심은 세 가지입니다.
첫째, AutoTokenizer는 텍스트를 모델이 이해하는 토큰 ID로 바꿉니다. LLM은 문장을 그대로 읽지 않고, 작은 토큰 단위의 숫자열을 입력으로 받습니다.
둘째, Gemma3ForCausalLM은 Gemma 3 텍스트 생성 모델을 불러오는 클래스입니다. CausalLM은 이전 토큰을 바탕으로 다음 토큰을 생성하는 언어 모델이라는 뜻입니다.
셋째, instruction-tuned 모델에는 apply_chat_template()을 적용합니다. 대화형 모델은 사용자 말과 모델 답변의 경계를 정해진 형식으로 구분합니다. 이 과정을 생략하고 단순 문자열만 넣으면 모델이 지시를 덜 안정적으로 이해할 수 있습니다.
do_sample=False는 같은 입력에 대해 비교적 일관된 답변을 얻기 위한 설정입니다. 첫 실습에서는 창의적인 답변보다 재현 가능한 실행이 더 중요합니다. 나중에 아이디어 생성이나 다양한 문체가 필요할 때 temperature, top_p 같은 생성 옵션을 조정하면 됩니다.
8비트 로딩은 필요할 때만 사용하기
GPU 메모리가 부족하다면 8비트 로딩을 시도할 수 있습니다. 8비트 로딩은 모델 가중치를 더 작은 숫자 형식으로 불러와 메모리 사용량을 줄이는 방법입니다. 다만 첫 실행에서는 변수를 줄이는 것이 좋으므로, 기본 코드가 실패할 때만 적용하는 편이 안전합니다.
필요하다면 bitsandbytes를 설치합니다.
pip install -U bitsandbytes그다음 모델 로딩 부분을 다음처럼 바꿀 수 있습니다.
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = Gemma3ForCausalLM.from_pretrained(
model_id,
token=hf_token,
device_map='auto',
quantization_config=quantization_config,
).eval()8비트 로딩은 메모리를 줄이는 데 도움이 되지만, 모든 환경에서 똑같이 잘 동작하지는 않습니다. 특히 CUDA, bitsandbytes, PyTorch 버전이 맞지 않으면 별도의 오류가 날 수 있습니다. 따라서 첫 번째 선택지는 작은 모델을 쓰는 것이고, 두 번째 선택지가 양자화입니다.
로컬에서 실행할 때 확인할 것
로컬 실행은 노트북보다 자유롭지만, 관리할 것도 늘어납니다. 먼저 가상환경을 만들고 패키지를 설치하세요.
python -m venv .venv
source .venv/bin/activate
pip install -U 'transformers>=4.50.0' accelerate huggingface_hub torchWindows PowerShell에서는 활성화 명령이 다릅니다.
.venvScriptsActivate.ps1Hugging Face 토큰은 환경 변수로 넣습니다.
export HF_TOKEN=hf_xxxxxxxxxxxxxxxxxWindows PowerShell에서는 다음처럼 설정합니다.
$env:HF_TOKEN='hf_xxxxxxxxxxxxxxxxx'로컬에서 가장 자주 놓치는 부분은 모델 파일 저장 위치입니다. Hugging Face 모델은 기본적으로 사용자 홈 디렉터리 아래 캐시에 저장됩니다.
du -sh ~/.cache/huggingface디스크가 작은 노트북이나 서버에서는 캐시 위치를 바꾸는 것이 좋습니다. 모델을 내려받기 전에 HF_HOME을 지정하세요.
export HF_HOME=/data/huggingface-cachePython 코드 안에서 지정할 수도 있지만, 반드시 from_pretrained()를 호출하기 전에 설정해야 합니다.
import os
os.environ['HF_HOME'] = '/data/huggingface-cache'다운로드가 중간에 끊기면 다음 실행 때 이어받기를 시도합니다. 그래도 계속 실패한다면 캐시에 손상된 파일이 남았을 수 있습니다. 이때는 캐시 목록을 확인하고 불필요한 항목을 지웁니다.
huggingface-cli scan-cache
huggingface-cli delete-cache무작정 전체 캐시를 삭제하기보다, 어떤 모델이 공간을 차지하는지 먼저 확인하는 습관을 들이세요. 여러 모델을 실험하다 보면 캐시가 빠르게 커집니다.
첫 실행 오류를 구분하는 법
첫 실행 오류는 대체로 몇 가지 유형으로 나뉩니다. 오류 메시지를 끝까지 읽고 원인을 구분하면 해결이 훨씬 빨라집니다.
접근 권한 오류
401, 403, Repository not found, gated repo 같은 메시지가 보이면 모델 접근 권한 문제일 가능성이 큽니다.
확인할 것은 세 가지입니다.
Hugging Face에서 Gemma 모델 사용 조건에 동의했는가
토큰에
read권한이 있는가코드에서
HF_TOKEN이 실제로 읽히는가
간단히 확인하려면 다음을 실행합니다.
import os
print(os.environ.get('HF_TOKEN') is not None)False가 나오면 토큰이 설정되지 않은 것입니다. 단, 토큰 전체 값을 출력하지는 마세요.
패키지 버전 오류
Gemma3ForCausalLM을 찾을 수 없거나 모델 구조를 알 수 없다는 오류가 나오면 transformers 버전을 먼저 확인합니다.
import transformers
print(transformers.__version__)버전이 낮다면 다시 업그레이드합니다.
pip install -U 'transformers>=4.50.0'업그레이드 후에는 런타임이나 Python 프로세스를 재시작하세요. 설치만 하고 재시작하지 않으면 이전 버전이 계속 사용될 수 있습니다.
GPU 메모리 부족
CUDA out of memory가 보이면 GPU 메모리가 부족한 것입니다. 해결 방향은 단순합니다.
더 작은 모델을 선택한다.
max_new_tokens를 줄인다.노트북 런타임을 재시작해 GPU 메모리를 비운다.
필요하면 8비트 로딩을 사용한다.
처음부터 큰 모델을 고집할 필요는 없습니다. 지금 목표는 품질 비교가 아니라 실행 성공입니다.
CPU에서 너무 느린 경우
CPU에서도 실행은 가능할 수 있지만, 응답 생성이 매우 느릴 수 있습니다. 이것은 오류가 아니라 성능 한계입니다. 실습 중이라면 GPU 런타임을 사용하는 편이 좋습니다. 로컬 CPU만 있는 환경에서는 짧은 프롬프트와 작은 max_new_tokens로 확인만 하고, 본격적인 실험은 GPU 환경에서 진행하세요.
CUDA와 라이브러리 충돌
PyTorch, CUDA, 드라이버, bitsandbytes가 서로 맞지 않으면 모델 로딩 전에 오류가 날 수 있습니다. 이 경우 한 번에 여러 패키지를 바꾸지 말고 순서대로 확인합니다.
8비트 로딩을 끄고 기본 로딩이 되는지 본다.
PyTorch가 GPU를 인식하는지 확인한다.
노트북이라면 런타임을 재시작한다.
로컬이라면 CUDA 버전에 맞는 PyTorch 설치 명령을 다시 확인한다.
GPU 인식 여부는 다음 코드로 확인할 수 있습니다.
import torch
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'CPU only')첫 실행에서 얻어야 할 것
이번 장에서 얻어야 할 결과는 멋진 챗봇이 아닙니다. 다음 세 가지를 확인하면 충분합니다.
모델과 토크나이저를 정상적으로 내려받았다.
chat template을 적용해 프롬프트를 넣었다.
generate()로 새 토큰을 생성하고 텍스트로 디코딩했다.
이 흐름이 Gemma 애플리케이션의 가장 작은 단위입니다. 이후에는 이 작은 단위를 더 잘 쓰는 방향으로 확장합니다. 프롬프트를 정교하게 만들고, 문서를 검색해 컨텍스트로 넣고, 필요하면 LoRA로 조정하고, 추론 서버에 올려 여러 사용자가 호출하게 만듭니다.
복잡한 시스템도 시작점은 같습니다. 입력을 토큰으로 바꾸고, 모델이 다음 토큰을 생성하고, 다시 사람이 읽는 텍스트로 바꾸는 과정입니다. 이 과정을 직접 실행해 봤다면 Gemma 개발의 첫 관문은 넘은 것입니다.
참고
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.