Orkun Soylu

4 dk okuma

pi harness: Qwen3.8-27B Q4_K_M vs Q8_0

13 ajan koşumun 13'ü de hatayı düzeltti ya da özelliği yazdı; birebir eşleşmesi gereken düzenlemelerin hiçbiri başarısız olmadı. Q8_0 %78'e kadar yavaş ve daha isabetli değil. Beklemenin neredeyse tamamı prompt'u yeniden okumaya gitti.

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ı
pi v0.84.2 → Ollama (OpenAI uyumlu API)
Modeller

qwen3.8:27bQ4_K_Mtest edilen

qwen3.8:27bQ8_0test edilen

Karar

pi ile yerel bir yoğun 27B, küçük ve iyi tarif edilmiş işler için çalışan bir kod ajanı. Q4_K_M kullanın — Q8_0 zaman ve VRAM yiyor, isabet kazandırmıyor. Bağlamı kısa tutun: her tur bütün konuşmayı yeniden okuyor.

İşe yarayan

  • 13/13 koşu testleri geçti; 32 birebir eşleşmeli düzenleme bloğunun 0'ı başarısız
  • Kolay kaçış olmasına rağmen hiçbir koşu tests/'e dokunmadı
  • pi'ın bütün prompt'u + araç şemaları 1.917 token — 27B için yeterince hafif

Yaramayan

  • İzin sistemi yok — ajan, onu başlatan kullanıcının bütün yetkileriyle çalışıyor
  • O sırada Ollama'da prompt önbelleği yoktu: görev başına 17–25K token yeniden işlendi
  • Dar bir test: küçük Python projesi, kısa oturumlar
Geçen koşu
13 / 13
Başarısız düzenleme
0 / 32
Görev A süresi, Q4 / Q8
50 / 89sn
Prompt + araç yükü
1.917token

Görev başına ortalama süre

düşük olan iyi
  • Q4_K_M
  • Q8_0
Görev A — hata düzeltme
50 snQ4_K_M · 50 sn
89 snQ8_0 · 89 sn
Görev B — çok dosyalı özellik
85 snQ4_K_M · 85 sn
114 snQ8_0 · 114 sn
Veri
Q4_K_MQ8_0
Görev A — hata düzeltme50 sn89 sn
Görev B — çok dosyalı özellik85 sn114 sn

Bağlama göre prefill süresi (Q4_K_M)

düşük olan iyi

Oturum büyüdükçe ajan turları neden yavaşlıyor

468 token
0,9 snPrefill süresi · 0,9 sn
3,6K token
5,9 snPrefill süresi · 5,9 sn
14,6K token
20,8 snPrefill süresi · 20,8 sn
29,1K token
33,7 snPrefill süresi · 33,7 sn
58,2K token
87,4 snPrefill süresi · 87,4 sn
Veri
Prefill süresi
468 token0,9 sn
3,6K token5,9 sn
14,6K token20,8 sn
29,1K token33,7 sn
58,2K token87,4 sn

pi nedir

pi, MIT lisanslı bir TypeScript ajan harness’ı (~250K satır, 453 test dosyası). Sağlayıcı katmanı ~40 sağlayıcının tuhaflıklarını veri olarak tutuyor — bağlam taşmasının tespiti bile sağlayıcı başına bir regex tablosu. Bilerek olmayanlar: MCP, alt ajanlar, izin soruları, plan modu, yapılacaklar listesi, arka plan bash’i. Elinizde yedi araç var — bash read write edit ls grep find — gerisi eklenti.

İzin sistemi yok. pi, onu başlatan kullanıcının bütün yetkileriyle çalışıyor; onay sorusu yok, dosya, süreç, ağ ya da kimlik bilgisi kısıtı yok. Bir container’da ya da ayrı bir VM’de çalıştırın — bu bir incelik değil, ön koşul.

Nasıl test ettim

pi’ı yalıtılmış bir npm önekine kurdum, yapılandırmasını PI_CODING_AGENT_DIR ile başka yere yönlendirdim. Modeli OpenAI uyumlu bir sağlayıcı olarak ekledim (supportsDeveloperRole: false, thinkingFormat: qwen-chat-template, sıcaklık 0,7, top_p 0,8, top_k 20).

Cevabı objektif olan iki görev seçtim — karar pytest’in, benim değil — ve çalışma ağacını her koşudan önce git checkout ile sıfırladım.

  • Görev A — hata avı. 5 testli küçük bir Python projesi, biri düşüyor: largest_debit() worst_value = Decimal("0") ile başlıyor, bu yüzden bütün bakiyeler pozitifken None dönüyor. Ancak testi okuyunca fark edilen tek satırlık bir mantık hatası.
  • Görev B — çok dosyalı özellik. Henüz var olmayan bir özelliği tarif eden 6 test: Entry dataclass’ına yeni bir alan, değişen bir post() imzası, Ledger.balance_as_of() ve report.monthly_summary() — iki dosyada birbirine bağlı dört değişiklik.

