InfoGrab DocsInfoGrab Docs

vLLM을 사용한 예시 모델 배포

요약

GPT OSS 120B는 vLLM으로 배포하는 예시 모델이며, GPU 선택부터 프로덕션 모니터링까지 다룹니다. GPT OSS 120B는 NVIDIA H100에서 학습되었으며 H100 이상의 데이터 센터 GPU에서 가장 잘 동작합니다.

GPT OSS 120B는 vLLM으로 배포하는 예시 모델이며, GPU 선택부터 프로덕션 모니터링까지 다룹니다.

GPU 선택#

GPT OSS 120B는 NVIDIA H100에서 학습되었으며 H100 이상의 데이터 센터 GPU에서 가장 잘 동작합니다. 전문가 혼합(mixture-of-experts, MoE) 구조가 토큰마다 네트워크의 일부만 활성화하므로, 이 모델은 단일 H100 80 GB GPU에 들어갑니다.

병렬화 전략 결정#

GPU를 어떻게 연결하는지에 따라 다음 병렬화 전략이 정해집니다.

  • GPU가 NVLink(수백 GB/s)로 연결되어 있다면 단일 노드에서 텐서 병렬화를 사용합니다. 텐서 병렬화는 각 레이어를 GPU 사이에 나누므로 높은 대역폭이 필요합니다.
  • GPU의 대역폭이 낮고 PCIe(약 64 GB/s)로 동작한다면 파이프라인 병렬화를 사용합니다. 파이프라인 병렬화는 레이어를 GPU 사이에 순차적으로 나눕니다.

텐서 병렬화의 최대 한계에 도달했지만 모델을 더 분산해야 한다면 두 병렬화 전략을 함께 사용할 수 있습니다. 예를 들어 노드 안에서는 텐서 병렬화를, 노드 사이에서는 파이프라인 병렬화를 사용합니다.

VRAM 요구 사항 계획#

필요한 VRAM은 컨텍스트 길이와 예상 동시 처리 수에 따라 달라집니다.

vLLM은 다음 용도로 VRAM을 할당합니다.

카테고리 크기 비고
모델 가중치 약 61 GB 고정
프레임워크 오버헤드 약 2 GB 고정
KV 캐시 나머지 동시 처리 수와 컨텍스트 길이에 따라 확장

KV 캐시는 각 요청에서 처리한 토큰의 사전 계산 벡터를 저장합니다. 각 토큰은 한 번만 계산되며, 변동이 발생하는 지점이 바로 이 캐시입니다.

예시: 단일 H100 80 GB#

--gpu-memory-utilization 0.95를 사용하면 76 GB의 VRAM을 쓸 수 있습니다.

76 GB usable
├── 61 GB  model weights          ← fixed
├──  2 GB  framework overhead     ← fixed
└──  13 GB  KV cache               ← fills as requests arrive

캐시된 토큰당 약 36 KB 이므로, 13 GB는 전체 어텐션 레이어에 걸쳐 약 370K 토큰의 컨텍스트를 담습니다. 에이전트형 요청 하나가 약 32K 토큰을 사용한다면 동시 요청 약 10 건 을 처리할 수 있습니다.

vLLM을 시작하면 로그에 정확한 수치가 표시됩니다.

Available KV cache memory: N GiB
GPU KV cache size: Y tokens
Maximum concurrency for Y tokens per request: Nx

설치#

환경에 맞는 방법을 선택합니다.

  • 설치 스크립트: CUDA 나 GPU 드라이버가 설치되지 않은 새 Ubuntu 또는 Debian 머신입니다.
  • vLLM만 설치: CUDA와 드라이버가 이미 있는 경우입니다(GCP의 NVIDIA Deep Learning VM, AWS Deep Learning AMI, 기존 GPU 머신).
  • Docker: 호스트 수준 설정을 전부 건너뜁니다.

하드웨어가 다르다면 추가 구성은 GPT OSS - vLLM Recipes를 참고합니다.

옵션 1: 설치 스크립트(처음부터)#

스택을 업데이트할 때는 각 변수에 다음 버전을 사용합니다. 이 버전들은 GPT OSS 120B를 서빙하는 데 필요한 최소 버전입니다. vLLM은 성능 개선, 버그 수정, 하드웨어 지원 확대가 포함된 최신 릴리스를 사용하는 것이 좋습니다.

