Inference Requests 대기열 중단
Source: Dev.to
Problem Overview
대부분의 추론 백엔드는 급증 시 성능이 저하됩니다.
이는 LLM에만 국한된 것이 아니라, 제한된 컴퓨팅 시스템이라면 모두 해당됩니다:
- 단일 GPU
- 로컬 모델 실행기
- CPU‑제한 워커
- 규모가 제한된 추론 플릿
수요가 급증하면 대부분의 시스템은 다음 두 가지 중 하나를 수행합니다:
- 모든 요청을 받아 내부에 누적시킵니다.
- 가장자리에서 도착을 제한합니다.
두 접근 방식 모두 실제 문제를 가립니다.
- 큐가 커집니다.
- 지연 시간이 늘어납니다.
- 재시도가 압력을 증폭시킵니다.
- 메모리 사용량이 예측 불가능해집니다.
- 과부하는 불투명해집니다.
실패를 바로 보지는 못하고, 느린 악화를 보게 됩니다.
The Missing Boundary
Rate limiting과 execution governance는 다릅니다.
- Rate limiting은 요청이 들어오는 속도를 제어합니다.
- Execution governance는 실행이 허용되는 요청 수를 제어합니다.
이 둘은 동일하지 않습니다. 속도를 제한하면서도 내부 큐를 무제한으로 만들 수 있습니다. 동시 실행에 대한 강제 상한을 두지 않으면 백엔드 자체가 큐가 되고, 급증 시 큐는 눈에 보이지 않는 부채가 됩니다.
A Different Approach: Explicit Yield
과부하를 버퍼링하는 대신 명시적인 응답으로 전환합니다. 용량이 가득 찼을 때:
- 큐에 넣지 않습니다.
- 차단하지 않습니다.
- 조용히 연기하지 않습니다.
다음과 같이 반환합니다:
status = yield
retry_hint_ms =
시스템은 경계가 유지되고, 클라이언트가 언제 재시도할지 결정하며, 과부하는 숨겨지는 것이 아니라 명시적으로 표시됩니다.
What This Looks Like
간단한 테스트 예시:
max_inflight = 1- 동시 클라이언트 20명
- 백엔드 실행 시간 = 10 초
관찰된 상태 전이:
t=44 inflight=1 executed_total=1 yielded_total=19
t=79 inflight=0 executed_total=1 yielded_total=19
해석
- Inflight은 1을 초과하지 않았습니다.
- 하나의 요청만 실행되었습니다.
- 19개는 즉시 yield되었습니다.
- 큐가 성장하지 않았습니다.
시스템은 성능 저하 없이 경계가 유지되었습니다.
Why This Matters for Inference Systems
추론 워크로드는 급증이 잦으며, 프롬프트는 부드러운 곡선이 아니라 클러스터 형태로 도착합니다:
- 사용자 새로고침 폭풍
- 재시도 루프
- 동시 UI 이벤트
- 로드밸런서 재배치
- 오토스케일러 지연
백엔드가 그 급증을 조용히 버퍼링하면, 나중에 꼬리 지연과 메모리 문제가 뒤따릅니다. 실행을 제한하고 yield를 반환함으로써 암묵적인 불안정성을 명시적인 역압력으로 교환하게 되며, 이는 거의 항상 가치 있는 선택입니다.
What This Is Not
이것은 다음이 아닙니다:
- 스케줄러
- 정책 엔진
- 공정성 시스템
- 게이트웨이
- 대시보드
- 분산 런타임
이는 좁은 원시 기능: 강제 동시성 상한 + 명시적 yield 입니다. 그 이상도 이하도 아닙니다.
A Small Tool, Intentionally
이 아이디어를 바탕으로 작은 인그레스 거버너를 만들었습니다. 이 도구는:
- TCP를 통해 줄바꿈으로 구분된 JSON 프레임을 수신
- 업로드 무결성을 검증
max_inflight를 강제- 포화 시 즉시
yield반환 - 최소 메트릭(
inflight,executed_total,yielded_total)을 노출
프롬프트를 검사하거나, 모델을 introspect 하거나, 토큰을 카운트하거나, 정책을 적용하지 않습니다. 단순히 실행 슬롯을 관리할 뿐입니다.
Why Not Just Use Nginx?
Rate limiting은 execution governance가 아닙니다. 초당 요청 수를 제한하면서도 백엔드에 무제한 동시 제출을 허용할 수 있습니다. 제한된 동시성 및 명시적 yield는 서로 다른 원시 기능이며, 동시에 존재할 수 있지만 해결하는 문제가 다릅니다.
The Core Idea
과부하를 버퍼링하는 것이 아니라 노출하는 것입니다. 용량이 가득 차면, 그렇게 말하십시오. yield를 반환하십시오. 경계를 유지합니다.