İki projenin AGENTS.md’si de “tests/ altını değiştirme” diyordu; her edit/write çağrısının hedef yolunu kontrol ettim.

Sonuçlar

Görev Model Koşu Geçen Ort. süre Ort. tur Ort. araç çağrısı Yeniden işlenen girdi
A (hata) Q4_K_M 5 5/5 50 sn 5,6 6,4 17,6K tok
B (özellik) Q4_K_M 3 3/3 85 sn 5,3 7,3 19,6K tok
A (hata) Q8_0 3 3/3 89 sn 7,0 8,3 25,4K tok
B (özellik) Q8_0 2 2/2 114 sn 5,0 7,5 19,3K tok

Yanıldığım tahmin: birebir eşleşmeli edit

Ölçmeden önce, birebir metin isteyen edit aracının bir 27B’nin tökezleyeceği yer olacağından emindim — boşluk kayması, bayat oldText, tekrar denemeler. Gerçekte olan: 13 koşuda 32 düzenleme bloğu, sıfır başarısızlık. Görev B’de model üç değişikliği blok dizisiyle tek bir edit çağrısında gönderdi ve hepsi uygulandı.

Düzenleme hataları model boyutunu değil bağlamın ne kadar taze olduğunu izliyor gibi: pi modele dosyayı düzenlemeden hemen önce okutuyor, araya da pek bir şey girmiyor. Uzun, dağınık oturumlar farklı davranabilir.

Yamaların kalitesi

Görev A’nın beş koşusu da birebir aynı yamayı üretti — üstelik artık yanlış hâle gelen docstring’i de düzeltti:

-    """Return the account with the most negative balance, or None if empty."""
+    """Return the account with the lowest balance, or None if empty."""
-    worst_value = Decimal("0")
+    worst_value = None
-        if value < worst_value:
+        if worst_value is None or value < worst_value:

Q8_0 daha iyi değil, yalnızca daha pahalı

Q4_K_M Q8_0
VRAM 26,8 GB 38,2 GB
Görev A ortalaması 50 sn 89 sn
Görev B ortalaması 85 sn 114 sn
İsabet 8/8 5/5

Bir Q8 koşusu testler zaten geçtikten sonra iki kozmetik düzenleme daha yaptı — bu kalite değil, gevezelik.

Bekleme nereye gidiyor

pi’ın sistem prompt’u + 7 araç şeması + projenin AGENTS.md’si + görev = 1.917 token. Ağır bir kod asistanı aynı noktada 10–15K taşıyor; bir 27B için bu büyük fark. Ama Ollama’da prompt önbelleği yoktu, yani her tur bütün konuşmayı yeniden işledi: girdi turdan tura 1,9K’dan 3,4K’ya büyüyor ve görev başına 17–25K token yeniden okunuyor.

Bağlam Prefill Üretim
468 tok 0,9 sn (517 tok/s) 25,9 tok/s
3,6K tok 5,9 sn (623 tok/s) 25,6 tok/s
14,6K tok 20,8 sn (702 tok/s) 23,6 tok/s
29,1K tok 33,7 sn (865 tok/s) 21,3 tok/s
58,2K tok 87,4 sn (666 tok/s) 17,9 tok/s

Yerel bir ajanı hızlandırmanın yolu daha hızlı bir GPU değil, daha kısa bir bağlam: erken sıkıştırın, görevi dar tanımlayın, gereksiz dosya okumalarını atlayın. 60K’da her tur bir buçuk dakika prefill.

Düştüğüm iki tuzak

  • pi -p stdin açıkken bloke oluyor. İlk toplu koşum on dakika tek satır yazmadan asılı kaldı; </dev/null ile aynı iş 38 sn’de bitti. Cron/CI’da stdin’i kapatın.
  • pgrep -f kendini buluyor. Bekleme döngüm pgrep -f "run.sh taskA" kullanıyordu; kendi komut satırıyla eşleşti ve 59 dakika kendini bekledi. Desenle değil, PID ile bekleyin (kill -0 $PID).

Test etmediklerim

Uzun oturumlar, sıkıştırma sonrası davranış, büyük bir kod tabanında yolunu bulmak ve pi’ın asıl iddiası — kendi TypeScript eklentilerini yazmak.