변수 버전
CUDA toolkit 12.9
최소 드라이버 575.x
Python 3.12
vLLM 0.18.0
#!/bin/bash
# vLLM + CUDA installation for gpt-oss-120b
# Target: Ubuntu 22.04 / Debian 12, x86_64

CUDA_VERSION="12-9"           # apt package suffix  →  cuda-toolkit-12-9
MIN_DRIVER_VERSION="575"      # minimum driver for CUDA 12.9
PYTHON_VERSION="3.12"
VLLM_VERSION="0.18.0"
VENV_DIR="${HOME}/vllm-env"

set -e

# ===========================================================================
# PART 1 — system prerequisites
# ===========================================================================
echo "--- Part 1: System prerequisites ---"

sudo apt-get update && sudo apt-get upgrade -y

sudo apt-get install -y \
    build-essential \
    dkms \
    linux-headers-$(uname -r) \
    wget curl gnupg2 \
    software-properties-common \
    python${PYTHON_VERSION} \
    python${PYTHON_VERSION}-venv \
    python${PYTHON_VERSION}-dev \
    python3-pip git

# Install uv — recommended by vLLM docs; gives extra index URLs higher
# priority than PyPI, which is required for the gpt-oss fork to resolve correctly.
curl --location --silent --show-error --fail "https://astral.sh/uv/install.sh" | sh
source "${HOME}/.local/bin/env"

# ===========================================================================
# PART 2 — NVIDIA drivers and CUDA toolkit
# Reboot required after this section before continuing to Part 3.
# ===========================================================================
echo "--- Part 2: NVIDIA drivers and CUDA ${CUDA_VERSION//-/.} ---"

# Add NVIDIA's package repository.
# For Debian 12, replace ubuntu2204 with debian12 in the URL.
# Current keyring URL: https://developer.nvidia.com/cuda-downloads
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt-get update

# cuda-drivers (no version suffix) is a meta-package — apt resolves
# the latest driver compatible with the pinned toolkit automatically.
sudo apt-get install -y \
    cuda-drivers \
    cuda-toolkit-${CUDA_VERSION} \
    nvidia-gds-${CUDA_VERSION}

echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc

# Keep GPU initialized between jobs (reduces cold-start latency)
sudo systemctl enable nvidia-persistenced

echo "Rebooting to load NVIDIA kernel modules..."
echo "After reboot, run:  bash install.sh --post-reboot"

if [[ "${1:-}" != "--post-reboot" ]]; then
    sudo reboot
fi

# ===========================================================================
# PART 3 — Python environment and vLLM
# Start here after reboot, or if using a cloud managed image.
# ===========================================================================
echo "--- Part 3: Verify drivers ---"

nvidia-smi       # confirm driver >= ${MIN_DRIVER_VERSION} and GPUs visible
nvcc --version   # confirm CUDA ${CUDA_VERSION//-/.}

echo "--- Part 3: Python environment ---"

uv venv "$VENV_DIR" --python ${PYTHON_VERSION} --seed
source "$VENV_DIR/bin/activate"

python --version   # should show Python 3.12.x

echo "--- Part 3: PyTorch ---"

# --torch-backend=auto inspects your installed CUDA driver at runtime and
# selects the matching PyTorch index automatically. This replaces hardcoded
# --index-url flags and stays correct across CUDA version updates.
uv pip install torch torchvision torchaudio --torch-backend=auto

echo "--- Part 3: vLLM ---"

uv pip install "vllm==${VLLM_VERSION}" --torch-backend=auto

echo ""
echo "Installation complete."
echo "Activate environment:  source ${VENV_DIR}/bin/activate"
echo "Verify vLLM version:   python -c \"import vllm; print(vllm.__version__)\""

옵션 2: vLLM만 설치#

CUDA와 드라이버가 이미 설치되어 있다면(클라우드 관리형 이미지, 기존 GPU 머신) 다음 명령으로 vLLM을 설치합니다.

uv venv
source .venv/bin/activate
uv pip install vllm --torch-backend=auto

옵션 3: Docker#

다음 명령으로 GPT OSS 120B Docker 이미지를 설치합니다. vllm/vllm-openai:v0.18.0 이미지에는 CUDA, 드라이버, vLLM 이 포함되어 있습니다.

