5 pontos por GN⁺ 2025-05-17 | 1 comentários | Compartilhar no WhatsApp
  • O Python free-threaded foi projetado para aproveitar com eficiência hardware multicore
  • No CPython 3.14, a segurança de threads e o desempenho dos módulos centrais melhoraram bastante
  • Ainda há muitos pacotes importantes que não oferecem suporte ao build free-threaded
  • Qualquer pessoa pode ajudar no avanço por meio de relatos de uso em produção e contribuições da comunidade

Visão geral

Na semana passada, foi lançado o CPython 3.14.0b1, e nesta semana a PyCon 2025 começa em Pittsburgh
Esses dois eventos são marcos importantes para a distribuição e a estabilização do Python free-threaded
Este artigo relembra o último ano e explica como a equipe da Quansight teve um papel central ao aplicar experimentalmente o build free-threaded a workflows reais de produção com dependências complexas

O que é e por que o Python free-threaded é necessário

  • O suporte ao Python free-threaded permite usar todos os recursos computacionais do hardware moderno, em que CPUs e GPUs multicore se tornaram comuns
  • No modelo tradicional com o GIL (Global Interpreter Lock), era necessário recorrer a contornos e ajustes extras para aproveitar totalmente algoritmos paralelos
  • Em geral, usava-se mais multiprocessing do que o módulo threading, mas isso tem alto custo de criação de processos e cópia de dados ineficiente
  • Quando um pacote Python inclui código nativo, o build free-threaded não é imediatamente compatível, portanto é indispensável fazer uma auditoria de código para garantir a segurança de threads
  • A remoção do GIL exigiu mudanças estruturais profundas no interpretador CPython e também acabou revelando problemas estruturais em pacotes existentes

Principais avanços

  • Junto com a equipe de runtime Python da Meta, foi adicionada compatibilidade com Python free-threaded em diversos pacotes e projetos, como os abaixo
    • Ferramentas de empacotamento e workflow, como meson, meson-python, setup-python GitHub Actions, packaging, pip e setuptools
    • Geradores de bindings, como Cython, pybind11, f2py e PyO3
    • Pacotes centrais do ecossistema PyData, como NumPy, SciPy, PyArrow, Matplotlib, pandas, scikit-learn e scikit-image
    • Dependências importantes entre os pacotes mais baixados do PyPI, como Pillow, PyYAML, yarl, multidict e frozenlist
  • O trabalho também avança gradualmente em pacotes populares que ainda não oferecem suporte (CFFI, cryptography, PyNaCl, aiohttp, SQLAlchemy, grpcio etc.) e em bibliotecas de machine learning (como safetensors e tokenizers)
  • Os desenvolvedores centrais do CPython da equipe Quansight incorporaram as seguintes melhorias na versão 3.14
    • O módulo warnings agora funciona com segurança de threads por padrão no build free-threaded
    • Correções de problemas graves de segurança de threads no asyncio e aumento da escalabilidade paralela
    • Melhoria ampla da segurança de threads no módulo ctypes
    • Melhor desempenho do coletor de lixo free-threaded
    • Otimizações no esquema de deferred reference counting e no adaptive specializing interpreter
    • Muitas correções de bugs e reforços adicionais de segurança de threads
  • Também foi produzido um guia abrangente1 para suporte a Python free-threaded, oferecendo documentação que pode servir de referência prática para muitos outros pacotes no futuro

Situação atual do ecossistema Python free-threaded

  • Há um ano, quando saiu o 3.13.0b1, a instalação da maioria dos pacotes Python no build free-threaded estava totalmente quebrada
  • As falhas de build não eram, na maior parte, causadas por problemas fundamentais, mas por opções padrão não suportadas ou pequenas suposições que deixaram de valer
  • Ao longo do último ano, muitos problemas foram resolvidos em colaboração com a comunidade, e a compatibilidade oficial do Cython 3.1.0 marcou um ponto de virada importante
  • Ainda restam pacotes com código compilado que não fornecem wheels free-threaded
    O andamento deles pode ser acompanhado em tabelas de rastreamento manuais e automáticas2

