5 puntos por GN⁺ 2025-05-17 | 1 comentarios | Compartir por WhatsApp
  • Python free-threaded está diseñado para aprovechar eficientemente el hardware multinúcleo
  • En CPython 3.14, la seguridad de hilos y el rendimiento de los módulos centrales mejoraron de forma notable
  • Aún quedan muchos paquetes importantes que no soportan la compilación free-threaded
  • Cualquiera puede sumarse a su avance mediante reportes en entornos reales y contribuciones de la comunidad

Resumen general

La semana pasada se publicó CPython 3.14.0b1, y esta semana comienza PyCon 2025 en Pittsburgh.
Estos dos eventos son hitos importantes para la distribución y estabilización de Python free-threaded.
Este artículo repasa el proceso del último año y explica cómo el equipo de Quansight tuvo un papel clave al aplicar de forma experimental la compilación free-threaded a flujos de trabajo reales de producción con dependencias complejas.

Qué significa y por qué hace falta Python free-threaded

  • El soporte para Python free-threaded permite aprovechar todos los recursos de cómputo del hardware moderno, donde los CPU y GPU multinúcleo ya son algo común
  • Con el enfoque tradicional del GIL (Global Interpreter Lock), para aprovechar por completo algoritmos paralelos hacían falta soluciones indirectas y ajustes adicionales
  • Normalmente se usaba multiprocessing en lugar del módulo threading, pero eso implica un costo alto de creación de procesos y además la copia de datos es ineficiente
  • En los paquetes de Python que incluyen código nativo, la compilación free-threaded no es compatible automáticamente, por lo que es indispensable auditar el código para garantizar la seguridad de hilos
  • La eliminación del GIL requirió cambios estructurales profundos en el intérprete CPython, y también dejó en evidencia problemas estructurales en paquetes existentes

Logros principales

  • Junto con el equipo de runtime de Python de Meta, se contribuyó soporte para Python free-threaded en varios paquetes y proyectos como los siguientes
    • Herramientas de empaquetado y flujo de trabajo como meson, meson-python, setup-python GitHub Actions, packaging, pip y setuptools
    • Generadores de bindings como Cython, pybind11, f2py y PyO3
    • Paquetes clave del ecosistema PyData como NumPy, SciPy, PyArrow, Matplotlib, pandas, scikit-learn y scikit-image
    • Dependencias importantes entre las más descargadas de PyPI como Pillow, PyYAML, yarl, multidict y frozenlist
  • También se sigue trabajando gradualmente en paquetes populares que todavía no tienen soporte (CFFI, cryptography, PyNaCl, aiohttp, SQLAlchemy, grpcio, etc.) y en bibliotecas de machine learning (safetensors, tokenizers, etc.)
  • Los desarrolladores principales de CPython del equipo de Quansight incorporaron en la versión 3.14 mejoras como las siguientes
    • El módulo warnings funciona con seguridad de hilos de forma predeterminada en compilaciones free-threaded
    • Se corrigieron problemas graves de seguridad de hilos en asyncio y aumentó su escalabilidad en paralelo
    • Se mejoró de forma integral la seguridad de hilos en el módulo ctypes
    • Mejoró el rendimiento del garbage collector free-threaded
    • Se optimizaron el esquema de deferred reference counting y el adaptive specializing interpreter
    • Se hicieron numerosas correcciones de errores y refuerzos de seguridad de hilos
  • También se redactó una guía integral1 para dar soporte a Python free-threaded, con documentación que puede servir de referencia práctica para muchos más paquetes en adelante

Estado actual del ecosistema Python free-threaded

  • Hace un año (cuando salió 3.13.0b1), la instalación de la mayoría de los paquetes de Python en compilaciones free-threaded estaba completamente rota
  • La causa de los fallos de compilación no era tanto un problema fundamental, sino opciones predeterminadas no compatibles o pequeñas suposiciones que dejaban de cumplirse
  • Durante el último año se resolvieron muchos problemas en colaboración con la comunidad, y un punto de inflexión importante fue el soporte oficial en Cython 3.1.0
  • Todavía quedan paquetes que incluyen código compilado pero no ofrecen wheels free-threaded
    Su avance puede consultarse en tablas de seguimiento manual y automático2

