24GB VRAM에서 Qwen3.6-27B + vLLM + Hermes 구동하기: 2026년 5월 레시피
요약
24GB VRAM 환경에서 Qwen3.6-27B 모델과 vLLM을 활용하여 안정적인 로컬 코딩 에이전트를 구축하는 최적의 설정법을 소개합니다. 긴 컨텍스트 유지와 도구 호출의 안정성을 위해 GPTQ 양자화 모델과 특정 vLLM 플래그 설정을 권장합니다.
핵심 포인트
- 24GB GPU에서 Qwen3.6-27B를 구동하기 위한 GPTQ-Marlin 경로 활용
- 에이전트 안정성을 위해 max_num_seqs를 1로 설정하여 KV 캐시 지역성 확보
- 긴 컨텍스트(최대 131k) 지원을 위한 vLLM 최신 나이틀리 버전 사용
- 추측적 디코딩(Speculative Decoding) 제외를 통한 OOM 및 충돌 방지
만약 제가 현재 사용 중인 로컬 Hermes Agent + Qwen3.6-27B 설정을 재현하고 싶다면, 저는 이 형태에서 시작할 것입니다.
목표 (Target)
로컬 코딩 에이전트(coding agent) 하나.
24GB GPU 하나.
긴 컨텍스트 (Long context).
도구 사용 (Tools enabled).
사고 과정 활성화 (Thinking enabled).
메인 요청과 충돌하는 하위 에이전트(child agents)는 없습니다.
목표는 짧은 프롬프트에서 최고의 토큰 생성 속도(tok/s)를 내는 것이 아닙니다. 목표는 다음과 같습니다: 동일한 에이전트 세션이 접두사 지역성(prefix locality)을 잃거나, 프리필(prefill) 중에 타임아웃이 발생하거나, 보조 요청(auxiliary requests)으로 인해 망가지지 않고 수 시간 동안 도구 호출(tool calls)을 수행하며 계속 작동할 수 있는가?
모델 (Model)
이 설정은 의도적으로 텍스트 전용(text-only)입니다.
여기서 멀티모달(multimodal) GGUF 변형을 서빙하지는 않습니다. 작동하는 구성은 vLLM을 통해 --language-model-only 옵션으로 groxaxo/Qwen3.6-27B-GPTQ-Pro-4bit를 사용하는 것입니다.
이 선택은 중요합니다. 24GB RTX 3090에서 텍스트 전용 GPTQ-Marlin 경로는 긴 컨텍스트, 접두사 캐싱(prefix caching), 안정적인 에이전트 동작, 그리고 사용 가능한 디코딩 속도(decode speed) 사이에서 제가 찾은 최적의 균형을 제공했습니다. 비전(Vision) 기능이 필요하다면 별도의 서비스나 모델로 처리해야 합니다.
vLLM
유용한 구성 형태:
CUDA_VISIBLE_DEVICES=0 vllm serve groxaxo/Qwen3.6-27B-GPTQ-Pro-4Bit \
--served-model-name qwen3.6-27b-gptq-pro-4bit \
--dtype float16 \
...
저는 오래된 안정화 버전 이미지가 아닌, 최신 vLLM 나이틀리(nightly) 버전(0.20.1rc1.dev16+g7a1eb8ac2)을 사용했습니다.
사람들이 논쟁하고 싶어 할 두 가지 플래그(flags):
--max-num-seqs 1
--max-model-len 131072
저는 의도적으로 max_num_seqs=1을 사용합니다. 에이전트 환경에서 병렬 처리(parallelism)는 공짜가 아닙니다. 제목 생성, 컨텍스트 압축, 재시도, 브라우저 확인, 도구 호출 및 사이드 작업(side jobs)은 모두 메인 요청으로부터 KV 캐시 지역성(KV/cache locality)을 앗아갈 수 있습니다. 하나의 24GB GPU에서는 서로를 방해하는 두 개의 요청보다 하나의 유용한 요청을 선호합니다.
131k 컨텍스트는 빠듯하지만 여기서는 작동 가능합니다. 만약 서비스에서 OOM(Out of Memory)이 발생한다면, MTP를 추가하기 전에 컨텍스트를 줄이거나 enforce-eager를 강제하십시오. 저는 110k, 그다음 100k, 그다음 80k 순으로 테스트할 것입니다.
제외한 사항 (What I Did Not Keep)
안정적인 구성에서 Qwen3 Next MTP/추측적 디코딩(speculative decoding)은 제외했습니다. 제가 사용하는 유용한 컨텍스트 크기에서는 충돌(crashes), OOM, 404 오류를 유발했습니다.
enforce-eager도 제외했습니다. (메모리는 절약하지만 성능을 저하시킵니다)
Hermes에 명시적인 max_tokens: 16384 제한을 두지 않았습니다. 이 제한은 텍스트 잘림(truncation) 현상과 긴 추론(reasoning)/최종 답변(final-answer) 동작을 디버깅하는 것을 어렵게 만들었기 때문에 제거했습니다.
Hermes
Hermes가 OpenAI 호환 vLLM 엔드포인트를 가리키도록 설정하고, 동일한 서빙 모델 이름인 qwen3.6-27b-gptq-pro-4bit를 사용합니다.
저에게 중요했던 설정값들은 다음과 같습니다:
- 컨텍스트(context) 약 131072
- 사고(thinking) 활성화
- preserve_thinking 활성화
- 긴 프로바이더/클라이언트 타임아웃(timeout)
- 자식 에이전트(child agents) 비활성화
- 엄격한 max_tokens 제한 없음
- 도구 호출(tool calls) 허용, 단 혼란을 야기하는 병렬화는 제외
타임아웃이 중요합니다. 컨텍스트가 클 경우, 클라이언트가 180초 후에 포기해 버리면 실제 프리필(prefill) 과정이 마치 죽은 프로바이더처럼 보일 수 있습니다. 모델을 탓하기 전에 긴 타임아웃을 먼저 사용해 보세요.
다음은 Qwen3.6/vLLM 설정에 중요한 부분만 편집 및 축약한 Hermes 전용 설정 발췌본입니다:
models:
default: qwen3.6-27b-gptq-pro-4bit
provider: vllm-qwen36.mylabdomain.com
...
캐시 관리 (Cache Discipline)
이 부분은 대부분 vLLM 플래그가 아니라 오케스트레이션(orchestration)에 관한 것입니다.
제가 제어할 수 있는 것: 안정적인 크론(cron) 프롬프트, 안정적인 스킬(skills), 자식 에이전트 군집(swarm) 방지, 병렬 디버그/개발 작업 금지, 긴 타임아웃, 그리고 한 번에 하나의 메인 요청만 처리.
제가 완전히 제어할 수 없는 것: Hermes가 모든 내부 프롬프트를 직렬화(serialize)하는 정확한 방식. 만약 휘발성 세션 상태(session state)나 보조 자료가 안정적인 지침보다 먼저 배치된다면, 접두사 재사용(prefix reuse) 효율이 떨어질 것입니다.
따라서 실질적인 규칙은 더 간단합니다. 제어 가능한 입력값은 지루하고 반복 가능하게 만들고, 메인 세션과 경쟁하는 부수적인 요청을 피하는 것입니다.
vLLM 접두사 캐싱(prefix caching)이 도움이 되지만, 이것이 마법 같은 영구 캐시 데이터베이스는 아닙니다. 이를 인메모리(in-memory) 서빙 최적화로 취급하고 그에 맞춰 트래픽을 구성하세요.
예상 동작
정상적인 실행:
- 접두사 재사용(prefix reuse)이 적용될 때 낮은 TTFT(Time To First Token)
- 큰 컨텍스트 전환 시에는 여전히 60-90초의 TTFT가 발생할 수 있음
- 제 환경에서 초당 약 30대 후반의 토큰 생성 속도(tok/s)
- 안정적인 도구 사용(tool use)
- 매 연속(continuation) 시마다 발생하는 전체 프리필(full-prefill) 없음
- 자식 에이전트 군집(child-agent swarm) 없음
비정상적인 실행:
- 매 요청마다 반복되는 전체 프리필 (full-prefill)
- 메인 에이전트가 대기하는 동안 발생하는 보조 요청 (auxiliary requests)
- 최종 답변 전에 모델이 출력 제한 (output cap)에 도달함
- MTP 불안정성/OOM (Out of Memory)
- 샘플링 (sampling)/설정 (config)/모델 불일치로 인한 도구 루프 (tool loops)
빠른 성능 스냅샷 (Quick Performance Snapshot)
이것은 공식적인 벤치마크가 아니라, 실제 OpenAI 호환 엔드포인트(endpoint)를 대상으로 한 간단한 검증 (sanity check)입니다.
작은 프롬프트 (Small prompt):
- 프롬프트 (prompt): 41 토큰 (tokens)
- 출력 (output): 384 토큰 (tokens)
- TTFT (Time To First Token): 0.29s
- 디코딩 (decode): 45.3 tok/s
큰 프롬프트, 약간 차가운 접두사 (Large prompt, cold-ish prefix):
- 프롬프트 (prompt): 41,985 토큰 (tokens)
- 출력 (output): 384 토큰 (tokens)
- TTFT (Time To First Token): 38.6s
- 디코딩 (decode): 41.8 tok/s
- 유효 프리필 (effective prefill): ~1,087 prompt tok/s
동일한 큰 프롬프트를 즉시 반복했을 때:
- 프롬프트 (prompt): 41,985 토큰 (tokens)
- 출력 (output): 384 토큰 (tokens)
- TTFT (Time To First Token): 1.59s
- 디코딩 (decode): 42.1 tok/s
마지막 줄이 에이전트 작업에서 중요한 부분입니다. 접두사 캐싱 (Prefix caching)은 추상적으로 모델을 "더 빠르게" 만드는 것이 아닙니다. 접두사 (prefix)가 안정적으로 유지될 때, 반복되는 긴 컨텍스트 (long-context) 연속 작업에서 전체 프리필 비용을 지불하지 않도록 만들어 주는 것입니다.
나의 실질적인 결론 (My Practical Takeaway)
이러한 워크로드 (workload)에서 병목 (blocker)은 모델이 아니었습니다. Qwen3.6-27B는 코딩 에이전트 (coding agent)로서 로컬에서 사용하기에 충분히 강력합니다.
어려운 부분은 서빙 규율 (serving discipline)입니다: 컨텍스트 크기 (context size), 요청 순서 (request sequencing), 접두사 재사용 (prefix reuse), 타임아웃 정책 (timeout policy), 그리고 스스로 초래하는 동시성 (concurrency) 방지 등이 여기에 해당합니다.
만약 당신이 "모델이 프롬프트 하나에 답변하는가?"만을 테스트한다면, 당신은 잘못된 것을 테스트하고 있는 것입니다.
루프 (loop)를 테스트하세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기