Skip to content
Otavio Junqueira C Leao edited this page Nov 25, 2025 · 17 revisions

Modelos de Previsão de Produção de Reservatórios de Petróleo

Breve Descrição

A previsão da produção de um reservatório de petróleo é uma tarefa fundamental na indústria de óleo e gás, servindo como base para o planejamento estratégico, a gestão de ativos e a tomada de decisões de investimento. Estimar com precisão a produção futura permite otimizar a recuperação de hidrocarbonetos, gerenciar custos operacionais e avaliar a viabilidade econômica de projetos, que envolvem bilhões de dólares.

No entanto, prever o comportamento de um reservatório é um desafio complexo. A produção é o resultado de interações não-lineares entre a geologia do campo, a física dos fluidos multifásicos (óleo, gás e água) e as intervenções operacionais (como a injeção de água). Os dados brutos, geralmente provenientes de simuladores de reservatório (em formatos como .sr3), consistem em vastos conjuntos de séries temporais multivariadas para centenas ou milhares de elementos, como poços (WELLS), grupos de poços (GROUPS) ou camadas do reservatório. As variáveis incluem taxas de produção de óleo (WOPR), água (WWPR) e gás (WGPR), pressão de fundo de poço (WBHP), corte de água (WWCT), entre muitas outras.

Tradicionalmente, a indústria utiliza a Análise de Curva de Declínio (ACD), como as curvas de Arps, que se baseiam em modelos matemáticos empíricos (exponencial, hiperbólico) ajustados aos dados históricos de produção. Embora simples e rápidas, essas técnicas são univariadas e frequentemente falham em capturar a complexidade física do reservatório, como os efeitos do suporte de pressão de poços injetores ou a interferência entre poços.

Este projeto propõe uma abordagem moderna utilizando Machine Learning para análise de séries temporais. O objetivo é superar as limitações dos métodos tradicionais, criando modelos capazes de aprender as relações complexas e não-lineares entre as múltiplas variáveis que influenciam a produção.

O sistema oferece um pipeline completo que inclui: a leitura e interpretação de arquivos de simulação (formato .sr3); o processamento e enriquecimento dos dados brutos; o treinamento e a avaliação comparativa de diferentes arquiteturas de modelos (como Redes Neurais Artificiais do tipo MLP e LSTM); e a geração de visualizações para análise dos resultados.

A ferramenta foi concebida para atender principalmente a engenheiros de reservatórios, pesquisadores em geociências e cientistas de dados que atuam na indústria de óleo e gás, facilitando a análise de cenários e a tomada de decisão. Atualmente, o projeto se encontra no estágio de uma prova de conceito robusta, funcionando como um módulo de sistema que pode ser expandido e integrado a fluxos de trabalho de análise mais complexos.

Ressalva: Os modelos foram treinados e validados com um conjunto de dados de simulação interno. Sua aplicação a campos com características geológicas ou de produção muito distintas pode exigir re-treinamento ou ajustes, uma vez que a performance depende diretamente da qualidade e variedade dos dados de entrada.

Visão de Projeto

Para ilustrar a aplicação prática e as limitações deste projeto, a seção a seguir apresenta quatro cenários de uso. Os cenários positivos descrevem situações de sucesso, demonstrando como diferentes perfis de usuários podem se beneficiar da ferramenta para atingir seus objetivos. Em contrapartida, os cenários negativos expõem limitações conhecidas do sistema, ajudando a alinhar as expectativas e a orientar futuras melhorias.

Cenário Positivo 1

Carlos, um engenheiro de reservatórios, recebe um novo conjunto de simulações para um campo em desenvolvimento. Ele executa o script principal do projeto, que automaticamente processa os novos arquivos, re-treina os modelos existentes e gera um dashboard comparando a previsão de produção de óleo e água para os próximos 5 anos. Com os gráficos, ele rapidamente identifica os cenários de simulação mais otimistas e pessimistas para apresentar em sua reunião.

Cenário Positivo 2

Ana, uma pesquisadora de mestrado, quer testar uma nova arquitetura de rede neural para séries temporais. Ela clona o repositório, cria uma nova classe de modelo seguindo a interface já definida, adiciona a configuração do novo modelo ao arquivo de ambiente e executa o pipeline de treinamento. O sistema treina seu modelo junto com os outros, permitindo que ela compare diretamente as métricas de erro e os gráficos de resíduos, validando sua hipótese de forma rápida.

