vLLM을 사용하여 Vision-Language Model (VLM)의 추론 속도를 가속화하는 간단한 예제와 실험 결과입니다.
🎯 핵심 결과: vLLM + BF16 설정으로 Transformers 대비 7.34배 속도 향상
acceleration/
├── vllm_vlm_simple.py # vLLM VLM 추론 간단 예제 (시작하기 좋음!)
├── vllm_acceleration.py # 종합 벤치마크 코드 (Transformers vs vLLM)
├── README.md
└── benchmark_results/
├── benchmark_comparison.png # 성능 비교 그래프
├── benchmark_report.txt # 상세 리포트
└── benchmark_results.json # JSON 결과
가장 기본적인 vLLM VLM 추론 예제입니다.
python acceleration/vllm_vlm_simple.py image.jpgTransformers와 vLLM의 성능을 비교하는 벤치마크
python acceleration/vllm_acceleration.py벤치마크 결과:
- 📊
benchmark_results/benchmark_comparison.png- 성능 비교 그래프 - 📄
benchmark_results/benchmark_report.txt- 상세 리포트 - 📋
benchmark_results/benchmark_results.json- JSON 결과
llm = LLM(
model="Qwen/Qwen2-VL-7B-Instruct",
# 데이터 타입 (속도 vs 정확도 트레이드오프)
dtype="bfloat16",
# GPU 메모리 사용률 (KV cache 크기 결정)
gpu_memory_utilization=0.7,
# 신뢰할 수 있는 원격 코드 실행 허용
trust_remote_code=True,
# 로컬 이미지 파일 경로 허용
allowed_local_media_path=".",
# Chunked Prefill (긴 시퀀스 처리 최적화)
enable_chunked_prefill=True,
# CUDA Graph (반복 호출 최적화)
enforce_eager=False,
# Tensor Parallelism (다중 GPU)
tensor_parallel_size=1,
)sampling_params = SamplingParams(
temperature=0.1, # 0.0: deterministic, 1.0: creative
top_p=0.95, # nucleus sampling (0.9~0.95 권장)
max_tokens=128, # 생성할 최대 토큰 수
top_k=50, # top-k sampling (선택사항)
repetition_penalty=1.0, # 반복 패널티
)- GPU: NVIDIA A100-SXM4-80GB (80GB VRAM)
- 모델: Qwen2-VL-7B-Instruct
- CUDA: 12.8
- PyTorch: 2.9.0+cu128
- 측정 방법: 각 설정당 10회 추론 후 평균
| 실험 | 평균 추론 시간 | 처리량 (req/s) | GPU 메모리 | Speedup |
|---|---|---|---|---|
| 1. Transformers Baseline | 14.90초 | 0.07 | 17.6 GB | 1.00x |
| 2. vLLM + No Chunked Prefill | 3.34초 | 0.30 | 65.1 GB | 4.46x |
| 3. vLLM + No CUDA Graph | 4.08초 | 0.25 | 66.0 GB | 3.66x |
| 4. vLLM Baseline (FP32) | 3.33초 | 0.30 | 64.7 GB | 4.47x |
| 5. vLLM + BF16 | 2.03초 | 0.49 | 69.9 GB | 🏆 7.34x |
설정: Hugging Face Transformers 라이브러리 사용, FP16 정밀도
- ⏱️ 평균 추론 시간: 14.90초
- 💾 GPU 메모리: 17.6 GB (가장 효율적)
- 📦 모델 로드 시간: 11초
가장 메모리 효율적이지만 추론 속도가 가장 느림. 단일 요청 처리에 최적화되어 있으며 KV cache 관리 및 배치 처리 최적화가 부족함.
설정: vLLM 사용, FP32 정밀도, Chunked Prefill 비활성화 (enable_chunked_prefill=False)
- ⏱️ 평균 추론 시간: 3.34초 (4.46x 빠름)
- 💾 GPU 메모리: 65.1 GB
- 📦 모델 로드 시간: 153초
Chunked Prefill을 비활성화해도 성능이 우수함. 짧은 시퀀스에서는 Chunked Prefill의 영향이 미미하며, vLLM의 기본 최적화(PagedAttention, CUDA Graph)만으로도 큰 성능 향상을 달성함.
💡 Chunked Prefill이란? 긴 입력 시퀀스를 여러 청크로 나누어 처리하는 기법. 메모리 사용량을 줄이고 긴 컨텍스트 처리 시 안정성을 향상시키지만, 짧은 시퀀스에서는 오버헤드가 발생할 수 있음.
설정: vLLM 사용, FP32 정밀도, CUDA Graph 비활성화 (enforce_eager=True)
- ⏱️ 평균 추론 시간: 4.08초 (3.66x 빠름)
- 💾 GPU 메모리: 66.0 GB
- 📦 모델 로드 시간: 127초
CUDA Graph 비활성화 시 약 22% 성능 저하 (3.34초 → 4.08초). CUDA Graph가 vLLM 성능에 중요한 역할을 하며, 디버깅이나 특수한 경우가 아니면 활성화 권장.
💡 CUDA Graph란? CUDA 연산을 그래프로 캡처하여 재사용하는 기법. CPU-GPU 동기화 오버헤드를 줄여 반복 호출 시 성능을 향상시킴.
설정: vLLM 기본 설정, FP32 정밀도, 모든 최적화 활성화
- ⏱️ 평균 추론 시간: 3.33초 (4.47x 빠름)
- 💾 GPU 메모리: 64.7 GB
- 📦 모델 로드 시간: 147초
vLLM의 기본 설정만으로 Transformers 대비 4.47배 빠름. Chunked Prefill과 CUDA Graph가 모두 활성화되어 최적의 성능을 발휘하며, FP32 정밀도로 최고 정확도를 보장함.
설정: vLLM 사용, BF16 정밀도 (dtype="bfloat16")
- ⏱️ 평균 추론 시간: 2.03초 (7.34x 빠름) 🏆
- 💾 GPU 메모리: 69.9 GB
- 📦 모델 로드 시간: 67초 (가장 빠름)
- 📊 처리량: 0.49 requests/sec (최고)
가장 빠른 설정으로 Transformers 대비 7.34배, FP32 대비 39% 추가 성능 향상. 모델 로드 시간도 절반 이상 단축되며, 메모리 사용량은 약간 증가하지만 A100 80GB에서 충분히 여유가 있음.
💡 BF16 (bfloat16)이란? Google이 개발한 16비트 부동소수점 형식. FP32와 동일한 지수 범위(8비트)를 가져 수치 안정성이 우수하며, FP16보다 정확도가 높고 오버플로우/언더플로우에 강함. A100 GPU에서 하드웨어 가속을 지원함.
- 기본 설정만으로도 Transformers 대비 4.47배 빠름
- PagedAttention, KV cache 최적화, CUDA Graph 등 다양한 최적화 기법 적용
- FP32 대비 39% 추가 성능 향상
- 정확도 손실 거의 없음
- CUDA Graph 비활성화 시 22% 성능 저하
- 반복적인 추론 작업에서 필수적인 최적화
- Transformers: 17.6 GB, 14.90초 (메모리 효율적)
- vLLM + BF16: 69.9 GB, 2.03초 (속도 우선)
- A100 80GB에서는 vLLM + BF16 사용 권장
