Recent Posts
Recent Comments
반응형
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

오늘도 공부

LLM 추론 엔지니어링 튜토리얼 본문

AI/추천 오픈소스

LLM 추론 엔지니어링 튜토리얼

행복한 수지아빠 2026. 7. 29. 14:35
반응형

LLM 추론 엔지니어링 튜토리얼

이미 만들어진 AI 모델을 GPU 서버에 올리고, 수많은 사용자에게 빠르고 안정적으로 제공하면서 비용까지 최적화하는 기술을 배우는 것입니다.


과정을 마치면 다음 결과물을 갖게 된다.

  • vLLM과 SGLang으로 구축한 OpenAI 호환 추론 서버
  • 처리량 중심, 지연시간 중심, 긴 문맥 중심의 서빙 파이프라인 3종
  • 비용·지연시간·품질을 함께 고려하는 모델 라우터
  • 사용자별 토큰 예산 및 요청 제어 API
  • Prometheus·Grafana 기반 운영 대시보드
  • Kubernetes 자동 확장 환경
  • 1,000개 이상의 동시 요청을 재현하는 부하 시험
  • 재현 가능한 공개 벤치마크 보고서
  • 요청당 원가와 손익분기점을 계산하는 비용 모델

대상 독자

  • Python과 REST API의 기본 개념을 아는 개발자
  • 로컬 LLM 실행에서 실제 서비스 운영으로 넘어가려는 사람
  • 모델 연구보다 서빙·성능·비용 최적화에 관심이 있는 사람

권장 학습 기간

주 5일, 하루 1.5

2시간을 기준으로 12주를 권장한다. GPU가 한 대여도 1

8주차 대부분을 학습할 수 있다. 1,000 동시 요청과 Kubernetes 다중 GPU 실습은 클라우드 GPU를 짧게 빌려 수행해도 된다.


전체 학습 지도

단계 기간 핵심 주제 대표 결과물
0 2일 환경과 측정 기준 기준 성능표
1 1주 Ollama·LM Studio·LiteLLM 로컬 API 게이트웨이
2 2주 vLLM·SGLang 서빙 파이프라인 2종
3 1주 Paged Attention·KV 캐시 긴 문맥 서버
4 1주 양자화 정밀도별 비교표
5 1주 추측 디코딩 draft/target 비교 실험
6 1주 라우터·토큰 예산 정책 기반 라우터
7 1주 관측 가능성 Grafana 대시보드
8 1주 부하 시험 1,000 동시 요청 보고서
9 1주 Kubernetes·HPA 자동 확장 배포
10 1주 ONNX·TensorRT·WebLLM 엣지 데모
11 1주 비용 경제성·공개 벤치마크 최종 포트폴리오

0. 준비와 기준선

0.1 권장 환경

로컬 학습용

  • Ubuntu 22.04/24.04 또는 WSL2
  • Python 3.11 또는 프로젝트가 지원하는 버전
  • Docker와 Docker Compose
  • RAM 64GB 권장, 최소 32GB
  • SSD 여유 공간 200GB 이상 권장
  • NVIDIA GPU 24GB 이상 권장

AMD 32GB GPU도 개념 학습, Ollama, llama.cpp 계열, 일부 SGLang·ROCm 실험에 사용할 수 있다. 다만 CUDA 전용 커널, TensorRT-LLM, FP8 및 일부 양자화 경로는 동일하게 재현되지 않을 수 있다. 따라서 이 과정에서는 AMD로 가능한 실습CUDA 환경에서 별도로 확인할 실습을 구분한다.

클라우드 실습용

  • 단일 GPU: L4, L40S, A100, H100급 중 예산에 맞는 인스턴스
  • 다중 GPU: 마지막 2주에만 시간 단위로 대여
  • Kubernetes: 로컬 kind/k3d로 구조를 익힌 뒤 GPU 노드에서 검증

0.2 저장소 구조

llm-inference-lab/
├── README.md
├── models/
├── configs/
├── servers/
│   ├── vllm/
│   ├── sglang/
│   └── router/
├── loadtest/
├── observability/
│   ├── prometheus/
│   └── grafana/
├── kubernetes/
├── edge/
├── results/
└── reports/

0.3 가장 먼저 정의할 지표

