AI 모델 배포 비용을 낮추는 두 가지 기술: Quantization과 Prefix Caching
- 5월 7일
- 9분 분량
최종 수정일: 5월 13일

안녕하세요. AIEEV Dev Team의 김진범입니다.
저는 학부와 대학원에서 컴퓨터공학을 전공하고 AIEEV 창업 초기부터 함께하며 Air Cloud에 더 많은 분산 자원이 효율적으로 운영될 수 있도록 기여하고 있습니다
연구생 시절에는 AI 서비스의 성능 향상을 위한 이론적 연구와 실험을 많이 진행했습니다. 하지만 실제 서비스를 운영하다 보니, 좋은 모델과 높은 성능만으로는 충분하지 않다는 것을 알게 되었으며, 중요한 것은 AI 서비스를 사용자가 실제로 사용할 수 있을 만큼 빠르고, 비용 측면에서도 지속 가능하며, 안정적으로 제공할 수 있느냐였습니다.
저희 팀도 분산 GPU 환경에서 서비스를 운영하며 이 문제를 계속 마주해왔습니다. 더 큰 모델을 안정적으로 배포하고, 더 많은 요청을 처리하면서도 응답 지연시간을 일정하게 유지하려면 추론 단계의 최적화가 필요합니다. 모델 크기가 커질수록 GPU 메모리 사용량은 자연스럽게 증가합니다. 여기에 긴 시스템 프롬프트나 많은 입력 토큰이 더해지면, GPU 자원 사용량과 응답 지연시간도 함께 늘어날 수 있습니다. 요청이 적을 때는 이런 차이가 크게 드러나지 않지만, 트래픽이 쌓이기 시작하면 운영 비용과 서비스 안정성에 직접적인 영향을 주게 됩니다.
이번 글에서는 LLM 서비스의 운영 비용과 응답 지연시간을 줄이는 데 활용할 수 있는 두 가지 기술을 소개하려 합니다.
하나는 양자화(Quantization)입니다. 모델 가중치를 중심으로, 방식에 따라 활성값이나 KV 캐시까지 더 낮은 정밀도로 표현해 메모리 사용량과 메모리 대역폭 부담을 줄이는 방법입니다.
다른 하나는 프리픽스 캐싱(Prefix Caching)입니다. 여러 요청에서 공통으로 사용되는 프롬프트 앞부분의 계산 결과를 재사용해, 같은 입력 구간을 반복해서 처리하지 않도록 하는 방법입니다.
LLM 추론 요청 처리 과정에서 발생하는 비용
두 기술을 자세히 살펴 보기 전에, LLM 요청이 처리되는 동안 어디서 리소스가 쓰이는지부터 살펴보겠습니다. 크게 세 구간으로 나눌 수 있습니다.
모델을 GPU 메모리에 올려두는 비용
입력 프롬프트를 읽고 내부 상태(KV 캐시)를 만드는 프리필(Prefill) 비용
다음 토큰을 하나씩 생성하는 디코드(Decode) 비용
여기서 양자화와 프리픽스 캐싱이 최적화하는 구간이 다릅니다. 양자화는 주로 모델 가중치가 차지하는 메모리 점유율을 줄입니다. 또한 디코드 단계가 메모리 대역폭의 영향을 크게 받는 환경에서는 처리량 개선으로 이어질 수 있습니다. 토큰을 생성할 때마다 모델 가중치와 KV 캐시에 반복적으로 접근해야 하므로, 낮은 정밀도 표현을 사용하면 GPU 메모리에서 읽고 유지해야 하는 데이터 양을 줄일 수 있습니다.
프리픽스 캐싱은 프리필 단계의 반복 계산을 줄입니다. 공통된 프리픽스를 공유하는 요청에서 이미 계산된 KV 캐시를 재사용해, 같은 입력 구간을 다시 처리하지 않도록 하는 방식입니다.
최적화가 없다면 어디서 낭비가 생길까
최적화를 적용하지 않으면 모델 가중치는 양자화되지 않은 정밀도 그대로 GPU에 올라가고, 동일한 프리픽스를 공유하는 요청이 들어오더라도 입력 구간을 매번 다시 계산해야 합니다. 모델이 커질수록 GPU 메모리 사용량도 대체로 함께 늘어납니다. 더 큰 모델을 안정적으로 올리려면 더 많은 GPU 메모리가 필요하고, 같은 GPU 안에서 동시에 처리할 수 있는 요청 수에도 제약이 생길 수 있습니다.
입력 처리도 마찬가지입니다. 시스템 프롬프트, 도구 정의, 출력 형식, 프로젝트의 지침, 반복되는 문서처럼 여러 요청에서 공통으로 사용되는 내용이 있더라도, 별도의 캐싱이 없다면 매번 프리필 연산을 다시 수행해야 합니다. 사용자 입장에서는 매번 다른 요청을 보내는 것처럼 보일 수 있습니다. 하지만 서버 입장에서는 같은 시스템 프롬프트와 도구 정의 등을 반복해서 처리하고 있는 셈입니다.
요청이 적을 때는 이런 반복 계산이 크게 드러나지 않을 수 있습니다. 하지만 서비스 트래픽이 증가하면 동일한 GPU 자원으로 안정적인 처리량과 지연시간을 유지하기 어려워질 수 있습니다. 여기에 매 요청마다 반복되는 입력 계산이 더해지면 프리필 시간이 늘어나고, 첫 토큰이 생성되기까지의 지연시간에도 영향을 줄 수 있습니다. 결국 AI 서비스를 안정적으로 운영하는 일은 단순히 더 큰 GPU로 scale-up하는 문제만으로 볼 수 없습니다. 모델이 차지하는 메모리를 줄이고, 재사용 가능한 데이터의 연산을 줄이는 방식까지 함께 고려해야 합니다.
이제 두 기술이 실제로 어떻게 동작하는지 하나씩 살펴보겠습니다.
Quantization: 같은 모델을 더 작은 숫자로 표현하기
LLM은 내부적으로 수많은 행렬 연산으로 동작합니다. 모델 가중치와 추론 과정에서 만들어지는 중간 계산값은 모두 숫자로 표현되고, 이 숫자들이 GPU 메모리 위에서 계속 읽히고 계산됩니다. 충분한 GPU 자원이 있다면 모든 값을 높은 정밀도로 다루는 것이 모델 품질을 보존하는 데 유리할 수 있습니다. 하지만 실제로는 대부분의 환경에서는 자원(GPU 메모리와 메모리 대역폭)이 한정되어 있기 때문에, 높은 정밀도를 그대로 유지할수록 더 많은 리소스를 사용하게 됩니다.
양자화는 이러한 숫자를 더 낮은 정밀도로 근사해, 같은 모델을 더 적은 메모리와 대역폭으로 다룰 수 있게 하는 방법입니다. 아래 그림은 이 개념을 단순화해 보여줍니다.

