แล็ปท็อปของคุณสามารถรันโมเดลขนาด 70B พารามิเตอร์ได้ผ่าน endpoint รูปแบบเดียวกับ OpenAI ที่คุณใช้ใน production เพียงเปลี่ยน base_url โค้ดเดิมก็ยังทำงานต่อได้ เหมาะสำหรับการพัฒนาแบบออฟไลน์ ลดค่าใช้จ่ายต่อโทเค็น และเก็บข้อมูลที่ถูกควบคุมไว้ในเครื่อง บทความนี้จะแสดงวิธีเลือกรันไทม์ เปิด endpoint ชี้ไคลเอ็นต์ไปยัง local LLM และทดสอบด้วย Apidog ก่อนสลับกลับไปใช้โมเดลที่โฮสต์ไว้
สรุปย่อ (TL;DR)
คุณสามารถรัน Local LLM API บนแล็ปท็อปด้วย Ollama, vLLM หรือ llama.cpp ได้ ทั้งหมดสามารถเปิด REST endpoint ที่เข้ากันได้กับ OpenAI ได้ในรูปแบบใกล้เคียงกัน ถ้าใช้ Ollama ให้เปลี่ยน base_url เป็น:
http://localhost:11434/v1
จากนั้น OpenAI SDK เดิมจะเรียก Llama 3.3, DeepSeek V4 หรือ Qwen 3.6 ได้โดยไม่ต้องเปลี่ยนโครงสร้าง request หลัก ใช้ Apidog จัดการ environment เพื่อให้ scenario test ชุดเดียวกันรันได้ทั้ง local และ hosted endpoint
บทนำ
Local LLM API ไม่ใช่แค่ของเล่นสำหรับงานวิจัยอีกต่อไป ภายในช่วงไม่กี่ปีที่ผ่านมา ฮาร์ดแวร์สำหรับนักพัฒนาแรงขึ้นมาก เช่น Apple M3 Max ที่มี unified memory 128 GB ขณะที่รันไทม์อย่าง Ollama และ vLLM ก็กลายเป็นเครื่องมือที่ใช้งานจริงในทีมพัฒนา
จุดเปลี่ยนสำคัญคือรันไทม์หลักเริ่มรองรับ endpoint รูปแบบ OpenAI เช่น:
/v1/chat/completions
นั่นหมายความว่าแอปของคุณไม่จำเป็นต้องมี client logic แยกสองชุดอีกต่อไป SDK เดียวกันสามารถส่ง request ไปที่ localhost หรือ api.openai.com ได้จาก environment variable เพียงตัวเดียว
สำหรับนักพัฒนา API สิ่งนี้สำคัญมาก เพราะ workflow เดิมยังใช้ได้:
- request template ใน Apidog ยังเป็นรูปแบบ OpenAI
- เปลี่ยนเฉพาะ base URL
- กด Send แล้วได้ JSON shape เดิม
- ไม่ต้องสร้าง schema ใหม่
- ไม่ต้องเปลี่ยน authentication flow สำหรับการทดสอบพื้นฐาน
ถ้าคุณติดตาม ค่าใช้จ่าย API ต่อฟีเจอร์ อยู่แล้ว คุณสามารถใช้ local model ทำ A/B test กับ hosted model แล้วเปรียบเทียบต้นทุน ความหน่วง และคุณภาพผลลัพธ์ได้โดยตรง
บทความนี้ครอบคลุม:
- การเลือกรันไทม์
- การตั้งค่า local server
- การเรียกผ่าน OpenAI SDK
- การทดสอบด้วย Apidog
- ข้อควรระวังเรื่อง quantization
- ตารางเปรียบเทียบต้นทุนและ latency
ตัวอย่างโค้ดอ้างอิงจาก Ollama 0.6 และ vLLM 0.7 บน macOS 15.4 และ Ubuntu 24.04 หากต้องการเปรียบเทียบโมเดลเพิ่มเติม ดู Best local LLMs 2026
ทำไม LLM ภายในเครื่องจึงมีประโยชน์สำหรับนักพัฒนา API
Local LLM API ช่วยให้คุณดีบักและทดสอบฟีเจอร์ที่พึ่งพา LLM ได้แม้ไม่มีอินเทอร์เน็ต เช่น:
- ทำงานบนเครื่องบิน
- อยู่ในงานประชุมที่ Wi-Fi ไม่เสถียร
- อยู่ในเครือข่ายลูกค้าที่บล็อก
*.openai.com - ต้องทดสอบ prompt ที่มีข้อมูลอ่อนไหว
1. ความเป็นส่วนตัวของข้อมูล
Prompt อาจถือเป็นข้อมูลผู้ใช้ทันทีเมื่อมีข้อมูลอย่าง:
- เวชระเบียน
- สัญญา
- หมายเลขบัญชี
- biometric identifier
- log ที่ระบุตัวบุคคลได้
ถ้าส่งข้อมูลเหล่านี้ไปยัง hosted endpoint คุณต้องจัดการเรื่อง data processor, audit, compliance และเอกสารกำกับดูแลเพิ่มขึ้น การรัน inference บนเครื่องหรือในเครือข่ายปิดช่วยลดภาระเหล่านี้ โดยเฉพาะกรณี HIPAA, GDPR และ EU AI Act
2. ต้นทุนต่อโทเค็น
ถ้าทีมของคุณส่ง prompt 50 ล้านโทเค็นต่อวันผ่านโมเดลที่คิด $5 ต่อ 1 ล้านโทเค็น ต้นทุนจะอยู่ที่ประมาณ $250 ต่อวัน
ถ้าปริมาณงานนี้ย้ายมารันบนเครื่อง M3 Max Studio ราคา $4,500 จุดคุ้มทุนจะอยู่ราว 18 วันของการใช้งานเต็มกำลัง โดยยังไม่รวมค่าไฟฟ้า คุณสามารถนำหลักคิดเดียวกันจาก วิธีใช้ GPT-5.5 Instant ไปคำนวณกับ workload ของคุณเอง
3. ความแน่นอนของโมเดล
Hosted model อาจเปลี่ยนน้ำหนักหรือ snapshot โดยที่คุณควบคุมไม่ได้ แต่ local model เป็นไฟล์บนดิสก์ ถ้าไม่เปลี่ยนไฟล์ ผลลัพธ์จะเสถียรกว่าในเชิง regression test
นี่สำคัญมากเมื่อ test suite ของคุณตรวจ output จาก LLM เพราะ endpoint ที่เข้ากันได้กับ OpenAI ทำให้คุณได้ความเสถียรนี้โดยไม่ต้องเขียน client ใหม่
สามรันไทม์ที่มาพร้อม endpoint ที่เข้ากันได้กับ OpenAI
ให้เลือกรันไทม์ตาม workload ไม่ใช่ตามความนิยม
| Runtime | เหมาะกับ | Endpoint หลัก |
|---|---|---|
| Ollama | dev machine, demo, CI runner | http://localhost:11434/v1 |
| vLLM | shared dev cluster, production-like serving | http://localhost:8000/v1 |
| llama.cpp | memory-constrained hardware, custom quantization | configurable เช่น http://localhost:8080/v1
|
Ollama
Ollama เป็นทางเริ่มต้นที่ง่ายที่สุด มี binary เดียว CLI เดียว และ HTTP server บนพอร์ต 11434 โดยจัดการเรื่อง model download, GGUF quantization และ prompt template ให้
ติดตั้งและรันบน macOS:
brew install ollama
ollama serve &
ollama pull llama3.3:70b-instruct-q4_K_M
ollama run llama3.3:70b-instruct-q4_K_M
เมื่อ ollama serve ทำงานแล้ว OpenAI-compatible base URL คือ:
http://localhost:11434/v1
Ollama รองรับ:
- chat completions
- embeddings
- streaming
บน M3 Max โมเดล 70B แบบ Q4_K_M ให้ throughput ประมาณ 12 tokens/s ส่วนโมเดลเล็กกว่าจะอยู่ประมาณ 80–120 tokens/s เหมาะกับ single-user development, demo และ CI smoke test
vLLM
vLLM เหมาะกับงานระดับ production หรือ shared dev cluster เพราะใช้ PagedAttention และ continuous batching เพื่อเพิ่ม throughput ได้สูงกว่ารันเนอร์ทั่วไปหลายเท่า ค่าเริ่มต้นเปิด server ที่พอร์ต 8000 และ expose OpenAI-compatible API ที่ /v1
ติดตั้งและรัน:
pip install vllm
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--port 8000 \
--gpu-memory-utilization 0.9 \
--max-model-len 8192
บน H100 ตัวเดียว vLLM สามารถให้บริการ Llama 3.3 70B ได้ประมาณ 2,400 tokens/s สำหรับ concurrent requests แต่ต้องใช้ CUDA GPU หรือ AMD ROCm รุ่นใหม่ จึงไม่เหมาะกับ Apple Silicon laptop
llama.cpp
llama.cpp เป็น C++ runtime ที่เป็นรากฐานของระบบ GGUF ทำงานได้ตั้งแต่ Raspberry Pi 5 ไปจนถึงเครื่องที่มี GPU หลายตัว binary llama-server รองรับ OpenAI-style endpoint ที่ /v1/chat/completions
ติดตั้งและรัน:
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp && make -j LLAMA_METAL=1
./llama-server -m models/llama-3.3-70b-q4_k_m.gguf \
--port 8080 \
--host 0.0.0.0 \
-c 8192 \
-ngl 99
แฟล็ก -ngl 99 ใช้ offload layer ไปยัง GPU ให้มากที่สุด llama.cpp เหมาะเมื่อคุณต้องควบคุม quantization, batching และ memory mapping อย่างละเอียด หรือเมื่อคุณต้องบีบโมเดลให้พอดีกับ VRAM จำกัด
LM Studio และ Jan ก็ห่อ llama.cpp ไว้ใน GUI และ expose OpenAI endpoint บนพอร์ตที่กำหนดได้ เหมาะกับคนในทีมที่ไม่อยากใช้ terminal แต่ต้องการทดสอบ prompt
ตรวจสอบว่า endpoint ทำงาน
ใช้ OpenAI Python SDK ทดสอบ endpoint ของ Ollama:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama",
)
resp = client.chat.completions.create(
model="llama3.3:70b-instruct-q4_K_M",
messages=[
{"role": "user", "content": "Reply with the word OK only."}
],
)
print(resp.choices[0].message.content)
ถ้าได้ผลลัพธ์เป็น:
OK
แปลว่า runtime, port และ OpenAI SDK contract ทำงานตรงกันแล้ว
ทดสอบ LLM ภายในเครื่องด้วย Apidog
Local LLM API จะมีประโยชน์จริงเมื่อ test suite ของคุณรันได้เหมือน production Apidog ช่วยให้คุณใช้ request template เดิม แต่เปลี่ยน environment variable เพื่อสลับระหว่าง local และ hosted endpoint
ทำตามขั้นตอนนี้:
- เปิดโปรเจกต์ Apidog แล้วสร้าง environment ชื่อ
Local - เพิ่มตัวแปร:
-
BASE_URL=http://localhost:11434/v1 -
API_KEY=ollama
-
- สร้างหรือ clone environment ชื่อ
Production - ตั้งค่า:
-
BASE_URL=https://api.openai.com/v1 -
API_KEY= API key ของ hosted provider
-
- ใน request ที่เรียก chat endpoint ให้เปลี่ยน URL เป็น:
{{BASE_URL}}/chat/completions
ตั้งค่า header:
Authorization: Bearer {{API_KEY}}
Content-Type: application/json
ตัวอย่าง body:
{
"model": "llama3.3:70b-instruct-q4_K_M",
"messages": [
{
"role": "user",
"content": "Return JSON with status=ok."
}
],
"response_format": {
"type": "json_object"
}
}
เพิ่ม assertions ใน scenario test เช่น:
choices[0].message.role == "assistant"
choices[0].message.content is not empty
usage.total_tokens > 0
จากนั้นรัน scenario กับ Local แล้วสลับเป็น Production และรันซ้ำ ถ้า assertions ผ่านทั้งคู่ แปลว่า contract ระหว่างแอปกับ LLM endpoint ยังเสถียร
รูปแบบนี้ใช้เป็น smoke test หลังอัปเกรดโมเดลได้ด้วย เช่น หลัง ollama pull tag ใหม่ ให้รัน scenario ซ้ำ ถ้า response shape เปลี่ยน คุณจะรู้ก่อนที่ application code จะใช้น้ำหนักใหม่จริง รูปแบบเดียวกันนี้ใช้กับ การทดสอบ AI agents ที่เรียก multi-step APIs ได้เช่นกัน
สลับ local และ hosted endpoint ในโค้ด
Python
import os
from openai import OpenAI
def get_client():
if os.getenv("ENV") == "local":
return OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama",
)
return OpenAI(
api_key=os.environ["OPENAI_API_KEY"],
)
client = get_client()
response = client.chat.completions.create(
model=os.getenv("MODEL", "llama3.3:70b-instruct-q4_K_M"),
messages=[
{"role": "system", "content": "You are a JSON-only assistant."},
{"role": "user", "content": "Return {\"status\": \"ok\"}."},
],
response_format={"type": "json_object"},
)
print(response.choices[0].message.content)
รัน local:
ENV=local python app.py
รัน hosted:
OPENAI_API_KEY=sk-... python app.py
JavaScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL:
process.env.ENV === "local"
? "http://localhost:11434/v1"
: "https://api.openai.com/v1",
apiKey:
process.env.ENV === "local"
? "ollama"
: process.env.OPENAI_API_KEY,
});
const resp = await client.chat.completions.create({
model: process.env.MODEL || "llama3.3:70b-instruct-q4_K_M",
messages: [
{
role: "user",
content: "Say hi.",
},
],
});
console.log(resp.choices[0].message.content);
หลักสำคัญคืออย่าฮาร์ดโค้ด endpoint ใน business logic ให้เก็บไว้ใน environment variable เสมอ
คุณยังสามารถเชื่อม scenario runner ของ Apidog เข้ากับ CI ได้ โดย export โปรเจกต์เป็นคอลเลกชัน apidog-cli แล้วเรียก apidog run ใน GitHub Actions ถ้า assertion fail ตัว runner จะคืน exit code ที่ไม่ใช่ศูนย์ ทำให้ build fail ทันที วิศวกร QA สามารถนำ flow นี้ไปใช้กับ ไปป์ไลน์การทดสอบ API ที่มีอยู่ได้
เทคนิคขั้นสูงและเคล็ดลับ
Quantization
Quantization เป็นตัวกำหนดว่าโมเดล 70B จะพอดีกับเครื่องคุณหรือไม่ GGUF รองรับน้ำหนักที่ 8, 6, 5, 4, 3 หรือ 2 บิตต่อพารามิเตอร์
แนวทางเลือกใช้งาน:
| Quantization | เหมาะกับ | หมายเหตุ |
|---|---|---|
| Q8 | code generation, งานที่ต้องการคุณภาพสูง | ใกล้ FP16 แต่ใช้ RAM/ดิสก์มาก |
| Q5_K_M | balance ระหว่างคุณภาพและขนาด | เหมาะเมื่อมี RAM เหลือ |
| Q4_K_M | chat, dev loop ทั่วไป | ค่าเริ่มต้นที่ดีสำหรับ 70B |
| Q2_K | เครื่องที่ memory จำกัดมาก | คุณภาพ reasoning ลดลงชัดเจน |
Q4_K_M ลดขนาดโมเดล 70B จากประมาณ 140 GB เหลือราว 40 GB โดยคุณภาพลดลงเล็กน้อยใน benchmark หลัก เหมาะเป็นค่าเริ่มต้นสำหรับงาน chat และ prototyping
GPU offload
ใน llama.cpp ใช้ -ngl เพื่อกำหนดจำนวน layer ที่ offload ไป GPU:
./llama-server -m model.gguf -ngl 99
ใน Ollama สามารถควบคุมผ่าน option ที่เกี่ยวกับ GPU ได้ หลักคือให้ offload ให้มากที่สุดเท่าที่ VRAM รองรับ เพราะ layer ที่ตกกลับไปทำงานบน CPU จะลด throughput อย่างมาก
Memory mapping
mmap เปิดเป็นค่าเริ่มต้นใน llama.cpp และ Ollama ช่วยให้ OS โหลด weight ตามต้องการ แทนที่จะโหลดทั้งโมเดลทันทีตอนเริ่มต้น
ควรเปิดไว้ ยกเว้นคุณรันใน container ที่มี memory limit เข้มงวดมาก ถ้าปิด mmap อาจลด first-token latency ได้เล็กน้อย แต่ RAM usage จะสูงขึ้นมาก
Batching
Batching คือจุดแข็งของ vLLM ถ้าส่ง concurrent requests จำนวนมาก vLLM จะรวม request เป็น GPU batch เดียวเพื่อเพิ่ม throughput
ตัวอย่างการตั้งค่า:
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--max-num-seqs 64
ใช้ --max-num-seqs 64 สำหรับเครื่องที่ memory จำกัด และเพิ่มเป็น 256 สำหรับฮาร์ดแวร์ระดับ H100
Streaming
Streaming ช่วยลด perceived latency เพราะ client ได้ token แรกก่อน response ทั้งหมดเสร็จ
Python:
stream = client.chat.completions.create(
model="llama3.3:70b-instruct-q4_K_M",
messages=[{"role": "user", "content": "Explain local LLMs briefly."}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="")
ทุก runtime ในบทความนี้รองรับ streaming
Ollama Modelfile
ถ้าคุณไม่อยากส่ง system prompt ซ้ำทุก request ให้สร้าง model name เฉพาะด้วย Modelfile:
FROM llama3.3:70b-instruct-q4_K_M
SYSTEM """
You are a JSON-only assistant.
"""
PARAMETER temperature 0.2
สร้างโมเดล:
ollama create my-assistant -f Modelfile
จากนั้นเรียก:
response = client.chat.completions.create(
model="my-assistant",
messages=[
{"role": "user", "content": "Return {\"status\":\"ok\"}."}
],
)
ข้อผิดพลาดที่พบบ่อย
หลีกเลี่ยงปัญหาเหล่านี้ตั้งแต่แรก:
- ฮาร์ดโค้ด
http://localhost:11434ใน production code - ลืมตั้ง
max_tokensหรือ stop sequence - รัน Ollama และ runtime อื่นบนพอร์ตเดียวกัน
- ไม่ส่ง
Authorizationheader เพราะ Ollama อาจไม่สนใจ แต่ vLLM ที่เปิด--api-keyจะตอบ401 - คาดหวังว่า Q4 จะให้คุณภาพเทียบเท่า hosted frontier model ในงาน reasoning หรือคณิตศาสตร์
- ใช้ model name คนละชื่อระหว่าง local และ production โดยไม่แยก mapping ให้ชัดเจน
- ไม่ทดสอบ response schema หลังอัปเดตโมเดล
ภายในเครื่องเทียบกับโฮสต์: ค่าใช้จ่ายและความหน่วง
ตัวเลขด้านล่างสมมติว่าใช้ M3 Max ที่มี unified memory 128 GB สำหรับ local และใช้ราคาสาธารณะของ hosted endpoint เวลา TTFT วัดจาก cold start, ไม่มี batching และ prompt ขนาด 1,024 tokens
| โมเดล | Local TTFT | Local throughput | Hosted equivalent | Hosted price | Hosted TTFT |
|---|---|---|---|---|---|
| Llama 3.3 70B Q4_K_M | 1.2 s | 12 tok/s | GPT-5.5 Instant | $5 / $30 per 1M | 200 ms |
| DeepSeek V4 67B Q4_K_M | 1.4 s | 10 tok/s | DeepSeek-Chat hosted | $0.55 / $2.20 per 1M | 280 ms |
| Qwen 3.6 32B Q5_K_M | 0.7 s | 28 tok/s | Qwen-Max hosted | $1.60 / $6.40 per 1M | 240 ms |
| Gemma 4 27B Q4_K_M | 0.5 s | 35 tok/s | Gemini 3 Flash | $0.35 / $1.05 per 1M | 180 ms |
Hosted model มักชนะเรื่อง latency ส่วน local model ชนะเรื่องต้นทุนเมื่อมีปริมาณใช้งานสูง และชนะเรื่อง privacy ตั้งแต่ request แรก
รูปแบบที่ใช้งานได้จริง:
- ใช้ local model ใน inner dev loop
- ใช้ hosted model ใน staging
- ให้ CI รัน scenario test กับทั้งสอง environment
- ตรวจ contract ด้วย Apidog ก่อน deploy
สำหรับ benchmark รายโมเดล ดู วิธีรัน DeepSeek V4 ภายในเครื่อง และ คู่มือการใช้งาน DeepSeek V4
กรณีการใช้งานจริง
Fintech compliance
ทีม compliance ด้าน fintech ในสิงคโปร์ใช้ Ollama บนแล็ปท็อปของวิศวกรเพื่อร่างรายงาน suspicious activity prompt มีหมายเลขบัญชีและ pattern ธุรกรรมที่ไม่สามารถออกนอกประเทศตามกฎ MAS ได้
ใน production พวกเขาใช้ hosted endpoint กับ prompt เวอร์ชันที่ redact แล้ว และใช้ Apidog scenarios ตรวจว่า data redaction ทำงานกับทุก request ก่อนออกจาก localhost
Game studio
สตูดิโอเกมในสตอกโฮล์มใช้ Qwen 3.6 ภายในเครื่องเพื่อฝึก prompt engineering ให้ designer รุ่นใหม่ ข้อดีคือฟรี ใช้งานออฟไลน์ และลดความเสี่ยงที่เนื้อเรื่องเกมใหม่จะรั่วไปยัง third party
โปรเจกต์เดียวกัน deploy ไป production ด้วย Gemini 3 Flash โดยเปลี่ยน environment variable เท่านั้น และ reuse คู่มือ Gemini 3 Flash API สำหรับ integration
Healthcare startup
สตาร์ทอัพด้าน healthcare รัน vLLM บน A100 ที่เช่าไว้ภายในเครือข่ายโรงพยาบาลของลูกค้า endpoint ไม่ออก public DNS และ integration test รันจาก Jenkins agent ใน VLAN เดียวกัน
ผลลัพธ์คือ:
- SDK เดียวกัน
- request contract เดียวกัน
- deployment target หลายแบบ
- scenario test ชุดเดียว
บทสรุป
Local LLM API ทำให้คุณย้าย prompt ออกจาก hosted endpoint ได้โดยไม่ต้องเขียน client, test หรือ CI ใหม่ ขั้นตอนหลักคือ:
- เลือก Ollama สำหรับ laptop, vLLM สำหรับ shared cluster และ llama.cpp เมื่อ memory จำกัด
- เปิด OpenAI-compatible endpoint แล้วตรวจด้วย SDK หรือ
curl - ย้าย
base_urlและapi_keyไปไว้ใน environment variable - สร้าง scenario test ใน Apidog ให้รันได้ทั้ง local และ hosted
- เปรียบเทียบ latency, privacy และต้นทุนต่อ workload
สัญญาณจาก Hacker News ที่ดันแนวคิด “Local AI needs to be the norm” เกิน 1,700 คะแนนสะท้อนว่า ecosystem พร้อมแล้ว เมื่อ API surface เสถียร เครื่องมือของนักพัฒนาก็รองรับได้ทันที
เริ่มจากชี้ environment หนึ่งใน Apidog ไปที่:
http://localhost:11434/v1
แล้วรัน scenario test เดิมของคุณ ถ้ายังไม่ได้เลือกรุ่นโมเดล ให้เริ่มจาก Best local LLMs 2026 และถ้าต้องการทดสอบ agent flow หลายขั้นตอน อ่านต่อที่ How to test AI agents API




Top comments (0)