본문으로 건너뛰기

Qwen 3.x 설치

AWS 서버 세팅​

EC2 인스턴스 설정​


기본 정보 (요약)​

카테고리선택
리전us-west-2 (오레곤)
애플리케이션 및 OS 이미지Deep Learning Base AMI with Single CUDA (Amazon Linux 2023)
인스턴스 유형g7e.4xlarge (GPU 1장, VRAM 96 GB)
스토리지EBS 2 TB (gp3) + 인스턴스 스토어 1.7 TB (NVMe)

리전 선택 근거

신형 GPU 인스턴스(G7e, P5, P6 등)는 공급이 수요를 못 따라잡는 상태 입니다. 리전·시간대에 따라 InsufficientInstanceCapacity 에러로 인스턴스 프로비저닝이 실패하는 일이 자주 발생합니다.

이런 이유로 리전 선택은 단순히 "가까운 리전"이 아니라, 다음 두 축을 함께 따져야 합니다.

  1. Capacity 점유 가능성 — 원할 때 실제로 띄울 수 있는가
  2. 한국 응답시간 — 사용자가 체감할 네트워크 지연

G7e 제공 리전 비교 (2026-05-19 측정)

리전Capacity 점수한국 TCP RTT종합
us-west-2 (오레곤) ⭐3180 ms🟢 균형 (capacity 3점 가용영역 2개)
us-east-1 (버지니아)3208 ms🟢 안정 (capacity 3점 가용영역 2개)
us-east-2 (오하이오)3213 ms🟢 안정
ap-northeast-1 (도쿄)146 ms🟠 가깝지만 점유 어려움
ap-northeast-2 (서울)118 ms🔴 점유 매우 어려움
eu-west-2 (런던)1301 ms🔴 멀고 점유 어려움

점수 해석

  • Capacity 점수(g7e.12xl, 1~10) = AWS Spot Placement Score (1=매우 부족 / 10=매우 여유). On-Demand 가용성과도 강한 상관관계
  • G7e 제공 6개 리전 모두 점수가 낮은 편 (신형 GPU 공통 현상) → 그중 점수 3이 현 시점 최선
  • 시간대·요일에 따라 점수가 바뀜 → 운영 전 직접 재측정 권장

Spot Placement Score 직접 조회

aws ec2 get-spot-placement-scores \
--instance-types g7e.12xlarge \
--target-capacity 1 \
--no-single-availability-zone \
--region-names us-west-2 us-east-1 us-east-2 ap-northeast-1 ap-northeast-2 eu-west-2 \
--query "sort_by(SpotPlacementScores, &Score) | reverse(@) | [].[Region, Score]" \
--output table
  • 필요 권한: ec2:GetSpotPlacementScores
  • 비용: 무료, 평가 기간: 향후 1시간

(1) Capacity 측면

  • 한·일 리전(서울·도쿄)은 점수 1 → 평일 업무시간 기준 잦은 프로비저닝 실패 예상
  • 미국 리전 3곳(us-east-1 / us-east-2 / us-west-2)은 점수 3
  • 그중 us-west-2와 us-east-1은 점수 3인 가용영역이 2개 (usw2-az1·az3 / use1-az2·az6) → 한 가용영역의 capacity가 소진되어도 다른 가용영역으로 폴백 가능

(2) 응답시간 측면

  • LLM 서빙은 모델 자체의 첫 토큰 생성에 200~500 ms 소요 → 네트워크 +150~200 ms는 실사용자 체감 차이가 거의 없는 수준
  • 한국 인접 우선이라면 도쿄가 sweet spot이지만 capacity 제약이 큼
팁

🎯 결론

  • 점유 안정성 을 우선 고려해 us-west-2(오레곤) 선택
  • 한국 사용자 인터랙티브 서빙으로 확장 시 ap-northeast-1(도쿄) 멀티리전 또는 Capacity Block for ML / Capacity Reservation 예약 검토

1. 애플리케이션 및 OS 이미지 (Amazon Machine Image)​

