9 분 소요

제 4 장의 내용을 읽고 아래와 같은 질문과 답변을 달았다. 이 장을 하나의 흐름으로 정리하면 이렇게 된다. 따라서 이 챕터의 가장 중요한 메시지는 세 문장으로 압축할 수 있다.

첫째, Agentic AI 시대에는 모델 서빙의 최적화 단위가 “한 번의 LLM 추론”이 아니라 “전체 Agent control loop”가 된다.

둘째, 프로덕션 LLM 플랫폼은 단순 GPU inference server가 아니라 API → orchestration → resource management → distributed serving → inference → optimization으로 분리된 계층형 시스템이어야 한다.

셋째, Bedrock과 직접 구축 중 어느 것이 더 좋은지는 고정된 답이 없으며, E2E/TTFT/ITL과 RPS/TPS, 비용, 트래픽 패턴을 측정하면서 필요에 따라 스펙트럼상의 위치를 이동하는 것이 가장 현실적인 전략이다.


             Agentic Application
                     │
        한 요청에서 여러 호출 발생
                     │
                     ▼
       Serving Complexity 증가
                     │
                     ▼
     Enterprise Layered Architecture
                     │
          ┌──────────┴───────────┐
          │                      │
     Cloud Managed            Build
       Bedrock            K8s/Ray/vLLM
          │                      │
          └──────────┬───────────┘
                     │
            어느 쪽이 더 좋은가?
                     │
                     ▼
             Performance 측정
                     │
          ┌──────────┴─────────┐
          │                    │
      Latency              Throughput
 E2E / TTFT / ITL         RPS / TPS
          │                    │
          └──────────┬─────────┘
                     │
                     ▼
            Cost / SLO 판단
                     │
                     ▼
          Build ↔ Cloud 위치 조정

1. 에이전트 Agentic 워크플로우가 등장하면서 모델 서빙 요구사항은 어떻게 달라지는가?

모델 서빙의 단위가 “한 번의 추론”에서 “하나의 작업을 끝내기 위한 반복적인 제어 루프”로 바뀐다는 것이다. 전통적인 LLM 서비스는 대체로 다음과 같다.

User
↓
LLM
↓
Response

요청 한 번에 모델을 한 번 호출하고 응답하면 끝난다. 에이전틱 시스템에서는 구조가 달라집니다.

User
↓
Agent
↓
Planning ──→ LLM
↓
Retrieval ─→ Embedding / Vector DB
↓
Reasoning ─→ LLM
↓
Tool Call ─→ API / DB / Search
↓
Result
↓
LLM
↓
필요하면 다시 반복
↓
Final Answer

즉, > 1 User Request ≠ 1 Model Request가 된다. Knowledge Agent 실습이 좋은 예이다. 사용자가 단 한 번 질문했지만 내부적으로는

Planner LLM      1회
Query Embedding  1회
Summary LLM      1회
Analysis LLM     1회
----------------------
총 API 호출 4회

가 발생했다.

1-1. 서빙 시스템에 생기는 5가지 변화

  • 토큰 사용량 증가: Planner, RAG context, tool result, intermediate result가 다음 LLM 호출에 계속 들어가므로 요청당 토큰 소비량이 급격히 증가한다.

  • 지연 시간 증폭(Latency amplification): Agent workflow가 직렬로 연결되어 있다면,

Total Agent Latency
≈ L1 + L2 + L3 + ... + Ln

처럼 각 단계의 E2E latency가 누적된다. 예를 들어,

Planning       0.7s
RAG            0.3s
Summary        1.4s
Analysis       2.0s
------------------
Agent E2E      4.4s

가 될 수 있다. 특히 다음 단계가 이전 단계의 전체 결과를 필요로 한다면 TTFT가 아무리 빨라도 전체 작업은 빨라지지 않는다.

  • 동적인 트래픽 패턴: 단순 질문은 LLM 한 번으로 끝날 수도 있지만 복잡한 질문은 5회, 10회, 20회 호출할 수도 있다. 따라서, User RPS = 10 이라고 해서 Model RPS = 10인 것이 아니다. 평균적으로 한 요청이 LLM을 6번 호출한다면 실질적으로는 10 user RPS × 6 calls ≈ 60 model RPS가 된다.

  • 여러 모델을 동시에 서빙해야 하는 문제: 현대 에이전트는 보통 하나의 모델만 쓰지 않는다.

Planner    → Small/Reasoning LLM
Generation → Large LLM
Embedding → Embedding Model
Vision → VLM
Speech → ASR/TTS
Reranker → Ranking Model

