요즘 OpenModel들이 잘 나오고 있는데, 가정용으로 많이 사용되는 보통 30B 근접한 모델들을 사용하는 것이 효율적으로 좋은 것으로 판단된다. 이때 어떻게 메모리를 효율적으로 사용할 수 있는지를 확인해보고자 한다.
여기에서 사용해볼만한 그래픽 카드는 랩탑 그래픽 카드 기준으로 다음과 같다.
- Geforce RTX 4090 (24GB)
- Geforce RTX 5090 (24GB)
- AMD AI 300시리즈 (온보드 메모리 64GB 이상인 모델부터 32GB 이상 iGPU 사용이 가능)
- 온보드 메모리 64GB(32GB)
- 온보드 메모리 128GB(92GB)
가장 먼저 28B 모델이라고 가정하고 GPU 메모리 요구량을 개산해 보았다.
28B 모델 GPU 메모리 요구사항 계산
추론 모드 (Inference)
정밀도모델 메모리 KV Cache활성화에 필요한 총 메모리 (오버헤드 포함)와 권장 GPU이다. 최소한 14GB에서 19GB가 필요한 것을 알 수 있다.
| FP16 | 56 GB | ~2 GB | ~4 GB | ~75 GB | A100 80GB, H100 |
| INT8 | 28 GB | ~1 GB | ~2 GB | ~37 GB | A100 40GB, A6000 |
| INT4 | 14 GB | ~0.5 GB | ~1 GB | ~19 GB | RTX 4090, A5000 |
학습 모드 (Training)
설정 총 메모리와 필요량 권장 GPU 구성으로 학습에는 많은 GPU가 필요하고, INT4로 양자화를 하더라도 24GB는 필요하므로 INT2, INT1등도 고려해야겠지만, 성능과 효율을 고려해야 할 것이다.
| FP16 + Adam | ~224 GB | 4x A100 80GB (Multi-GPU) |
| FP16 + LoRA | ~85 GB | 2x A100 80GB |
28B 모델 실행을 위한 최소 요구사항:
- FP16 추론: 80GB GPU (A100 80GB 또는 H100)
- INT8 추론: 40GB GPU (A100 40GB, A6000)
- INT4 추론: 24GB GPU (RTX 4090, A5000) ✅ 가장 현실적
- 학습: 멀티 GPU 필수 (4x A100 80GB 권장)
1. 양자화 (Quantization)
가장 효과적인 메모리 절감 방법으로 일반적으로 가장 많이 사용된다.
INT8 양자화 (bitsandbytes)
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# INT8 로딩 - 메모리 50% 절감
model = AutoModelForCausalLM.from_pretrained(
"model-name-28b",
load_in_8bit=True,
device_map="auto", # 자동 GPU 분산
torch_dtype=torch.float16
)
# 메모리 절감: 56GB → 28GB
# 성능 손실: < 2%
INT4/NF4 양자화 (QLoRA)
from transformers import BitsAndBytesConfig
# 4비트 양자화 설정
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # NormalFloat 4-bit
bnb_4bit_use_double_quant=True, # 추가 압축
bnb_4bit_compute_dtype=torch.bfloat16
)
model = AutoModelForCausalLM.from_pretrained(
"model-name-28b",
quantization_config=bnb_config,
device_map="auto"
)
# 메모리 절감: 56GB → 14GB (75% 절감!)
# 성능 손실: < 5%
GPTQ/AWQ 양자화
# GPTQ - 사전 양자화된 모델 로드
from auto_gptq import AutoGPTQForCausalLM
model = AutoGPTQForCausalLM.from_quantized(
"model-name-28b-gptq",
use_safetensors=True,
device_map="auto"
)
# AWQ - 더 빠른 추론 속도
from awq import AutoAWQForCausalLM
model = AutoAWQForCausalLM.from_quantized(
"model-name-28b-awq",
fuse_layers=True
)
2. FlashAttention 2.0
Attention 메커니즘의 메모리 효율을 개선할 수 있는데, 바로 한번에 처리하지 않고 나누어서 GPU메모리에 올려서 처리하는 방식으로 변경하여 개선할 수 있다.
# FlashAttention 활성화
model = AutoModelForCausalLM.from_pretrained(
"model-name-28b",
torch_dtype=torch.float16,
attn_implementation="flash_attention_2", # 핵심!
device_map="auto"
)
# 효과:
# - 메모리: 30-50% 절감
# - 속도: 2-4배 향상
# - 긴 시퀀스(4k, 8k+)에서 특히 효과적
설치:
pip install flash-attn --no-build-isolation
3. Gradient Checkpointing (학습 시)
Gradient Checkpointing은 순전파 때 모든 중간 activation을 다 저장하지 않고, 일부 지점만 “체크포인트”로 저장해 두었다가, 역전파 때 필요한 구간의 순전파를 다시 계산(recompute)함으로써 메모리를 줄이는 기법이다.
# 학습 시 메모리 절감
model.gradient_checkpointing_enable()
# Trainer에서 사용
from transformers import TrainingArguments
training_args = TrainingArguments(
gradient_checkpointing=True,
gradient_checkpointing_kwargs={"use_reentrant": False}, # 더 안정적
# ...
)
# 효과:
# - Activation 메모리: 70-80% 절감
# - 속도: 20-30% 느려짐
# - 트레이드오프 가치 있음
4. KV Cache 최적화
KV Cache는 디코딩 동안 각 레이어의 Key/Value 벡터를 계속 쌓아 두고, 새 토큰의 Query가 이전 K/V와만 어텐션 하도록 해서 이전 토큰의 연산을 다시 하지 않게 하는 구조다.
# 1. Past Key Values 재사용
outputs = model.generate(
input_ids,
max_new_tokens=100,
use_cache=True, # KV cache 사용
return_dict_in_generate=True
)
# 2. PagedAttention (vLLM)
from vllm import LLM, SamplingParams
llm = LLM(
model="model-name-28b",
tensor_parallel_size=2, # 2개 GPU
gpu_memory_utilization=0.95, # GPU 메모리 95% 사용
)
# PagedAttention으로 KV cache를 블록 단위로 관리
# - 메모리 파편화 방지
# - 배치 처리 효율 증가
7. LoRA/QLoRA (Fine-tuning 시)
LoRA/QLoRA는 “적은 파라미터만 학습해서, 훨씬 적은 메모리로 거대 LLM을 미세조정(finetune)하는 기법”이다.
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
# 4비트 모델 로드
model = AutoModelForCausalLM.from_pretrained(
"model-name-28b",
load_in_4bit=True,
quantization_config=bnb_config
)
# LoRA 준비
model = prepare_model_for_kbit_training(model)
# LoRA 설정
lora_config = LoraConfig(
r=16, # LoRA rank (낮을수록 메모리 적음)
lora_alpha=32,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
# 효과:
# - 학습 가능 파라미터: 0.1-1% (28B → 28M~280M)
# - 메모리: Full fine-tuning 대비 70-80% 절감
# - 성능: Full fine-tuning과 비슷
메모리 최적화 조합 추천
# 🏆 최적의 조합 (28B 추론)
"""
1. INT4 양자화 (14GB)
2. FlashAttention (추가 30% 절감 → 10GB)
3. KV Cache 최적화 (2GB 절감 → 8GB)
→ RTX 4090 24GB에서 배치 2 가능!
"""
# 🏆 최적의 조합 (28B 학습)
"""
1. INT4 + QLoRA (15GB)
2. Gradient Checkpointing (추가 50% 절감)
3. DeepSpeed ZeRO-3 + CPU Offload
4. Gradient Accumulation (배치 크기 유지)
→ A100 40GB 1장으로 학습 가능!
"""
실전 예제: 28B 모델을 24GB GPU에서 실행한다면
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch
# 설정
model_name = "your-28b-model"
# 4비트 양자화 + FlashAttention
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=torch.bfloat16
)
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=bnb_config,
device_map="auto",
attn_implementation="flash_attention_2",
torch_dtype=torch.bfloat16,
low_cpu_mem_usage=True,
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
# 추론
input_text = "Your prompt here"
inputs = tokenizer(input_text, return_tensors="pt").to("cuda")
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=512,
use_cache=True,
do_sample=True,
temperature=0.7
)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
# 메모리 확인
print(f"\nGPU Memory: {torch.cuda.memory_allocated(0) / 1024**3:.2f}GB")
이 최적화 기법들을 조합하면 28B 모델을 소비자용 GPU(RTX 4090 24GB)에서도 실행할 수 있다.
'Bigdata' 카테고리의 다른 글
| AMD AI 9 관련 (370 등) CPU ROCm 지원, 설치 방법 (0) | 2025.12.19 |
|---|---|
| Windows 11 - AMD Ryzen AI 시리즈를 위한 최신 HIP SDK로 Ollama 설치 방법 (0) | 2025.12.19 |
| Gemma 토크나이저 특징 - 한국어 처리 효율 (0) | 2025.10.21 |
| Google Embedding Gemma: 최고의 임베딩 모델 (0) | 2025.09.10 |
| 'GPT-5'를 코딩에 효과적으로 활용하기 위한 6가지 프롬프트 입력법을 공개 (1) | 2025.08.25 |