การแก้ไขปัญหาคู่มือ
llama.cpp ประมวลผลพรอมป์ช้าลง 35 เท่า? แก้ KV cache q5_1
Flash attention บวก KV cache q5_1 อาจดัน attention ไปที่ CPU วิธีตรวจสอบ แก้ด้วย q8_0 และเมื่อใดที่ API ง่ายกว่า

ในหน้านี้
โมเดลโลคอลของคุณตอบได้ดี แต่ทุกพรอมป์ยาวตอนนี้ต้องรอเป็นนาทีครึ่งในขณะที่ GPU ไม่ได้ทำอะไรเลย ถ้าคุณรัน llama.cpp ด้วย -fa on และ KV cache แบบ q5_1 นั่นน่าจะเป็นสาเหตุ: บิลด์ CUDA เริ่มต้นไม่มีเคอร์เนล flash-attention สำหรับแคชประเภทนั้น ขั้นตอน attention จึงไปรันบน CPU อย่างเงียบ ๆ การเปลี่ยนแคชเป็น q8_0 ทำให้ผู้รายงานคนหนึ่งได้จาก 38 เป็น 1348 tokens/s ในการประมวลผลพรอมป์
ตัวเลขด้านล่างมาจาก llama.cpp issue #28455 (เปิดเมื่อ 5 กันยายน 2026, บิลด์ 10791, ตรวจสอบเมื่อ 28 ตุลาคม 2026) ผู้รายงานหนึ่งคน, RTX 4080 หนึ่งตัว, โมเดล 27B หนึ่งตัว ดังนั้นอ่านเป็นตัวอย่างที่ทำจริง ไม่ใช่กฎตายตัว การวิเคราะห์สาเหตุรากก็เป็นของพวกเขาเอง: ผู้ดูแลเรียกว่า "known issue" และปิด issue ในวันถัดมา
หน้าตาบนหน้าจอ#
การตั้งค่าเป็นเรื่องปกติ มีคนต้องการคอนเท็กซ์ 131072 โทเคนบนการ์ด 16 GB ใบเดียว จึงลด KV cache ลงเป็น q5_1:
llama-server -m model.gguf -ngl 99 -fa on -c 131072 -np 4 \
--cache-type-k q5_1 --cache-type-v q5_1จากนั้นส่งพรอมป์ 3.6K โทเคน การประมวลผลพรอมป์รันที่ 38.4 tokens/s และ decoding ที่ 6.5 tokens/s ลองหารดู: 3,600 ÷ 38.4 = 93.75 ดังนั้นประมาณ 94 วินาทีก่อนคำแรก ด้วย q8_0 พรอมป์เดียวกันรันที่ 1348 tokens/s: 3,600 ÷ 1,348 = 2.67 ต่ำกว่าสามวินาที
จุดสังเกตอยู่ที่ task manager ระหว่างการรันที่ช้า GPU อยู่ที่เกือบ 0% ขณะที่ CPU แสดงประมาณ 930% (เก้าหรือสิบคอร์กำลังทำงาน) GPU ที่ว่างเปล่าขณะที่คุณ "รันบน GPU" คืออาการที่ต้องมองหา