지표 의미 주의점
TTFT 요청부터 첫 토큰까지 걸린 시간 대화형 UX에 중요
ITL 토큰 사이의 평균 지연시간 스트리밍 체감 속도
TPOT 출력 토큰 1개당 처리시간 ITL과 정의를 통일
E2E latency 요청 전체 완료 시간 입력·출력 길이를 함께 기록
Throughput 초당 처리한 요청 또는 토큰 요청/초와 토큰/초를 구분
Goodput SLO를 만족한 유효 처리량 단순 처리량보다 운영에 유용
Queue time 대기열에서 기다린 시간 GPU 계산 시간과 분리
Cache hit rate 재사용된 prefix/KV 비율 동일 프롬프트 비율과 함께 기록
Error rate 전체 요청 중 실패 비율 타임아웃과 서버 오류를 구분
Cost/request 요청 한 건의 추론 원가 GPU 유휴시간도 포함

0.4 기준선 실험

동일한 모델, 동일한 데이터셋, 동일한 입력·출력 길이로 아래 표를 채운다.

| 엔진 | 모델 | 정밀도 | 동시성 | 입력/출력 토큰 | TTFT p50/p95 | ITL p50/p95 | tok/s | GPU 메모리 |
|---|---|---|---:|---:|---:|---:|---:|---:|

완료 조건

  • 측정 스크립트를 두 번 실행해 결과 편차를 확인했다.
  • 모델명, revision, 엔진 버전, GPU, 드라이버를 기록했다.
  • 워밍업 요청을 측정값에서 분리했다.

1. 로컬 도구로 추론 흐름 익히기

1.1 Ollama

학습 목표는 모델 다운로드, 메모리 적재, 프롬프트 요청, 스트리밍 응답의 흐름을 이해하는 것이다.

ollama pull qwen3:4b
ollama run qwen3:4b

API 확인:

curl http://localhost:11434/api/generate \
  -d '{"model":"qwen3:4b","prompt":"KV cache를 한 문장으로 설명해 줘.","stream":false}'

확인할 항목:

  • 첫 요청과 두 번째 요청의 시간 차이
  • 모델이 메모리에 남아 있을 때의 변화
  • 입력 길이가 늘어날 때 TTFT 변화

1.2 LM Studio

GUI에서 모델별 메모리 사용량과 오프로딩 설정을 비교한다. 로컬 서버 기능을 켠 뒤 OpenAI 호환 클라이언트로 호출한다.

from openai import OpenAI

client = OpenAI(base_url="http://localhost:1234/v1", api_key="local")
response = client.chat.completions.create(
    model="local-model",
    messages=[{"role": "user", "content": "continuous batching을 설명해 줘."}],
)
print(response.choices[0].message.content)

1.3 LiteLLM

LiteLLM은 여러 모델 제공자 또는 로컬 서버를 하나의 API 형태로 연결하는 게이트웨이 실습에 사용한다.

# configs/litellm.yaml
model_list:
  - model_name: local-fast
    litellm_params:
      model: openai/local-model
      api_base: http://localhost:1234/v1
      api_key: local
litellm --config configs/litellm.yaml

미니 프로젝트

Ollama와 LM Studio 중 사용 가능한 서버를 선택하고, 실패하면 다른 서버로 전환하는 작은 게이트웨이를 만든다.

완료 조건

  • /v1/chat/completions로 두 개 이상의 백엔드에 요청했다.
  • 모델 로딩 시간과 순수 생성 시간을 분리했다.
  • 타임아웃과 연결 실패를 로그에서 구분했다.

2. vLLM과 SGLang

아래 명령의 옵션은 릴리스에 따라 달라질 수 있다. 실습 전에 각 프로젝트의 공식 최신 CLI 문서를 확인한다.

2.1 vLLM 서버

별도의 가상환경에서 설치한다.

python -m venv .venv-vllm
source .venv-vllm/bin/activate
python -m pip install --upgrade pip
pip install vllm

서버 시작:

vllm serve Qwen/Qwen3-4B-Instruct-2507 \
  --host 0.0.0.0 \
  --port 8000 \
  --dtype auto \
  --api-key local-token

요청:

curl http://localhost:8000/v1/chat/completions \
  -H "Authorization: Bearer local-token" \
  -H "Content-Type: application/json" \
  -d '{
    "model":"Qwen/Qwen3-4B-Instruct-2507",
    "messages":[{"role":"user","content":"Paged Attention이 필요한 이유는?"}],
    "max_tokens":128
  }'

검증:

curl http://localhost:8000/health
curl http://localhost:8000/metrics

2.2 SGLang 서버

python -m venv .venv-sglang
source .venv-sglang/bin/activate
python -m pip install --upgrade pip
pip install "sglang[all]"
python -m sglang.launch_server \
  --model-path Qwen/Qwen3-4B-Instruct-2507 \
  --host 0.0.0.0 \
  --port 30000

같은 프롬프트 묶음을 vLLM과 SGLang에 보내 다음을 비교한다.

  • 단일 요청 TTFT
  • 동시성 1, 8, 32, 128의 처리량
  • 반복 prefix가 있을 때의 처리량
  • 긴 입력과 짧은 출력
  • 짧은 입력과 긴 출력

2.3 파이프라인 3종

A. 처리량 우선

  • 연속 배칭 활성화
  • GPU 메모리 사용률을 점진적으로 높여 탐색
  • 동시 요청 수를 늘리며 최대 goodput 측정
  • p95 지연시간 SLO를 넘으면 직전 설정으로 복귀

B. 대화형 지연시간 우선

  • 요청당 출력 상한 설정
  • 대형 배치보다 짧은 대기열 선호
  • 스트리밍 사용
  • TTFT p95를 핵심 SLO로 설정

C. 긴 문맥 우선

  • prefix caching 또는 Radix Cache 활용
  • 최대 문맥 길이를 실제 제품 요구에 맞춰 제한
  • KV 캐시 부족 시 선점·재계산·퇴출 현상 관찰
  • 긴 요청이 짧은 요청을 막지 않도록 스케줄링 정책 실험

완료 조건

  • 두 엔진의 결과를 같은 표 형식으로 기록했다.
  • “어느 엔진이 항상 빠르다”가 아니라 워크로드별 승자를 설명했다.
  • 서버 시작 명령과 전체 환경 정보를 보고서에 남겼다.

3. Paged Attention과 KV 캐시

3.1 먼저 이해할 계산

Transformer의 KV 캐시 메모리는 모델 구조와 데이터형에 따라 달라진다. 개념적으로는 다음 항목에 비례한다.

KV cache bytes
≈ batch × sequence_length × layers
  × 2(K,V) × KV_heads × head_dim × bytes_per_element

Grouped Query Attention을 사용하는 모델은 attention head 수 대신 KV head 수가 중요하다. 모델 설정 파일의 num_key_value_heads, num_hidden_layers, head_dim 또는 이에 해당하는 값을 직접 확인한다.

3.2 Paged Attention

Paged Attention은 요청별 KV 캐시를 고정된 큰 연속 공간으로 잡는 대신 블록 단위로 관리해 단편화와 낭비를 줄이는 접근이다. 운영 관점에서는 다음 질문으로 연결한다.

  • 블록 크기가 메모리 낭비와 관리 비용에 어떤 영향을 주는가?
  • 요청이 끝난 뒤 블록이 얼마나 빨리 재사용되는가?
  • 여러 요청이 동일 prefix를 공유할 때 어느 정도 절약되는가?

3.3 캐시 퇴출 실험

세 가지 트래픽을 만든다.

  1. 짧은 대화 100개
  2. 동일한 시스템 프롬프트를 공유하는 요청 100개
  3. 긴 문서 질의 20개와 짧은 대화 100개의 혼합

각 실험에서 다음을 기록한다.

  • KV 캐시 사용률
  • prefix cache hit rate
  • preemption 또는 recomputation 횟수
  • 대기열 길이
  • TTFT p50/p95/p99

3.4 퇴출 정책 설계 과제

아래 점수로 직접 정책을 설계한다.

eviction_score =
  0.40 × idle_time_normalized
  + 0.25 × cache_size_normalized
  + 0.20 × recompute_cost_inverse
  + 0.15 × tenant_priority_inverse

이 공식은 학습용 예시다. 가중치를 바꾸며 다음 사례를 비교한다.

  • LRU
  • 가장 큰 캐시 우선
  • 재계산 비용이 낮은 항목 우선
  • 유료 사용자 우선 보존

