GPU para pesquisa ML · Pagamento crypto sem KYC
IteraGPU
Método 01 · Da estimativa à medição

Por que o pico de memória ultrapassa sua estimativa?

Uma fórmula de pesos descreve o armazenamento dos parâmetros; o pico descreve uma execução, com suas entradas e alocações temporárias. Para explicar a diferença, mantenha as mesmas unidades, meça cada fase e separe memória alocada, memória reservada e ocupação da placa. O pacote IteraGPU Lab v1 fornece um cálculo reproduzível e um pequeno exercício instrumentado. Os números ilustrativos abaixo são cálculos, nunca medições de GPU publicadas.

01 /

Definir a carga antes de escolher o contador

"Um modelo 7B" não especifica nem a representação dos pesos nem o trabalho a realizar. Registre sua revisão, o framework, as versões das extensões, o formato realmente carregado e a operação: treinamento, adaptação ou geração. Para texto, anote os comprimentos de entrada e saída; para visão, a resolução e o número de imagens. Um modelo multimodal exige manter essas duas dimensões.

Prepare uma entrada habitual, uma longa mas esperada e uma próxima do seu limite funcional. Guarde-as durante as comparações. Verifique as formas após tokenização, padding, agrupamento ou redimensionamento: o valor registrado na configuração não prova a forma realmente processada.

Defina também o que permanece simultaneamente na memória: uma sequência, um microbatch, várias requisições ou uma avaliação lançada após o treinamento. Sua pergunta torna-se verificável: essa carga completa cabe em cada dispositivo utilizado, inclusive durante sua etapa mais exigente?

  • Identidade do ensaio: modelo ou código, revisão, conjunto de entradas e semente quando pertinente.
  • Dimensões: batch, contexto, tokens gerados, resolução ou número de requisições simultâneas.
  • Ambiente: GPU selecionado, driver, Python, PyTorch, backend CUDA ou HIP/ROCm e ajustes de alocador.
  • Escopo: carregamento, cálculo, transferência, avaliação, exportação; primeira passada ou passada após aquecimento.
02 /

Calcular os pesos sem misturar GB e GiB

Um GB corresponde a 1 000 000 000 bytes; um GiB a 1 073 741 824 bytes. Os contadores do PyTorch usados aqui retornam bytes. Mantenha esse valor bruto no arquivo de resultados e aplique uma única conversão para comparar as linhas. O rótulo comercial de uma placa não substitui a capacidade efetivamente declarada pelo dispositivo.

Para um conjunto denso de sete bilhões de parâmetros armazenados em dois bytes cada, os pesos representam 14 000 000 000 bytes: 14 GB, ou cerca de 13,04 GiB. Essa operação não inclui ativações, gradientes, cache KV nem estados de otimizador. Adicionar uma reserva de 4 GiB dá aproximadamente 17,04 GiB como hipótese de preparação; isso não demonstra que uma carga caberá nesse envelope.

A divisão teórica em quatro bits pressupõe um armazenamento compacto uniforme. Um carregamento quantizado real pode adicionar escalas e outras informações, e manter alguns módulos em outra precisão. O formato de armazenamento dos pesos e o formato de cálculo devem, portanto, aparecer separadamente na sua ficha.

Pesos estimados em GiB = parâmetros × bits por parâmetro ÷ 8 ÷ 1 073 741 824
Cálculo ilustrativo para 7 000 000 000 parâmetros; nenhum resultado de execução.
Hipótese de armazenamentoBytes calculadosGiB aproximados
32 bits uniformes28 000 000 00026,08
16 bits uniformes14 000 000 00013,04
4 bits compactos, sem metadados3 500 000 0003,26

Fontes técnicas: NIST — prefixos binários e comparação GB/GiB · Hugging Face — formatos e módulos quantizados com bitsandbytes

03 /

No treinamento, medir um passo completo

Os pesos coexistem com outros objetos: gradientes, estados de otimizador, ativações necessárias à passada reversa e tensores temporários. Seus tamanhos dependem do loop, da precisão e das dimensões da carga. Uma constante universal em bytes por parâmetro mascarraria, em particular, o efeito do microbatch e das entradas.

Instrumente a passada direta, o cálculo de perda, a retropropagação e a atualização. Para observar os estados realmente criados pelo seu otimizador, não pare no carregamento do modelo. Mantenha também uma medição do primeiro passo completo: um aquecimento bem-sucedido pode já ter realizado uma inicialização que você precisa conseguir financiar em memória na partida.

Adicione uma avaliação e a exportação de que seu projeto precisa. Se a falha ocorrer durante a avaliação, reduzir apenas o batch de treinamento não corrige essa fase. Uma adaptação que treina poucos parâmetros pode ainda manter um modelo base e ativações volumosas.