Desafios imediatos

  • Hoje, o build free-threaded do Python está em uma fase que ainda exige experimentação e feedback em workflows reais
  • Há potencial de ganho de desempenho especialmente em workflows em que o custo do uso de multiprocessos é alto, mas uma auditoria detalhada de estabilidade entre threads para cada pacote continua sendo essencial
  • Muitas bibliotecas oferecem estruturas de dados mutáveis, mas ainda têm documentação insuficiente sobre segurança de threads ou não garantem isso de fato
  • Quando o pacote é grande e tem muito legado, costuma faltar gente capaz de compreender completamente o código, o que atrasa o suporte
  • Em nível de comunidade, são necessários esforços para a sustentabilidade da manutenção de pacotes essenciais

Como contribuir

  • É possível consultar o guia de contribuição do guia oficial
  • O rastreamento de problemas de todo o ecossistema e os principais documentos de compatibilidade são mantidos no repositório free-threaded-compatibility5
  • Também é possível participar das discussões e contribuir no Discord da comunidade6, organizado pela Quansight-Labs

Próxima apresentação na PyCon

  • O autor do texto e seu colega de equipe Lysandros Nikolaou farão uma apresentação na PyCon 2025
  • O plano é compartilhar casos práticos de porting e know-how derivados da experiência, e também será disponibilizada uma gravação no YouTube
  • Eles acreditam que o build free-threaded é o futuro da linguagem Python e demonstram grande entusiasmo por poder contribuir para torná-lo realidade
  • Esperam que o esforço de hoje se torne um ponto de virada que abra o futuro de pacotes diversos e vastos, usados diariamente por milhões de desenvolvedores

