ทีมที่อยากเก็บข้อมูลไว้ในเครื่องของตัวเอง หรือมี GPU ว่างอยู่แล้ว มักเริ่มจาก Ollama บนโน้ตบุ๊ก แล้วติดปัญหาตอนให้คนทั้งทีมเรียกพร้อมกัน คำตอบเริ่มช้าและคิวยาวขึ้นเรื่อยๆ ช่องว่างตรงนี้คืองานของ inference server อย่าง vLLM
Inference server ทำหน้าที่อะไร
Inference server คือโปรแกรมที่โหลดน้ำหนักโมเดลขึ้น GPU ค้างไว้ แล้วรับคำขอจากผู้ใช้หลายคนผ่าน HTTP API จัดคิว จัดสรรหน่วยความจำ และส่งคำตอบกลับทีละ token แบบ streaming ต่างจากสคริปต์ที่โหลดโมเดลมาตอบทีละคำถาม ซึ่งใช้ได้กับคนเดียวแต่ GPU ว่างเสียส่วนใหญ่
| ส่วนประกอบ | หน้าที่ | ถ้าไม่มี |
|---|---|---|
| API layer | เปิด endpoint แบบ OpenAI เช่น /v1/chat/completions | ต้องเขียน client เอง |
| Scheduler | รวมคำขอหลายตัวให้ GPU คำนวณพร้อมกัน | ตอบได้ทีละคน คนที่มาทีหลังต้องรอ |
| ตัวจัดการ KV cache | แบ่งหน่วยความจำให้ context ของแต่ละคำขอ | VRAM เต็มเร็ว รับผู้ใช้ได้น้อย |
| Metrics | บอกจำนวนคำขอที่รอ เวลาตอบ และการใช้ cache | ไม่รู้ว่าระบบช้าเพราะอะไร |
เพราะ API layer พูดภาษาเดียวกับ OpenAI โปรแกรมที่เขียนไว้แล้วจึงย้ายมาใช้เซิร์ฟเวอร์ของตัวเองได้ด้วยการเปลี่ยน base URL อย่างเดียว (อ่านหลักการได้ที่ OpenAI-compatible API คืออะไร)
vLLM คืออะไร ทำไมรับผู้ใช้พร้อมกันได้เยอะ
vLLM คือ inference server แบบ open source ที่เริ่มพัฒนาใน Sky Computing Lab ของ UC Berkeley รองรับ GPU ของ NVIDIA และ AMD รวมถึงฮาร์ดแวร์อื่นผ่านปลั๊กอิน จุดเด่นที่ทำให้รับผู้ใช้พร้อมกันได้มากคือสองเทคนิค ได้แก่ PagedAttention และ continuous batching ณ พฤศจิกายน 2569 เวอร์ชันล่าสุดบน PyPI คือ 0.33.0 ออกเมื่อ 2 พฤศจิกายน 2569
PagedAttention จัด KV cache เหมือนหน้าหน่วยความจำ
ระบบรุ่นก่อนจอง KV cache เป็นก้อนต่อเนื่องเท่ากับความยาวสูงสุดที่คำขอนั้นอาจใช้ ทั้งที่คำตอบส่วนใหญ่สั้นกว่านั้นมาก ทีม vLLM รายงานว่าระบบเดิมเสียหน่วยความจำไป 60–80% จากการจองเกินและช่องว่างที่ใช้ไม่ได้
PagedAttention ใช้แนวคิดเดียวกับ virtual memory ของระบบปฏิบัติการ คือแบ่ง KV cache เป็นบล็อกขนาดเท่ากัน วางตรงไหนของ VRAM ก็ได้ แล้วมีตารางบอกว่าบล็อกไหนเป็นของคำขอใด ใช้เพิ่มเท่าไรก็ขอบล็อกเพิ่มเท่านั้น ทีม vLLM รายงานว่าส่วนที่เสียเปล่าเหลือไม่ถึง 4% จึงรับคำขอพร้อมกันได้มากขึ้น และคำขอที่ขึ้นต้นด้วยข้อความเดียวกัน เช่น system prompt ยาวๆ ยังใช้บล็อกร่วมกันได้ (prefix caching)
Continuous batching ไม่ต้องรอให้ทั้งชุดเสร็จ
batching แบบเดิมรวมคำขอเป็นชุด แล้วรอให้คำขอที่ยาวที่สุดในชุดเสร็จก่อนจึงรับชุดใหม่ คำขอสั้นที่เสร็จแล้วต้องนั่งรอ และ GPU ทำงานไม่เต็มที่
continuous batching จัดคิวใหม่ทุกรอบการคำนวณ คำขอที่เขียนเสร็จออกไปทันที คำขอใหม่เข้ามาแทนในรอบถัดไป เหมือนรถรางที่ผู้โดยสารขึ้นลงได้ทุกป้ายโดยรถไม่ต้องกลับเข้าอู่ ผลคือ GPU มีงานเต็มเกือบตลอด และคนที่ถามสั้นๆ ไม่ต้องรอคนที่สั่งเขียนยาว
อธิบายด้วยภาพ
รอทั้งชุด กับ continuous batching
- Static batchingรอให้ทั้งชุดเสร็จก่อนคำขอสั้นต้องรอคำขอยาว GPU ว่างเป็นช่วงๆ
- Continuous batchingคำขอเข้าออกได้ทุกรอบคำขอที่เสร็จออกทันที คำขอใหม่เข้าแทนในรอบถัดไป
vLLM ใช้ continuous batching คู่กับ PagedAttention เพื่อรับผู้ใช้พร้อมกันได้มากขึ้น
ติดตั้ง vLLM และเปิด API ด้วย vllm serve
vLLM ติดตั้งได้ด้วย uv หรือ pip บน Linux ที่มี GPU แล้วเปิด API ด้วยคำสั่ง vllm serve ตามด้วยชื่อโมเดลบน Hugging Face ค่าเริ่มต้นจะฟังที่ http://localhost:8000 ขั้นตอนข้างล่างอ้างอิงเอกสาร quickstart ของ vLLM ณ พฤศจิกายน 2569 ซึ่งระบุ Python 3.11–3.14
# 1) ติดตั้ง (NVIDIA GPU)
uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm --torch-backend=auto
vllm download-kernels # ไม่บังคับ: โหลด kernel ที่คอมไพล์ไว้แล้ว เริ่มเซิร์ฟเวอร์ได้เร็วขึ้น
# 2) ตั้ง key แล้วเปิด API
export VLLM_API_KEY="$(openssl rand -hex 32)"
vllm serve Qwen/Qwen3-8B \
--served-model-name qwen3-8b \
--max-model-len 32768 \
--gpu-memory-utilization 0.90 \
--api-key "$VLLM_API_KEY" \
--reasoning-parser qwen3ตัวอย่างนี้เหมาะกับการ์ด 48 GB เช่น L40S เพราะ Qwen3-8B แบบ BF16 มีน้ำหนักราว 16 GB ถ้าใช้การ์ด 24 GB ให้ลด --max-model-len เหลือ 16384 หรือเปลี่ยนเป็น Qwen/Qwen3-8B-FP8 ถ้า KV cache ไม่พอสำหรับ context ยาวสุดหนึ่งคำขอ vLLM จะเริ่มไม่ขึ้นและแจ้งให้ปรับค่า (วิธีคิด VRAM ทีละก้อนอยู่ใน GPU สำหรับรัน LLM ต้องใช้ VRAM เท่าไร)
| flag | ทำอะไร |
|---|---|
--max-model-len | context สูงสุดต่อคำขอ รวม prompt และคำตอบ ถ้าไม่ตั้งจะใช้ค่าจาก config ของโมเดล |
--gpu-memory-utilization | สัดส่วน VRAM ที่ vLLM ใช้ได้ ส่วนที่เหลือจากน้ำหนักโมเดลกลายเป็น KV cache |
--tensor-parallel-size | แบ่งโมเดลไปหลายการ์ด เช่น 2 หรือ 4 |
--api-key | บังคับให้คำขอแนบ key (อ่านจากตัวแปร VLLM_API_KEY ได้เช่นกัน) |
--kv-cache-dtype fp8 | เก็บ KV cache เป็น 8-bit ให้ได้ context รวมมากขึ้น |
--enable-auto-tool-choice กับ --tool-call-parser | เปิด tool calling ต้องเลือก parser ให้ตรงกับโมเดล |
ถ้ารันผ่าน Docker ใช้ image ทางการ ระบุเวอร์ชันให้ชัด และใส่ --ipc=host เพราะ vLLM ใช้ shared memory ตอนแบ่งโมเดลไปหลายการ์ด
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
--env "HF_TOKEN=$HF_TOKEN" --env "VLLM_API_KEY=$VLLM_API_KEY" \
-p 8000:8000 --ipc=host \
vllm/vllm-openai:v0.33.0 \
--model Qwen/Qwen3-8B --served-model-name qwen3-8bเรียก vLLM จากโค้ดหรือ coding agent อย่างไร
เรียก vLLM ได้เหมือนเรียก OpenAI API ทุกอย่าง แค่เปลี่ยน base URL เป็น http://<เครื่อง>:8000/v1 ใส่ key ที่ตั้งไว้ และใช้ชื่อโมเดลตาม --served-model-name
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $VLLM_API_KEY" \
-d '{"model": "qwen3-8b", "messages": [{"role": "user", "content": "อธิบาย KV cache ใน 2 ประโยค"}]}'import os
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key=os.environ["VLLM_API_KEY"])
resp = client.chat.completions.create(
model="qwen3-8b",
messages=[{"role": "user", "content": "สรุป README นี้ให้เหลือ 5 บรรทัด"}],
)
print(resp.choices[0].message.content)นอกจาก /v1/chat/completions แล้ว vLLM ยังมี /v1/responses ที่ Codex CLI ใช้ และ /v1/messages แบบ Anthropic Messages จึงชี้ coding agent หลายตัวมาที่เซิร์ฟเวอร์ของตัวเองได้ (ดูฝั่ง Claude Code ใน Claude Code กับ API อื่น) แต่ agent ต้องเรียกเครื่องมือ จึงต้องเปิด --enable-auto-tool-choice และเลือก --tool-call-parser ตามตารางในเอกสาร tool calling ของ vLLM เช่น gpt-oss ใช้ openai ส่วน Qwen3-Coder ใช้ qwen3_xml ไม่อย่างนั้นคำสั่งเรียกเครื่องมือจะกลับมาเป็นข้อความธรรมดา
vLLM, SGLang, llama.cpp และ Ollama ต่างกันอย่างไร
ทั้งสี่ตัวเปิด API แบบ OpenAI-compatible ได้เหมือนกัน ความต่างอยู่ที่งานที่ออกแบบมาให้ทำ vLLM และ SGLang เน้นเซิร์ฟเวอร์ GPU ที่รับผู้ใช้พร้อมกันจำนวนมาก ส่วน llama.cpp และ Ollama เน้นเครื่องเดียว ไฟล์ GGUF และการติดตั้งที่ง่าย
| ตัวเลือก | เหมาะกับ | คำสั่งเริ่ม | สถานะ ณ พ.ย. 2569 |
|---|---|---|---|
| vLLM | เซิร์ฟเวอร์ GPU ของทีม หลายผู้ใช้พร้อมกัน | vllm serve <model> (พอร์ต 8000) | ออกเวอร์ชันใหม่ราวทุกสองสัปดาห์ ล่าสุด 0.33.0 |
| SGLang | เซิร์ฟเวอร์ GPU จุดเด่นคือ RadixAttention สำหรับใช้ prefix ซ้ำ | sglang serve <model> --port 30000 | อยู่ภายใต้ LMSYS ล่าสุด 0.5.23 บน PyPI |
| llama.cpp | ไฟล์ GGUF, CPU, Mac และการ์ดเล็ก | llama-server -m model.gguf (ค่าเริ่มต้น 127.0.0.1:9931) | พัฒนาต่อเนื่อง |
| Ollama | ใช้คนเดียวบนเครื่องตัวเอง | ollama serve (พอร์ต 11434) | พัฒนาต่อเนื่อง |
| TGI | ระบบเดิมที่ใช้อยู่แล้ว | — | maintenance mode |
Hugging Face ประกาศให้ TGI เข้าสู่ maintenance mode และแนะนำ vLLM กับ SGLang รวมถึง llama.cpp หรือ MLX สำหรับรันบนเครื่อง ระบบใหม่จึงไม่ควรเริ่มจาก TGI ส่วนการทดลองบนเครื่องตัวเอง ดูรัน LLM บนเครื่องตัวเองด้วย Ollama และ LM Studio
ก่อนเปิดให้ทีมใช้จริงต้องเตรียมอะไรบ้าง
การเปิด vLLM ให้คนอื่นเรียกใช้ต้องมีอย่างน้อยสี่เรื่อง คือการยืนยันตัวตนที่ไม่ปล่อยพอร์ตออกอินเทอร์เน็ตตรงๆ การดู metrics การจำกัดโหลด และการล็อกเวอร์ชัน ซึ่ง vllm serve ไม่ได้ทำให้ครบเอง
- วาง reverse proxy ที่ทำ TLS ไว้ข้างหน้า เช่น nginx หรือ Caddy เพราะ
--api-keyครอบคลุมเฉพาะ path กลุ่ม/v1,/v2,/inferenceและ/cohereส่วน/metricsและ/healthเรียกได้โดยไม่ต้องใช้ key - แยก key ต่อคนหรือต่อทีม ใช้ LLM gateway อย่าง LiteLLM ออก key แยกและดูการใช้ต่อ key แล้วตั้งเพดานการเรียกที่ gateway เพื่อไม่ให้สคริปต์ของคนเดียวกินคิวทั้งเครื่อง
- ดู metrics ตลอด
/metricsส่งค่าแบบ Prometheus ตัวที่ควรตั้ง alert คือvllm:num_requests_waiting(คำขอที่รอ),vllm:kv_cache_usage_perc(KV cache ใกล้เต็ม) และvllm:time_to_first_token_seconds - กำหนดเพดานโหลด ตั้ง
--max-num-seqsและ--max-model-lenให้เหมาะกับการ์ด และตั้ง timeout ฝั่ง client - ทดสอบโหลดก่อนเปิด ใช้
vllm bench serve(ติดตั้งด้วยpip install vllm[bench]) จำลองจำนวนผู้ใช้จริงของทีม - ล็อกเวอร์ชันและตั้ง health check ใช้ tag อย่าง
vllm/vllm-openai:v0.33.0แทนlatestเพราะ flag บางตัวถูกเลิกใช้ระหว่างเวอร์ชัน และให้ระบบเรียก/healthเพื่อรีสตาร์ตเมื่อเซิร์ฟเวอร์ค้าง - ดูเรื่องข้อมูลและไลเซนส์ log ของ prompt อาจมีข้อมูลส่วนบุคคล ถ้าเช่า GPU ในต่างประเทศ ข้อมูลก็ออกนอกประเทศเช่นกัน และอ่านไลเซนส์ของโมเดลก่อนใช้เชิงพาณิชย์
สุดท้ายอย่าลืมเวลาคนที่ต้องดูแลระบบ ถ้าอยากเทียบเป็นเงินว่าคุ้มกว่าจ่ายตาม token หรือไม่ ดูต้นทุน AI Inference
ไม่อยากดูแลเซิร์ฟเวอร์เอง buzzAI ช่วยตรงไหน
buzzAI เป็น API สำหรับ coding agent ที่รันโมเดล open-weight Qwen3.8-27B บนการ์ด GPU ที่ buzzAI ดูแลเอง ตอนนี้งานประมวลผลอยู่บนเซิร์ฟเวอร์ GPU ของผู้ให้บริการคลาวด์ในต่างประเทศ เรียกใช้ที่ base URL https://api.heybuzzai.com/v1 ชื่อโมเดล Qwen3.8-27B รองรับทั้ง Chat Completions, Responses ที่ Codex CLI ใช้ และ Anthropic Messages ที่ Claude Code ใช้ (ตั้ง ANTHROPIC_BASE_URL เป็น https://api.heybuzzai.com โดยไม่มี /v1)
แพ็กเป็นแบบเหมาจ่าย ไม่คิดค่า token และไม่มีโควตารายวันหรือรายสัปดาห์ สิ่งที่จำกัดแทนคือจำนวน agent ที่รันพร้อมกัน ขนาด context ตามแพ็ก และคิวในช่วงที่คนใช้เยอะ ในเวลาทำการ (จันทร์–ศุกร์ 08:00–20:00 น.) แพ็กบริษัทและสล็อตที่จองไว้ได้คิวก่อน แพ็ก Personal จึงอาจต้องรอ buzzAI ไม่เอาข้อมูลหรือโค้ดของคุณไปเทรนโมเดล และแพ็กบริษัททำ DPA ตาม PDPA ได้ API ยังไม่เปิดให้ใช้ทั่วไป กดขอร่วมทดสอบได้ที่หน้าแรก แล้วเราจะส่ง API key ทางอีเมลเมื่อมีผู้สมัครครบโควต้าที่กำหนด ดูแพ็กทั้งหมดที่หน้าราคา
คำถามที่พบบ่อย
vLLM ใช้กับ Windows หรือ Mac ได้ไหม?
เอกสารติดตั้งของ vLLM ระบุระบบปฏิบัติการที่รองรับเป็น Linux ถ้าใช้ Windows ทางที่ตรงที่สุดคือเครื่อง Linux แยกหรือเช่า GPU บนคลาวด์ ส่วน Mac มี vLLM-Metal สำหรับ GPU ของ Apple Silicon แต่ถ้าใช้คนเดียวบนเครื่องตัวเอง Ollama หรือ llama.cpp ตั้งง่ายกว่า
vLLM ใช้ไฟล์ GGUF ได้ไหม?
เอกสารของ vLLM ระบุ GGUF ไว้ในรายการ quantization ที่รองรับ แต่ vLLM ออกแบบมาโหลดโมเดลจาก Hugging Face เป็นหลัก ถ้าไฟล์ที่มีอยู่เป็น GGUF แล้ว llama-server ของ llama.cpp เป็นทางที่ตรงกว่า
vLLM ฟรีไหม มีค่าไลเซนส์หรือเปล่า?
ตัว vLLM เป็น open source ใช้ได้โดยไม่เสียค่าไลเซนส์ ค่าใช้จ่ายจริงคือ GPU ค่าไฟหรือค่าเช่าเครื่อง และเวลาคนดูแลระบบ ส่วนตัวโมเดลแต่ละตัวมีไลเซนส์ของตัวเองที่ต้องอ่านก่อนใช้เชิงพาณิชย์
ทำไมเปิด vLLM แล้ว VRAM เต็มทันทีทั้งที่ยังไม่มีใครใช้?
เพราะ vLLM จองหน่วยความจำ GPU ไว้ล่วงหน้าตาม --gpu-memory-utilization แล้วกันส่วนที่เหลือจากน้ำหนักโมเดลไว้เป็น KV cache ตั้งแต่ตอนเริ่ม เป็นพฤติกรรมปกติ ถ้าต้องแบ่งการ์ดกับโปรแกรมอื่น ให้ลดค่านี้ลง
แหล่งอ้างอิง
ข้อมูล ณ วันที่อัปเดต แพ็ก โควตา และคำสั่งของแต่ละเครื่องมือเปลี่ยนได้บ่อย ก่อนใช้งานจริงควรตรวจกับเอกสารทางการที่ลิงก์ไว้ในแหล่งอ้างอิง