Skip to content

Storage e artefatos

Mapa de fontes de verdade

DadoFonte de verdadeQuem grava
snapshots canônicosfilesystem ou S3 de ingestãojob materialize_snapshot
séries projetadas para treinofilesystem ou S3 de ingestãojob project_training_series
metadados de snapshots e modelosClickHouseAPI e jobs
artefatos treinadosfilesystem ou S3 de artefatosjob train_model_candidates
runs de treinoMLflowtracker adapter

O projeto separa claramente metadado de payload pesado. ClickHouse guarda estado operacional; arquivos e objetos guardam datasets e binários.

Regra arquitetural:

  • o control plane persiste estado durável em ClickHouse;
  • o data plane persiste snapshots e artefatos em filesystem/S3;
  • o control plane referencia metadados do data plane, mas não persiste frames no banco.

Isso deixa claro onde futuras extensões entram:

  • feature catalog, snapshot metadata enriquecida e orchestration metadata continuam no control plane;
  • materialização, leitura e projeção de features continuam no data plane.
  • SeriesKey continua sendo a identidade compartilhada entre as duas camadas.

Para a lista atual de tabelas ClickHouse e seus contratos de coluna, veja Database tables.

Input path vs snapshot canônico

O input_path recebido pelo comando de treino não vira fonte de treino direta.

Fluxo:

  1. a API valida e persiste o input_path junto com source_format (csv ou parquet);
  2. o snapshot fica em processing;
  3. o materializer resolve o arquivo informado sem inferir formato por sufixo;
  4. o validator central do data plane aplica normalização canônica, tenant scope e regras por série;
  5. só então o job de materialização grava o snapshot canônico.

Essa separação evita que treino leia fontes sem validação ou dependa de heurística de extensão para decidir como ler o input.

Layout do snapshot canônico

Depois da materialização, o storage canônico recebe:

demand-snapshots/org=<organization_id>/snapshot=<snapshot_id>/data.parquet
demand-snapshots/org=<organization_id>/snapshot=<snapshot_id>/manifest.json

data.parquet contém a tabela canônica de demanda. manifest.json descreve:

  • snapshot_id
  • organization_id
  • row_count
  • series_count
  • lista de data_file_uris
  • projected_series_data_uri, quando a projeção já rodou
  • projected_series_index_uri, quando a projeção já rodou

O catalog canônico lê e valida esse manifest antes do treino:

  • reaplica o contrato canônico do frame;
  • row_count e series_count precisam bater com o frame canônico carregado.

Depois disso, o restante do fluxo opera sobre DemandSnapshotManifest: o control enxerga o snapshot já resolvido. A etapa de projeção lê data_file_uris, grava artefatos derivados por série e atualiza o mesmo manifest com projected_series_data_uri e projected_series_index_uri.

Isso mantém o contrato do snapshot pequeno e suficiente para detectar deriva óbvia entre manifest e frame carregado, sem transformar o hot path de treino em um pass extra sobre arquivos grandes.

Layout das séries projetadas

project_training_series grava uma visão derivada do snapshot canônico:

demand-snapshots/org=<organization_id>/snapshot=<snapshot_id>/projected/recipe=<recipe_key>/data/
demand-snapshots/org=<organization_id>/snapshot=<snapshot_id>/projected/recipe=<recipe_key>/series-index/

O dataset projetado é particionado por series_id, que é a identidade textual do SeriesKey. O índice lista as séries disponíveis e permite que o treino Polars carregue somente as partições necessárias para cada work item, sem varrer o snapshot inteiro.

O snapshot canônico continua imutável para o ciclo de treino. A projeção é derivada da configuração ativa congelada, principalmente de series_projection_recipe, e por isso fica documentada no manifest em campos separados.

Artefatos de treino

O treino persiste o payload binário resolvido pela estratégia em um artifact store separado do storage de ingestão.

Em filesystem:

<root>/org=<organization_id>/model_definition=<model_definition_id>/series_kind=<series_kind>/series=<series_id>/grain=<grain>/strategy=<strategy_key>/version=<version>/artifact.bin

Em S3, a convenção é a mesma, com bucket e prefixo configuráveis.

O que vai para MLflow

MLflow não substitui o artifact store local/S3 usado pelo Atreides. Ele concentra:

  • uma sessão lógica por workflow de treino;
  • um run pai por série, nomeado a partir do SeriesKey e de um sufixo nanoid;
  • child runs por candidata/série com parâmetros, métricas, tags pesquisáveis e referência para o artefato persistido;
  • training_report.json nos runs pais de série quando a composição in-process registra o relatório consolidado; esse arquivo reúne perfil da série, candidatas, configuração resolvida, flags de campeã e metadados opcionais de explicação;
  • empacotamento pyfunc e registry sync do campeão produzido pelo treino.

Na prática:

  • o artifact store guarda o payload serializado pela estratégia;
  • MLflow guarda histórico operacional, debugging do treino, o modelo empacotado e a referência registrada do campeão;
  • snapshot_id segue junto na lineage da instância treinada e nas tags do run.
  • estado de campeã, auditoria de promoção, fingerprints, métricas de seleção e referências de serving seguem no domínio e na persistência command-side.

Backends locais e remotos

Para demanda:

  • local: DEMAND_STORAGE_BACKEND=filesystem
  • remoto: DEMAND_STORAGE_BACKEND=s3

Para artefatos de modelo:

  • local: ARTIFACT_STORE_BACKEND=filesystem
  • remoto: ARTIFACT_STORE_BACKEND=s3

Isso permite rodar localmente sem mudar a semântica geral do fluxo.

O que não deve vazar entre camadas

  • domínio não conhece path, bucket nem URI;
  • o control plane trabalha com repositórios, promotion state e metadata durável;
  • o data plane trabalha com frames, snapshots, parquet e validação estrutural;
  • adapters resolvem file://, s3:// e clientes concretos.

Essa fronteira é importante para manter treino e promoção testáveis sem infraestrutura real.

Quando usar esta página

Use esta página quando estiver:

  • depurando “onde foi parar” um snapshot ou artefato;
  • validando a separação entre input_path e snapshot canônico;
  • ajustando variáveis de ambiente de storage local ou S3.

Onde continuar