Retos inmediatos

  • Actualmente, la compilación free-threaded de Python está en una etapa en la que necesita experimentación y retroalimentación en flujos de trabajo reales
  • Hay potencial de mejora de rendimiento especialmente en flujos de trabajo donde el costo de usar multiprocessing es alto, pero es indispensable hacer una auditoría minuciosa de seguridad de hilos para cada paquete
  • Muchas bibliotecas ofrecen estructuras de datos mutables sin una documentación suficiente sobre seguridad de hilos ni garantías reales de seguridad
  • Cuando un paquete es grande y arrastra mucho legado, a menudo faltan personas que comprendan completamente el código, lo que retrasa el soporte
  • A nivel comunitario, hace falta trabajar por la sostenibilidad del mantenimiento de paquetes clave

Cómo contribuir

  • Se puede consultar la guía de contribución oficial
  • Los problemas de todo el ecosistema y la documentación principal de compatibilidad se gestionan en el repositorio free-threaded-compatibility5
  • También se puede participar en discusiones y contribuciones en el Discord de la comunidad organizado por Quansight-Labs6

Próxima charla en PyCon

  • El autor del texto y su compañero de equipo Lysandros Nikolaou presentarán en PyCon 2025
  • Planean compartir casos prácticos de porting y aprendizajes concretos surgidos de la experiencia, y también habrá grabación en YouTube
  • Creen que la compilación free-threaded es el futuro del lenguaje Python, y les entusiasma poder contribuir a hacerlo realidad
  • Esperan que el esfuerzo de hoy se convierta en un punto de inflexión que abra el futuro de los diversos y enormes paquetes que usan millones de desarrolladores cada día

