รัน LLM บนเครื่องตัวเองด้วย Ollama

หลายองค์กรอยากใช้ LLM ช่วยสรุปเอกสาร จัดหมวดคำร้อง หรือช่วยตอบคำถามภายใน แต่ติดเงื่อนไขว่าข้อมูลห้ามออกนอกองค์กร หรืออยากทดลองโดยไม่ต้องกังวลเรื่องค่าใช้จ่ายต่อ request ทางเลือกหนึ่งคือรันโมเดลแบบ open-weight บนเครื่องของเราเอง และ Ollama เป็นเครื่องมือที่ทำให้เรื่องนี้ง่ายพอที่นักพัฒนาทั่วไปจะเริ่มได้ภายในไม่กี่นาที บทความนี้จะอธิบายว่าเมื่อไรควรรันเอง ต้องใช้เครื่องแบบไหน ติดตั้งและใช้งานอย่างไร วิธีเรียก API บนเครื่องจาก PHP และข้อจำกัดที่ต้องรู้ก่อนตัดสินใจ
ทำไมต้องรัน LLM เอง
เหตุผลหลักที่ทีมพัฒนาเลือกรันโมเดลบนเครื่องตัวเอง
- ข้อมูลไม่ออกนอกเครื่อง prompt และเอกสารที่ส่งให้โมเดลอยู่ในเครื่องหรือเครือข่ายขององค์กร เหมาะกับข้อมูลภายในหรือข้อมูลที่มีข้อกำหนดเรื่องการส่งออก (เรื่อง PDPA และนโยบายข้อมูลควรตรวจกับผู้รับผิดชอบขององค์กร บทความนี้ไม่ใช่คำแนะนำทางกฎหมาย)
- ใช้งานแบบ offline ได้ ทำงานได้แม้ไม่มีอินเทอร์เน็ต เหมาะกับงานภาคสนามหรือเครือข่ายปิด
- ค่าใช้จ่ายคาดการณ์ได้ ไม่มีค่าใช้ต่อ token แต่มีต้นทุนฮาร์ดแวร์ ไฟฟ้า และเวลาดูแลแทน
- ทดลองได้อิสระ ลองหลายโมเดล ลอง prompt ซ้ำ ๆ หรือรัน eval ชุดใหญ่โดยไม่ต้องห่วง rate limit
ทั้งนี้ "ข้อมูลไม่ออกนอกเครื่อง" จะเป็นจริงก็ต่อเมื่อเราตั้งค่าและดูแลระบบถูกต้องด้วย เช่น ไม่เปิดพอร์ต API ออกสู่อินเทอร์เน็ต และไม่ส่งข้อมูลต่อไปยังบริการอื่นในขั้นถัดไปของแอป
สเปกเครื่องที่ต้องใช้
ปัจจัยที่สำคัญที่สุดคือหน่วยความจำ โมเดลต้องถูกโหลดเข้า RAM หรือ VRAM ของ GPU ทั้งตัว ยิ่งโมเดลมีจำนวนพารามิเตอร์มาก ยิ่งต้องใช้หน่วยความจำมาก หลักคิดคร่าว ๆ:
- หน่วยความจำ ดูขนาดไฟล์ของโมเดลที่จะใช้ในหน้ารายการโมเดลของ Ollama แล้วเผื่อพื้นที่สำหรับ context และระบบปฏิบัติการอีกพอสมควร ถ้าหน่วยความจำไม่พอ โมเดลจะโหลดไม่ได้หรือช้ามาก
- GPU ช่วยให้สร้างคำตอบเร็วขึ้นมาก ถ้าไม่มี GPU ก็รันบน CPU ได้ แต่ช้ากว่า เหมาะกับโมเดลขนาดเล็กหรืองานที่ไม่ต้องตอบทันที เครื่อง Mac ที่ใช้ชิปตระกูล Apple Silicon ใช้หน่วยความจำร่วมกับ GPU ได้ จึงนิยมใช้ทดลอง
- Quantization โมเดลส่วนใหญ่ที่ให้ดาวน์โหลดมีแบบที่ลดความละเอียดของตัวเลขลงเพื่อให้ไฟล์เล็กและใช้หน่วยความจำน้อยลง แลกกับคุณภาพที่อาจลดลงบ้าง
- ดิสก์ แต่ละโมเดลใช้พื้นที่หลาย GB ถ้าทดลองหลายตัวพื้นที่จะหมดเร็ว
วิธีที่ดีที่สุดคือเริ่มจากโมเดลขนาดเล็กในเครื่องที่มีอยู่ วัดความเร็วและคุณภาพกับงานจริงของเรา แล้วค่อยตัดสินใจลงทุนฮาร์ดแวร์
ติดตั้งและใช้งาน Ollama
ดาวน์โหลดจากเว็บไซต์ทางการ ollama.com เท่านั้น สำหรับ macOS และ Windows มีตัวติดตั้งให้ ส่วน Linux มีสคริปต์ติดตั้งที่ระบุไว้ในหน้าดาวน์โหลด ควรเปิดอ่านสคริปต์ก่อนรันเสมอ และระวังเว็บหรือแพ็กเกจที่ตั้งชื่อเลียนแบบ
เมื่อติดตั้งแล้ว คำสั่งพื้นฐานที่ใช้บ่อย (แทน MODEL_NAME ด้วยชื่อโมเดลที่เลือกจากรายการบนเว็บไซต์)
# ดาวน์โหลดโมเดล
ollama pull MODEL_NAME
# คุยกับโมเดลใน terminal (ถ้ายังไม่มีโมเดล จะดาวน์โหลดให้ก่อน)
ollama run MODEL_NAME
# ดูโมเดลที่มีในเครื่อง และโมเดลที่กำลังโหลดอยู่ในหน่วยความจำ
ollama list
ollama ps
# ลบโมเดลที่ไม่ใช้แล้วเพื่อคืนพื้นที่
ollama rm MODEL_NAME
ก่อนเลือกโมเดล ให้อ่านหน้ารายละเอียดของโมเดลนั้น ดูว่ารองรับภาษาไทยดีแค่ไหน รองรับ context ยาวเท่าไร และที่สำคัญคือ ไลเซนส์ของโมเดล แต่ละโมเดลมีเงื่อนไขการใช้งานต่างกัน บางตัวมีข้อจำกัดการใช้เชิงพาณิชย์ ต้องตรวจก่อนนำไปใช้ในงานจริง
Ollama จะรัน server ไว้เบื้องหลังและเปิด HTTP API ที่พอร์ต 11434 บน localhost โดยค่าเริ่มต้นรับเฉพาะการเชื่อมต่อจากเครื่องตัวเอง ถ้าจะเปลี่ยนให้เครื่องอื่นเข้าถึงได้ ให้ศึกษาการตั้งค่าในเอกสารทางการ และวางไว้หลัง reverse proxy ที่มีการยืนยันตัวตนหรือจำกัดเครือข่าย เพราะ API นี้ไม่ได้ออกแบบมาให้เปิดสู่สาธารณะ
เรียก API บนเครื่องจาก PHP
API ของ Ollama รับและตอบเป็น JSON มี endpoint สำหรับสร้างข้อความและสำหรับสนทนาแบบมีหลายข้อความ รายละเอียดฟิลด์ของ request และ response อาจเปลี่ยนตามเวอร์ชัน ให้ตรวจกับเอกสาร API ของ Ollama ที่ติดตั้งอยู่ก่อนใช้งานจริง ตัวอย่างด้านล่างเป็น component ใน Yii2 ที่เรียก endpoint สนทนาแบบไม่ stream
<?php
namespace common\components;
use RuntimeException;
use yii\base\Component;
class OllamaClient extends Component
{
public string $baseUrl = 'http://127.0.0.1:11434';
public string $model = '';
public int $timeout = 120;
/**
* @param array<int, array{role: string, content: string}> $messages
*/
public function chat(array $messages): string
{
if ($this->model === '') {
throw new RuntimeException('ยังไม่ได้ตั้งค่าชื่อโมเดล');
}
$payload = json_encode([
'model' => $this->model,
'messages' => $messages,
'stream' => false,
], JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
$ch = curl_init(rtrim($this->baseUrl, '/') . '/api/chat');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => $this->timeout,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$error = curl_error($ch);
if ($body === false) {
throw new RuntimeException('เรียก Ollama ไม่สำเร็จ: ' . $error);
}
if ($status !== 200) {
throw new RuntimeException('Ollama ตอบกลับสถานะ ' . $status);
}
$data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
$content = $data['message']['content'] ?? null;
if (!is_string($content)) {
throw new RuntimeException('รูปแบบคำตอบไม่ตรงกับที่คาดไว้');
}
return $content;
}
}
ตั้งค่าใน config และใช้งาน โดยอ่านชื่อโมเดลจาก environment เพื่อเปลี่ยนได้โดยไม่ต้องแก้โค้ด
// config/main.php
'components' => [
'ollama' => [
'class' => common\components\OllamaClient::class,
'model' => getenv('OLLAMA_MODEL') ?: '',
],
],
// ในส่วนที่เรียกใช้
$summary = Yii::$app->ollama->chat([
['role' => 'system', 'content' => 'สรุปคำร้องต่อไปนี้เป็นภาษาไทยไม่เกิน 3 บรรทัด'],
['role' => 'user', 'content' => $request->detail],
]);
ข้อควรระวัง: การสร้างคำตอบบนเครื่องอาจใช้เวลานาน โดยเฉพาะครั้งแรกที่ต้องโหลดโมเดลเข้าหน่วยความจำ จึงไม่ควรเรียกใน web request ที่ผู้ใช้รอ ให้ส่งเข้า queue แล้วประมวลผลเบื้องหลัง หรือใช้แบบ stream เพื่อแสดงผลทีละส่วน และผลลัพธ์จากโมเดลต้องถูก escape ด้วย Html::encode() ก่อนแสดงผลเหมือนข้อมูลจากผู้ใช้ทั่วไป ถ้าหน้าบ้านใช้ JSON โดยตรงก็ต้อง validate ก่อนเชื่อเสมอ
ข้อจำกัดที่ต้องรู้ก่อนตัดสินใจ
- คุณภาพ โมเดลขนาดที่รันบนเครื่องทั่วไปได้ มักทำงานซับซ้อนได้ไม่ดีเท่าโมเดลขนาดใหญ่ที่ให้บริการผ่าน cloud โดยเฉพาะงานที่ต้องให้เหตุผลหลายขั้น
- ภาษาไทย ความสามารถภาษาไทยต่างกันมากระหว่างโมเดล บางตัวตอบไทยปนอังกฤษหรือใช้คำไม่เป็นธรรมชาติ ต้องทดสอบกับข้อความจริงของเรา
- ความเร็วและการรองรับผู้ใช้พร้อมกัน เครื่องเดียวรองรับ request พร้อมกันได้จำกัด ถ้าจะให้ผู้ใช้จำนวนมากใช้ ต้องวางแผน capacity และ queue
- การดูแล เราต้องดูแลเครื่อง อัปเดต Ollama และโมเดล ติดตาม log และความปลอดภัยเอง
- Prompt injection ยังมีอยู่ การรันบนเครื่องไม่ได้ทำให้ปลอดภัยจากการโจมตีผ่านเนื้อหา ถ้าแอปส่งเอกสารจากภายนอกให้โมเดล ยังต้องป้องกันตามหลักเดิม
แนวทางที่ใช้ได้ดีคือใช้โมเดลบนเครื่องกับงานที่ข้อมูลอ่อนไหวและงานไม่ซับซ้อน เช่น จัดหมวด สรุปสั้น ดึงข้อมูลจากข้อความ แล้ววัดผลด้วย eval ชุดเดียวกับที่ใช้กับโมเดลอื่น เพื่อเทียบอย่างเป็นธรรม
สรุป
- รัน LLM เองเหมาะเมื่อข้อมูลห้ามออกนอกองค์กร ต้องทำงาน offline หรืออยากทดลองโดยไม่มีค่าใช้ต่อ request
- หน่วยความจำคือข้อจำกัดหลัก เริ่มจากโมเดลเล็กบนเครื่องที่มี แล้ววัดผลกับงานจริง
- ติดตั้งจาก ollama.com เท่านั้น ใช้ ollama pull และ ollama run และตรวจไลเซนส์ของโมเดลก่อนใช้งานจริง
- API อยู่ที่พอร์ต 11434 บน localhost เรียกจาก PHP ได้ด้วย curl แต่ห้ามเปิดสู่อินเทอร์เน็ตโดยไม่มีการป้องกัน
- คุณภาพและภาษาไทยต่างกันมากระหว่างโมเดล ต้องทดสอบด้วยข้อมูลของเราเอง
ลองทำ
ติดตั้ง Ollama แล้ว pull โมเดลขนาดเล็กหนึ่งตัวที่ระบุว่ารองรับหลายภาษา นำ OllamaClient ไปใช้ใน console command ของ Yii2 ให้สรุปข้อความภาษาไทย 10 ข้อความจากงานจริง (ตัดข้อมูลส่วนบุคคลออกก่อน) จดเวลาที่ใช้ต่อข้อความ และให้คะแนนคุณภาพสรุปแต่ละข้อเป็น ดี พอใช้ หรือใช้ไม่ได้ แล้วพิจารณาว่าโมเดลนี้พอสำหรับงานนี้หรือไม่
ความคิดเห็น (0)
ยังไม่มีความคิดเห็น — เริ่มคุยเป็นคนแรก ถามสิ่งที่สงสัย หรือแชร์ประสบการณ์ของคุณ