KVSplit - executando contextos 2–3x mais longos no Apple Silicon
(github.com/dipampaul17)- KVSplit é um projeto open source que permite executar LLMs grandes e janelas de contexto longas no Apple Silicon
- Por meio da alocação de precisão separada para chaves e valores, alcança até 72% de redução de memória com perda de qualidade inferior a 1%
- É otimizado para chips M1/M2/M3 e para o framework Metal
- Comprova melhorias de velocidade e economia de memória com benchmarks medidos e ferramentas de visualização
- Oferece instalação fácil, comparação com um único comando e várias ferramentas de benchmark e análise
Introdução: por que o KVSplit é importante
KVSplit é uma ferramenta open source que torna possível executar LLMs de grande porte e janelas de contexto muito mais longas em ambientes Apple Silicon (M1/M2/M3) ao aplicar quantização com precisões diferentes para chaves e valores dentro do cache KV. Ela supera a limitação de projetos anteriores, que quantizavam chaves e valores da mesma forma, e reduz drasticamente o uso de memória enquanto mantém a perda de qualidade em um nível quase imperceptível. Como benchmarks reais, velocidade e métricas de qualidade são todos públicos, é uma solução confiável, e o suporte a Metal junto com ferramentas intuitivas de comparação e visualização aumentam a eficiência de desenvolvimento.
As principais vantagens em relação a projetos semelhantes são:
- Separação da precisão entre chave e valor para um gerenciamento de memória mais eficiente
- Especialização para Apple Silicon e otimização completa para o framework Metal
- Fornece de forma integrada benchmarks, perplexidade, medições de memória/velocidade/qualidade e visualização
- Instalação com um comando, compatibilidade com modelos e integração com llama.cpp
- Visualização em tempo real da economia de memória e várias ferramentas de teste comparativo
Principais características e pontos centrais
Visão geral
- Com KVSplit, é possível executar LLMs muito maiores e contextos mais longos do que antes no Apple Silicon
- Ao atribuir precisões de quantização diferentes para chaves e valores, obtém tanto economia de memória quanto melhora de velocidade
- Foram confirmados até 72% de economia de memória, melhora de velocidade (5–15%↑) e perda de qualidade inferior a 1%
- Suporte completo a Metal, com aceleração ideal no Apple Silicon
Principais resultados de benchmark
- Na configuração K8V4 (chaves em 8 bits, valores em 4 bits)
- 59% de economia de memória e 0,86% de perda de qualidade (com base em perplexidade)
- 5,7% mais rápido que FP16
- Na configuração K4V4 (chaves/valores ambos em 4 bits)
- Até 72% de economia de memória
- Cerca de 6% de perda de qualidade. Recomendado para usos menos sensíveis à qualidade
Comparação do efeito de economia de memória
- Com base em FP16, 176MB (8K tokens)
- K8V8 (chaves/valores em 8 bits) : 93.5MB (47%)
- K8V4 (chaves em 8 bits, valores em 4 bits) : 71.5MB (41%)
- K4V4 (chaves/valores em 4 bits) : 49.5MB (28%)
Principais funcionalidades
- Quantização individual de chaves e valores do cache KV
- Otimização completa para Apple Silicon e Metal
- Scripts de análise para benchmark/qualidade (perplexidade)/uso de memória
- Ferramentas de visualização e geração de gráficos com qualidade de publicação
- Setup com um comando e comparação em tempo real
Estrutura de pastas do projeto
- llama.cpp: inclui build otimizada para Metal
- models: armazenamento de arquivos de modelo
- scripts: inclui scripts de benchmark/instalação/comparação/visualização
- results, plots: armazenamento de resultados de benchmark e arquivos de visualização
- README.md
Insights científicos e resultados experimentais
Fenômeno central do cache KV
- Os vetores de chave têm sensibilidade à quantização muito maior do que os vetores de valor → é preciso atribuir maior precisão às chaves para preservar a qualidade
- K8V4 é o sweet spot: a combinação chave 8 bits/valor 4 bits oferece o melhor equilíbrio entre qualidade e memória
- 59% de economia de memória, apenas 0,86% de piora na perplexidade e velocidade superior ao FP16
- K4V8, mesmo com o mesmo número total de bits de K8V4, apresenta mais de 7 vezes mais perda de qualidade → comprovando a importância da precisão no lado das chaves
Implicações gerais
- Torna possível obter eficiência de memória e preservação da qualidade do modelo ao mesmo tempo → permitindo operar contextos muito mais longos e modelos maiores em hardware de consumo
Exemplos de uso e recomendações de configuração
Exemplos de execução com diferentes precisões de quantização
- Padrão (FP16): ./llama.cpp/build/bin/llama-cli -m models/your-model.gguf -p "prompt" -t 8 --flash-attn
- Recomendado K8V4: --kvq 8
- K4V8 (DEMO): --kvq-key 4 --kvq-val 8
- K4V4 (economia máxima): --kvq 4
Exemplo de contexto longo
- Contexto de 32K: FP16 requer ~1.4GB, mas K8V4 pode rodar com ~400MB
Explicação das flags de linha de comando
-t 8: número de threads, 8 recomendado para M1/M2/M3--flash-attn: otimização para Apple Silicon--kvq N: define N bits para chaves/valores--kvq-key,--kvq-val: suporte a configuração individual-c N: número de tokens de contexto (quanto maior, maior o efeito do KVSplit)-n N: número de tokens gerados-f FILE: arquivo de entrada do documento-m MODEL: caminho do modelo
Benchmark avançado e visualização
- Com benchmark_kvsplit.py, mede características por configuração, comprimento de sequência, memória/velocidade/perplexidade/escala
- Com visualize_results.py, gera gráficos em nível de artigo acadêmico
- Os resultados são salvos automaticamente em CSV/JSON e um resumo é fornecido
Otimização para Apple Silicon e visualização de memória
- Uso completo do framework Metal
- Efeito decisivo em modelos M1/M2/M3 com maior pressão de memória
- Com capture_memory.sh, é possível visualizar a economia de memória em tempo real
- Devido ao alinhamento de páginas personalizado, a economia real pode diferir ligeiramente do valor teórico
Resumo das funcionalidades
- Precisão de bits independente para chave/valor e quantização personalizada
- Otimização completa para Apple Silicon e Metal
- Benchmark abrangente de memória/velocidade/qualidade
- Visualização com qualidade de artigo e comparação em tempo real, com suporte a captura de memória
- Interface de instalação/uso extremamente simples
Citações e pesquisas de referência
- "More for Keys, Less for Values: Adaptive KV Cache Quantization" (2024)
- "Unifying KV Cache Compression for Large Language Models with LeanKV" (2025)
- Implementação base: [llama.cpp], modelo de teste: [TinyLlama]
Recomendações de configuração e planos futuros
- K8V4 (chaves em 8 bits/valores em 4 bits) : perda de qualidade de 0,86%, redução de memória de 59% e velocidade +5,7%, oferecendo o melhor equilíbrio
- K4V4: economia máxima de memória (72%), com queda de qualidade de cerca de 6%. Adequado para usos em que memória é prioridade absoluta
- Especialmente forte para execução com contexto longo, permitindo operar contextos 2–3x mais longos
Roadmap futuro
- Precisão adaptativa baseada na importância do token
- Quantização individual por camada
- Otimização personalizada por modelo (Mistral, Phi-3 etc.)
- Suporte planejado para demo web e mobile (iOS/iPadOS)
Licença e contribuições
- Licença MIT
- Qualquer desenvolvedor ou pesquisador de IA pode contribuir via Issue e PR
1 comentários
Comentários do Hacker News
Demonstra interesse por parecer algo interessante, pergunta sobre a intuição de por que esse fenômeno acontece e como isso foi descoberto, sugere melhorias de usabilidade como o fato de a etapa de aplicar patch no script de instalação estar incompleta e o uso de
git submodule, além de propor separar ollama.cppdas dependências Python para considerar diferentes ambientes Pythonllama.cpp, que o código de parsing de argumentos já foi movido paraarg.cppe por isso o patch não faz sentido, e explica que as opções de quantização K/V já haviam sido adicionadas aollama.cppem 2023. Questiona a razão de existir do patch, dizendo que parece apenas mudar os argumentos de linha de comando, e recomenda fortemente evitar executar um arquivoinstall.shde um novo repositório para aplicar um patch tão simplesPergunta se esse patch também seria possível no MLX, observando que o MLX parece mais rápido e esperando que essa abordagem ajude usuários de Mac com conversas longas em velocidade prática de uso real
Pergunta se há diferença prática em relação às opções
--cache-type-ke--cache-type-vbf16foi adicionado recentemente. Por isso, no passado, em GPUs da Apple, a abordagemtype_k/vsó permitia no mínimo 16 bits (f16/bf16), então, embora não conheça bem os detalhes internos dollama.cpp, supõe que possa haver alguma diferençaDepois de ler o código, conclui que o patch é desnecessário e confirma por um link de PR que essa funcionalidade já foi incorporada ao
llama.cppem 2023. Diz que é preciso cautela porque o projeto induz o usuário a executar uminstall.shpara aplicar patch em vez de usar um fork do repositório, aponta uma estrutura confusa com vários arquivos de patch, código duplicado e sobrescrita de patches, e observa que na prática só adiciona a opção--kvq, embora já existam opções separadas para quantização K/V. Suspeita que o autor não poderia desconhecer essa funcionalidade existente, não recomenda executar scripts de repositórios com lógica complexa, critica o fato de o post no HN e o número de estrelas no GitHub estarem altos apesar de o conteúdo ser enganoso, preocupa-se com o fato de o autor continuar evitando perguntas e conclui que tanto o repositório quanto o script estão misturados com uma base antiga dollama.cppe não batem com a estrutura atual, o que aumenta a confusãoPergunta se também é possível aplicar quantização KV diferenciada (
K8V4etc.) a modelos já convertidos em formato.gguf, e se há restrições ligadas ao tipo de modelo ou configuração de tokenizer.ggufexistentes, sem conversão especial. Explica que a quantização é aplicada apenas ao cache KV em tempo de execução e é independente dos pesos do modelo, e que os flags--kvq-keye--kvq-valapenas definem o formato de armazenamento em memória. Diz que testou com sucesso em vários modelos, como LLama-3, Mistral, Phi-2/Phi-3, TinyLlama e Qwen, mas ressalta que isso é exclusivo do backend Metal dollama.cppe que o Flash Attention atualmente ignora formatos customizados de cache KV, então é preciso usar a opção-fa 0. Fora isso, afirma que funciona com qualquer arquitetura Transformer que use atençãoPergunta se, em Apple Silicon com muita memória, como 64 GB ou 128 GB, esse patch fica mais rápido ou melhor, comentando rumores de que ampliar a janela de contexto no Apple Silicon na prática fica lento e questionando se isso tem utilidade real em máquinas com muita memória
K8V4, atribuído à eficiência de acesso à memória. Explica que o problema de “lentidão” com modelos grandes vem principalmente do limite de desempenho computacional e não de RAM ou da presença de otimizações no cache KV; assim, o KVSplit é útil quando o gargalo é memória. Em uso prático, considera ideal alocar janelas de contexto maiores para modelos menores, como 7B a 13B. Se forem necessários ao mesmo tempo modelos grandes e contextos extremamente longos, GPUs de nível servidor ainda são mais apropriadas, mas a técnica amplia o limite do que dá para fazer no hardware da AppleDemonstra interesse e pede uma explicação mais de alto nível: pergunta se um modelo de 2048 tokens pode ser estendido para algo como 4~6k, se um modelo com contexto de 128k poderia ser usado com janelas de 256k+, e quais seriam os casos de uso ideais para modelos locais
K8V4, é possível reduzir o uso de memória em 59%, o que aumenta o comprimento máximo de contexto em até 2,4 vezes. Assim, um modelo de 2048 tokens poderia ir para cerca de 5000 tokens e um modelo de 8K para algo próximo de 19,5K. Diz que, na prática, isso permite processar um livro inteiro de uma vez no MacBook, analisar bases de código grandes ou manter histórico longo em apps conversacionais. Explica que a economia cresce linearmente com o tamanho do contexto e relata que, em sua experiência, o cache KV caiu de 176 MB para 72 MB em contexto de 8K, enquanto em 128k a economia chega a vários gigabytes. Afirma que essa é uma solução especialmente eficaz quando o problema é OOM por limite de comprimento de entradaElogia a ideia e a tentativa, pergunta se isso também poderia ser aplicado em GPU e se pode ser combinado com outras técnicas de quantização
llama.cppjá permite configuração separada com--cache-type-ke--cache-type-v, e que o patch atual é especializado para Metal, mas o princípio pode ser portado como está. Também afirma que pode ser combinado com outras técnicas de quantização, já que a quantização do cache KV só é aplicada durante a execução e não conflita com a quantização dos pesos, sendo uma etapa separada no pipeline. Ressalta, porém, que engines comovLLMeTensorRT-LLM, que usam estruturas próprias de cache, exigiriam implementação específica. Acrescenta que, em GPU, o maior efeito viria ao integrar isso diretamente à arquitetura do FlashAttention, onde economia de memória pode se converter em ganho de velocidadeDiz que há partes que não entende bem e que algo parece estranho, recomenda evitar executar o script em questão e informa que fez uma denúncia
Pergunta como o desempenho muda: mesmo colocando um contexto mais longo na memória, a velocidade de computação no fim não seria a mesma?
fp16,q8eq4, sentiu velocidades de iteração parecidas. Diz que não verificou o funcionamento interno, mas esperava que os vetores fossem empacotados com processamento SIMD em lote de 4 a 8 bits, embora tenha ficado com a impressão de que esse empacotamento na verdade não ocorre