docker run \
  --gpus all \
  -p 8000:8000 \
  --ipc=host \
  vllm/vllm-openai:v0.18.0 \
  --model openai/gpt-oss-120b

vLLM 구성#

vLLM 구성 값은 트래픽 패턴에 따라 달라집니다. 아래 권장 설정으로 시작한 다음 이 조정 항목들을 맞춰 갑니다.

플래그 기본값 설명
--gpu-memory-utilization 0.90 vLLM 이 확보하는 GPU 메모리 비율입니다. KV 캐시를 늘리고 처리량을 높이려면 0.95로 올립니다. 부하 상황에서 OOM 오류가 발생하면 낮춥니다.
--max-model-len 모델 최대값(GPT OSS 120B의 경우 128K) 요청당 최대 컨텍스트 길이를 제한합니다. 이 값을 낮추면 동시 처리 용량이 늘어납니다.
--max-num-seqs 256 단일 배치의 최대 요청 수입니다. 값이 클수록 GPU 활용도와 처리량이 좋아지지만 요청당 지연 시간이 늘어납니다. 실제 동시 처리 수는 사용 가능한 KV 캐시로 여전히 제한됩니다.
--max-num-batched-tokens None 반복당 처리하는 전체 토큰 수입니다. --max-num-seqs와 함께 동작하며, vLLM은 둘 중 먼저 도달하는 한계까지 배치를 구성합니다.
--tensor-parallel-size None 레이어를 N 개의 GPU에 수평으로 나눕니다. 높은 대역폭이 필요하며 NVLink로 연결된 단일 노드 안에서 사용합니다.
--pipeline-parallel-size None 레이어를 N 개의 GPU에 순차적으로 나눕니다. 낮은 대역폭도 견디므로 PCIe로 연결된 노드 사이에 적합합니다.

권장 설정#

다음 표는 하드웨어별 권장 설정입니다. 사용하는 하드웨어와 예상 트래픽 패턴에 맞는 행을 고른 다음, 해당 구성을 사용합니다.

근사 동시 요청 수 칼럼은 표에 적힌 컨텍스트 길이에서 KV 캐시로 제한되는 대략적인 동시 처리 수이며, --max-num-seqs 값이 아닙니다.

하드웨어 최대 컨텍스트 근사 동시 요청 수 최적 용도
Single H100 80 GB 32K 10 개발·테스트, 저트래픽 서빙
2× H100 80 GB 64K 34 중간 규모 프로덕션 부하
4× H100 80 GB 128K 51 전체 컨텍스트 창, 높은 처리량
2× A100 40 GB 32K 3 최소 구성의 A100 설정
4× A100 40 GB 32K 69 더 높은 A100 처리량
2× L40S / RTX A6000 Ada 48 GB 32K 19 비용 효율적인 Ada Lovelace 옵션

Single H100 80 GB#

이 설정에서 --gpu-memory-utilization을 기본값 0.90보다 높은 0.95로 올리는 것은 단일 H100의 알려진 CUDA OOM 문제를 우회하기 위해서입니다.

vllm serve openai/gpt-oss-120b \
  --gpu-memory-utilization 0.95 \
  --max-model-len 32768 \
  --max-num-seqs 16 \
  --max-num-batched-tokens 4096

2× H100 80 GB#

이 설정에서는 합쳐진 KV 캐시 풀이 더 크므로 컨텍스트 창을 넓히고 동시 요청을 더 많이 처리할 수 있습니다.

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 2 \
  --max-model-len 65536 \
  --max-num-seqs 32 \
  --max-num-batched-tokens 8192

4× H100 80 GB#

이 설정은 128K 컨텍스트 창 전체를 제공합니다.

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 4 \
  --gpu-memory-utilization 0.95 \
  --max-model-len 131072 \
  --max-num-seqs 64 \
  --max-num-batched-tokens 16384

2× A100 40 GB#

이 설정에서 단일 A100 40 GB는 61 GB 모델 가중치를 담지 못합니다. GPU 두 개가 최소 구성입니다.

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 2 \
  --max-model-len 32768 \
  --max-num-seqs 24 \
  --max-num-batched-tokens 4096

4× A100 40 GB#

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 4 \
  --max-model-len 32768 \
  --max-num-seqs 128 \
  --max-num-batched-tokens 16384

