Otimização do Desempenho de Modelos de Linguagem Grande
Um novo sistema melhora a eficiência e reduz atrasos no tratamento de tarefas de modelos de linguagem.
― 8 min ler
Índice
- A Necessidade de Melhor Agendamento
- Perguntas de Pesquisa
- Observações e Descobertas
- Uma Nova Abordagem
- A Importância da Gestão Distinta de Tarefas
- Entendendo a Interferência de Desempenho
- Construindo a Solução
- Gerenciando Tarefas de Pré-preenchimento
- Gestão Independente de Fases
- Agendamento Inteligente
- Detalhes de Implementação
- Avaliação de Desempenho
- Resultados em Diferentes Cargas de Trabalho
- Conclusão
- Fonte original
Modelos de Linguagem Grande (LLMs) se tornaram parte essencial de muitos serviços online, como chatbots e ferramentas de criação de conteúdo. Eles funcionam pegando a entrada do usuário e gerando respostas em duas fases principais: pré-preenchimento e decodificação. Na fase de pré-preenchimento, o modelo prepara a primeira resposta, enquanto na fase de decodificação, ele continua a desenvolver essa resposta, criando saídas uma peça de cada vez.
Apesar da popularidade dos LLMs, muitos métodos existentes para configurá-los ignoram as diferenças entre essas duas fases. Isso pode causar problemas quando o modelo precisa lidar com muitos pedidos diferentes ao mesmo tempo, resultando em atrasos e desperdício de recursos.
A Necessidade de Melhor Agendamento
Quando muitos pedidos chegam ao mesmo tempo, é importante gerenciá-los de forma adequada. Diferentes tarefas podem exigir diferentes quantidades de poder de computação e memória, levando a uma situação em que o sistema não consegue acompanhar. Por exemplo, um pedido que precisa de muita computação pode desacelerar outras tarefas que exigem respostas rápidas e pesadas em memória.
Para entender os desafios, precisamos ver como os pedidos podem variar. Um prompt de entrada longo pode levar mais tempo para processar, enquanto uma saída curta pode ser gerada rapidamente. Isso significa que a carga de trabalho não é uniforme, o que torna difícil compartilhar recursos de forma eficiente.
Perguntas de Pesquisa
Essa situação levanta duas perguntas principais:
- Como os pedidos se desempenham quando estão rodando juntos?
- O que pode ser feito para construir um sistema que reduza a interferência entre esses pedidos?
Ao examinar como diferentes tarefas afetam umas às outras, podemos descobrir como melhorar o desempenho dos LLMs.
Observações e Descobertas
Através de testes, encontramos desacelerações significativas ao misturar tarefas de pré-preenchimento e decodificação. Por exemplo, misturar apenas tarefas de pré-preenchimento levou a uma desaceleração de até 10x, enquanto combinar pré-preenchimento com pedidos de decodificação causou uma desaceleração de 5x. Esses problemas surgem porque tarefas pesadas podem saturar os recursos do sistema, o que desacelera tudo o mais.
Uma solução comum, mas impraticável, é alocar recursos para cada tipo de pedido com antecedência. Esse approach não é economicamente viável devido aos altos custos associados à execução desses modelos.
Uma Nova Abordagem
Para lidar com o problema da interferência, projetamos um sistema que agenda e agrupa pedidos com base em suas necessidades únicas. Nossa abordagem tem três componentes principais:
Particionamento de Pedidos: Dividimos os prompts em pedaços menores e de tamanho fixo. Isso permite que o hardware opere próximo aos seus limites sem causar atrasos.
Separação de Fases: Criamos instâncias separadas para tarefas de pré-preenchimento e decodificação. Dessa forma, cada uma pode ser gerida de forma independente, reduzindo conflitos.
Agendamento Inteligente: Usamos um sistema de agendamento em dois níveis que prevê a demanda de recursos. Isso ajuda a evitar pontos congestionados durante a decodificação.
Ao implementar essas ideias, notamos melhorias significativas no desempenho. Nosso sistema reduziu os recursos necessários em 38%, ao mesmo tempo que melhorou o tempo para gerar o primeiro token e completar trabalhos.
A Importância da Gestão Distinta de Tarefas
Modelos de Linguagem Grande podem lidar com uma variedade de tarefas, de conversas simples a resumos de documentos complexos. Cada tipo de tarefa pode ser categorizado com base em propriedades como o comprimento do prompt de entrada e o comprimento dos tokens de saída. Por exemplo, uma tarefa de sumarização pode ter prompts longos, mas requerer apenas alguns tokens de saída. Em contraste, uma tarefa de criação de conteúdo pode ter prompts curtos, mas gerar saídas mais longas.
Por causa dessas diferenças, é crucial examinar como as tarefas se desempenham quando misturadas. Testes anteriores mostraram que a interferência variava bastante entre combinações de tarefas, destacando a necessidade de melhores estratégias de gerenciamento.
Entendendo a Interferência de Desempenho
O conceito de interferência de desempenho se refere aos atrasos que ocorrem quando múltiplas tarefas competem por recursos do sistema. Nas nossas descobertas, identificamos três situações específicas:
Executando várias tarefas de pré-preenchimento: Quando muitas tarefas de pré-preenchimento pesadas são executadas juntas, isso pode desacelerar drasticamente o processo geral.
Misturando tarefas de pré-preenchimento e decodificação: Combinar tarefas das duas fases pode prejudicar o desempenho porque os dois tipos de tarefas operam de maneiras diferentes.
Misturando pedidos de decodificação: Essa situação leva à contenda por memória, o que pode causar desacelerações significativas.
Para resolver esses problemas, projetamos nosso sistema para acomodar melhor as diferentes necessidades de recursos de cada tarefa.
Construindo a Solução
Nosso sistema, inspirado no jogo Tetris, gerencia tarefas como empilhar blocos. Ele utiliza as três estratégias principais descritas anteriormente para lidar com os pedidos de forma eficiente.
Gerenciando Tarefas de Pré-preenchimento
Para evitar desacelerações durante a fase de pré-preenchimento, limitamos quantos tokens podem ser processados em uma única iteração. Isso significa que as tarefas são mantidas dentro de limites gerenciáveis, permitindo um uso melhor do hardware e menos atrasos.
Gestão Independente de Fases
Separando as fases de pré-preenchimento e decodificação, cada uma pode rodar independentemente. Durante a operação, instâncias de pré-preenchimento podem compartilhar resultados com instâncias de decodificação, garantindo que ambas estejam otimizadas para desempenho.
Agendamento Inteligente
O sistema de agendamento em dois níveis envolve um agendador global que gerencia pedidos e agendadores locais que lidam com a organização das tarefas com base em suas necessidades. Também incorporamos um modelo preditivo que ajuda a antecipar quanto tempo cada tarefa vai levar, permitindo gerenciar os recursos de forma mais eficaz.
Detalhes de Implementação
Nosso sistema é construído usando software que aproveita ferramentas existentes, com as funcionalidades principais implementadas em Python. Também criamos uma pilha de rede em C++ para facilitar a comunicação eficiente entre os componentes.
Testamos nosso sistema usando uma variedade de cargas de trabalho realistas, observando que ele consistentemente supera modelos tradicionais. Cada instância executa suas próprias tarefas, garantindo que nenhum componente fique sobrecarregado.
Avaliação de Desempenho
Para avaliar o desempenho do nosso sistema, comparamos ele com modelos padrão usando várias métricas, incluindo o tempo para gerar o primeiro token e o tempo total de conclusão das tarefas. Olhamos especificamente para:
- Tempo-Para-Primeiro-Token (TTFT): Quanto tempo leva para o modelo começar a responder.
- Tempo de Conclusão do Trabalho (JCT): Duração total para completar uma tarefa.
- Eficiência: Desempenho em relação aos custos de recursos.
No geral, encontramos que nosso sistema trouxe melhorias significativas em todas as métricas.
Resultados em Diferentes Cargas de Trabalho
Testamos nosso sistema sob várias cargas de trabalho, como:
Pré-preenchimento Leve e Decodificação Leve: Isso representa cenários de chat padrão. Nosso sistema reduziu o TTFT em 44% em comparação com métodos tradicionais, enquanto melhorou o JCT em 40%.
Pré-preenchimento Leve e Decodificação Pesada: Isso simula cargas de trabalho de criação de conteúdo. Nesse caso, nosso sistema melhorou o TTFT em impressionantes 97% e o JCT em 47%, usando 38% menos hardware.
Pré-preenchimento Pesado e Decodificação Leve/Pesada: Essas cargas de trabalho se concentram em tarefas de sumarização ou engenharia. Apesar dos desafios com prompts longos, nosso sistema ainda melhorou as métricas de desempenho, embora tenha exigido um pouco mais de recursos.
Cargas de Trabalho Misturadas: Isso testa a habilidade do sistema de lidar com vários pedidos simultaneamente. Nossa abordagem levou a uma redução significativa no TTFT, JCT e uso de recursos.
Conclusão
Resumindo, nosso sistema oferece uma maneira eficaz de gerenciar tarefas de inferência de modelos de linguagem grande, agendando e agrupando pedidos de forma cuidadosa. Ao separar fases distintas, reduzir a interferência e gerenciar recursos de forma inteligente, conseguimos melhorias notáveis em desempenho e eficiência. Essa abordagem nos aproxima da otimização dos LLMs para aplicações do mundo real, tornando-os mais rápidos e baratos de operar.
Acreditamos que, através de um planejamento e execução cuidadosos, esse sistema pode beneficiar imensamente empresas e usuários que dependem de modelos de linguagem grande e suas capacidades. Os resultados fazem um caso forte por uma abordagem mais cuidadosa para gerenciar essas tecnologias avançadas.
Título: Inference without Interference: Disaggregate LLM Inference for Mixed Downstream Workloads
Resumo: Transformer-based large language model (LLM) inference serving is now the backbone of many cloud services. LLM inference consists of a prefill phase and a decode phase. However, existing LLM deployment practices often overlook the distinct characteristics of these phases, leading to significant interference. To mitigate interference, our insight is to carefully schedule and group inference requests based on their characteristics. We realize this idea in TetriInfer through three pillars. First, it partitions prompts into fixed-size chunks so that the accelerator always runs close to its computationsaturated limit. Second, it disaggregates prefill and decode instances so each can run independently. Finally, it uses a smart two-level scheduling algorithm augmented with predicted resource usage to avoid decode scheduling hotspots. Results show that TetriInfer improves time-to-first-token (TTFT), job completion time (JCT), and inference efficiency in turns of performance per dollar by a large margin, e.g., it uses 38% less resources all the while lowering average TTFT and average JCT by 97% and 47%, respectively.
Autores: Cunchen Hu, Heyang Huang, Liangliang Xu, Xusheng Chen, Jiang Xu, Shuang Chen, Hao Feng, Chenxi Wang, Sa Wang, Yungang Bao, Ninghui Sun, Yizhou Shan
Última atualização: 2024-01-20 00:00:00
Idioma: English
Fonte URL: https://arxiv.org/abs/2401.11181
Fonte PDF: https://arxiv.org/pdf/2401.11181
Licença: https://creativecommons.org/licenses/by/4.0/
Alterações: Este resumo foi elaborado com a assistência da AI e pode conter imprecisões. Para obter informações exactas, consulte os documentos originais ligados aqui.
Obrigado ao arxiv pela utilização da sua interoperabilidade de acesso aberto.