LLM Inference vLLM Docker Container Deploy

โดย อ. บอมกิตติทัศน์เจริญพนาสิทธิ์ | อัปเดต 24 ก. พ. 2026 | อ่าน 16 นาที
- LLM Inference คืออะไร — ความท้าทาย
- vLLM คืออะไร — High-throughput Inference Engine
- PagedAttention — เทคนิคที่เปลี่ยนเกม
- เปรียบเทียบ vLLM vs TGI vs Ollama vs llama.cpp
- GPU Requirements ตาม Model Size
- Deploy vLLM ด้วย Docker
- Docker Compose — Production Setup
- OpenAI-compatible API — ใช้แทน OpenAI ได้เลย
- Quantization — ลด VRAM ด้วย AWQ/GPTQ
- Tensor Parallelism — กระจายไปหลาย GPU
- Performance Tuning
- Monitoring และ Metrics
- Deploy บน Kubernetes
- Best Practices และสรุป
LLM Inference คืออะไร — ความท้าทาย
LLM Inference คือการนำ Large Language Model ที่ Train เสร็จแล้วมาใช้งานจริงรับ Input (Prompt) แล้วสร้าง Output (Response) ความท้าทายของ LLM Inference ต่างจาก Model อื่นเพราะ LLM มีขนาดใหญ่มาก (7B-405B Parameters) ต้องใช้ GPU VRAM มหาศาล, สร้าง Token ทีละตัว (Autoregressive) ทำให้ช้า, KV Cache ใช้ Memory มากและเพิ่มขึ้นตาม Sequence Length และต้อง Serve หลาย Request พร้อมกัน (Concurrent Users)
ในปี 2026 การ Self-host LLM กลายเป็นทางเลือกที่นิยมมากขึ้นเพราะลดค่า API Cost สำหรับ High-volume Usage, ข้อมูลไม่ออกนอกองค์กร (Data Privacy), Customize Model ได้ (Fine-tuning) และไม่ต้องพึ่งพา Provider ภายนอก
vLLM คืออะไร — High-throughput Inference Engine
vLLM เป็น Open Source LLM Inference Engine ที่พัฒนาโดยทีมจาก UC Berkeley ใช้เทคนิค PagedAttention ที่ปฏิวัติวิธีจัดการ KV Cache ทำให้ Throughput สูงกว่า HuggingFace Transformers 2-24 เท่าและสูงกว่า Text Generation Inference (TGI) ของ HuggingFace 2-5 เท่า
จุดเด่นของ vLLM ได้แก่ PagedAttention จัดการ Memory อย่างมีประสิทธิภาพ, Continuous Batching รับ Request ใหม่ได้ตลอดไม่ต้องรอ Batch เดิมเสร็จ, OpenAI-compatible API ใช้แทน OpenAI ได้ทันที, Tensor Parallelism กระจายไปหลาย GPU, Quantization Support รองรับ AWQ, GPTQ, INT8 และ Streaming ส่ง Token กลับทีละตัว
PagedAttention — เทคนิคที่เปลี่ยนเกม
ปัญหาใหญ่ของ LLM Inference คือ KV Cache ที่เก็บ Key-Value ของ Attention Layer สำหรับทุก Token ที่สร้างแล้วระบบเดิมจอง Memory ล่วงหน้าตาม Max Sequence Length ทำให้ Memory ถูกจองแต่ไม่ได้ใช้จริง (Waste 60-80%)
PagedAttention แก้ปัญหานี้โดยใช้แนวคิด Virtual Memory Paging จาก OS แบ่ง KV Cache เป็น Block ขนาดเล็กจอง Block เพิ่มเมื่อต้องการจริง Block ที่ใช้เสร็จแล้วคืนกลับ Pool ผลลัพธ์คือ Memory Waste ลดจาก 60-80% เหลือแค่ 4% ทำให้ใส่ Request ได้มากขึ้น 2-4 เท่าบน GPU เดียวกัน
เปรียบเทียบ vLLM vs TGI vs Ollama vs llama.cpp
| Engine | จุดเด่น | GPU Required | เหมาะกับ |
|---|---|---|---|
| vLLM | Throughput สูงสุด, Production-grade | NVIDIA (CUDA) | Production Server, High Traffic |
| TGI (HuggingFace) | HuggingFace Ecosystem | NVIDIA (CUDA) | HuggingFace Users |
| Ollama | ง่ายมาก 1 คำสั่ง | Optional (CPU/GPU) | Local Development, ทดลอง |
| llama.cpp | CPU Inference, GGUF Format | Optional | Edge Device, No GPU |
| TensorRT-LLM | NVIDIA Optimized สุดๆ | NVIDIA (CUDA) | NVIDIA GPU เท่านั้น, Max Performance |
GPU Requirements ตาม Model Size
| Model Size | FP16 VRAM | INT8 VRAM | INT4 VRAM | แนะนำ GPU |
|---|---|---|---|---|
| 7-8B | ~16 GB | ~8 GB | ~5 GB | RTX 4090 (24 GB) |
| 13B | ~26 GB | ~13 GB | ~8 GB | A100 40GB |
| 34B | ~68 GB | ~34 GB | ~20 GB | A100 80GB |
| 70B | ~140 GB | ~70 GB | ~40 GB | 2x A100 80GB หรือ H100 |
| 405B | ~810 GB | ~405 GB | ~230 GB | 8x H100 80GB |
Deploy vLLM ด้วย Docker
# วิธีที่ง่ายที่สุด — 1 คำสั่ง
docker run --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.1-8B-Instruct \
--max-model-len 8192 \
--gpu-memory-utilization 0.9
# ทดสอบด้วย curl
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Llama-3.1-8B-Instruct",
"messages": [{"role": "user", "content": "สวัสดีครับ แนะนำตัวหน่อย"}],
"temperature": 0.7,
"max_tokens": 512
}'
Docker Compose — Production Setup
# docker-compose.yml
version: '3.8'
services:
vllm:
image: vllm/vllm-openai:latest
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=all
- HUGGING_FACE_HUB_TOKEN=
volumes:
- model-cache:/root/.cache/huggingface
ports:
- "8000:8000"
ipc: host
command: >
--model meta-llama/Llama-3.1-8B-Instruct
--max-model-len 8192
--gpu-memory-utilization 0.9
--max-num-batched-tokens 16384
--max-num-seqs 128
--enable-prefix-caching
--dtype bfloat16
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/ssl
depends_on:
- vllm
restart: unless-stopped
volumes:
model-cache:
OpenAI-compatible API — ใช้แทน OpenAI ได้เลย
# Python — ใช้ openai library กับ vLLM
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed" # vLLM ไม่ต้อง API Key
)
# Chat Completion
response = client.chat.completions.create(
model="meta-llama/Llama-3.1-8B-Instruct",
messages=[
{"role": "system", "content": "คุณเป็น AI Assistant ตอบเป็นภาษาไทย"},
{"role": "user", "content": "อธิบาย Docker ให้เข้าใจง่ายๆ"}
],
temperature=0.7,
max_tokens=1024,
stream=True # Streaming Response
)
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
# Embeddings (ถ้า Model รองรับ)
embeddings = client.embeddings.create(
model="BAAI/bge-large-en-v1.5",
input=["Hello world"]
)
เนื่องจาก vLLM ให้ OpenAI-compatible API สามารถใช้ Library/Framework ที่รองรับ OpenAI API ได้ทันทีเช่น LangChain, LlamaIndex, Haystack, CrewAI แค่เปลี่ยน base_url เป็น vLLM Server
Quantization — ลด VRAM ด้วย AWQ/GPTQ
# Deploy Model ที่ Quantize แล้ว (AWQ)
docker run --gpus all \
-p 8000:8000 \
vllm/vllm-openai:latest \
--model TheBloke/Llama-2-70B-Chat-AWQ \
--quantization awq \
--max-model-len 4096
# GPTQ Quantization
docker run --gpus all \
-p 8000:8000 \
vllm/vllm-openai:latest \
--model TheBloke/Mistral-7B-Instruct-v0.2-GPTQ \
--quantization gptq \
--max-model-len 8192
AWQ (Activation-aware Weight Quantization) และ GPTQ เป็น INT4 Quantization ที่ลด VRAM ลง ~75% โดยคุณภาพลดลงเล็กน้อย (1-3% บน Benchmark) เหมาะกับ GPU ที่มี VRAM จำกัด
Tensor Parallelism — กระจายไปหลาย GPU
# ใช้ 2 GPU สำหรับ Model 70B
docker run --gpus all \
-p 8000:8000 \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 2 \
--max-model-len 4096
# ใช้ 4 GPU สำหรับ Model ขนาดใหญ่
docker run --gpus all \
-p 8000:8000 \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 4 \
--max-model-len 8192
Performance Tuning
- gpu-memory-utilization — ตั้ง 0.85-0.95 ใช้ VRAM ให้เต็มที่แต่เหลือไว้สำหรับ CUDA Overhead
- max-num-batched-tokens — เพิ่มให้ Batch ใหญ่ขึ้น = Throughput สูงขึ้นแต่ Latency อาจเพิ่ม
- max-num-seqs — จำนวน Concurrent Request สูงสุดตั้งตาม VRAM ที่เหลือ
- enable-prefix-caching — Cache System Prompt ที่ซ้ำกันทุก Request ลด Computation
- dtype bfloat16 — ใช้ BF16 แทน FP16 สำหรับ GPU ที่รองรับ (A100, H100) ลด Overflow
- max-model-len — ตั้งให้พอดีกับ Use Case ไม่ต้องตั้งสูงสุดเสมอลด VRAM Usage
Monitoring และ Metrics
# vLLM มี Prometheus Metrics ในตัว
curl http://localhost:8000/metrics
# Metrics สำคัญ:
# vllm:num_requests_running — จำนวน Request ที่กำลัง Process
# vllm:num_requests_waiting — จำนวน Request ที่รอใน Queue
# vllm:gpu_cache_usage_perc — % ของ KV Cache ที่ใช้
# vllm:avg_generation_throughput_toks_per_s — Token/s เฉลี่ย
# vllm:e2e_request_latency_seconds — Latency ต่อ Request
# ตั้ง Alert:
# - num_requests_waiting > 50 → เพิ่ม GPU/Instance
# - gpu_cache_usage_perc > 95% → ลด max-num-seqs หรือ max-model-len
# - e2e_request_latency > 10s → ตรวจ Bottleneck
Deploy บน Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-llama
spec:
replicas: 1
selector:
matchLabels:
app: vllm-llama
template:
metadata:
labels:
app: vllm-llama
spec:
containers:
- name: vllm
image: vllm/vllm-openai:latest
args:
- "--model"
- "meta-llama/Llama-3.1-8B-Instruct"
- "--max-model-len"
- "8192"
- "--gpu-memory-utilization"
- "0.9"
ports:
- containerPort: 8000
resources:
limits:
nvidia.com/gpu: 1
requests:
cpu: "4"
memory: "32Gi"
volumeMounts:
- name: model-cache
mountPath: /root/.cache/huggingface
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 120
periodSeconds: 30
volumes:
- name: model-cache
persistentVolumeClaim:
claimName: model-cache-pvc
Best Practices และสรุป
- เลือก Model ตาม Use Case — ไม่ต้องใช้ 70B ถ้า 8B เพียงพอลด Cost
- ใช้ Quantization — AWQ/GPTQ ลด VRAM 75% คุณภาพลดเล็กน้อย
- เปิด Prefix Caching — ถ้า System Prompt ซ้ำกันทุก Request
- Monitor GPU Utilization — ใช้ nvidia-smi และ vLLM Metrics
- ตั้ง max-model-len ให้พอดี — ลด VRAM Waste
- ใช้ Persistent Volume สำหรับ Model Cache — ไม่ต้อง Download ซ้ำ
- Health Check + Auto Restart — vLLM อาจ OOM ต้อง Restart อัตโนมัติ
- Load Balancer สำหรับ Multi-GPU — กระจาย Request ไปหลาย vLLM Instance
vLLM เป็น LLM Inference Engine ที่ดีที่สุดสำหรับ Production ในปี 2026 ด้วย PagedAttention, Continuous Batching และ OpenAI-compatible API ทำให้ Self-host LLM ได้ง่ายและ Performant ติดตามบทความใหม่ๆได้ที่ SiamCafe.net
Q: vLLM คืออะไร
High-throughput LLM Inference Engine จาก UC Berkeley ใช้ PagedAttention เร็วกว่า HuggingFace 2-24 เท่ารองรับ OpenAI-compatible API