3090 2대로 8개 에이전트 동시 구동, 각각 250K 컨텍스트 (~600+ tok/s)
8 agents × 250K context, concurrently, on two 3090s (~600+ tok/s total)
핵심 요약
시스템 RAM에 전체 KV 캐시를 저장하고 필요한 1%만 GPU로 불러오는 방식으로 8개 에이전트의 250K 컨텍스트를 효율적으로 처리함.
- 효율적 컨텍스트 관리 — 시스템 RAM에 전체 KV 캐시를 저장하고 필요한 1%만 GPU로 불러와 처리함.
- 성능 최적화 — 3090 2대로 8개 에이전트가 각각 250K 컨텍스트를 유지하며 초당 600토큰 이상 생성함.
- 기술적 구현 — Triton 커널과 vLLM 패치를 통해 동적 sparse/dense 전환 및 스케줄링 개선을 적용함.
- 잠재적 한계 — 근접한 코드 라인이 섞이는 등 근사치 기반 어텐션으로 인한 미세한 오류 가능성이 존재함.
내가 틀렸을 수도 있다는 생각은 하지만, 그래도 내 발견을 공유할 가치는 있다고 본다.
8개의 에이전트가 각각 코드베이스를 병렬로 길게 설명하는 내 UI 영상이다: https://imgur.com/JSqlXIi
며칠 전에 Stanford/Berkeley TokenGate 논문을 읽었다. 토큰을 미리 쳐내서 긴 컨텍스트를 싸게 처리하자는 아이디어더라.
직접 해봤는데, 질문 하나 던질 땐 괜찮아. 근데 에이전트들이 계속 꼬리 질문을 던지니까, 정작 필요한 토큰들이 다 날아가서 코드 리콜 성능이 개박살 나더라고.
그래서 아예 반대로 가기로 했다. 아무것도 버리지 말고, 그냥 한꺼번에 다 보지 말자고. 전체 컨텍스트는 시스템 RAM에 박아두고, 매 단계마다 지금 당장 필요한 ~1%만 끌어오는 방식이다.
며칠 뒤, 3090 두 장으로 8개의 코딩 에이전트를 동시에 돌리고 있다. 각자 250K 토큰 컨텍스트를 들고 있는 상태다:
-
모든 디코드 단계에서 각 어텐션 레이어는 토큰의 ~1%만 읽는다. 이건 아주 작은
rank-64"키 스케치(key sketch)"로 골라낸다. -
전체 KV 캐시는 시스템 RAM(
int4)에 상주한다. GPU는 스케치랑 작은 핫셋(hot set)만 들고 있는다. -
골라낸 토큰만 PCIe를 건너간다.
구현 과정:
-
Triton 커널: 스케치를 만들고, 모든 토큰 점수를 매겨서 상위 ~2K를 뽑은 다음, 기존 int8 어텐션 커널용으로 패킹한다. CUDA-graph도 문제없다.
-
vLLM 패치: 단계별로 덴스(dense)/스파스(sparse)를 전환해서 짧은 대화는 원래 속도 그대로 유지하게 했다.
-
KV 캐시용 RAM 계층: 프리픽스 캐시랑 리커런트 스테이트 체크포인트를 써서 후속 질문 때 재계산 안 하게 만들었다.
-
후속 질문은 골라낸 행만 가져옴: v1 때는 매 턴마다 전체 문서를 다시 복사(
~8 GB)해서 카드당 에이전트 2개밖에 못 돌렸는데, 이걸 해결했다. -
스케줄러 수정: 에이전트 하나가 거대한 프롬프트 읽는다고 나머지가 멈추는 현상을 잡았다.
-
고정된 스케치 베이시스(파일 하나)랑 그걸 다시 맞추는 스크립트.
전부 포크가 아니라 패치 형태로 레포에 올려뒀다. HyperQwen @ ce9615c (공개 vLLM 포크) 위에 패치 적용하고 설치 스크립트 돌리면 된다. 테스트랑 벤치마크 스크립트, 결과까지 다 들어있다.
모델: + HyperQwen의 . 모든 수치는 을 로드한 상태에서 측정했다(3090 BF16 텐서 처리량을 거의 두 배로 늘려주는 커널 모듈인데, 프롬프트 읽는 속도가 빨라짐).