그림은 FP32처럼 부동소수점으로 표현된 높은 정밀도 값을 INT4 같은 정수형 저정밀 값으로 근사하는 과정을 보여줍니다. 낮은 정밀도로 표현할수록 저장하고 읽어야 하는 데이터 양은 줄어들지만, 여러 값이 하나의 가까운 값으로 매핑될 수 있기 때문에 배포 전 품질 검증이 필요합니다.
실제 LLM 배포에서는 모델과 양자화 방식에 따라 사용하는 표현 형식이 달라질 수 있습니다. 예를 들어 기존 모델이 FP16이나 BF16 형태의 가중치를 사용하고 있었다면, 양자화 이후에는 일부 가중치를 INT8, INT4, FP8 같은 더 낮은 정밀도 형식으로 표현할 수 있습니다.
데이터 타입 | 비트 수 | FP16/BF16 기준 이론상 크기 |
FP32 | 32 | 2.0x |
FP16 / BF16 | 16 | 1.0x |
FP8 | 8 | 0.5x |
INT8 | 8 | 0.5x |
INT4 | 4 | 0.25x |
여기서 중요한 점은 이 값이 “단순 저장 크기 기준의 이론값”이라는 것입니다.
비트 수만 보면 FP16/BF16 가중치를 INT8로 바꾸면 절반, INT4로 바꾸면 1/4 수준까지 줄어드는 것처럼 보입니다. 하지만 실제 배포 환경에서는 스케일 정보, 패킹 포맷, 정렬을 위한 패딩, KV 캐시, 활성값, 임시 버퍼가 함께 메모리를 사용합니다. 그래서 전체 GPU 메모리 절감 폭이 이론상 비율과 항상 일치하지는 않습니다.
또한 양자화를 적용한다고 해서 모델의 레이어 수나 attention 구조 같은 전체 아키텍처가 바뀌는 것도 아닙니다. 같은 모델 구조를 유지하되, 가중치와 일부 계산값을 저장하고 처리하는 숫자의 표현 방식이 바뀌는 것입니다.
다만 실제 구현은 단순히 FP16 값을 INT8이나 INT4로 형 변환하는 작업이 아닙니다. 낮은 정밀도의 값을 계산에 사용하려면 스케일링 방식, 그룹 또는 블록 단위 양자화, 패킹 포맷, 전용 커널 같은 요소가 함께 맞아야 합니다. 대부분의 추론 엔진은 이러한 세부 구현을 추상화해 제공하지만, 실제 적용 시에는 양자화된 모델 형식이 사용하는 추론 엔진과 GPU 환경에서 잘 지원되는지 확인해야 합니다.
왜 리소스 사용량이 줄어드는가
크게 두 가지 효과를 기대할 수 있습니다.
첫째, GPU 메모리 사용량이 줄어듭니다. 모델 가중치가 차지하는 메모리가 작아지면 같은 GPU에서 더 여유 있게 모델을 올릴 수 있고, 더 큰 배치나 더 높은 동시 처리량을 검토할 여지도 생깁니다.
둘째, 메모리 대역폭 부담이 줄어들 수 있습니다. LLM 추론의 디코드 단계에서는 새 토큰을 생성할 때마다 모델 가중치와 KV 캐시에 반복적으로 접근합니다. 이 구간이 메모리 대역폭의 영향을 크게 받는 환경이라면, 가중치 표현을 줄이는 것만으로도 GPU 메모리에서 읽어야 하는 데이터 양을 줄일 수 있습니다. 따라서 조건이 맞으면 처리량 개선으로 이어질 수 있습니다.
다만 가중치 크기가 줄어든 비율만큼 전체 GPU 메모리 사용량이나 처리량이 그대로 개선되는 것은 아닙니다. 추론 중에는 가중치뿐만 아니라 KV 캐시, 활성값, 실행 중 필요한 임시 버퍼도 함께 메모리를 사용합니다. 또한 양자화 방식에 따라 필요한 부가 정보가 생길 수 있고, 낮은 정밀도의 값을 실제 계산에 맞게 변환하는 과정도 추가될 수 있습니다. 이 때문에 실제 메모리 절감 효과와 처리량 개선 폭은 모델 구조와 추론 설정에 따라 달라질 수 있습니다.
주의할 점
양자화는 GPU 메모리 사용량을 줄이는 데 도움이 되지만, 배포 전 반드시 서비스 품질에 대한 검증이 필요합니다. 정밀도를 낮춘다는 것은 원래 값을 더 적은 비트로 근사한다는 뜻이고, 이 과정에서 모델 품질이 일부 떨어질 수 있습니다.
또한 양자화 방식이 실제 성능 개선으로 이어지려면, 사용하는 GPU와 추론 엔진에서 해당 방식이 잘 지원되는지도 확인해야 합니다. 같은 INT4나 FP8이라고 해도 하드웨어 세대, 추론 엔진, 커널 구현에 따라 지원 범위가 달라질 수 있습니다. 지원되는 방식이라도 실제 처리량과 지연시간은 모델 구조, 배치 크기, 입력·출력 길이, GPU 설정에 따라 달라질 수 있습니다.