완료 조건

  • 캐시가 부족해지는 시점을 그래프로 찾았다.
  • hit rate가 높아져도 p95가 나빠질 수 있는 조건을 설명했다.
  • 퇴출 정책의 장단점을 실제 측정값으로 비교했다.

4. 양자화: INT4, FP8, AWQ, GPTQ

4.1 구분

방식 핵심 성격 주로 확인할 것
FP8 낮은 정밀도의 부동소수점 연산 하드웨어 지원, 처리량, 품질
INT4 4비트 정수 기반 가중치 표현 메모리 절감, 커널 지원
AWQ activation을 고려한 weight-only 양자화 실제 프롬프트 품질
GPTQ 2차 정보 근사를 이용한 사후 학습 양자화 양자화 설정과 커널 호환성

AWQ와 GPTQ는 “파일이 더 작다”만으로 평가하지 않는다. 엔진과 GPU에 맞는 커널이 없으면 메모리는 줄어도 속도가 느려질 수 있다.

4.2 비교 실험

동일 모델 계열에서 BF16/FP16, FP8, AWQ INT4, GPTQ INT4를 준비한다.

| 형식 | 모델 크기 | VRAM idle/peak | TTFT p95 | tok/s | 정확도 | 비고 |
|---|---:|---:|---:|---:|---:|---|

품질 평가는 최소 세 층으로 나눈다.

  • 짧은 지식·상식 100문항
  • 한국어 지시 이행 50문항
  • 실제 서비스 프롬프트 50개

4.3 선택 규칙

if GPU가 FP8을 효율적으로 지원하고 품질 저하가 허용 범위:
    FP8 후보
elif VRAM이 가장 큰 제약이고 지원 커널이 검증됨:
    AWQ 또는 GPTQ INT4 후보
else:
    BF16/FP16 기준선 유지

완료 조건

  • 메모리 절감률과 처리량 향상률을 따로 기록했다.
  • 정확도 평균뿐 아니라 실패 유형을 분류했다.
  • 현재 장비에서 실제로 지원하지 않는 경로를 미검증으로 표시했다.

5. 추측 디코딩

5.1 개념

작은 draft 모델이 여러 후보 토큰을 먼저 제안하고 target 모델이 이를 검증한다. 목표는 출력 품질을 유지하면서 토큰 사이 지연시간을 낮추는 것이다. 성능 향상은 모델 조합, acceptance rate, 배치 크기, 메모리 대역폭과 워크로드에 따라 달라진다.

5.2 실험 설계

변수 값 예시
target model 7B~14B instruct
draft model 같은 tokenizer를 쓰는 소형 모델
speculative tokens 1, 3, 5, 8
동시성 1, 8, 32
출력 길이 32, 256, 1,024

수집 항목:

  • draft acceptance rate
  • speculative efficiency
  • ITL p50/p95
  • 전체 처리량
  • 추가 GPU 메모리
  • 비추측 기준선 대비 속도 변화

5.3 중단 조건

다음 중 하나면 해당 설정을 채택하지 않는다.

  • p95 ITL이 기준선보다 나빠짐
  • draft 모델 메모리 때문에 동시성이 감소함
  • acceptance rate가 낮아 추가 계산이 이익을 상쇄함

완료 조건

  • 최소 2개 draft/target 조합을 비교했다.
  • 단일 요청과 높은 동시성에서 결과가 다른 이유를 설명했다.

6. 모델 라우터와 토큰 예산

6.1 라우팅 목표

라우터는 “가장 좋은 모델”을 고르는 장치가 아니라 요청의 품질 하한, 지연시간 SLO, 비용 상한을 동시에 만족하는 후보를 선택하는 정책 계층이다.

flowchart TD
    A["사용자 요청"] --> B["정책·예산 검사"]
    B --> C["난이도·길이 분류"]
    C --> D{"후보 모델"}
    D --> E["저비용 모델"]
    D --> F["저지연 모델"]
    D --> G["고품질 모델"]
    E --> H["응답·비용 기록"]
    F --> H
    G --> H

6.2 최소 데이터 모델

from dataclasses import dataclass

