kvpress

repository·main·Indexed 22 days ago

https://github.com/nvidia/kvpress

A library designed to efficiently compress the Key-Value (KV) cache of pretrained transformer models to reduce memory overhead during long-context LLM deployment. It integrates with Hugging Face transformers pipelines and provides various compression 'presses', including KVzap, which uses a surrogate model to predict importance scores for hidden states via Dynamic Memory Sparsification (DMS). The library includes evaluation tools for benchmarks such as Loogle, RULER, Zero Scrolls, Infinitebench, LongBench, and Needle in a Haystack.

Tokens
13.9K
Snippets
40
Records
62
Agent score
78%

What's inside kvpress

  1. Use ExpectedAttentionPress for attention-based compression

    main
    The ExpectedAttentionPress class is used to compute compression scores based on the expected attention that tokens will pay to future positions. This allows for more intelligent KV cache management by prioritizing tokens that are likely to be attended to in subsequent steps. Detailed implementation steps and usage can be found in the expected_attention.ipynb notebook.
  2. How decoding compression works with DecodingPress

    main

    While standard presses work during the prefilling phase, DecodingPress is an experimental wrapper that enables compression during the token generation (decoding) phase.

    Instead of a compression ratio, DecodingPress uses a target_size to determine how much to compress. It performs compression every compression_interval steps to ensure the cache size after compression matches the target_size.

    Important Constraints:

    • DecodingPress only supports ScorerPress types as its base_press.
    • It can optionally maintain a buffer of recent hidden states via hidden_states_buffer_size.
    from transformers import pipeline
    from kvpress import KnormPress, DecodingPress
    
    # Initialize the pipeline
    device = "cuda:0"
    model = "meta-llama/Llama-3.1-8B-Instruct"
    model_kwargs = {"attn_implementation": "flash_attention_2"}
    pipe = pipeline("kv-press-text-generation", model=model, device=device, model_kwargs=model_kwargs)
    
    # Configure decoding compression
    decoding_press = DecodingPress(
        base_press=KnormPress(),
        compression_interval=10,
        target_size=512
    )
    
    context = "A very long text you want to compress during generation"
    question = "Tell me a long story about this context"
    response = pipe(context, question=question, press=decoding_press)["answer"]
  3. Understand the Needle in a Haystack benchmark

    main

    The Needle in a Haystack benchmark evaluates a model's long-context understanding by testing its ability to retrieve a specific piece of information (the "needle") hidden within a large body of text (the "haystack").

    Key details:

    • Haystack Source: Uses Paul Graham's essays as the primary text source.
    • Needle Selection: By default, the needle is a sentence defined within the dataset. However, you can replace it with a custom sentence for specific testing scenarios like passkey retrieval. Customization logic can be found in utils.py.
  4. How a press works and how to use it as a context manager

    main

    A press works by registering a forward hook (press.forward_hook) to each attention layer during the prefilling phase. You can apply a press to a model by using the press instance as a context manager via the __call__ method. This allows you to wrap model calls or model.generate() calls to apply KV cache compression.

    Note: While you can use with press(model): with model.generate(), this method does not allow excluding the question from compression (which is important for methods like SnapKV) and does not support batching multiple questions at once.

    import torch
    from transformers import AutoModelForCausalLM
    from kvpress import KnormPress
    
    device = "cuda:0"
    ckpt = "meta-llama/Meta-Llama-3.1-8B-Instruct"
    model = AutoModelForCausalLM.from_pretrained(ckpt).to(device)
    press = KnormPress(compression_ratio=0.4)
    
    inputs = model.dummy_inputs["input_ids"].to(device)
    
    with torch.no_grad():
        print(model(inputs).past_key_values[0][0].shape)
        # torch.Size([3, 8, 5, 128])
        
    with torch.no_grad(), press(model):
        print(model(inputs).past_key_values[0][0].shape)
        # torch.Size([3, 8, 3, 128])
  5. Understand the MATH-500 benchmark dataset

    main
    The MATH-500 dataset is a subset of 500 problems from the MATH benchmark, originally adapted from the Hugging Face HuggingFaceH4/MATH-500 dataset. It was created by OpenAI for their 'Let's Verify Step by Step' paper. This dataset is used within kvpress for evaluating model performance on mathematical reasoning tasks.
  6. Install optimum-quanto for quantized cache support

    main

    To use quantized cache implementations (e.g., 4-bit quantization) within the KV press pipeline, you must install the optimum-quanto package.

    #!pip install -U optimum-quanto
  7. Use kvpress for prefilling-phase compression

    main

    KVPress provides "presses" that compress the KV cache during the prefilling phase. The easiest way to use them is via the kv-press-text-generation pipeline, which is automatically registered with Hugging Face transformers upon import. This pipeline handles chat templates and tokenization automatically.

    To use it, initialize a pipeline with the name kv-press-text-generation and pass a press object (like ExpectedAttentionPress) to the pipeline call.

    from transformers import pipeline
    from kvpress import ExpectedAttentionPress
    
    model = "Qwen/Qwen3-8B"
    pipe = pipeline("kv-press-text-generation", model=model, device_map="auto", dtype="auto")
    
    context = "A very long text you want to compress once and for all"
    question = "\nA question about the compressed context"
    
    # Apply compression with a specific ratio
    press = ExpectedAttentionPress(compression_ratio=0.5)
    answer = pipe(context, question=question, press=press)["answer"]
  8. Implement a custom press in kvpress

    main
    To extend kvpress with a new compression strategy, refer to the new_press.ipynb notebook. This notebook explains the underlying mechanism of key-value (KV) compression and provides a template for applying these mechanisms to transformer models. Implementing a custom press allows you to define specific logic for how KV caches are pruned or compressed during the inference process.
  9. Evaluate KVPress performance

    main

    KVPress provides tools to evaluate the performance of different compression methods:

    1. Accuracy: Use the provided CLI to test methods on popular long-context benchmarks.
    2. Speed and Memory: Use the speed_and_memory notebook (notebooks/speed_and_memory.ipynb) to measure peak memory usage and total time gains.

    Detailed results and instructions can be found in the evaluation/ directory of the repository.