# IteraGPU Lab v1

Recursos originais, versão de 24 de setembro de 2026, para preparar um experimento de GPU reprodutível. O notebook de memória e seu companheiro executam uma pequena rede sintética `Linear → GELU → Linear`. Eles não baixam nenhum modelo nem conjunto de dados. Essa rede não é um LLM, nem um treinamento, nem um benchmark representativo das GPUs oferecidas para locação.

## Conteúdo

- `mesure-memoire.ipynb`: notebook autônomo, código incluído, células sem saídas registradas.
- `mesure_memoire.py`: mesma aritmética e mesmo protocolo de medição, utilizáveis na linha de comando.
- `protocole-qualite.md`: protocolo de negócio a ser completado antes de comparar tempo e custo.
- `resultats-bruts.csv`: grade em branco, uma linha a preencher por passagem real.
- `calcul_forfaits.py`: cálculo do forfait completo, sem dependência externa.
- `tarifs-forfaits.csv`: 45 tarifas IteraGPU, 15 modelos × 3 durações, instantâneo de 24 de setembro de 2026.
- `LICENSE.txt`: licença MIT do código, do notebook e dos documentos originais.
- `MANIFEST.json`: lista exaustiva dos nove membros do arquivo, tamanhos e SHA-256 dos oito arquivos de conteúdo. O manifesto se declara sem impressão digital para evitar uma impressão autorreferente.

O arquivo `iteragpu-lab-v1.zip` contém esses nove arquivos sob uma pasta única. Ele não contém resultado de GPU, nem ambiente Python, nem driver, nem credencial. Extraia os arquivos em um diretório novo. O notebook também pode ser baixado sozinho: ele não importa o script companheiro.

## Pré-requisitos e limites

Os cálculos aritméticos e de forfait usam apenas Python 3.10 ou superior e sua biblioteca padrão. O notebook requer uma ferramenta capaz de abrir um notebook Python; nenhum servidor Jupyter é fornecido. A medição requer, além disso, uma instalação existente de PyTorch compatível com a GPU, o driver e seu runtime CUDA ou ROCm. Nenhum comando da pasta instala esses componentes.

Escolha um device explícito, por exemplo `cuda:0`. O backend ROCm do PyTorch também reutiliza esse nome de interface; isso não prova a compatibilidade de uma instalação AMD específica. Sem PyTorch carregável ou sem GPU acessível, `measure` termina com o código 2 e uma mensagem clara. Ele não grava nenhuma medição falsa e não migra para a CPU. `environment` é um diagnóstico: uma saída válida pode anunciar uma GPU indisponível.

## 1. Estimar os pesos, sem GPU

```console
python mesure_memoire.py estimate --parameters 7000000000 --bits 16 --reserve-gib 4
```

Esse cálculo recebe um número de parâmetros e uma largura de armazenamento. Ele arredonda os bits para o número inteiro de bytes superior e depois converte em GiB (`2**30` bytes). Um GB decimal representa `10**9` bytes. Os 4 GiB são uma hipótese escolhida neste exemplo, não uma reserva medida. O resultado não inclui automaticamente ativações, cache KV, metadados de quantização, gradientes, estados de otimizador ou bibliotecas. Ele não prevê se um modelo real cabe em uma placa.

## 2. Verificar o ambiente existente

```console
python mesure_memoire.py environment --device cuda:0
```

Guarde Python, versão do PyTorch, versão de build CUDA/HIP, GPU realmente visível e memória anunciada pelo runtime. O driver deve ser registrado separadamente com a ferramenta do fornecedor. O script não coleta variáveis de ambiente nem dados pessoais. A versão do runtime integrado ao PyTorch não é a versão do driver.

## 3. Efetuar uma medição explicitamente limitada

Comece pequeno, em um processo novo:

```console
python mesure_memoire.py measure --device cuda:0 --batch 1 --context 16 --width 64 --dtype float32 --warmup 1 --repeats 2 --output mesures-petit-essai.json
```

Para explorar depois as dimensões do MLP, um exemplo de comando maior é:

```console
python mesure_memoire.py measure --device cuda:0 --batch 2 --context 128 --width 1024 --dtype float32 --warmup 3 --repeats 5 --output mesures.json
```

Aumente uma dimensão por vez e monitore a memória disponível. O segundo comando é uma configuração proposta, não uma capacidade garantida nem um resultado publicado. `context` designa aqui o número de posições da entrada `[batch, context, width]`, sem mecanismo de atenção ou cache KV. Os pesos e as entradas compartilham o dtype solicitado; sem autocast, gradientes, otimizador, quantização ou divisão entre GPUs. `float16` e `bfloat16` dependem da instalação efetiva e não são validados apenas pelo teste em float32.

O JSON contém `environment`, `configuration`, `synthetic_model` e `phases`. O arquivo deve ter um nome novo; o script se recusa a sobrescrever um resultado existente.

