Articlehuggingface.co·2025년 7월 28일·2

Prefill and Decode for Concurrent Requests - Optimizing LLM Performance

Quick Summary

동시 요청을 처리하는 LLM 추론에서는 프리필과 디코드의 계산 특성이 달라, 첫 토큰 지연·토큰 생성 지연·총처리량·GPU 활용률 사이의 균형에 맞춰 배칭과 프리필 청크 크기를 조정해야 한다.

Prefill and Decode for Concurrent Requests - Optimizing LLM Performance 관련 대표 이미지

🖼️ 인포그래픽

Prefill and Decode for Concurrent Requests - Optimizing LLM Performance 내용을 설명하는 본문 이미지

🖼️ 4컷 인포그래픽

Prefill and Decode for Concurrent Requests - Optimizing LLM Performance의 핵심 내용을 4단계로 요약한 인포그래픽
Prefill and Decode for Concurrent Requests - Optimizing LLM Performance 핵심 내용을 4단계로 압축한 4컷 인포그래픽

💡 한 줄 요약

동시 요청을 처리하는 LLM 추론에서는 프리필과 디코드의 계산 특성이 달라, 첫 토큰 지연·토큰 생성 지연·총처리량·GPU 활용률 사이의 균형에 맞춰 배칭과 프리필 청크 크기를 조정해야 한다.

📌 핵심 요약

  • LLM 추론은 입력 프롬프트를 병렬 처리해 첫 출력 토큰을 만드는 프리필 단계와, 이후 토큰을 순차 생성하는 디코드 단계로 나뉜다.
  • 프리필 지연은 첫 토큰까지의 시간으로, 개별 디코드 지연은 출력 토큰당 시간으로 측정되며, 대화형 서비스에서는 두 지표를 모두 관리해야 한다.
  • 프리필은 GPU 연산 집약적이지만 개별 디코드는 주로 메모리 대역폭의 제약을 받으므로, 여러 디코드 요청을 배치하면 GPU 활용률과 총토큰 처리량을 높일 수 있다.
  • 정적 배칭은 디코드를 중단하지 않지만 가장 긴 요청이 끝날 때까지 신규 요청을 기다리게 하므로 자원 활용과 첫 토큰 지연 측면에서 비효율적이다.
  • 연속 배칭의 프리필 우선 전략은 신규 요청의 첫 토큰 지연을 줄이는 대신 기존 디코드를 방해하며, 청크 프리필은 청크 크기를 통해 첫 토큰 지연과 토큰당 지연의 균형을 조절한다.

🧩 주요 포인트

  1. LLM 추론은 입력 프롬프트를 병렬 처리해 첫 출력 토큰을 만드는 프리필 단계와, 이후 토큰을 순차 생성하는 디코드 단계로 나뉜다.
  2. 프리필 지연은 첫 토큰까지의 시간으로, 개별 디코드 지연은 출력 토큰당 시간으로 측정되며, 대화형 서비스에서는 두 지표를 모두 관리해야 한다.
  3. 프리필은 GPU 연산 집약적이지만 개별 디코드는 주로 메모리 대역폭의 제약을 받으므로, 여러 디코드 요청을 배치하면 GPU 활용률과 총토큰 처리량을 높일 수 있다.
  4. 정적 배칭은 디코드를 중단하지 않지만 가장 긴 요청이 끝날 때까지 신규 요청을 기다리게 하므로 자원 활용과 첫 토큰 지연 측면에서 비효율적이다.
  5. 연속 배칭의 프리필 우선 전략은 신규 요청의 첫 토큰 지연을 줄이는 대신 기존 디코드를 방해하며, 청크 프리필은 청크 크기를 통해 첫 토큰 지연과 토큰당 지연의 균형을 조절한다.

🧠 상세 정리

1. 다중 사용자 환경에서의 동시 처리 문제

이 글은 여러 사용자의 요청을 병렬로 처리할 때 LLM 추론 성능이 어떻게 달라지는지를 다룬다. 앞선 글이 사용자별 우선순위를 정하는 큐잉 전략에 집중했다면, 이번 글은 실제로 요청들을 동시에 실행하는 방식과 그 결과를 살핀다. 주요 평가 대상은 개별 요청의 지연 시간, 시스템 전체의 토큰 처리량, GPU 자원 활용률이다. TNG는 24개의 H100 GPU로 여러 대규모 언어 모델을 자체 호스팅하며, 50개 애플리케이션에서 시간당 5,000건이 넘는 추론과 하루 1,000만 개 이상의 토큰 생성을 처리한다고 설명한다. 이 운영 규모는 동시 요청 스케줄링이 단순한 이론 문제가 아니라 실제 서비스 용량과 사용자 경험을 좌우하는 문제임을 보여준다.

2. 자동회귀 생성과 프리필·디코드의 구분

