Fix VRAM usage increase on HIP/ROCm with RDNA3 and possibly more - #71
Closed
stragulus wants to merge 2 commits into
Closed
Fix VRAM usage increase on HIP/ROCm with RDNA3 and possibly more#71stragulus wants to merge 2 commits into
stragulus wants to merge 2 commits into
Conversation
having to dequantize the entire kv cache, thus preserving vram memory
… this commit fixes. 1. fattn-common.cuh sinks fix: Only pass in sinks on the first batch call 2. fattn-vec.cuh mask stride fix: align with how fattn-tile and fattn-wmma already compute the mask row stride.
Author
|
I had to wipe out my fork as it somehow blocked forking llama.cpp itself - since these changes are not related to the turbo quants themselves and are a pre-existing issue in llama.cpp, I will instead add the PR there. ggml-org#19979 |
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Jul 20, 2026
Die 'Priorisierung nach Cost-Benefit' Sektion listete noch M1-M4 Items als 'Sofort umsetzbar' obwohl alle ✅/❌ sind. Aktualisiert auf M6 (Forschung): - Tier 2: AtomicBot-ai#36 Auto Parameter Fitting TP (einziger offener Tier-2-Item) - Tier 3: 11 Items nach Cost-Benefit sortiert (AtomicBot-ai#73, AtomicBot-ai#72, AtomicBot-ai#71, TheTom#76, ...) - Tier 4: 15 Forschungs-Items (3+ Monate Solo-Agent) - Verschobene Items (⏭️) mit Re-Eval-Hinweisen Header-Datum auf 2026-07-19 aktualisiert.
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Jul 20, 2026
…cBot-ai#71 CPU-GPU MoE ⏭️ Tiefen-Evals 3 parallele Tiefen-Evals für Tier-3 Items: AtomicBot-ai#73 CascadeInfer (arXiv:2512.19179) ❌ VERWORFEN: - Multi-Instance-Cluster-Scheduler für vLLM (3000 LoC Python + 700 C++) - Fork ist Single-Instance, Architektur-Mismatch fundamental - 67% Latenz-Reduktion nur unter Cluster-Load (16+ GPUs) - Kein Host im LAN hat Multi-Instance-Setup - Kein Referenzcode, Aufwand 2-3 MONATE nicht 2-3 Wochen AtomicBot-ai#72 N4_0 Native 4-bit Float (PR ggml-org#23572) ❌ VERWORFEN: - PR stale (7 Wochen, kein Maintainer-Approval, NVFP4-Experte lehnt ab) - N4_0 ist nur CLI-Alias für NVFP4 (6 Zeilen), kein neues Feature - Backend-Infrastruktur existiert bereits im Fork - Zero Hardware-Benefit: Kein Blackwell im Fleet (FP4 MMA nur RTX 50xx) - Auf Ada/Ampere: DP4A-Fallback, Accuracy-Regression vs Q4_0 - Reaktivierung: 30 Min Cherry-Pick wenn Blackwell-Host kommt AtomicBot-ai#71 Efficient CPU-GPU Collaborative MoE (arXiv:2512.16473) ⏭️ SPÄTER: - Fork hat bereits 1883-Zeilen MoE-Cache (moe-cache.cu) - AtomicBot-ai#71 ist Upgrade auf set-associative (N×M), kein Neubau - Aufwand revidiert: 3-4 Wochen → 2 Wochen (CUDA-only) - Styx + Hydra profitieren (8GB VRAM, PCIe-Bottleneck) - Bedingung: erst nach AtomicBot-ai#69 Heuristic-Benchmark (Konfundierung vermeiden) - Referenzcode: github.com/elsa-lab/MoE-CPU-GPU-Collaborative-Inference (MIT, PyTorch) Priorisierung aktualisiert: 9 offene Tier-3 Items statt 11.
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Jul 20, 2026
…efen-Evals — Tier-3 komplett Letzte 2 Tiefen-Evals für Tier-3 Items: AtomicBot-ai#43 SliderQuant (Sliding-layer PTQ) ⏭️ SPÄTER (conditional): - PTQ, Fork nutzt QAT Q4_K_XL (methodisch überlegen, wie AtomicBot-ai#22 GWQ) - Referenzcode vorhanden (github.com/deep-optimization/SliderQuant, PyTorch) aber hilft nicht beim C++/Vulkan-Port - Vulkan-Kernel-Neuentwicklung hochriskant für Mars/Venus - Hardware-Relevanz niedrig: QAT löst Low-Bit-Druck bereits - Aufwand revidiert: 4-6 → 6-10 Wochen - Reaktivierung nur bei QAT-Lücke für spezifisches Zielmodell AtomicBot-ai#44 Alloc-MoE (Budget-aware Expert Activation) ☐ MACHBAR GESTAFFELT: - Alloc-L (Layer-Level, DP + Sensitivity-Profiling) ist MVP mit 3-4 Wochen - Alloc-T (Token-Level) bringt bei Decode T=1 nichts — 1.34× decode-Speedup stammt aus Alloc-L (reduziertes K), nicht Alloc-T - Synergie mit AtomicBot-ai#40 (Freq-Tracking als Input) und AtomicBot-ai#62 (Profiler-Infra) - Kein Konflikt mit moe-cache.cu (synergistisch) - Styx profitiert klar (CPU-bound → halbe Aktivierungen = halbe CPU-Last) - RISIKO: 17% Quality-Drop bei K=2 (Gemma 4 A4B) — Quality-Benchmark vor Go - Aufwand revidiert: 6-8 → 3-4 Wo (Phase 1) / 7-9 Wo (voll+Vulkan) Tier-3 Tiefen-Evals KOMPLETT (11/11 Items): - ☐ Machbar: AtomicBot-ai#71, AtomicBot-ai#44, AtomicBot-ai#18 (gestaffelt, mit Solo-Plan) - ⏭️ Später: TheTom#76, AtomicBot-ai#75, AtomicBot-ai#23, AtomicBot-ai#43 (Abhängigkeiten/Risiko) - ❌ Verworfen: AtomicBot-ai#73, AtomicBot-ai#72, AtomicBot-ai#74, AtomicBot-ai#22 (Architektur/Redundanz/QAT-Konflikt) Priorisierung aktualisiert: 3 machbare + 4 spätere + 4 verworfene.
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Jul 20, 2026
Styx Benchmark 2026-07-21 (GTX 1070, 26B-A4B QAT, -ncmoe 20, turbo3/4, FA, Budget=512MB, Reserve=256MB): | Policy | tg128 t/s | Hit-Rate | Slots | |-----------|-----------------|----------|-------| | LRU | 28.16 ± 0.92 | 39.7% | 320 | | Heuristic | 27.28 ± 0.75 | 39.9% | 320 | Heuristic -3.1% langsamer als LRU, 5%-Schwelle deutlich verfehlt. Hit-Rate identisch → Heuristic trifft dieselben Eviction-Entscheidungen wie LRU auf diesem Workload. Root Cause: α=0.7/β=0.3 Frequency korreliert stark mit Recency auf tg128-Runs. Paper's 2.6× bezieht sich auf SSD-Offloading (nicht CPU-Offload wie Styx) — Hebel kleiner. Phase 2 (FlashMoE FFN) ❌ verworfen — wenn schon einfache Heuristic kein Win, ist FFN-Version skeptisch. AtomicBot-ai#69 → ❌. Voraussetzung für AtomicBot-ai#71 (CPU-GPU Collaborative MoE) und AtomicBot-ai#18 (DALI Cache-Policy) erfüllt — beide können jetzt starten. Throttle=1 → Bail-out für beide Policies bestätigt (Cache-Overhead > CPU-Path bei 1.3-1.6ms vs 540-615us pure-CPU).
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Jul 20, 2026
N-index M-way set-associative cache für moe-cache.cu. - Voraussetzung (AtomicBot-ai#69 Benchmark) erfüllt (2026-07-21: ❌ NO-GO) - 2 Wochen Aufwand, CUDA-only (Styx/Hydra) - MIT-Referenzcode (github.com/elsa-lab/MoE-CPU-GPU-Collaborative-Inference) - 4 Phasen: Design (2-3d), Impl (4-5d), Bench (3-4d), Doku (1-2d) - Go/No-Go-Gate: >5% Speedup vs LRU - Trilium: Note 0PCCcdM2WgpJ (M6 Tier-3 Evals), TTT 2026-07-21
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Aug 2, 2026
… Cache — ❌ NO-GO Implementiert set-associative Cache (POLICY_SET_ASSOC_LRU) als neue Eviction-Policy in moe-cache.cu. N×M Slots mit LRU pro Set, Hash-basiertes Set-Mapping (key % n_sets). Env-Vars: GGML_CUDA_MOE_CACHE_POLICY=set-assoc-lru + GGML_CUDA_MOE_CACHE_SET_WAYS=M (Default 4). Benchmark auf hydra (RTX 3070, 8GB, 26B-A4B QAT, -ngl 0): - 512MB (160 slots): LRU tg64=1.90, 40×4=1.42 (-25%), 80×2=0.94 (-50%), 20×8=1.13 (-41%) - 1024MB (320 slots): LRU tg128=1.36, 80×4=1.34 (-1.5% Rauschen), 40×8=1.35 (-0.7% Rauschen) Go/No-Go >5% → ❌ NO-GO. Root Cause: 128 Experten × 30 Layer = 3840 Entries → 160-320 Slots = starke Oversubscription. Fully-associative LRU hat keine Conflict-Misses, Set-assoc restrictiert Placement. HashMap O(1) nicht Bottleneck (PCIe dominiert). Paper's 4.4× war RTX 4090 + SSD-Offloading. Code bleibt als POLICY_SET_ASSOC_LRU (Default OFF) für Modelle mit wenigen Experten (≤16). ROADMAP AtomicBot-ai#71 → ❌.
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Aug 2, 2026
… ❌ NO-GO Implementiert sliding-window workload accumulation (DALI Phase 1) als neue Eviction-Policy. Windowed frequency pro Slot, periodic reset nach wsize plan()-Calls, evict slot mit niedrigstem workload_score. Env-Vars: GGML_CUDA_MOE_CACHE_POLICY=workload + GGML_CUDA_MOE_CACHE_WSIZE=N (Default 32). Benchmark auf hydra (RTX 3070, 8GB, 26B-A4B QAT, -ngl 0): - n=128 r=3: LRU tg128=2.19, Workload=3.97 (+81%) — Artefakt (Discovery-Phase) - n=256 r=5: LRU tg256=4.42, Workload=4.53 (+2.5%), Heuristic=4.50 (+1.8%) - n=512 r=5: 512MB: Workload=4.40 (-1.1%); 1024MB: Workload=4.54 (+0.4% Rauschen) Go/No-Go >5% → ❌ NO-GO. Root Cause: 128 Experten × 30 Layer = 3840 Entries → 160-320 Slots = 24:1 Oversubscription. Eviction-Policy nicht Bottleneck (PCIe dominiert). LRU ist 'good enough'. MoE-Cache-Thema für 128-Expert-Modelle erschöpft: AtomicBot-ai#69 Heuristic ❌, AtomicBot-ai#71 Set-Assoc ❌, AtomicBot-ai#18 Workload-Aware ❌ Code bleibt als POLICY_WORKLOAD (Default OFF). ROADMAP AtomicBot-ai#18 → ❌.
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Aug 2, 2026
…ommen 4 Eviction-Policies dokumentiert: LRU (Default), Heuristic, Set-Associative, Workload-Aware. Env-Vars und ROADMAP-Referenzen (AtomicBot-ai#18/AtomicBot-ai#69/AtomicBot-ai#71) eingetragen.
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Aug 2, 2026
… ROADMAP P1 AtomicBot-ai#3: Pool-Alloc in moe_cache_begin unter g.mu Lock — verhindert Data Race mit Worker/Backfill-Threads die d.pools[pi] lesen. cudaMalloc unter Lock akzeptabel (nur bei Pool-Erstellung, nicht im Hot Path). P2: Workload-Eviction Tie-Breaker — bei gleichem workload_score den LRU- ältesten Slot evicten (cur_tick - last_access). Verhindert deterministische Slot-0-Eviction nach Window-Reset. P3: ROADMAP 'MoE-Cache erschöpft' Sektion — fasst AtomicBot-ai#69/AtomicBot-ai#71/AtomicBot-ai#18 Ergebnisse zusammen. LRU ist optimal bei 128-Expert 24:1 Oversubscription.
fukuro-kun
referenced
this pull request
in fukuro-kun/fukuro-llama-cpp-turboquant
Aug 2, 2026
…i#18/AtomicBot-ai#44 ❌ NO-GO Cleanup -358 Zeilen experimenteller Code aus 3 ❌ NO-GO Experimenten entfernt: AtomicBot-ai#71 POLICY_SET_ASSOC_LRU: N-index M-way set-associative Cache (-25% bis -50%) AtomicBot-ai#18 POLICY_WORKLOAD: DALI workload-aware windowed-frequency Cache (±0%) AtomicBot-ai#44 LLAMA_MOE_K_OVERRIDE: K-Reduktion (+13.5% PPL bei K=6) Entfernt: - enum eviction_policy: POLICY_SET_ASSOC_LRU, POLICY_WORKLOAD - struct moe_cache_slot: workload_score Feld - struct moe_cache_pool: n_sets, n_ways, set_lru_head/tail, set_n_used, window_count - struct moe_cache_global: set_assoc_ways, workload_wsize - Set-associative LRU-Helfer (moe_cache_set_idx, set_lru_remove, set_lru_push_back) - Workload Reset-Logik und Workload-Eviction-Zweig - Env vars: GGML_CUDA_MOE_CACHE_SET_WAYS, GGML_CUDA_MOE_CACHE_WSIZE - GGML_CUDA_MOE_CACHE_POLICY: set-assoc-lru und workload cases - src/llama-model.cpp: LLAMA_MOE_K_OVERRIDE Block Behalten: - POLICY_LRU (default, funktioniert) - POLICY_HEURISTIC (bestehend, funktioniert) - Grundlegende Cache-Infrastruktur (slots, map, lru_head/tail, freq, last_access) - Prefetch/backfill/worker Logik Build grün auf Hydra. MoE-Cache initialisiert korrekt mit LRU-Policy.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Fixes unbounded VRAM usage growth when using flash attention and quantized kv cache types on HIP/ROCm with RDNA3 architecture (and possibly more)
Additional details
This PR batches flash attention kernel invocation with a fixed size batch when quantized kv cache types are used. Without this change, the kernels would increasingly allocate more vram as they require the entire kv cache to be dequantized to f16 types. A compounding problem existed when using the legacy memory pool ggml_cuda_pool_leg (e.g. when using HIP with at least RDNA3). The memory pool allocates fragments of a fixed size, and allocation requests use a best-fit algorithm. Allocation requests that don't fit into any of the existing individual fragments trigger allocation of a new fragment. The pool never deallocates fragments until the pool itself is destructed. Due to the ever-growing sizes of the allocation requests, new allocations would not fit in a previously created fragment, thus another new fragment would be allocated. This rapidly consumes more and more vram, completely cancelling out any benefit to be had from using quantized kv cache types for non-synthetic workloads.
The VEC flash attention kernel solves this by dequantizing the kv cache entries one by one instead of all in advance. Simple, however, this has a very significant impact on prompt processing speed (easily ~50% reduction compared to the other kernels like TILE). While this does completely solve the growing vram usage problem, the performance impact is not acceptable.
Thus, I chose a hybrid solution where we don't fall back to slow VEC, but instead the flash attention kernel calls are batched with a maximum batch size if quantized kv types are used. The code will choose the previous unbatched path for maximum performance if batching is not required. Benchmarks show that prompt processing speeds for a 30k prompt and turbo3 k/v types are ~700 tokens per seconds, versus ~3xx tokens/sec when using the VEC kernel. VRAM usage stays stable, also tested with a 120k bench that shows 0 new allocations after prompt processing starts.
Token generation speed should be unaffected by these changes.
This SHOULD work on the other flash attention kernels as well, but I did not test this.
Passed basic coding challenge using opencode against llama-server with turbo3/turbo3 k/v quants
Tested on an arch linux system with a 7900 XTX/24GB and rocm-7.2.1
Benchmarks
Before changes:
VRAM flat at 18024
| qwen35 27B Q4_K - Medium | 15.39 GiB | 26.90 B | ROCm | 100 | 1 | pp30000 | 695.04 ± 0.00 |
| qwen35 27B Q4_K - Medium | 15.39 GiB | 26.90 B | ROCm | 100 | 1 | tg128 | 27.92 ± 0.00 |
VRAM usage stable at 17124MB
| qwen35 27B Q4_K - Medium | 15.39 GiB | 26.90 B | ROCm | 100 | q8_0 | q8_0 | 1 | pp30000 | 698.56 ± 0.00 |
| qwen35 27B Q4_K - Medium | 15.39 GiB | 26.90 B | ROCm | 100 | q8_0 | q8_0 | 1 | tg128 | 28.82 ± 0.00 |
VRAM stable at 16508MB
| qwen35 27B Q4_K - Medium | 15.39 GiB | 26.90 B | ROCm | 100 | turbo3 | turbo3 | 1 | pp30000 | 675.35 ± 0.00 |
| qwen35 27B Q4_K - Medium | 15.39 GiB | 26.90 B | ROCm | 100 | turbo3 | turbo3 | 1 | tg128 | 27.47 ± 0.00 |