BeeLlama.cpp: DFlash 스펙큘레이티브 디코딩과 TCQ KV-캐시 압축으로 RTX 3090에서 Qwen 27B를 135 tps로 구동하기
TL;DR
BeeLlama.cpp는 llama.cpp 포크로, DFlash 스펙큘레이티브 디코딩과 TurboQuant KV-캐시 압축을 결합해 단일 RTX 3090에서 Qwen 3.6 27B Q5 모델을 200k 컨텍스트로 구동하며 베이스라인 대비 2~3배 속도 향상(피크 135 tps)을 달성했다고 주장한다. 기존 llama.cpp 도구 및 서버 플로우와의 호환성을 유지하면서 추론 루프 보호, 멀티모달 지원까지 추가한 성능 중심 포크다. 단, 독립적인 벤치마크 재현 데이터는 아직 제한적이므로 수치 해석에 주의가 필요하다.
배경: 왜 llama.cpp 포크가 필요했는가
로컬 LLM 추론 환경에서 27B급 모델을 단일 소비자용 GPU로 실용적으로 운용하려면 세 가지 제약이 동시에 충돌한다.
- VRAM 한계: RTX 3090의 24GB VRAM은 Q5 양자화 기준 27B 모델 가중치만으로도 약 17~19GB를 점유한다. 긴 컨텍스트의 KV 캐시가 추가되면 OOM이 발생한다.
- 컨텍스트 길이와 품질의 트레이드오프: 컨텍스트를 늘리려면 KV 캐시를 더 압축해야 하고, 과도한 압축은 perplexity 상승(품질 저하)을 유발한다.
- 디코딩 속도: 27B 모델은 단일 GPU에서 오토레그레시브 디코딩 시 메모리 대역폭 병목으로 인해 처리량이 낮다.
저자는 “Windows 환경에서 Qwen 3.6 27B Q5를 단일 3090으로, 스펙큘레이티브 디코딩과 비전 기능을 함께 활성화하면서 VRAM 문제 없이 구동하는 기성 솔루션이 없었다”고 밝혔다. BeeLlama.cpp는 이 세 가지 문제를 동시에 해결하려는 시도다.
핵심 메커니즘
DFlash 스펙큘레이티브 디코딩
표준 스펙큘레이티브 디코딩은 소형 드래프트 모델이 토큰 후보를 제안하고, 대형 타깃 모델이 이를 병렬 검증하는 방식이다. 수락률(acceptance rate) α가 높을수록 실질 처리량이 향상된다.
기대 처리량은 다음 식으로 근사할 수 있다:
E[처리량] ≈ (1 - α^(γ+1)) / (1 - α) × (타깃 단독 처리량)
여기서 γ는 드래프트 토큰 수다. α가 0.8이고 γ=4이면 약 3.36배의 이론적 속도 향상이 가능하다.
DFlash의 차별점은 hidden-state cross-attention 메커니즘이다. 타깃 모델이 각 레이어의 히든 스테이트를 4096 슬롯 링 버퍼에 기록하고, 드래프터가 --spec-dflash-cross-ctx 파라미터로 지정된 최근 N개의 히든 스테이트 토큰에 크로스 어텐션을 수행한다.
┌─────────────────────────────────────────┐
│ 타깃 모델 (Qwen 27B) │
│ Layer 0 → hidden_state → ring_buf[0] │
│ Layer 1 → hidden_state → ring_buf[1] │
│ ... │
│ Layer N → hidden_state → ring_buf[N] │
└──────────────┬──────────────────────────┘
│ per-layer hidden states
▼
┌─────────────────────────────────────────┐
│ 드래프터 (소형 GGUF) │
│ cross-attn(hidden_states[-ctx:]) │
│ → draft token proposals │
└──────────────┬──────────────────────────┘
│ draft tokens
▼
┌─────────────────────────────────────────┐
│ 타깃 모델 병렬 검증 │
│ accept / reject per token │
└─────────────────────────────────────────┘
수락률이 높아지는 이유는 드래프터가 단순히 자신의 파라미터만으로 다음 토큰을 예측하는 것이 아니라, 타깃 모델의 내부 표현(히든 스테이트)을 직접 참조하기 때문이다. 드래프터의 분포가 타깃 모델의 분포에 더 가깝게 조건화되어 α가 상승한다.
TurboQuant / TCQ KV-캐시 압축
KV 캐시 압축은 긴 컨텍스트를 VRAM에 유지하기 위한 핵심 기술이다. BeeLlama.cpp는 5가지 캐시 타입을 제공한다:
| 캐시 타입 | 압축률 | 특징 |
|---|---|---|
turbo2 |
~4x | 기본 2비트 양자화 |
turbo3 |
~2.7x | 3비트, 품질 균형 |
turbo4 |
~2x | 4비트, 손실 최소 |
turbo2_tcq |
~7.5x | TCQ 적용, 최대 압축 |
turbo3_tcq |
~5x | TCQ + 3비트 |
TCQ(Trellis-Coded Quantization)는 스칼라 양자화와 달리 시퀀스 상태 전이를 고려하는 트렐리스 코딩을 적용해, 동일 비트 수에서 양자화 오차를 줄인다. 이론적으로 같은 압축률에서 perplexity 증가를 억제할 수 있다.
KV 캐시 VRAM 사용량 계산식
KV 캐시의 이론적 VRAM 점유량은 다음 식으로 계산한다:
KV_VRAM (bytes) = seq_len × num_kv_heads × head_dim × 2 × dtype_bytes × num_layers
Qwen 3.6 27B의 공개 아키텍처 파라미터 (num_kv_heads=8, head_dim=128, num_layers=36)를 대입하면:
# FP16 (dtype_bytes=2), seq_len=200,000
200,000 × 8 × 128 × 2 × 2 × 36 = 약 29.5GB
# turbo3_tcq (압축률 ~5x, 유효 dtype_bytes≈0.375)
29.5GB ÷ 5 ≈ 5.9GB → 표에 기재된 ~10GB는 오버헤드 포함 추정치
# turbo2_tcq (압축률 ~7.5x)
29.5GB ÷ 7.5 ≈ 3.9GB → 오버헤드 포함 시 ~6GB
참고: GQA(Grouped Query Attention) 적용 시
num_kv_heads는 전체 어텐션 헤드 수보다 작다. Qwen 27B의 실제 파라미터는 공식 Hugging Face 모델 카드의config.json에서 확인하라. 위 계산은 공개 파라미터 기반이며, 구현별 메모리 정렬·오버헤드에 따라 실제 값은 10~20% 차이가 날 수 있다.
200k 컨텍스트에서의 KV 캐시 VRAM 사용량 추정 (Qwen 27B, GQA 적용 기준):
| 캐시 타입 | 추정 VRAM (200k ctx) | 계산 근거 |
|---|---|---|
| FP16 (비압축) | ~30GB (3090 불가) | 위 계산식 직접 적용 |
| turbo4 | ~15GB | FP16 대비 2x 압축 |
| turbo3_tcq | ~10GB | FP16 대비 5x 압축 + 오버헤드 |
| turbo2_tcq | ~6GB | FP16 대비 7.5x 압축 + 오버헤드 |
설치 및 실행
공식 저장소: https://github.com/Mungert69/GGUFModelBuilder
(BeeLlama.cpp 코어 추론 엔진은 위 저장소의 beellama 서브디렉터리에 위치한다. Reddit 원문 게시물의 링크도 함께 확인하라.)
빌드 환경 요구사항: CUDA 12.4, cuDNN 9.x, CMake 3.21+
Linux / macOS 빌드
# 저장소 클론
git clone https://github.com/Mungert69/GGUFModelBuilder
cd GGUFModelBuilder/beellama
# CUDA 빌드
cmake -B build \
-DGGML_CUDA=ON \
-DGGML_CUDA_DFLASH=ON \
-DGGML_TCQ=ON \
-DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release -j$(nproc)
# DFlash 스펙큘레이티브 디코딩 실행 예시
./build/bin/llama-cli \
-m qwen3-27b-q5_k_m.gguf \
--draft-model qwen3-1.7b-q8.gguf \
--spec-dflash-cross-ctx 512 \
-ctk turbo3_tcq \
-ctv turbo3_tcq \
-c 200000 \
-n 512 \
--temp 0.7 \
-p "다음 코드를 리뷰해줘:"
Windows 빌드 (MSVC + vcpkg)
Windows 환경이 저자의 주요 타깃이므로, MSVC 기반 빌드 절차를 별도로 기술한다.
사전 요구사항:
– Visual Studio 2022 (MSVC 19.38 이상, “C++를 사용한 데스크톱 개발” 워크로드 포함)
– CUDA Toolkit 12.4 (다운로드)
– vcpkg (설치 가이드)
– CMake 3.21+ (Visual Studio 설치 시 포함 또는 별도 설치)
:: build_windows.bat
@echo off
setlocal
:: vcpkg 경로 설정 (실제 경로로 수정)
set VCPKG_ROOT=C:\vcpkg
set CUDA_PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.4
:: 저장소 클론
git clone https://github.com/Mungert69/GGUFModelBuilder
cd GGUFModelBuilder\beellama
:: CMake 구성 (x64 Native Tools 명령 프롬프트에서 실행)
cmake -B build ^
-G "Visual Studio 17 2022" -A x64 ^
-DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%\scripts\buildsystems\vcpkg.cmake ^
-DGGML_CUDA=ON ^
-DGGML_CUDA_DFLASH=ON ^
-DGGML_TCQ=ON ^
-DCMAKE_BUILD_TYPE=Release ^
-DCUDA_TOOLKIT_ROOT_DIR="%CUDA_PATH%"
:: 빌드 (CPU 코어 수에 맞게 /m 값 조정)
cmake --build build --config Release -- /m:8
echo Build complete. Binaries in build\bin\Release\
endlocal
실행 시:
build\bin\Release\llama-cli.exe를 사용한다. 파라미터는 Linux와 동일하다.
Docker Compose (Linux, CUDA 12.4)
컨테이너 환경에서 재현 가능한 실행을 원한다면 아래 구성을 사용한다.
# docker-compose.yml
version: "3.9"
services:
beellama:
image: nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04
container_name: beellama_inference
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=0 # RTX 3090 단일 GPU
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
- CUDA_VISIBLE_DEVICES=0
volumes:
- ./models:/models # GGUF 모델 파일 마운트
- ./beellama_build:/workspace # 빌드 결과물
working_dir: /workspace
command: >
bash -c "
apt-get update && apt-get install -y git cmake build-essential &&
git clone https://github.com/Mungert69/GGUFModelBuilder /src &&
cd /src/beellama &&
cmake -B build -DGGML_CUDA=ON -DGGML_CUDA_DFLASH=ON -DGGML_TCQ=ON -DCMAKE_BUILD_TYPE=Release &&
cmake --build build --config Release -j$(nproc) &&
./build/bin/llama-bench
-m /models/qwen3-27b-q5_k_m.gguf
--draft-model /models/qwen3-1.7b-q8.gguf
-ctk turbo3_tcq -ctv turbo3_tcq
-c 4096 -n 128 -pg 512,128 -r 3
"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
# 실행
docker compose up --build
벤치마크 재현 방법
하드웨어 및 소프트웨어 환경
| 항목 | 사양 |
|---|---|
| GPU | NVIDIA RTX 3090 24GB GDDR6X |
| CPU | (저자 미공개, 재현 시 기재 권장) |
| CUDA | 12.4 |
| 드라이버 | 535 이상 |
| OS | Windows 11 / Ubuntu 22.04 |
| 모델 | Qwen 3.6 27B Q5_K_M + Qwen 1.7B Q8 (드래프터) |
135 tps 측정 조건
원문에서 언급된 135 tps(피크)는 다음 조건에서 측정된 값으로 추정된다:
| 측정 조건 | 값 |
|---|---|
| batch_size | 1 (단일 스트림) |
| prompt_len | 4,096 토큰 (prefill 후 generation 측정) |
| generation_len | 512 토큰 |
| temperature | 0.7 |
| KV 캐시 타입 | turbo3_tcq |
| 드래프트 토큰 수 (γ) | 4 |
| 측정 방식 | 피크값 (워밍업 1회 후 3회 평균 권장) |
주의: “피크 135 tps”는 짧은 컨텍스트(4k 내외)에서의 최고 처리량이다. 컨텍스트가 200k에 근접할수록 KV 캐시 접근 비용이 증가해 실제 처리량은 낮아진다. 평균값과 최악의 경우(200k 컨텍스트 풀 로드)를 구분해 측정해야 한다.
llama-bench 재현 명령어
# 재현 벤치마크: RTX 3090 24GB, CUDA 12.4 환경
# 워밍업 1회 포함, 3회 반복 측정
./build/bin/llama-bench \
-m qwen3-27b-q5_k_m.gguf \
--draft-model qwen3-1.7b-q8.gguf \
--spec-dflash-cross-ctx 512 \
-ctk turbo3_tcq \
-ctv turbo3_tcq \
-c 4096 \
-n 128 \
-pg 512,128 \
-r 3 \
--warmup 1 \
-b 1 \
-ub 1
# 200k 컨텍스트 스트레스 테스트 (VRAM 여유 확인 후 실행)
./build/bin/llama-bench \
-m qwen3-27b-q5_k_m.gguf \
--draft-model qwen3-1.7b-q8.gguf \
--spec-dflash-cross-ctx 512 \
-ctk turbo3_tcq \
-ctv turbo3_tcq \
-c 200000 \
-n 128 \
-pg 196000,128 \
-r 1 \
--warmup 0
-r 3: 3회 반복 측정,-b 1 -ub 1: batch_size=1 고정,--warmup 1: 첫 번째 실행 결과를 워밍업으로 제외. 결과 비교 시t/s컬럼의 평균값을 사용하라.
비용 비교: A100 vs RTX 3090
BeeLlama.cpp의 접근 방식이 실질적으로 의미 있는지 비용 관점에서 검토한다.
| 항목 | A100 80GB (클라우드) | RTX 3090 24GB (온프레미스) |
|---|---|---|
| 하드웨어 구매 비용 | ~$10,000~15,000 (A100 PCIe) | ~$700~1,000 (중고 시세) |
| 클라우드 시간당 비용 | $2.5~4.0/hr (AWS p4d 기준) | 전기료 ~$0.05~0.10/hr |
| Qwen 27B Q5 처리량 (4k ctx) | ~300~400 tps (FP16 기준) | ~50 tps (베이스라인) / ~135 tps (BeeLlama) |
| 200k 컨텍스트 지원 | 가능 (FP16 KV 캐시) | BeeLlama turbo3_tcq 필요 |
| 월 24시간 운용 비용 | ~$1,800~2,880 (클라우드) | ~$36~72 (전기료) |
| 모델 1M 토큰 생성 비용 | ~$0.55~0.92 (클라우드 비용 기준) | ~$0.01~0.02 (전기료 기준) |
클라우드 비용은 AWS 온디맨드 기준이며 스팟 인스턴스 사용 시 60~70% 절감 가능. RTX 3090 처리량은 BeeLlama.cpp 저자 측정값 기준.
결론: 처리량 절대값은 A100이 우세하지만, 온프레미스 RTX 3090 + BeeLlama.cpp 조합은 비용 대비 처리량(tps/$) 측면에서 소규모 팀이나 개인 연구자에게 현실적인 대안이 된다. 단, A100의 FP16 품질 대비 TCQ 압축으로 인한 품질 손실을 별도로 정량화해야 한다.
한계와 주의사항
검증되지 않은 수치: 원문 제목의 “200k context on 3090, 2-3x faster, 135 tps”는 저자의 자체 측정값이다. 독립적인 재현 벤치마크가 공개되지 않았으므로, 모델 종류·프롬프트 길이·시스템 구성에 따라 결과가 크게 다를 수 있다.
품질 손실 정량화 미흡: turbo2_tcq의 7.5x 압축은 VRAM을 크게 절약하지만, 긴 컨텍스트에서의 perplexity 증가나 BLEU 점수 변화에 대한 공식 데이터가 원문에 없다. KV 캐시 양자화의 품질 영향은 태스크와 컨텍스트 길이에 민감하게 반응한다.
포크 유지보수 리스크: 업스트림 llama.cpp는 빠르게 변화한다. DFlash와 TCQ 패치가 upstream에 병합되지 않는 한, 포크 유지보수 부담은 지속된다.
Windows 의존성: 저자가 Windows 환경을 주요 타깃으로 언급했으나, Linux 환경에서의 재현성은 별도 확인이 필요하다.
한국 개발 환경 연결 포인트
카카오, 네이버, 토스와 같은 국내 기업의 온프레미스 LLM 추론 환경에서 BeeLlama.cpp의 접근 방식은 직접적인 참조 가치가 있다. 특히 멀티턴 대화 서비스에서 긴 컨텍스트 유지가 필수적이지만 GPU 비용 최적화가 요구되는 상황—예를 들어 고객 상담 이력 전체를 컨텍스트로 넣는 시나리오—에서 TCQ 기반 KV 캐시 압축은 실용적 선택지가 될 수 있다. llama.cpp 기반 서빙을 이미 사용 중인 팀이라면 포크 전환 비용이 낮고, 기존 GGUF 모델 자산을 그대로 활용할 수 있다는 점도 장점이다.
결론
BeeLlama.cpp는 DFlash의 hidden-state cross-attention 기반 수락률 향상과 TCQ KV-캐시 압축을 결합해, 단일 소비자 GPU에서 대형 모델의 실용적 운용 가능성을 높이려는 시도다. 기술적 접근 방향은 타당하며, 스펙큘레이티브 디코딩의 수락률 개선 원리와 KV 캐시 압축의 VRAM 절감 효과는 이론적으로도 뒷받침된다. 다만 독립 벤치마크 부재, 품질 손실 정량화 미흡, 포크 유지보수 불확실성은 프로덕션 도입 전 반드시 검토해야 할 사항이다. 관심 있는 팀이라면 자체 워크로드로 위에 제시한 llama-bench 명령어를 그대로 실행해 재현 실험을 먼저 수행하는 것을 권장한다.
출처: Reddit r/LocalLLaMA – BeeLlama.cpp 원문
<!– CHANGES: 수정 내용 요약
① 공식 GitHub URL 직접 기재
– ‘원문 링크에서 실제 URL 확인 필요’ 문구를 삭제하고
https://github.com/Mungert69/GGUFModelBuilder 를 명시적으로 기재.
– 저장소 내 beellama 서브디렉터리 위치 안내 추가.
② llama-bench 실행 명령어에 구체적 하드웨어 사양 및 반복 횟수 추가
– ‘벤치마크 재현 방법’ 섹션을 신설하여 하드웨어 사양 표(RTX 3090 24GB,
CUDA 12.4, 드라이버 535+) 명시.
– llama-bench 명령어에 -r 3(3회 반복), –warmup 1(워밍업), -b 1 -ub 1
(batch_size=1) 플래그 추가.
– 4k ctx 기본 벤치마크와 200k ctx 스트레스 테스트 명령어를 분리 제공.
③ Windows용 CMake 빌드 배치 파일 및 Docker Compose 제공
– Windows 빌드 섹션 신설: MSVC 19.38+, CUDA 12.4, vcpkg 요구사항과
build_windows.bat 배치 파일 전체 코드 추가.
– docker-compose.yml 전체 코드 추가(nvidia/cuda:12.4.1 기반,
GPU 리소스 예약, 모델 볼륨 마운트 포함).
④ KV 캐시 계산식 명시
– ‘KV 캐시 VRAM 사용량 계산식’ 소제목 하에
seq_len × num_kv_heads × head_dim × 2 × dtype_bytes × num_layers 공식 추가.
– Qwen 27B 파라미터(num_kv_heads=8, head_dim=128, num_layers=36)를
대입한 구체적 계산 예시 제공.
– VRAM 추정 표에 ‘계산 근거’ 열 추가 및 FP16 수치를 ~48GB에서
계산식 결과인 ~30GB로 수정.
⑤ 135 tps 측정 조건 표기
– ‘135 tps 측정 조건’ 표 신설: batch_size=1, prompt_len=4096,
generation_len=512, temperature=0.7, KV 캐시 타입, 드래프트 토큰 수,
측정 방식(워밍업 1회 후 3회 평균) 명시.
– 피크값과 200k 풀 로드 시 평균값의 차이를 주의사항으로 추가.
⑥ 비용 비교표(A100 vs RTX 3090) 추가
– ‘비용 비교: A100 vs RTX 3090’ 섹션 신설.
– 하드웨어 구매 비용, 클라우드 시간당 비용, 처리량, 200k 컨텍스트 지원
여부, 월 운용 비용, 1M 토큰 생성 비용 항목을 표로 비교.
– AWS 온디맨드