2× L40S 48GB 또는 RTX A6000 Ada 48 GB#

두 설정 모두 48 GB의 Ada Lovelace를 사용합니다.

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 2 \
  --max-model-len 32768 \
  --max-num-seqs 16 \
  --max-num-batched-tokens 4096

NVIDIA Blackwell 및 Hopper 추가 최적화는 GPT OSS - vLLM Recipes: Recipe for NVIDIA Blackwell & Hopper Hardware를 참고합니다.

서버 확인#

vLLM을 시작한 다음에는 아래 요청으로 정상적으로 서빙되는지 확인합니다.

curl "http://localhost:8000/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-oss-120b",
    "messages": [{"role": "user", "content": "Hello"}],
    "max_tokens": 64
  }'

모델의 완성 결과가 담긴 JSON 응답이 표시됩니다. 서버가 아직 준비되지 않았다면 연결 거부 오류를 받습니다. vLLM은 처음 시작할 때 모델 가중치를 불러올 시간이 필요하며, 저장소 속도에 따라 몇 분이 걸릴 수 있습니다.

모니터링#

vLLM은 Prometheus 호환 /metrics 엔드포인트를 제공합니다. 전체 목록은 Production Metrics - vLLM을 참고합니다.

vLLM을 모니터링할 때는 사용자 대면 지연 시간과 용량 압박 지표를 확인합니다.

메트릭 설명
사용자 대면 지연 시간
time_to_first_token 사용자가 응답성으로 느끼는 시간입니다.
time_per_output_token_seconds 스트리밍이 얼마나 부드럽게 느껴지는지를 나타냅니다.
용량 압박
kv_cache_usage_perc 사용 중인 KV 풀의 비율입니다. 주요 메모리 압박 신호입니다. 0.85를 넘는 값이 지속되면 용량에 가까워지고 있다는 뜻입니다.
num_requests_waiting KV 캐시가 가득 차서 대기 중인 요청 수입니다. 대기열이 계속 늘어나면 용량을 초과한 것입니다. GPU를 늘리거나, --max-model-len을 줄이거나, --max-num-seqs를 낮춥니다.
num_requests_running 실제 동시 처리 수입니다.

문제 해결#

클라이언트 타임아웃 또는 num_requests_waiting의 지속 증가#

들어오는 요청이 KV 캐시 용량을 초과한 경우입니다. vLLM은 캐시 공간이 확보될 때까지 새 요청을 대기열에 넣고, 대기열은 줄어들지 않습니다.

이 문제를 해결하는 방법은 다음과 같습니다.

  1. kv_cache_usage_perc를 확인합니다. 0.85를 넘는 값이 지속되면 메모리에 병목이 있다는 뜻입니다.
  2. --max-model-len을 줄여 요청당 KV 할당량을 낮춥니다. 그러면 동시 요청을 더 받을 여유가 생깁니다.
  3. --max-num-seqs를 줄여 동시에 캐시를 두고 경쟁하는 요청 수를 제한합니다.
  4. 단일 노드 조정을 모두 시도했다면 수평으로 확장합니다. GPU 나 노드를 추가하고 여러 vLLM 인스턴스에 부하를 분산합니다.

CUDA OOM 오류로 인한 서버 충돌#

부하가 높을 때 서버의 GPU 메모리가 부족한 경우입니다.

이 문제를 해결하려면 다음 순서로 조정합니다.

  1. --max-num-seqs를 줄여 동시 배치 크기를 제한합니다.
  2. --max-model-len을 줄여 요청당 KV 할당량을 낮춥니다.
  3. 시작 시점에 OOM 이 발생하면 --gpu-memory-utilization을 낮춥니다.

예상보다 느린 토큰 생성#

time_per_output_token_seconds가 높고 전체 토큰/초가 낮은 경우입니다. GPU가 반복마다 처리하는 작업량이 부족한 상태입니다.

이 문제를 해결하는 방법은 다음과 같습니다.

  1. --max-num-batched-tokens를 늘려 vLLM 이 반복마다 더 많은 토큰을 처리하도록 합니다.
  2. --max-num-seqs를 늘려 더 많은 요청이 함께 배치되도록 합니다. 그러면 GPU 활용도가 좋아집니다.

vLLM을 사용한 예시 모델 배포