선택한 AMI

항목값
이름Deep Learning Base AMI with Single CUDA (Amazon Linux 2023) 20260512
OSAmazon Linux 2023 (커널 6.1.170)
OwnerAmazon
아키텍처x86_64

참고: AMI 설명상 지원 인스턴스 목록

G4dn, G5, G6, Gr6, G6e, P4d, P4de, P5, P5e, P5en, P6-B200, P6-B300
경고

ℹ️ 공식 목록에 G7e가 없음 . 다만 실측 결과 Blackwell 드라이버·CUDA가 정상 작동 확인. 향후 재생성 시에는 G7e를 명시 지원하는 Deep Learning Base OSS Nvidia Driver GPU AMI (AL2023) 사용 권장.


2. 인스턴스 유형​

선택한 인스턴스 : g7e.4xlarge

항목값
vCPU16
RAM128 GB
GPUNVIDIA RTX PRO 6000 Blackwell Server Edition × 1
VRAM96 GB (97,887 MiB 실측)
GPU 아키텍처Blackwell (sm_120, FP4 네이티브 지원)
Network50 Gbps
인스턴스 스토어NVMe SSD 1.9 TB (nvme1n1 ) — 인스턴스 유형에 기본 포함
g7e 패밀리 비교 (참고)
TypevCPURAMGPU 수VRAM 총량Network
g7e.2xlarge864 GB196 GB50 Gbps
g7e.4xlarge ⭐16128 GB196 GB50 Gbps
g7e.8xlarge32256 GB196 GB100 Gbps
g7e.12xlarge48512 GB2192 GB400 Gbps
g7e.24xlarge961 TB4384 GB800 Gbps
g7e.48xlarge1922 TB8768 GB1600 Gbps

4xlarge 선택 근거

  • Qwen3-Coder-30B-A3B / Qwen3.6-35B-A3B 등 MoE 30~35B 모델은 bf16에서 ~70GB VRAM → 96GB 1장에 KV 캐시까지 여유
  • FP8/FP4 양자화 시 더 큰 모델(80~120B)도 가능
  • 우선 1 GPU로 검증 후 확장 필요 시 12xlarge 이상으로 변경

모델별 VRAM 요구량

32k 컨텍스트, 단일 시퀀스 기준. vLLM은 paged KV 캐시를 동적 할당하므로 실제 사용량은 워크로드에 따라 달라집니다.

모델총/활성 파라미터정밀도가중치 VRAMKV 캐시 (32k×1)총 VRAM
Qwen3.5-122B-A10B-GPTQ-Int4122B / 10B (MoE)Int4 (GPTQ)~63 GB~3 GB~69 GB
Qwen3.6-27B-FP827B (Dense)FP8 (block 128)~29 GB~8 GB~40 GB

3. 스토리지 구성​

1) 루트 EBS 볼륨 (영구 스토리지)

항목값
크기2,048 GiB (2 TB)
타입gp3
IOPS16,000
Throughput1,000 MB/s
암호화미적용(운영 전환 시 암호화 권장)
디바이스nvme0n1
마운트/ (루트)

용도 : 모델 가중치(영구 보관), Docker 이미지, OS 등

2) 인스턴스 스토어 (임시 스토리지 — g7e.4xlarge 기본 포함)

항목값
디바이스nvme1n1
크기1.7 TB
타입NVMe SSD (인스턴스 로컬)
마운트/mnt/nvme (XFS, 수동 마운트 필요 — 아래 NVME 설정 참고)
주의

⚠️ 인스턴스 스토어 데이터 영속성

작업데이터
Reboot (재부팅)유지
Stop / Start삭제
Terminate삭제
하드웨어 장애삭제

용도 분리 권장

  • EBS ( / ) : 모델 가중치, 영구 데이터 → 절대 잃으면 안 되는 것
  • 인스턴스 스토어 ( /mnt/nvme ) : KV 캐시, 임시 빌드, swap, 추론 로그 → 잃어도 되는 것

