เลือกโมเดล AI ให้เหมาะงาน: ใหญ่ เล็ก เร็ว ถูก

เมื่อเริ่มทำฟีเจอร์ AI คำถามที่ตามมาเสมอคือ "ใช้โมเดลไหนดี" คำตอบที่พบบ่อยคือเลือกตัวที่ดังที่สุดหรือตัวที่ใหญ่ที่สุดไว้ก่อน ซึ่งอาจทำให้จ่ายแพงเกินจำเป็นและช้ากว่าที่ผู้ใช้รับได้ หรือกลับกัน เลือกตัวถูกที่สุดแล้วพบว่าตอบภาษาไทยไม่ดี โมเดลใหม่ออกมาเร็วมากจนคำแนะนำแบบ "ใช้ตัวนี้" ล้าสมัยภายในไม่กี่เดือน บทความนี้จึงไม่บอกว่าควรใช้โมเดลไหน แต่ให้เกณฑ์และวิธีเลือกที่ใช้ได้ตลอด ตั้งแต่คุณภาพ ความเร็ว ราคา ขนาด context ภาษาไทย การรันเอง ไปจนถึงการตัดสินด้วย eval ของเราเองพร้อมตัวอย่างโค้ด PHP
เริ่มจากงาน ไม่ใช่จากโมเดล
ก่อนดูรายชื่อโมเดล ให้เขียนลักษณะงานให้ชัดก่อน เพราะเกณฑ์แต่ละข้อมีน้ำหนักต่างกันตามงาน
- ความยากของงาน จัดหมวดคำร้อง ดึงเลขที่เอกสารจากข้อความ หรือสรุปสั้น เป็นงานที่โมเดลเล็กทำได้ดีพอ ส่วนการวิเคราะห์เอกสารยาวหลายฉบับหรือเขียนโค้ดซับซ้อน มักต้องใช้โมเดลที่ความสามารถสูงกว่า
- ผู้ใช้รอคำตอบหรือไม่ chatbot ต้องเร็ว ส่วนงานประมวลผลเอกสารตอนกลางคืนรอได้
- ปริมาณ วันละสิบครั้งกับวันละหมื่นครั้ง ทำให้เรื่องราคาสำคัญต่างกันมาก
- ความอ่อนไหวของข้อมูล ข้อมูลส่งออกไปบริการภายนอกได้หรือไม่ ต้องอยู่ในประเทศหรือในองค์กรหรือเปล่า
- ราคาของความผิดพลาด ตอบผิดแล้วผู้ใช้แค่กดถามใหม่ หรือตอบผิดแล้วเกิดความเสียหาย
เกณฑ์หลักในการเลือก
| เกณฑ์ | คำถามที่ต้องตอบ | วิธีวัด |
|---|---|---|
| คุณภาพ | ตอบถูกตามเกณฑ์ของงานเราบ่อยแค่ไหน | eval ชุดของเราเอง ไม่ใช่ตัวเลขจากที่อื่น |
| ความเร็ว | เวลาถึงคำตอบแรกและเวลาจนตอบจบเป็นเท่าไร | วัด latency จริงจากเครือข่ายของเรา ช่วงเวลาที่ใช้งานจริง |
| ราคา | ต้นทุนต่อหนึ่งงานเป็นเท่าไร | จำนวน token เข้าและออกเฉลี่ยต่องาน คูณราคาปัจจุบันของผู้ให้บริการ |
| ขนาด context | ต้องส่งข้อความยาวแค่ไหนในครั้งเดียว | วัดความยาวของ prompt จริง รวม system prompt และเอกสารที่แนบ |
| ภาษาไทย | เข้าใจและเขียนไทยเป็นธรรมชาติไหม | ชุดทดสอบที่เป็นข้อความไทยจริง รวมคำเฉพาะของธุรกิจ |
| ความสามารถเสริม | ต้องใช้ structured output, tool use, รับภาพ หรือไม่ | ทดสอบฟีเจอร์ที่ต้องใช้จริง |
| การรันเองและข้อมูล | ต้องรันในองค์กรหรือส่งออกได้ | นโยบายข้อมูลขององค์กร และเงื่อนไขของผู้ให้บริการ |
| ไลเซนส์และเงื่อนไข | ใช้เชิงพาณิชย์ได้ไหม มีข้อห้ามอะไร | อ่านเงื่อนไขการใช้งานของโมเดลหรือบริการ |
ข้อสังเกตเรื่องภาษาไทย: โมเดลหลายตัวแบ่งข้อความไทยเป็น token มากกว่าข้อความอังกฤษที่ความยาวใกล้กัน ทำให้ทั้งราคาและการใช้ context สูงกว่าที่คำนวณจากตัวอย่างภาษาอังกฤษ ควรวัดจำนวน token จากข้อความไทยจริงที่ API ส่งกลับมา
ใหญ่ เล็ก เร็ว ถูก: ไม่จำเป็นต้องเลือกตัวเดียว
ระบบจริงหลายระบบใช้มากกว่าหนึ่งโมเดล โดยเลือกตามงาน รูปแบบที่พบบ่อย:
- แยกตามงาน ใช้โมเดลเล็กกับงานจัดหมวดและดึงข้อมูล ใช้โมเดลใหญ่กับงานวิเคราะห์ที่ซับซ้อน
- Cascade ให้โมเดลเล็กตอบก่อน ถ้าผลไม่ผ่านการตรวจ (เช่น JSON ไม่ตรง schema หรือโมเดลบอกว่าไม่มั่นใจ) ค่อยส่งต่อให้โมเดลใหญ่
- แยกตามความอ่อนไหวของข้อมูล ข้อมูลภายในใช้โมเดลที่รันในองค์กร ข้อมูลทั่วไปใช้บริการ cloud ได้
- ลดงานก่อนถึงโมเดล หลายงานไม่ต้องใช้ LLM เลย เช่น ค้นหาด้วย full-text search หรือตรวจรูปแบบด้วย regex ก่อน ใช้ LLM เฉพาะส่วนที่จำเป็น
เพื่อให้สลับโมเดลได้ง่าย ให้แอปเรียกผ่าน interface กลาง ไม่ผูกโค้ดกับผู้ให้บริการรายใดรายหนึ่ง
<?php
namespace common\ai;
interface ModelClient
{
/** ชื่อที่ใช้แสดงในรายงาน */
public function name(): string;
/**
* @param array<int, array{role: string, content: string}> $messages
*/
public function complete(array $messages): ModelResult;
}
final class ModelResult
{
public function __construct(
public readonly string $text,
public readonly int $inputTokens,
public readonly int $outputTokens,
public readonly float $latencySeconds,
) {
}
}
แต่ละผู้ให้บริการหรือ Ollama บนเครื่องเป็นคลาสหนึ่งที่ implement interface นี้ ชื่อโมเดลและ API key อ่านจาก config หรือ environment ทำให้เปลี่ยนโมเดลได้โดยไม่ต้องแก้ business logic
ตัดสินด้วย eval ของเราเอง
ผล benchmark สาธารณะบอกภาพกว้างได้ แต่ไม่ได้วัดงานของเรา ข้อความภาษาไทยของเรา หรือรูปแบบคำตอบที่ระบบเราต้องการ วิธีที่เชื่อถือได้คือสร้างชุดทดสอบจากงานจริงแล้วรันกับทุกโมเดลที่สนใจ (รายละเอียดการสร้างชุดทดสอบอยู่ในบทความ "Evals: วัดคุณภาพคำตอบ AI ก่อนขึ้น Production" ของซีรีส์นี้) ตัวอย่าง runner ที่เทียบหลายโมเดลพร้อมกัน วัดทั้งอัตราผ่าน เวลา และต้นทุนโดยประมาณ
<?php
namespace common\ai;
final class ModelComparison
{
/**
* @param ModelClient[] $clients
* @param array<string, array{input: float, output: float}> $pricePerMillion ราคาต่อ 1 ล้าน token ที่เรากรอกเองจากหน้าราคาปัจจุบัน
* @param array<int, array{prompt: string, check: callable(string): bool}> $cases
* @return array<string, array<string, float|int>>
*/
public function run(array $clients, array $pricePerMillion, array $cases, string $systemPrompt): array
{
$report = [];
foreach ($clients as $client) {
$passed = 0;
$latencies = [];
$cost = 0.0;
$price = $pricePerMillion[$client->name()] ?? ['input' => 0.0, 'output' => 0.0];
foreach ($cases as $case) {
$result = $client->complete([
['role' => 'system', 'content' => $systemPrompt],
['role' => 'user', 'content' => $case['prompt']],
]);
if (($case['check'])($result->text)) {
$passed++;
}
$latencies[] = $result->latencySeconds;
$cost += $result->inputTokens / 1_000_000 * $price['input']
+ $result->outputTokens / 1_000_000 * $price['output'];
}
sort($latencies);
$count = max(count($cases), 1);
$report[$client->name()] = [
'pass_rate' => round($passed / $count * 100, 1),
'median_latency' => $latencies[intdiv(count($latencies), 2)] ?? 0.0,
'cost_per_case' => round($cost / $count, 6),
];
}
return $report;
}
}
ข้อควรจำเมื่อรันเทียบ:
- ใช้ prompt และชุดทดสอบเดียวกันทุกโมเดล แต่ยอมให้ปรับ prompt ให้เหมาะกับแต่ละโมเดลได้ในรอบถัดไป เพราะบางโมเดลตอบสนองต่อรูปแบบ prompt ต่างกัน
- ราคาให้กรอกเองจากหน้าราคาของผู้ให้บริการ ณ วันที่ทดสอบ และบันทึกวันที่ไว้ เพราะราคาเปลี่ยนได้
- รันซ้ำมากกว่าหนึ่งรอบ คำตอบของ LLM ไม่คงที่ ผลที่ต่างกันเล็กน้อยระหว่างโมเดลอาจเป็นแค่ความแปรปรวน
- อย่าใส่ข้อมูลส่วนบุคคลจริงในชุดทดสอบที่ส่งไปบริการภายนอก ให้ทำข้อมูลให้เป็นนิรนามก่อน
ตัดสินใจและทบทวนเป็นรอบ
เมื่อได้ผล eval แล้ว ให้กำหนดเกณฑ์ขั้นต่ำก่อน แล้วเลือกตัวที่ถูกและเร็วที่สุดในกลุ่มที่ผ่านเกณฑ์ ไม่ใช่เลือกตัวที่คะแนนสูงสุดเสมอ ตัวอย่างเกณฑ์: "อัตราผ่านอย่างน้อยตามที่ทีมตกลง, median latency ไม่เกินที่หน้าจอรับได้, ต้นทุนต่อเดือนตามปริมาณที่คาดไม่เกินงบ" จากนั้น
- เขียนเหตุผลการเลือกไว้ใน decision record ของโปรเจกต์ พร้อมผล eval และวันที่
- ติดตามคุณภาพหลังขึ้นจริง ด้วยการสุ่มตรวจคำตอบและเก็บกรณีที่ผู้ใช้ร้องเรียนเข้าชุดทดสอบ
- ทบทวนเป็นรอบ เช่น ทุกไตรมาส หรือเมื่อผู้ให้บริการประกาศเปลี่ยนรุ่นหรือเลิกให้บริการรุ่นที่ใช้
- เตรียมแผนสำรอง ถ้าบริการหลักล่ม จะ fallback ไปโมเดลไหน หรือจะปิดฟีเจอร์อย่างไรให้ผู้ใช้เข้าใจ
เมื่อมี interface กลางและ eval ชุดเดิม การเปลี่ยนโมเดลในอนาคตจะเป็นการตัดสินใจจากข้อมูล ไม่ใช่การเดา
สรุป
- เริ่มจากลักษณะงาน: ความยาก ความเร่งด่วน ปริมาณ ความอ่อนไหวของข้อมูล และราคาของความผิดพลาด
- เกณฑ์หลักคือคุณภาพ ความเร็ว ราคา ขนาด context ภาษาไทย ความสามารถเสริม การรันเอง และไลเซนส์
- ไม่ต้องใช้โมเดลเดียว ใช้การแยกตามงานหรือ cascade และเรียกผ่าน interface กลาง
- ตัดสินด้วย eval จากงานจริงของเรา วัดทั้งอัตราผ่าน latency และต้นทุนต่องาน
- เลือกตัวที่ถูกและเร็วที่สุดในกลุ่มที่ผ่านเกณฑ์ บันทึกเหตุผล และทบทวนเป็นรอบ
ลองทำ
เลือกงาน AI หนึ่งงานในระบบของคุณ เขียนชุดทดสอบ 15 ข้อจากข้อมูลจริงที่ทำเป็นนิรนามแล้ว พร้อมฟังก์ชันตรวจผลแต่ละข้อ จากนั้น implement ModelClient อย่างน้อยสองตัว (เช่น โมเดลจากบริการที่ใช้อยู่ และโมเดลบนเครื่องผ่าน Ollama) รัน ModelComparison สองรอบ แล้วเขียน decision record สั้น ๆ ว่าจะเลือกตัวไหนเพราะอะไร
ความคิดเห็น (0)
ยังไม่มีความคิดเห็น — เริ่มคุยเป็นคนแรก ถามสิ่งที่สงสัย หรือแชร์ประสบการณ์ของคุณ