대부분의 LLM은 앞서 나온 모든 토큰을 바탕으로 다음 토큰을 계산하는 자동회귀 방식으로 텍스트를 생성한다. 첫 출력 토큰은 전체 프롬프트에 의존하고, 두 번째 출력 토큰은 프롬프트와 첫 출력 토큰 모두에 의존하므로 한 요청 안에서 출력 토큰 생성을 병렬화할 수 없다. 어텐션 계산에서는 이전 토큰들의 키·값·쿼리 벡터가 필요하지만, 키와 값 계산 결과는 KV 캐시에 저장해 이후 단계에서 재사용할 수 있다. 처음에는 캐시가 비어 있어 모든 입력 토큰의 키와 값을 계산해야 하지만, 입력 토큰은 처음부터 전부 알려져 있으므로 이 계산을 병렬로 수행할 수 있다. 이처럼 첫 출력 토큰을 만드는 병렬 처리 구간이 프리필이고, 그 뒤 KV 캐시에 한 토큰씩 추가하며 순차 처리하는 구간이 디코드다.

3. 첫 토큰 시간과 출력 토큰당 시간

프리필과 디코드의 차이는 첫 토큰까지의 시간과 출력 토큰당 시간이라는 두 핵심 지표로 나타난다. 첫 토큰까지의 시간은 프리필 단계의 지연이고, 출력 토큰당 시간은 한 번의 디코드 단계에 걸리는 지연이다. 프리필도 결과적으로 출력 토큰 하나를 만들지만 전체 입력 프롬프트를 처리해야 하므로 단일 디코드보다 오래 걸린다. 다만 입력 토큰들을 병렬로 처리할 수 있기 때문에, 같은 수의 토큰을 디코드로 순차 생성하는 것보다는 토큰 수 대비 빠르며 글은 상용 API에서 입력 토큰 가격이 출력 토큰 가격보다 낮은 이유를 이 차이와 연결한다. 추론 백엔드의 요청 도착 시각과 스트리밍 출력의 토큰별 생성 시각을 기록하면 두 지연 지표를 실제로 측정할 수 있다.

4. 대화형 지연 목표와 총토큰 처리량

챗봇과 같은 대화형 애플리케이션에서는 첫 토큰 지연과 출력 토큰당 지연이 모두 사용자 경험에 직접 영향을 준다. 사용자가 응답을 5초 넘게 보지 못하면 서비스가 고장 났다고 생각해 이탈할 수 있고, 초당 1토큰 정도로만 생성되면 완료될 때까지 기다리기 어렵다. 글에서 제시한 일반적인 목표는 출력 토큰당 100~300밀리초, 즉 초당 3~10토큰이며 첫 토큰까지의 시간은 3초 이하다. 그러나 이 목표는 모델 크기, 하드웨어, 프롬프트 길이, 동시 부하에 따라 달성하기 어려울 수 있다. 반면 도서 번역이나 대규모 코드 저장소 요약처럼 비대화형 작업은 개별 지연보다 모든 동시 요청에서 합산한 초당 토큰 처리량이 더 중요하며, 전체 처리량 극대화와 개별 요청 지연 최소화 사이에는 일반적으로 상충 관계가 있다.

5. 프리필과 디코드의 GPU 자원 특성

프리필은 모든 입력 토큰을 병렬 계산하므로 GPU의 연산 능력을 강하게 사용하는 단계다. 반면 요청 하나의 디코드는 출력 토큰 하나만 처리해 계산 능력을 적게 사용하며, 모델 가중치와 활성값 및 키·값 벡터를 GPU 메모리에서 얼마나 빠르게 불러오는지가 속도를 제한하는 경우가 많다. 따라서 프리필은 긴 프롬프트 하나만으로도 최대 GPU 활용률에 도달할 수 있지만, 디코드는 여러 요청을 배치 처리해야 활용률을 높일 수 있다. 동시 요청 수가 적은 메모리 대역폭 제한 구간에서는 배치가 커질수록 총토큰 처리량이 거의 선형으로 증가한다. 이후 GPU 연산 능력이 포화되어 연산 제한 구간에 들어가면 동시성을 더 높여도 처리량은 거의 증가하지 않으며, 짧은 프롬프트는 프리필의 연산 활용률이 낮아 더 높은 요청률에서 포화된다.

6. 정적 배칭의 동작과 한계

정적 배칭은 빈 배치에 대기 중인 요청을 가능한 만큼 채우고, 배치에 포함된 모든 요청이 끝날 때까지 처리한 뒤에야 다음 배치를 구성하는 방식이다. 같은 배치의 요청들은 프리필을 함께 시작하고, 병렬화된 하나의 큰 GPU 연산으로 프리필을 마친 후 디코드도 동시에 시작한다. 출력이 짧은 요청은 먼저 완료될 수 있지만 다음 대기 요청은 해당 배치에서 출력이 가장 긴 요청까지 끝나야 시작할 수 있다. 이 방식은 디코드가 도중에 방해받지 않으므로 출력 토큰당 시간을 최적화하지만, 프리필에서는 여러 요청을 함께 실행해도 긴 프롬프트 하나가 이미 연산 능력을 포화시킬 수 있고 디코드에서는 GPU가 충분히 활용되지 않을 수 있다. 무엇보다 짧은 요청이 일찍 끝나도 빈 자리를 즉시 채우지 못해 신규 요청의 첫 토큰 지연이 크게 늘어나는 것이 가장 큰 단점이다.