Cenário Negativo 1

João tenta usar o modelo pré-treinado em dados de um campo muito antigo, com pouca variedade de cenários de injeção de água. O modelo prevê uma produção estável, mas na realidade o campo sofreu um colapso na produção. Isso ocorre porque o modelo não foi exposto a esse tipo de comportamento nos dados de treino e não conseguiu generalizar para essa situação 'fora da curva'.

Cenário Negativo 2

Mariana tenta rodar o processamento de dados em seu notebook local com 8GB de RAM, usando 1000 arquivos de simulação de alta resolução. O processo falha com um erro de MemoryError. O sistema foi projetado para rodar em servidores com mais memória ou usando Dask para processamento distribuído, e o processamento de um volume tão grande em uma máquina com recursos limitados não é suportado nativamente.

Documentação Técnica do Projeto

Esta seção da Wiki se destina a desenvolvedores, pesquisadores e outros usuários técnicos que desejam compreender, reutilizar ou estender o projeto. As subseções a seguir detalham os requisitos do software, sua arquitetura, o fluxo de dados e as tecnologias utilizadas, fornecendo uma visão aprofundada do sistema.

Especificação dos requisitos funcionais e não-funcionais

Requisitos Funcionais

  • RF01: O sistema deve ser capaz de ler e interpretar arquivos de simulação de reservatório no formato .sr3.
  • RF02: O sistema deve ser capaz de calcular propriedades derivadas (como WATERCUT) dos dados brutos.
  • RF03: O sistema deve processar os dados brutos e salvá-los em um formato otimizado (Parquet) para consumo posterior.
  • RF04: O sistema deve permitir o treinamento simultâneo de múltiplos modelos de Machine Learning (e.g., MLP, LSTM) implementados em diferentes frameworks (TensorFlow, PyTorch).
  • RF05: O sistema deve permitir a adição de novos modelos de forma modular, sem a necessidade de alterar o pipeline principal.
  • RF06: O sistema deve gerar previsões da curva de produção de óleo com base nos modelos treinados.
  • RF07: O sistema deve gerar e salvar em disco um dashboard visual com gráficos (e.g., predição vs. real, resíduos) para cada modelo treinado.

Requisitos Não-Funcionais

  • RNF01 (Desempenho): O processamento de dados deve ser paralelizado para otimizar o uso de múltiplos núcleos de CPU.
  • RNF02 (Configurabilidade): Todos os parâmetros críticos (caminhos de diretórios, hiperparâmetros do modelo, features) devem ser configuráveis externamente através de um arquivo .env.
  • RNF03 (Extensibilidade): A arquitetura deve seguir um padrão que facilite a adição de novos tipos de gráficos, pré-processadores ou modelos.
  • RNF04 (Reprodutibilidade): O ambiente de execução e suas dependências devem ser gerenciados pelo pipenv para garantir a consistência entre diferentes máquinas.

Modelo de arquitetura, dados e semântica

graph TD
    subgraph "Entrada de Dados Brutos"
        direction LR
        A1[Arquivos de Simulação .sr3]
    end

    subgraph "1 Geração de Dataframes (ETL)"
        direction TB
        B1(pipenv run model-1-generate-dataframes) --> B2{FileScanner};
        B2 --> B3{SimulationReader};
        B3 --> B4{ScriptProperties};
        B4 --> B5(Dataframes Parquet);
    end

    subgraph "2 Pipeline de Treinamento e Avaliação"
        direction TB
        C1(pipenv run model-2-train) --> C2(ModelGenController);
        C2 --> C3(DataLoader);
        C3 --> C4(Preprocessor);
        C4 --> C5(Models);
        subgraph "Modelos de ML"
            direction LR
            C5_TF(TensorFlow Models)
            C5_PT(PyTorch Models)
        end
        C5 --> C5_TF & C5_PT
        C2 --> C6(Resultados do Treinamento);
    end

    subgraph "3 Geração de Relatórios"
        direction TB
        D1(pipenv run model-2-train) --> D2(PresentationGridDashboard);
        D2 --> D3(Plotters);
        D2 --> D4(PresentationFileSharer);
        D4 --> D5(Gráficos Salvos .png);
    end

    subgraph "Configuração Central"
        E1(configs/Environment.py)
        E2(Arquivos .env)
        E2 --> E1
    end

    subgraph "Servidor de API"
        F1(main.py - FastAPI) --> F2(Routers)
        F2 -- Futuramente --> C2
    end

    A1 --> B1;
    B5 --> C3;
    C6 --> D2;

    E1 --> B1 & C1 & F1;

    classDef default fill:#f9f9f9,stroke:#333,stroke-width:2px;
    classDef input fill:#d4edda,stroke:#155724;
    classDef output fill:#f8d7da,stroke:#721c24;
    classDef process fill:#cce5ff,stroke:#004085;
    class A1,B5,D5 input;
    class B1,C1,F1 process;
    class D4,D2,D3,C2,C3,C4,C5,B2,B3,B4,F2,E1,E2 default;