Fontes técnicas: Hugging Face — categorias de memória durante o treinamento

04 /

Na inferência, acompanhar o contexto e a concorrência

Em uma geração autorregressiva com atenção, o cache KV guarda estados associados aos tokens. Para um cache denso uniforme, seu tamanho depende das camadas, das cabeças KV, de sua dimensão, dos tokens conservados e das sequências presentes ao mesmo tempo. Use as cabeças KV do modelo, não automaticamente suas cabeças de consulta.

Exemplo aritmético: 32 camadas, 8 cabeças KV, uma dimensão de 128, 8 192 tokens, dois bytes por valor e uma sequência dão 1 073 741 824 bytes, ou 1 GiB para K e V juntos. Quatro sequências idênticas dão 4 GiB para esse único item. Esse cálculo não mede nem a vazão nem a ocupação completa da GPU.

Adapte a fórmula ao cache realmente usado. Uma janela deslizante não conserva necessariamente todo o histórico; um cache estático pode pré-alocar sua capacidade máxima. Caches quantizados e descarregados também mudam o problema. Meça separadamente o processamento inicial da entrada e a geração, sem atribuir automaticamente toda a sua diferença ao cache.

KV denso em bytes ≈ 2 × camadas × cabeças KV × dimensão da cabeça × tokens conservados × sequências × bytes por valor

Fontes técnicas: Hugging Face — estratégias de cache, alocação estática e janelas

05 /

Allocated e reserved: duas leituras que não se somam

memory_allocated descreve os bytes ocupados pelos tensores rastreados pelo PyTorch no dispositivo. memory_reserved descreve a memória gerenciada pelo seu alocador com cache, incluindo a que já serve a esses tensores. Somar as duas conta duas vezes uma parte da memória. Mantenha-as em duas colunas distintas.

Suas variantes máximas registram cada uma um pico desde o início do monitoramento ou desde sua última reinicialização. São picos absolutos do período, que incluem as alocações já presentes no início. O resultado não representa automaticamente apenas os objetos criados pela fase.

Uma leitura de sistema pode ter um escopo mais amplo. As alocações feitas diretamente por uma biblioteca CUDA, por exemplo algumas comunicações NCCL, não são todas visíveis no alocador PyTorch. Uma diferença em relação a uma ferramenta de sistema, portanto, não estabelece por si só um vazamento.

Quatro contadores, todos em bytes, a registrar para o mesmo dispositivo.
ContadorPergunta à qual ele respondeErro a evitar
memory_allocatedQuanto os tensores ocupam neste ponto de leitura?Tomá-lo por toda a ocupação da placa.
memory_reservedQuanto o alocador gerencia neste ponto de leitura?Adicioná-lo a allocated.
max_memory_allocatedQual pico dos tensores foi monitorado durante o período?Confundi-lo com o valor no fim da fase.
max_memory_reservedQual pico de reserva o alocador reporta?Supor que ele ocorre no mesmo instante que o outro pico.

Fontes técnicas: PyTorch — memory_allocated · PyTorch — memory_reserved · PyTorch — max_memory_allocated · PyTorch — alocações fora de seu alocador

06 /

Por que a diferença entre os dois picos não mede o cache

Consideremos apenas os dois instantes fictícios da tabela. O pico allocated vale 8 GiB e o pico reserved 12 GiB. Sua diferença, 4 GiB, não é a diferença observada em nenhum desses dois instantes: esta vale respectivamente 2 e 6 GiB. Dois máximos não descrevem necessariamente um mesmo estado.

Para estudar sua diferença em um dado momento, registre allocated e reserved no mesmo ponto de controle, após sincronização e sem nova operação voluntária entre as leituras. Você obtém uma diferença de contadores nesse instante, não uma medida do cache KV do modelo, nem uma garantia de que toda essa diferença possa satisfazer a próxima alocação.

Mantenha também o backend do alocador no relatório. A documentação do PyTorch 2.14 esclarece que, com cudaMallocAsync, max_memory_reserved pode combinar os níveis mais altos de dois pools e fornecer um limite superior do pico simultâneo. Isso reforça a necessidade de manter o nome e o escopo do contador.

Dois estados inventados para explicar o cálculo; esta tabela não é um trace de GPU.
Instante ilustrativoAllocatedReservedReserved − allocated neste instante
A8 GiB10 GiB2 GiB
B6 GiB12 GiB6 GiB

Fontes técnicas: PyTorch — definição e limite de max_memory_reserved

07 /

Delimitar cada fase antes de registrar seu pico

As operações de GPU podem ser enfileiradas antes de serem concluídas. Para uma medida por fase, conclua os trabalhos anteriores antes de reinicializar os picos, depois aguarde o fim da fase antes da leitura. torch.cuda.synchronize aguarda os kernels de todos os streams do dispositivo selecionado; essa escolha define uma fronteira explícita para esse protocolo.

