PTENES
MÓDULO 2.1

🐍 Ecosistema Python: PyTorch, Transformers, Gymnasium

Las herramientas que todo ingeniero VLA necesita dominar: del tensor al environment. PyTorch para autograd, HuggingFace para modelos preentrenados, Gymnasium para entornos estandarizados.

6
Temas
~3h
Estimado
T2
Técnico
Práctico
Tipo
Python 3.10+ Lenguaje base del ecosistema VLA PyTorch Tensores + Autograd GPU CUDA nativa · bfloat16 nn.Module · optim.AdamW 🤗 Transformers Más de 300 mil modelos en el Hub from_pretrained · LoRA/PEFT AutoModelForVision2Seq Gymnasium Entornos de RL obs / act / reward / done VectorEnv · wrappers W&B Tracking Experimentos Barridos · Registry Docker · Reproducibilidad · NVIDIA NGC
1

🔥 PyTorch para robótica: tensores y autograd

El framework de deep learning dominante en robótica. Entender los tensores y el sistema de diferenciación automática es el requisito técnico previo para cualquier trabajo serio con VLA.

💡 Qué es

PyTorch es el framework de deep learning dominante en robótica y VLA. Tensores son arrays multidimensionales con soporte nativo para GPU mediante CUDA. El sistema autograd calcula gradientes automáticamente a través del grafo computacional — esencial para la backpropagation durante el entrenamiento de políticas neuronales. Prácticamente todo VLA relevante (OpenVLA, pi-0, ACT) está implementado en PyTorch.

✓ Hacer

  • ✓ Usar bfloat16 en GPU Ampere+ para entrenar VLAs grandes
  • ✓ Mover tensores al device antes de operar: .to(device)
  • ✓ Usar torch.compile() para acelerar ciclos de entrenamiento repetitivos
  • ✓ Llamar optimizer.zero_grad() antes de cada backward

✗ Evitar

  • ✗ Acumular tensores en listas de Python — filtra memoria GPU silenciosamente
  • ✗ Mezclar float32 e float16 sin torch.amp
  • ✗ Llamar .item() dentro del loop de entrenamiento (sincroniza CPU/GPU)
  • ✗ Olvidar model.eval() / torch.no_grad() en la inferencia
📦 Patrón mínimo: entrenar una política PyTorch
import torch
import torch.nn as nn

# device-agnostic
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model = PolicyNet().to(device)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4)

# mixed precision (Ampere+)
scaler = torch.cuda.amp.GradScaler()

for batch in dataloader:
    obs, action = batch["obs"].to(device), batch["action"].to(device)
    optimizer.zero_grad()
    with torch.autocast(device_type="cuda", dtype=torch.bfloat16):
        pred = model(obs)
        loss = nn.functional.mse_loss(pred, action)
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()
torch.Tensor
Array ND con device, dtype y grad
nn.Module
Base de toda red; forward() obligatorio
autograd
Grafo computacional + backward()
torch.compile
JIT para bucles repetitivos (2× faster)
2

🤗 HuggingFace Transformers: modelos preentrenados

La biblioteca que democratizó el acceso a modelos de lenguaje y visión, y que aloja prácticamente todo VLA open-source relevante.

⚡ Por qué aprender primero

HuggingFace Hub es el centro del ecosistema open-source de VLA. OpenVLA, SmolVLA, Qwen-VL, PaliGemma — todos distribuidos a través de Hub con pipeline de inferencia listo. LeRobot aloja más de 58k datasets allí. Sin dominar from_pretrained(), ni siquiera puedes hacer inferencias.

300k+
modelos en el Hub
58k+
datasets LeRobot
PEFT
Ajuste fino eficiente con LoRA
🔧 Inferencia con OpenVLA vía HuggingFace
from transformers import AutoModelForVision2Seq, AutoProcessor
import torch

processor = AutoProcessor.from_pretrained("openvla/openvla-7b", trust_remote_code=True)
model = AutoModelForVision2Seq.from_pretrained(
    "openvla/openvla-7b",
    attn_implementation="flash_attention_2",
    torch_dtype=torch.bfloat16,
    low_cpu_mem_usage=True,
    trust_remote_code=True
).to("cuda")

# Processar frame + instrução em linguagem natural
inputs = processor(
    "In: What action should the robot take to pick up the cup?\nOut:",
    image,
    return_tensors="pt"
).to("cuda", dtype=torch.bfloat16)

action = model.predict_action(**inputs, unnorm_key="bridge_orig", do_sample=False)

