RT-T6: 실시간 추론 서버 설계

🎯 실시간 추론 서버 개요배치 학습 → 온라인 추론

RT-T5까지는 일 1회 배치 재학습 파이프라인을 다뤘다. RT-T6는 학습된 모델을 운영 환경에서 실시간으로 서빙하기 위한 추론 서버를 설계한다. 배차 요청이 들어오면 FastAPI 비동기 핸들러가 요청을 받고, Redis 캐시가 동일 키의 직전 결과를 즉시 반환하거나 캐시 미스 시에만 피처 빌드 → LightGBM 추론 → OR-Tools 최적화를 수행한다.

SLA 목표는 응답 3초 이내, 초당 500건 처리이며, 5분 TTL Redis 캐싱으로 반복 요청의 연산 비용을 제거한다.

🧭 요청 처리 파이프라인cache-hit은 2·3·4·5단계 건너뜀 (~30ms)
STEP 1
receive_request

FastAPI /route/score POST 수신. RouteRequest 스키마 검증.

STEP 2
redis.get

score:{route_id}:{date} 키 조회. hit이면 즉시 반환.

STEP 3
feature_build

정적 피처는 Redis 1h 캐시 사용. 동적 피처만 실시간 계산.

STEP 4
model.predict

LightGBM 배치 predict. 동일 루트 ShipTo 묶음 호출로 추론 비용 상각.

STEP 5
optimizer.solve

OR-Tools CP-SAT. 2초 타임아웃 보장, 최선해 반환(최적해 필수 아님).

STEP 6
redis.setex

결과를 5분 TTL로 캐싱. 동일 요청 재호출 시 비용 0.

🐍 FastAPI 엔드포인트 (Python pseudocode)
# FastAPI 엔드포인트
@app.post("/route/score")
async def score_route(req: RouteRequest):
    cache_key = f"score:{req.route_id}:{req.date}"
    cached = await redis.get(cache_key)
    if cached: return json.loads(cached)

    features = feature_builder.build(req)
    scores   = model.predict(features) # LightGBM
    result   = optimizer.solve(scores, req) # OR-Tools
    await redis.setex(cache_key, 300, json.dumps(result))
    return result
🚀 성능 최적화 전략 & SLA3초 이내 · 초당 500건
avg_latency = hit_rate × t_hit + (1 − hit_rate) × t_miss
throughput = min(rps_target, workers × 1000 / avg_latency)
# hit_rate ↑ / t_miss ↓ / workers ↑ 세 레버로 SLA 달성
hitredis.get 20ms + 응답 10ms ≈ 30ms (대부분의 재조회 요청)
miss피처 빌드 150ms + predict 80ms + OR-Tools ≤2s + 캐시 쓰기 15ms ≈ ≤2.3s
batch동일 루트 ShipTo를 한 번의 predict()로 묶어 호출, 추론 비용 상각
timeoutOR-Tools 2s 하드 타임아웃 — 최적해 보장 불필요, 최선해 반환

정적 피처(지역/거리 등)는 Redis 1시간 캐시에 따로 보관되어 매번 계산하지 않는다. 동적 피처(현재 적재율, 차량 위치 등)만 요청 시점에 계산하므로 feature_build 단계의 비용이 크게 줄어든다.

참고문헌
[1] FastAPI Docs, "Async Concurrency and Performance" (2025.12)
[2] Redis Labs, "Caching Patterns for ML Inference" (2025.09)