그래서 모델 선택과 오케스트레이션(orchestration)이 코어 추론(Core Inference)만큼 중요해진다.

  • 상태와 메모리 관리: 이전 호출의 결과, tool result, conversation history, RAG context, KV cache 등을 다음 호출에서 재사용해야 한다. 그래서 에이전틱 서빙(Agentic Serving)에서는 다음 기술의 중요성이 크게 올라간다.
KV Cache
Prompt Cache
CAG
Cache-aware Routing
Continuous Batching
Scheduler
Model Routing
Tool Orchestration
Observability

1-2. RAG와 CAG의 의미도 달라진다

RAG는 매 요청마다 외부 지식(nowledge)을 검색한다.

Query
    → Embedding
    → Vector Search
    → Retrieved Context
    → LLM

장점은 최신성과 동적 지식이다. 반면 문맥 증강 생성(CAG,Context-Augmented Generation)는 자주 재사용하는 지식을 미리 문맥과 KV 캐시에 올려 놓는다.

Knowledge
    → Prefill once
    → KV Cache
        ↓
Query → reuse

따라서 반복적인 에이전틱 워크로드에서는 RAG와 CAG를 경쟁 관계라기보다

RAG = 지식 검색 최적화 CAG = 반복 추론 실행 최적화

로 볼 수 있다.

2. 엔터프라이즈 LLM 서빙 플랫폼의 계층형 아키텍처는 어떻게 구성되며 Kubernetes/Ray Serve에서는 어떻게 구현하는가?

엔터프라이즈급 플랫폼에서 중요한 생각은

“LLM을 GPU에서 실행하는 것”과 “LLM 서비스를 운영하는 것”은 완전히 다른 문제다.

전체 구조를 단순화하면 다음과 같다.

             Client / Agent
                    │
                    ▼
┌──────────────────────────────────┐
│ 1. Public API                    │
│ Auth / Rate Limit / Billing      │
└──────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────┐
│ 2. Model Selection              │
│ Routing / Cost / Quality / SLA   │
└──────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────┐
│ 3. Resource Management          │
│ GPU / CPU / Memory / Scheduling  │
└──────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────┐
│ 4. Distributed Serving          │
│ Multi-GPU / Cache / Multi-node   │
└──────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────┐
│ 5. Core Inference               │
│ vLLM / TRT-LLM / SGLang          │
└──────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────┐
│ 6. Model Optimization           │
│ Quant / Spec Decode / Kernels    │
└──────────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────┐
│ 7. Models                        │
│ Base / FT / Adapter / Version    │
└──────────────────────────────────┘

2.1 Layer 1 - 공인 API

역할은 외부 트래픽을 안전하게 받아들이는 것이다.

Authentication
Authorization
Tenant
Quota
Rate Limit
Billing
Routing
DDoS protection

Open Source에서는 보통

FastAPI
+
Kubernetes Service
+
Ingress / Gateway
+
Redis
+
JWT / API Key

등으로 구현할 수 있다. 예를 들어 두 단계의 요청 제한(rate limiting)이 가능하다.

Ingress
→ global rate limit

FastAPI
→ tenant-specific quota

이는 심층 방어(defense-in-depth) 구조이다.

2-2. Layer 2 - 모델 선택과 오케스트레이션

모든 요청에 가장 큰 모델을 쓰는 것은 비효율적이다.

Simple Request
↓
Small Model

Complex Reasoning
↓
Large Model

이 레이어에서 최적화하는 품질(Quality), 지연시간(latency) 비용 등 세 가지가 있다. 또한 모델 라우팅(Model routing), 카나리 배포(Canary deployment), 테넌트 지정 모델(Tenant-specific model), 추측 디코딩(Speculative decoding), 대체 경로(Fallback), 로드 밸런싱(Load Balancing) 등도 수행한다.

예를 들어:


if long_generation:
    speculative_decode()
else:
    normal_model()

처럼 모델 실행 전략 자체를 바꿀 수도 있다.

2-3. Layer 3 - 리소스 관리

레이어3는 모델보다 GPU라는 희소 자원이 중심이다. 질문은 이런 것이다.

누가 GPU를 사용할 것인가?
몇 GPU를 할당할 것인가?
H100과 L40S 중 무엇을 사용할 것인가?
GPU utilization은 얼마인가?
Priority workload는 무엇인가?