Loading
  • Scripts de Execução (pipenv run ...): São os pontos de entrada que orquestram os diferentes processos (geração de dataframes, treinamento, etc.).
  • Configuração (configs/Environment.py): Centraliza todas as configurações do projeto (caminhos de arquivos, hiperparâmetros, etc.) usando Pydantic, carregando variáveis de arquivos .env.
  • Processamento de Dados Brutos:
    • FileScanner: Localiza os arquivos de simulação brutos (ex: .sr3).
    • SimulationReader: Lê e interpreta os diferentes formatos de arquivos de simulação.
    • ScriptProperties: Adiciona o cálculo de propriedades derivadas (como WATERCUT) aos dados lidos.
  • Pipeline de Treinamento (ModelGenController):
    • DataLoader (OilPredModelDataLoader): Responsável por carregar os dados já processados (arquivos Parquet) para o treinamento.
    • Preprocessor (OilPredModelPreprocessor): Executa a limpeza, normalização (scaling), criação de janelas deslizantes (sequências) e divisão dos dados em treino, validação e teste.
    • Models (ex: OilPredTensorFlowMLPSimpleModel, OilPredPyTorchLSTMModel): As implementações dos modelos de Machine Learning. A arquitetura permite que vários modelos sejam treinados e comparados.
  • Módulo de Apresentação (core/presentation):
    • Plotters (ex: PresentationScatterPlot): Componentes para criar visualizações específicas (gráficos de dispersão, resíduos).
    • Dashboard (PresentationGridDashboard): Agrupa múltiplos gráficos em um único painel.
    • Sharer (ex: PresentationFileSharer): Salva os resultados (gráficos) em disco.
  • API (FastAPI):
    • main.py: Ponto de entrada da API.
    • Routers: Organizam os endpoints da API (não totalmente detalhado no contexto, mas a estrutura está presente).

Modelo funcional do software

O software oferece duas operações principais ao usuário, acessíveis através dos scripts definidos no Pipfile:

  1. Geração de Dataframes: O usuário pode executar pipenv run model-1-generate-dataframes para converter um diretório de arquivos .sr3 brutos em um conjunto de dados processado e otimizado (arquivos Parquet), que fica pronto para a etapa de treinamento.

  2. Treinamento e Avaliação: Ao executar pipenv run model-2-train, o usuário dispara o pipeline completo que carrega os dataframes, treina todos os modelos configurados, avalia sua performance e gera um dashboard visual com os resultados para cada modelo.

Modelo de Fluxo

O diagrama a seguir ilustra o fluxo de trabalho principal, desde a entrada de dados brutos até a geração dos relatórios visuais.

graph TD
    subgraph "Entrada de Dados Brutos"
        direction LR
        A1(Arquivos de Simulação .sr3)
    end

    subgraph "1 Geração de Dataframes (ETL)"
        direction TB
        B1(pipenv run model-1-generate-dataframes) --> B2{FileScanner};
        B2 --> B3{SimulationReader};
        B3 --> B4{ScriptProperties};
        B4 --> B5(Dataframes Parquet);
    end

    subgraph "2 Pipeline de Treinamento e Avaliação"
        direction TB
        C1(pipenv run model-2-train) --> C2(ModelGenController);
        C2 --> C3(DataLoader);
        C3 --> C4(Preprocessor);
        C4 --> C5(Models);
        subgraph "Modelos de ML"
            direction LR
            C5_TF(TensorFlow Models)
            C5_PT(PyTorch Models)
        end
        C5 --> C5_TF & C5_PT
        C2 --> C6(Resultados do Treinamento);
    end

    subgraph "3 Geração de Relatórios"
        direction TB
        D1(pipenv run model-2-train) --> D2(PresentationGridDashboard);
        D2 --> D3(Plotters);
        D2 --> D4(PresentationFileSharer);
        D4 --> D5(Gráficos Salvos .png);
    end

    A1 --> B1;
    B5 --> C3;
    C6 --> D2;