ทำไมแคชที่เล็กกว่าจึงช้าลงมากขนาดนี้#
Flash attention เป็นเคอร์เนล GPU แบบ fused บิลด์ CUDA เริ่มต้นมาพร้อมกับมันเฉพาะบางคู่ของประเภท KV cache สำหรับ q4_0, q4_1, q5_0 และ q5_1 ไม่มีเคอร์เนล ดังนั้น llama.cpp จึงไม่หยุดด้วยข้อผิดพลาด มันย้ายการดำเนินการนั้นไปที่ CPU แล้วทำต่อ ทุกอย่างยังทำงานได้ แค่ช้ากว่าประมาณ 35 เท่าในการประมวลผลพรอมป์ (1348 ÷ 38.4 = 35.1)
คำว่า "เงียบ ๆ" นั่นแหละคือปัญหาทั้งหมด ไม่มีอะไรในคำตอบบอกคุณ การประมวลผลพรอมป์ลดลงมากที่สุด (ประมาณ 35×) และการสร้างก็ช้าลงด้วย: 6.5 tokens/s เทียบกับ 30.1 ด้วย q8_0 ใน issue เดียวกัน
ตรวจสอบในสองนาที#
รัน llama-bench ด้วยประเภทแคชเดียวกับที่คุณใช้ในเซิร์ฟเวอร์ ครั้งละหนึ่งแบบ และดู GPU ในอีก terminal หนึ่ง:
llama-bench -m model.gguf -ngl 99 -fa 1 -ctk q8_0 -ctv q8_0 -p 512 -n 0
llama-bench -m model.gguf -ngl 99 -fa 1 -ctk q5_1 -ctv q5_1 -p 512 -n 0
nvidia-smi -l 1ผลลัพธ์ pp512 ของผู้รายงานบน Qwen 27B Q5_K_XL: 1511.92 tokens/s สำหรับ q8_0/q8_0, ประมาณ 197 สำหรับ q5_1/q5_1 บนบิลด์เริ่มต้น ถ้าสองบรรทัดของคุณแสดงช่องว่างแบบนั้นและ nvidia-smi แสดงว่า GPU ว่างระหว่างบรรทัดที่สอง คุณเจอแล้ว
ก่อนจะแก้ไขอะไร จับคู่สิ่งที่เห็นกับสาเหตุที่เป็นไปได้:
จับคู่
จับคู่อาการแต่ละอย่างกับสาเหตุ
แตะรายการทางซ้าย แล้วแตะคู่ของมัน
- GPU ที่ ~0%, CPU ที่ ~930% ระหว่างพรอมป์ยาวAttention รันบน CPU
- Decoding ลดลงเหลือ ~6.5 tokens/s เทียบกับ 30.1 ด้วย
q8_0การสร้างก็ช้าลง ไม่ใช่แค่การประมวลผลพรอมป์ - แฟล็กเดียวกันเร็วด้วย
q8_0คู่ประเภทแคชนี้ไม่มีเคอร์เนล GPU flash-attention ในบิลด์เริ่มต้น
วิธีแก้ 1: ใช้ q8_0 (หรือรีบิลด์)#
วิธีแก้ที่เร็วที่สุดคือเปลี่ยนสองแฟล็กและเก็บอย่างอื่นไว้เหมือนเดิม:
llama-server -m model.gguf -ngl 99 -fa on -c 131072 -np 4 \
--cache-type-k q8_0 --cache-type-v q8_0ใน issue นี้ให้ 1348 tokens/s ในการประมวลผลพรอมป์และ 30.1 tokens/s ในการ decoding (เพิ่มจาก 6.5) ราคาที่ต้องจ่ายคือหน่วยความจำ: แคช q8_0 ใหญ่กว่า q5_1 ดังนั้นตรวจสอบว่าความยาวคอนเท็กซ์ของคุณยังพอดีใน VRAM
ถ้าคุณจำเป็นต้องเก็บ q5_1 ไว้ด้วยเหตุผลด้านหน่วยความจำ ให้รีบิลด์โดยคอมไพล์ทุกชุดค่าผสมของแคช flash-attention ไว้:
cmake -B build -DGGML_CUDA=ON -DGGML_CUDA_FA_ALL_QUANTS=ON
cmake --build build --config Release -jบิลด์นั้นรัน q5_1 ที่ 1509.70 tokens/s บน pp512 และ 1162 tokens/s บนพรอมป์ 3.6K โทเคน โดย decoding ที่ 38.5 tokens/s มีผู้แสดงความคิดเห็นใน issue ชี้ว่าการย้ายงานระหว่างแบ็กเอนด์อาจเปลี่ยนผลลัพธ์เชิงตัวเลขเล็กน้อย และแนะนำให้เปรียบเทียบ perplexity ระหว่างบิลด์ ถ้าคุณใส่ใจผลลัพธ์ที่ตรงเป๊ะ ให้รันสักครั้ง
เปรียบเทียบ
วิธีแก้ไหนเหมาะกับการ์ดของคุณ?
แคช q8_0
เปลี่ยน --cache-type-k และ --cache-type-v เป็น q8_0 ไม่ต้องรีบิลด์ ใช้ VRAM มากกว่า q5_1 ดังนั้นตรวจสอบขนาดคอนเท็กซ์ที่ใส่ได้อีกครั้ง
รีบิลด์ด้วย FA_ALL_QUANTS
เก็บ q5_1 ไว้และบิลด์ด้วย - VRAM เท่าเดิม แต่คุณต้องดูแลบิลด์เองและคอมไพล์นานขึ้น
คำตอบ "known issue" ของผู้ดูแลไม่ได้บอกว่าเวอร์ชัน llama.cpp ปัจจุบันเปลี่ยนเรื่องนี้หรือไม่ การตรวจสอบที่ซื่อตรงคือคู่ llama-bench ด้านบน: ถ้าทั้งสองบรรทัดใกล้กัน คุณก็สบายใจได้
เมื่อการจูนไม่คุ้มอีกต่อไป#
สมมติคุณแก้ได้แล้ว และตอนนี้กำลังชั่งน้ำหนักรอบถัดไป: แฟล็กเพิ่ม, GPU ตัวที่สอง, quant ที่เล็กลง ถ้างานคือสรุป รีวิวโค้ด หรือสกัดข้อมูลบนพรอมป์ไม่กี่พันโทเคน ให้ถามว่าคำขอหนึ่งครั้งกินเวลาและแรงคุณเท่าไร ไม่ใช่แค่กินวัตต์
นี่คือเวิร์กโหลดที่ระบุไว้เพื่อเปรียบเทียบ สมมติงานสรุปส่ง 3,600 โทเคนอินพุตและได้กลับมา 500 โทเคน 1,000 ครั้ง บน CheapTokens นั่นประมาณ $0.104 บน DeepSeek-V4-Flash (คอนเท็กซ์ 380K, เอาต์พุตสูงสุด 32,768 โทเคนต่อคำตอบ, ราคาเดียวทุกชั่วโมง) และประมาณ $0.092 บน GLM-5.3-Flash (คอนเท็กซ์ 390K) ตารางนับอินพุตและเอาต์พุตรวมกัน พร้อมคอลัมน์ OpenRouter เพื่อเปรียบเทียบ:
| โมเดล | Input $/1M | Output $/1M | ต่อคำขอ | 1,000 คำขอ | OpenRouter, 1,000 คำขอ |
|---|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.000092 | $0.092 | $0.187 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.0001 | $0.104 | $0.249 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.00026 | $0.255 | $1.68 |
3,600 โทเค็นอินพุตและ 500 โทเค็นเอาต์พุตต่อคำขอ ราคาต่อ 1M โทเค็นเป็นราคาปัจจุบันและเปลี่ยนแปลงไปพร้อมกับอัตราค่าบริการของเรา คอลัมน์ OpenRouter แสดงราคาอ้างอิงสำหรับปริมาณงานเดียวกัน
API ไม่สนใจประเภทแคช, VRAM หรือแฟล็กบิลด์ของคุณ ไม่มีอะไรต้องตกไปที่ CPU ส่งพรอมป์จริงของคุณสักสองสามอันก่อนแล้วตัดสินคำตอบด้วยตัวเอง ขั้นตอนเล็กมาก: endpoint พูดรูปแบบ OpenAI Chat Completions ดังนั้นไคลเอนต์โลคอลส่วนใหญ่แค่ต้องเปลี่ยน base URL
curl https://api.cheaptokens.dev/v1/chat/completions \
-H "Authorization: Bearer $CHEAPTOKENS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "deepseek-ai/DeepSeek-V4-Flash-0731", "messages": [{"role": "user", "content": "Summarize the text below in 5 bullets: ..."}], "max_tokens": 500}'การตั้งค่าทั้งหมดอยู่ใน เอกสาร CheapTokens และราคาต่อโมเดลปัจจุบันอยู่ที่ หน้าราคา สำหรับมุมมองที่ยาวขึ้นเกี่ยวกับฮาร์ดแวร์เทียบกับ API ดู Run DeepSeek locally or use an API ถ้าคุณอยากเห็นว่าอินพุตและเอาต์พุตคิดเงินแยกกันอย่างไร input vs output tokens ครอบคลุมเรื่องนี้
ลำดับที่ควรทำ#
เรียงลำดับ
เรียงขั้นตอนการแก้ปัญหา
ลากรายการหรือใช้ลูกศร
- รัน llama-bench สำหรับ q8_0 และ q5_1 แล้วดู nvidia-smi
- เปลี่ยนประเภทแคชทั้งสองเป็น q8_0
- ตรวจสอบว่าความยาวคอนเท็กซ์ยังพอดีใน VRAM
- รีบิลด์ด้วย GGML_CUDA_FA_ALL_QUANTS=ON เฉพาะเมื่อคุณต้องการ q5_1
- เปรียบเทียบพรอมป์เดียวกันบน API ถ้าการตั้งค่าโลคอลยังไม่คุ้ม esfuerzo
ข้อควรระวังอีกอย่างเกี่ยวกับแหล่งข้อมูล: การวินิจฉัยทั้งหมดอาศัย issue สาธารณะหนึ่งอันและ GPU หนึ่งตัว มอง 1348 และ 38.4 เป็นสิ่งที่เกิดขึ้นที่นั่น และวัดการ์ดของคุณเองก่อนจะเชื่อตัวใดตัวหนึ่ง