위 그림은 vLLM에서 제공하는 양자화 구현별 하드웨어 지원 범위입니다. 표의 세부 항목을 모두 이해할 필요는 없지만, 중요한 것은 양자화 방식마다 지원되는 하드웨어와 커널이 다를 수 있다는 점입니다.
따라서 FP8, INT8, INT4처럼 표현 형식만 보고 선택하기보다는, 적용하려는 모델 형식, 양자화 방식, GPU 세대, 추론 엔진의 지원 여부를 함께 확인해야 합니다. 메모리가 부족하다고 곧바로 가장 낮은 비트로 내리기보다는, 한 단계씩 낮춰가며 검증하는 편이 안전합니다. 각 단계에서 모델 품질을 확인하고, 같은 GPU 환경에서 처리량과 지연시간이 실제로 개선되는지도 함께 봐야 합니다. 결국 양자화의 목표는 모델 품질을 유지할 수 있는 범위 안에서 GPU 메모리 사용량과 요청당 리소스 사용량을 줄이는 데 있다고 볼 수 있습니다.
Prefix Caching: 반복되는 프롬프트 앞부분 재사용하기
양자화가 모델 자체를 더 작은 숫자로 표현해 GPU 메모리와 메모리 대역폭 부담을 줄이는 방법이라면, 프리픽스 캐싱(Prefix Caching)은 요청 처리 과정에서 반복되는 입력 구간의 계산을 줄이는 방법입니다. LLM 서비스의 프롬프트는 보통 크게 두 영역으로 나눌 수 있습니다. 하나는 여러 요청에서 반복되는 고정 영역이고, 다른 하나는 요청마다 달라지는 변동 영역입니다.
예를 들어 다음과 같은 두 요청을 생각해볼 수 있습니다.
요청 1:
[당신은 시스템 소프트웨어에 능통한 전문가입니다. 모든 답변은 한국어로 작성하세요.]
+
[Linux OS의 구조와 동작 원리를 시스템 소프트웨어 관점에서 설명해주세요.]
요청 2:
[당신은 시스템 소프트웨어에 능통한 전문가입니다. 모든 답변은 한국어로 작성하세요.]
+
[블록체인이 무엇인지 쉽게 설명해주세요.]
두 요청의 입력 데이터를 자세히 살펴보면, 앞부분의 시스템 프롬프트는 완전히 동일하고, 뒤쪽의 사용자의 질문만 차이가 있음을 확인할 수 있습니다.
프리픽스 캐싱이 없다면 모델은 두 요청 모두에서
당신은 시스템 소프트웨어에 능통한 전문가입니다. 모든 답변은 한국어로 작성하세요. 라는 동일한 시스템 프롬프트를 매번 다시 계산해야 할 것입니다. 이는 요청 수가 적을 때는 큰 문제가 아닐 수 있지만, 앞서 언급한 것처럼 보다 긴 시스템 프롬프트, 많은 도구 정의 등이 반복되는 상황에서 요청 수가 증가할 경우에는 중복 연산으로 인한 오버헤드는 무시하기 어려워질 수 있습니다.
여기서 반복되는 프롬프트의 앞부분을 공통 프리픽스를 가진다고 볼 수 있습니다. 프리픽스 캐싱은 이 공통 프리픽스에 대한 계산 결과를 저장해두고, 이후 같은 토큰 시퀀스로 시작하는 요청이 들어오면 해당 구간을 다시 계산하지 않고 재사용하는 방식입니다. vLLM의 Automatic Prefix Caching(APC)도 같은 방향의 최적화입니다. 기존 요청에서 만들어진 KV 캐시를 보관해두었다가, 새 요청이 이전 요청과 같은 프리픽스를 공유하면 해당 구간의 KV 캐시를 재사용해 공통되는 구간의 프리필 계산을 건너뜁니다.
Prefix Caching은 어떻게 동작하나