1 comentarios

 
GN⁺ 2025-05-17
Opiniones de Hacker News
  • Mucha gente usa multiprocesamiento, y se menciona que el costo de crear procesos es caro

    • Existe la función SharedMemory, y no entienden por qué no se usa más seguido

    • Se enfatiza que la experiencia usando ShareableList fue buena

    • En Unix, la velocidad de creación de procesos está por debajo de 1 ms

      • Pero iniciar un proceso del intérprete de PYTHON puede tomar entre 30 ms y 300 ms dependiendo de la cantidad de imports
      • Como hay una diferencia de uno o dos órdenes de magnitud, las cifras exactas importan
      • CGI es una excepción en este punto, y con C·Rust·Go no hay problema
      • También se comparte como ejemplo que sqlite.org usa un proceso separado por solicitud
    • ShareableList solo permite compartir escalares atómicos y bytes·cadenas

      • Los objetos estructurados de Python generan costo de serialización como pickle dump y costo de memoria duplicada por proceso
    • Hubo una experiencia de gran éxito compartiendo arreglos de numpy

      • La carga de un esquema de compartición explícita no es nada comparada con la dificultad de depurar problemas causados por compartir accidentalmente entre hilos
      • Mucha gente sobreestima qué tan buenos son los hilos frente al multiprocesamiento
      • Hay preocupación de que, si se libera el GIL, aumente la depuración de segfault aleatorios
      • Se menciona que la gente no se quejó demasiado de que JavaScript no soporte threading basado en memoria compartida
      • Se interpreta que JavaScript lo necesita menos porque es más rápido
      • Se desea que haya más esfuerzo en mejorar el rendimiento base de Python
    • Como los procesos mueren de forma independiente, si un proceso muere mientras modifica una estructura de datos en memoria compartida con un lock tomado, es difícil recuperarse

      • Se menciona como ejemplo las estructuras de memoria compartida de Postgres y la necesidad de cerrar todos los procesos backend
      • Se comenta que con los hilos este problema se percibe menos porque mueren juntos
    • La memoria compartida solo funciona en hardware dedicado

      • En entornos como AWS Fargate no hay memoria compartida, y hay que usar red o sistema de archivos, lo que aumenta la latencia
      • La duplicación de procesos con fork trae otro conjunto de problemas
      • Según experiencia real, los green threads y el modelo actor fueron mucho más efectivos
  • Hay curiosidad por si quitar el GIL tiene otros efectos en el código multihilo de Python además del procesamiento en paralelo

    • Se entiende que el GIL se mantuvo no porque el multihilo dependiera de él, sino porque quitarlo complica la implementación del intérprete y las extensiones en C, además de degradar la velocidad del código de un solo hilo

    • Se pregunta si Free-threaded Python mantiene la misma garantía existente de que puede haber desalojo en cualquier frontera de bytecode

    • O si habrá que escribir el código de otra forma, por ejemplo usando más locks

    • Free-threaded Python mantiene casi todas las mismas garantías

      • Sin free-threading, la gente usa menos el threading, así que en la práctica los bugs por desalojo en esos límites no aparecen mucho
      • Con la llegada del free-threading, saldrán a la luz más bugs
      • Ya no hará falta recurrir a rodeos con multiprocesos, así que el código de usuario se simplifica; se considera que eso justifica de sobra la mayor complejidad del intérprete
      • El problema de complejidad en extensiones C es peor con los sub-intérpretes que con free-threading; el equipo de numpy ya dijo claramente que no puede dar soporte a sub-intérpretes
      • numpy ya soporta free-threading y está corrigiendo bugs pendientes
      • Que el rendimiento de un solo hilo baje un poco (un dígito %) es un trade-off aceptable
    • Se puede aprovechar múltiples núcleos, pero con menor rendimiento por hilo y necesidad de rehacer bibliotecas

      • En pruebas con PyTorch, se observó 10 veces más uso de CPU pero solo la mitad del throughput de trabajo
      • Se espera que mejore con el tiempo, y después de esperar esto por 20 años, igual da gusto verlo llegar
    • Como las condiciones de carrera pueden aparecer con más frecuencia, hará falta más cuidado al escribir Python multihilo si se quiere garantizar confiabilidad

  • Se comparte la noticia de que Microsoft disolvió el equipo de Faster Python

    • Al parecer no se mantuvo el equipo por no cumplir las proyecciones de resultados para 2025

    • Queda por ver si se seguirán agregando mejoras de rendimiento a CPython o si otra empresa las patrocinará

    • Parece que Facebook (Meta) todavía patrocina una parte

    • Se menciona que el cronograma de Microsoft se retrasó mucho frente a sus promesas

      • Últimamente seguramente ya conocen problemas serios de política y gobernanza; se opina que empleados capaces no querrían contribuir para luego ser difamados por el grupo
      • Se critica a la organización de CPython por prometer de más, cargar de trabajo a los conformistas y apartar a opositores competentes
      • Se dice que antes esto no pasaba, y que es un problema que provocaron ellos mismos
    • Aunque es una pena, se comenta que se cumplió la expectativa personal de no confiar en los compromisos a largo plazo de Microsoft

    • Circula el rumor de que Google también despidió recientemente a todo su equipo de desarrollo de Python

      • Hay curiosidad por saber si ambos casos tienen una causa de época o algún denominador común
    • Se considera muy lamentable, pero con el matiz de que después de embrace & extend ya solo quedaba una cosa más

  • Se pregunta si uno es el único preocupado por la desaparición del GIL en Python

    • Se comenta que en cualquier lenguaje es difícil confiar en código multihilo complejo, y que en Python da aún más inseguridad por su naturaleza dinámica

    • No es la única persona que siente temor ante el cambio, aunque esa preocupación podría no ser racional

      • El GIL es pura deuda técnica, así que conviene eliminarlo por el bien de la comunidad
      • Hoy en día, en Python se usa más non blocking IO y async que hilos
      • Si no se usan hilos, quitar el GIL no cambia nada; las bibliotecas C también son seguras en un solo hilo
      • Solo hace falta cuidado si realmente se usan hilos
      • El código Python ingenuamente multihilo hasta ahora funcionaba como si fuera de un solo hilo por culpa del GIL; ahora podría volverse un poco más rápido, pero también traer más bugs
      • La recomendación es no usar hilos o, si se usan, aprender a hacerlo bien
      • Se espera que aparezcan mejores abstracciones y que en la comunidad se discutan cosas como structured concurrency
    • Se usa asyncio activamente

      • Aunque es de un solo hilo, permite escribir Python concurrente de forma agradable; se usa como Node.js
      • Para trabajo web y de red, se recomienda este enfoque
    • Se espera una estructura como en ML/IA, donde especialistas construyen primero bibliotecas complejas y luego se las entregan a usuarios comunes

      • Han aumentado los casos en los que el GIL de Python se vuelve un cuello de botella serio
      • Por eso se aprendió Go; puede verse como una abstracción más baja que Python pero más alta que C/C++, con soporte de hilos bien resuelto
      • El modelo de compilación también es un factor de fondo tan importante como el threading
    • Puede ser una alarma innecesaria, pero se recuerda que los LLM fueron entrenados con código Python escrito bajo la suposición de décadas de existencia del GIL

    • Tener o no GIL solo afecta a quienes quieren trabajo multicore

      • Si hasta ahora no se prestó atención a threading o multiprocesamiento, en la práctica no cambia nada
      • Los problemas de condiciones de carrera existen con o sin GIL
  • Se usa Python con frecuencia, pero no a nivel experto, y a veces se ejecutan varias funciones simples al mismo tiempo con concurrent.futures

    • Se pregunta qué tendría que cambiar este tipo de usuario en el futuro

    • Los hilos ya no estarán atados al GIL y en general todo será más rápido

      • Si los locks de objetos compartidos ya estaban bien manejados, no hay nada extra de qué preocuparse
  • Se comparten impresiones tras 20 años de experiencia profesional con Python

    • Cuando de verdad se necesitan hilos, suele ser solo en casos donde el paso de mensajes es inevitable

      • El ecosistema de Python ya ofrece rodeos para todas esas situaciones
      • Por todas las trampas de manejar varios hilos (locks, etc.), probablemente siga siendo algo necesario solo en ciertas bibliotecas o dominios específicos
      • Si se quiere exprimir el máximo rendimiento posible usando Python puro, se pueden aprovechar bibliotecas basadas en código nativo (por ejemplo, Pypy, numba)
      • La verdadera revolución de rendimiento en Python ha sido la programación async; se recomienda aprenderla sí o sí
    • Otra persona dice haber usado Python durante un tiempo similar y estar de acuerdo, aunque lo formularía distinto

      • Los hilos en Python siempre fueron tan malos que surgieron muchas soluciones indirectas para evitarlos
      • Al intentar duplicar la velocidad de trabajo CPU-bound con hilos, se chocó con el GIL y se terminó migrando a multiprocesamiento; eso trajo costos por serializar estructuras de datos y experiencias ineficientes como 1.5x de velocidad usando el doble de núcleos
      • Hay muchos entornos donde sí se quisiera aprovechar un buen soporte de hilos; como no existía, se usaron varios enfoques alternativos
      • Se recomienda fuertemente usar async cuando la situación lo permita (¡glyph, tenías razón!)
  • Aunque es una imagen de IA, llama la atención que la serpiente tenga dos colas

    • Hay una respuesta de apoyo diciendo que mejor lo dejen pasar; se comenta en tono de broma que cuando un artículo sobre Python trae un dibujo de serpiente, normalmente es una señal de que no vale mucho la pena prestarle atención

    • Se propone en broma el nombre Confusoborus

  • Se señala que la serpiente de la imagen de encabezado parece tener dos colas

    • Se bromea con que parece que creó un segundo hilo dentro del mismo proceso
  • Más allá del soporte de bibliotecas, se pregunta si hay otras restricciones para correr workers de WSGI y Celery en un solo proceso

    • No hay restricciones, pero se comenta que esta forma de trabajar no es una capacidad de primera clase del lenguaje
      • Se explica que el GIL es un problema de deuda técnica
      • También hay aspectos, aparte del paralelismo, que requieren eliminar el GIL
  • Se considera que esto es un enorme trabajo de base para la próxima era del rendimiento