Skip to content

Predição batch

Papel no sistema

O Atreides é principalmente o command side de forecasting: ele cria snapshots, treina candidatas, promove campeãs e persiste auditoria. A exceção explícita é a predição batch. Esse fluxo existe para executar artefatos campeões sobre um novo snapshot de demanda e persistir ForecastRuns duráveis.

Não há previsão online síncrona neste serviço. A API apenas cria o snapshot, dispara o Airflow e devolve o run_id.

Entrada HTTP

O endpoint é:

POST /v1/model-definitions/{model_definition_id}/prediction-jobs

Como todas as rotas /v1/*, ele exige JWT bearer. O organization_id efetivo vem do token, não do corpo.

O payload segue o mesmo contrato de input de demanda do treino:

  • input_path
  • source_format
  • model_version, opcional

Quando model_version é omitido, o job pode selecionar campeãs ativas de versões diferentes, desde que as instâncias selecionadas compartilhem uma receita congelada compatível de projeção para a série alvo.

DAG

A DAG model_prediction, em src/infra/dags/model_prediction.py, executa:

materialize_snapshot
-> project_training_series
-> execute_model_forecasts
-> persist_forecast_results
flowchart LR A["HTTP prediction command"] --> B["DemandSnapshot processing"] B --> C["Airflow model_prediction"] C --> D["materialize_snapshot"] D --> E["project_training_series"] E --> F["execute_model_forecasts"] F --> G["forecast frame artifacts"] G --> H["persist_forecast_results"] H --> I["ForecastRun records in ClickHouse"]

As duas primeiras tarefas são compartilhadas com o treino:

  • materialize_snapshot valida o input bruto e grava o snapshot canônico;
  • project_training_series aplica a series_projection_recipe e grava partições por series_id.

execute_model_forecasts carrega campeãs ativas, artefatos e configuração congelada para produzir frames de forecast por série. A task grava os frames em Parquet no storage configurado e retorna apenas o URI do manifesto para o XCom. persist_forecast_results usa esse manifesto como entrada, carrega todos os frames e faz um único batch insert no ClickHouse.

Configuração congelada

Predição não reinterpreta a configuração viva do ModelDefinition para decidir como um artefato antigo deve rodar. O job usa a referência gravada no treino da campeã ativa:

  • resolved_config_snapshot;
  • resolved_config_hash;
  • validation_policy_hash;
  • projection_recipe_hash;
  • feature_recipe_hash;
  • strategy_params_hash;
  • selection_policy_hash;
  • artifact_uri;
  • strategy_key.

Se uma instância ativa antiga não tiver snapshot de configuração resolvida, o job falha explicitamente. Mudanças novas de configuração valem para novos treinos, não para a execução de um artefato já promovido.

Saída

A saída durável é ForecastRun, persistido em ClickHouse pela task persist_forecast_results. A aplicação enxerga esse handoff por duas portas: ForecastResultArtifactStorePort grava e lê o manifesto intermediário, e ForecastRunWritePort persiste os registros preparados para o banco.

O adapter Polars é apenas a implementação atual do store de artefatos. A escrita final usa SparkClickHouseForecastRunWriter, que configura o catálogo nativo do ClickHouse no Spark e grava em clickhouse.<database>.forecast_runs com a Catalog API (DataFrameWriterV2.writeTo(...).append()). Não existe repository HTTP dedicada para esse passo.

Um run concluído carrega:

  • tenant, modelo, versão e SeriesKey;
  • horizonte e unidade;
  • frame de forecast em payload columnar;
  • referência de execução;
  • status.

Quando uma série falha durante a execução, a task de execução falha antes de publicar o manifesto de resultados. Assim a etapa de persistência nunca recebe um batch parcial como se fosse completo.

Relação com MLflow e artefatos

ClickHouse é a fonte de verdade do campeão ativo e do ForecastRun. MLflow/registry é uma projeção operacional para packaging e aliases externos. Durante a predição, o adapter usa a referência de artefato da instância ativa e valida o manifesto do artefato antes de chamar a estratégia.

Onde continuar