프로토타입의 환상과 TTFT·ITL 측정

소수 사용자가 짧은 질문을 던지는 프로토타입 단계에서는 성능 이슈가 드러나지 않지만, 실제 서비스 출시 후에는 상황이 바뀐다. 트래픽이 몰려 요청이 큐에 쌓이고, RAG(검색 증강 생성) 파이프라인이 매 요청마다 방대한 컨텍스트를 추가하며, 에이전트가 도구를 여러 번 호출하면서 지연 시간이 누적된다. 특히 초기 설정에서 관대하게 잡은 출력 토큰 제한은 비용과 지연 시간을 높이는 주범이 된다. 이때 무작정 모델 체급을 올리거나 GPU를 증설하는 것은 비효율적이다. 최적화의 핵심은 불필요한 토큰 생성과 중복 호출을 줄여 모델의 연산량을 최소화하는 것이다.

정확한 병목 지점을 찾으려면 전체 응답 시간 대신 TTFT와 ITL을 측정해야 한다. TTFT(Time to First Token, 첫 토큰 생성 시간)는 요청 후 첫 글자가 나타날 때까지의 시간이다. TTFT가 길다면 프롬프트가 너무 길거나, 검색 단계의 지연, 혹은 요청 큐의 대기 시간이 원인이다. 반면 ITL(Inter-token Latency, 토큰 간 생성 시간)은 첫 토큰 이후 다음 토큰들이 생성되는 간격이다. ITL이 높다면 모델 크기가 너무 크거나 GPU 부하가 심한 상태, 또는 배칭 설정 오류나 메모리 압박이 원인일 가능성이 크다.

이 두 지표를 분리하지 않으면 엉뚱한 곳을 최적화하게 된다. TTFT가 문제일 때 모델 추론 속도를 높이려 양자화를 적용하는 것은 해결책이 되지 않으며, 프롬프트를 줄이거나 검색 효율을 높이는 것이 우선이다. 반대로 ITL이 문제라면 모델 크기를 줄이거나 서빙 스택의 배칭 설정을 조정해야 한다. GPU 증설 전 TTFT와 ITL 중 어디에 병목이 있는지 수치로 확인하는 것이 비용 효율적인 최적화의 시작이다.

출력 토큰 제한과 모델 라우팅 설계

모델은 토큰을 순차적으로 생성하므로 응답 길이가 두 배가 되면 생성 시간과 비용도 거의 두 배로 늘어난다. 따라서 내부 지원 어시스턴트의 경우 700단어의 설명 대신 세 개의 불렛 포인트와 소스 링크만 제공하도록 제약 조건을 설정해 불필요한 생성을 막아야 한다. 사용자가 읽지 않을 토큰에 비용을 지불하지 않는 것이 최적화의 기본이다.

단순 반복이나 구조적 작업은 작은 모델로도 충분한 품질을 낼 수 있다. 텍스트 분류, 데이터 추출, 정해진 형식의 요약 같은 작업은 프롬프트 길이, 작업 유형, 사용자 등급, 모델 신뢰도 등을 기준으로 호출 모델을 나누는 모델 라우팅 기법을 적용한다. 가벼운 분류기를 앞에 두어 작업 난이도를 먼저 판단하면 고성능 모델이 모든 요청을 처리하는 낭비를 막고 자원을 효율적으로 배분할 수 있다.

에이전트가 계획 수립, 도구 선택, 결과 요약을 각각 별도의 모델 호출로 처리하면 지연 시간이 누적된다. 이를 하나의 프롬프트와 구조화된 출력 형식으로 통합하면 호출 횟수를 줄이고 에러 발생 가능성을 낮출 수 있다. 또한 단순한 조건문이나 정규 표현식으로 해결 가능한 작업은 LLM 대신 일반 코드로 처리하는 결정론적 코드 활용이 필요하다. 검색, 분류, 배경 정보 보강 같은 독립적인 작업은 병렬로 동시에 실행해 전체 대기 시간을 줄인다.

프롬프트 캐싱과 다층 캐시 전략 비교

매 요청마다 수천 토큰의 시스템 프롬프트를 다시 읽게 하는 것은 비용 낭비다. 프롬프트 캐싱(Prompt Caching)은 모든 요청에 공통으로 포함되는 고정 콘텐츠를 프롬프트 앞부분에 배치해 중복 연산을 줄이는 기법이다. 시스템 지침이나 퓨샷 예시 같은 고정 데이터를 최상단에 두고, 사용자의 질문 같은 가변 데이터를 가장 뒤에 배치해야 한다. 가변 데이터가 앞에 위치하면 그 뒤의 고정 콘텐츠 캐시가 무효화되어 매번 전체 토큰을 다시 계산해야 하기 때문이다.

응답 자체를 저장하는 다층 캐시 전략도 필요하다. Exact Cache는 완전히 동일한 요청에 대해 동일한 응답을 저장하는 방식으로, 환불 규정 안내처럼 정답이 고정된 질문에 효과적이다. 이때는 TTL(Time-to-Live, 데이터 유효 기간) 설정과 버전 관리가 필수다. Semantic Cache는 질문의 문구는 다르지만 의미가 유사한 경우 기존 응답을 재사용한다. 비밀번호 변경 방법과 패스워드 재설정 안내를 같은 의도로 인식해 처리하는 식이다. 이 방식은 반복적인 정보 요청이 많은 환경에서 유용하며, 엉뚱한 답변을 막기 위해 엄격한 유사도 임계값과 사용자별 데이터 격리를 수행해야 한다.

