최근 몇 달간 Azure에서 대형 언어 모델을 서빙해야 하는 상황이 자주 생긴다. 특히 한국 기업들이 AI를 실제 서비스에 녹여내려고 할 때 그렇다. 그럼 대부분 이런 고민을 한다. “OpenAI API만 쓰면 안 되나? 왜 굳이 직접 모델을 서빙해야 하지?” 그 답은 간단하다. 비용, 지연시간, 그리고 데이터 프라이버시다.
직접 모델을 서빙하면 OpenAI 같은 외부 API에 의존하지 않아도 된다. 응답 속도도 빠르고, 비용도 훨씬 싸다. 특히 대량의 요청을 처리해야 하는 엔터프라이즈 환경에선 거의 필수가 됐다. 그런데 이걸 제대로 하려면 vLLM이라는 도구가 정말 유용하다.
vLLM은 대형 언어 모델을 효율적으로 서빙하기 위한 엔진이다. 페이스북(Meta)의 연구진들이 만들었고, 요즘 AI 엔지니어들 사이에선 표준이 돼가고 있다. 응답 속도가 빠르고, GPU 메모리를 효율적으로 쓰고, 수평 확장이 쉽다. 근데 Azure에서 vLLM을 제대로 배포하려면 알아야 할 게 꽤 많다. GPU 선택부터 시작해서 모델 최적화까지 여러 단계가 있거든.
이 글은 실제 프로덕션 환경에 vLLM을 배포하면서 겪은 경험들을 정리한 거다. 처음 시작하는 사람도 따라갈 수 있도록 단계별로 풀어냈다.
GPU 인스턴스 선택, 여기서 결정이 난다
vLLM을 시작하기 전에 가장 중요한 결정이 있다. 어떤 GPU를 쓸 것인가? 이게 전체 비용과 성능을 좌우한다.
Azure에서 제공하는 GPU VM들을 보면 여러 옵션이 있다. NVIDIA의 A100, H100, V100, T4 같은 것들 말이다. 각각의 특성이 다르니까 정확히 이해해야 한다.
H100 같은 최신 GPU는 엄청 강력하지만 비용도 어마어마하다. 한 시간에 몇 십만 원대다. 만약 소규모 프로젝트라면 과하다. 그렇다고 T4를 쓰면? 속도는 느리지만 가격은 저렴하다. 균형을 맞춰야 한다.
일반적으로 중견 규모의 AI 서빙에는 A100이 좋다. 성능이 충분하고 비용도 합리적이다. A100의 경우 한국 리전 기준 한 시간에 약 8~10만 원 정도면 GPU를 렌트할 수 있다. 비싸 보이지만, 10~20명이 동시에 요청을 보낼 수 있으니까 사람당 비용으로 나누면 그리 높지 않다.
또 하나 고려할 점이 메모리다. A100은 40GB와 80GB 두 가지가 있다. 실행하려는 모델의 크기에 따라 선택해야 한다. 예를 들어 7B짜리 Llama 모델은 40GB로 충분하지만, 70B 모델을 쓰려면 80GB가 필요할 수도 있다. 양자화(Quantization)를 하면 메모리를 줄일 수 있지만, 그럼 응답 속도가 조금 느려진다.
한국에선 Korea Central 리전에 GPU가 제한적이니까, 주변 리전(일본, 싱가포르)을 봐야 할 수도 있다. 지역은 다르지만 지연시간 차이는 생각보다 크지 않다. 100ms 정도 차이면 대부분의 애플리케이션에서 무시할 수 있는 수준이다.
VM 생성과 초기 설정
Azure Portal에서 Virtual Machine을 만들자. 계산 유형에서 GPU를 선택하고, 위에서 언급한 인스턴스 크기를 고르면 된다. Ubuntu 20.04 또는 22.04를 OS로 추천한다. vLLM은 Linux 환경에서 제일 잘 작동한다.
VM이 만들어진 후 SSH로 접속하면 처음 해야 할 일이 드라이버 설치다. NVIDIA GPU 드라이버를 깔아야 한다. Azure는 기본적으로 드라이버를 깔아주지만, 항상 최신 버전인 건 아니다. 수동으로 업데이트하는 게 좋다.
터미널에서 몇 줄의 명령어로 드라이버를 설치할 수 있다. CUDA 툴킷도 함께 설치하는 게 좋다. vLLM이 CUDA에 의존하거든. CUDA 11.8 또는 12.0 버전을 추천한다. 최신 버전이 모든 라이브러리와 호환되지 않을 수 있으니까.
설치 후 nvidia-smi 명령어를 치면 GPU 정보가 나온다. 여기서 GPU 메모리, 드라이버 버전, CUDA 버전을 확인하자. 모든 게 정상이면 준비 완료다.
다음은 Python 환경 설정이다. Python 3.10 이상을 써야 한다. vLLM의 최신 버전들이 더 이상 Python 3.9를 지원하지 않거든. conda나 venv를 써서 가상 환경을 만드는 게 좋다. 시스템 Python에 직접 패키지를 깔면 나중에 충돌이 생길 수 있다.
vLLM 설치와 첫 번째 실행
이제 vLLM을 설치할 시간이다. pip로 간단하게 설치할 수 있다. 하지만 GPU 지원을 원한다면 조금 신경 써야 한다. 기본 pip 설치는 CUDA 버전 호환성이 완벽하지 않을 수 있거든.
가장 안전한 방법은 공식 문서를 참고해서 설치하는 거다. vLLM은 주기적으로 업데이트되고, 각 버전마다 권장 설치 방법이 다를 수 있다. 2026년 현재 최신 버전이라면 pip install vLLM[all]로 하면 대부분 잘 설치된다.
설치 후 처음으로 작은 모델부터 시작하는 게 좋다. Llama-2 7B 같은 가벼운 모델 말이다. 모델은 보통 HuggingFace에서 다운로드한다. HuggingFace 토큰이 있으면 private 모델도 쓸 수 있다.
첫 번째 테스트는 Python 스크립트로 간단하게 하자. vLLM의 LLM 클래스를 사용해서 모델을 로드하고, 입력을 주면 출력이 나온다. 이 과정에서 몇 가지를 확인해야 한다. 모델 로드에 얼마나 시간이 걸리는지, GPU 메모리를 얼마나 쓰는지, 응답 속도는 어느 정도인지 말이다.
처음엔 뭔가 느릴 수 있다. GPU 초기화, 모델 다운로드 등이 시간을 먹거든. 하지만 한 번 로드되고 나면 응답이 매우 빠르다. 7B 모델이라면 초당 수십 개의 토큰을 생성할 수 있다.
동시 요청 처리를 위한 vLLM 서버 세팅
단순히 모델을 로드하는 것 외에, 여러 사용자의 동시 요청을 받아야 한다. 여기서 vLLM의 진정한 장점이 드러난다. vLLM은 배치 처리(Batch Processing)를 매우 효율적으로 한다.
vLLM은 OpenAI와 호환되는 API 서버를 제공한다. 이를 사용하면 curl이나 Python requests로 쉽게 요청을 보낼 수 있다. 명령어 한 줄로 서버를 띄울 수 있다. vllm serve 명령어에 모델 이름만 주면 된다.
서버가 띄워지면 포트 8000에서 대기한다. 다른 포트를 쓰고 싶으면 –port 옵션으로 지정할 수 있다. 그리고 아주 중요한 옵션이 몇 개 있다.
먼저 –max-model-len은 처리할 수 있는 최대 토큰 길이다. 메모리와 밀접한 관련이 있다. 너무 크게 설정하면 메모리 부족 에러가 나고, 너무 작으면 긴 문서를 처리할 수 없다. 보통 GPU 메모리의 50~60% 정도를 쓴다고 생각하면 된다.
–tensor-parallel-size는 여러 GPU를 쓸 때 모델을 분산 처리하는 옵션이다. 한 개 GPU만 있다면 1로 설정하면 된다. 하지만 여러 GPU가 있다면 높일 수 있다. 예를 들어 A100 두 개가 있다면 2로 설정해서 모델을 두 GPU에 나눌 수 있다.
–swap-space는 CPU 메모리를 GPU 메모리 확장처럼 쓰는 옵션이다. 메모리가 부족한 상황에서 도움이 될 수 있지만, 속도는 느려진다. 대부분의 경우 필요 없다.
응답 속도와 처리량 최적화
서버가 잘 떴는데 응답이 느리다면? 여러 가지 튜닝 포인트가 있다.
가장 먼저 확인할 게 GPU 메모리 할당이다. nvidia-smi를 보면서 GPU 메모리가 어떻게 변하는지 관찰하자. 처음엔 비어있다가 첫 요청이 들어오면 급격히 늘어난다. 안정화되면 그 수치가 baseline이 된다. 만약 이 수치가 GPU 메모리의 80% 이상이라면, 더 이상 많은 동시 요청을 처리하기 어렵다.
이럴 땐 양자화를 고려해야 한다. 양자화는 모델의 정밀도를 낮춰서 메모리를 줄이는 기법이다. int8이나 int4 양자화를 쓰면 메모리를 절반 이상 줄일 수 있다. vLLM은 bitsandbytes 라이브러리와 통합되어 있어서 –load-in-8bit 같은 옵션으로 간단하게 활성화할 수 있다.
양자화를 하면 응답 품질이 약간 떨어질 수 있지만, 대부분의 경우 인식할 수 없는 수준이다. 특히 간단한 질문-답변이나 생성 작업이라면 큰 차이가 없다. 하지만 정밀한 추론이 필요한 작업이라면 full precision을 유지하는 게 좋다.
처리량 측면에서는 배치 크기가 중요하다. vLLM은 자동으로 들어오는 요청들을 배치로 묶어서 처리한다. –max-num-batched-tokens 옵션으로 한 배치에서 처리할 최대 토큰 수를 정할 수 있다. 이걸 높이면 처리량이 올라가지만, 응답 대기 시간도 늘어난다. 보통 2000~4000 정도가 적당하다.
Azure 위에서 vLLM 운영하기
이제 모델이 안정적으로 작동한다. 하지만 실제 프로덕션 환경이라면 몇 가지 더 생각해야 한다.
먼저 VM이 재부팅될 때를 대비해야 한다. Azure에서는 때때로 호스트 유지보수를 위해 VM을 재부팅한다. 이때 vLLM 서버도 내려간다. 따라서 systemd를 설정해서 VM 부팅 시 자동으로 vLLM 서버가 시작되도록 하는 게 좋다.
또한 로깅과 모니터링이 중요하다. vLLM 서버를 백그라운드에서 띄울 때 로그를 파일로 남기자. 문제가 생겼을 때 로그를 보면 원인을 파악할 수 있다. 그리고 Azure Monitor를 사용해서 GPU 메모리, CPU 사용률, 네트워크 트래픽을 모니터링할 수 있다.
프로덕션에서는 로드 밸런싱도 고려해야 한다. 단일 VM의 vLLM 서버는 어느 정도 동시 요청까지만 처리할 수 있다. 요청이 더 많아지면 여러 VM을 띄워야 한다. Azure Load Balancer를 사용하면 여러 vLLM 인스턴스로 요청을 분산시킬 수 있다.
또한 API 게이트웨이를 앞에 두는 게 좋다. Azure API Management를 사용하면 인증, 속도 제한(Rate Limiting), 캐싱 같은 기능을 추가할 수 있다. 특히 캐싱은 매우 유용하다. 같은 요청이 들어왔을 때 vLLM까지 가지 않고 캐시된 결과를 반환하면 훨씬 빠르다.
실무에서 자주 겪는 문제들
이 정도 설정을 하면 대부분 잘 작동한다. 하지만 몇 가지 함정이 있다.
메모리 부족 에러는 가장 흔하다. 특히 대형 모델을 작은 GPU에서 띄우려고 할 때다. 이럴 땐 양자화를 하거나, 더 작은 모델을 쓰거나, 더 큰 GPU를 쓰거나, 모델을 여러 GPU에 분산시켜야 한다.
응답 시간이 갑자기 느려지는 경우도 있다. 이건 보통 두 가지 원인이다. 첫 번째는 GPU가 거의 꽉 찬 상태에서 동시 요청이 계속 들어오는 경우다. 이럴 땐 큐가 쌓여서 대기 시간이 늘어난다. 두 번째는 메모리 부족으로 인한 스왑이 발생하는 경우다. CPU 메모리에서 처리하니까 당연히 느리다.
모델 가중치가 바뀔 때마다 다시 다운로드해야 하는데, 이게 시간이 걸린다. 예를 들어 Llama 70B는 크기가 140GB 정도다. 처음 로드할 때 이 모든 걸 HuggingFace에서 다운로드해야 한다. 네트워크 속도에 따라 1시간 이상 걸릴 수도 있다. 가중치를 미리 다운로드하거나 Azure Blob Storage에 저장해놨다가 로컬에 옮기는 방법도 있다.
마무리: 실전에서 배운 것들
결국 Azure에서 vLLM을 성공적으로 배포하려면 몇 가지가 중요하다. 첫째, GPU 선택을 신중하게 하자. 이게 전체 경제성을 좌우한다. 둘째, 작은 모델부터 시작해서 점진적으로 확장하자. 큰 모델을 한 번에 띄우려고 하면 실패할 가능성이 높다. 셋째, 모니터링을 처음부터 갖춰놓자. 문제가 생겼을 때 빠르게 대응할 수 있다.
지난 몇 개월 vLLM을 운영하면서 가장 놀라웠던 건 효율성이다. 같은 GPU로 OpenAI API를 쓸 때보다 훨씬 많은 요청을 처리할 수 있다. 응답 속도도 빠르고, 비용도 훨씬 저렴하다. 초기 설정에는 시간과 노력이 필요하지만, 그 이후로는 안정적으로 작동한다.
특히 한국 기업들이 AI를 내재화하려고 할 때 vLLM은 좋은 선택지다. 오픈소스라서 비용이 없고, 커뮤니티가 활발해서 문제 해결이 빠르다. Azure라는 엔터프라이즈급 인프라 위에 올려놓으면 보안이나 안정성도 걱정할 필요 없다.
지금 바로 시작해보자. 작은 VM 하나로 7B 모델부터 시작하면 된다. 그것도 충분히 강력하다. 경험을 쌓으면서 필요에 따라 더 큰 모델, 더 많은 GPU를 추가하면 된다. 처음부터 완벽할 필요는 없다.