Hace años desplegué una app de Laravel en un servidor que no tenía ext-mbstring, y no se rompió nada. Ese era el problema. Composer había traído sin rechistar symfony/polyfill-mbstring, todas las funciones de cadenas seguían funcionando, y nuestro importador de CSV pasó los ocho meses siguientes yendo bastante más lento que en mi portátil, porque PHP en userland hacía un trabajo que le tocaba a una extensión en C. Nadie vio un error. No había ninguno que ver. Lo cuento porque el equipo de PyTorch acaba de publicar la versión 2.14 y, enterrada bajo 2,995 commits de 487 colaboradores, hay una decisión que me gustaría enmarcar y colgar encima del escritorio de cada mantenedor de PHP.
Aquí la tienes. PyTorch 2.14 publica wheels para Python 3.15, incluida la build free-threaded, pero torch.compile todavía no funciona en 3.15. En lugar de devolverte en silencio a la ejecución eager y dejar que tu paso de entrenamiento tarde el doble mientras te preguntas si la culpa es del data loader, lanza un error. Pediste código compilado, no puedes tenerlo, y te explica por qué. Esa es toda la novedad, y creo que es lo más maduro de la release.
Llama todavía más la atención cuando lees el resto de las notas, porque muchas de las grandes mejoras de rendimiento en Apple Silicon son limpiezas justo del patrón contrario. El álgebra lineal en el backend MPS solía caer a la CPU sin avisar a nadie, pagando copias de memoria en ambas direcciones. En 2.14, SVD, eigh y lstsq se ejecutan de forma nativa en la GPU para float32 y complex64, la factorización LU estrena kernels de Metal propios con aceleraciones de más de 100x en matrices pequeñas por lotes, y la CTC loss ya no se escapa a la CPU. También había una forma de decodificación de un solo token que se saltaba el camino rápido y provocaba una ralentización de 8.5x en bf16 y fp16. Cada uno de esos casos es un fallback silencioso que alguien acabó teniendo que ir a buscar con un profiler. Las cifras te dicen cuánto puede costar una degradación educada antes de que nadie se entere de que existe.
Ahora, el contraargumento justo, y es potente. Los fallbacks son la razón por la que el software sobrevive al contacto con máquinas reales. El nuevo backend de matmul NVGEMM en torch.compile recurre a Triton para cualquier forma que no sepa manejar, y eso es claramente lo correcto: elegiste un camino más rápido, y perderlo en una forma rara no debería tumbar una ejecución. Lo mismo pasa con float64 en Metal, que sigue ejecutándose en la CPU porque el hardware no tiene un tipo de coma flotante de 64 bits. Nadie quiere un modelo que se caiga en un Mac porque un tensor sea de doble precisión. El polyfill que ocultó mi extensión ausente también mantuvo en pie un sitio en producción en un hosting que yo no controlaba. Lento y funcionando gana a rápido y muerto, casi siempre.
Entonces, ¿dónde está la línea? Yo la pondría en la intención. Que NVGEMM recurra a Triton es el sistema eligiendo entre dos kernels compilados que ya habías aceptado, ambos dentro del modo que pediste. Que torch.compile en 3.15 se convirtiera en eager sin decir nada habría sido el sistema descartando justo lo que pediste de forma explícita, y eso merece un no bien alto. La misma release hace visibles los avisos de deprecación de TorchScript, y encaja con el patrón: si el suelo se mueve bajo tus pies, el trabajo de la herramienta es decírtelo, aunque el log quede más feo durante una temporada.
PHP tiene los dos tipos de fallback y casi nunca los distinguimos. Cambiar una extensión en C por un polyfill está bien cuando nunca pediste la extensión. Cargar el JIT de opcache y que se desactive porque alguna extensión sobrescribe el executor es un caso en el que sí lo pediste, y PHP 8 al menos emite un aviso ahí, cosa que considero el instinto correcto. Lo que me gustaría es ver más de eso en userland: librerías que eligen un camino lento y se lo callan, ORMs que caen en consultas N+1 cuando una relación no se puede cargar de forma anticipada, drivers de caché que se degradan a almacenamiento en array cuando Redis no responde y solo lo cuentan en un log de debug que nadie mira. Cada uno de ellos mantiene viva la petición y te deja un misterio de rendimiento para resolver más adelante, con la fecha de entrega de otra persona.
El arreglo barato está más en nuestro propio código que en php-src. Los requisitos de plataforma de Composer ya te permiten declarar ext-mbstring o ext-intl como obligatorias, y muchos proyectos sencillamente no lo hacen. Una comprobación al arrancar que lance una excepción cuando el driver que pediste no es el que de verdad está sirviendo tráfico son unas diez líneas. PyTorch se pasó un ciclo de releases deshaciendo ralentizaciones ocultas en un backend y, en otro, eligió fallar pronto. Sale más barato escribir el error ahora que salir a cazar la ralentización después.
¿Dónde pones tú esa línea en tu stack? ¿Hay algún fallback en tu app ahora mismo que preferirías convertir en una excepción, o alguno que te alegra que siguiera en silencio porque te salvó en un mal momento? Me interesan los dos casos, sobre todo si tienes PHP corriendo en un hosting que no controlas del todo.




Comentarios
Aún no hay comentarios — escribe el primero.
Inicia la conversación
Sin cuenta ni contraseña — introduce tu correo y te enviamos un enlace de acceso de un solo uso. ¿Primera vez? Todo se configura automáticamente.
Tu valoración se aplicará automáticamente al iniciar sesión.
Revisa tu bandeja de entrada
Hemos enviado un enlace de acceso a …. Ábrelo en este dispositivo — esta pestaña te conectará automáticamente.
¿No llega nada? Mira en la carpeta de spam — y marca el correo como «No es spam» para que la próxima vez llegue directo.