NVME 설정​

  • NVME 는 Cloud 환경에서는 일반 물리서버와 다르게 아래와 같은 특성이 있음
    • 재부팅시 데이터 유지

    • Instance stop→start, terminator 시 데이터 소멸 됨

1. NVME Device 확인​

> lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 2T 0 disk
├─nvme0n1p1 259:2 0 2T 0 part /
├─nvme0n1p127 259:3 0 1M 0 part
└─nvme0n1p128 259:4 0 10M 0 part /boot/efi
nvme1n1 259:1 0 1.7T 0 disk
> lsblk -d -o NAME,MODEL,SIZE
NAME MODEL SIZE
nvme0n1 Amazon Elastic Block Store 300G
nvme1n1 Amazon EC2 NVMe Instance Storage 3.5T

2. 디스크 포멧 및 마운트​

> sudo mkfs.xfs -f /dev/nvme1n1
meta-data=/dev/nvme1n1 isize=512 agcount=16, agsize=28991699 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1 bigtime=1 inobtcount=1 nrext64=0
= exchange=0
data = bsize=4096 blocks=463867184, imaxpct=5
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1, parent=0
log =internal log bsize=4096 blocks=226497, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
Discarding blocks...Done.
>
> sudo mkdir -p /mnt/nvme
> sudo mount -o noatime /dev/nvme1n1 /mnt/nvme
> sudo chown -R root:root /mnt/nvme
> df -h /mnt/nvme
Filesystem Size Used Avail Use% Mounted on
/dev/nvme1n1 1.8T 13G 1.8T 1% /mnt/nvme
>

모델 설치​

현실적으로 A100 이나 H100 장비 대여가 쉽지 않은 상황에서 1장으로 운영 가능한 GPU 에서 돌릴 수 있는 서버에서 아래 2개의 모델을 비교 한다. (비교 문서는 추후 배포)

모델명모델 가중치 크기실제 GPUKV 캐시 가용 (90% 활용 기준)
Qwen3.5-122B-A10B-GPTQ-Int462GB65~70GB~18GB
Qwen3.6-27B-FP831GB33~35GB~52GB
  • 기본 패키지 설치
  • 모델 다운로드
  • vllm 설정
  • 모델 설정

기본 패키지 설치​

huggingface-cli 설치​
> pip install -U "huggingface_hub[cli]" hf_transfer
환경 변수 설정​
# 다운로드 가속 (멀티스레드)
export HF_XET_HIGH_PERFORMANCE=1

# 저장 위치 - 둘 중 선택
export HF_HOME=/mnt/nvme/hf-cache # 빠르지만 stop 시 소실
# export HF_HOME=/root/hf-cache # 또는 EBS (영구)

모델 다운로드​

  • 모델을 로컬 디렉토리에 다운로드
  • 모델은 다운로드 후, S3 에 올려 두어도 된다.
## 첫번째 모델 다운로드
> hf download Qwen/Qwen3.5-122B-A10B-GPTQ-Int4 \
--local-dir /stg/models/Qwen3.5-122B-A10B-GPTQ-Int4 \
--max-workers 16

## 두번째 모델 다운로드
> hf download Qwen/Qwen3.6-27B-FP8 \
--local-dir /stg/models/Qwen3.6-27B-FP8 \
--max-workers 16

> ls -al /stg/models
total 32
drwxr-xr-x. 6 root root 116 May 19 18:46 .
drwxr-xr-x. 3 root root 20 May 19 16:56 ..
-rw-r--r--. 1 root root 0 May 19 17:25 .check_for_update_done
drwxr-xr-x. 3 root root 16384 May 19 17:30 Qwen3.5-122B-A10B-GPTQ-Int4
drwxr-xr-x. 3 root root 16384 May 19 18:46 Qwen3.6-27B-FP8
drwxr-xr-x. 4 root root 92 May 19 18:45 hub
drwxr-xr-x. 4 root root 59 May 19 17:28 xet

VLLM 설치​