GitLab v19.4
Tier: Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기

요약

GPT OSS 120B는 vLLM으로 배포하는 예시 모델이며, GPU 선택부터 프로덕션 모니터링까지 다룹니다. GPT OSS 120B는 NVIDIA H100에서 학습되었으며 H100 이상의 데이터 센터 GPU에서 가장 잘 동작합니다.

GPT OSS 120B는 vLLM으로 배포하는 예시 모델이며, GPU 선택부터 프로덕션 모니터링까지 다룹니다.

GPU 선택#

GPT OSS 120B는 NVIDIA H100에서 학습되었으며 H100 이상의 데이터 센터 GPU에서 가장 잘 동작합니다. 전문가 혼합(mixture-of-experts, MoE) 구조가 토큰마다 네트워크의 일부만 활성화하므로, 이 모델은 단일 H100 80 GB GPU에 들어갑니다.

병렬화 전략 결정#

GPU를 어떻게 연결하는지에 따라 다음 병렬화 전략이 정해집니다.

  • GPU가 NVLink(수백 GB/s)로 연결되어 있다면 단일 노드에서 텐서 병렬화를 사용합니다. 텐서 병렬화는 각 레이어를 GPU 사이에 나누므로 높은 대역폭이 필요합니다.
  • GPU의 대역폭이 낮고 PCIe(약 64 GB/s)로 동작한다면 파이프라인 병렬화를 사용합니다. 파이프라인 병렬화는 레이어를 GPU 사이에 순차적으로 나눕니다.

텐서 병렬화의 최대 한계에 도달했지만 모델을 더 분산해야 한다면 두 병렬화 전략을 함께 사용할 수 있습니다. 예를 들어 노드 안에서는 텐서 병렬화를, 노드 사이에서는 파이프라인 병렬화를 사용합니다.

VRAM 요구 사항 계획#

필요한 VRAM은 컨텍스트 길이와 예상 동시 처리 수에 따라 달라집니다.

vLLM은 다음 용도로 VRAM을 할당합니다.

카테고리 크기 비고
모델 가중치 약 61 GB 고정
프레임워크 오버헤드 약 2 GB 고정
KV 캐시 나머지 동시 처리 수와 컨텍스트 길이에 따라 확장

KV 캐시는 각 요청에서 처리한 토큰의 사전 계산 벡터를 저장합니다. 각 토큰은 한 번만 계산되며, 변동이 발생하는 지점이 바로 이 캐시입니다.

예시: 단일 H100 80 GB#

--gpu-memory-utilization 0.95를 사용하면 76 GB의 VRAM을 쓸 수 있습니다.

76 GB usable
├── 61 GB  model weights          ← fixed
├──  2 GB  framework overhead     ← fixed
└──  13 GB  KV cache               ← fills as requests arrive

캐시된 토큰당 약 36 KB 이므로, 13 GB는 전체 어텐션 레이어에 걸쳐 약 370K 토큰의 컨텍스트를 담습니다. 에이전트형 요청 하나가 약 32K 토큰을 사용한다면 동시 요청 약 10 건 을 처리할 수 있습니다.

vLLM을 시작하면 로그에 정확한 수치가 표시됩니다.

Available KV cache memory: N GiB
GPU KV cache size: Y tokens
Maximum concurrency for Y tokens per request: Nx

설치#

환경에 맞는 방법을 선택합니다.

  • 설치 스크립트: CUDA 나 GPU 드라이버가 설치되지 않은 새 Ubuntu 또는 Debian 머신입니다.
  • vLLM만 설치: CUDA와 드라이버가 이미 있는 경우입니다(GCP의 NVIDIA Deep Learning VM, AWS Deep Learning AMI, 기존 GPU 머신).
  • Docker: 호스트 수준 설정을 전부 건너뜁니다.

하드웨어가 다르다면 추가 구성은 GPT OSS - vLLM Recipes를 참고합니다.

옵션 1: 설치 스크립트(처음부터)#

스택을 업데이트할 때는 각 변수에 다음 버전을 사용합니다. 이 버전들은 GPT OSS 120B를 서빙하는 데 필요한 최소 버전입니다. vLLM은 성능 개선, 버그 수정, 하드웨어 지원 확대가 포함된 최신 릴리스를 사용하는 것이 좋습니다.