✓ Buenas prácticas

  • ✓ Usar safetensors en lugar de pickle (.bin)
  • ✓ Versionar modelos con revision="main" o tag
  • ✓ LoRA para fine-tuning: entrena el 1-10% de los parámetros
  • ✓ Usar flash_attention_2 cuando esté disponible

✗ Errores comunes

  • ✗ Olvidar trust_remote_code=True en VLAs personalizados
  • ✗ Descargar modelos sin verificar la licencia de uso comercial
  • ✗ Cargar el modelo completo sin low_cpu_mem_usage (OOM)
  • ✗ Mezclar el processor del modelo A con el model B
AutoModel
Carga automáticamente la arquitectura correcta
LoRA/PEFT
Ajuste eficiente con pocos parámetros
safetensors
Formato seguro y rápido para pesos
Hub API
Push y pull de modelos y datasets mediante programación
3

🏋️ Gymnasium: entornos estandarizados

La API universal entre la política y el entorno. MuJoCo, Isaac Sim y PyBullet implementan esta interfaz: entender obs/act/reward/done es fundamental para cualquier loop de entrenamiento.

🔍 Qué es

Gymnasium (sucesor de OpenAI Gym) define la interfaz estándar para entornos de RL. En robótica VLA, funciona como wrapper para simuladores y permite entrenar políticas con una interfaz consistente. La API es simple pero potente:

Espacios

  • • observation_space — lo que ve el robot
  • • action_space — lo que puede hacer
  • • Box para continuo, Discrete para discreto

Ciclo de vida

  • • env.reset() → estado inicial
  • • env.step(action) → (obs, reward, done, info)
  • • Bucle hasta terminated o truncated

Bucle de episodio de Gymnasium

1

obs, info = env.reset(seed=42)

Inicia un episodio y devuelve la observación inicial. Seed garantiza la reproducibilidad del estado inicial.

2

action = policy(obs)

La política procesa la observación y devuelve una acción en el espacio continuo (p. ej.: velocidades de las articulaciones, delta cartesiano).

3

obs, reward, terminated, truncated, info = env.step(action)

El entorno ejecuta la acción y devuelve una nueva observación, una señal de recompensa y flags de terminación.

4

VectorEnv: N ambientes paralelos

Para entrenar más rápido: gymnasium.vector.make("env-id", num_envs=8) ejecuta 8 episodios simultáneos en un único proceso.

gym.Env
Clase base para crear subclases
Box(shape)
Espacio continuo n-dimensional
Wrappers
Transforman obs/act sin tocar env
VectorEnv
N entornos paralelos en un proceso
4

📦 Datasets y DataLoaders para trayectorias

Los datos son el principal cuello de botella en robótica. Estructurar, cargar y aumentar trayectorias de forma eficiente es tan importante como la arquitectura del modelo.

📊 Formatos de datasets de robótica

  • RLDS (Google): TFRecord con metadatos de episodios, estándar de Open X-Embodiment con 1M+ trayectorias.
  • LeRobot Dataset: Parquet + video MP4 en HuggingFace Hub. Más de 58k datasets, API Python nativa con from_hub().
  • HDF5 propio: Usado por la robótica académica (RoboMimic, R2R2). Jerárquico, eficiente para secuencias largas.
RLDS / Open X
  • • más de 1M de trayectorias reales
  • • TFRecord (requiere TF)
  • • Metadatos detallados por paso
  • • Estándar de Google/DeepMind
LeRobot Dataset ★
  • • más de 58k datasets en Hub
  • • Parquet + video MP4
  • • API Python limpia
  • • Integración nativa de entrenamiento
HDF5 / Proprio
  • • Flexible y jerárquico
  • • Acceso aleatorio rápido
  • • Sin dependencia de la nube
  • • Común en el ámbito académico

💡 Consejo: DataLoader para trayectorias

Las trayectorias tienen longitudes variables. Usa collate_fn personalizado para hacer padding o truncar secuencias al armar batches. Combínalo con num_workers=4 e pin_memory=True para maximizar el throughput de la GPU.

loader = DataLoader(
    dataset, batch_size=32, num_workers=4,
    pin_memory=True, collate_fn=pad_trajectory_batch
)
RLDS
TFRecord con episodios Open X
LeRobot DS
Parquet + video, 58k datasets
collate_fn
Crear batches de trayectorias variables
aumento de datos
Crop/jitter específico de robótica
5

📈 Weights & Biases: seguimiento de experimentos

