개요
ChatGPT가 세상에 나온 이후로 정말 눈 깜짝할 새에 빠르고 정확하고, 심지어 이미지나 음성까지 다루는 멀티모달 모델들이 쏟아져 나오고 있습니다. 특히 2024년에는 상용 LLM(ex. chatgpt)과 오픈소스 LLM(ex. llama)이 서로 경쟁하면서 정말 놀라운 발전을 보여주고 있습니다.
하지만 이렇게 뛰어난 LLM을 실제 서비스에 활용하려면 넘어야 할 산이 있습니다. 그중 하나가 바로 '속도' 문제입니다. gemma2 9B처럼 중간 크기의 LLM도 일반적인 환경에서는 응답을 받는 데 수십 초씩 걸릴 정도로 느립니다. 이렇게 느린 속도는 사용자 경험에 부정적인 영향을 미칠 수 있기 때문에 LLM을 효율적으로 서비스하는 기술이 매우 중요해졌습니다.
그래서 이 글에서는 vLLM과 Triton Inference Server를 이용해서 LLM의 추론 속도를 획기적으로 높이는 방법을 소개합니다. 두 기술의 기본 원리보다는 실제 사용 방법을 설명하며, 어떻게 생성형 LLM을 실시간으로 서비스할 수 있는지 알아보도록 하겠습니다.
vLLM: Easy, fast, and cheap LLM serving for everyone
Github: https://github.com/vllm-project/vllm?tab=readme-ov-file
Documentation: https://docs.vllm.ai/en/stable/
- vLLM은 LLM의 추론(inference)과 서빙(serving)을 위한 고성능 오픈소스 라이브러리입니다.
💫 PagedAttention
vLLM의 가장 중요한 특징은 PagedAttention이라는 새로운 어텐션 알고리즘입니다. 특징은 다음과 같습니다.
- GPU 메모리를 작은 블록으로 나누어 효율적으로 관리합니다.
- *KV cache를 더 작은 블록으로 나누고 비연속적으로 할당하여 메모리 단편화를 크게 줄입니다.
- 사용 할 메모리를 지정해서 미리 할당하여 전체 메모리 사용 효율을 높입니다.
*KV cache
KV cache(Key-value cache)는 Transformer 구조에서 중복 계산을 줄여 추론 속도를 향상시키기 위한 기술입니다. Transformer 구조는 이전 입력 토큰들을 이용해 self-attention을 계산하는데, 이미 계산된 attention 결과를 저장하고 재사용하면 효율을 높일 수 있습니다.
예를 들어, 새로운 단어를 생성할 때 이전 토큰에 대한 계산은 이미 저장된 값을 사용하므로 중복 작업을 피할 수 있습니다.
vLLM Quick start
(1) vLLM 설치하기
요구사항
OS: Linux (windows, mac os는 지원하지 않는다.)
Python: 3.9 – 3.12
GPU: compute capability 7.0 or higher (e.g., V100, T4, RTX20xx, A100, L4, H100, etc.)
vLLM 설치는 conda, pip를 통해 설치할 수 있습니다.
$ # (Recommended) Create a new conda environment.
$ conda create -n myenv python=3.10 -y
$ conda activate myenv
$ # Install vLLM with CUDA 12.1.
$ pip install vllm
* conda를 통해 설치를 할 수 있지만, 공식문서에서는 pip로 설치하는 것을 적극 권장합니다.
Offline Batched Inference with vLLM
vLLM을 사용하면 여러 입력 프롬프트에 대해 텍스트를 생성할 수 있는 오프라인 배치 추론(Offline Batched Inference)을 실행할 수 있습니다.
먼저 아래와 같이 LLM과 SamplingParams 클래스를 import 합니다.
from vllm import LLM, SamplingParams
- LLM: vLLM 엔진을 사용해 오프라인 추론을 실행하는 주요 클래스입니다.
- SamplingParams: 샘플링 과정에서 사용되는 매개변수를 지정합니다.
샘플링 설정 및 입력 정의
다음은 입력 프롬프트와 샘플링 매개변수를 정의하는 코드입니다. 여기서 temperature는 0.8로, top_p은 0.95로 설정되어 있습니다.
prompts = [
"Hello, my name is",
"The president of the United States is",
"The capital of France is",
"The future of AI is",
]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
LLM 엔진 초기화
이제 LLM 클래스를 사용해 vLLM 엔진과 모델을 초기화합니다. 아래는 OPT-125M 모델을 사용하는 예제입니다.
llm = LLM(model="facebook/opt-125m")
참고
기본적으로 vLLM은 HuggingFace에서 모델을 다운로드합니다. ModelScope의 모델을 사용하려면 VLLM_USE_MODELSCOPE 환경 변수를 설정한 후 엔진을 초기화하세요.
텍스트 생성 실행
가장 중요한 부분은 텍스트를 생성하는 과정입니다! llm.generate를 사용하면 입력 프롬프트를 vLLM 엔진의 대기열에 추가하고, 높은 처리량으로 출력을 생성할 수 있습니다. 생성된 출력은 RequestOutput 객체 리스트로 반환되며, 출력 텍스트를 포함합니다.
예제 코드
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
prompt = output.prompt
generated_text = output.outputs[0].text
print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
출력 예시
각 프롬프트와 생성된 텍스트는 다음과 같은 형식으로 출력됩니다.
Prompt: 'Hello, my name is', Generated text: 'John Doe.'
Prompt: 'The president of the United States is', Generated text: 'Joe Biden.'
...
Triton Inference Server: 효율적인 LLM 서빙
Github : https://github.com/triton-inference-server
NVIDIA Triton Inference Server는 모델 배포 및 실행을 표준화할 수 있도록 도와주고, 프로덕션 환경에 빠르고 확장 가능한 AI를 제공하는 오픈 소스 추론 지원 소프트웨어입니다
다양한 프레임워크 지원
- TensorFlow, PyTorch, ONNX, TensorRT, XGBoost 등 여러 딥러닝 프레임워크를 지원합니다.
- 하나의 서버에서 다양한 프레임워크의 모델을 동시에 운영할 수 있습니다.
고성능 추론
- C++ 기반으로 개발되어 Python 기반 추론보다 빠른 성능을 제공합니다.
- 단일 GPU에서 여러 모델을 효율적으로 실행할 수 있도록 설계되었습니다. (멀티 GPU 환경도 지원)
- 동적 배치(Dynamic Batching) 기능을 통해 지연 시간을 최소화하고 처리량을 최적화합니다.
확장성 및 운영 효율성
- Kubernetes와의 통합을 지원하여 확장 및 모니터링이 용이합니다.
- 멀티 GPU 환경을 지원합니다.
- Prometheus 기반의 모니터링 기능을 제공합니다.
성능 이점
- TensorRT 변환 모델 사용 시, PyTorch 모델 대비 GPU 메모리 사용량을 절반 이하로 줄일 수 있습니다.
- TensorRT 모델은 처리량이 PyTorch 모델 대비 약 2배 이상 향상될 수 있습니다.
Triton Inference Server는 이처럼 다양한 기능을 제공하여 AI 모델의 효율적인 배포와 운영을 지원하며, 특히 실시간 추론이 요구되는 애플리케이션에 적합한 솔루션입니다.
Triton Inference Server Quick start
vLLM용 Triton backend는 Python-based backend입니다. 해당 backen를 사용하면 모든 요청이 수신되는 즉시 vLLM AsyncEngine에 배치됩니다.
Inflight batching 이나 paged attention은 vLLM AsyncEngine에서 처리됩니다.
Installing the vLLM Backend
vLLM backend를 설치하는 방법은 여러가지가 있지만, 본 글에서는 사전에 빌드된 Docker image를 활용합니다.
docker pull nvcr.io/nvidia/tritonserver:<xx.yy>-vllm-python-py3
# docker pull nvcr.io/nvidia/tritonserver:24.11-vllm-python-py3
<xx.yy> 안에는 사용할 이미지 버전을 적으면 됩니다.
Using the vLLM Backend
Triton에서 vLLM을 사용하는 예제는 링크 의 model_repository에서 확인할 수 있습니다.
다음 단계를 통해 설정을 진행할 수 있습니다.
1. 모델 변경
- model_repository 폴더에 있는 model.json 파일을 수정하여 모델을 변경할 수 있습니다.
- model.json은 vLLM의 AsyncLLMEngine을 초기화할 때 전달되는 key-value 형식의 설정 파일입니다.
- 사용 가능한 인수는 vLLM의 arg_utils.py에서 확인할 수 있습니다.
2. 멀티 GPU 지원
- model.json에서 tensor_parallel_size와 같은 EngineArgs를 지정하여 멀티 GPU를 활용할 수 있습니다.
3. GPU 메모리 관리
- 기본 설정으로 vLLM은 GPU 메모리의 최대 90%를 사용합니다.
- 샘플 모델에서는 gpu_memory_utilization 값을 50%로 설정하여 메모리 사용량을 조정합니다.
- 필요에 따라 model.json의 gpu_memory_utilization 및 기타 설정을 수정해 최적화할 수 있습니다.
Triton Inference Server 실행
모델 설정이 완료되었다면 Triton 서버를 실행할 차례입니다. Installing the vLLM Backend 에서 설명한 공식 이미지를 활용합니다.
docker run --gpus all -it --net=host --rm -p 8001:8001 \
--shm-size=1G --ulimit memlock=-1 --ulimit stack=67108864 \
-v ${PWD}:/work -w /work nvcr.io/nvidia/tritonserver:<xx.yy>-vllm-python-py3 \
tritonserver --model-repository ./model_repository
<xx.yy>를 사용하려는 Triton 버전으로 대체해야합니다.
서버 출력 확인
서버 실행 후, 다음과 같은 출력이 나타나면 Triton이 요청을 받을 준비가 완료된 상태입니다:
I1030 22:33:28.291908 1 grpc_server.cc:2513] Started GRPCInferenceService at 0.0.0.0:8001
I1030 22:33:28.292879 1 http_server.cc:4497] Started HTTPService at 0.0.0.0:8000
I1030 22:33:28.335154 1 http_server.cc:270] Started Metrics Service at 0.0.0.0:8002
추론 요청 보내기
서버가 실행된 후, 아래 명령어를 통해 첫 번째 추론 요청을 보낼 수 있습니다.
샘플 모델 저장소와 함께 제공된 generate 엔드포인트를 사용합니다.
curl -X POST localhost:8000/v2/models/vllm_model/generate \
-d '{"text_input": "What is Triton Inference Server?", "parameters": {"stream": false, "temperature": 0}}'
성공 시 서버 응답 예시:
{
"model_name": "vllm_model",
"model_version": "1",
"text_output": "What is Triton Inference Server?\n\nTriton Inference Server is a server that is used by many"
}
마치며
이번 글에서는 LLM의 추론 속도를 극대화할 수 있는 두 가지 주요 프레임워크, vLLM과 Triton Inference Server를 소개하고, 각각의 특징과 간단한 활용 방법을 살펴보았습니다.
이 두 프레임워크는 LLM의 실시간 추론을 가능하게 함으로써 LLM을 상용 서비스에 적용할 때 발생하는 속도 문제를 효과적으로 해결할 수 있습니다.
실제 사용 사례에서는 vLLM 뿐만 아니라 TensorRT-LLM, llama.cpp, sglang 등 다양한 프레임워크를 사용합니다. 또한 Triton Inferece server의 모니터링 기능을 활용하면 서빙 환경을 보다 안정적으로 구축하고 운영할 수 있습니다.
본 글에서는 핵심적인 내용에 초점을 맞춰 소개했지만, 각 프레임워크의 세부적인 활용 방법과 다양한 옵션도 충분히 연구해보길 추천드립니다. 이를 통해 여러분의 LLM 서비스가 더욱 효과적이고 실용적인 결과를 낼 수 있기를 바랍니다.
감사합니다.
Reference
- https://toss.tech/article/llm-serving
- https://recording-it.tistory.com/117
- https://developer.nvidia.com/ko-kr/nvidia-triton-inference-server
- 스마일 게이트 - triton-inference-server로 모델 서빙 성능 끌어올리기
- https://github.com/triton-inference-server/vllm_backend
'딥러닝 > LLM' 카테고리의 다른 글
LLM 효율성을 높이는 양자화 기법 탐구 및 성능 분석 (0) | 2024.11.12 |
---|---|
RoPE scaling for LLM (0) | 2024.11.03 |
All you need to know about RAG (0) | 2024.10.09 |
RAG(Relevance-Augmented Generation): LLM의 한계를 넘는 새로운 접근 (0) | 2024.10.09 |
LLM을 활용한 지식 증류: sLLM 성능 최적화 실험 (3) | 2024.09.01 |