본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 20. 02:41

MTP TPS를 쫓는 것을 멈추고 24GB VRAM에서 실제로 사용 가능한 로컬 27B 에이전트를 얻었습니다

요약

24GB VRAM 환경에서 실용적으로 작동하는 27B 로컬 코딩 에이전트 구축 방법을 공유합니다. Qwopus3.6-27B 모델을 GPTQ-Pro 4-bit로 양자화하여 긴 컨텍스트와 도구 사용 능력을 유지하면서도 안정적인 루프를 구현했습니다.

핵심 포인트

  • 24GB GPU 1장에서 구동 가능한 27B 모델 양자화 최적화
  • 단일 요청 집중(max_num_seqs=1)을 통한 에이전트 안정성 확보
  • 단순 벤치마크보다 지속 가능한 에이전트 루프 유지에 집중
  • vLLM과 GPTQ-Pro를 활용한 효율적인 서빙 구성

저는 이미 groxaxo/Qwen3.6-27B-GPTQ-Pro-4bit + vLLM + Hermes 레시피에 만족하고 있었습니다: 하나의 로컬 에이전트, 하나의 24GB GPU, 긴 컨텍스트 (long context), 도구 (tools), 사고 기능 (thinking) 활성화, 그리고 수 시간 동안의 편집, 터미널 호출, 재시도, 압축 및 컨텍스트 성장이 있은 후에도 세션이 계속 작동할 수 있을 만큼 충분한 서빙 규율 (serving discipline)을 갖춘 구성이었습니다.

그래서 Jackrong이 Qwopus3.6-27B-v2를 출시했을 때, 동일한 레시피가 유효할지 확인하고 싶었습니다.

A100을 대여하고 양자화 (quantization)에 몇 달러를 사용한 후, 그 결과를 게시했습니다: XReyRobert/Qwopus3.6-27B-v2-GPTQ-Pro-v1

결과물 (The artifact)

이것은 Jackrong/Qwopus3.6-27B-v2의 GPTQ-Pro 4-bit 양자화 파생 모델입니다. GPTQ-Pro 레시피와 실질적인 양자화 노하우의 상당 부분은 groxaxo로부터 왔으므로, 공로를 돌립니다: https://github.com/groxaxo

목표는 사용성 (usability)이었습니다: 제가 실제로 실행하는 로컬 코딩 에이전트 설정에서 이 모델을 실용적으로 만드는 것입니다.

즉, 하나의 로컬 에이전트, 하나의 24GB GPU, 긴 컨텍스트 (long context), 도구 (tools), 사고 기능 (thinking) 활성화, 그리고 수 시간 동안의 편집, 터미널 호출, 재시도, 압축 및 컨텍스트 성장이 있은 후에도 세션이 계속 작동할 수 있을 만큼 충분한 서빙 규율 (serving discipline)을 갖추는 것을 의미합니다.

목표는 짧은 프롬프트 벤치마크가 아니었습니다.

다음과 같은 것이 아니었습니다:

"하나의 프롬프트에 답할 수 있는가?"

진짜 질문은 이것입니다:

"루프 (loop)가 유지되는가?"

참고로 양자화 형태 (quantization shape)는 다음과 같습니다:

- GPTQ-Pro / GPTQModel
- 4-bit
- group size 128
...

서빙 형태 (The serving shape)

저는 텍스트 전용으로 서빙합니다.

이 설정에는 멀티모달 (multimodal) 경로가 없습니다. 투기적 디코딩 (speculative decoding)도 없습니다. 병렬 요청 누적 (parallel request pile-up)도 없습니다.

CUDA_VISIBLE_DEVICES=0 vllm serve XReyRobert/Qwopus3.6-27B-v2-GPTQ-Pro-v1 \
  --served-model-name qwopus3.6-27b-gptq-pro-v1 \
  --language-model-only \
...

max_num_seqs=1은 의도적인 설정입니다.

24GB 카드 한 장에서는 병렬 처리(parallelism)가 공짜가 아닙니다. 제목 생성, 압축, 재시도, 요약 및 사이드 요청(side requests)이 모두 메인 에이전트 요청과 경쟁할 수 있습니다.

저는 두 요청이 서로를 방해하는 것보다, 하나의 유용한 요청이 깔끔하게 완료되는 것을 선호합니다.

왜 추측적 디코딩 (Speculative Decoding)을 사용하지 않나요?

이 설정에서는 제가 중요하게 생각하는 지표인 '엔드 투 엔드(end-to-end) 롱 컨텍스트(long-context) 에이전트 처리량'을 개선하지 못했기 때문입니다.

이 아티팩트(artifact)는 vLLM의 추측적 디코딩을 위한 non-MTP로 취급되어야 합니다. 일부 MTP 관련 설정 메타데이터를 유지하고 있지만, 공개된 가중치 인덱스에는 실제 mtp.* 텐서가 포함되어 있지 않습니다.

