Construindo componentes baseados em contêiner

Os componentes baseados em contêiner fornecem flexibilidade para integrar código escrito em qualquer linguagem em seu pipeline, desde que você possa executar esse código em um contêiner Docker.

Se você é novo nos pipelines do TFX, saiba mais sobre os principais conceitos dos pipelines do TFX .

Criando um componente baseado em contêiner

Os componentes baseados em contêiner são apoiados por programas de linha de comando em contêineres. Se você já possui uma imagem de contêiner, poderá usar o TFX para criar um componente a partir dela usando a função create_container_component para declarar entradas e saídas. Parâmetros de função:

  • nome: o nome do componente.
  • entradas: um dicionário que mapeia nomes de entrada para tipos. saídas: um dicionário que mapeia nomes de saída para tipos. Parâmetros: um dicionário que mapeia nomes de parâmetros para tipos.
  • imagem: nome da imagem do contêiner e, opcionalmente, tag da imagem.
  • comando: linha de comando do ponto de entrada do contêiner. Não executado dentro de um shell. A linha de comando pode usar objetos de espaço reservado que são substituídos no momento da compilação pela entrada, saída ou parâmetro. Os objetos de espaço reservado podem ser importados de tfx.dsl.component.experimental.placeholders . Observe que os modelos Jinja não são suportados.

Valor de retorno: uma classe Component herdada de base_component.BaseComponent que pode ser instanciada e usada dentro do pipeline.

Espaços reservados

Para um componente que possui entradas ou saídas, o command geralmente precisa ter espaços reservados que sejam substituídos por dados reais em tempo de execução. Vários espaços reservados são fornecidos para essa finalidade:

  • InputValuePlaceholder : um espaço reservado para o valor do artefato de entrada. No tempo de execução, esse espaço reservado é substituído pela representação de string do valor do artefato.

  • InputUriPlaceholder : um espaço reservado para o URI do argumento do artefato de entrada. No tempo de execução, esse espaço reservado é substituído pelo URI dos dados do artefato de entrada.

  • OutputUriPlaceholder : um espaço reservado para o URI do argumento do artefato de saída. Em tempo de execução, esse espaço reservado é substituído pelo URI onde o componente deve armazenar os dados do artefato de saída.

Saiba mais sobre os espaços reservados de linha de comando do componente TFX .

Exemplo de componente baseado em contêiner

A seguir está um exemplo de um componente não python que baixa, transforma e carrega os dados:

import tfx.v1 as tfx

grep_component = tfx.dsl.components.create_container_component(
    name='FilterWithGrep',
    inputs={
        'text': tfx.standard_artifacts.ExternalArtifact,
    },
    outputs={
        'filtered_text': tfx.standard_artifacts.ExternalArtifact,
    },
    parameters={
        'pattern': str,
    },
    # The component code uses gsutil to upload the data to Google Cloud Storage, so the
    # container image needs to have gsutil installed and configured.
    image='google/cloud-sdk:278.0.0',
    command=[
        'sh', '-exc',
        '''
          pattern="$1"
          text_uri="$3"/data  # Adding suffix, because currently the URI are "directories". This will be fixed soon.
          text_path=$(mktemp)
          filtered_text_uri="$5"/data  # Adding suffix, because currently the URI are "directories". This will be fixed soon.
          filtered_text_path=$(mktemp)

          # Getting data into the container
          gsutil cp "$text_uri" "$text_path"

          # Running the main code
          grep "$pattern" "$text_path" >"$filtered_text_path"

          # Getting data out of the container
          gsutil cp "$filtered_text_path" "$filtered_text_uri"
        ''',
        '--pattern', tfx.dsl.placeholders.InputValuePlaceholder('pattern'),
        '--text', tfx.dsl.placeholders.InputUriPlaceholder('text'),
        '--filtered-text', tfx.dsl.placeholders.OutputUriPlaceholder('filtered_text'),
    ],
)