| Fase | Escopo |
| --- | --- |
| `model_load` | Construção e inicialização do modelo na CPU, transferência para a GPU escolhida. O tempo inclui essa preparação na CPU; os contadores de memória referem-se apenas à GPU. |
| `inputs` | Criação das entradas sintéticas nessa GPU. |
| `cold_forward` | Primeira passagem do modelo após a inicialização do device, do gerador e das entradas. Não é um início a frio da máquina ou do driver. |
| `warmup` | Conjunto das passagens de aquecimento; esse tempo não é misturado às repetições seguintes. |
| `warm_forward` | Uma linha por repetição após o aquecimento. |

Cada fase sincroniza o device antes e depois da operação, registra as baselines e então reinicializa os picos. As saídas ainda estão presentes no registro do fim; elas são liberadas antes da passagem seguinte. Os pesos e as entradas persistem entre as passagens. O cache do alocador é preservado. Os tempos incluem o custo do Python e a sincronização: não são tempos de kernel isolados.

`allocated` faz parte de `reserved`, portanto não se somam. `peak_allocated_bytes` e `peak_reserved_bytes` são dois máximos distintos: não se subtrai um do outro para calcular um cache. Compare separadamente as baselines, os fins e os picos absolutos. Os contadores cobrem apenas o alocador PyTorch deste processo na GPU escolhida, não toda a memória da GPU, do driver ou de outros processos. Uma eventual outra GPU não é medida. Os valores também dependem do alocador e do software: conserve o ambiente junto com os resultados.

## 4. Relacionar qualidade e custo

Leia `protocole-qualite.md`, defina o trabalho útil e o limiar antes do teste, depois preencha `resultats-bruts.csv` com as observações reais. Esta pasta não fornece nenhum corpus de classificação nem medida de qualidade.

```console
python calcul_forfaits.py --gpu b200 --days 7 --lots 2
```

O preço de um lote B200 já inclui dois GPUs. Dois lotes dão quatro GPUs, mas o preço do lote é multiplicado apenas por dois. As tarifas são as do catálogo IteraGPU no dia deste instantâneo: unidades inteiras em centavos de USD, durações de 3, 7 ou 30 dias, sem conversão nem proporção por hora. O CSV não prova disponibilidade atual nem reservation. Verifique a oferta exibida antes de qualquer decisão de compra.

A opção `--accepted-results` é voluntariamente sem valor padrão. Adicione-a somente com o número inteiro positivo de unidades úteis distintas realmente aceitas. O custo unitário usa o preço do forfait inteiro. As repetições do mesmo benchmark não são novos corpus úteis. Sem denominador preenchido, o custo unitário permanece `null`; zero é recusado.

## Validação desta versão

A aritmética, as tarifas e a ausência de saídas preenchidas previamente são verificadas com Python 3.12.14 e sua biblioteca padrão. Este ambiente não contém PyTorch: portanto, a guarda de ausência é testada de fato. Nenhuma instalação foi realizada.

Um teste funcional limitado também foi executado em 24 de setembro de 2026 em uma **GeForce RTX 5070 local**, driver 610.62, Python 3.14.6, PyTorch 2.11.0+cu128, CUDA 12.8: batch 1, contexto 16, largura 64, float32, um aquecimento e duas repetições. Ele valida a execução das seis linhas de fase do script nesse único caso. Ele não valida nem o desempenho dos GPUs do catálogo, nem uma máquina alugada, nem um LLM, nem ROCm, nem as outras precisões. As medições desse teste não estão preenchidas previamente nos arquivos distribuídos. O notebook mantém todas as suas saídas vazias.

## Fontes técnicas primárias

Documentação consultada em 24 de setembro de 2026. Estas referências explicam as APIs; a versão do PyTorch realmente executada é indicada acima, distinta da das páginas de documentação.

- [PyTorch: gerenciamento de memória CUDA](https://docs.pytorch.org/docs/2.14/notes/cuda.html#memory-management)
- [PyTorch: semântica HIP/ROCm](https://docs.pytorch.org/docs/2.14/notes/hip.html)
- [PyTorch: sincronização do device](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.synchronize.html)
- [PyTorch: redefinição dos picos](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.reset_peak_memory_stats.html)
- [PyTorch: memória alocada](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_allocated.html) e [memória reservada](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_reserved.html)
- [PyTorch: máximo alocado](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.max_memory_allocated.html) e [máximo reservado](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.max_memory_reserved.html)
- [Python: aritmética decimal](https://docs.python.org/3/library/decimal.html) e [arquivos CSV](https://docs.python.org/3/library/csv.html)

## Licença

As criações originais do diretório são distribuídas sob licença MIT, reproduzida em `LICENSE.txt`. Mantenha o aviso em caso de redistribuição. Python, PyTorch e as demais ferramentas citadas não são distribuídos com o arquivo e mantêm suas respectivas licenças.