Loading
  • Leitura: Os arquivos .sr3 são lidos, contendo séries temporais de múltiplas propriedades para diferentes elementos (poços, grupos).
  • Processamento e Enriquecimento:
    • Os dados são lidos e propriedades computadas (ex: WATERCUT) são adicionadas.
    • Os dados são estruturados em um formato "tidy" (tabular) e salvos como arquivos Parquet. Cada arquivo Parquet representa uma simulação e contém colunas como SIM_ID, ELEMENT_NAME, TIMESTEP_JULIAN, e as várias FEATURES e TARGET.
  • Carregamento para Treinamento: O DataLoader lê múltiplos arquivos Parquet e os concatena em um único DataFrame (Dask ou Pandas).
  • Pré-processamento:
    • O DataFrame é filtrado (ex: para manter apenas poços produtores).
    • Os dados são divididos em conjuntos de treino, validação e teste.
    • As features são normalizadas usando um Scaler (ex: MinMaxScaler). O scaler é "treinado" (fit) apenas nos dados de treino.
    • Os dados normalizados são transformados em sequências de entrada (X) e saída (y) usando a técnica de janela deslizante (sliding windows).
  • Treinamento: Os batches de (X_train, y_train) são passados para o modelo. O modelo é avaliado com (X_val, y_val) para controle (ex: EarlyStopping).
  • Avaliação: O modelo treinado faz previsões usando X_test. As previsões (y_pred) são comparadas com os valores reais (y_test).
  • Pós-processamento: As previsões e valores reais, que estão normalizados, são revertidos para a escala original (inverse_transform) para que possam ser interpretados.
  • Visualização: Os dados na escala original são usados para gerar gráficos de dispersão e de resíduos, que são salvos como imagens.

Modelos de Treinamento

O projeto implementa uma variedade de arquiteturas de modelos, desde baselines simples até redes neurais mais complexas, permitindo uma análise comparativa robusta. Um diferencial importante é que cada modelo foi desenvolvido tanto em PyTorch quanto em TensorFlow, garantindo flexibilidade e a possibilidade de comparar o desempenho entre os frameworks.

A seguir, os modelos são apresentados em ordem de complexidade crescente. Para cada um, é exibido um dashboard com os resultados do conjunto de teste.

Como Analisar os Dashboards

Cada dashboard resume a performance do modelo. Os principais parâmetros utilizados no treinamento, como o número de épocas (epochs), tamanho do lote (batch_size), tamanho da janela de entrada (input_seq_len), pontos de previsão (output_seq_len), e os tamanhos dos conjuntos de teste (test_size) e validação (val_size), estão descritos no subtítulo para referência.

  • Gráfico da Esquerda (Prediction vs. Actual): Este gráfico de dispersão compara diretamente os valores previstos pelo modelo (eixo Y) com os valores reais (eixo X).

    • Para que serve? Para avaliar visualmente a acurácia geral do modelo.
    • O que observar? Em um modelo perfeito, todos os pontos (em azul) estariam exatamente sobre a linha laranja (y=x). Quanto mais próximos os pontos estiverem dessa linha, mais precisas são as previsões. A dispersão dos pontos indica a magnitude dos erros.
  • Gráfico da Direita (Residuals Analysis): Este gráfico analisa os erros (resíduos), que são a diferença entre o valor real e o valor previsto.

    • Para que serve? Para verificar se o modelo possui algum viés (bias) ou se os erros são aleatórios.
    • O que observar? Idealmente, os pontos devem se distribuir de forma aleatória e homogênea em torno da linha horizontal em y=0, sem formar padrões claros (como uma curva ou um funil). Um padrão indica que o modelo erra sistematicamente para certas faixas de valores. O histograma à direita deve se assemelhar a uma curva de sino (distribuição normal) centrada no zero, confirmando que os erros são, em sua maioria, pequenos e não tendenciosos.

