문제 해결: 증상 → 원인 → 해결
로컬 추론은 패턴으로 실패합니다. 같은 열두 가지 증상이 거의 모든 도움 요청을 차지하고, 각각은 지루한 원인과 2분짜리 해결책이 있습니다. 표를 훑고, 해결책을 적용하고, 그런 다음 숫자를 읽어 실제로 고쳐졌는지 확인하세요.
진단표
| 증상 | 추정 원인 | 해결 |
|---|---|---|
출력에 역할 토큰 포함 (user:, `< |
im_start | >`) |
| 즉시 빈 응답 | 템플릿이 "끝난" 챗으로 렌더링되거나 EOS 토큰이 틀림 | 템플릿 수정; EOS 확인: 프롬프팅 |
| 답 대신 질문을 반복 | 인스트럭트 모델이 아니라 베이스 모델 | 인스트럭트/챗 GGUF 사용 |
| 로드 중 메모리 부족 | 가중치 + quant가 VRAM 초과 | 더 작은 quant 또는 더 작은 모델: VRAM 계산 |
| 생성 중 메모리 부족 | KV 캐시가 여유를 넘어 성장 | 더 짧은 컨텍스트, KV 캐시 q8_0: KV 캐시 |
| GPU가 있는데 1–3 tok/s | 레이어가 여전히 CPU에 | 풀 오프로드 (n_gpu_layers): 엔진 파라미터 |
| 첫 토큰 느리고 이후 스트림 빠름 | 프리필 병목: 매우 긴 프롬프트 | 프롬프트 축소, 배칭, 더 빠른 프리필: 속도 |
| 끝없는 반복, 구절 루프 | 샘플러가 너무 관대, 페널티 꺼짐 | temp ≤ 0.8, repeat_penalty 1.05–1.1: 샘플링 |
| 한국어 출력이 이상하거나 어색함 | 모델의 한국어가 약함 | 다국어 패밀리 (Qwen, Gemma): 모델 패밀리 |
| 문장 중간에 출력 잘림 | 컨텍스트 창 가득 또는 max_tokens가 너무 낮음 | 컨텍스트 다듬기 또는 출력 상한 인상 |
| 좋은 모델에서 유효하지 않은 JSON | 자유형 샘플링 | 제약 디코딩: 구조화 출력 |
| 모델이 지시를 무시 | 긴 프롬프트에서 한가운데 묻힘 | 목표 먼저, 페이로드 마지막, 요청 반복: 프롬프팅 |
| 로드 시 크래시 또는 코어덤프 | 손상된 다운로드 | 체크섬 확인, 재다운로드 |
원인이 아니라 증상 우선으로 읽으세요. 보이는 것을 찾고, 해결책을 적용하고, 다시 측정하세요. "내 모델이 망가졌다"는 신고의 대부분은 1, 2, 6행에서 끝납니다.
5분 사전 점검
깊은 디버깅 전에 사실을 모으세요:
nvidia-smi --query-gpu=name,memory.total,memory.used --format=csv # GPU + VRAM
ls -lh model.gguf # 크기 vs VRAM
llama-server --version # 엔진 빌드
모델 파일이 가용 VRAM보다 크면 4행이 답이고 어떤 플래그도 구해주지 못합니다. 생성 중 memory.used가 꾸준히 오르면 그것은 누수가 아니라 KV 캐시입니다.
정상의 생김새
성능을 디버깅하기 전에 자릿수를 알아두세요. 7–8B Q4_K_M 모델의 디코드 속도, 배치 1:
| 하드웨어 | 디코드 tok/s |
|---|---|
| 중급 GPU (RTX 3060/4060급) | 30–60 |
| 고급 GPU (RTX 3090/4090급) | 100–150 |
| Apple M 시리즈 (통합 메모리) | 20–40 |
| CPU 온리 (현대 8코어) | 3–8 |
두 공식이 대부분을 설명합니다:
decode tok/s ≈ memory bandwidth (GB/s) ÷ model size (GB)
VRAM needed ≈ weights + KV cache + 1–2 GB overhead
288 GB/s 카드의 4.5 GB 7B quant는 이론상 64 tok/s 근처가 상한. 실제 ~45–55를 기대하세요. 표의 2배 안이면 당신 하드웨어에 문제가 있는 것이 아닙니다.
첫-토큰-까지-시간(TTFT)은 짧은 프롬프트에서 충분히 1초 미만이어야 합니다. 프롬프트 길이를 프리필 처리량(디코드 속도의 10–100배)으로 나눈 만큼 자랍니다. 10k 토큰 프롬프트가 첫 토큰까지 20 s를 쓰면 망가진 것이 아니라 프리필 병목입니다.
VRAM 회계: 가중치가 잘 로드됐는데 나중에 OOM이면 quant가 아니라 KV 캐시 또는 컨텍스트 길입니다 — KV 캐시.
워크플로: 변수 하나만 교체하세요
두 가지를 동시에 바꾸면 버그는 숨습니다. 이 사슬을 따라 고립시키세요 — 모델 → 엔진 → 설정 → 프롬프트:
- 베이스라인. 알려진-양호 모델, 알려진-양호 엔진, 기본 플래그. 챗이 되는가? 그러면 스택은 멀쩡합니다.
- 모델 교체 (같은 엔진, 같은 플래그). 깨지는가? 파일 또는 그 템플릿입니다.
- 엔진 교체 (같은 모델). 깨지는가? 엔진 버그 또는 플래그 번역.
- 플래그 이분탐색. 기본값으로 되돌리고, 깨질 때까지 하나씩 다시 더하세요.
- 렌더링된 프롬프트 덤프. 출력이 이상한데-도는-중일 때, 렌더링된 템플릿에 진실이 삽니다.
가면서 기록하세요 — "temp 0.8에서 작동, min_p 0.2에서 파괴"는 진단이고, "이것저것 해봤는데 여전히 나쁨"은 아닙니다.
도움을 잘 요청하는 법
좋은 도움 요청 글은 실험 보고서입니다. 포함하세요:
- 모델 파일: 정확한 이름, quant, 출처 (
qwen2.5-7b-instruct-q4_k_m.gguf, 어느 저장소). - 엔진과 버전: llama.cpp 빌드 날짜, Ollama 버전, vLLM 릴리스 — 엔진은 매주 바뀝니다.
- 정확한 플래그 또는 API 호출: 요약이 아니라 명령줄이나 요청 본문 전체.
- 하드웨어: GPU + VRAM (또는 맥 + RAM), 레이어를 떠안고 있다면 CPU도.
- 관찰된 숫자: tok/s, TTFT, 사용 VRAM, 있다면 정확한 에러 문구.
- 이미 시도한 것과 그 결과로 무엇이 바뀌었는지.
복사-붙여넣기 스켈레톤:
Model: qwen2.5-7b-instruct-q4_k_m.gguf (bartowski repo)
Engine: llama.cpp b4321 (llama-server)
Flags: -ngl 99 -c 8192 --temp 0.7
Hardware: RTX 4060 8GB / Ryzen 7 / 32GB RAM
Observed: loads in 21s, ~35 tok/s, TTFT ~1.2s, then OOM at ~6k ctx
Tried: -c 4096 → no crash; q8_0 KV → no crash
이 여섯 사실이 있으면 대부분의 문제는 답글 한 번만에 위 표의 한 행으로 매핑됩니다. 이 포럼은 정확히 이런 글을 위해 존재합니다 — 실험 보고서를 가져오세요, 해결책을 받으리라.