reset_peak_memory_stats reinicializa o monitoramento dos picos a partir do estado atual; ele não libera os tensores do programa. Registre primeiro os níveis iniciais. No fim, conserve os dois picos absolutos e os dois níveis atuais. Não apresente a subtração de um nível inicial como o volume exato de todos os tensores temporários: objetos anteriores também podem ter sido liberados durante a fase.

Essa instrumentação pode alterar a sobreposição habitual das fases. Use-a para localizar o problema, depois verifique também o loop completo com seu ordenamento real. Em multicartão, repita as leituras para cada dispositivo; uma medida em cuda:0 não descreve as outras GPUs.

  • 1. Dar um nome à fase e anotar suas entradas exatas.
  • 2. Sincronizar o dispositivo, depois registrar allocated e reserved iniciais.
  • 3. Chamar reset_peak_memory_stats nesse mesmo dispositivo.
  • 4. Executar a fase definida conservando as saídas necessárias para o que vem a seguir.
  • 5. Sincronizar, registrar os picos e os níveis finais, depois salvar sucesso ou erro.
  • 6. Manter o resultado bruto, as dimensões e a configuração; não preencher nenhuma medida ausente com zero.

Fontes técnicas: PyTorch — sincronização de um dispositivo · PyTorch — reinicialização das estatísticas de pico

08 /

Distinguir primeira passagem e passagens após aquecimento

O primeiro teste e um loop já preparado não respondem à mesma pergunta. Guarde um registro do carregamento e da primeira passagem, depois documente o número de iterações de aquecimento antes das repetições. Não elimine uma falha de inicialização com o argumento de que as passagens seguintes teriam sido mais leves.

O script IteraGPU distingue model_load, inputs, cold_forward, warmup e warm_forward. Seu cold_forward é a primeira passagem do modelo pequeno após a inicialização do dispositivo. Ele não mede toda a inicialização de um servidor, de um driver ou de um serviço. As repetições warm_forward permanecem no mesmo processo e aproveitam seu estado existente.

Para o seu modelo, comece uma nova série em um novo processo quando você mudar uma condição suscetível de deixar objetos ou reservas anteriores. Anote a ordem dos testes e a política de aquecimento. Executar cinco vezes o mesmo loop e iniciar cinco processos não constituem o mesmo protocolo.

09 /

Usar o notebook e o script IteraGPU Lab v1

Comece pelo README, depois baixe o notebook autônomo ou o script Python. O cálculo estimate usa a biblioteca padrão. A medição exige PyTorch instalado com um backend GPU compatível e um dispositivo acessível; ela não baixa modelo nem pacote. O notebook exige um ambiente capaz de ler os arquivos ipynb.

O exercício de medição usa uma pequena rede densa original e entradas sintéticas. As opções batch, context e width descrevem seus tensores; context aqui não é o comprimento de um verdadeiro LLM com cache KV. Esse suporte serve para examinar o método de medição e variar uma dimensão. Ele não demonstra a capacidade de uma placa para o seu modelo de pesquisa.

Execute os comandos abaixo a partir da pasta que contém o script. Consulte primeiro o relatório environment. Se faltar PyTorch ou a GPU, measure deve parar explicitamente com o código 2; nenhum resultado de CPU deve ser interpretado como uma medição de GPU. O JSON de saída de uma medição bem-sucedida é produzido no seu ambiente. Escolha um novo nome de arquivo para cada série: o script se recusa a sobrescrever um resultado existente.

O primeiro comando refaz o cálculo dos pesos e da reserva hipotética de 4 GB. Para os seguintes, use um dispositivo que você tem autorização para solicitar e mantenha dimensões modestas no início. Registre a versão do PyTorch realmente usada: as referências técnicas desta página descrevem em particular a versão 2.14, sem impor que ela esteja instalada na sua máquina.

O funcionamento do script foi verificado em um caso pequeno: RTX 5070 local fora do catálogo, driver 610.62, Python 3.14.6 e PyTorch 2.11.0+cu128. O teste usava batch 1, contexto 16, largura 64, float32, um aquecimento e duas repetições. Ele valida esse caminho de execução, sem qualificar um LLM, um treinamento ou as GPUs oferecidas para locação. O notebook é entregue sem saídas e a tabela de comparação sem resultados; a proteção de ausência de PyTorch também foi verificada em um ambiente distinto.

shell
python mesure_memoire.py estimate --parameters 7000000000 --bits 16 --reserve-gib 4
python mesure_memoire.py environment --device cuda:0
python mesure_memoire.py measure --device cuda:0 --batch 2 --context 128 --width 1024 --dtype float32 --warmup 3 --repeats 5 --output mesures.json
10 /

