Curso / PyTorch / Por qué ganó
● piloto de formato

PyTorch · Fundamentos (cierre)

Por qué PyTorch ganó la carrera de frameworks

Todo lo que usaste en HF y fast.ai —Transformers, fastai, miniai, vLLM— corre sobre PyTorch, no por casualidad ni por moda. Esta página cierra el círculo con el contexto histórico y de ecosistema.

1. La guerra de frameworks que ya casi nadie recuerda

A mediados de la década de 2010, TensorFlow (Google, 2015) dominaba investigación e industria con un modelo de grafo estático: se definía el grafo de cómputo completo primero (tf.placeholder, sesiones, sess.run()), y recién después se ejecutaba. Esto permitía optimizaciones agresivas antes de correr una sola operación, pero hacía que debuggear fuera una pesadilla — un error de shape solo aparecía al ejecutar la sesión, lejos del código que realmente tenía el bug, y no se podía usar un print() ni un debugger de Python en medio del grafo.

PyTorch (Meta/Facebook, 2017) apostó por lo opuesto desde el día uno: ejecución eager — cada operación corre inmediatamente, como cualquier código Python normal. Se puede poner un print(tensor) en medio del forward pass, usar pdb, y ver los valores reales en cada paso. Investigadores lo adoptaron masivamente porque iterar experimentos era radicalmente más rápido — la fracción de papers de NeurIPS/ICML que usaban PyTorch pasó de ser minoritaria a dominante en apenas unos años.

2. Por qué "eager por defecto" fue la apuesta correcta

La presión de TensorFlow fue tan fuerte que su propia versión 2.0 (2019) adoptó eager execution por defecto, validando retroactivamente la apuesta de PyTorch. Pero para ese momento el ecosistema de investigación ya había migrado: los papers nuevos salían con código de referencia en PyTorch, lo cual generaba más tutoriales, más Stack Overflow, más ingenieros formados en PyTorch — un efecto de red que se retroalimentaba solo.

El costo de performance de eager (visto en la página anterior) se resolvió después, con torch.compile — pero se resolvió sin abandonar la experiencia eager por defecto: el modelo se sigue escribiendo y debuggeando en modo eager, y la compilación es un paso opcional y aditivo al final. TensorFlow resolvió el mismo problema al revés: empezó grafo-primero y agregó eager después. La secuencia en la que cada framework resolvió el trade-off performance/ergonomía terminó siendo la diferencia decisiva.

3. El ecosistema que se construyó encima

Prácticamente todo lo que recorriste en este curso corre sobre PyTorch como capa base:

  • Hugging Face Transformers — la librería central de todo el HF LLM Course — usa PyTorch como backend principal.
  • fastai y miniai — toda la Parte 1 y Parte 2 de fast.ai — son capas de conveniencia sobre torch.nn, torch.optim y torch.utils.data.
  • vLLM, el motor de inferencia detrás de tus propios fixes upstream, está construido sobre PyTorch (con kernels custom en CUDA/Triton para las partes críticas de performance).
  • Diffusers de HF, que usaste en la Unidad 5 de fast.ai Parte 2, es PyTorch puro.
  • torchtitan, la librería de referencia de Meta para entrenar LLMs desde cero a escala de producción, vive directamente dentro del ecosistema oficial de PyTorch.

Esto no es casualidad: cuando el framework de investigación de facto y el framework de producción de facto son el mismo, el costo de llevar un modelo de "funciona en un notebook" a "sirve tráfico real" baja drásticamente. Es una de las razones estructurales por las que el ciclo de investigación → producción en LLMs se acortó tanto en los últimos años.

4. Entrenamiento distribuido: DDP y FSDP, en breve

Todo lo visto hasta acá asume un solo dispositivo. Entrenar modelos del tamaño de los que usás en tus propios proyectos (Gemma-4, modelos de 30B+ parámetros) requiere repartir el trabajo entre varias GPUs — dos estrategias nativas de PyTorch, con roles distintos:

  • DDP (DistributedDataParallel): cada GPU tiene una copia completa del modelo y procesa un subconjunto distinto del batch; los gradientes se promedian entre todas las copias antes de cada step. Simple y eficiente cuando el modelo entero entra en la memoria de una sola GPU.
  • FSDP (Fully Sharded Data Parallel): cuando el modelo no entra en una sola GPU, FSDP parte (shardea) los parámetros, gradientes y estados del optimizador entre todas las GPUs disponibles, reconstruyendo cada capa completa solo momentáneamente durante su forward/backward. Es el mecanismo detrás de entrenar modelos de decenas o cientos de miles de millones de parámetros sin necesitar una sola GPU con memoria imposible.

Ninguna de las dos requiere reescribir la arquitectura del modelo — se aplican como una capa que envuelve el nn.Module ya definido, otra vez el mismo patrón de "agregar una capa sin tocar el modelo" que ya viste con torch.compile.

5. Resumen — cierre de PyTorch

  1. PyTorch ganó apostando por ejecución eager cuando TensorFlow apostaba por grafos estáticos — más fácil de debuggear, más rápido de iterar para investigación.
  2. El efecto de red (papers → tutoriales → ingenieros formados) se retroalimentó solo, incluso después de que TensorFlow 2.0 adoptara eager también.
  3. PyTorch resolvió el costo de performance de eager sin sacrificar la ergonomía — torch.compile es opcional y aditivo, no un cambio de paradigma forzado.
  4. El ecosistema completo de este curso (HF Transformers, fastai/miniai, vLLM, Diffusers) corre sobre la misma base — investigación y producción comparten framework.
  5. DDP y FSDP escalan el mismo nn.Module sin reescribirlo — de una GPU a un cluster, la arquitectura del modelo no cambia.