변수 버전
CUDA toolkit 12.9
최소 드라이버 575.x
Python 3.12
vLLM 0.18.0
#!/bin/bash
# vLLM + CUDA installation for gpt-oss-120b
# Target: Ubuntu 22.04 / Debian 12, x86_64

CUDA_VERSION="12-9"           # apt package suffix  →  cuda-toolkit-12-9
MIN_DRIVER_VERSION="575"      # minimum driver for CUDA 12.9
PYTHON_VERSION="3.12"
VLLM_VERSION="0.18.0"
VENV_DIR="${HOME}/vllm-env"

set -e

# ===========================================================================
# PART 1 — system prerequisites
# ===========================================================================
echo "--- Part 1: System prerequisites ---"

sudo apt-get update && sudo apt-get upgrade -y

sudo apt-get install -y \
    build-essential \
    dkms \
    linux-headers-$(uname -r) \
    wget curl gnupg2 \
    software-properties-common \
    python${PYTHON_VERSION} \
    python${PYTHON_VERSION}-venv \
    python${PYTHON_VERSION}-dev \
    python3-pip git

# Install uv — recommended by vLLM docs; gives extra index URLs higher
# priority than PyPI, which is required for the gpt-oss fork to resolve correctly.
curl --location --silent --show-error --fail "https://astral.sh/uv/install.sh" | sh
source "${HOME}/.local/bin/env"

# ===========================================================================
# PART 2 — NVIDIA drivers and CUDA toolkit
# Reboot required after this section before continuing to Part 3.
# ===========================================================================
echo "--- Part 2: NVIDIA drivers and CUDA ${CUDA_VERSION//-/.} ---"

# Add NVIDIA's package repository.
# For Debian 12, replace ubuntu2204 with debian12 in the URL.
# Current keyring URL: https://developer.nvidia.com/cuda-downloads
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt-get update

# cuda-drivers (no version suffix) is a meta-package — apt resolves
# the latest driver compatible with the pinned toolkit automatically.
sudo apt-get install -y \
    cuda-drivers \
    cuda-toolkit-${CUDA_VERSION} \
    nvidia-gds-${CUDA_VERSION}

echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc

# Keep GPU initialized between jobs (reduces cold-start latency)
sudo systemctl enable nvidia-persistenced

echo "Rebooting to load NVIDIA kernel modules..."
echo "After reboot, run:  bash install.sh --post-reboot"

if [[ "${1:-}" != "--post-reboot" ]]; then
    sudo reboot
fi

# ===========================================================================
# PART 3 — Python environment and vLLM
# Start here after reboot, or if using a cloud managed image.
# ===========================================================================
echo "--- Part 3: Verify drivers ---"

nvidia-smi       # confirm driver >= ${MIN_DRIVER_VERSION} and GPUs visible
nvcc --version   # confirm CUDA ${CUDA_VERSION//-/.}

echo "--- Part 3: Python environment ---"

uv venv "$VENV_DIR" --python ${PYTHON_VERSION} --seed
source "$VENV_DIR/bin/activate"

python --version   # should show Python 3.12.x

echo "--- Part 3: PyTorch ---"

# --torch-backend=auto inspects your installed CUDA driver at runtime and
# selects the matching PyTorch index automatically. This replaces hardcoded
# --index-url flags and stays correct across CUDA version updates.
uv pip install torch torchvision torchaudio --torch-backend=auto

echo "--- Part 3: vLLM ---"

uv pip install "vllm==${VLLM_VERSION}" --torch-backend=auto

echo ""
echo "Installation complete."
echo "Activate environment:  source ${VENV_DIR}/bin/activate"
echo "Verify vLLM version:   python -c \"import vllm; print(vllm.__version__)\""

옵션 2: vLLM만 설치#

CUDA와 드라이버가 이미 설치되어 있다면(클라우드 관리형 이미지, 기존 GPU 머신) 다음 명령으로 vLLM을 설치합니다.

uv venv
source .venv/bin/activate
uv pip install vllm --torch-backend=auto

옵션 3: Docker#

다음 명령으로 GPT OSS 120B Docker 이미지를 설치합니다. vllm/vllm-openai:v0.18.0 이미지에는 CUDA, 드라이버, vLLM 이 포함되어 있습니다.