vllm 은 패키지 의존성을 많이 요구하기 때문에 uv 환경에서 격리 하여 패키지 설치를 권장 함

  • 대상: RTX PRO 6000 Blackwell(sm_120) / CUDA 13.0 / Python 3.12 / AL2023
vllm==0.22.0
torch==2.11.0+cu130
torchaudio==2.11.0+cu130
torchvision==0.26.0+cu130
flashinfer-python==0.6.12
transformers==5.8.1

uv 설치​

> curl -LsSf https://astral.sh/uv/install.sh | sh
downloading uv 0.11.15 x86_64-unknown-linux-gnu
installing to /root/.local/bin
uv
uvx
everything's installed!
> source ~/.bashrc
> uv --version
uv 0.11.15 (x86_64-unknown-linux-gnu)
>

환경 설치​

# 디렉토리 생성
> mkdir -p /usr/service/vllm-svc
> cd /usr/service/vllm-svc

# UV 새엉
> uv venv --python 3.12
Using CPython 3.12.13 interpreter at: /usr/bin/python3.12
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate

# 확인
> source .venv/bin/activate
(vllm-svc) > python --version
Python 3.12.13
(vllm-svc) >

Torch 설치​

  • sm_120 미포함이면 절대 진행 금지 (Balckwell GPU 에서 필요)
    • sm_100 / sm_120 : 블랙웰 (Blackwell), RTX 5090, 5080 등 RTX 50 시리즈 등을 지원하는 아키텍처
(vllm-svc) > uv pip install \
torch==2.11.0 torchaudio==2.11.0 torchvision==0.26.0 \
--index-url https://download.pytorch.org/whl/cu130

(vllm-svc) > python - <<'PY'
import torch
al = torch.cuda.get_arch_list()
print("torch", torch.__version__, "| cuda", torch.version.cuda)
print("arch_list", al)
assert torch.__version__.endswith("+cu130"), "❌ cu130 휠 아님"
assert "sm_120" in al, "❌ sm_120 미포함 → Blackwell 커널 없음"
print("✅ torch OK")
PY

torch 2.11.0+cu130 | cuda 13.0
arch_list ['sm_75', 'sm_80', 'sm_86', 'sm_90', 'sm_100', 'sm_120']
✅ torch OK
(vllm-svc) >


# VLLM 이 torch 버전을 변경할 수 있으니, 고정 시켜서 설치한다.
(vllm-svc) > cat > /tmp/torch-constraint.txt <<'EOF'
torch==2.11.0+cu130
torchaudio==2.11.0+cu130
torchvision==0.26.0+cu130
EOF

(vllm-svc) > uv pip install vllm==0.22.0 \
--constraint /tmp/torch-constraint.txt \
--extra-index-url https://download.pytorch.org/whl/cu130 \
--index-strategy unsafe-best-match

# 최종 버전 확인
(vllm-svc) > .venv/bin/vllm --version
0.22.0
(vllm-svc) >

멀티모달 기능 추가​

(vllm-svc) > uv pip install ninja
(vllm-svc) > which ninja
/usr/service/vllm-svc/.venv/bin/ninja
(vllm-svc) >

Cache 디렉토리 생성​

(vllm-svc) > mkdir -p /usr/service/cache/flashinfer
(vllm-svc) > mkdir -p /usr/service/cache/vllm-cache
(vllm-svc) > mkdir -p /usr/service/cache/hf-cache
테스트​
(vllm-svc) > vllm serve /stg/models/Qwen3.5-122B-A10B-GPTQ-Int4 \
--served-model-name qwen \
--port 8000 \
--tensor-parallel-size 1 \
--quantization moe_wna16 \
--max-model-len 32768 \
--max-num-seqs 8 \
--gpu-memory-utilization 0.90 \
--reasoning-parser qwen3 \
--trust-remote-code
(vllm-svc) > curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen",
"messages": [{"role":"user","content":"안녕"}],
"max_tokens": 100,
"chat_template_kwargs": {"enable_thinking": false}
}'