Sin un seguimiento estructurado, los entrenamientos de VLA se convierten en una caja negra. W&B hace que la pérdida, la tasa de éxito y los hiperparámetros sean visuales y reproducibles.

LeRobot python train.py loss · success_rate wandb: true en el config wandb.log() W&B Dashboard Comparar ejecuciones lado a lado Barridos: búsqueda de hiperparámetros Tables: visualizar trayectorias Model Registry: control de versiones Artefactos: checkpoints análisis Decisiones ¿ACT o Diffusion Policy? ¿lr=1e-4 o 5e-5? ¿Divergió en step 2k? Lo sabes.

💡 W&B + LeRobot: integración nativa

LeRobot tiene soporte nativo para W&B mediante config YAML. Solo tienes que establecer wandb.enable: true en el archivo de configuración, sin una línea de código extra.

# config/train_act.yaml
wandb:
  enable: true
  project: "vla-pickup-cup"
  entity: "meu-time"
  notes: "ACT baseline lr=1e-4"
wandb.init()
Inicia una ejecución experimental
Barridos
Búsqueda automática de hiperparámetros
Tables
Visualizar trayectorias y predicciones
Registry
Control de versiones de checkpoints
6

🐳 Docker y reproducibilidad en robótica

La combinación de controlador CUDA + PyTorch + MuJoCo puede fallar de maneras misteriosas. Los contenedores eliminan de la ecuación el «funciona en mi máquina».

🔍 Por qué Docker es crítico en robótica

Docker crea contenedores para el entorno de desarrollo: las versiones exactas de Python, PyTorch, CUDA y las dependencias quedan fijas. En robótica, donde la combinación CUDA driver + PyTorch + MuJoCo puede fallar fácilmente; los contenedores son esenciales. NVIDIA NGC y LeRobot proporcionan contenedores listos con todo configurado.

✓ Setup recomendado

  • ✓ Partir de una imagen NVIDIA NGC: nvcr.io/nvidia/pytorch:24.01-py3
  • ✓ Compilación multi-stage: builder → runtime (imagen más pequeña)
  • ✓ Montar datasets mediante volumen, no copiarlos a la imagen
  • ✓ devcontainer para VS Code con GPU passthrough

✗ Errores comunes

  • ✗ Copiar todo el dataset dentro de la imagen de Docker
  • ✗ Usar docker run sin --gpus all
  • ✗ Ignorar la compatibilidad entre el driver de CUDA y CUDA de PyTorch
  • ✗ Incluir secretos (tokens HF, clave de API de W&B) en el Dockerfile
🐳 Dockerfile mínimo para VLA con LeRobot
# Base: PyTorch + CUDA oficial NVIDIA
FROM nvcr.io/nvidia/pytorch:24.01-py3

WORKDIR /workspace

# Instalar LeRobot e dependências
RUN pip install lerobot[gymnasium,wandb] huggingface_hub

# Montar datasets externamente (não copiar)
VOLUME ["/data"]

# GPU passthrough: nvidia-docker2 ou --gpus all
CMD ["python", "train.py", "--config", "config/act.yaml"]

💡 devcontainers: GPU en VS Code

Añade .devcontainer/devcontainer.json con "runArgs": ["--gpus", "all"] y todo el equipo abre el proyecto con el mismo entorno, incluido CUDA, sin configuración manual. LeRobot ofrece un devcontainer listo en el repositorio oficial.

NVIDIA NGC
Contenedores optimizados PyTorch+CUDA
--gpus all
Passthrough de GPU para el contenedor
devcontainer
Entorno uniforme en VS Code
multi-stage
Builder + runtime = imagen compacta

✅ Resumen del módulo

✓
PyTorch es el corazón del entrenamiento VLA — tensores, autograd, mixed precision y torch.compile conforman la base técnica de todo ingeniero.
✓
HuggingFace Hub + LoRA — Acceso a más de 300k modelos preentrenados y fine-tune eficiente con el 1-10% de los parámetros originales.
✓
Gymnasium: contrato universal obs/act/reward — cualquier simulador (MuJoCo, Isaac Sim, PyBullet) habla este lenguaje; VectorEnv paraleliza episodios.
✓
Docker + W&B = reproducibilidad — Los entornos fijos con contenedores y seguimiento visual de experimentos son tan importantes como el modelo.

Siguiente módulo

2.2 — LeRobot: pipeline de extremo a extremo (recolección, entrenamiento y deploy en un robot real)