또한 실제 MTP 텐서를 복구하고 대규모 MTP 선형 레이어(linears)를 양자화(quantized)한 후속 아티팩트를 테스트했습니다. 초안 수락(Draft acceptance)은 실제로 이루어졌지만, 단일 RTX 3090에서는 유용한 100k-131k 컨텍스트 범위에서 non-MTP 베이스라인보다 여전히 느렸습니다.

이러한 워크로드에서 MTP는 다음과 같은 요소를 추가합니다:

  • 메모리 압박 (memory pressure)
  • 서빙 복잡성 (serving complexity)
  • 1x3090에서의 엔드 투 엔드 속도 향상 없음

더 큰 GPU나 짧은 프롬프트 워크로드에서는 추측적 디코딩을 다시 검토할 가치가 있을 수 있습니다.

24GB 롱 컨텍스트 코딩 에이전트의 경우, 다른 증거가 나타날 때까지는 사용하지 않는 것으로 결정했습니다.

초당 토큰 수(Token/s)가 전부가 아닙니다

진정으로 유용한 질문은 에이전트가 프리픽스(prefix)를 '핫(hot)'하게 유지하여 전체 프리필(prefill) 비용을 반복해서 지불하는 것을 피할 수 있느냐 하는 것입니다.

이상적인 동작은 다음과 같습니다:

  • 대규모 컨텍스트가 여전히 작동함
  • 프리픽스 캐시(prefix-cache) 히트가 빈번함
  • 프리픽스가 재사용될 때 TTFT(Time To First Token)가 감소함
  • 도구 호출(tool calls)이 안정적으로 유지됨
  • 메인 요청이 사이드 작업과 경쟁하지 않음

제 3090급 설정에서 관찰된 결과는 다음과 같습니다:

  • 평균 프롬프트: ~33k 토큰
  • 평균 TTFT: ~5.7s
  • 프리필 처리량 (prefill throughput): ~1917 tok/s
  • 디코드 추정치 (decode estimate): ~43 tok/s
  • 프리픽스 캐시 히트 비율 (prefix cache hit ratio): ~83%

이것이 제가 관심을 갖는 지표 군(metric cluster)입니다.

12시간 동안 진행된 terminal-bench 스타일의 실행에서, 엔드포인트는 단순히 아주 작은 프롬프트에 답변하는 것에 그치지 않았습니다. 반복적인 작업, 유지된 컨텍스트 (retained context), 도구 호출 (tool calls), 더 긴 생성 (longer generations), 새로운 시작 (fresh starts), 재시도 (retries), 그리고 압축 (compression)을 처리했습니다.

이는 코딩 에이전트 (coding agent)가 실제로 동작하는 방식에 훨씬 더 가깝습니다.

유용한 신호들은 다음과 같았습니다:

  • 대기 시간 (queue time)이 낮게 유지됨
  • 작업 변경 후에도 접두사 캐시 재사용 (prefix-cache reuse)이 회복됨
  • 종료 사유 (finish reasons)가 대부분 정상적인 중단 (normal stops)이었음
  • 길이 제한 (length caps) 및 오류가 지배적이지 않았음
  • 긴 컨텍스트 압박 (long-context pressure) 하에서도 도구 호출 (tool-call) 동작이 안정적으로 유지됨

디코딩 (decode) 수치는 이야기의 절반에 불과합니다. 긴 컨텍스트 에이전트 (long-context agents)의 경우, 프리필 처리량 (prefill throughput) 또한 똑같이 중요합니다. 왜냐하면 모든 콜드 (cold) 또는 부분적으로 콜드인 프롬프트는 유용한 생성이 시작되기 전에 그 비용을 지불해야 하기 때문입니다. 프리필 (prefill) 성능이 형편없다면 디코딩 속도가 준수하더라도 여전히 체감 성능은 나쁩니다. 양호한 접두사 재사용 (prefix reuse)과 건강한 프리필 처리량 (prefill throughput)을 갖춘 설정이야말로 반복되는 긴 컨텍스트 연속 실행 (long-context continuations)을 견딜 만하게 만드는 핵심입니다.

제가 보여드리고 싶은 패널들은 단순히 속도만이 아니라, 루프 (loop)를 설명해 주는 것들입니다.

Prompt and generation throughput during the long run

장기 실행 중의 프롬프트 및 생성 처리량 (throughput). 약 43 tok/s의 생성 속도는 이야기의 절반일 뿐입니다. 프롬프트 처리량 (prompt throughput)은 캐시가 콜드 (cold) 상태이거나 부분적으로만 재사용 가능할 때, 긴 컨텍스트 프리필 (long-context prefill)이 얼마나 고통스러운지를 결정하는 요소입니다. 사용 가능한 로컬 에이전트 (local agent)가 되려면 준수한 디코딩 속도 (decode speed)와 견딜 만한 프리필 동작 (prefill behavior)이 모두 필요합니다.