Interpretar uma falha antes de trocar de placa

Um teste incompleto continua sendo uma observação útil. Guarde a fase, as dimensões solicitadas, a mensagem de erro e os últimos valores disponíveis. Um pico parcial antes de uma saturação não constitui a necessidade de memória de uma execução completa. Reduza uma única dimensão para construir um caso que funcione, depois procure a fronteira entre sucesso e falha.

empty_cache libera blocos não utilizados do cache do alocador, sem liberar tensores ainda vivos. Não é uma correção universal para uma carga muito grande. Chamá-lo entre cada repetição altera as condições: documente essa escolha em vez de misturar esses testes com os que mantêm o cache.

Se os contadores simples não explicam a situação, um trace de memória pode ajudar a identificar as alocações ao longo do tempo. Seu escopo permanece o das alocações visíveis pelo PyTorch. Um pico baixo de allocated, portanto, não exclui uma alocação externa ou outro usuário da placa.

Ligar o sintoma a uma próxima verificação, sem diagnóstico automático.
ObservaçãoVerificação útilPróximo teste
Falha durante o carregamentoFormato carregado, posicionamento dos pesos e memória já ocupada.Reproduzir o carregamento sozinho em um processo novo.
Carregamento bem-sucedido, passo backward impossívelMicrobatch, entradas, ativações retidas e estado do loop.Reduzir uma dimensão e refazer o passo completo.
Avaliação isolada falhandoBatch de avaliação, saídas retidas e contexto de cálculo.Medir a avaliação com seus próprios limites.
Allocated aumenta de uma repetição para outraReferências retidas em listas, caches da aplicação ou grafos.Verificar seu tempo de vida antes de culpar o alocador.
Reserved permanece alto após o cálculoTensores ainda vivos e política de cache.Comparar os valores atuais, sem somar os contadores.
Uma ferramenta de sistema indica maisEscopo da ferramenta, contexto da GPU, outros processos e bibliotecas.Isolar a carga e aproximar leituras feitas no mesmo momento.

Fontes técnicas: PyTorch — o que empty_cache libera · PyTorch — traces e limites de visibilidade da memória

11 /

Construir uma margem a partir de cargas comparáveis

Evite um percentual de margem apresentado como universal. A margem deve cobrir variações identificadas: entrada mais longa, batch autorizado, avaliação, exportação, versão de biblioteca ou outra ocupação da placa. Teste os casos limite esperados e registre o que fica fora do escopo. Uma execução bem-sucedida com uma única entrada pequena não valida a carga máxima.

Altere uma variável por vez: batch 1 e depois 2 com contexto constante, ou contextos 2.048 e depois 4.096 com batch constante. Mantenha o mesmo conteúdo e as mesmas regras de preparação. Uma truncagem que remove uma informação necessária torna a tarefa diferente, mesmo que reduza o pico.

Se os pesos dominam, estude outro formato controlando a qualidade. Se as ativações dominam, o microbatch ou o checkpointing de ativações podem ser caminhos. Este último troca memória por recálculo: meça também a duração e verifique os resultados. Se o cache KV domina, examine contexto, concorrência e estratégia de cache. O dossiê de comparação complementa essa abordagem com uma regra de qualidade comum.

Fontes técnicas: PyTorch — checkpointing de ativações e recálculo

12 /

Passar do trace a uma decisão de configuração

Sua saída esperada é uma ficha curta: estimativa dos pesos, carga máxima testada, fases bem-sucedidas ou falhas, quatro contadores com unidades, ambiente e escolha adotada. Anexe o resultado bruto a essa ficha. Separe o que você calculou, o que você observou e o que você ainda supõe.

Compare em seguida a necessidade com a capacidade de cada placa, mantendo as restrições de software. Várias GPUs exigem uma distribuição do trabalho e dos dados; sua presença não cria automaticamente um único reservatório de memória para a aplicação. Uma falha em uma placa pode persistir apesar de memória livre em outra.

O protocolo PyTorch usa a interface torch.cuda; uma build HIP/ROCm do PyTorch reutiliza esse nome. Identifique o backend realmente instalado antes de comparar duas famílias de hardware. O uso de uma mesma função Python não demonstra que os kernels, as precisões ou os resultados são equivalentes.

O dimensionador permite retomar a hipótese inicial; as fichas de GPU permitem comparar as capacidades. Volte então ao mesmo caso de trabalho para verificar a escolha. A pequena rede do download continua sendo um exercício de instrumentação: somente a execução da sua carga, em seu ambiente documentado, pode validar sua própria margem.

Fontes técnicas: NVIDIA — distribuição do trabalho em várias GPUs · PyTorch — interface torch.cuda em builds HIP/ROCm