# IteraGPU Lab v1

Recursos originales, versión del 24 de septiembre de 2026, para preparar un experimento GPU reproducible. El notebook de memoria y su compañero ejecutan una pequeña red sintética `Linear → GELU → Linear`. No descargan ningún modelo ni conjunto de datos. Esta red no es un LLM, ni un entrenamiento, ni un benchmark representativo de las GPU ofrecidas en alquiler.

## Contenido

- `mesure-memoire.ipynb`: notebook autónomo, código incluido, celdas sin salidas guardadas.
- `mesure_memoire.py`: misma aritmética y mismo protocolo de medición, utilizables en línea de comandos.
- `protocole-qualite.md`: protocolo de negocio que hay que completar antes de comparar tiempo y coste.
- `resultats-bruts.csv`: plantilla en blanco, una línea que rellenar por cada pasada real.
- `calcul_forfaits.py`: cálculo del forfait completo, sin dependencia externa.
- `tarifs-forfaits.csv`: 45 tarifas de IteraGPU, 15 modelos × 3 duraciones, instantánea del 24 de septiembre de 2026.
- `LICENSE.txt`: licencia MIT del código, del notebook y de los documentos originales.
- `MANIFEST.json`: lista exhaustiva de los nueve miembros del archivo, tamaños y SHA-256 de los ocho archivos de contenido. El manifiesto se declara a sí mismo sin huella para evitar una huella autorreferente.

El archivo `iteragpu-lab-v1.zip` contiene estos nueve archivos bajo una carpeta única. No contiene ni resultado GPU, ni entorno Python, ni controlador, ni credencial. Extrae los archivos en un directorio nuevo. El notebook también puede descargarse solo: no importa el script compañero.

## Requisitos y límites

Los cálculos aritméticos y de forfait utilizan solo Python 3.10 o posterior y su biblioteca estándar. El notebook necesita una herramienta capaz de abrir un notebook Python; no se proporciona ningún servidor Jupyter. La medición necesita además una instalación existente de PyTorch compatible con la GPU, el controlador y su runtime CUDA o ROCm. Ningún comando de la carpeta instala estos componentes.

Elige un device explícito, por ejemplo `cuda:0`. El backend ROCm de PyTorch también reutiliza este nombre de interfaz; eso no demuestra la compatibilidad de una instalación AMD concreta. Sin PyTorch cargable o sin GPU accesible, `measure` termina con el código 2 y un mensaje claro. No escribe ninguna medición falsa y no recurre a la CPU. `environment` es un diagnóstico: una salida válida puede anunciar una GPU no disponible.

## 1. Estimar los pesos, sin GPU

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

Este cálculo toma un número de parámetros y un ancho de almacenamiento. Redondea los bits al número entero de bytes superior y luego convierte a GiB (`2**30` bytes). Un GB decimal representa `10**9` bytes. Los 4 GiB son una hipótesis elegida en este ejemplo, no una reserva medida. El resultado no incluye automáticamente activaciones, caché KV, metadatos de cuantización, gradientes, estados del optimizador ni bibliotecas. No predice si un modelo real cabe en una tarjeta.

## 2. Verificar el entorno existente

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

Conserva Python, versión de PyTorch, versión de build CUDA/HIP, GPU realmente visible y memoria anunciada por el runtime. El controlador debe registrarse por separado con la herramienta del proveedor. El script no recopila ni variables de entorno ni datos personales. La versión del runtime integrado en PyTorch no es la versión del controlador.

## 3. Efectuar una medición explícitamente acotada

Empieza pequeño, en un proceso nuevo:

```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 después las dimensiones del MLP, un ejemplo de comando más grande es:

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

Aumenta una dimensión a la vez y vigila la memoria disponible. El segundo comando es una configuración propuesta, no una capacidad garantizada ni un resultado publicado. `context` designa aquí el número de posiciones de la entrada `[batch, context, width]`, sin mecanismo de atención ni caché KV. Los pesos y las entradas comparten el dtype solicitado; sin autocast, gradientes, optimizador, cuantización ni reparto entre GPU. `float16` y `bfloat16` dependen de la instalación efectiva y no quedan validados por la sola prueba en float32.

El JSON contiene `environment`, `configuration`, `synthetic_model` y `phases`. El archivo debe tener un nombre nuevo; el script se niega a sobrescribir un resultado existente.

| Fase | Alcance |
| --- | --- |
| `model_load` | Construcción e inicialización en CPU del modelo, transferencia a la GPU elegida. El tiempo incluye esta preparación en CPU; los contadores de memoria solo abarcan la GPU. |
| `inputs` | Creación de las entradas sintéticas en esa GPU. |
| `cold_forward` | Primera pasada del modelo tras inicializar el device, el generador y las entradas. No es un arranque en frío de la máquina ni del controlador. |
| `warmup` | Conjunto de las pasadas de calentamiento; este tiempo no se mezcla con las repeticiones siguientes. |
| `warm_forward` | Una línea por repetición tras el calentamiento. |

Cada fase sincroniza el device antes y después de la operación, registra las baselines y luego reinicia los picos. Las salidas siguen presentes en la medición de fin; se liberan antes de la pasada siguiente. Los pesos y las entradas persisten entre pasadas. La caché del allocator se conserva. Los tiempos incluyen el coste de Python y la sincronización: no son tiempos de kernel aislados.

`allocated` forma parte de `reserved`, así que no se suman. `peak_allocated_bytes` y `peak_reserved_bytes` son dos máximos distintos: no se restan para calcular una caché. Compara por separado las baselines, los fines y los picos absolutos. Los contadores solo cubren el allocator de PyTorch de este proceso en la GPU elegida, no toda la memoria de la GPU, del controlador ni de otros procesos. Una posible segunda GPU no se mide. Los valores también dependen del allocator y del software: conserva el entorno junto con los resultados.

## 4. Relacionar calidad y coste

Lee `protocole-qualite.md`, fija el trabajo útil y el umbral antes de la prueba, y luego rellena `resultats-bruts.csv` con las observaciones reales. Esta carpeta no proporciona ningún corpus de clasificación ni medida de calidad.

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

El precio de un lote B200 ya incluye dos GPU. Dos lotes dan cuatro GPU, pero el precio del lote se multiplica únicamente por dos. Las tarifas son las del catálogo de IteraGPU en la fecha de esta instantánea: unidades enteras en centavos USD, duraciones de 3, 7 o 30 días, sin conversión ni prorrateo por hora. El CSV no demuestra ni la disponibilidad actual ni la reserva. Verifica la oferta mostrada antes de cualquier decisión de compra.

La opción `--accepted-results` no tiene valor por defecto de forma deliberada. Añádela solo con el número entero positivo de unidades útiles distintas realmente aceptadas. El coste unitario usa el precio del forfait completo. Las repeticiones del mismo benchmark no son nuevos corpus útiles. Sin denominador indicado, el coste unitario queda en `null`; se rechaza el cero.

## Validación de esta versión

La aritmética, las tarifas y la ausencia de salidas prerrellenadas se verifican con Python 3.12.14 y su biblioteca estándar. Este entorno no contiene PyTorch: por tanto, la guarda de ausencia se prueba de verdad. No se ha efectuado ninguna instalación.

También se ejecutó una prueba funcional acotada el 24 de septiembre de 2026 en una **GeForce RTX 5070 local**, controlador 610.62, Python 3.14.6, PyTorch 2.11.0+cu128, CUDA 12.8: batch 1, contexto 16, ancho 64, float32, un calentamiento y dos repeticiones. Valida la ejecución de las seis líneas de fase del script en ese único caso. No valida ni el rendimiento de las GPU del catálogo, ni una máquina alquilada, ni un LLM, ni ROCm, ni las demás precisiones. Las medidas de esta prueba no están prerrellenadas en los archivos distribuidos. El notebook conserva todas sus salidas vacías.

## Fuentes técnicas primarias

Documentación consultada el 24 de septiembre de 2026. Estas referencias explican las API; la versión de PyTorch realmente ejecutada se indica arriba, distinta de la de las páginas de documentación.

- [PyTorch: gestión de memoria 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: sincronización del device](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.synchronize.html)
- [PyTorch: reinicio de los picos](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.reset_peak_memory_stats.html)
- [PyTorch: memoria asignada](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_allocated.html) y [memoria reservada](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_reserved.html)
- [PyTorch: máximo asignado](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.max_memory_allocated.html) y [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) y [archivos CSV](https://docs.python.org/3/library/csv.html)

## Licencia

Las creaciones originales del dossier se distribuyen bajo licencia MIT, reproducida en `LICENSE.txt`. Conserva el aviso al redistribuir. Python, PyTorch y las demás herramientas citadas no se distribuyen con el archivo y conservan sus respectivas licencias.