{"id":"chatcmpl-89cf9de14d6fdfd2","object":"chat.completion","created":1779181606,"prompt_routed_experts":null,"model":"qwen","choices":[{"index":0,"message":{"role":"assistant","content":"안녕하세요! 반갑습니다. 😊\n오늘 어떤 도움이 필요하신가요? 궁금한 점이 있거나 대화하고 싶은 주제가 있다면 언제든지 말씀해 주세요.","refusal":null,"annotations":null,"audio":null,"function_call":null,"tool_calls":[],"reasoning":null},"logprobs":null,"finish_reason":"stop","stop_reason":null,"token_ids":null,"routed_experts":null}],"service_tier":null,"system_fingerprint":"vllm-0.21.0-2426ae93","usage":{"prompt_tokens":14,"total_tokens":49,"completion_tokens":35,"prompt_tokens_details":null},"prompt_logprobs":null,"prompt_token_ids":null,"prompt_text":null,"kv_transfer_params":null}[root@ip-172-31-22-41 models]#

Service 등록​

  • Qwen3.6-27B-FP8
[Unit]
Description=vLLM Qwen3.6-27B-FP8 Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=vllm
WorkingDirectory=/usr/service/vllm-svc

Environment="PATH=/usr/service/vllm-svc/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
Environment="HF_HOME=/mnt/nvme/hf-cache"
Environment="VLLM_CACHE_ROOT=/mnt/nvme/vllm-cache"

# NVMe 마운트 확인
ExecStartPre=/bin/bash -c 'mountpoint -q /mnt/nvme || (echo "NVMe not mounted" && exit 1)'

# 모델/캐시 디렉토리 준비
ExecStartPre=/bin/mkdir -p /mnt/nvme/models /mnt/nvme/hf-cache /mnt/nvme/vllm-cache

# EBS → NVMe 동기화
ExecStartPre=/usr/bin/rsync -a --delete \
/stg/models/Qwen3.6-27B-FP8/ \
/mnt/nvme/models/Qwen3.6-27B-FP8/

ExecStart=/usr/service/vllm-svc/.venv/bin/vllm serve \
/mnt/nvme/models/Qwen3.6-27B-FP8 \
--served-model-name qwen \
--port 8000 \
--tensor-parallel-size 1 \
--max-model-len 262144 \
--max-num-seqs 16 \
--gpu-memory-utilization 0.92 \
--enable-prefix-caching \
--reasoning-parser qwen3 \
--trust-remote-code

StandardOutput=append:/usr/service/logs/vllm/qwen_27.log
StandardError=append:/usr/service/logs/vllm/qwen_27.log

TimeoutStartSec=600
TimeoutStopSec=60
Restart=on-failure
RestartSec=10
KillMode=mixed
LimitNOFILE=1048576
LimitNPROC=1048576

[Install]
WantedBy=multi-user.target


Qwen3-Omni-30B-A3B-Instruct (멀티모달)​

앞의 텍스트 모델(Qwen3.5 / 3.6)과 달리 영상·이미지·오디오를 함께 입력 받는 옴니 모델. 6초 클립 영상 이해 벤치마크(vision-bench)에 사용한다. 설치 흐름은 위와 동일하되 오디오 디코더 의존성 과 멀티모달 서빙 플래그 가 추가된다. (vLLM 설치는 위 VLLM 설치 섹션과 동일한 venv 를 재사용 하며, 여기선 audio deps 만 추가한다.)

모델 다운로드​

> hf download Qwen/Qwen3-Omni-30B-A3B-Instruct \
--local-dir /stg/models/Qwen3-Omni-30B-A3B-Instruct \
--max-workers 16

오디오 입력 지원 (필수)​

uv pip install vllm 기본 설치엔 오디오 디코더가 빠져 있어, 오디오 입력 요청 시 400 "Invalid or unsupported audio file" 가 발생한다 (비디오 단독 요청은 정상이라 증상이 헷갈림). 아래 3개를 venv 에 추가해야 한다.