Kubernetes에서는 이를 포드(Pod), 스케줄러, GPU 오퍼레이터, 디바이스 플러그인(Device Plugin), 노드 셀렉터(Node Selector), 노드 배제 설정과 파드 허용 규칙(Taint/Toleration), HPA, 큐(Kueue), 카펜터(Karpenter) 등으로 관리할 수 있다.

Ray에서는

ray_actor_options={
    "num_gpus": 1
}

같은 식으로 애플리케이션이 필요한 리소스를 선언할 수 있다.

2.4 Layer 4 - 분산 서빙

모델이 하나의 GPU에 들어가지 않을 때 필요하다. 예를 들어, Model Weight = 160 GB, GPU VRAM = 80 GB 라면 최소 2 GPU가 필요합니다. 대표 기술은

Tensor Parallel
Pipeline Parallel
Data Parallel
Prefill/Decode Disaggregation
Distributed KV Cache
Prompt Cache
Cache-aware Routing

이다. 예를 들어,

Node 1: GPU × 8 → TP=8
Node 2: GPU × 8 → TP=8
Inter-Node (노드 간) → PP=2

처럼 구성할 수 있다.

2.4 Layer 5 - 코어 추론(Core Inference)

여기가 실제 토큰 계산이 일어나는 부분이다. 대표 추론 엔진은 vLLM, TensorRT-LLM, SGLang, Triton 등이다. 그리고 아래쪽에는

FlashAttention
PagedAttention
GEMM
CUDA kernels

같은 최적화가 존재한다. 구조적으로는

Ray Serve
↓
vLLM
↓
PyTorch / CUDA
↓
GPU

이다. Ray Serve와 vLLM의 역할을 혼동하면 안 됩된다.

Ray Serve = 서비스 오케스트레이션 / 스케일링 vLLM = LLM 추론 엔진

이다.

2.5 Layer 6 - 모델 최적화(Model Optimization)

모델 최적화는 모델을 새로 학습하지 않고 추론 효율을 높인다.

대표 기술로는 다음과 같다.

FP8
INT8
INT4
AWQ
GPTQ
Speculative Decoding
KV Cache optimization
Kernel fusion
Continuous batching

모든 최적화가 같은 지표를 좋아지게 하는 것은 아니다. 예를 들어 처리량(throughput)을 극대화하기 위해 배치를 크게 하면 TTFT는 악화될 수 있다.

2.6 Kubernetes + KubeRay + Ray Serve + vLLM로 합치면

제 4 장 오픈소스 구현을 가장 간결하게 나타내면:

                Internet
                     │
                Ingress/Gateway
                     │
                  FastAPI
                     │
               Model Router
                     │
               Ray Serve
                     │
          ┌──────────┴─────────┐
          │                    │
     LLMServer             LLMServer
          │                    │
        vLLM                  vLLM
          │                    │
        GPU 0                 GPU 1

────────────────────────────────────

Kubernetes
├─ Networking
├─ Pod lifecycle
├─ GPU allocation
├─ Scaling
└─ Monitoring

KubeRay
└─ Ray lifecycle

Ray Serve
├─ Deployment
├─ Replica
├─ Routing
├─ Autoscaling
└─ Multiplexing

vLLM
├─ PagedAttention
├─ KV cache
├─ Continuous batching
└─ Token generation

특히 프로덕션 서빙에서는 RayCluster보다 RayService가 자연스럽다.

RayCluster = Ray Computing Cluster Management
RayService = RayCluster
    + Ray Serve Application
    + Health Check
    + Rolling Update
    + HA

그래서 KubeRay 기반 LLM serving의 전형적인 구조는

Kubernetes
↓
KubeRay Operator
↓
RayService
↓
Ray Serve
↓
vLLM
↓
GPU

가 된다.

3. Build vs Cloud는 어떤 기준으로 선택하며, 무엇을 측정해야 하는가?

가장 중요한 결론부터 말하면:

Build vs Buy가 아니라 Control Spectrum이다.

즉 다음 두 극단 사이에서 움직이는 문제이다.

    Managed                                      DIY

Bedrock
↓
JumpStart
↓
BYO Model
↓
BYO Code
↓
BYO Container
↓
EKS + Ray Serve + vLLM

왼쪽으로 갈수록

Ease of Use ↑
Operation burden ↓
Control ↓

오른쪽으로 갈수록

Control ↑
Optimization freedom ↑
Operation burden ↑

이다.

3-1. AWS 6단계로 보면