@dataclass
class ModelProfile:
    name: str
    input_cost_per_million: float
    output_cost_per_million: float
    p95_ttft_ms: float
    p95_itl_ms: float
    quality_score: float
    max_context: int

6.3 점수 함수

def route_score(
    quality: float,
    latency_ms: float,
    estimated_cost: float,
    quality_weight: float = 0.5,
    latency_weight: float = 0.3,
    cost_weight: float = 0.2,
) -> float:
    return (
        quality_weight * quality
        - latency_weight * latency_ms
        - cost_weight * estimated_cost
    )

실제 구현에서는 단위가 다른 값을 그대로 더하지 말고 0~1 범위로 정규화한다. 또한 품질 하한과 비용 상한을 먼저 적용한 후 남은 후보에 점수를 계산한다.

6.4 토큰 예산

def output_budget(
    plan_limit: int,
    used_tokens: int,
    requested_max_tokens: int,
    reserve_tokens: int = 256,
) -> int:
    remaining = max(0, plan_limit - used_tokens - reserve_tokens)
    return min(requested_max_tokens, remaining)

필수 정책:

  • 사용자·팀·API 키별 일/월 토큰 한도
  • 요청당 최대 입력·출력 토큰
  • 시스템 프롬프트와 도구 호출 토큰 포함 여부
  • 스트리밍 도중 예산 소진 처리
  • 재시도와 fallback 요청의 중복 과금 처리
  • 예약량과 실제 사용량의 정산

6.5 라우터 평가

정적 규칙, latency 기반, cost 기반, 품질 포함 다목적 라우터를 같은 요청 집합으로 비교한다.

| 정책 | 성공률 | 품질 | p95 지연 | 평균 원가 | SLO 위반률 |
|---|---:|---:|---:|---:|---:|

완료 조건

  • 라우팅 이유를 요청 로그에서 재현할 수 있다.
  • 예산 초과 요청은 GPU에 도달하기 전에 거절된다.
  • fallback이 무한 반복되지 않는다.

7. 관측 가능성: Prometheus와 Grafana

7.1 반드시 수집할 네 종류

요청

  • 요청 수, 성공 수, 오류 수
  • 입력·출력 토큰
  • 모델, tenant, 상태 코드

지연시간

  • TTFT
  • ITL/TPOT
  • E2E
  • queue time

엔진

  • 실행 중·대기 중 요청
  • KV 캐시 사용률과 hit rate
  • preemption
  • batch 크기

자원

  • GPU 사용률, 메모리, 전력
  • CPU, RAM, 네트워크
  • Pod 재시작과 OOM

7.2 카디널리티 경고

Prometheus label에 user_id, request_id, 전체 프롬프트를 넣지 않는다. 사용자 단위 상세 기록은 로그 또는 분석 저장소에 보내고, 메트릭은 plan, model, region처럼 제한된 값만 사용한다.

7.3 대시보드 구성

  1. 서비스 건강: RPS, error rate, p95 E2E
  2. 사용자 경험: TTFT와 ITL
  3. GPU 효율: utilization, memory, tokens/s
  4. 스케줄러: running/waiting requests, queue time
  5. 캐시: KV 사용률, prefix hit rate, preemption
  6. 비용: 시간당 비용, 요청당 비용, 1M token당 비용

7.4 알림 예시

groups:
  - name: llm-serving
    rules:
      - alert: LLMHighErrorRate
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m]))
          /
          clamp_min(sum(rate(http_requests_total[5m])), 1)
          > 0.02
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "LLM API 5xx 비율이 2%를 초과했습니다."

메트릭 이름은 실제 애플리케이션에서 노출하는 이름에 맞춰 수정한다.

완료 조건

  • 느린 응답이 queue, prefill, decode 중 어디서 발생했는지 구분한다.
  • 대시보드의 수치와 원시 요청 로그를 표본 대조했다.

8. 1,000+ 동시 요청 부하 시험

8.1 도구

  • k6: HTTP 부하와 시나리오 작성
  • Locust: Python 기반 사용자 행동 모델
  • vegeta: 단순 HTTP 처리량 확인
  • 엔진별 benchmark 도구: 순수 추론 성능 확인

