Qwen3.8-27B Q8_0 vs Q4_K_M
W7800'ümde Q8_0'dan Q4_K_M'e inmek %29 daha hızlı üretim ve 12 GB VRAM kazandırdı — bant genişliği hesabının vaat ettiğinden çok daha az — ve uzun prompt'ta prefill'i %7 yavaşlattı.
- Test tarihi
- Kurulum
Radeon Pro W7800 48 GB — fiziksel iş istasyonuFiziksel makine, Linux, ROCm (Ollama) · AMD Ryzen 5 7600 (6 çekirdek / 12 iş parçacığı, AVX-512) · 64 GB DDR5-6400
- Çalışma ortamı
- Ollama 0.32.14, ROCm 7.2.4, flash attention açık, q8_0 KV önbelleği, 262K bağlam
- Modeller
qwen3.8:27bQ8_0referans
qwen3.8:27bQ4_K_Mtest edilen
Karar
Q4_K_M'e VRAM için değer, hız için değil: üretim %24–29 kazanıyor, prefill biraz kötüleşiyor ve bağlam doldukça avantaj eriyor. Q8_0'daki 20 tok/s bu kartın düpedüz tavanı, arıza değil.
İşe yarayan
- −12 GB VRAM (262K'da 38 GB yerine 26 GB)
- Kısa prompt'ta üretim +%29, 31K token'da +%24
Yaramayan
- ~35 tok/s beklendi, 25,7 ölçüldü — bant genişliği verimi %69'dan %53'e düşüyor
- Prefill Q8_0'dan %7 yavaş (498'e karşı 534 tok/s)
- Bağlam doldukça daha çok yavaşlıyor (−%19'a karşı −%16)
- Üretim, Q8_0 → Q4_K_M
- 19,9 → 25,7tok/s
- Bant genişliği verimi
- %69 → %53
- 31K token prefill
- 534 → 498tok/s
- 262K'da VRAM
- 38 → 26GB
Üretim hızı
yüksek olan iyi- Q8_0
- Q4_K_M
Veri
| Q8_0 | Q4_K_M | |
|---|---|---|
| Kısa prompt (21 tok) | 19,85 tok/s | 25,68 tok/s |
| Uzun prompt (31.073 tok) | 16,77 tok/s | 20,75 tok/s |
| Teorik tavan (864 GB/s ÷ ağırlık) | 28,80 tok/s | 48,70 tok/s |
Prefill, 31.073 token'lık prompt
yüksek olan iyi- Q8_0
- Q4_K_M
Veri
| Q8_0 | Q4_K_M | |
|---|---|---|
| Prefill | 533,6 tok/s | 498,0 tok/s |
Neden ölçtüm
Günlük kullanımda qwen3.8:27b-q8_0 ~20 tok/s ile yavaş geliyordu. Bir sorun mu vardı, Q4_K_M bunu çözer miydi?
Nasıl ölçtüm
- Kısa prompt: 21 token (“bana bir python kod örneği yaz”), 2–3 tekrar.
- Uzun prompt: 99.000 karakterlik Türkçe dolgu metni ve bir talimat — 31.073 token (Türkçe, İngilizceden daha kötü token’a bölünüyor).
/api/chat,stream: false,think: false. Her ölçümden önce iki modeli dekeep_alive: 0ile boşalttım (30 + 18 GB birlikte sığmıyor).- İkisinde de KV önbelleği
q8_0. KV tipi ağırlık kuantizasyonuna bağlı değil, yani 31K token’da iki model de aynı bayt miktarında KV taşıyor. 5. maddede bunu hatırlayın.
Sonuçlar
| Q8_0 | Q4_K_M | |
|---|---|---|
| Diskteki ağırlık | 29,98 GB | 17,74 GB |
VRAM (ollama ps, bağlam 262.144) |
38 GB | 26 GB |
| Teorik tavan (864 GB/s ÷ ağırlık) | 28,8 tok/s | 48,7 tok/s |
| Üretim, kısa (21 tok) | 19,85 (19,9 / 19,8) | 25,68 (26,00 / 25,59 / 25,45) |
| Bant genişliği verimi (kısa) | %69 | %53 |
| Üretim, uzun (31.073 tok) | 16,77 | 20,75 |
| Uzun bağlamda yavaşlama | −%15,5 | −%19,2 |
| Prefill, uzun prompt | 533,6 tok/s (58,2 sn) | 498,0 tok/s (62,4 sn) |
| Toplam süre (uzun) | 67,8 sn | 69,5 sn |
Bulduklarım
- 20 tok/s arıza değil. %100 GPU, taşma yok, sıcaklıklar normal. Q8’de bir 27B token başına ~30 GB okuyor; 864 GB/s bunu 28,8 tok/s’de sınırlıyor ve %69 verim ROCm üzerinde llama.cpp için normal.
- Q4 tahminim tutmadı: ~35 bekledim, 25,7 çıktı. Hatam, Q8’deki %69 verimin aynen taşınacağını varsaymaktı.
Ağırlıklar küçüldükçe iş bant genişliğine bağlı olmaktan çıkıp ağırlıkları açmaya (dequantization) kayıyor ve
K-quant’ları (blok başına ölçek ve minimum) açmak Q8_0’ın
int8 × ölçek’inden çok daha pahalı. - Verim kuantizasyonla düşüyor. Aynı kart, aynı model, aynı motor: Q8_0 %69, Q4_K_M %53. Yalnızca kuantizasyonu ayıran ilk temiz ölçümüm bu oldu.
- Q4_K_M’de prefill aslında daha yavaş. Prefill hesaba bağlı (matris × matris: ağırlıklar bir kez okunup binlerce token için yeniden kullanılıyor); küçük ağırlığın yararı olmuyor, pahalı açma maliyeti ise yerinde duruyor. Üretim bant genişliğine bağlı (matris × vektör: her token’da bütün ağırlıklar yeniden okunuyor) — Q4’ün kazandığı yer orası.
- Q4’ün avantajı bağlam büyüdükçe eriyor. q8_0 KV trafiği iki modelde de aynı bayt; Q4’ün daha küçük token başı okumasında bu daha büyük bir pay tutuyor. Temmuz verisiyle çapraz kontrol: Qwen3.6-27B Q8_0 ~25K’da %14, Qwen3.8 31K’da %15,5 kaybediyor — kart ve yazılım tutarlı davranıyor.
- Bekleme prefill’de. 31K’da ilk token’dan önce 58–62 sn, sonra 85 token 5 sn’de. Bunu hiçbir kuantizasyon değişikliği çözmüyor; daha kısa prompt ya da önek önbelleği çözüyor.
thinkhızı değil, kaç token aldığınızı değiştiriyor. Aynı soru:think:false→ 572 token / 28,8 sn,think:true→ 1.263 token / 64,0 sn; ikisi de ~19,8 tok/s.
Bir projeksiyon (ölçülmedi): 2× W7800 ile BF16
Bu soru donanım planlarken aklıma geldi. llama.cpp/Ollama çoklu GPU’yu katman katman bölüyor; kartlar sırayla çalışıyor — bant genişlikleri toplanmıyor, süreler toplanıyor.
| Kurulum | Ağırlık | Etkin bant genişliği | Teorik | Beklenen |
|---|---|---|---|---|
| 1× W7800, Q8_0 | 30 GB | 864 GB/s | 28,8 | 19,9 (ölçüldü) |
| 1× W7800, Q4_K_M | 17,7 GB | 864 GB/s | 48,7 | 25,7 (ölçüldü) |
| 2× W7800, BF16, katman bölme | ~56 GB | 864 GB/s | 15,4 | ~10,5 |
| 2× W7800, BF16, tensör paralel (vLLM) | ~56 GB | 1.728 GB/s | 31 | RDNA3’te çalışırsa ~20–25 |
İkinci kart eklersem gerekçesi hassasiyet değil kapasite olmalı: 27B’de BF16 ile Q8_0 arasındaki kalite farkı gürültü düzeyinde.