Programação e desenvolvimento de software

Como usar Numba para acelerar modelos computacionais de Python em serviços financeiros

Chad Schuster, da Milliman, explica como a Numba pode transformar partes de programas Python em código otimizado por meio do LLVM, aproveitando o processamento paralelo e as unidades de GPU. A experiência apresenta ganhos significativos de desempenho, mas também revela limitações na programação orientada a objetos, na inferência de tipos e no tempo de compilação, o que torna a escolha das partes adequadas para aceleração um fator decisivo.

2026-08-27
6 min de leitura
3,914 visualizações
certi.news Editorial Team
Como usar Numba para acelerar modelos computacionais de Python em serviços financeiros

Chad Schuster, Principal na prática de gestão de riscos financeiros da Milliman, apresentou uma experiência prática de construção de modelos computacionais de alto desempenho usando Python e Numba, em vez de depender integralmente de aplicações escritas em C++. A experiência parte de um problema comum nos serviços financeiros: modelos que simulam fluxos de caixa em um grande número de cenários exigem muita capacidade computacional, enquanto as equipes desejam manter a velocidade de desenvolvimento e a facilidade de manutenção do Python.

O problema é especialmente relevante em modelos de seguros de vida e produtos de aposentadoria, como annuities, nos quais os cálculos são usados para avaliar obrigações futuras e executar vários cenários. Segundo a apresentação, as seguradoras historicamente dependiam de redes locais com entre 5.000 e 10.000 nós, mas a migração para a nuvem tornou o tempo de execução e o custo de cada operação mais evidentes nas decisões de infraestrutura.

O que a Numba acrescenta ao Python?

O Python tradicional, ou CPython, interpreta o código durante a execução, enquanto linguagens compiladas como C++ transformam o código em instruções de máquina antes da execução. A Numba tenta reduzir essa diferença por meio da compilação Just-in-Time, pois compila as funções elegíveis durante a execução do programa usando o LLVM e, em seguida, substitui a função original pela implementação compilada.

O desenvolvedor normalmente ativa esse processo por meio de decoradores do Python, como JIT ou njit. A Numba opera no nível da função: examina o código e o transforma em uma representação intermediária própria; depois infere os tipos das variáveis, dos parâmetros e dos valores de retorno, antes de reduzir a representação para LLVM IR e realizar as otimizações necessárias. Se a função for chamada com tipos diferentes, a Numba pode criar implementações compiladas especializadas para cada conjunto de tipos, por meio do que chama de polymorphic dispatch.

Os ganhos de desempenho não são um número fixo

Na prova de conceito apresentada por Schuster, a Numba tornou o programa aproximadamente 75 vezes mais rápido em comparação com o Python interpretado. Em outro modelo, o resultado foi diferente: transferir os cálculos numéricos intensivos para a Numba na CPU produziu uma aceleração de aproximadamente duas vezes; depois, a migração para a GPU gerou uma aceleração adicional de 750 vezes naquela execução específica. A apresentação afirmou que esse nível de melhoria fez com que uma unidade de GPU equivalesse aproximadamente a 750 núcleos usados naquela execução, com uma redução estimada do custo para cerca de um décimo.

No entanto, esses resultados não representam uma promessa geral para todas as aplicações. A melhoria depende da quantidade de código compilável, do volume das operações computacionais em comparação com as operações de entrada e saída, da eficiência do Python original e da capacidade do LLVM de otimizar o código resultante. Além disso, o processamento em GPU não é adequado para todos os algoritmos; por isso, o gargalo real deve ser medido antes de o modelo ser redesenhado.

O que muda na prática para as equipes de engenharia?

A experiência recomenda manter em Python as camadas de preparação de dados, entradas e saídas, transferindo para a Numba apenas a parte numericamente intensiva sempre que possível. Essa abordagem reduz o escopo da reescrita e preserva grande parte do ambiente Python, enquanto concentra o esforço de otimização nas funções que consomem a maior parte do tempo de execução. Quando as funções numéricas são limitadas e claras, Schuster considera que experimentar a Numba pode ser uma opção direta para quem deseja permanecer no Python.

Já quando uma lógica ampla e complexa é introduzida na Numba, aumentam os custos de projeto e manutenção. A experiência recorreu a arrays do NumPy, tuples e estruturas de dados simples, porque o suporte da Numba não abrange todos os recursos do Python. Entre as limitações mencionadas estão dicionários com tipos flexíveis, exceções, gerenciadores de contexto, closures e listas criadas por comprehensions, além do suporte limitado a algumas funções comuns, como print, sorted e getattr.

Limitações que devem ser consideradas antes da adoção