A seguir, os modelos são apresentados em ordem de complexidade crescente:

  1. MLP Simples (mlp_simple.py):

    • Arquitetura: É o modelo mais básico, um Multi-Layer Perceptron (Perceptron de Múltiplas Camadas) padrão. Ele trata a sequência de entrada como um vetor de features achatado (flat), sem considerar explicitamente a ordem temporal.
    • Propósito: Serve como um baseline rápido e simples para estabelecer um desempenho mínimo a ser superado pelas arquiteturas mais complexas.
    OilPredTensorFlowMLPSimpleModel_results_dashboard OilPredPyTorchMLPSimpleModel_results_dashboard
  2. MLP com Dropout (mlp_droupout.py):

    • Aprimoramento: Adiciona camadas de Dropout ao MLP. Durante o treinamento, o Dropout zera aleatoriamente uma fração das entradas de uma camada, o que força a rede a aprender representações mais robustas.
    • Propósito: É uma técnica de regularização para combater o superajuste (overfitting), melhorando a capacidade de generalização do modelo para dados não vistos.

    OilPredTensorFlowMLPDropoutModel_results_dashboard

    OilPredPyTorchMLPDropoutModel_results_dashboard
  3. MLP com Batch Normalization (mlp_batchnorm.py):

    • Aprimoramento: Incorpora camadas de Batch Normalization. Essa técnica normaliza a saída de uma camada anterior, estabilizando a distribuição das ativações.
    • Propósito: Acelera e estabiliza o processo de treinamento, permitindo o uso de taxas de aprendizado mais altas e tornando o modelo menos sensível à inicialização dos pesos.
    OilPredTensorFlowMLPBatchNormModel_results_dashboard OilPredPyTorchMLPBatchNormModel_results_dashboard
  4. LSTM (lstm.py):

    • Arquitetura: Utiliza uma rede neural recorrente do tipo Long Short-Term Memory. Diferente do MLP, a LSTM processa os dados sequencialmente e possui "portões" (gates) que controlam um estado interno, permitindo que ela aprenda e retenha dependências de longo prazo na série temporal.
    • Propósito: É um modelo fundamental para séries temporais, projetado especificamente para capturar padrões temporais que os MLPs não conseguem.
    OilPredTensorFlowLSTMModel_results_dashboard OilPredPyTorchLSTMModel_results_dashboard
  5. CNN-LSTM (cnn_lstm.py):

    • Arquitetura: Um modelo híbrido que combina Redes Neurais Convolucionais (CNN) e LSTM. As camadas de CNN atuam primeiro, extraindo features locais e padrões espaciais da sequência de entrada. O resultado é então passado para a camada LSTM, que interpreta essas features ao longo do tempo.
    • Propósito: Aumentar a capacidade de extração de features do modelo. A CNN pode identificar padrões complexos em janelas curtas de tempo, que são então contextualizados pela LSTM.
    OilPredTensorFlowCNNLSTMModel_results_dashboard OilPredPyTorchCNNLSTMModel_results_dashboard
  6. CNN-GRU (cnn_gru.py):

    • Arquitetura: Similar ao CNN-LSTM, mas substitui a camada LSTM por uma Gated Recurrent Unit (GRU). A GRU é uma variação mais moderna e simplificada da LSTM, com menos portões e parâmetros.
    • Propósito: Oferece uma alternativa à LSTM que é, muitas vezes, computacionalmente mais eficiente. Em diversos problemas, a GRU pode atingir um desempenho similar ou até superior com um tempo de treinamento menor.
    OilPredPyTorchCNNGRUModel_results_dashboard OilPredTensorFlowCNNGRUModel_results_dashboard

Sobre o código

Este projeto é desenvolvido em Python 3.12, utilizando pipenv para gerenciamento de dependências e ambientes virtuais, garantindo reprodutibilidade. A arquitetura do código é modular, facilitando a adição de novos modelos e a manutenção.

