6/6 · 6/6
ถามทีละข้อ: ทั้งสองโมเดลตอบถูกหมด
9/18 เทียบ 17/18
รวมคำถามเดิมไว้ด้วยกัน: MoE เทียบ dense
0/3 เทียบ 2/3
รอบที่ถูกครบทุกข้อเมื่อรวมคำถาม
≈2.1 เท่า
ความเร็ว decode แต่เวลาจริงใกล้เคียงกัน
ทำไมเราจึงทดสอบเรื่องนี้
เราใช้โมเดลในเครื่องภายในระบบเอเจนต์เขียนโค้ด โมเดลจะอ่านไฟล์ด้วยเครื่องมือแบบอ่านอย่างเดียวแล้วตอบคำถามเกี่ยวกับโค้ดเบส วิธีตรวจสอบโมเดลแบบนี้ที่คนมักใช้คือถามคำถามเดียวแล้วดูว่าตอบถูกไหม เราอยากรู้ว่าแค่นั้นพอหรือเปล่า
เราพบความต่างนี้โดยบังเอิญ ลูปตัวหนึ่งทำให้โปรเซสของเอเจนต์กลืนอินพุตมาตรฐานไป คำถามข้อ 2 ถึง 6 จึงถึงโมเดลเป็นพรอมต์ก้อนใหญ่ก้อนเดียว แทนที่จะเป็นห้าคำถามแยกกัน ผลลัพธ์ต่างจากเดิมชัดเจนจนเรานำเงื่อนไขแบบรวมก้อนนี้มาทำเป็นการทดสอบอย่างเป็นทางการ
บทความนี้รายงานการทดสอบนั้น เป็นข้อสังเกตเล็ก ๆ เรื่องวิธีทดสอบ ไม่ใช่การจัดอันดับโมเดล
ถ้าทดสอบทีละข้อ เราคงไม่มีวันเห็นความต่างนี้
การตั้งค่าการทดสอบ
ทุกอย่างรันบนเครื่องเดียว โหลดโมเดลทีละตัว
- เครื่อง
- Mac ชิป Apple Silicon 1 เครื่อง: M1 Max, 64 GB
- รันไทม์ในตอนนั้น
- Ollama 0.32.14 โหลดโมเดลไว้ทีละตัวเท่านั้น
- โมเดล A
- โมเดล mixture-of-experts (MoE) 35B-A3B มีพารามิเตอร์ที่ทำงานจริงประมาณ 3B (ตระกูล Qwen3.5) แบบ Q4_K_M
- โมเดล B
- โมเดล dense 27B (ตระกูล Qwen3.8) แบบ Q4_K_M
- งาน
- ตอบคำถามโดยอ่านโค้ดเบสของเราเองด้วยเครื่องมืออ่านอย่างเดียว (read, grep, find, ls) ผ่านระบบเอเจนต์ตัวเดียวกับที่เราใช้ทุกวัน
- การให้คะแนน
- ต้องตรงกับเฉลยที่คนตรวจสอบแล้วทุกตัวอักษร
งาน
คำถามที่มีคำตอบแน่นอนซึ่งคนตรวจสอบแล้ว
ระบบเอเจนต์
ตัวเดียวกับที่เราใช้ทุกวัน ใช้เครื่องมืออ่านอย่างเดียว: read, grep, find, ls
โมเดลในเครื่อง
MoE หรือ dense โหลดไว้ทีละตัว
การให้คะแนน
สคริปต์ตรวจว่าตรงกับเฉลยที่คนตรวจสอบแล้วทุกตัวอักษร
โมเดล mixture-of-experts ใช้พารามิเตอร์เพียงบางส่วนต่อโทเคน (ที่นี่ประมาณ 3B) ส่วนโมเดล dense ใช้ทั้งหมด เราไม่เปิดเผยชื่อไฟล์ ชื่อการตั้งค่า หรือโค้ดจากโค้ดเบส จึงอธิบายงานแบบกว้าง ๆ
เราถามอะไรบ้าง
ทั้งหมด 6 คำถาม แต่ละข้อมีคำตอบที่แน่นอนซึ่งคนตรวจสอบแล้ว
- 1ระบุการตั้งค่า 15 รายการที่ขึ้นต้นด้วยคำนำหน้าเดียวกัน
- 2ไล่ตามสายเหตุผล 3 ขั้น แล้วบอกรหัสการตรวจ ฟังก์ชันที่อยู่เบื้องหลัง และค่าคงที่
- 3บอกค่าที่แน่นอนที่เงื่อนไขหนึ่งใช้
- 4ใช้เหตุผลว่าการตรวจแบบ “มีสักตัวที่ตรงเงื่อนไขไหม” จะคืนค่าอะไรเมื่อรายการว่างเปล่า
- 5บอกหมายเลขบรรทัดที่ข้อความหนึ่งปรากฏ โดยไม่นับส่วนที่เป็นคอมเมนต์
- 6นับว่านิพจน์หนึ่งปรากฏกี่ครั้ง
ผลที่ 1: ถามทีละข้อ
ขั้นแรกเราถามทั้ง 6 คำถามทีละข้อ รันละหนึ่งข้อ โมเดลทั้งสองตอบถูกครบทั้ง 6 ข้อ
MoE ใช้เวลารวม 137.3 วินาที ส่วน dense ใช้เวลารวม 417.4 วินาที ช้ากว่า 3.0 เท่า แต่ด้านคุณภาพ การทดสอบนี้ไม่เห็นความต่างเลย
เวลาต่อข้อ เมื่อถามทีละข้อ
เวลาเป็นวินาทีของแต่ละคำถามทั้ง 6 ข้อ โมเดลทั้งสองตอบถูกครบ และ dense ใช้เวลานานกว่าในทุกข้อ
- ข้อ 117.543.9
- ข้อ 221.0135.3
- ข้อ 329.2121.0
- ข้อ 448.167.6
- ข้อ 515.731.5
- ข้อ 65.818.1
- รวม · MoE
- 137.3 วินาที
- รวม · dense
- 417.4 วินาที
ดูข้อมูลเป็นตาราง
| คำถาม | MoE | dense |
|---|---|---|
| ข้อ 1 | 17.5 | 43.9 |
| ข้อ 2 | 21.0 | 135.3 |
| ข้อ 3 | 29.2 | 121.0 |
| ข้อ 4 | 48.1 | 67.6 |
| ข้อ 5 | 15.7 | 31.5 |
| ข้อ 6 | 5.8 | 18.1 |
| รวม | 137.3 | 417.4 |
| ตอบถูก | 6/6 | 6/6 |
ถ้าหยุดแค่ตรงนี้ เราคงสรุปว่าโมเดลสองตัวนี้เชื่อถือได้พอ ๆ กันสำหรับงานแบบนี้
ผลที่ 2: รวมไว้ในบริบทเดียว
จากนั้นเรารวมคำถามเดิมทั้ง 6 ข้อไว้ในบริบทเดียว แล้วรันก้อนนี้โมเดลละ 3 รอบ รวมโมเดลละ 18 คำตอบย่อย
ความต่างที่การทดสอบทีละข้อซ่อนไว้ ปรากฏขึ้นทันที
เมื่อรวมไว้ในบริบทเดียว: ทุกคำตอบย่อย ทีละรอบ
โมเดลละ 3 รอบ รอบละ 6 คำตอบย่อย เครื่องหมาย ✓ คือตรงเฉลย ✕ คือผิด ส่วนแถวลายเฉียงคือรอบที่ไม่มีผลลัพธ์ออกมาเลย
MoE
dense
ดูข้อมูลเป็นตาราง
| รอบ | MoE | dense |
|---|---|---|
| รอบที่ 1 | 0/6 · 187.7 วินาที ผลลัพธ์ว่างเปล่า | 6/6 · 375.5 วินาที ถูกทั้งหมด |
| รอบที่ 2 | 4/6 · 168.9 วินาที ทำรายการตก 1 รายการ และตอบจริง/เท็จผิด 1 ข้อ | 5/6 · 346.8 วินาที รายการ 15 รายการถูกหมด แต่เพิ่มชื่อที่ไม่มีอยู่จริงอีก 2 ชื่อ (รวม 17 รายการ) |
| รอบที่ 3 | 5/6 · 155.5 วินาที ตอบเป็นนิพจน์และตัวแปรภายใน ทั้งที่ต้องตอบชื่อฟังก์ชันและชื่อค่าคงที่ | 6/6 · 364.4 วินาที ถูกทั้งหมด |
| รวม | 9/18 (50%) | 17/18 (94%) |
ภาพรวมเมื่อรวมคำถาม
คำตอบย่อยที่ถูกจาก 18 รอบที่ถูกครบทุกข้อจาก 3 และเวลาเฉลี่ยต่อรอบ
คำตอบย่อยที่ถูก
รอบที่ถูกครบทุกข้อ
เวลาเฉลี่ยต่อรอบ
ดูข้อมูลเป็นตาราง
| ตัวชี้วัด | MoE | dense |
|---|---|---|
| คำตอบย่อยที่ถูก | 9/18 (50%) | 17/18 (94%) |
| รอบที่ถูกครบทุกข้อ | 0/3 | 2/3 |
| เวลาเฉลี่ยต่อรอบ | 170.7 วินาที | 362.2 วินาที |
MoE รวม 9 จาก 18 (50%) ไม่มีรอบไหนถูกครบทุกข้อ (0 จาก 3) เวลาเฉลี่ย 170.7 วินาที ส่วน dense รวม 17 จาก 18 (94%) ถูกครบทุกข้อ 2 จาก 3 รอบ เวลาเฉลี่ย 362.2 วินาที ช้ากว่า MoE 2.12 เท่า
ในรอบที่ 1 ของ MoE โปรเซสจบการทำงานอย่างเงียบ ๆ หลังผ่านไป 187.7 วินาที โดยไม่มีข้อมูลออกทางเอาต์พุตมาตรฐานหรือข้อผิดพลาดมาตรฐานเลยแม้แต่ไบต์เดียว
สองโมเดลพลาดกันคนละแบบ
การนับจำนวนข้อที่ถูกไม่ได้บอกว่ารอบนั้นพังอย่างไร เราจึงบันทึกรูปแบบความล้มเหลวด้วย
พลาดอะไร แยกตามประเภท
นับรูปแบบความล้มเหลวเป็นคำตอบย่อย (หนึ่งคำถามในหนึ่งรอบ) รอบเงียบของ MoE รอบเดียวก็นับเป็น 6
ดูข้อมูลเป็นตาราง
| รูปแบบความล้มเหลว | MoE | dense |
|---|---|---|
| ผลลัพธ์ว่างเปล่าโดยเงียบ | 6 | 0 |
| รายการตก | 1 | 0 |
| ตอบจริง/เท็จผิด | 1 | 0 |
| คิดตื้น | 1 | 0 |
| แต่งรายการขึ้นเอง | 0 | 1 |
โมเดล MoE เมื่อมีภาระมาก
- เงียบและว่างเปล่า: รอบที่ 1 จบการทำงานโดยไม่มีอะไรออกมาเลยทั้งเอาต์พุตมาตรฐานและข้อผิดพลาดมาตรฐาน
- ทำรายการตก: ขาดไป 1 จาก 15 รายการ และตอบจริง/เท็จผิดอีก 1 ข้อ
- คิดตื้น: หยุดอยู่แค่ผิวเผิน ไม่ไล่สายการเรียกไปถึงฟังก์ชันและค่าคงที่ตัวจริง
โมเดล dense
- แต่งขึ้นเอง: ตอบรายการจริงครบ 15 รายการ แล้วเติมชื่อที่ไม่มีอยู่จริงเพิ่มอีก 2 ชื่อ
สำหรับบทบาทที่มอบหมายการตัดสินใจให้ เราเห็นว่าการรันที่เงียบและว่างเปล่าเป็นความล้มเหลวที่เสียหายกว่า
ความเร็ว decode กับเวลาจริง
ตัวเลขความเร็วมักอ้างความเร็ว decode คือโมเดลเขียนได้กี่โทเคนต่อวินาที แต่งานเอเจนต์จริงยังมี prefill ด้วย คือขั้นที่โมเดลอ่านทุกอย่างที่ได้รับ ซึ่งในที่นี้คือไฟล์ที่เอเจนต์เปิด เราวัดทั้งสองอย่างกับโมเดล dense ด้วยพรอมต์เดียวกัน ในสภาพที่โมเดลอุ่นเครื่องแล้ว และปิด thinking
ความเร็ว decode เทียบกับเวลาจริง (โมเดล dense สองเอนจิน)
รันละ 3 รอบ เอนจิน MLX ทำ decode ได้เร็วกว่า แต่เมื่อรันชุดคำถามรวม เวลาใกล้เคียงกัน
ความเร็ว decode, tok/s (แท่งยาวกว่า = เร็วกว่า)
dense, Q4_K_M (GGUF)
9.2 / 8.7 / 7.2 tok/s
dense, MLX (nvfp4)
18.3 / 18.2 / 17.2 tok/s
≈2.1× decode เร็วกว่า (MLX เทียบ GGUF)
เวลาจริง, วินาที (แท่งสั้นกว่า = เร็วกว่า)
dense, Q4_K_M (GGUF)
529.4 / 468.0 / 447.8 วินาที · เฉลี่ย 481.7
dense, MLX (nvfp4)
639.8 / 338.5 / 498.3 วินาที · เฉลี่ย 492.2
เวลาจริง: ไม่มีความต่างที่มีนัยสำคัญ
เหตุผล: งานเอเจนต์จริงส่วนใหญ่คือ prefill คือโมเดลอ่านไฟล์ที่ได้รับ ซึ่งความเร็ว decode ไม่ได้วัด
ดูข้อมูลเป็นตาราง
| รูปแบบ | รอบที่ 1 | รอบที่ 2 | รอบที่ 3 | เฉลี่ย |
|---|---|---|---|---|
| MoE, Q4_K_M · tok/s | 39.9 | 40.0 | 40.0 | — |
| dense, Q4_K_M (GGUF) · tok/s | 9.2 | 8.7 | 7.2 | — |
| dense, Q4_K_M (GGUF) · วินาที | 529.4 | 468.0 | 447.8 | 481.7 |
| dense, MLX (nvfp4) · tok/s | 18.3 | 18.2 | 17.2 | — |
| dense, MLX (nvfp4) · วินาที | 639.8 | 338.5 | 498.3 | 492.2 |
เอนจิน MLX ทำ decode ได้เร็วกว่า GGUF ประมาณ 2.1 เท่า แต่เมื่อรันชุดคำถาม 6 ข้อรวมกัน เวลาจริงแทบไม่ต่างกัน ค่าเฉลี่ยของ GGUF คือ 481.7 วินาที และของ MLX คือ 492.2 วินาที ไม่มีความต่างที่มีนัยสำคัญ เพราะในงานเอเจนต์จริง เวลาส่วนใหญ่หมดไปกับ prefill (การอ่านไฟล์) ไม่ใช่ decode
ทั้งสองรูปแบบตอบถูกในคำถามที่ไม่ถูกกระทบจากการแก้โค้ดภายหลัง (ดูข้อจำกัดด้านล่าง)
อัตราส่วนความเร็วระหว่าง MoE กับ dense ก็ขึ้นกับพรอมต์ ในการทดสอบนี้คือ 4.8 เท่า (40.0 เทียบกับ 8.4 tok/s) ส่วนในการทดสอบก่อนหน้านี้คือ 7 เท่า โปรดอย่าอ้าง “7 เท่า” เป็นตัวเลขทั่วไป
ตอนนี้เราทำอย่างไร
- ทดสอบเอเจนต์ด้วยภาระแบบที่จะเจอจริง คือบริบทยาวที่รวมคำถามไว้ด้วยกัน ไม่ใช่แค่ถามทีละข้อ
- บันทึกรูปแบบความล้มเหลวด้วย ไม่ใช่แค่คะแนน: ผลลัพธ์ว่างเปล่าโดยเงียบ รายการตก คิดตื้น แต่งขึ้นเอง
- มอง tok/s ของ decode ว่าเป็นตัวแทนที่ไม่ดีของเวลาทำงาน เมื่อ prefill กินเวลาส่วนใหญ่
- ให้คะแนนด้วยสคริปต์เทียบกับเฉลยที่คนตรวจสอบแล้ว และเก็บล็อกดิบไว้
- บอกการตั้งค่าและข้อจำกัดให้ชัด อย่าเอา n=3 ไปทำเป็นตารางอันดับ
ข้อจำกัดและข้อควรระวัง
- นี่เป็นการทดสอบขนาดเล็ก: 6 คำถาม x 3 รอบ x 2 โมเดล เครื่องเดียว โค้ดเบสเดียว n=3 ต่อช่อง เป็นข้อสังเกตเรื่องการออกแบบการทดสอบ ไม่ใช่การจัดอันดับโมเดล
- ซอฟต์แวร์เดินหน้าไปแล้ว ชุด Ollama ที่ใช้ที่นี่ถูกแทนที่ด้วย llama.cpp ในระบบของเราแล้ว ชื่อตระกูลโมเดลตรงกับที่ทดสอบ ผลวันนี้อาจต่างไป และเราไม่ได้อ้างอะไรเกี่ยวกับเวอร์ชันปัจจุบัน
- เงื่อนไขเรื่องความเร็วรันหลังจากการแก้โค้ดที่ทำให้คำตอบของคำถามหนึ่งข้อ (ข้อ 5) เปลี่ยนไป จึงเทียบเงื่อนไขนั้นจากอีก 5 ข้อที่เหลือเท่านั้น
- ฮาร์ดแวร์เป็น Apple Silicon ไม่ใช่ NVIDIA อย่านำตัวเลขเหล่านี้ไปปนกับตัวเลขจากระบบของคนอื่น
- การให้คะแนนใช้การตรงกับเฉลยที่คนตรวจสอบแล้วทุกตัวอักษร การตรวจด้วยสายตาครั้งแรกพลาดการแต่งขึ้นเองของโมเดล dense ในรอบที่ 2 ไปหนึ่งจุด และสคริปต์แก้ให้ถูก จึงควรให้คะแนนด้วยสคริปต์เสมอ
ลองกับเอเจนต์ของคุณเอง
ไม่ต้องใช้โค้ดของเราก็นำแนวคิดเดียวกันไปใช้ได้
- เขียนงานที่มีคำตอบแน่นอนซึ่งคนตรวจสอบแล้ว เพื่อให้สคริปต์ให้คะแนนได้
- รันแต่ละงานแยกกันก่อน แล้วรวมเป็นบริบทยาวก้อนเดียวให้เหมือนที่การรันจริงของคุณเป็น
- ทำซ้ำแต่ละเงื่อนไขหลายครั้ง และเก็บผลของแต่ละรอบไว้
- บันทึกประเภทความล้มเหลวของทุกรอบที่ผิด: ผลลัพธ์ว่าง รายการตก คิดตื้น แต่งขึ้นเอง
- วัดเวลาจริง และวัดความเร็ว decode แยกต่างหาก
- ให้คะแนนด้วยสคริปต์และเก็บล็อกดิบไว้
- จดการตั้งค่าและข้อจำกัดไว้ข้างผลลัพธ์
บันทึกดิบ
ล็อกการรัน (ตามต้นฉบับ)
[qwen3.5:35b-a3b] C1 done 187.7s[qwen3.5:35b-a3b] C2 done 168.9s[qwen3.5:35b-a3b] C3 done 155.5s[qwen3.8:27b] C1 done 375.5s[qwen3.8:27b] C2 done 346.8s[qwen3.8:27b] C3 done 364.4s| โมเดล | รอบ | เอาต์พุต (ไบต์) | แถบขนาด | วินาที |
|---|---|---|---|---|
| MoE | รอบที่ 1 | 0 ⚠ | 187.7 | |
| MoE | รอบที่ 2 | 475 | 168.9 | |
| MoE | รอบที่ 3 | 488 | 155.5 | |
| dense | รอบที่ 1 | 495 | 375.5 | |
| dense | รอบที่ 2 | 533 | 346.8 | |
| dense | รอบที่ 3 | 495 | 364.4 |
| คำถาม | MoE รอบที่ 1 | MoE รอบที่ 2 | MoE รอบที่ 3 | dense รอบที่ 1 | dense รอบที่ 2 | dense รอบที่ 3 |
|---|---|---|---|---|---|---|
| ข้อ 1 | ไม่มีผลลัพธ์ | ผิด | ถูก | ถูก | ผิด | ถูก |
| ข้อ 2 | ไม่มีผลลัพธ์ | ถูก | ผิด | ถูก | ถูก | ถูก |
| ข้อ 3 | ไม่มีผลลัพธ์ | ถูก | ถูก | ถูก | ถูก | ถูก |
| ข้อ 4 | ไม่มีผลลัพธ์ | ผิด | ถูก | ถูก | ถูก | ถูก |
| ข้อ 5 | ไม่มีผลลัพธ์ | ถูก | ถูก | ถูก | ถูก | ถูก |
| ข้อ 6 | ไม่มีผลลัพธ์ | ถูก | ถูก | ถูก | ถูก | ถูก |
อภิธานศัพท์
- MoE (mixture of experts)
- โมเดลที่ใช้พารามิเตอร์เพียงบางส่วนต่อโทเคน
- โมเดล dense
- โมเดลที่ใช้พารามิเตอร์ทั้งหมดต่อโทเคน
- prefill
- ขั้นที่โมเดลอ่านทุกอย่างที่ได้รับ เช่น ไฟล์ที่เอเจนต์เปิด
- decode
- ขั้นที่โมเดลเขียนคำตอบออกมาทีละโทเคน
- tok/s
- จำนวนโทเคนต่อวินาที บอกว่า decode เร็วแค่ไหน
- เวลาจริง (wall-clock)
- เวลาจริงตั้งแต่เริ่มจนจบการรัน รวม prefill และ decode
- ตรงกันทุกตัวอักษร (exact match)
- นับว่าถูกก็ต่อเมื่อตรงกับเฉลยที่คนตรวจสอบแล้วทุกตัวอักษร
ข้อมูลและวิธีการ
ดาวน์โหลดข้อมูล
บันทึกเบื้องหลังบทความนี้ ในรูปแบบไฟล์ธรรมดา แต่ละไฟล์ CSV ขึ้นต้นด้วยส่วนอธิบายสั้น ๆ
# ที่มา: ล็อกการรันของเราเอง วัดผลเมื่อ 17 สิงหาคม 2569 บน Apple M1 Max 64 GB ด้วย Ollama 0.32.14 ให้คะแนนด้วยสคริปต์ ไม่เผยแพร่คำตอบที่ถูกต้อง สัญญาอนุญาต: ยังไม่ได้ระบุ
- การรันแบบรวมคำถาม: คะแนน วินาที ขนาดเอาต์พุต
bundled-runs.csvดาวน์โหลด: bundled-runs.csv - การรันแบบรวมคำถาม: ทุกคำตอบย่อย
bundled-per-question.csvดาวน์โหลด: bundled-per-question.csv - ถามทีละข้อ: เวลาเป็นวินาที
one-question-seconds.csvดาวน์โหลด: one-question-seconds.csv - ความเร็ว decode และเวลาจริง
speed-variants.csvดาวน์โหลด: speed-variants.csv - ล็อกการรันตามต้นฉบับ
run-log.txtดาวน์โหลด: run-log.txt - ทุกอย่างข้างต้นในไฟล์ JSON เดียว
local-llm-bundled-context.jsonดาวน์โหลด: local-llm-bundled-context.json
แหล่งอ้างอิง
- ล็อกการรันและเฉลย. ล็อกการรันของเราเอง ให้คะแนนใหม่ด้วยการเทียบตรงกันทุกตัวอักษรกับเฉลยที่คนตรวจสอบแล้ว ทีมเก็บรักษาไว้ ไม่เผยแพร่เฉลย
- ไฟล์ข้อมูลด้านบน. ตัวเลขทุกตัวในบทความนี้อยู่ในไฟล์เหล่านั้น