7. 연속 배칭과 프리필 우선 전략

연속 배칭은 완료된 요청을 즉시 배치에서 제거하고 그 자리에 대기 중인 다음 요청을 넣어 정적 배칭의 유휴 공간과 긴 대기 시간을 줄인다. 이 구조에서는 새 요청의 프리필과 기존 요청의 디코드가 동시에 존재하므로 두 단계 사이의 스케줄링이 필수적이다. vLLM과 TGI가 사용하는 프리필 우선 방식은 신규 요청이 도착하고 현재 배치에 들어갈 수 있으면 가능한 한 빨리 프리필을 실행한다. 새 프리필과 기존 요청들의 디코드 한 단계를 같은 GPU 연산에 포함할 수 있지만, 실행 시간은 훨씬 무거운 프리필에 의해 결정되며 기존 요청은 그동안 각각 출력 토큰 하나만 생성한다. 결과적으로 신규 요청의 첫 토큰 지연은 최소화되지만, 다른 사용자가 긴 프롬프트를 제출할 때 이미 진행 중이던 스트리밍 출력이 일시 정지하는 것처럼 보일 수 있다.

8. 청크 프리필을 통한 지연 균형 조정

청크 프리필은 긴 프롬프트 전체를 한 번에 처리하지 않고 여러 조각으로 나누어 프리필 우선 전략이 기존 디코드를 장시간 막는 문제를 완화한다. 프리필이 여러 청크로 나뉘면 다른 요청들은 전체 프리필 동안 토큰 하나만 생성하는 대신 각 청크마다 디코드 한 단계를 실행해 출력 토큰을 하나씩 만들 수 있다. 청크 하나도 독립적인 디코드보다는 오래 걸리지만, 청크가 작으면 사용자는 스트리밍이 완전히 멈추는 대신 생성 속도가 느려지는 형태로 체감하며 평균 출력 토큰당 시간도 줄어든다. 반대로 프리필 요청에는 분할 처리의 오버헤드가 생겨 연속된 단일 프리필보다 첫 토큰까지의 시간이 조금 늘어난다. 따라서 청크 크기는 첫 토큰 지연과 출력 토큰당 지연 중 무엇을 우선할지 조절하는 수단이며, 글은 일반적인 크기로 512~8192토큰을 제시하고 청크 프리필의 가장 큰 장점으로 자원 효율 극대화를 꼽는다.

🧾 핵심 주장 / 시사점

  • 동시 요청 수를 늘리는 것만으로 처리량이 계속 증가하지는 않으며, 메모리 대역폭 제한 구간을 지나 GPU 연산 능력이 포화되면 추가 동시성의 처리량 이득이 사라진다.
  • 신규 요청의 첫 토큰을 빠르게 만드는 프리필 우선 정책은 이미 응답을 받고 있는 사용자의 스트리밍을 방해하므로, 첫 토큰 지연 개선이 곧 전체 사용자 경험 개선을 의미하지는 않는다.
  • 청크 프리필의 청크 크기는 신규 요청의 첫 토큰 지연, 기존 요청의 출력 토큰당 지연, GPU 자원 효율 사이의 우선순위를 조절하는 핵심 설정값이다.

✅ 액션 아이템

  • 프리필 지연(첫 토큰까지 시간)과 개별 디코드 지연(토큰당 시간)을 동일 로그 규격으로 수집해 대화형 응답 품질을 함께 관리한다.
  • 정적 배칭과 연속 배칭을 동일 부하 조건에서 분리 측정해 첫 토큰 지연, 토큰당 지연, 총처리량의 트레이드오프를 수치로 비교한다.
  • 청크 프리필 크기를 단계별로 변경하며 GPU 활용률·첫 토큰 지연·토큰당 지연의 균형이 맞는 구간을 찾아 운영 기준을 정한다.

❓ 열린 질문

  • 청크 프리필 크기를 늘리면 어느 지점에서 첫 토큰 지연 감소 효과가 토큰당 지연 증가에 밀리는가?
  • 정적 배칭에서 가장 긴 요청 완료 대기 때문에 전체 처리량이 떨어질 때 어느 구간부터 비용이 급증하는가?
  • GPU 연산 병목인 프리필과 메모리 대역폭 병목인 디코드를 구분해 배칭 정책을 언제 전환하는 기준을 둘 것인가?

관련 문서

공통 태그와 주제 흐름을 기준으로 같이 보면 좋은 문서를 이어서 제안합니다.