단계 방식 편의성 통제권 운영 부담
1 Bedrock 매우 높음 매우 낮음 매우 낮음
2 JumpStart 높음 낮음 낮음
3 BYO Model 중상 중간 중간
4 BYO Code 중간 높음 중상
5 BYO Image 낮음 매우 높음 높음
6 BYO Infrastructure 가장 낮음 최고 최고

3.1 선택 기준 1 - 시장 출시(Time to Market)

PoC 단계라면 Bedrock 같은 관리형 API가 매우 유리한다. 모델 서빙 플랫폼 구축에 몇 주를 쓰는 대신 바로 애플리케이션 검증이 가능하다.

3.2 선택 기준 2 - 맞춤화(Customization)

다음과 같은 요구가 생기면 오른쪽으로 이동한다.

Custom batching
Custom routing
Quantization
Speculative decoding
Custom CUDA kernel
Custom vLLM version
GPU sharing
KV cache routing
Prefill/decode separation

이런 요구는 관리형 API에서 구현하기 어렵다.

3.2 선택 기준 3 - 트래픽 볼륨(Traffic Volume)

트래픽이 작거나 불규칙하면 서버리스가 유리하다.

Low / burst traffic → Bedrock

반대로 항상 높은 부하가 유지된다면

High sustained traffic → Dedicated GPU

가 비용 면에서 유리할 수 있다. 따라서 중요한 질문은

“얼마나 많은 요청이 들어오느냐?”보다 “얼마나 많은 토큰을 얼마나 지속적으로 처리하느냐?”

이다.

3.3 선택 기준 4 - 비용(Cost)

관리형 API는 보통 $/token이고 직접 호스팅은 $/GPU-hour 이다. 따라서 어느 지점에서는 손익분기점이 생긴다. 개념적으로 API cost / sec = Tokens/sec × Price/tokenGPU cost / sec를 비교하면 된다.

트래픽이 충분히 크고 일정하면 전용 GPU가 유리해질 가능성이 커진다. 반면 utilization이 5~10% 수준이라면 비싼 GPU를 24시간 유지하는 것보다 관리형 API가 더 저렴할 수 있다.

그래서 반드시 성능을 측정해야 한다. Build vs Cloud 판단은 느낌으로 하는 것이 아니라 SLO + 비용 + 성능 지표로 해야 한다. 가장 중요한 지표는 크게 지연시간과 처리량 두 종류이다.

4 지연시간(Latency)

4.1 E2E Latency

Request
│
├─ Queue
├─ Routing
├─ Prefill
├─ Decode
├─ Network
↓
Response Complete

전체 시간이다. 에이전틱 워크플로에서는 중요하다. 왜냐하면,

Agent E2E ≈ Step1 E2E
    + Step2 E2E
    + Step3 E2E
    + ...

가 되기 때문이다.

4.2 TTFT - Time To First Token

Request
↓
Prefill
↓
First Token

첫 토큰이 나올 때까지의 시간이다. 사용자가 느끼는 **“응답이 시작되는 속도”**이다. 그래서 Chat UI에서는 매우 중요하다.

4.3 ITL / TPOT

첫 토큰 이후 토큰 사이의 간격이다. Token1 ──40ms── Token2 ──40ms── Token3 라면 `ITL ≈ 40 ms’ 이다. 출력이 길수록 중요하다.

4.4 이들의 관계

출력 토큰이 N이고 ITL이 일정하다고 단순화하면:

E2E ≈ TTFT + ITL × (N - 1)

예:

TTFT = 0.5 sec
ITL = 0.04 sec
N = 101
E2E
= 0.5 + 0.04 × 100
= 4.5 sec

이다.

5. 처리량(Throughput)

5.1 RPS

Requests / Second

예: 1177 requests / 300 sec ≈ 3.92 RPS

앞서 Ray Serve 실습 결과와 같다. 하지만 LLM에서는 RPS만 보면 위험하다.

Request A
10 input → 10 output

Request B
8000 input → 2000 output

둘을 똑같이 “1 request”로 계산하기 때문이다.

5-2. TPS

Generated Tokens / Second

LLM에서는 RPS보다 모델 처리 능력을 더 잘 보여준다. 하지만 이것도 조건을 명시해야 한다.

Input length
Output length
Concurrency
Batch size
Model
Precision
GPU
Context length

가 달라지면 TPS가 크게 달라진다. 그래서

Model A = 10,000 TPS
Model B = 8,000 TPS

라는 숫자만으로 A가 더 빠르다고 말해서는 안 된다.

댓글남기기