핵심 요약
새로 구매한 L40S GPU 서버에 Docker 기반 vLLM을 설치하고 Qwen3-30B-A3B-Instruct 모델을 구동하는 전체 과정을 다룹니다. 서버 초기 설정부터 모델 실행까지 실제 작업 순서대로 정리했으며, 중간에 발생할 수 있는 문제 해결 방법도 함께 담았습니다.
요즘 AI 모델 서빙에 관심 있는 분들 사이에서 vLLM이 화제입니다. 특히 대용량 언어 모델을 빠르고 효율적으로 운영할 수 있다는 점 때문에 많은 개발자들이 선택하고 있죠. 저도 최근 L40S GPU 서버를 새로 장만하면서 Qwen3-30B 모델을 올려보기로 했는데, 생각보다 설정 과정에서 신경 쓸 부분이 많더라고요. 그래서 이번 글에서는 제가 직접 겪은 과정을 바탕으로 서버 구매 후 첫 세팅부터 모델 구동까지 모든 단계를 차근차근 정리해봤습니다.
서버 받자마자 가장 먼저 할 일
서버가 도착하면 흥분되는 마음에 바로 뭔가 설치하고 싶은 마음이 굴뚝같지만, 잠깐만 기다려보세요. 기본 설정을 제대로 해두지 않으면 나중에 골치 아픈 상황이 생길 수 있거든요.
먼저 SSH로 서버에 접속합니다. 대부분의 서버 호스팅 업체에서 초기 root 계정과 비밀번호를 제공할 텐데요, 이걸로 접속하면 됩니다.
ssh root@서버IP주소
접속했다면 시스템 업데이트부터 진행합니다. Ubuntu 기준으로 설명할게요.
apt update && apt upgrade -y
이 과정이 꽤 시간이 걸릴 수 있는데, 커피 한 잔 마시면서 여유롭게 기다리면 됩니다. 업데이트가 끝나면 재부팅 한 번 해주는 게 좋습니다.
reboot
재부팅 후 다시 접속하면 기본 패키지들을 설치할 차례입니다. 앞으로 작업하면서 필요한 도구들을 미리 깔아둡니다.
apt install -y build-essential curl git vim htop
보안 설정은 선택이 아닌 필수
서버를 인터넷에 노출시키는 순간부터 각종 공격 시도가 들어옵니다. 특히 root 계정으로 SSH 접속을 허용하면 정말 위험하거든요. 그래서 일반 사용자 계정을 만들고 sudo 권한을 주는 방식으로 운영하는 게 안전합니다.
adduser aiserver
usermod -aG sudo aiserver
비밀번호를 설정하라고 나오면 강력한 비밀번호로 지정해주세요. 그다음 SSH 설정을 변경해서 root 직접 로그인을 막습니다.
vim /etc/ssh/sshd_config
파일 안에서 아래 항목을 찾아 수정합니다.
PermitRootLogin no
PasswordAuthentication yes
저장하고 SSH 서비스를 재시작합니다.
systemctl restart sshd
이제부터는 방금 만든 aiserver 계정으로 접속해서 작업하면 됩니다. 더 안전하게 운영하려면 SSH 키 기반 인증도 설정하는 게 좋지만, 일단 여기까지만 해도 기본적인 보안은 갖춰집니다.
NVIDIA 드라이버 설치하기
L40S는 NVIDIA GPU니까 당연히 드라이버가 필요합니다. 요즘은 Ubuntu에서 자동으로 권장 드라이버를 찾아주는 기능이 있어서 예전보다 훨씬 편해졌어요.
sudo apt install -y ubuntu-drivers-common
sudo ubuntu-drivers autoinstall
자동 설치가 끝나면 역시 재부팅이 필요합니다.
sudo reboot
재접속 후 드라이버가 제대로 설치됐는지 확인해봅니다.
nvidia-smi
여기서 GPU 정보가 쭉 나오면 성공입니다. L40S의 메모리 용량이랑 드라이버 버전, CUDA 버전 같은 정보가 표시될 거예요. 혹시 에러가 나온다면 드라이버 설치 과정에서 문제가 생긴 건데, 수동으로 설치하거나 NVIDIA 공식 사이트에서 드라이버를 받아서 설치해야 합니다.
Docker 환경 구축하기
이제 본격적으로 Docker를 설치할 시간입니다. vLLM을 컨테이너로 띄울 거니까 Docker는 필수죠.
Docker 공식 저장소를 추가합니다.
sudo apt install -y ca-certificates gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
이제 Docker를 설치합니다.
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
설치가 끝나면 현재 사용자를 docker 그룹에 추가해서 sudo 없이도 Docker 명령어를 쓸 수 있게 만듭니다.
sudo usermod -aG docker $USER
이 설정을 적용하려면 로그아웃 후 다시 로그인해야 합니다. 귀찮지만 한 번만 하면 되니까 참아봅시다.
exit
다시 접속해서 Docker가 잘 동작하는지 확인합니다.
docker run hello-world
메시지가 정상적으로 나오면 Docker 설치 완료입니다.
NVIDIA Container Toolkit 설정
Docker에서 GPU를 사용하려면 NVIDIA Container Toolkit이라는 게 필요합니다. 이게 있어야 컨테이너 안에서 GPU에 접근할 수 있거든요.
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
저장소 추가 후 설치를 진행합니다.
sudo apt update
sudo apt install -y nvidia-container-toolkit
Docker 데몬 설정을 업데이트합니다.
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
제대로 설치됐는지 테스트해봅니다.
docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi
컨테이너 안에서도 nvidia-smi 결과가 나온다면 완벽하게 세팅된 겁니다.
vLLM Docker 이미지 준비
vLLM은 공식 Docker 이미지를 제공하고 있어서 직접 빌드할 필요 없이 바로 사용할 수 있습니다. 이미지를 미리 받아놓으면 나중에 실행할 때 더 빠르죠.
docker pull vllm/vllm-openai:latest
이미지 크기가 좀 큰 편이라 다운로드에 시간이 걸립니다. 네트워크 속도에 따라 다르지만 보통 몇 분 정도 소요됩니다.
Qwen3-30B 모델 다운로드
Hugging Face에서 모델 파일을 받아야 합니다. 용량이 상당히 크기 때문에 서버에 충분한 디스크 공간이 있는지 먼저 확인해보세요. 30B 모델이면 대략 60GB 정도 잡으면 됩니다.
작업할 디렉토리를 만듭니다.
mkdir -p ~/models
cd ~/models
Hugging Face CLI를 설치합니다.
pip install -U huggingface_hub
모델을 다운로드합니다. Hugging Face에 로그인이 필요한 모델이라면 토큰을 발급받아서 사용해야 합니다.
huggingface-cli download Qwen/Qwen3-30B-A3B-Instruct-2507 --local-dir ./Qwen3-30B-A3B-Instruct-2507
다운로드가 완료될 때까지 기다립니다. 속도가 느리다면 차라리 밤에 받아두고 자는 것도 방법입니다.
vLLM 컨테이너 실행하기
드디어 모든 준비가 끝났습니다. 이제 vLLM 컨테이너를 띄워서 모델을 서빙할 차례입니다.
docker run -d \
--gpus all \
--name vllm-qwen3 \
-v ~/models/Qwen3-30B-A3B-Instruct-2507:/model \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model /model \
--served-model-name Qwen3-30B \
--host 0.0.0.0 \
--port 8000
각 옵션이 무슨 의미인지 간단히 설명하면, gpus all은 모든 GPU를 사용하겠다는 뜻이고, v 옵션으로 로컬 모델 경로를 컨테이너 안으로 마운트합니다. 포트는 8000번을 외부에 노출시키고, served-model-name으로 API 호출할 때 쓸 모델 이름을 지정합니다.
컨테이너가 정상적으로 실행 중인지 확인합니다.
docker ps
로그를 확인해서 모델 로딩 상태를 체크할 수 있습니다.
docker logs -f vllm-qwen3
모델 로딩에는 시간이 좀 걸립니다. 30B 모델이 GPU 메모리에 올라가려면 몇 분 정도 소요되는데, 로그에서 “Application startup complete” 같은 메시지가 나오면 준비된 겁니다.
API 테스트해보기
서비스가 잘 떠 있는지 간단한 API 호출로 확인해봅시다.
curl http://localhost:8000/v1/models
모델 정보가 JSON 형태로 반환되면 정상입니다. 실제 추론도 테스트해볼까요?
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3-30B",
"messages": [
{"role": "user", "content": "안녕하세요"}
]
}'
응답이 제대로 나온다면 모든 설정이 완료된 겁니다. 이제 이 서버를 통해 다양한 애플리케이션에서 Qwen3 모델을 활용할 수 있습니다.
성능 최적화 팁
기본 설정으로도 충분히 동작하지만, 조금 더 나은 성능을 원한다면 몇 가지 옵션을 추가할 수 있습니다.
텐서 병렬 처리를 활용하려면 tensor-parallel-size 옵션을 추가합니다. GPU가 여러 개라면 이 값을 조정해서 성능을 높일 수 있어요.
--tensor-parallel-size 1
메모리 사용량을 조절하고 싶다면 gpu-memory-utilization 값을 설정합니다. 기본값은 0.9인데, 여유를 더 두고 싶다면 0.8 정도로 낮춰도 됩니다.
--gpu-memory-utilization 0.85
배치 처리를 최적화하려면 max-num-seqs와 max-model-len 값도 조정 가능합니다. 이건 실제 사용 패턴을 보면서 조절하는 게 좋습니다.
문제 발생 시 체크 포인트
가끔 컨테이너가 제대로 안 뜨거나 모델 로딩에 실패하는 경우가 있습니다. 그럴 때 확인해볼 사항들을 정리했어요.
GPU 메모리가 부족한 경우, L40S는 48GB VRAM을 가지고 있는데 30B 모델을 FP16으로 로딩하면 거의 다 쓰게 됩니다. 다른 프로세스가 GPU를 사용하고 있진 않은지 nvidia-smi로 확인해보세요.
모델 파일 경로 문제일 수도 있습니다. Docker 볼륨 마운트가 제대로 됐는지, 모델 파일들이 정확한 위치에 있는지 다시 한번 체크해봅니다.
포트 충돌도 흔한 원인입니다. 이미 8000번 포트를 다른 프로세스가 쓰고 있다면 vLLM이 시작되지 않습니다. 다른 포트로 변경하거나 기존 프로세스를 종료해야 합니다.
서비스 지속 운영을 위한 설정
서버를 재부팅하면 Docker 컨테이너도 함께 꺼집니다. 자동으로 다시 시작되게 하려면 restart 정책을 추가하면 됩니다.
기존 컨테이너를 먼저 중지하고 삭제합니다.
docker stop vllm-qwen3
docker rm vllm-qwen3
재시작 정책을 포함해서 다시 실행합니다.
docker run -d \
--gpus all \
--name vllm-qwen3 \
--restart unless-stopped \
-v ~/models/Qwen3-30B-A3B-Instruct-2507:/model \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model /model \
--served-model-name Qwen3-30B \
--host 0.0.0.0 \
--port 8000
이제 서버가 재부팅되더라도 vLLM 서비스가 자동으로 다시 시작됩니다.
모니터링 환경 갖추기
서비스를 운영하다 보면 GPU 사용률이나 메모리 상태를 계속 체크해야 합니다. 간단하게 htop과 nvidia-smi를 주기적으로 확인할 수도 있지만, 좀 더 체계적으로 모니터링하고 싶다면 Prometheus나 Grafana 같은 도구를 연동하는 것도 방법입니다.
일단 기본적으로는 watch 명령어로 실시간 모니터링을 할 수 있습니다.
watch -n 1 nvidia-smi
이렇게 하면 1초마다 GPU 상태가 갱신되면서 보여집니다. 추론 요청이 들어왔을 때 GPU 사용률이 어떻게 변하는지 실시간으로 확인할 수 있어서 유용합니다.
외부 접근 허용하기
지금까지는 localhost에서만 테스트했는데, 실제로 다른 서버나 클라이언트에서 접근하려면 방화벽 설정이 필요합니다.
UFW를 사용하는 경우 8000번 포트를 열어줍니다.
sudo ufw allow 8000/tcp
sudo ufw reload
클라우드 서버라면 보안 그룹이나 네트워크 ACL 설정도 확인해야 합니다. 각 클라우드 제공사마다 설정 방법이 다르니 해당 문서를 참고하세요.
외부에서 접근할 때는 서버의 공인 IP 주소를 사용하면 됩니다.
curl http://서버공인IP:8000/v1/models
보안이 걱정된다면 API 키 인증을 추가하거나, NGINX 같은 리버스 프록시를 앞단에 두고 HTTPS를 설정하는 것도 좋은 방법입니다.
여기까지 L40S 서버를 처음 받아서 vLLM으로 Qwen3-30B 모델을 띄우는 전 과정을 살펴봤습니다. 처음에는 복잡해 보일 수 있지만, 한 단계씩 따라가다 보면 생각보다 어렵지 않습니다. 중요한 건 각 단계에서 제대로 동작하는지 확인하면서 진행하는 거예요. 특히 GPU 드라이버랑 NVIDIA Container Toolkit 설정이 제대로 안 되면 나중에 문제가 생기니까, 이 부분은 꼼꼼하게 체크하는 게 좋습니다.
vLLM은 정말 강력한 추론 엔진입니다. 같은 하드웨어에서도 다른 방식보다 훨씬 빠른 응답 속도와 높은 처리량을 보여주거든요. Qwen3 모델도 성능이 뛰어나서 다양한 한국어 태스크에 활용할 수 있고요. 이 두 가지를 조합하면 실무에서 충분히 쓸 만한 AI 서비스를 구축할 수 있습니다.
앞으로 더 많은 모델을 실험해보고 싶다면 같은 방식으로 다른 모델들도 쉽게 교체해가며 테스트할 수 있습니다. 모델 파일만 바꿔주고 컨테이너를 다시 시작하면 되니까요. 여러분의 L40S 서버가 멋진 AI 서비스의 시작점이 되길 바랍니다.