Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Os gráficos de chama de perfilagem da GPU mostram quais as funções que consomem mais memória da GPU. Este artigo explica como interpretar os grafos de chama gerados pelas ferramentas de perfilagem de GPU para o Azure Kubernetes Service (AKS).
Important
As funcionalidades de pré-visualização do AKS estão disponíveis num regime de autosserviço e de adesão voluntária. As visualizações prévias são fornecidas "como estão" e "conforme disponíveis" e são excluídas dos contratos de nível de serviço e da garantia limitada. As versões de pré-visualização do AKS são apenas parcialmente abrangidas pelo suporte ao cliente, na medida do possível. Assim sendo, estas funcionalidades não se destinam ao uso em produção. Para obter mais informações, consulte os seguintes artigos de suporte:
Antes de começar, configure o perfil da GPU e confirme se os dados de perfil estão disponíveis no Pyroscope e no Grafana.
Note
A primeira execução de perfilagem pode não mostrar todos os símbolos, incluindo símbolos de operações de arranque como carregamento de modelos, enquanto o perfilador analisa a carga de trabalho e resolve símbolos. Execute novamente a carga de trabalho após a análise inicial para capturar estes símbolos em perfis subsequentes.
Compreenda os grafos de chama
Um gráfico de chama visualiza pilhas de chamadas perfiladas. Cada barra representa uma função, e as barras empilhadas mostram a cadeia de chamadas, ou seja, que função chamou outra. A largura de cada barra representa a quantidade do recurso medido, como o tempo de CPU ou a memória GPU alocada, que passa por essa função.
Regra chave: quanto maior a barra, mais recursos medidos passam por essa função.
Os seguintes gráficos de chama de exemplo são capturados a partir de uma carga de trabalho de inferência vLLM.
Tip
Use Expandir todos os grupos no painel do gráfico de chama do Grafana para ver a pilha completa de chamadas sem colapsar. Use a caixa de Pesquisa para encontrar funções ou palavras-chave específicas. Para evitar que o painel volte a colapsar, coloque em pausa a atualização automática do dashboard definindo o intervalo de atualização para Desativado no canto superior direito do dashboard do Grafana, enquanto inspeciona o gráfico de chama expandido.
Tip
Utilize Focus block para se concentrar num caminho de alocação específico.
Leia os símbolos
As etiquetas de grafos de chama seguem estas convenções:
| Formato do símbolo | Meaning |
|---|---|
Foo > bar |
class Foo: method def bar() |
Foo > __init__ |
Construtor da classe Foo |
bar (sozinho) |
Função independente def bar() |
<interpreter trampoline> |
CPython por cima. Podes ignorar este símbolo. |
<raw-address>, por exemplo, 0x7f151 |
Código nativo C ou CUDA sem símbolo Python disponível. |
Os exemplos incluem:
-
GPUModelRunner/_allocate_kv_cache_tensors: Um método numa classe. Leia este símbolo comoclass GPUModelRunner: def _allocate_kv_cache_tensors(self). -
LlamaMLP/__init__: Um construtor invocado quando se cria um objetoLlamaMLP(...). -
_compile_fx_inner: Uma função autónoma ao nível do módulo que não está dentro de uma classe.
Compreender a alocação própria em comparação com a alocação total
Utilize os valores Self e Total para determinar onde o recurso é consumido:
- Total é o recurso consumido por uma função e tudo o que ela chama. Uma função pode ter um total elevado mas não alocar nada porque faz parte da cadeia de chamadas.
- Self são os recursos consumidos diretamente pela função, excluindo as suas funções subordinadas. Um valor próprio elevado significa que é nesta função que o recurso é consumido.
Por exemplo, se GPUModelRunner._allocate_kv_cache_tensors tiver 55,1 GB de alocação própria, trata-se da função que chama torch.empty() para criar os tensores da cache de chave-valor (KV).
Use as seguintes técnicas de navegação:
- Começa com os nós folha, que são barras sem nada acima deles. A largura total representa a autoatribuição.
- Evita barras largas sem alocação própria quando procuras a origem de uma alocação. Estas funções orquestram chamadas para outras funções.
- Investigue barras largas com alta auto-alocação como potenciais alvos de otimização.
Encontre o maior consumidor de recursos
Use os seguintes passos para identificar pontos críticos:
Olha para as barras mais largas no topo do gráfico. Estas funções folha alocam memória. Quanto mais larga for a barra, mais memória consome.
Verifique a alocação própria face à alocação total. Uma barra larga na parte inferior com
self: 0faz parte da cadeia de chamadas. Segue-a para cima até encontrares uma barra com elevada autoalocação.Lê a pilha de chamadas de baixo para cima para perceber porque é que a função foi chamada. O exemplo seguinte termina com a função que executa a alocação:
<raw-address>, for example, 0x7f151 -> native code entry <interpreter trampoline> -> CPython dispatch <module> -> script top level EngineCoreProc.run_engine_core -> vLLM engine startup EngineCore.__init__ -> engine initialization EngineCore._initialize_kv_caches -> KV cache setup Worker.initialize_from_config -> worker setup GPUModelRunner.initialize_kv_cache -> model runner GPUModelRunner._allocate_kv_cache_tensors -> actual allocation
Use a tabela seguinte como referência rápida:
| Goal | O que procurar |
|---|---|
| Encontre o que aloca mais memória | Barra de folhas mais larga no topo da pilha |
| Encontrar o que é responsável pela maior quantidade de memória | Barra mais larga na base da pilha |
| Identificar alvos de otimização | Barras com ampla auto-alocação |
| Identifica funções que podes saltar | Barras largas com zero autoalocação |