docker run \
  --gpus all \
  -p 8000:8000 \
  --ipc=host \
  vllm/vllm-openai:v0.18.0 \
  --model openai/gpt-oss-120b

vLLM 구성#

vLLM 구성 값은 트래픽 패턴에 따라 달라집니다. 아래 권장 설정으로 시작한 다음 이 조정 항목들을 맞춰 갑니다.

플래그 기본값 설명
--gpu-memory-utilization 0.90 vLLM 이 확보하는 GPU 메모리 비율입니다. KV 캐시를 늘리고 처리량을 높이려면 0.95로 올립니다. 부하 상황에서 OOM 오류가 발생하면 낮춥니다.
--max-model-len 모델 최대값(GPT OSS 120B의 경우 128K) 요청당 최대 컨텍스트 길이를 제한합니다. 이 값을 낮추면 동시 처리 용량이 늘어납니다.
--max-num-seqs 256 단일 배치의 최대 요청 수입니다. 값이 클수록 GPU 활용도와 처리량이 좋아지지만 요청당 지연 시간이 늘어납니다. 실제 동시 처리 수는 사용 가능한 KV 캐시로 여전히 제한됩니다.
--max-num-batched-tokens None 반복당 처리하는 전체 토큰 수입니다. --max-num-seqs와 함께 동작하며, vLLM은 둘 중 먼저 도달하는 한계까지 배치를 구성합니다.
--tensor-parallel-size None 레이어를 N 개의 GPU에 수평으로 나눕니다. 높은 대역폭이 필요하며 NVLink로 연결된 단일 노드 안에서 사용합니다.
--pipeline-parallel-size None 레이어를 N 개의 GPU에 순차적으로 나눕니다. 낮은 대역폭도 견디므로 PCIe로 연결된 노드 사이에 적합합니다.

권장 설정#

다음 표는 하드웨어별 권장 설정입니다. 사용하는 하드웨어와 예상 트래픽 패턴에 맞는 행을 고른 다음, 해당 구성을 사용합니다.

근사 동시 요청 수 칼럼은 표에 적힌 컨텍스트 길이에서 KV 캐시로 제한되는 대략적인 동시 처리 수이며, --max-num-seqs 값이 아닙니다.

하드웨어 최대 컨텍스트 근사 동시 요청 수 최적 용도
Single H100 80 GB 32K 10 개발·테스트, 저트래픽 서빙
2× H100 80 GB 64K 34 중간 규모 프로덕션 부하
4× H100 80 GB 128K 51 전체 컨텍스트 창, 높은 처리량
2× A100 40 GB 32K 3 최소 구성의 A100 설정
4× A100 40 GB 32K 69 더 높은 A100 처리량
2× L40S / RTX A6000 Ada 48 GB 32K 19 비용 효율적인 Ada Lovelace 옵션

Single H100 80 GB#

이 설정에서 --gpu-memory-utilization을 기본값 0.90보다 높은 0.95로 올리는 것은 단일 H100의 알려진 CUDA OOM 문제를 우회하기 위해서입니다.

vllm serve openai/gpt-oss-120b \
  --gpu-memory-utilization 0.95 \
  --max-model-len 32768 \
  --max-num-seqs 16 \
  --max-num-batched-tokens 4096

2× H100 80 GB#

이 설정에서는 합쳐진 KV 캐시 풀이 더 크므로 컨텍스트 창을 넓히고 동시 요청을 더 많이 처리할 수 있습니다.

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 2 \
  --max-model-len 65536 \
  --max-num-seqs 32 \
  --max-num-batched-tokens 8192

4× H100 80 GB#

이 설정은 128K 컨텍스트 창 전체를 제공합니다.

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 4 \
  --gpu-memory-utilization 0.95 \
  --max-model-len 131072 \
  --max-num-seqs 64 \
  --max-num-batched-tokens 16384

2× A100 40 GB#

이 설정에서 단일 A100 40 GB는 61 GB 모델 가중치를 담지 못합니다. GPU 두 개가 최소 구성입니다.

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 2 \
  --max-model-len 32768 \
  --max-num-seqs 24 \
  --max-num-batched-tokens 4096

4× A100 40 GB#

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 4 \
  --max-model-len 32768 \
  --max-num-seqs 128 \
  --max-num-batched-tokens 16384

