15. 모델 로딩
개요
eulerforge.load_model()은 EulerForge로 훈련한 체크포인트를 한 줄로 로드할 수 있는 공용 API입니다. 훈련 전략(plain LoRA, MoE, MixtureLoRA)을 자동 감지하고, 적절한 로딩 방식을 선택합니다.
- 적합한 용도: 훈련 완료 후 추론, 모델 검사, 배치 생성, 양자화 로딩
- 호환 전략: dense_lora, moe_expert_lora, mixture_lora, none (모두 자동 감지)
- 참조 예제:
examples/load_and_chat.py,examples/load_quantized.py
사전 요구 사항
- EulerForge 설치 완료
- 훈련 완료된 체크포인트 (run_dir 또는 checkpoint_dir)
- (선택) int4/int8 양자화:
pip install bitsandbytes
1. 기본 사용법
from eulerforge import load_model
result = load_model("outputs/run_20260311_163425")
# 반환값
result.model # nn.Module (eval 모드)
result.tokenizer # PreTrainedTokenizer
result.metadata # ModelMetadata
load_model()은 경로 유형을 자동 감지합니다:
| 경로 유형 | 판별 기준 | 예시 |
|---|---|---|
run_dir |
resolved_config.json 존재 |
outputs/run_20260311_163425 |
checkpoint_dir |
config.json 존재 |
outputs/run_20260311_163425/final |
2. 체크포인트 선택
run_dir를 지정하면 checkpoint 매개변수로 체크포인트를 선택할 수 있습니다.
# final (기본값)
result = load_model("outputs/run_20260311_163425", checkpoint="final")
# best checkpoint
result = load_model("outputs/run_20260311_163425", checkpoint="best")
# latest checkpoint
result = load_model("outputs/run_20260311_163425", checkpoint="latest")
| checkpoint | 서브디렉토리 |
|---|---|
"final" |
{run_dir}/final/ |
"best" |
{run_dir}/checkpoint-best/ |
"latest" |
{run_dir}/checkpoint-latest/ |
checkpoint_dir를 직접 지정하면 checkpoint 매개변수는 무시됩니다:
result = load_model("outputs/run_20260311_163425/final")
3. 로드 정밀도 (양자화)
load_precision 매개변수로 모델의 로딩 정밀도를 지정할 수 있습니다.
# 4bit 양자화 (NF4 + double quantization)
result = load_model("outputs/run_20260311_163425", load_precision="int4")
# 8bit 양자화
result = load_model("outputs/run_20260311_163425", load_precision="int8")
# bfloat16 (Ampere 이상 GPU)
result = load_model("outputs/run_20260311_163425", load_precision="bf16")
지원 정밀도
| 값 | 설명 | 요구사항 |
|---|---|---|
None |
모델 원본 정밀도 (기본) | — |
"fp32" |
float32 | — |
"fp16" |
float16 | GPU 권장 |
"bf16" |
bfloat16 | Ampere+ GPU |
"int8" |
8bit 양자화 | bitsandbytes |
"int4" |
4bit NF4 양자화 | bitsandbytes |
int4 양자화 설정
int4를 지정하면 다음 BitsAndBytesConfig가 자동 적용됩니다:
BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
)
4. 훈련 전략별 자동 로딩
load_model()은 체크포인트의 훈련 전략을 자동 감지하여 적절한 방식으로 로드합니다.
| 전략 | 로딩 방식 | 결과 모델 |
|---|---|---|
dense_lora |
LoRA 병합 → dense | dense 모델 |
moe_expert_lora |
MoE 구조 재구성 | MoE 모델 (구조 보존) |
mixture_lora |
MixtureLoRA 재구성 | MixtureLoRA 모델 (구조 보존) |
none |
from_pretrained() 직접 로드 |
HF 모델 |
사용자 코드는 전략에 관계없이 동일합니다:
# dense_lora, moe_expert_lora, mixture_lora 모두 동일 코드
result = load_model("outputs/run_20260311_163425")
response = generate(result.model, result.tokenizer, "안녕하세요")
5. 메타데이터 검사
result = load_model("outputs/run_20260311_163425")
m = result.metadata
print(f"전략: {m.strategy}") # "dense_lora"
print(f"백본: {m.backbone}") # "qwen3"
print(f"경로 유형: {m.path_type}") # "run_dir"
print(f"체크포인트: {m.checkpoint_dir}") # 절대경로
print(f"구조 보존: {m.structure_preserved}") # True/False
print(f"로드 정밀도: {m.load_precision}") # "int4" 등 또는 None
if m.lora_config:
print(f"LoRA r: {m.lora_config['lora_r']}")
print(f"LoRA alpha: {m.lora_config['lora_alpha']}")
ModelMetadata 필드
| 필드 | 타입 | 설명 |
|---|---|---|
strategy |
str |
"dense_lora" | "moe_expert_lora" | "mixture_lora" | "none" |
backbone |
str |
"qwen3" | "llama" | "gemma3" | "" |
path_type |
str |
"run_dir" | "checkpoint_dir" |
checkpoint_dir |
str |
실제 체크포인트 디렉토리 절대경로 |
lora_config |
dict \| None |
{"lora_r": int, "lora_alpha": float} |
structure_preserved |
bool |
MoE/MixtureLoRA 구조 보존 여부 |
load_precision |
str \| None |
로드 정밀도 |
6. 추론 예제
6.1 채팅 생성
import torch
from eulerforge import load_model
result = load_model("outputs/run_20260311_163425", load_precision="int4")
messages = [{"role": "user", "content": "한국의 수도는?"}]
if getattr(result.tokenizer, "chat_template", None):
text = result.tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
else:
text = "[USER]\n한국의 수도는?\n\n[ASSISTANT]\n"
inputs = result.tokenizer(text, return_tensors="pt")
inputs = {k: v.to(result.model.device) for k, v in inputs.items()}
with torch.no_grad():
outputs = result.model.generate(
**inputs,
max_new_tokens=256,
do_sample=True,
temperature=0.7,
pad_token_id=result.tokenizer.eos_token_id,
)
input_len = inputs["input_ids"].shape[1]
response = result.tokenizer.decode(
outputs[0][input_len:], skip_special_tokens=True
).strip()
print(response)
6.2 메모리 사용량 비교
from eulerforge import load_model
# 원본 정밀도
r1 = load_model("outputs/run_20260311_163425", load_precision="fp16")
mem1 = sum(p.nelement() * p.element_size() for p in r1.model.parameters())
# 4bit 양자화
r2 = load_model("outputs/run_20260311_163425", load_precision="int4")
mem2 = sum(p.nelement() * p.element_size() for p in r2.model.parameters())
print(f"fp16: {mem1 / 1024**2:.1f} MB")
print(f"int4: {mem2 / 1024**2:.1f} MB")
print(f"절약: {(1 - mem2/mem1) * 100:.0f}%")
7. 예제 스크립트
examples/ 디렉토리에 실행 가능한 예제가 포함되어 있습니다:
| 예제 | 설명 | 명령어 |
|---|---|---|
load_and_chat.py |
기본 채팅 | python examples/load_and_chat.py <path> |
load_quantized.py |
양자화 로딩 | python examples/load_quantized.py <path> --precision int4 |
load_and_inspect.py |
메타데이터 검사 | python examples/load_and_inspect.py <path> |
load_batch_inference.py |
배치 추론 | python examples/load_batch_inference.py <path> |
8. API 레퍼런스
from eulerforge import load_model, LoadedModel, ModelMetadata
result: LoadedModel = load_model(
path, # run_dir 또는 checkpoint_dir 경로
*,
checkpoint="final", # "final" | "best" | "latest"
device="auto", # "auto" | "cpu" | "cuda" | "cuda:0"
dtype="auto", # "auto" | "float32" | "bfloat16"
load_precision=None, # None | "fp32" | "fp16" | "bf16" | "int8" | "int4"
)
에러 처리
모든 에러는 ValueError로 3줄 포맷을 사용합니다:
EulerForge 체크포인트를 식별할 수 없습니다: ...
Fix: 유효한 run_dir 또는 checkpoint_dir 경로를 지정하세요.
See: docs/tutorials/11_bench.md
참조
- Spec:
docs/fixtures/specs/loader_spec.md - CLI:
do../cli.md§Python API - 테스트:
tests/test_loader.py(30 tests)