Decifrando o cache de prompts: dos princípios de PagedAttention à redução de custos em 10 vezes e ao aumento da eficiência. Este artigo de @dejavucoder explora os princípios subjacentes do Prompt Caching, particularmente com base na tecnologia PagedAttention do @vllm_project. Baseando-se em suas próprias experiências ao encontrar dificuldades durante o desenvolvimento, o autor corrige muitos equívocos comuns que os desenvolvedores têm sobre mecanismos de cache e fornece sugestões de otimização altamente práticas. Conceito Errado Fundamental e Verdade: O Cache é Global, Não Privado. Conceito Errado: O autor (como muitos de nós) inicialmente acreditava que o Cache de Prompt era baseado em "sessões de usuário". Ou seja, somente mensagens subsequentes do mesmo usuário na mesma caixa de diálogo poderiam utilizar mensagens em cache anteriores. A verdade é: o cache de prompts é baseado no conteúdo, não no usuário. • Lógica principal: Desde que os prompts do sistema ou as definições das ferramentas sejam textos completamente consistentes, o cache gerado pelo usuário A pode ser totalmente reutilizado pelo usuário B. • Significado: Isso significa que, em cenários de alta concorrência, desde que o prefixo seja consistente, o sistema pode alcançar a "reutilização global", reduzindo significativamente os cálculos redundantes. Por que o armazenamento em cache é necessário? (Custo vs. velocidade) O processo de raciocínio do LLM é dividido em duas etapas, e entender essa diferença é fundamental para compreender o valor do cache: • Etapa de pré-preenchimento: Esta etapa processa o grande número de prompts inseridos e calcula o cache de pares chave-valor. Este processo é computacionalmente intensivo e consome muita capacidade de processamento. • Fase de decodificação: Geração de tokens de resposta um a um. Este processo exige muita memória e largura de banda. • Sem cache: Cada vez que uma solicitação é recebida, mesmo que os primeiros 90% dos prompts sejam iguais, o modelo precisa ser recalculado para o preenchimento prévio, o que é lento e custoso. • Acessa o cache: Pode ignorar diretamente o cálculo de preenchimento prévio, que é complexo, reduzindo o custo de entrada de tokens em 10 vezes e melhorando significativamente a velocidade de geração do primeiro caractere. Apresentação Técnica: PagedAttention O gerenciamento tradicional de cache chave-valor é muito ineficiente, exigindo a pré-alocação de um grande bloco de memória de vídeo contígua, o que facilmente leva à fragmentação e ao desperdício. O vLLM introduz a ideia de gerenciamento de memória pelo sistema operacional — paginação. • Blocos: Em vez de alocar grandes blocos contíguos de memória, o sistema divide o cache KV em "blocos" de tamanho fixo. Esses blocos podem estar dispersos e não contíguos dentro da memória de vídeo física. • Hashing de blocos – a chave para um cache eficaz: Como o sistema sabe que "esta passagem já foi calculada antes"? Ele calcula o valor de hash do bloco. • Dependência do bloco pai: O valor de hash de um bloco depende não apenas do seu próprio conteúdo, mas também do valor de hash do bloco anterior. • Reação em cadeia: Isso é semelhante a um blockchain. O valor de hash atual só corresponderá se tudo "desde o início" for completamente consistente. Isso garante a correção da causalidade — você não pode simplesmente reutilizar um segmento intermediário; o prefixo deve corresponder exatamente. • Busca global: Quando uma nova solicitação chega, o sistema calcula o hash do bloco da palavra de solicitação e o procura na tabela hash global. Se uma correspondência for encontrada, ele aponta diretamente para um bloco de memória existente, sem precisar realizar quaisquer cálculos adicionais. Conselhos práticos para desenvolvedores: Como "enganar" o sistema para que ele acesse o cache? Para maximizar a taxa de acertos no cache, você precisa fazer com que o sistema trate solicitações diferentes como "iguais". O artigo fornece várias regras de ouro: • Manter um prefixo estável. Coloque todo o conteúdo estático (avisos do sistema, definições de ferramentas, textos de exemplo) logo no início. • Contraexemplo: Se você colocar "hora atual" ou "nome de usuário" no início do prompt, toda a cadeia de hash será quebrada desde o início e o conteúdo subsequente, mesmo que idêntico, não poderá ser reutilizado no cache. • Serialização determinística Ao usar o formato JSON para transmitir dados (por exemplo, para chamadas de utilitários), a ordem das chaves deve ser mantida constante. Dica: Use `json.dumps(..., sort_keys=True)` em Python. Isso porque `{ "a": 1, "b": 2 }` e `{ "b": 2, "a": 1 }`, embora semanticamente idênticos, geram strings diferentes, o que leva a uma falha de cache. • Modo somente anexar Ao manter o histórico de diálogos com várias interações, tente adicionar conteúdo novo apenas no final. Não modifique ou trunque o histórico no meio, pois, uma vez que o meio seja alterado, toda a cadeia de cache subsequente se tornará inválida. • Tenha cuidado com alterações nas definições de ferramentas. As definições de ferramentas são frequentemente anexadas aos prompts do sistema pelo modelo. Se você ativar/desativar dinamicamente diferentes ferramentas para diferentes usuários, o prefixo mudará, causando a invalidação do cache. Resumir A essência do Prompt Caching não é a "memória", mas sim a "reutilização dos resultados de computação". Compreender os mecanismos subjacentes de blocos e cadeias de hash permite aos desenvolvedores entender por que os "prefixos" são tão importantes. Resumindo: coloque sempre os elementos imutáveis (comandos do sistema, documentos de apoio, listas de ferramentas) no início e os elementos variáveis (perguntas do usuário, variáveis dinâmicas) no final. Leia o texto original
Carregando detalhes do thread
Buscando os tweets originais no X para montar uma leitura limpa.
Isso normalmente leva apenas alguns segundos.
