23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
vLLM은 대규모 언어 모델(Large Language Model, LLM)을 고속으로 추론하기 위한 효율적인 엔진으로, 특히 serving 환경에서 높은 처리량과 낮은 지연 시간을 목표로 한다.
핵심 기술은 PagedAttention이라는 메모리 관리 기법으로, GPU 메모리를 효율적으로 분할·재사용함으로써 여러 요청을 동시에 빠르게 처리할 수 있게 해준다.
이를 통해 기존 대비 더 많은 동시 사용자 요청을 처리할 수 있고, 비용 효율적인 인퍼런스를 가능하게 한다.
Hugging Face Transformers 와도 호환되며, OpenAI API 스타일의 서버도 쉽게 구성할 수 있어 실무 적용이 용이하다.
vLLM 은 여러 연구 결과와 기술들을 효과적으로 조합하여 탄생 하였다. LLM 서빙 분야의 발전에 크게 기여 했다고 평가받는 주요 기술은 다음과 같다.
PagedAttention (vLLM 의 창시자인 권우석님 의 논문)
Split KV-cache into blocks + page table : like virtual memory management in OS
Fused kernel for attention using KV-cache
Efficient memory sharing for beam search, parallel sampling, etc.
Flash Attention
Tiling to reduce memory read/write
Fused operator : matrix multiplication + softmax operator
Continuous batching
ORCA : iteration level scheduling + selective batching (LLM 추론에 새로운 스케줄링 방식을 도입한 Friendli AI 의 유경인님 의 논문)
SARATHI : chunked-prefil + decode-maximal batching
vLLM의 설정 항목은 매우 다양한데, 테스트를 거쳐 성능에 영향을 주는 설정들을 골라보았다 (v0.7.0 기준).
최대 배치 토큰 크기 등 서비스 시나리오와 관련 있는 설정은 다루지 않았다.
--enable-prefix-cachingPrefix Caching 은 이전 요청의 KV 캐시를 저장해 두었다가, 이후 요청의 prefix 가 겹치는 경우 이를 재활용하는 방식이다.
특히 system prompt 가 길게 유지되는 서비스에 효과적이며, TTFT (First Token Latency) 와 throughput 모두에 긍정적인 효과를 준다.
TTFT 가 줄어드는 것은 일견 당연한데, throughput 도 서비스 시나리오에 따라 두 배 가까이 향상되기도 한다.
--enable-chunked-prefillORCA 에서 영향을 받은 vLLM 의 기본 스케줄러는 prefill 작업을 먼저, decode 는 나중 순으로 스케줄링 하는데 이 둘을 섞지는 않는다.
이로 인해 compute-bound 한 성격이 강한 다수의 prefill 작업이 한 번에 몰리면 decode 작업들이 밀리면서 평균 TTFT 가 저하되는 현상이 발생한다.
Chunked prefill 은 SARATHI 논문의 아이디어를 구현한 것으로, decode 를 우선적으로 스케줄링하고(decode-maximal),
남은 배치 영역에 하나의 prefill 을 잘라서(chunked-prefill) 포함시켜 토큰 생성의 효율을 높이는 방식이다.
논문에 "P-D 비율이 클수록 throughtput 이 높다", "prefill chunk 마다 KV-cache 억세스에 따른 상당한 오버헤드가 존재한다" 고 하는데 이것이 하나의 prefill 을 사용하는 이유로 생각된다.
이러한 이유로 설정 이름에는 chunk 가 들어가지만 chunk size 같은 왠지 있어야 할 것 같은 설정은 존재하지 않는다 (남은 배치 영역과 max-model-len 중 작은값으로 결정됨).
두개 이상의 prefill 을 하나의 배치에 포함하도록 하는 설정이 있기는 한데 (max-num-partial-prefills) 실제 써 본적은 없다.
1M 이상의 매우 긴 prompt 가 섞인 경우 해당 prompt 가 계속 chunk 되며 (chunk 된 prefill 이 다음 스케줄링시에 우선 순위가 있음) 다른 request 의 prefill 이 밀리는 문제가 있는데, 처리 순서가 중요(FIFO) 하지 않은 경우 max-long-partial-prefills, long-prefill-token-threshold 같은 설정을 사용할 수 있다.
Optimization and Tuning 에서는 chunked prefill 로 ITL 이 개선된다고 하는데 실제 테스트 결과 ITL 은 변화 없이 TTFT 가 개선되는 모습을 보여준다.
테스트 시나리오와 프로그램에 따라 다르다고 봐야 할 것 같다.
--num-scheduler-steps 10vLLM 팀의 성능 프로파일링 결과, GPU 의 연산량이나 대역폭의 문제 보다 오히려 CPU 에서의 스케줄링 오버헤드가 latency에 큰 영향을 주는 경우가 있는데 특히 작은 모델에서 이러한 영향이 잘 나타난다.
multi-step scheduling 은 매 iteration 마다 수행하던 스케줄링 작업을 n번에 한 번만 수행하도록 하여 이러한 오버헤드를 최소화 한다.
TTFT 를 어느 정도 포기하는 대신 throughput 을 올리는 방법에 가깝다.
--speculative-model [ngram]
# v0.8.2 이후
--speculative-config '{"method": "ngram"}'2024 년 가장 주목 받았던 기술 중 하나인 Speculative Decoding (SD)은 한 번에 여러 토큰을 생성한 뒤, 이를 병렬로 검증하는 방식으로 작동한다.
위 예시에서 설정한 "[ngram]" 은 사용자의 input prompt 에서 n-gram 을 추출하여 다음 토큰을 예측하는데,
이런 단순한 방식으로도 시나리오에 따라 latency 가 (정확히는 ITL 이) 절반으로 감소하는 효과를 얻을 수 있었다.
하지만 아쉽게도 LoRA 와 같이 사용할 수 없는데, 각 기능이 독립적으로 개발되는 오픈소스의 특성상 기능 간의 호환성 문제는 빠르게 해결되지 않는 느낌이다.
Medusa, Eagle 등 draft 모델이 아닌 최소한의 레이어만 추가하여 빠르게 다음 토큰을 생성하는 새로운 SD 방식도 도입 되고 있는데, 테스트 중 해결 불가능한 문제가 발생해서 실제 사용은 해보지 못했다.
-O3알파 버전 v1 엔진과 함께 새로 들어온 기능으로, PyTorch 모델을 자동으로 최적화하여 실행 속도를 높여 준다.
특히 TTFT 에 상당한 개선 효과가 있는데, 역시나 아쉽게도 SD 와 마찬가지로 LoRA 를 지원하지 않는다.
이 설정을 적용하면 다음과 같은 로그가 출력된다. compile 된 코드는 어딘가(~/.cache/vllm/torch_compile_cache/) 에 저장되어 다음 부팅때에 재사용된다.
INFO 02-25 01:46:38 backends.py:418] Dynamo bytecode transform time: 17.19 s
INFO 02-25 01:47:08 backends.py:132] Cache the graph of shape None for later use
INFO 02-25 01:47:08 backends.py:144] Compiling a graph for general shape takes 26.68 s
INFO 02-25 01:47:09 monitor.py:33] torch.compile takes 43.86 s in total
INFO 02-25 01:47:11 worker.py:267] Memory profiling takes 49.98 seconds기본으로 포함되는 dynamic shape 말고 직접 컴파일 할 배치 크기를 지정해 줄 수 있다. 시간이 제법 걸리지만 역시나 결과가 cache 되므로 다음 부팅때는 좀 더 빠르다.
--compilation-config="{'compile_sizes': [1, 2, 4, 8, 12, 16, 20]}"이 경우 Autotune 을 이용하여 최적의 파라미터(K, M, N, warp, etc.) 를 찾는 작업을 추가로 수행한다. 간단히 테스트 해 봤을 때 생각만큼 큰 효과는 없었다.
AUTOTUNE mm(8x2048, 2048x256)
triton_mm_199 0.0342 ms 100.0% ACC_TYPE='tl.float32', ALLOW_TF32=True, BLOCK_K=128, BLOCK_M=16, BLOCK_N=32, B_PROLOGUE_CAST_TYPE=None, EVEN_K=True, GROUP_M=8, num_stages=5, num_warps=2
triton_mm_198 0.0386 ms 88.6% ACC_TYPE='tl.float32', ALLOW_TF32=True, BLOCK_K=32, BLOCK_M=16, BLOCK_N=32, B_PROLOGUE_CAST_TYPE=None, EVEN_K=True, GROUP_M=8, num_stages=5, num_warps=2
triton_mm_197 0.0394 ms 86.9% ACC_TYPE='tl.float32', ALLOW_TF32=True, BLOCK_K=32, BLOCK_M=16, BLOCK_N=64, B_PROLOGUE_CAST_TYPE=None, EVEN_K=True, GROUP_M=8, num_stages=5, num_warps=4
triton_mm_202 0.0413 ms 82.7% ACC_TYPE='tl.float32', ALLOW_TF32=True, BLOCK_K=64, BLOCK_M=16, BLOCK_N=64, B_PROLOGUE_CAST_TYPE=None, EVEN_K=True, GROUP_M=8, num_stages=3, num_warps=4
triton_mm_209 0.0423 ms 80.9% ACC_TYPE='tl.float32', ALLOW_TF32=True, BLOCK_K=32, BLOCK_M=16, BLOCK_N=64, B_PROLOGUE_CAST_TYPE=None, EVEN_K=True, GROUP_M=8, num_stages=4, num_warps=4
triton_mm_196 0.0429 ms 79.7% ACC_TYPE='tl.float32', ALLOW_TF32=True, BLOCK_K=128, BLOCK_M=16, BLOCK_N=32, B_PROLOGUE_CAST_TYPE=None, EVEN_K=True, GROUP_M=8, num_stages=2, num_warps=2
triton_mm_205 0.0484 ms 70.7% ACC_TYPE='tl.float32', ALLOW_TF32=True, BLOCK_K=32, BLOCK_M=16, BLOCK_N=128, B_PROLOGUE_CAST_TYPE=None, EVEN_K=True, GROUP_M=8, num_stages=4, num_warps=8
triton_mm_208 0.0487 ms 70.2% ACC_TYPE='tl.float32', ALLOW_TF32=True, BLOCK_K=32, BLOCK_M=16, BLOCK_N=64, B_PROLOGUE_CAST_TYPE=None, EVEN_K=True, GROUP_M=8, num_stages=3, num_warps=4
triton_mm_206 0.0488 ms 70.1% ACC_TYPE='tl.float32', ALLOW_TF32=True, BLOCK_K=64, BLOCK_M=16, BLOCK_N=128, B_PROLOGUE_CAST_TYPE=None, EVEN_K=True, GROUP_M=8, num_stages=3, num_warps=4
mm 0.0513 ms 66.7%
SingleProcess AUTOTUNE benchmarking takes 1.6520 seconds and 0.0039 seconds precompiling앞서 말한 것 처럼 개별 기능의 안정화 및 개선 과는 별도로 이를 동시에 지원 하느냐와 이를 지원 하더라도 같이 사용시 문제가 없는지는 또다른 문제이다.
이러한 문제로 vLLM 은 호환성 매트릭스 를 통하여 두 기능 간의 호환성을 정리하고 있다.
하지만 세 가지 이상의 기능을 동시에 적용할 수 있는지 여부는 직접 테스트 해보는 수 밖에 없다.
아래는 주요 기능들 조합이 가능해진 버전의 개발 이력이다.
Chunked prefill + prefix caching (v0.6.0)
Multi-step scheduling + chunked prefill + prefix caching (v0.6.3)
LoRA + chunked-prefill (v0.6.5)
v0.7.3 시점 기준으로도 num-scheduler-steps 나 torch.compile 은 여전히 LoRA와 호환되지 않는다.
이로 인해 상용 엔진 대비 성능 차이가 생기기도 했고, SD 기술 적용에도 한계가 있어 LoRA 사용 자체를 포기할지 고민이 있었다.
다행히 새로 등장한 vLLM v1 엔진이 안정적인 성능을 내고, LoRA 에 대한 지원도 빠르게 개선되고 있어서 이 문제들은 조만간 해결될 것으로 보고 있다.
vLLM 은 새로운 기능 위주로 개발되어 왔고 성능도 개별 기능 단위로 개선되어 왔는데,
vLLM 프로젝트 전체로써의 성능에 집중하게 된 것은 아래 블로그의 글의 영향이 크다고 알려져 있다.
Achieving Faster Open-Source Llama3 Serving with SGLang Runtime (vs. TensorRT-LLM, vLLM)
새로운 오픈 소스 LLM 서빙 시스템인 SGLang 이 vLLM (v0.5.2) 대비 3.1 배까지 빠르다(Llama3.1-70B 기준)는 내용이다. 심지어 v0.5.3 은 돌아가지 않더라는 코멘트도 있다.
vLLM 도 여기에 대한 응답으로 여러가지 성능 개선 방안을 탐구하여 적용하였다.
vLLM v0.6.0: 2.7x Throughput Improvement and 5x Latency Reduction
vLLM v0.6.0 이 v0.5.3 대비 2.7배 빨라졌다는 내용인데, 한달 남짓한 기간동안 해치운 일을 보면 얼마나 열 받았는지를 알 수 있다.
API 서버와 추론 엔진을 별도 프로세스로 분리 (PR #6883)
- OpenAI 프로토콜에 맞춘 네트워크 요청 처리 및 응답 포맷팅이 CPU 자원을 상당히 소모함
- HTTP 서비스 컴포넌트를 vLLM 엔진과 분리하고, 두 컴포넌트를 ZMQ 소켓으로 연결함
배치 스케줄링을 여러 스텝 앞까지 예측 수행 (PR #7000)
- vLLM의 스케줄러와 입력 준비 과정에서 발생하는 CPU 오버헤드로 인해 GPU 자원이 충분히 활용되지 않음
- 스케줄링 및 입력 준비를 한 번만 수행하고, 모델을 n개의 연속된 스텝 동안 실행
- Llama 70B 모델을 4xH100에서 실행할 때 처리량이 28% 향상됨
비동기 출력 처리 (PR #7049, #7921, #8050)
- 이전에는 토큰을 생성한 후, GPU에서 CPU로 출력을 옮기고 정지 조건을 체크한 뒤 다음 스텝을 실행함
- 출력 처리 과정을 모델 실행과 겹치게 비동기로 처리함
- Llama 70B 모델을 4xH100에서 실행할 때 토큰당 생성 시간이 8.7% 향상됨
기타 최적화
- Python 객체 캐시 (#7162) : 엔드 투 엔드 처리량 24% 향상
- CPU → GPU 논블로킹 통신 (#7172)
- 단순 샘플링 파라미터에 대한 빠른 경로 처리 (#7117)하지만 sLLM 의 성능 개선과 함께 LLM 서빙이 중요한 트렌드로 자리잡자 vLLM 과의 성능 비교는 끊이질 않았다.
아래는 TensorRT-LLM 이 위의 개선사항을 모두 포함한 vLLM v0.6.1 대비 16% 정도 빠르다는 글이다.
계속적으로 vLLM 성능에 대한 구설수가 있자 vLLM 팀은 그간 쌓인 엔지니어링 부채도 탕감할 겸 아예 새로 구현 하기로 하고 기존 엔진을 완전 대체할 차기 V1 엔진의 구조를 설계 하였다 .
여기서 밝히는 기존 엔진의 문제점들은 다음과 같다.
결국 GPU 는 점점 빨라지지만 IO 와 CPU 는 상대적으로 느린데 앞으로도 계속 느릴 것이고, 이들을 최적화 하는 것이 성능 개선의 핵심이라는 내용이다.
이를 반영한 v1 엔진의 설계 사상의 핵심은 GPU 를 전담하는 statefull 한 프로세스를 별도로 만들고 GPU 작업시간에 CPU 작업을 최대한 압축하여 비동기적으로 처리하는 것이다.
이를 통해 GPU 의 idle time 을 최소화 하고, 유연한 모듈식 구조를 도입하여 새로운 기능의 확장을 용이하게 하며, 새로운 기능이 추가 되더라도 다른 기능들과 완전히 호환되게 하는 것을 목표로 한다.
마지막 절은 vLLM 사용자가 기존에 쓰던 기능이 새롭게 추가된 기능과 같이 사용 가능한지에 대해 더이상 고민할 필요가 없다는 것을 의미한다.
생각보다 빠르게 v1 엔진의 V1 엔진의 알파 버전이 공개 되었다.
v0.7.0 부터 써볼 수 있게 되었으며(VLLM_USE_V1=1) 다음과 같은 개선 사항들이 있다.
초기에는 LoRA 를 지원하지 않거나(v0.7.x) 엄청 느린(v0.8.0) 문제가 있었으나 점점 개선되어 가는 중이다.
몇가지만 살펴보면,
기존에는 inference 서버가 단일 process 내에서 model 실행과 스케줄링을 함께 처리 했으나 v1 에서는 EngineCore 라 불리는 별도의 process 를 생성하여 사용한다.
CPU 오버헤드가 줄어드는 효과와 동시에 스케줄링과 execution 이 분리되어 구조적 확장이 용이하게 되었다.
prefill 과 decode 의 구분을 없에서 코드를 단순화 하고 GPU 가 작업하는 동안(async) 다음 iteration(single-step) 의 스케줄링을 작업을 수행한다.
이로써 chunked-prefill 이나 multi-step scheduling 설정이 말 그대로 의미가 없게 되었다.
여기에 LMDeploy 에서 사용된 persistent batch 를 적용하여 CPU 오버헤드를 최소화 하였다.
기존 vLLM 의 prefix cache 는 오버헤드가 많은 것으로 악명이 높았는데, 이를 개선하여 0% cache-hit 에서도 성능이 떨어지지 않게 되었다고 한다.
v1 엔진을 쓰면 디폴트로 작동한다.
모델 전체를 CUDA Graph 캡처하던 기존 방식과 달리 torch compile 한 코드에서 attention 부분만 잘라서 떼고 남은 부분들(piecewse)을 CUDA Graph 캡처하는 방식이다.
이는 attention 내부에 계속 발전하는 KV cache 관련 로직이 포함되어 있고, 최신 모델들의 attention 메커니즘이 점점 다양해짐에 따라 이들 모두를 CUDA-compatible 하게 구현하기 어렵기 때문이다.
v0.8.2 이전에는 LoRA 와 함께 동작하지 않았으나 0.8.2 부터는 사용할 수 있게 되었다.
v0.8.3 기준으로 v1 엔진을 사용하면 컴파일 옵션을 어떻게 설정해도 무조건 적용되기 때문에 O3 옵션도 의미가 없어졌다.
기본 설정에서는 symbolic shape 를 사용하여 하나의 torch.compile 그래프를 생성한 뒤, 다양한 batch size 에 대해 각각 CUDA Graph 를 캡처하는 방식으로 동작한다.
VLLM_LOGGING_LEVEL=DEBUG 를 설정하면 진행 상황에 대한 자세한 로그를 볼 수 있는데
아래는 LoRA 를 적용한 batch size 40 인 shape 에 대해 CUDA Graph 를 캡처하는 로그이다.
DEBUG 04-01 07:46:50 [models.py:36] Removing adapter int id: 1
DEBUG 04-01 07:47:10 [models.py:728] Adding lora. Model id: 1, int id: 1, scaling factor: 1
DEBUG 04-01 07:47:10 [models.py:394] Activating LoRA. int id: 1, slot index: 0
DEBUG 04-01 07:47:10 [backends.py:643] Warming up 1/1 for shape 40
DEBUG 04-01 07:47:10 [models.py:36] Removing adapter int id: 1
DEBUG 04-01 07:47:10 [models.py:36] Removing adapter int id: 1
DEBUG 04-01 07:47:30 [models.py:728] Adding lora. Model id: 1, int id: 1, scaling factor: 1
DEBUG 04-01 07:47:30 [models.py:394] Activating LoRA. int id: 1, slot index: 0
DEBUG 04-01 07:47:30 [backends.py: 654] Capturing a cudagraph for shape 40
DEBUG 04-01 07:47:31 [models.py:36] Removing adapter int id: 1
DEBUG 04-01 07:47:31 [models.py:36] Removing adapter int id: 1
DEBUG 04-01 07:47:50 [models.py: 728] Adding lora. Model id: 1, int id: 1, scaling factor: 1H100 에서 기본 설정으로 Llama3.1-8B 모델을 부팅하면, 1부터 512까지 총 67개의 batch size 에 대해 CUDA Graph 를 캡처하게 된다.
하나의 shape 당 캡처 시간은 보통 1초 미만으로, 전체 작업은 1분 이내에 완료된다.
LoRA 를 사용하지 않을때는 문제가 없었지만 위 로그에서 확인할 수 있듯, LoRA 를 설정(--enable-lora) 하는 경우 shape 당 길게는 40초가 넘게 소요되는 문제가 발생했다.
vLLM GitHub 이나 Slack 에는 유사한 이슈가 보고되지 않는 것으로 보아 특정 환경에서만 발생하는 문제로 추정된다.
일주일간의 시행착오 끝에, 다음과 같은 환경 변수를 설정함으로써 문제를 회피할 수 있었다. 동일한 문제를 겪는 경우 아래 설정을 시도해 보시길 권한다.
OMP_NUM_THREADS=32또한, 동시 사용자 수가 제한적인 서비스라면 예상 사용자 수에 batch size 의 최대값을 맞추고, 구간을 더 촘촘하게 설정하는 것이 성능 면에서 약간의 이점을 줄 수 있다고 한다.
예를 들어, 최대 동시 사용자 수가 60을 넘지 않는다면 아래와 같이 설정하는 식이다.
--compilation_config "{'cudagraph_capture_sizes': [1, 2, 4, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64]}"Hopper GPU 를 사용할 수 있는 환경이라면 v1 엔진을 통해 성능이 대폭 개선된 FlashAttention 3 를 사용할 수 있게 되었다.
GEMM-Softmax 오버래핑과 에러를 최소화한 FP8 연산으로 기존 대비 연산량이 두배 가까이 차이가 난다.
Attention 을 별도로 설정(VLLM_ATTENTION_BACKEND) 하지 않으면 FlashAttention 을 사용하는데, 내부적으로 알아서 GPU 버전에 맞춰 version 을 적용한다.
문서에는 VLLM_FLASH_ATTN_VERSION 로 임의로 변경할 수 있을 것 처럼 되어 있지만 그냥 무시되는 듯 하다.
V1 엔진 이전에는 prefix caching, chunked prefill, multi-step scheduling, torch compile 등의 옵션들을 바꿔가며 어떤 설정이 서비스 시나리오에 최적인지를 찾는 작업이 필요했다.
하지만 V1 에서는 이 모든 설정들이 필요가 없어지거나 디폴트로 적용되기 때문에 운영자 입장에서 딱히 고민할 거리가 없다는 점이 크게 어필하는 부분이다.
다만 V1 의 성능이 기존 엔진(V0)에 최선의 설정을 했을때 보다 더 나은지 혹은 떨어지더라도 큰 차이가 없는지를 확인하는 과정은 필요하다.
간단한 시나리오와 테스트로 확인해 보자.
v0.7.0 | +CP | +PC | +MSS | +PC+MSS | +PC+CP | +PC+CP+MSS | v0.7.0 (v1) | v0.8.3 (v1) | +ngram | |
|---|---|---|---|---|---|---|---|---|---|---|
out-token/sec | 1760.87 | 1888.99 | 1883.29 | 1919.41 | 2101.06 | 2025.77 | 2180.78 | 2172.94 | 2154.32 | 2722.66 |
TTFT (mean) | 371.57 | 153.08 | 325.81 | 487.31 | 411.27 | 140.02 | 382.80 | 198.22 | 182.06 | 159.91 |
TTFT (P50) | 167.90 | 90.47 | 130.59 | 319.72 | 307.72 | 91.97 | 384.05 | 103.15 | 120.94 | 101.15 |
TTFT (P99) | 1542.30 | 1518.04 | 1293.87 | 1555.57 | 1263.88 | 1307.34 | 1632.63 | 1477.07 | 1307.33 | 1419.03 |
v0.7.0 Base 에 CP (chunked prefill), PC (prefix cache), MSS 10 (multi-step scheduling) 을 각각 혹은 동시에 같이 적용한 테스트 결과이다
(O3 는 큰 차이가 없어서 생략했다. n-gram 은 서비스 특성을 많이 타므로 일단 무시하자).
CP, PC, MSS 세 가지 모두 쓰루풋이 개선되지만 TTFT 측면에서는 특성이 다른 것을 알 수 있다.
CP 는 TTFT 가 개선되는 반면 MSS 의 경우 오히려 이를 증가시킨다. PC 는 모든 수치가 전반적으로 좋아지는 것을 알 수 있다.
PC+CP, PC+MSS 의 조합도 비슷한 결과이다. 셋을 모두 조합하면 쓰루풋 측면에서는 가장 좋지만 TTFT-P50 은 매우 떨어진다.
이를 V1 의 결과와 비교해 보면 쓰루풋과 TTFT 모두 최선은 아니지만 둘 다 최선에 가까운 결과를 내는 것을 볼 수 있다.
좀더 heavy 한 서비스를 가정해 보자
v0.7.0 | +CP | +PC | +MSS | +PC+MSS | +PC+CP | +PC+CP+MSS | v0.7.0 (v1) | v0.8.3 (v1) | +ngram | |
|---|---|---|---|---|---|---|---|---|---|---|
out-token/sec | 678.48 | 715.1 | 881.94 | 693.84 | 920.26 | 941.55 | 829.04 | 1070.65 | 1063.59 | 1393.09 |
TTFT (mean) | 1880.4 | 924.21 | 1250.39 | 1536.52 | 1203.71 | 581.47 | 7439.99 | 536.11 | 540.65 | 600.47 |
TTFT (P50) | 606.51 | 532.18 | 428.57 | 751.16 | 519.14 | 376.41 | 7441.64 | 300.00 | 304.93 | 417.52 |
TTFT (P99) | 8699.91 | 10458.29 | 5697.97 | 8594.55 | 5737.38 | 6393.64 | 10308.27 | 5117.71 | 5634.43 | 5179.76 |
PC+CP+MSS 모두 적용한 경우 쓰루풋도 조금 내려가고 TTFT 는 전반적으로 매우 안좋아졌다. 반면 V1 은 두가지 메트릭에서 최선의 결과를 내었다.
두 테스트에서 0.7.0 과 0.8.3 의 v1 엔진은 거의 차이가 없거나 오히려 최신 버전이 약간 낮은 성능을 보이는데, LoRA 지원이 점점 좋아지고 있다는 것만으로도 충분히 위안이 된다.
그럼 과연 vLLM V1 엔진은 앞서 언급 했던 다른 LLM 서빙 엔진들의 도전을 물리쳤는가? 아직은 SGLang 같은 가벼운 엔진의 성능이 조금이라도 더 나아보인다.
https://x.com/lmsysorg/status/1913064701313073656?s=46&t=5dc2It8fgDoPPNfyFViTdw
Llama4 scout
아래는 올초 AI 계를 강타했던 DeepSeek R1 모델의 성능 비교이다.
SGLang 이 MTP 를 지원해서 이럴 리가 없을 것 같은데, LLM 세상에는 테스트를 어떻게 했는지를 말 안해주는 암묵적인 문화가 있는 듯 하다.
https://x.com/vllm_project/status/1913004324613243166
다들 아시겠지만 이런 벤치마크 결과값은 모델이나 환경 설정, 시나리오에 따라 크게 달라져서 결정적인 것이라 보기는 힘들고, 그냥 vLLM 도 열심히 하고 있구나 라는 정도로 이해 하시면 될 것 같다.
결론적으로 성능이 두배까지 차이나는 상황만 아니라면 커뮤니티 활성도가 높고 빠르게 진화하는 vLLM 을 계속 사용하게 될 것 같다.
SGLang 도 한번 해보면 좋겠지만 일단 올해는 vLLM 에 SD 까지 적용해서 서비스에 반영하는 것을 목표로 하고 있다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.