9월 21일 월요일
에이전트 추론의 성능은 모델 한 번의 응답 시간이 아니라 메모리 계층, 캐시 지역성, 스케줄링, 상태 초기화와 GPU 실행 순서를 끝까지 묶어 검증할 때 결정된다.
추론의 병목은 요청 하나가 아니라 작업 전체에서 생긴다
에이전트는 긴 접두부를 공유하는 호출을 수십 번 반복한다. FLOPs만 보는 대신 가중치와 KV 캐시를 어디에 두고, 어느 replica로 보내며, 전체 작업이 언제 끝나는지를 측정해야 한다.

에이전트 추론 스택은 무엇을 병목으로 보고 어떤 단위로 최적화해야 하는가?
학습은 큰 행렬 연산을 병렬화하는 compute 중심 작업이지만, autoregressive inference는 토큰을 생성할 때마다 모델 가중치와 상태를 읽는다. 원문이 제시한 2014~2024년 비교에서 GPU 부동소수점 연산량은 약 120배 늘었고 메모리 대역폭은 약 17배 늘었다. 이 간극은 추론을 FLOPs보다 메모리 용량·대역폭·이동 비용의 문제로 만든다. 에이전트 워크로드는 여기에 또 하나의 축을 더한다. 계획, 도구 호출, 관찰을 반복하면서 입력이 길어지고, 연속 단계가 대부분의 프롬프트 접두부를 공유한다. Deep Research형 작업은 수십~수백 번의 추론을 분에서 시간 단위로 실행할 수 있다. 따라서 단일 요청의 첫 토큰 지연시간만 줄여서는 충분하지 않다. 가중치와 사용자별 KV 캐시를 어느 계층에 둘지, 공유 접두부가 있는 replica로 요청을 어떻게 보낼지, 하위 에이전트의 변동하는 동시성을 어떻게 스케줄할지까지 묶어 task completion time을 최소화해야 한다.
- 01
메모리 벽을 먼저 모델링한다
추론 원가는 파라미터를 몇 비트로 저장하는지뿐 아니라 사용자별 KV 캐시가 얼마나 커지는지에 좌우된다. 원문은 긴 세션 하나의 캐시가 약 100GB가 될 수 있고, 에이전트 코딩 추적에서는 토큰의 약 96%가 캐시될 수 있다고 설명한다. 캐시된 토큰의 재사용은 새 토큰을 다시 계산하는 것보다 훨씬 싸지만, 저장 공간과 이동 경로를 요구한다. GPU 메모리만으로 끝내지 않고 호스트 메모리와 디스크를 포함한 계층, 양자화에 따른 품질 비용, 축출 정책을 함께 설계해야 한다.
- 02
접두부를 계산한 곳으로 요청을 보낸다
Prefix caching은 앞 단계에서 계산한 KV를 보존하고 새 suffix만 처리하게 한다. 하지만 다음 호출이 캐시가 없는 replica로 이동하면 이 이점이 사라진다. Cache-aware routing은 공유 접두부가 남아 있는 실행 위치로 요청을 보내 지역성을 지키고, 분산 캐시는 여러 replica가 같은 접두부를 재사용하게 한다. 라우터의 부하 균형만 최적화하면 캐시 재계산이 늘 수 있으므로, 대기열 길이와 캐시 적중 가능성을 함께 봐야 한다.
- 03
요청 지표를 작업 지표로 올린다
채팅은 요청 하나가 비교 단위가 되기 쉽지만 에이전트는 여러 호출과 도구 실행이 끝나야 가치가 생긴다. 개별 호출을 가장 빠르게 만드는 스케줄이 전체 작업을 가장 빨리 끝내는 스케줄과 같지 않을 수 있다. 다음 단계가 필요로 할 접두부를 미리 준비하거나, 에이전트 맥락을 아는 축출 정책으로 곧 재사용할 캐시를 남기는 이유다. 벤더의 split test에서 약 7배 속도와 낮은 오류율이 보고됐지만, 운영 판단은 자신의 호출 그래프와 실패율로 다시 검증해야 한다.
- 04
효율 향상을 용량 감소로 오해하지 않는다
와트당 토큰이나 캐시 효율이 좋아져도 데이터센터 수요가 자동으로 줄어드는 것은 아니다. 절약된 전력과 메모리를 더 많은 사용자, 더 긴 컨텍스트, 더 많은 에이전트 단계에 다시 쓸 수 있기 때문이다. 장기적으로는 전력 생산이 중요하지만 원문은 당장 배치를 늦추는 제약으로 자본, 부채, 인허가와 지역의 합의를 함께 지목한다. 시스템 설계의 성능 목표와 실제로 배치 가능한 용량 계획을 분리하지 말아야 한다.
에이전트 추론의 최소 관측 단위는 모델 호출이 아니라 하나의 작업 그래프다. 운영자는 요청별 latency와 throughput에 더해 task completion time, prefix cache hit, 재계산된 토큰, 계층별 KV 점유, replica 이동, 도구 실패 뒤 재시도 비용을 함께 기록해야 한다. 모델 선택도 같은 기준으로 비교해야 한다. 오픈 웨이트 모델의 토큰 단가가 낮아도 캐시 지역성이 깨지거나 장기 작업의 오류율이 높으면 이점이 사라지고, 반대로 더 큰 모델도 높은 캐시 재사용과 짧은 완료 시간으로 총비용을 낮출 수 있다.
GPU 최적화는 수식보다 실행 순서에서 무너진다
작은 정규화 커널을 줄여도 스트림 join, 상태 초기화, 인덱스 폭이 틀리면 시스템은 충돌 없이 오래된 상태를 읽고 자신 있게 잘못된 출력을 낸다.
커널 최적화와 상태 기반 추론에서 속도와 정확성을 함께 지키는 검증 흐름은 무엇인가?
- 1
1. FLOPs보다 주변 비용을 프로파일링한다
RMSNorm은 산술량이 작아도 decode 단계에서 약 33번 실행될 수 있다. 작은 커널의 launch, 중간 메모리 이동, 다른 연산을 기다리는 시간이 누적되므로 wall time과 실행 타임라인을 함께 본다.
- 2
2. 런타임 연산을 오프라인으로 옮긴다
Gain을 projection weight에 미리 접고 scalar division을 matmul 뒤로 미루면 원소별 연산과 이동을 줄이고 tensor unit의 matmul과 CUDA core의 reduction을 겹칠 수 있다. 대수적 동치가 최적화의 첫 조건이다.
- 3
3. 두 생산자의 완료를 명시적으로 기다린다
Matmul 스트림과 RMS 스트림을 병렬화한 뒤 post-scale이 한쪽만 기다리면 오래된 버퍼를 읽는다. 두 종료 이벤트를 각각 기록하고 소비 단계가 모두를 기다리게 해야 병렬성을 유지하면서 stale read를 막는다.
- 4
4. 상태 초기화 순서를 invariant로 둔다
Mamba 요청이 prefill보다 먼저 decode로 가면 새 요청이 이전 요청의 state cache를 읽을 수 있다. 스케줄러는 새 요청을 decode 경로에 넣지 않는 조건을 성능 힌트가 아니라 correctness invariant로 보장해야 한다.
- 5
5. 부하를 바꿔 실패 경계를 당긴다
드문 gibberish는 메모리 사용률을 90%에서 20%로 낮춰 동시 요청을 늘렸을 때 특정 요청으로 재현됐다. rollout 수를 8에서 128까지 키우자 주기적 logprob spike도 첫 단계까지 앞당겨졌다. 설정 변화는 수정이 아니라 재현 도구다.
- 6
6. 요청 ID와 주소 계산을 커널까지 잇는다
약 2³²를 넘긴 uint32 인덱스는 예외 없이 wraparound해 잘못된 state 위치를 가리켰다. 요청 ID를 엔진과 커널까지 전파하고 독립 baseline의 token-level logprob와 비교해야, 정상 응답처럼 보이는 침묵형 오류를 찾을 수 있다.
두 사례의 공통점은 테스트가 통과했다는 사실이 실행 순서의 정확성을 보증하지 않았다는 데 있다. RMSNorm 변경은 단위 테스트와 perplexity를 통과하고도 긴 생성에서 one-step lag를 냈고, Mamba 버그는 약 1,000건당 한 번 발생하거나 일정한 학습 단계에서만 드러났다. 검증 묶음에는 긴 autoregressive generation, 동시성·메모리 압력 변화, baseline logprob 비교, 스트림 이벤트 확인, 인덱스 경계 테스트가 함께 들어가야 한다. 성능 최적화 PR의 완료 조건도 평균 latency 향상만이 아니라 이 불변식들이 부하 아래 유지되는지까지 포함해야 한다.
아직 못 읽은 북마크
북마크를 고르는 중…