Mereduksi Context Window Drifting: Strategi KV-Cache Pruning pada Arsitektur Transformer Modern
Ada ilusi kenyamanan yang berbahaya ketika kita disodori angka spesifikasi model bahasa generasi terbaru: 128k, 1M, bahkan 2M token context window. Di atas kertas, batas komputasi seolah telah runtuh. Kita membayangkan bisa memasukkan seluruh repositori kode, puluhan dokumen legal ratusan halaman, atau transkrip percakapan berbulan-bulan tanpa kehilangan satu detail pun.
Namun, siapa pun yang pernah menjalankan sesi interaksi panjang pada beban produksi tahu ada jurang menganga antara klaim teoritis dan kenyataan operasional.
Pada token ke-4.000, model merespons dengan presisi seorang dokter bedah. Menginjak token ke-35.000, nada jawabannya mulai mengambang. Menjelang token ke-80.000, model tersebut sering kali mengalami apa yang di kalangan periset disebut sebagai Context Window Drifting—sebuah kondisi ketika reasoning engine kehilangan daya cengkeram atas instruksi awal, terdistraksi oleh noise di tengah dokumen, mengabaikan batasan sistem (system prompt), dan perlahan berhalusinasi.
Masalah ini bukan sekadar persoalan kapasitas memori grafis (VRAM) yang terancam jebol oleh akumulasi Key-Value (KV) cache. Masalah utamanya jauh lebih fundamental: entropi distribusi perhatian (attention distribution entropy) yang terdispersi secara berlebihan.
Ketika matriks softmax dipaksa membagi bobot probabilitasnya ke puluhan ribu token yang tidak relevan, sinyal krusial tenggelam dalam kebisingan statistik. Menumpuk seluruh riwayat interaksi ke dalam memori tanpa seleksi bukanlah strategi cerdas; itu adalah bentuk penimbunan data (data hoarding) yang merusak penalaran.
1. Anatomi Kerusakan: Mengapa Jendela Panjang Menumpulkan Penalaran?
Untuk memahami mengapa model "kehilangan akal" di tengah sesi panjang, kita perlu membedah dua fenomena komputasi yang saling berkelindan: Attention Dilution dan KV-Cache Bloat.
[Prompt Awal / System Directive] ────┐
├──> (High Weight / Sinks)
[Histori Percakapan Lama(Noise)] ───┼──> Attention Dilution(Softmax terbagi rata)
│ └── Bobot instruksi inti tergerus tipis
[Pertanyaan User Saat Ini] ──────────┘Fenomena Attention Dilution
Mekanisme Scaled Dot-Product Attention standar bekerja dengan rumus:$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$
Ketika urutan sequence ($N$) membengkak, penyebut pada operasi softmax mengakumulasi eksponensial dari ribuan nilai dot-product:
$$\text{softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{N} e^{z_j}}$$
Meskipun model telah dilatih dengan positional embedding modern seperti RoPE (Rotary Position Embedding) dengan modifikasi base frequency ($\theta$), penyebaran massa probabilitas melintasi puluhan ribu token menyebabkan nilai atensi pada token-token krusial menyusut drastis. Fenomena ini diperparah oleh efek Lost in the Middle, di mana LLM secara inheren memberikan bobot lebih tinggi pada awal (primacy) dan akhir (recency) konteks, sementara data di kuadran tengah terdegradasi menjadi sekadar beban komputasi.
Beban Linear-to-Quadratic pada VRAM
Setiap token yang diproses selama fase pre-filling dan autoregressive decoding harus menyimpan representasi vektor Key ($K$) dan Value ($V$) pada setiap layer transformer.Untuk model berbobot 70 Miliar parameter (misalnya Llama 3 70B dengan Grouped-Query Attention / GQA):
- Jumlah Layer ($L$) = 80
- Key/Value Heads ($H_{kv}$) = 8
- Head Dimension ($d_h$) = 128
- Presisi = FP16 (2 byte per parameter)
Memori KV-Cache per token dihitung sebagai:
$$\text{Memori per token} = 2 \times L \times H_{kv} \times d_h \times \text{bytes} = 2 \times 80 \times 8 \times 128 \times 2 \approx 327.680 \text{ byte } (\approx 320\text{ KB/token})$$
| Panjang Konteks ($N$) | Memori KV-Cache (Batch Size = 1) | Memori KV-Cache (Batch Size = 16) |
|---|---|---|
| 8.192 token | 2,56 GB | 40,96 GB |
| 32.768 token | 10,24 GB | 163,84 GB |
| 65.536 token | 20,48 GB | 327,68 GB |
| 131.072 token | 40,96 GB | 655,36 GB |
Pada konkurensi produksi dengan concurrency 16 request pada 128k token, kita membutuhkan lebih dari 650 GB VRAM hanya untuk menyimpan KV-cache, belum menghitung bobot model itu sendiri. Tanpa intervensi, latensi Time-to-First-Token (TTFT) dan Inter-Token Latency (ITL) meroket tajam akibat memory-bound bottleneck.
2. Paradigma KV-Cache Pruning: Memilah Sinyal dari Derau
Menghadapi keterbatasan fisik ini, komunitas engineering bergeser dari pendekatan brute-force hardware menuju optimasi komputasi yang lebih elegan: KV-Cache Pruning.
Filosofi dasarnya sederhana: Tidak semua token diciptakan setara.
Jika kita menganalisis peta atensi (attention maps) pada layer transformer yang dalam, sebagian besar matriks didominasi oleh nilai mendekati nol. Hanya sebagian kecil token yang secara konsisten menerima fokus atensi lintas layer dan timestep.
Token Index -> [0] [1] [2] [3] ... [N-2] [N-1] [N]
Layer 1 Attention: [██] [ ] [ ] [██] ... [ ] [██] [██]
Layer 16 Attention: [██] [ ] [ ] [ ] ... [ ] [██] [██]
Layer 32 Attention: [██] [ ] [ ] [██] ... [ ] [██] [██]
▲ ▲ ▲
│ │ └── Local Window(Recency)
Attention Sinks Heavy HittersTerdapat tiga kategori token esensial yang wajib dipertahankan dalam KV-Cache:
- Attention Sinks (Token Awal): Token pertama (seperti
<s>, token sistem) yang menyerap bobot atensi masif tak berdasar semantik hanya sebagai penstabil numerik softmax. Jika token ini dibuang, performa model langsung hancur (perplexity collapse). - Heavy Hitters (H2): Token-token yang secara akumulatif mengumpulkan skor atensi tertinggi dari token-token generasi setelahnya (biasanya kata benda, variabel kode, entitas utama).
- Local Window (Recency Cache): $K$ token terakhir sebelum token saat ini, yang menjaga kelancaran gramatikal dan konteks jangka pendek terdekat.
3. Taksonomi Strategi: Membandingkan Pendekatan State-of-the-Art
Berbagai metode pruning telah diusulkan untuk mengeksekusi seleksi ini saat inferensi (inference-time dynamic pruning) tanpa perlu melatih ulang (re-training) model dasar.
┌─────────────────────────────────────┐
│ KV-Cache Pruning Taxonomy │
└──────────────────┬──────────────────┘
│
┌───────────────────────────┴───────────────────────────┐
▼ ▼
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ Eviction-Based Policies │ │ Observation-Window Policies │
│ (Token-level Dynamic Drop) │ │ (Cluster & Head Truncation) │
└────────────────┬────────────────┘ └────────────────┬────────────────┘
│ │
┌─────────┴─────────┐ ┌─────────┴─────────┐
▼ ▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│Streaming │ │ H2O │ │ SnapKV │ │ PyramidKV │
│ LLM │ │ (Heavy │ │ (Cluster │ │ (Layer- │
│ (Sink+Win)│ │ Hitters) │ │ Voting) │ │ Adaptive) │
└───────────┘ └───────────┘ └───────────┘ └───────────┘StreamingLLM: Stabilisasi Window dan Attention Sink
StreamingLLM membuktikan bahwa model bahasa autoregresif dapat mempertahankan perplexity yang stabil pada sequence tanpa batas ($N \to \infty$) hanya dengan mempertahankan 4 token pertama (attention sinks) digabungkan dengan rolling local window (misal 2.048 token terakhir).Metode ini luar biasa efisien untuk conversational streaming, namun memiliki kelemahan fatal: ia sepenuhnya buta terhadap fakta spesifik yang terletak di luar local window jika fakta tersebut tidak berada di 4 token pertama.
Heavy Hitter Oracle (H2O)
H2O memelihara skor akumulatif dari matriks atensi. Token yang tidak lagi memberikan kontribusi pada skor atensi kumulatif dalam $M$ langkah terakhir akan diejeksi (evicted) dari memory buffer. Pendekatan ini dinamis dan menjaga integritas reasoning jauh lebih baik daripada fixed sliding window.SnapKV: Ekstraksi Pola Atensi Pre-filling
SnapKV melakukan observasi pada fase pre-fill. Saat memproses dokumen panjang, SnapKV mengamati kepala atensi (attention heads) pada beberapa token fitur di ujung prompt, mengidentifikasi posisi-posisi penting di seluruh teks, lalu langsung memangkas KV-cache sebelum decoding dimulai. Hasilnya: kompresi hingga 80-90% dengan degradasi skor akurasi di bawah 1-2%.Tabel Komparasi Teknis Metode Pengelolaan KV-Cache
| Parameter Evaluasi | Vanilla Attention | StreamingLLM | H2O (Heavy Hitter) | SnapKV | PyramidKV |
|---|---|---|---|---|---|
| Kompleksitas Memori | $\mathcal{O}(N)$ tak terbatas | $\mathcal{O}(W + S)$ konstan | $\mathcal{O}(K)$ terikat | $\mathcal{O}(K)$ terkompresi | $\mathcal{O}(K)$ piramidal |
| Retensi Detail Tengah | Tinggi (tapi drifting) | Nol (di luar window) | Tinggi (selektif) | Sangat Tinggi | Luar Biasa |
| Overhead Komputasi | Rendah (tidak ada pruning) | Sangat Rendah | Sedang (tracking skor) | Rendah (saat prefill) | Sedang |
| Kebutuhan Re-training | Tidak | Tidak | Tidak | Tidak | Tidak |
| Resiko Perplexity Spike | Rendah (kecuali OOM) | Rendah | Sedang jika budget < 20% | Sangat Rendah | Sangat Rendah |
| Use Case Ideal | Dokumen pendek (<8k) | Chatbot streaming | Penalaran multi-turn | Analisis dokumen masif | Coding agent kompleks |
4. Implementasi Praktis: Dynamic Eviction Hook pada Pipeline PyTorch
Berikut adalah blueprint implementasi modul KV-cache dynamic eviction controller sederhana yang mengombinasikan mekanisme Attention Sink dan Heavy-Hitter retention yang dapat diintegrasikan pada inferensi model HuggingFace / custom PyTorch runtime.
import torch
import torch.nn as nn
from typing import Tuple, Optional
class PrunedKVCacheManager:
"""
Mengelola KV Cache dinamis dengan strategi Sink Token + Heavy Hitter + Recency Window.
Mencegah memory fragmentation dan degradasi representasi konteks panjang.
"""
def __init__(
self,
num_sink_tokens: int = 4,
recent_window_size: int = 1024,
heavy_hitter_budget: int = 1024,
):
self.num_sink = num_sink_tokens
self.recent_size = recent_window_size
self.hh_budget = heavy_hitter_budget
self.max_capacity = self.num_sink + self.recent_size + self.hh_budget
def prune_kv_pair(
self,
key_states: torch.Tensor, # [Batch, Heads, Seq_Len, Head_Dim]
value_states: torch.Tensor, # [Batch, Heads, Seq_Len, Head_Dim]
attention_scores: torch.Tensor # [Batch, Heads, Current_Query, Seq_Len]
) -> Tuple[torch.Tensor, torch.Tensor]:
seq_len = key_states.shape[-2]
# Jika sequence length masih di bawah ambang batas kapasitas, pertahankan
if seq_len <= self.max_capacity:
return key_states, value_states
# 1. Lindungi Sink Tokens
sink_keys = key_states[:, :, :self.num_sink, :]
sink_values = value_states[:, :, :self.num_sink, :]
# 2. Lindungi Recency Tokens
recent_keys = key_states[:, :, -self.recent_size:, :]
recent_values = value_states[:, :, -self.recent_size:, :]
# 3. Evaluasi Zona Tengah (Kandidat Pruning)
middle_keys = key_states[:, :, self.num_sink:-self.recent_size, :]
middle_values = value_states[:, :, self.num_sink:-self.recent_size, :]
# Agregasi skor atensi pada zona tengah (mean across queries & batch)
# attention_scores: [Batch, Heads, 1, Seq_Len]
middle_attn = attention_scores[:, :, :, self.num_sink:-self.recent_size]
cumulative_scores = middle_attn.sum(dim=-2) # [Batch, Heads, Middle_Len]
# Cari indeks top-k Heavy Hitters
_, topk_indices = torch.topk(
cumulative_scores,
k=self.hh_budget,
dim=-1,
largest=True,
sorted=False
)
# Expand index agar sesuai dimensi head_dim untuk gather
topk_indices_expanded = topk_indices.unsqueeze(-1).expand(-1, -1, -1, key_states.shape[-1])
# Ekstraksi Heavy Hitters
hh_keys = torch.gather(middle_keys, dim=-2, index=topk_indices_expanded)
hh_values = torch.gather(middle_values, dim=-2, index=topk_indices_expanded)
# 4. Rekonstruksi Buffer Cache
retained_keys = torch.cat([sink_keys, hh_keys, recent_keys], dim=-2)
retained_values = torch.cat([sink_values, hh_values, recent_values], dim=-2)
return retained_keys, retained_valuesDengan logika di atas, memori KV-Cache tidak lagi tumbuh tak terbatas ($\mathcal{O}(N)$), melainkan dibatasi secara rigid pada $\mathcal{O}(\text{Sink} + \text{HeavyHitters} + \text{RecentWindow})$.
Kunci stabilitas penalaran terletak pada dynamic scoring: representasi memori tidak dibuang begitu saja secara acak, melainkan melalui proses eliminasi alami berbasis intensitas atensi.
5. Arsitektur Produksi: Mengatasi Tantangan pada Layer Infrastruktur
Dalam ekosistem riil, mengotak-atik kernel CUDA KV-cache secara manual di level bare-metal sering kali bukan opsi yang realistis bagi sebagian besar tim engineering. Keterbatasan waktu, risiko regresi model, dan rumitnya orkestrasi cluster vLLM/TensorRT-LLM menuntut solusi yang lebih terisolasi dan modular.
Di sinilah peran optimasi di layer API Gateway & Middleware menjadi penentu arsitektur modern.
┌──────────────────────────────────────────────┐
│ AiStudio.id Gateway │
│ │
┌─────────────────┐ │ ┌──────────────┐ ┌──────────────────┐ │ ┌─────────────────┐
│ Client App │ ───────────┼─►│ Token Caching│ ───► │ Semantic Context │ ├──┼──────────► │ Upstream LLM │
│ (IDE/Agent/RAG) │ ◄──────────┼──│ & Deduplicat.│ ◄─── │ Router & Masking │ │◄───────────┼─ │ Cluster(Inference)
└─────────────────┘ │ └──────────────┘ └──────────────────┘ │ └─────────────────┘
└──────────────────────────────────────────────┘Pendekatan enterprise tidak membiarkan client melempar payload konteks masif secara membabi buta ke upstream. Pengelolaan konteks modern dibagi menjadi dua benteng pertahanan:
- Edge-Level Context Masking & Routing (Gateway Layer):
- Upstream Inference Engine Optimization:
Hasilnya adalah latensi Time-to-First-Token yang tetap konstan meski percakapan telah berjalan ratusan putaran, penurunan drastis token billing yang sia-sia, dan yang paling krusial: model tidak mengalami drifting karena input context telah dibersihkan dari artefak usang sebelum menyentuh matriks atensi.
6. Panduan Praktis Menjaga Ketajaman Konteks: Step-by-Step
Bagi engineering lead atau AI architect yang sedang membangun AI agent, coding assistant, atau sistem RAG berskala besar, berikut adalah langkah konkret yang harus dieksekusi:
[Langkah 1: Audit VRAM & Token Profile]
│
▼
[Langkah 2: Terapkan Strategi Windowing Campuran]
│
▼
[Langkah 3: Integrasikan Semantic Caching via API Gateway]
│
▼
[Langkah 4: Setup Needle-In-A-Haystack Monitoring]Langkah 1: Audit Profil Entropi Konteks Anda
Gunakan visualizer perhatian atau logging perplexity per batch token. Identifikasi di titik token ke berapa model Anda mulai melupakan instruksi sistem. Jika degradasi mulai terjadi pada token ke-16k pada model berkapasitas 32k, jangan paksakan context window hingga batas maksimal.Langkah 2: Terapkan Strategi Windowing Campuran (Sink + Dynamic Window)
Jangan simpan seluruh prompt mentah ke dalam state interaksi. Gunakan skema:- System Anchor (Tokens 0-256): Kunci instruksi inti, format output, dan batasan operasional.
- Dynamic Sparse Middle: Lewatkan hanya ringkasan terkompresi atau representasi vector similarity tertinggi dari percakapan masa lalu.
- Active Working Memory (Tokens $N-2048$ hingga $N$): Pertahankan interaksi mentah terbaru secara utuh.
Langkah 3: Optimalkan Rute via Gateway Cerdas
Gunakan arsitektur proxy seperti AiStudio.id API Gateway untuk mengotomatisasi:- Stateful Prefix Caching: Memastikan system prompt dan dokumen referensi statis tidak diproses ulang secara komputasi di setiap turn.
- Dynamic Context Truncation: Membuang turn interaksi yang memiliki relevansi cosine-similarity rendah terhadap query aktif saat ini.
- Multi-Model Fallback: Mengalihkan tugas penalaran panjang ke model dengan arsitektur attention yang lebih resilient secara otomatis ketika context window melebihi ambang batas aman.
Langkah 4: Bangun Unit Test Evaluasi Sintetis (Needle-in-a-Haystack Terfokus)
Sebelum meluncurkan agent ke tahap produksi, uji pipeline Anda menggunakan benchmark sintetis:- Masukkan sebuah instruksi tersembunyi (the needle) di variasi kedalaman konteks (10%, 30%, 50%, 70%, 90% dari total panjang jendela).
- Uji apakah teknik pruning atau gateway masking Anda tetap mampu mengekstraksi dan mengeksekusi instruksi tersebut dengan akurasi 100%.
Menatap Masa Depan: Di Balik Tirai Quadratic Attention
Arsitektur Transformer dengan mekanisme Full Self-Attention telah membawa kita melangkah jauh, namun ia bukanlah akhir dari evolusi representasi kecerdasan buatan. Model-model hibrida yang memadukan State Space Models (SSM) seperti Mamba dengan layer Transformer, atau arsitektur Recurrent Memory Transformer (RMT), secara bertahap mulai menawarkan jalur alternatif untuk memori jangka panjang dengan komputasi linear $\mathcal{O}(1)$ atau $\mathcal{O}(N)$.
Namun selama Transformer murni masih menjadi tulang punggung model-model frontier, keahlian mengelola KV-cache bukan lagi sekadar trik optimasi performa—melainkan pembeda fundamental antara sistem AI yang rapuh dan mesin inferensi yang handal, tajam, dan efisien secara ekonomi.
Kecerdasan bukanlah tentang seberapa banyak informasi yang mampu Anda jejalkan ke dalam satu ruang, melainkan tentang ketajaman insting untuk menentukan informasi mana yang layak diabaikan.
Catatan Penulis

> Sandra menulis seputar rekayasa prompt, efisiensi arsitektur AI, dan produk digital di AiStudio.id.