위 그림처럼, LLM은 입력 토큰을 처리하면서 각 레이어에서 attention 연산에 필요한 key/value 텐서를 만듭니다. 이 값들은 이후 다음 토큰을 생성할 때 다시 참조되며, 이를 일반적으로 KV 캐시라고 부릅니다. 추론 과정은 앞에서 살펴본 것처럼 크게 프리필(Prefill)과 디코드(Decode)로 나눌 수 있습니다.
프리필 단계에서는 입력 프롬프트를 처리하면서 각 토큰에 대한 KV 캐시가 만들어집니다. 이후 디코드 단계에서는 새 토큰을 하나씩 생성하면서 이전 토큰들의 KV 캐시를 참조하고, 새로 생성된 토큰의 key/value도 캐시에 추가합니다.
프리픽스 캐싱은 이 중 프리필 단계에서 반복되는 프리픽스의 KV 캐시를 재사용하는 최적화 방법입니다. 첫 번째 요청에서 프리필 연산 이후 KV 캐시가 만들어지면, 추론 엔진은 이를 캐시로 보관할 수 있습니다. 이후 동일한 프리픽스로 시작하는 요청이 들어오면 이미 계산된 구간은 재사용하고, 아직 계산되지 않은 뒤쪽 입력만 새롭게 처리합니다.
이 방식은 특히 “긴 공통 입력 + 짧은 사용자 요청” 구조를 가지는 요청을 처리하는 상황에서의 효과가 빛을 발합니다. AI Agent를 예로 들면, Claude Code의 CLAUDE.md나 Codex의 AGENTS.md처럼 프로젝트 규칙, 빌드 방법, 테스트 명령어, 코드 스타일, 리뷰 기준을 담은 지침 파일이 작업 컨텍스트에 반복적으로 포함될 수 있습니다. 사용자 요청은 매번 달라지더라도, 같은 저장소나 같은 작업 환경 안에서는 이러한 프로젝트 지침이 상당 부분 동일하게 유지되는 경우가 많습니다.
예를 들어 같은 저장소에서 다음과 같은 요청들이 연속해서 들어온다고 가정해볼 수 있습니다.
요청 1:
[프로젝트 공통 지침: CLAUDE.md 또는 AGENTS.md]
+
[로그인 API의 버그를 수정해줘]
요청 2:
[프로젝트 공통 지침: CLAUDE.md 또는 AGENTS.md]
+
[결제 모듈에 테스트를 추가해줘]
요청 3:
[프로젝트 공통 지침: CLAUDE.md 또는 AGENTS.md]
+
[이번 변경사항을 PR 리뷰 관점에서 점검해줘]
세 요청에서 실제 사용자 요청은 모두 다르지만, 앞부분의 프로젝트 공통 지침은 동일하게 유지될 수 있습니다. 캐싱이 없다면 모델은 매 요청마다 같은 지침 파일을 다시 프리필해야 합니다. 반면 프리픽스 캐싱이 적용되어 있고 해당 지침 영역이 동일한 프리픽스로 유지된다면, 추론 엔진은 이미 계산된 KV 캐시를 재사용하고 뒤쪽의 사용자 요청에 대해서만 새롭게 프리필 연산을 수행할 수 있습니다.
이 최적화가 최근 더 중요해지는 이유는 LLM 서비스에서 입력 컨텍스트가 점점 길어지는 방향으로 발전하고 있기 때문입니다. 단순한 질의응답에서는 입력이 비교적 짧을 수 있지만, AI Agent는 시스템 지침, 프로젝트 규칙, 도구 정의, 출력 형식, 참고 문서, 이전 대화 이력처럼 모델이 응답 전에 읽어야 하는 정보가 함께 전달되는 경우가 많습니다.
이런 구조에서는 모델이 실제 답변 토큰을 생성하기 전에 처리해야 하는 프리필 구간이 길어집니다. 그리고 여러 요청이 공통된 긴 프리픽스를 공유한다면, 그 구간을 매번 다시 계산하는 비용도 함께 커집니다.
따라서 프리픽스 캐싱은 단순히 “같은 프롬프트에 대한 연산 결과를 저장하는 기능”이라기보다, 긴 입력 컨텍스트를 전제로 하는 AI Agent나 LLM 서비스에서 프리필 비용과 첫 토큰 지연시간(TTFT)을 관리하기 위한 방법으로 볼 수 있습니다.
주의할 점
프리픽스 캐싱이 효과를 발휘하려면 실제로 여러 요청이 공통된 프리픽스 구간을 가지도록 해야 합니다. 만약 요청마다 시스템 프롬프트가 동적으로 바뀌거나, 사용자 정보, 타임스탬프(Timestamp)와 같은 변동 값을 프롬프트 앞부분에 포함시킬경우에는 캐시 적중률이 떨어질 수 있습니다. 사람이 보기에는 거의 같은 프롬프트처럼 보여도, 입력되는 데이터의 토큰 시퀀스가 달라지면 동일한 프리픽스로 재사용하기 어렵습니다.
따라서 프리픽스 캐싱을 고려한다면 프롬프트 구조를 안정적으로 유지하는 것이 중요합니다. 일반적으로 시스템 프롬프트, 도구 정의, 출력 형식처럼 반복되는 정적인 내용은 앞쪽에 두고, 사용자 질문이나 요청마다 달라지는 값은 뒤쪽에 두는 편이 유리합니다. RAG 컨텍스트도 같은 문서 묶음이 여러 요청에서 반복된다면 캐싱으로 인한 처리량 향상을 기대할 수 있습니다. 예를 들어 하나의 긴 매뉴얼이나 정책 문서를 기준으로 여러 질문을 반복해서 처리하는 경우에는, 문서 영역이 공통 구간으로 유지될 수 있습니다.
또 한 가지 고려할 점은 메모리입니다. 프리픽스 캐싱은 반복 계산을 줄이기 위해 KV 캐시를 보관하지만, 이 캐시 자체도 GPU 메모리를 사용합니다. 캐시를 많이 유지할수록 재사용 가능성은 커질 수 있지만, 동시에 처리 중인 요청이나 보다 긴 컨텍스트 윈도우 제공을 위한 메모리 여유는 줄어들 수 있습니다.
마지막으로, 공통된 프리픽스를 가지는 요청은 사람이 보기에 비슷한 문장이 아니라, 토큰 시퀀스 기준으로 동일해야 합니다. 따라서 프롬프트 템플릿과 직렬화(Serialization) 방식을 일관되게 관리하는 것만으로도 캐시 효율에 큰 영향을 줄 수 있습니다.
프리픽스 캐싱의 목표는 모든 입력을 캐싱하는 것이 아니라, 반복되는 입력 구간을 안정적으로 재사용해 프리필 비용과 첫 토큰 지연시간을 줄이는 데 있기 때문입니다.
마치며
이번 글에서는 LLM 서비스 배포 비용을 줄이기 위해 자주 검토하는 두 가지 기술인 양자화(Quantization)와 프리픽스 캐싱(Prefix Caching)을 살펴보았습니다.
간단히 정리해보자면, 양자화는 모델의 가중치와 일부 계산값을 더 낮은 정밀도의 숫자 형식으로 표현해 메모리 사용량과 대역폭 부담을 줄이는 방법이고, 프리픽스 캐싱은 공통 프리픽스 구간에 대한 KV 캐시를 활용해 프리필 단계의 재연산을 줄이는 방법입니다.
다만 두 기술 모두 실제 서비스에 적용할 때는 반드시 확인해야 할 부분이 있습니다. 양자화는 모델의 성능과 비용 절감 사이의 트레이드오프를 항상 검증해야 하고, 프리픽스 캐싱은 실제 워크로드에서 공통 구간의 프리픽스가 얼마나 자주 재사용되는지 확인해야 합니다.
따라서 어느 기술을 어느 정도까지 적용할지는 결국 서비스 특성에 따라 달라집니다. 사용 중인 모델, 프롬프트 구조, 트래픽 패턴, GPU 환경, 서비스 품질 기준을 함께 보면서 한 단계씩 검증해가는 것을 권장합니다. AIEEV Dev Team에서도 자체 서비스인 AirAPI에 이러한 최적화 기술을 어떻게 적용할 수 있을지 계속 고민하고 있습니다. 기회가 된다면 다음 포스팅에서는 이러한 기술을 실제 워크로드에 적용해가는 과정과 그에 따른 개선 효과도 간단히 공유드릴 수 있도록 하겠습니다.
여기까지 긴 글 읽어주셔서 감사합니다.
.
.
.

| Dev Team
| Author: JB Kim
| Site: Linkedin


