v9.1.1
Menu

KV-Cache Attention

hardFREEAttention MechanismsLLM 1: Foundations

Implement KV-cache for efficient autoregressive inference.

During autoregressive generation, we cache previous K and V values. At each new step:

  1. We only have a new single query vector (1, d)
  2. We append the new K and V to the cache
  3. We compute scaled dot-product attention with the full cached K, V: softmax(qKT/d) V\text{softmax}(qK^T/\sqrt{d})\,V

Input: kv_cache_attention(d, steps)

  • d: the dimension
  • steps: a list of (q, k, v) tuples, one per generation step, each vector holding d floats

The example input lists the same data as lines: d, then num_steps, then the q, k and v vectors of each step.

Output: A list with one attention output vector (d floats) per step. Values are printed rounded to 4 decimal places.

Use causal attention (each step sees all previous + current).

Example

Input
2
2
1 0
1 0
1 0
0 1
0 1
0 1
Output
[1.0000 0.0000]
[0.3302 0.6698]
Reasoning
  • Inputs: d=2d = 2 and two steps. Step 1 brings q=k=v=(1,0)q = k = v = (1, 0); step 2 brings q=k=v=(0,1)q = k = v = (0, 1).
  • Step 1: the cache holds a single key, K=V=(10)K = V = \begin{pmatrix}1 & 0\end{pmatrix}. Softmax over one score is always 11, so the output is exactly that value: (1,0)(1, 0).
  • Step 2: the cache now has two rows, K=V=(1001)K = V = \begin{pmatrix}1 & 0 \\ 0 & 1\end{pmatrix}. Scores: q⋅k1/2=0q \cdot k_1 / \sqrt{2} = 0 and q⋅k2/2=1/2≈0.7071q \cdot k_2 / \sqrt{2} = 1/\sqrt{2} \approx 0.7071.
  • Softmax: e0=1e^{0} = 1, e0.7071≈2.0281e^{0.7071} \approx 2.0281, total 3.02813.0281, giving weights 1/3.0281≈0.33021/3.0281 \approx 0.3302 and 2.0281/3.0281≈0.66982.0281/3.0281 \approx 0.6698.
  • Output: 0.3302 (1,0)+0.6698 (0,1)=(0.3302,0.6698)0.3302\,(1, 0) + 0.6698\,(0, 1) = (0.3302, 0.6698), printed as [0.3302 0.6698].
  • Notice: unscaled scores 00 and 11 would give weights 0.26890.2689 and 0.73110.7311. Dividing by 2\sqrt{2} narrows the gap to 0.70710.7071, pushing the weights closer to even.

Constraints

  • 1 <= d <= 8, 1 <= num_steps <= 5
  • Each step produces a 1xd output
  • Cache grows by one K,V pair per step
  • Round to 4 decimal places

Learn this in

More from LLM 1: Foundations

solution.py

Test results

Sign in to run your code against the test cases.