2× L40S 48GB 또는 RTX A6000 Ada 48 GB#

두 설정 모두 48 GB의 Ada Lovelace를 사용합니다.

vllm serve openai/gpt-oss-120b \
  --tensor-parallel-size 2 \
  --max-model-len 32768 \
  --max-num-seqs 16 \
  --max-num-batched-tokens 4096

NVIDIA Blackwell 및 Hopper 추가 최적화는 GPT OSS - vLLM Recipes: Recipe for NVIDIA Blackwell & Hopper Hardware를 참고합니다.

서버 확인#

vLLM을 시작한 다음에는 아래 요청으로 정상적으로 서빙되는지 확인합니다.

curl "http://localhost:8000/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-oss-120b",
    "messages": [{"role": "user", "content": "Hello"}],
    "max_tokens": 64
  }'

모델의 완성 결과가 담긴 JSON 응답이 표시됩니다. 서버가 아직 준비되지 않았다면 연결 거부 오류를 받습니다. vLLM은 처음 시작할 때 모델 가중치를 불러올 시간이 필요하며, 저장소 속도에 따라 몇 분이 걸릴 수 있습니다.

모니터링#

vLLM은 Prometheus 호환 /metrics 엔드포인트를 제공합니다. 전체 목록은 Production Metrics - vLLM을 참고합니다.

vLLM을 모니터링할 때는 사용자 대면 지연 시간과 용량 압박 지표를 확인합니다.

메트릭 설명
사용자 대면 지연 시간
time_to_first_token 사용자가 응답성으로 느끼는 시간입니다.
time_per_output_token_seconds 스트리밍이 얼마나 부드럽게 느껴지는지를 나타냅니다.
용량 압박
kv_cache_usage_perc 사용 중인 KV 풀의 비율입니다. 주요 메모리 압박 신호입니다. 0.85를 넘는 값이 지속되면 용량에 가까워지고 있다는 뜻입니다.
num_requests_waiting KV 캐시가 가득 차서 대기 중인 요청 수입니다. 대기열이 계속 늘어나면 용량을 초과한 것입니다. GPU를 늘리거나, --max-model-len을 줄이거나, --max-num-seqs를 낮춥니다.
num_requests_running 실제 동시 처리 수입니다.

문제 해결#

클라이언트 타임아웃 또는 num_requests_waiting의 지속 증가#

들어오는 요청이 KV 캐시 용량을 초과한 경우입니다. vLLM은 캐시 공간이 확보될 때까지 새 요청을 대기열에 넣고, 대기열은 줄어들지 않습니다.

이 문제를 해결하는 방법은 다음과 같습니다.

  1. kv_cache_usage_perc를 확인합니다. 0.85를 넘는 값이 지속되면 메모리에 병목이 있다는 뜻입니다.
  2. --max-model-len을 줄여 요청당 KV 할당량을 낮춥니다. 그러면 동시 요청을 더 받을 여유가 생깁니다.
  3. --max-num-seqs를 줄여 동시에 캐시를 두고 경쟁하는 요청 수를 제한합니다.
  4. 단일 노드 조정을 모두 시도했다면 수평으로 확장합니다. GPU 나 노드를 추가하고 여러 vLLM 인스턴스에 부하를 분산합니다.

CUDA OOM 오류로 인한 서버 충돌#

부하가 높을 때 서버의 GPU 메모리가 부족한 경우입니다.

이 문제를 해결하려면 다음 순서로 조정합니다.

  1. --max-num-seqs를 줄여 동시 배치 크기를 제한합니다.
  2. --max-model-len을 줄여 요청당 KV 할당량을 낮춥니다.
  3. 시작 시점에 OOM 이 발생하면 --gpu-memory-utilization을 낮춥니다.

예상보다 느린 토큰 생성#

time_per_output_token_seconds가 높고 전체 토큰/초가 낮은 경우입니다. GPU가 반복마다 처리하는 작업량이 부족한 상태입니다.

이 문제를 해결하는 방법은 다음과 같습니다.

  1. --max-num-batched-tokens를 늘려 vLLM 이 반복마다 더 많은 토큰을 처리하도록 합니다.
  2. --max-num-seqs를 늘려 더 많은 요청이 함께 배치되도록 합니다. 그러면 GPU 활용도가 좋아집니다.