OpenAI 스트리밍 응답은 일반 HTTP 완료 시간만 측정하면 TTFT와 ITL을 놓칠 수 있다. SSE 청크의 도착 시간을 기록하는 전용 클라이언트를 준비한다.

8.2 단계적 증가

1 → 8 → 32 → 64 → 128 → 256 → 512 → 1,000 → 1,500

각 단계에서 최소 5분간 안정 상태를 측정한다. 오류율 또는 p95가 SLO를 넘으면 더 높은 단계로 진행하지 않고 원인을 찾는다.

8.3 현실적인 요청 분포

유형 비율 입력 토큰 출력 토큰
짧은 질의 50% 64~256 32~128
일반 대화 30% 256~1,024 128~512
긴 문서 15% 4K~16K 128~512
긴 생성 5% 256~1K 1K~4K

8.4 보고서

  • 동시성별 offered load와 completed throughput
  • p50/p95/p99 TTFT, ITL, E2E
  • timeout, 429, 5xx
  • GPU 사용률과 메모리
  • queue length
  • SLO를 만족하는 최대 goodput

완료 조건

  • 1,000 연결을 열었다는 사실과 1,000 요청이 성공했다는 사실을 구분했다.
  • 클라이언트 CPU·네트워크가 병목이 아닌지 확인했다.
  • 실패 지점과 안전 운영 한계를 명시했다.

9. Kubernetes와 GPU 자동 확장

9.1 학습 순서

  1. Deployment와 Service
  2. GPU resource request
  3. readiness/liveness probe
  4. rolling update
  5. node selector, taint, toleration
  6. HPA
  7. Prometheus custom metrics
  8. queue 기반 확장

9.2 Deployment 골격

apiVersion: apps/v1
kind: Deployment
metadata:
  name: llm-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: llm-server
  template:
    metadata:
      labels:
        app: llm-server
    spec:
      containers:
        - name: server
          image: your-registry/llm-server:VERSION
          ports:
            - containerPort: 8000
          resources:
            limits:
              nvidia.com/gpu: 1
          readinessProbe:
            httpGet:
              path: /health
              port: 8000
            initialDelaySeconds: 60
            periodSeconds: 10

이미지 태그와 health endpoint는 실제 배포물에 맞춰 검증한다.

9.3 HPA 골격

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: llm-server
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: llm-server
  minReplicas: 1
  maxReplicas: 8
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 600
  metrics:
    - type: Pods
      pods:
        metric:
          name: llm_waiting_requests
        target:
          type: AverageValue
          averageValue: "4"

이 예시는 custom metrics adapter가 llm_waiting_requests를 제공한다고 가정한다. GPU Pod는 모델 로딩 시간이 길기 때문에 CPU 사용률만으로 확장하면 늦을 수 있다. queue length, waiting requests, 예상 대기시간 같은 선행 지표를 비교한다.

9.4 운영 실험

  • 0→100 요청 급증
  • 10분 동안 점진 증가
  • 한 Pod 강제 종료
  • 새 모델 이미지 rolling update
  • 노드 하나 장애

완료 조건

  • 새 Pod가 준비되기 전에는 트래픽을 받지 않는다.
  • scale-down 중 진행 중 요청의 종료 정책을 검증했다.
  • 모델 다운로드 시간이 확장 지연에 포함됨을 측정했다.

10. 엣지 배포

10.1 ONNX Runtime

작은 encoder 또는 소형 생성 모델을 ONNX로 변환해 CPU, DirectML, CUDA 실행 공급자를 비교한다.

학습 항목:

  • 정적 shape와 동적 shape
  • graph optimization
  • INT8 양자화
  • cold start와 warm latency

10.2 TensorRT 계열

CUDA 환경에서만 별도 트랙으로 진행한다.

  • 엔진 빌드 시간과 실행 시간 구분
  • 지원 precision 확인
  • 고정/동적 shape profile
  • GPU 아키텍처와 엔진 호환성

AMD 장비에서는 이 트랙을 개념 학습 후 클라우드 NVIDIA GPU에서 검증한다.

10.3 WebLLM

브라우저에서 WebGPU로 소형 모델을 실행한다.

측정 항목:

  • 최초 모델 다운로드 크기와 시간
  • 브라우저별 WebGPU 지원
  • prefill/decode 속도
  • 탭 전환과 메모리 회수
  • 개인정보가 서버로 전송되지 않는 로컬 처리 범위