(vllm-svc) > uv pip install ninja
(vllm-svc) > which ninja
/usr/service/vllm-svc/.venv/bin/ninja
(vllm-svc) >
(vllm-svc) > uv pip install soundfile librosa av
  • soundfile (libsndfile 바인딩) · librosa (리샘플링) · av (PyAV, 컨테이너 demux) — 셋 다 필요
  • 설치 후 서비스 재기동해야 적용 된다 (sudo systemctl restart vllm_omni_i )
  • 클라이언트 요청 본문에 mm_processor_kwargs: {"use_audio_in_video": true} 를 넣어야 mp4 안 오디오가 함께 처리된다

수동 테스트​

  • venv 쉘이 적용된 상태에서 실행 한다.
(vllm-svc) > export VLLM_CACHE_ROOT=/usr/service/cache/vllm-cache
export HF_HOME=/usr/service/cache/cache/hf-cache

PATH="/usr/service/vllm-svc/.venv/bin:$PATH" \
vllm serve /mnt/nvme/models/Qwen3-Omni-30B-A3B-Instruct \
--served-model-name qwen \
--port 8000 --host 0.0.0.0 \
--dtype bfloat16 \
--max-model-len 16384 \
--max-num-seqs 8 \
--gpu-memory-utilization 0.90 \
--mm-encoder-attn-backend TORCH_SDPA \
--moe-backend triton \
--allowed-local-media-path /mnt/nvme/vod \
--limit-mm-per-prompt '{"image":1,"video":1,"audio":1}' \
--tensor-parallel-size 1 \
--trust-remote-code

Service 등록​

참고: 오디오 입력을 쓰려면 --limit-mm-per-prompt 에 audio 가 포함돼야 하고, venv 엔 위 오디오 deps 가 설치돼 있어야 한다.

[Unit]
Description=vLLM Qwen3-Omni-30B-A3B-Instruct Service
After=network-online.target nvme-prep.service
Wants=network-online.target
Requires=nvme-prep.service

[Service]
Type=simple
User=vllm
WorkingDirectory=/usr/service/vllm-svc

Environment="PATH=/usr/service/vllm-svc/.venv/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin"
Environment="HOME=/root"
Environment="HF_HOME=/usr/service/cache/hf-cache"
Environment="VLLM_CACHE_ROOT=/usr/service/cache/vllm-cache"
Environment="FLASHINFER_WORKSPACE_BASE=/usr/service/cache"

# Nvme 디렉토리 검사 및 s3 -> nvme 로 모델 복사
ExecStartPre=/bin/bash -c 'mountpoint -q /mnt/nvme || (echo "NVMe not mounted" && exit 1)'
ExecStartPre=/bin/bash /usr/service/start_server/s3_sync_omni.sh

ExecStart=/usr/service/vllm-svc/.venv/bin/vllm serve /mnt/nvme/models/Qwen3-Omni-30B-A3B-Instruct \
--served-model-name qwen \
--port 8000 \
--host 0.0.0.0 \
--dtype bfloat16 \
--max-model-len 16384 \
--max-num-seqs 8 \
--gpu-memory-utilization 0.82 \
--mm-encoder-attn-backend TORCH_SDPA \
--moe-backend triton \
--allowed-local-media-path /mnt/nvme/vod \
--limit-mm-per-prompt "{\"image\":1,\"video\":1,\"audio\":1}" \
--tensor-parallel-size 1 \
--trust-remote-code

ExecStartPost=/bin/bash /usr/service/start_server/vllm_warmup.sh

StandardOutput=append:/usr/service/logs/vllm/qwen_omni.log
StandardError=append:/usr/service/logs/vllm/qwen_omni.log
TimeoutStartSec=1800
TimeoutStopSec=60
Restart=on-failure
RestartSec=10
KillMode=mixed
LimitNOFILE=1048576
LimitNPROC=1048576

[Install]
WantedBy=multi-user.target

감사합니다.