1 comentários

 
GN⁺ 2025-05-17
Comentários do Hacker News
  • Muitas pessoas usam multiprocessamento, mas foi mencionado que o custo de criar processos é alto

    • Existe a funcionalidade SharedMemory, e não entendem por que ela não é usada com mais frequência

    • Destacam que tiveram uma boa experiência com ShareableList

    • Em Unix, a criação de processos leva menos de 1 ms

      • Mas iniciar um processo do interpretador Python pode levar de 30 ms a 300 ms, dependendo da quantidade de imports
      • Como a diferença é de uma ou duas ordens de grandeza, os números exatos importam
      • CGI é uma exceção nesse ponto, e com C·Rust·Go isso não é um problema
      • Também compartilham o exemplo de que o sqlite.org usa um processo separado por requisição
    • ShareableList só permite compartilhar escalares atômicos e bytes·strings

      • Objetos estruturados do Python geram custo de serialização, como pickle dump, além do custo de memória duplicada por processo
    • Relato de grande sucesso ao compartilhar arrays do numpy

      • O compartilhamento explícito não é um fardo se comparado à dificuldade de depurar problemas causados por compartilhamento acidental entre threads
      • Muita gente superestima o quanto threads são melhores do que multiprocessamento
      • Há preocupação de que, com a remoção do GIL, aumente a depuração de segfault aleatórios
      • Mencionam que as pessoas não reclamaram tanto de o JavaScript não oferecer threading baseado em memória compartilhada
      • A interpretação é que o JavaScript é rápido o bastante para precisar menos disso
      • Gostariam de ver mais esforço em melhorar o desempenho básico do Python
    • Como processos morrem de forma independente, se um processo morrer enquanto modifica uma estrutura de dados em memória compartilhada com um lock adquirido, a recuperação é difícil

      • Citam como exemplo as estruturas de memória compartilhada do Postgres e a necessidade de encerrar todos os processos de backend
      • Como threads morrem juntas, esse tipo de problema tende a ser menos percebido
    • Memória compartilhada só funciona em hardware dedicado

      • Em ambientes como AWS Fargate não há memória compartilhada; é preciso usar rede ou sistema de arquivos, o que aumenta a latência
      • A duplicação de processos via fork traz outro conjunto de problemas
      • Pela experiência prática, green threads e o modelo de atores foram muito mais eficazes
  • Há curiosidade sobre se remover o GIL terá outros efeitos no código multithread em Python além do paralelismo

    • O entendimento é que o GIL foi mantido não porque o multithreading dependesse dele, mas porque removê-lo prejudica a implementação do interpretador, as extensões em C e a velocidade do código single-thread

    • Perguntam se o Free-threaded Python mantém a mesma garantia anterior de poder ser preemptado em qualquer fronteira de bytecode

    • Ou se a forma de escrever muda, como exigir mais locks

    • O Python free-threaded mantém em grande parte as mesmas garantias

      • Porém, sem free-threading, as pessoas usam menos threading, então bugs de preempção nas fronteiras quase não aparecem na prática
      • Com a adoção do free-threading, mais bugs ficam expostos
      • Como deixa de ser necessário recorrer a soluções de multiprocessamento, o código de usuário fica mais simples; consideram que isso compensa o aumento da complexidade do interpretador
      • O problema de complexidade nas extensões em C é mais grave com sub-interpreters do que com free-threading; a equipe do numpy declarou claramente que não consegue dar suporte a sub-interpreters
      • O numpy já oferece suporte a free-threading e está corrigindo os bugs restantes
      • A leve perda de velocidade em single-thread (alguns poucos %) é vista como um trade-off aceitável
    • É possível usar múltiplos núcleos, mas há perda de desempenho por thread e necessidade de retrabalho nas bibliotecas

      • Em experimentos com PyTorch, relataram usar 10x mais CPU para obter metade da vazão de trabalho
      • Esperam melhorias com o tempo e comemoram, já que esperavam por isso havia 20 anos
    • Como condições de corrida podem ocorrer com mais frequência, será preciso mais cuidado ao escrever Python multithread para garantir confiabilidade

  • Compartilham a notícia de que a Microsoft dissolveu a equipe Faster Python

    • A equipe não foi mantida por não ter atingido a expectativa de desempenho para 2025

    • Vão observar se melhorias de desempenho continuarão sendo adicionadas ao CPython, ou se outras empresas vão patrocinar isso

    • Parece que o Facebook (Meta) ainda patrocina parte do trabalho

    • Mencionam que o cronograma atrasou bastante em relação ao que a Microsoft havia prometido

      • Dizem que recentemente a empresa deve ter percebido problemas sérios de política e governança; na opinião deles, funcionários competentes não quereriam contribuir à toa para depois ver o grupo ser difamado
      • Criticam a organização do CPython por prometer demais, concentrar trabalho em pessoas conformistas e afastar opositores competentes
      • Dizem que antes esses problemas não existiam e que a situação atual foi criada pelo próprio grupo
    • Lamentam o resultado, mas comentam que a própria expectativa de não confiar no compromisso de longo prazo da Microsoft acabou se confirmando

    • Há rumor de que o Google também demitiu toda a equipe de desenvolvimento Python recentemente

      • Ficam se perguntando se existe uma causa de época ou algum denominador comum entre os dois casos
    • Consideram muito lamentável, mas com a nuance de que, depois de embrace & extend, só restaria uma coisa

  • Perguntam se são os únicos preocupados com o desaparecimento do GIL no Python

    • Em qualquer linguagem, código multithread complexo é difícil de confiar, e no Python isso parece ainda mais incerto por causa de seu caráter dinâmico

    • Respondem que não são os únicos a ter medo da mudança, embora o fundamento possa ser irracional

      • O GIL é pura dívida técnica, então precisa ser removido em benefício da comunidade
      • Hoje em dia, na maior parte do Python, usa-se async e non-blocking IO em vez de threads
      • Se você não usa threads, a remoção do GIL não muda nada; bibliotecas em C também continuam seguras em single-thread
      • Só é preciso tomar cuidado se realmente usar threads
      • Código Python com threads escrito de forma ingênua vinha funcionando como se fosse single-thread por causa do GIL; agora pode ficar um pouco mais rápido, mas também pode ganhar mais bugs
      • A solução é não usar threads ou, se usar, aprender a usá-las corretamente
      • Esperam que no futuro surjam abstrações melhores, e que a comunidade discuta mais coisas como structured concurrency
    • Dizem que usam asyncio ativamente

      • Mesmo sendo single-thread, é possível escrever Python concorrente de forma agradável; usam de maneira parecida com Node.js
      • Recomendam essa abordagem para trabalho web e de rede
    • Esperam uma estrutura como a de ML/IA, em que especialistas primeiro constroem bibliotecas complexas e depois as entregam aos usuários em geral

      • Os casos em que o GIL do Python vira gargalo sério aumentaram bastante
      • Por isso aprenderam a linguagem Go; ela oferece suporte real a threads, é mais de baixo nível que Python, mas mais abstrata que C/C++
      • A forma compilada da linguagem também é um fator de fundo tão importante quanto threading
    • Lembram que isso pode soar como alarme desnecessário, mas destacam o fato de que LLMs foram treinados com código Python escrito ao longo de décadas assumindo a existência do GIL

    • A existência ou não do GIL só importa para quem quer trabalho multicore

      • Se você já não ligava para threading ou multiprocessamento, na prática nada muda
      • Problemas de race condition existem independentemente de haver GIL ou não
  • Dizem que usam Python com frequência, mas não são especialistas, e às vezes apenas executam várias funções simples em paralelo com concurrent.futures

    • Perguntam o que alguém assim precisará mudar daqui para frente

    • Como as threads deixam de ficar presas ao GIL, tudo fica mais rápido no geral

      • Se os locks de objetos compartilhados já forem tratados corretamente, não há motivo para preocupação extra
  • Compartilham impressões de 20 anos trabalhando profissionalmente com Python

    • Quando threads realmente são necessárias, isso costuma ficar restrito a casos em que passagem de mensagens é inevitável

      • O ecossistema Python já oferece saídas para todas essas situações
      • Por causa das várias armadilhas no uso de múltiplas threads (locks etc.), isso talvez continue necessário só em bibliotecas e domínios específicos
      • Para extrair o máximo de desempenho em Python puro, ainda é possível usar bibliotecas baseadas em código nativo (ex.: Pypy, numba)
      • A grande revolução de desempenho do Python acabou sendo a programação assíncrona; recomendam muito aprender isso
    • Outro comentário diz que também usa Python há um tempo parecido e concorda, mas com uma formulação um pouco diferente

      • Como as threads em Python sempre foram muito ruins, várias soluções alternativas foram desenvolvidas para evitá-las
      • Ao tentar dobrar a velocidade de trabalho CPU-bound com threads, esbarraram no GIL e migraram para multiprocessamento; isso trouxe custos de serialização de estruturas de dados e experiências ineficientes, como 2x núcleos para 1,5x de ganho
      • Se houver um bom suporte a threads, há muitos ambientes em que gostariam de usá-lo; como isso não existia até agora, recorreram a várias abordagens substitutas
      • Recomendam fortemente usar async quando fizer sentido (glyph, você estava certo!)
  • Embora seja uma imagem gerada por IA, acham estranho a cobra ter duas caudas

    • Outro comentário apoia em tom de brincadeira: é melhor deixar quieto; quando um artigo sobre Python vem com desenho de cobra, isso geralmente é um sinal de que não vale muito a pena levar tão a sério

    • Sugerem em tom de piada o nome Confusoborus

  • Apontam que a cobra da imagem de cabeçalho parece ter duas caudas

    • Fazem a brincadeira de que ela parece ter criado uma segunda thread dentro do mesmo processo
  • Perguntam se, além do suporte de bibliotecas, há outras restrições para executar workers de WSGI e Celery em um único processo

    • Não haveria restrições, mas esse tipo de uso ainda não é um recurso de primeira classe da linguagem
      • Explicam que o GIL é um problema de dívida técnica
      • Há também outros elementos além do paralelismo que exigem a remoção do GIL
  • Consideram isso uma enorme fundação para a próxima era de desempenho