Finish reasons during the long run

장기 실행 중의 종료 사유 (finish reasons). 유용한 신호는 대부분의 요청이 길이 제한 (length caps)이나 오류가 아닌, 정상적인 중단 사유로 종료된다는 점입니다. 에이전트 루프 (agent loop)에서는 이것이 토큰 처리량 (token throughput)만큼이나 중요합니다.

접두사 캐시 (prefix-cache) 그래프가 제가 가장 신경 쓰는 부분입니다.

Grafana Prefix Cache Hit Rate panel over a long vLLM run

장기적인 관점에서의 접두사 캐시 적중률 (Prefix-cache hit rate)입니다. 작업 형태 (task shape)가 변할 때 수치가 떨어지는 것은 예상된 일입니다. 유의미한 신호는 국소성 (locality)이 안정화될 때 캐시 재사용이 다시 돌아온다는 점입니다.

새로운 작업은 자연스럽게 국소성을 깨뜨립니다. 그것은 괜찮습니다. 중요한 부분은 프롬프트 형태 (prompt shape)가 다시 안정화될 때, 접두사 재사용 (prefix reuse)이 다시 이루어진다는 것입니다.

이것이 계속해서 작동하는 로컬 에이전트와, 세션이 고통스러워질 때까지 계속해서 전체 프리필 (prefill) 비용을 지불해야 하는 에이전트 사이의 차이점입니다.

TTFT는 서비스 계약의 일부입니다

100k 이상의 컨텍스트 (context)에서는 TTFT (Time To First Token)가 항상 작지만은 않습니다.

그렇다고 해서 모델이 반드시 느리거나 고장 났다는 뜻은 아닙니다. 때때로 서버는 실제 프리필 (prefill) 작업을 수행하고 있는 것입니다. 접두사 (prefix)가 캐싱되어 있다면 TTFT는 떨어집니다. 작업 형태가 변하면 캐시는 더 차가워지며 (colder), 서버는 다시 그 비용을 지불해야 합니다.

Grafana Time To First Token Latency panel for a long vLLM run

긴 컨텍스트 에이전트 트래픽 중의 TTFT입니다. 급증 (spikes)이 반드시 실패를 의미하는 것은 아닙니다. 이는 종종 서버가 더 차가워진 프롬프트 전환 이후에 실제 프리필 (prefill) 작업을 수행하고 있음을 의미합니다.

이것이 짧은 클라이언트 타임아웃 (client timeout)이 로컬 롱 컨텍스트 (long-context) 에이전트에게 독이 되는 이유입니다.

이 설정에서, 긴 프로바이더 (provider) 및 게이트웨이 (gateway) 타임아웃은 단순히 미적인 문제가 아닙니다. 그것은 에이전트 루프를 신뢰할 수 있게 만드는 필수 요소입니다.

FP8 KV가 중요한 이유

이 정도의 컨텍스트 길이에서는 가중치 (weights)가 메모리 이야기의 전부가 아닙니다.

KV 캐시 (KV cache)가 제약 사항이 됩니다.

그렇기 때문에 저는 다음을 사용합니다:

--kv-cache-dtype fp8_e5m2

저는 FP8 KV를 마법처럼 취급하지 않습니다. 이는 롱 컨텍스트 (long-context) 설정을 24GB 카드에 맞출 수 있도록 도와주는 실질적인 절충안 (tradeoff)입니다.

실질적인 시사점

작동하는 설정은 다음과 같은 조합입니다:

  • Qwopus3.6-27B GPTQ-Pro
  • vLLM GPTQ-Marlin
  • 텍스트 전용 서빙 (text-only serving)
  • 131k 컨텍스트 (context)
  • FP8 KV 캐시 (KV cache)
  • 프리픽스 캐싱 (prefix caching)
  • max_num_seqs=1
  • 사고 기능 활성화 (thinking enabled)
  • 긴 타임아웃 (long timeouts)
  • 투기적 디코딩 (speculative decoding) 미사용
  • 자식 에이전트 스웜 (child-agent swarm) 미사용

단 하나의 프롬프트만 테스트한다면, 당신은 잘못된 것을 테스트하고 있는 것입니다.

코딩 에이전트 (coding agents)의 경우, 진짜 테스트는 루프 (loop)입니다.

다른 분들 중에도 유사한 단일 GPU 24GB 에이전트 루프를 실행하고 계신 분이 있나요? 프리픽스 캐싱 (prefix caching)이나 KV 캐시 (KV cache)에 대해 어떤 트릭이 효과적이었는지 궁금합니다.

@vllm_project @NousResearch

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0