마지막으로 LLM 처리 전 단계의 중간 데이터를 저장하는 Data Cache를 도입한다. 임베딩 값, 검색 결과, 리랭킹 결과, API 출력값처럼 결과가 일정하게 나오는 데이터를 저장해 모델의 연산량을 줄인다. 에이전트가 사용하는 도구가 매번 동일한 데이터베이스 쿼리를 수행한다면 이를 저장해 재사용하는 것이 훨씬 빠르다. 최신 데이터 업데이트 주기에 맞춰 API 출력값이나 제품 조회 결과를 캐싱하면, 모델이 이미 시스템이 알고 있는 정보를 다시 처리하느라 토큰을 소비하는 낭비를 막을 수 있다.

RAG 컨텍스트 예산과 인프라 최적화

검색 단계에서 수십 개의 문서 조각을 그대로 프롬프트에 넣으면 처리 비용이 급증하고 생성 속도가 느려지며, 모델이 불필요한 정보 사이에서 정확도가 떨어진다. 이를 해결하기 위해 컨텍스트 예산(Context Budget, 모델에 제공할 최대 정보량)을 엄격히 설정하고 리랭킹을 통해 정제된 핵심 정보만 제공해야 한다. 즉각적인 응답이 필요 없는 데이터 요약이나 배경 정보 보강 작업은 실시간 경로에서 제외해 하위 우선순위 큐나 배치 API로 분리 처리함으로써 인터랙티브한 응답 속도를 보호한다.

GPU 메모리 부족 문제는 KV 캐시(Key-Value Cache) 관리 방식에서 결정된다. 컨텍스트 윈도우 크기와 동시 요청 수를 제한하지 않으면 메모리 압박으로 큐 대기 시간이 길어진다. Paged KV 캐시처럼 메모리를 조각내어 효율적으로 할당하는 시스템을 도입하거나 양자화를 통해 메모리 점유율을 낮춘다. 또한 모델이 지원하는 최대 컨텍스트 길이를 그대로 노출하지 않고 서비스 목적에 맞는 상한선을 두어 메모리 낭비를 막는다. 배칭 튜닝은 GPU 이용률을 높이는 것이 아니라 SLO(Service Level Objective)를 충족하는 적정 배치 크기를 찾는 과정이다. 과도한 배칭은 전체 처리량은 높일 수 있으나 첫 토큰 생성 시간을 늦춰 체감 속도를 떨어뜨린다.

자체 서빙 스택에서는 작은 모델이 먼저 토큰을 예측하고 큰 모델이 검증하는 투기적 디코딩(Speculative Decoding)과 모델 가중치를 여러 GPU에 나누어 처리하는 텐서 병렬 처리(Tensor Parallelism)를 적용해 효율을 높인다. 가중치 정밀도를 낮춰 메모리 사용량을 줄이는 양자화(Quantization) 역시 핵심 수단이다. 다만 이러한 기능들은 환경에 따라 통신 오버헤드를 발생시켜 지연 시간을 늘릴 수 있으므로, 실제 운영 트래픽을 반영한 벤치마크를 통해 득실을 검증해야 한다.

P95 지연시간 중심의 실무 판단 기준

서버 관리자가 GPU 점유율이 낮다고 판단해도 사용자는 10초 넘게 기다리는 경우가 발생한다. 이때 필요한 지표가 P95와 P99 지연시간이다. P95는 전체 요청 중 하위 5%를 제외한 95%의 사용자가 경험하는 최대 지연시간을 뜻한다. 평균값은 소수의 극단적인 지연 사례를 가리기 때문에, 실무에서는 프로덕션 트래픽 기반의 P95와 P99 지연시간을 기준으로 서비스 가용성을 판단해야 한다.

트래픽 급증 시 시스템 마비를 막으려면 속도 제한(Rate Limiting) 장치를 먼저 배치해 큐 대기 시간이 무한정 늘어나는 것을 방지해야 한다. 부하가 임계치를 넘었을 때는 점진적 기능 저하(Graceful Degradation) 전략을 쓴다. 응답 길이를 평소보다 짧게 제한해 출력 토큰을 아끼거나, 고성능 모델 대신 가벼운 소형 모델로 자동 전환해 응답을 유지하는 방법이다. 모든 요청에 완벽한 답을 주려다 서비스 전체가 마비되는 것보다 일부 기능을 낮춰서라도 응답을 주는 것이 사용자 경험 측면에서 유리하다.

비용과 속도를 잡기 위한 최적화는 다음 순서로 접근한다. 먼저 출력 토큰 수를 줄여 생성 시간을 단축하고, 불필요한 모델 호출 횟수를 축소한다. 이후 프롬프트 캐싱을 적용해 중복 계산을 없애고, 마지막으로 컨텍스트 크기를 제어한다. 이 순서를 지키지 않고 무작정 GPU를 늘리면 데이터 처리 병목은 그대로 둔 채 비용만 증가한다. 모델을 더 좋은 것으로 바꾸는 것은 모든 최적화 단계를 거친 후 선택하는 마지막 수단이어야 한다. 인프라 확장 전 이 네 가지 단계를 점검하고 P95 수치 변화를 확인하는 것이 실무적인 최적화 기준이다.

프로토타입의 쾌적한 속도는 실제 사용자가 유입되는 순간 API 비용 급증과 지연 시간이라는 현실로 바뀐다. LLM 최적화의 본질은 더 성능 좋은 모델을 선택하는 것이 아니라, 불필요한 토큰 생성과 중복 호출을 줄여 모델이 할 일을 최소화하는 설계에 있다.

GPU 증설이라는 비용 중심의 해결책 대신 TTFT와 ITL 측정값과 프롬프트 캐싱 구조를 먼저 살펴야 한다. 본문에서 다룬 12가지 최적화 체크리스트를 기준으로 현재의 워크플로를 점검하는 것이 가장 빠르게 비용을 낮추고 속도를 높이는 실무적인 방법이다.