As principais técnicas de programação e bibliotecas utilizadas incluem:

  • Processamento de Dados: Pandas e Dask para manipulação e processamento eficiente de grandes volumes de dados de simulação.
  • Modelagem de Machine Learning: TensorFlow e PyTorch para a implementação de diferentes arquiteturas de redes neurais (MLP, LSTM), permitindo flexibilidade na experimentação de modelos.
  • Configuração: Pydantic é empregado para a validação e gerenciamento de configurações do projeto, carregadas a partir de arquivos .env, o que promove segurança e facilidade de uso.
  • Testes: A qualidade do código é assegurada através de testes unitários e de integração, utilizando a framework pytest.
  • Documentação Interna: O código segue uma estratégia de comentários em linha clara e concisa, além de docstrings para funções e classes, visando facilitar a compreensão e a colaboração.

Manual de Utilização para Usuários Contemplados

O manual de utilização deve ser elaborado para todos os tipos de usuários contemplados e ser consistente com todo o restante do conteúdo da Wiki. Abaixo, são detalhadas as principais tarefas que um usuário pode realizar com o sistema.

{
  Guia de Instruções:
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  Para **Configurar o ambiente de execução** faça:
  Passo 1: Clone o repositório do projeto para sua máquina local.
  Passo 2: Certifique-se de ter o Python 3.12 instalado. Recomenda-se o uso de um gerenciador de ambientes como `conda` ou `pyenv`.
  Passo 3: Instale o `pipenv` globalmente (ou no seu ambiente Python) com o comando: `pip install pipenv`.
  Passo 4: Navegue até o diretório raiz do projeto e instale todas as dependências do projeto (incluindo as de desenvolvimento) usando `pipenv install --dev`.
  Passo 5: Copie o arquivo `.env.example` para `.env` na raiz do projeto. Edite o arquivo `.env` para configurar os caminhos para os diretórios de dados brutos (`SIMULATIONS_SOURCE_DIR`), dados processados (`DATAFRAMES_DIRECTORY`) e resultados (`ROOT_DIRECTORY`).

  Exceções ou potenciais problemas:
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  Se [Erro durante a instalação de dependências]:
     É porque: Pode haver um problema de compatibilidade de pacotes ou uma versão incorreta do Python. Verifique a saída do erro e a versão do Python.

  Se [Erro ao iniciar o ambiente Pipenv]:
     É porque: O `pipenv` pode não estar no PATH ou o ambiente virtual não foi criado corretamente. Tente `pipenv shell` para ativar o ambiente.
}

{
  Guia de Instruções:
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  Para **Executar o pipeline de treinamento de modelos** faça:
  Passo 1: Certifique-se de que seu ambiente `pipenv` esteja ativado (`pipenv shell`).
  Passo 2: Execute o script de treinamento usando o comando: `pipenv run model-2-train`.

  Exceções ou potenciais problemas:
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  Se [FileNotFoundError]:
     É porque: O caminho para os dataframes (`DATAFRAMES_DIRECTORY`) configurado no arquivo `.env` está incorreto ou os arquivos Parquet não foram gerados na etapa anterior.

  Se [MemoryError]:
     É porque: O volume de dados sendo processado ou o tamanho do modelo excede a memória RAM disponível. Considere reduzir o número de simulações, ajustar os parâmetros de batch size ou executar em um ambiente com mais recursos.
}

{
  Guia de Instruções:
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  Para **Adicionar um novo modelo de Machine Learning** faça:
  Passo 1: Crie um novo arquivo Python dentro do diretório `core/models`.
  Passo 2: Implemente sua nova classe de modelo, garantindo que ela herde de uma classe base (`BaseModel` ou similar) e siga a interface definida para modelos existentes (métodos `train`, `predict`, etc.).
  Passo 3: Adicione a configuração para o seu novo modelo no arquivo de ambiente (`configs/Environment.py`) ou em um arquivo de configuração específico, se aplicável.
  Passo 4: Integre o novo modelo ao `ModelGenController` para que ele possa ser selecionado e treinado junto aos demais.

  Exceções ou potenciais problemas:
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  Se [Erro de importação ou classe não encontrada]:
     É porque: O novo arquivo ou classe do modelo não foi importado corretamente ou não está no caminho de módulos do Python. Verifique os imports e a estrutura de diretórios.
}