10.4 엣지 의사결정표

조건 후보
브라우저 오프라인 실행 WebLLM
데스크톱/모바일 네이티브 ONNX Runtime
NVIDIA 서버 최대 성능 TensorRT 계열
개발 편의와 폭넓은 모델 llama.cpp/Ollama 계열

완료 조건

  • 같은 작은 모델을 서버와 엣지에서 비교했다.
  • 다운로드 비용, cold start, 전력, 개인정보를 성능표에 포함했다.

11. 추론 비용과 단위 경제성

11.1 기본 공식

GPU hourly cost
= 인스턴스 비용 + 스토리지 + 네트워크 + 관측 비용

effective tokens per hour
= measured tokens/s × 3,600 × utilization × success_rate

cost per 1M tokens
= GPU hourly cost / effective tokens per hour × 1,000,000

cost per request
= input_token_cost + output_token_cost
  + routing + storage + network + retry overhead

11.2 손익분기점

gross margin per request
= revenue per request - variable cost per request

break-even requests per month
= monthly fixed cost / gross margin per request

11.3 반드시 포함할 숨은 비용

  • 낮은 사용률과 유휴 GPU
  • 모델 로딩과 재배포 시간
  • 실패·재시도·fallback
  • 긴 system prompt
  • 사용하지 않고 남은 예약 용량
  • 로그·메트릭·네트워크
  • 엔지니어 운영 시간
  • 품질 저하로 발생하는 재질문

11.4 실습

세 시나리오를 비교한다.

  1. 단일 고성능 GPU 자체 서빙
  2. 여러 저가 GPU 자체 서빙
  3. 외부 API 사용

트래픽이 낮음/보통/높음일 때 월 비용과 gross margin을 계산한다. 자체 서빙은 최고 처리량이 아니라 실제 평균 사용률로 계산한다.

완료 조건

  • 가격과 성능 수치의 기준일을 기록했다.
  • 최선/기준/최악 시나리오를 분리했다.
  • 비용 절감이 품질과 SLO에 미치는 영향을 함께 제시했다.

12. 최종 프로젝트

프로젝트 요구사항

다음 아키텍처를 구현한다.

flowchart TD
    A["클라이언트"] --> B["API·토큰 예산"]
    B --> C["모델 라우터"]
    C --> D["vLLM 풀"]
    C --> E["SGLang 풀"]
    D --> F["Prometheus"]
    E --> F
    F --> G["Grafana"]

기능

  • OpenAI 호환 chat completions API
  • 최소 2개 모델 또는 2개 배포
  • 비용·지연시간·품질 기반 라우팅
  • 사용자별 일일 토큰 예산
  • 스트리밍
  • 요청·토큰·오류·비용 기록
  • Prometheus 메트릭
  • Grafana 대시보드
  • 부하 시험
  • Docker Compose 로컬 실행
  • 선택: Kubernetes와 HPA

서빙 파이프라인

  1. 처리량 최적화 vLLM
  2. prefix 공유에 최적화한 SGLang
  3. 양자화 또는 추측 디코딩을 적용한 실험 파이프라인

공개 벤치마크 필수 정보

date:
git_commit:
model_id:
model_revision:
engine:
engine_version:
container_image:
gpu:
gpu_count:
driver:
cuda_or_rocm:
cpu:
ram:
prompt_dataset:
input_length_distribution:
output_length_distribution:
concurrency:
warmup:
duration:
sampling_parameters:

최종 평가표

영역 배점 통과 기준
재현성 20 다른 사람이 명령대로 실행 가능
성능 측정 20 TTFT·ITL·goodput·오류 포함
캐시·배칭 15 적용 전후 비교
라우팅·예산 15 결정 이유와 제한 동작 확인
관측 10 병목 위치를 대시보드에서 확인
부하 시험 10 현실적인 분포와 안전 중단
비용 10 요청당 원가와 손익분기점

매일 공부 루틴

90분 버전

  1. 15분: 공식 문서 또는 논문 한 절 읽기
  2. 45분: 하나의 변수만 바꾸는 실험
  3. 15분: 그래프와 표 업데이트
  4. 10분: 실패 원인 기록
  5. 5분: 다음 실험의 가설 작성