A programação orientada a objetos continua sendo um ponto fraco importante nessa experiência. A Numba oferece recursos experimentais, como jitclasses e structrefs, para proporcionar um comportamento semelhante ao de objetos, mas eles podem mudar entre versões e não oferecem suporte a GPU, o que os tornou inadequados para a abordagem adotada pela equipe. Por isso, a aplicação adotou um estilo mais próximo da programação funcional e estruturas de dados simples, embora o design orientado a objetos fosse desejável por razões relacionadas à manutenção e à entrega dos modelos aos clientes.

Além disso, erros de inferência de tipos e erros de lowering podem ser difíceis de rastrear, especialmente em programas com muitas camadas de chamadas. O erro pode apontar para uma função distante do local em que o problema realmente surgiu. Uma abordagem prática sugerida é usar JIT em vez de njit quando necessário, permitindo desativar temporariamente a Numba e retornar ao Python interpretado para facilitar a depuração, reativando depois a aceleração na execução de produção.

Também existe um tempo inicial de compilação que ocorre na primeira chamada de cada função e pode aumentar quando a técnica de inlining é usada em larga escala. É possível recorrer à compilação Ahead-of-Time para evitar esse atraso, mas isso pode reduzir a capacidade do código de se adaptar ao dispositivo efetivamente utilizado, em comparação com a compilação Just-in-Time.

Leitura editorial: o principal valor dessa experiência não está no número de 750 vezes em si, mas na abordagem que relaciona a medição de desempenho à divisão do modelo. A Numba é adequada quando o gargalo é computacional e pode ser isolado em funções com tipos e estruturas claros; já transformar todo um sistema Python em código compilável pode transferir o problema da lentidão de execução para a complexidade do desenvolvimento e da depuração. Portanto, as equipes financeiras e de engenharia devem equilibrar velocidade de execução, facilidade de manutenção, tempo de compilação e compatibilidade com GPU antes de considerá-la uma alternativa abrangente ao C++ ou a uma reformulação mais ampla do sistema.

Fonte da notícia
InfoQ - Architecture Articles
Abrir fonte original ↗
c
Autor

certi.news Editorial Team

O que você precisa saber

A experiência mostra que Numba pode acelerar funções computacionalmente intensivas em Python por meio de compilação just-in-time usando LLVM, com possibilidade de aproveitar a CPU e GPUs. No entanto, os ganhos variam conforme a natureza do algoritmo, enquanto Numba impõe limitações à programação orientada a objetos e a alguns recursos do Python. Por isso, é recomendável isolar as partes computacionais e medir o gargalo antes de adotá-la.

  • Numba usa compilação just-in-time para converter funções compatíveis em código otimizado por meio do LLVM.
  • A experiência mostrou uma aceleração de cerca de 75 vezes em um caso, e uma aceleração próxima de duas vezes na CPU, seguida de 750 vezes adicionais na GPU em uma execução específica.
  • O preparo dos dados e as entradas e saídas devem permanecer em Python, enquanto apenas os cálculos numéricos intensivos devem ser transferidos para Numba.
  • Há limitações relacionadas a dicionários flexíveis, exceções, gerenciadores de contexto e algumas funções comuns. O suporte à programação orientada a objetos e a recursos de GPU também é limitado.
  • Erros de inferência de tipos e operações de lowering podem ser difíceis de diagnosticar, e a primeira chamada pode acrescentar tempo de compilação.
  • Os resultados exigem medição prática, pois a aceleração por GPU não é adequada para todos os algoritmos, e os números de desempenho não representam uma promessa geral.

Perguntas frequentes

O que Numba faz com programas Python?

Converte funções compatíveis, durante a execução, em código otimizado usando compilação just-in-time e tecnologias do LLVM.

Numba sempre proporciona uma grande aceleração?

Não. A melhoria depende da proporção de código compilável, da intensidade computacional, da eficiência do Python original, da capacidade do LLVM e da adequação do algoritmo ao processamento em GPU.

Qual é a abordagem prática recomendada para usar Numba?

A apresentação recomenda manter as camadas de preparação de dados e as entradas e saídas em Python, transferindo para Numba as funções numéricas que consomem a maior parte do tempo de execução.

Quais são as principais limitações a considerar?

As limitações incluem o suporte restrito a alguns recursos do Python, a dificuldade de rastrear erros de tipos e operações de lowering, o tempo inicial de compilação e a menor adequação de alguns recursos de programação orientada a objetos e de GPU.

Explore esta história

Tópicos e entidades relacionados

Na mesma categoria

Você também pode gostar

Ver todas as notícias