Orkun Soylu

3 dk okuma

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
Kısa prompt (21 tok)
19,85 tok/sQ8_0 · 19,85 tok/s
25,68 tok/sQ4_K_M · 25,68 tok/s
Uzun prompt (31.073 tok)
16,77 tok/sQ8_0 · 16,77 tok/s
20,75 tok/sQ4_K_M · 20,75 tok/s
Teorik tavan (864 GB/s ÷ ağırlık)
28,80 tok/sQ8_0 · 28,80 tok/s
48,70 tok/sQ4_K_M · 48,70 tok/s
Veri
Q8_0Q4_K_M
Kısa prompt (21 tok)19,85 tok/s25,68 tok/s
Uzun prompt (31.073 tok)16,77 tok/s20,75 tok/s
Teorik tavan (864 GB/s ÷ ağırlık)28,80 tok/s48,70 tok/s

Prefill, 31.073 token'lık prompt

yüksek olan iyi
  • Q8_0
  • Q4_K_M
Prefill
533,6 tok/sQ8_0 · 533,6 tok/s
498,0 tok/sQ4_K_M · 498,0 tok/s
Veri
Q8_0Q4_K_M
Prefill533,6 tok/s498,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 de keep_alive: 0 ile 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

  1. 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.
  2. 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ı.
  3. 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.
  4. 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ı.
  5. 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.
  6. 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.
  7. think hı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.