실험 노트 양식

# 실험 제목

## 가설

## 고정 조건

## 변경 변수

## 실행 명령

## 예상 결과

## 실제 결과

## 해석

## 미검증 항목

## 다음 실험

논문과 자료를 읽는 법

모델 출시 뉴스보다 다음 질문에 답하는 자료를 우선한다.

  • 메모리 이동량을 어떻게 줄였는가?
  • prefill과 decode를 어떻게 나눴는가?
  • 배칭과 스케줄링이 tail latency에 어떤 영향을 주는가?
  • KV 캐시를 어떻게 배치·압축·퇴출하는가?
  • 품질을 유지하면서 연산량을 어떻게 줄였는가?
  • 어떤 하드웨어와 워크로드에서만 이득이 있었는가?

읽을 주제:

  • PagedAttention
  • continuous batching
  • prefix caching와 RadixAttention
  • speculative decoding, Medusa, EAGLE 계열
  • disaggregated prefill/decode
  • KV cache quantization과 eviction
  • tensor/pipeline/data/expert parallelism
  • goodput과 SLO-aware scheduling

논문 요약에는 반드시 기준선, 하드웨어, 모델, 입력·출력 길이, 동시성, 한계를 기록한다.


자주 발생하는 실패

CUDA/ROCm 메모리 부족

확인 순서:

  1. 다른 프로세스가 GPU 메모리를 쓰는지 확인
  2. 최대 문맥 길이와 동시 요청 수 축소
  3. GPU memory utilization 설정 점검
  4. 양자화 모델로 기준선 재구성
  5. CPU offload는 속도 저하를 포함해 다시 측정

처리량은 높은데 응답이 느림

[Inference] 높은 배치 크기로 총 처리량은 올라갔지만 queue time 또는 TTFT가 악화됐을 가능성이 있다. 대기시간과 실제 GPU 실행 시간을 분리해 확인한다.

GPU 사용률이 낮음

[Inference] 입력 준비, 토크나이징, 네트워크, 작은 배치 또는 부하 생성기가 병목일 가능성이 있다. GPU만 보지 말고 CPU, queue, batch size, 클라이언트 사용률을 함께 확인한다.

양자화했는데 느려짐

[Inference] 현재 GPU·엔진에 최적화된 커널이 없거나 dequantization 비용이 이득을 상쇄했을 가능성이 있다. 동일 동시성과 동일 길이에서 커널 및 정밀도별 결과를 비교한다.

HPA가 늦게 확장됨

[Inference] CPU 사용률이 대기열 증가보다 늦게 반응하거나 모델 로딩 시간이 긴 것이 원인일 수 있다. waiting requests와 예상 대기시간을 선행 지표 후보로 검증한다.


공식 문서


시작 체크리스트

  • GPU와 드라이버 정보를 기록했다.
  • 모델과 엔진 버전을 고정했다.
  • TTFT, ITL, throughput, goodput 정의를 정했다.
  • Ollama 또는 LM Studio API를 호출했다.
  • vLLM 서버를 실행했다.
  • SGLang 서버를 실행했다.
  • 동일 워크로드로 두 엔진을 비교했다.
  • KV 캐시 사용률과 cache hit rate를 관찰했다.
  • 양자화 전후 메모리·속도·품질을 비교했다.
  • 추측 디코딩의 acceptance rate를 측정했다.
  • 모델 라우터와 토큰 예산을 구현했다.
  • Prometheus와 Grafana를 연결했다.
  • 1,000 동시 요청 시험을 수행했다.
  • Kubernetes HPA를 검증했다.
  • 요청당 원가와 손익분기점을 계산했다.
  • 모든 명령과 환경을 공개 보고서에 기록했다.

검증 범위와 주의사항

이 문서는 학습 사이트의 구조와 실습 설계를 제공한다. 이 환경에는 GPU가 연결되어 있지 않아 vLLM, SGLang, CUDA, ROCm, Kubernetes GPU 배포 명령을 실제 실행하지 않았다. 따라서 각 실습의 성공 결과는 미검증이며, 사용하는 GPU·드라이버·엔진 릴리스의 공식 문서에서 지원 조합과 CLI 옵션을 확인해야 한다.

반응형