Komponent rurociągu InfraValidator TFX

InfraValidator to komponent TFX używany jako warstwa wczesnego ostrzegania przed wprowadzeniem modelu do produkcji. Nazwa walidatora „infra” wzięła się stąd, że waliduje model w rzeczywistym modelu obsługującym „infrastrukturę”. Jeśli Evaluator ma zagwarantować wydajność modelu, InfraValidator ma zagwarantować, że model będzie sprawny mechanicznie i zapobiec wypchnięciu złych modeli.

Jak to działa?

InfraValidator pobiera model, uruchamia serwer modelu w trybie piaskownicy z modelem i sprawdza, czy można go pomyślnie załadować i opcjonalnie wysłać zapytanie. Wynik walidacji infra zostanie wygenerowany w wynikach blessing w taki sam sposób, jak robi to Evaluator .

InfraValidator koncentruje się na zgodności pomiędzy plikiem binarnym serwera modelu (np. Serving TensorFlow ) a modelem do wdrożenia. Pomimo nazwy walidator „infra”, za prawidłowe skonfigurowanie środowiska odpowiada użytkownik , a walidator infra współdziała jedynie z serwerem modelowym w środowisku skonfigurowanym przez użytkownika, aby sprawdzić, czy działa poprawnie. Prawidłowa konfiguracja tego środowiska zapewni, że pozytywny lub negatywny wynik walidacji infra będzie wskazywał, czy model będzie możliwy do obsługi w środowisku obsługującym środowisko produkcyjne. Oznacza to niektóre z poniższych, ale nie ogranicza się do nich:

  1. InfraValidator używa tego samego pliku binarnego modelu serwera, jaki będzie używany w środowisku produkcyjnym. Jest to minimalny poziom, do którego musi dojść środowisko walidacji infrastruktury.
  2. InfraValidator wykorzystuje te same zasoby (np. ilość przydzielonego procesora, pamięć i akceleratory), jakie będą wykorzystywane w produkcji.
  3. InfraValidator korzysta z tej samej konfiguracji serwera modelowego, która będzie używana w środowisku produkcyjnym.

W zależności od sytuacji użytkownicy mogą wybrać, w jakim stopniu InfraValidator ma być identyczny ze środowiskiem produkcyjnym. Technicznie rzecz biorąc, model można bez problemu poddać infrawalidacji w lokalnym środowisku Docker, a następnie udostępnić w zupełnie innym środowisku (np. klastrze Kubernetes). Jednakże InfraValidator nie sprawdzi tej rozbieżności.

Tryb pracy

W zależności od konfiguracji walidacja infra odbywa się w jednym z następujących trybów:

  • Tryb LOAD_ONLY : sprawdzanie, czy model został pomyślnie załadowany w infrastrukturze obsługującej, czy nie. LUB
  • Tryb LOAD_AND_QUERY : tryb LOAD_ONLY plus wysłanie kilku przykładowych żądań w celu sprawdzenia, czy model jest w stanie obsługiwać wnioski. InfraValidator nie dba o to, czy prognoza była poprawna, czy nie. Liczy się tylko to, czy prośba została uwzględniona, czy nie.

Jak z niego korzystać?

Zwykle InfraValidator jest definiowany obok komponentu Evaluator, a jego dane wyjściowe są przekazywane do Pushera. Jeśli InfraValidator zawiedzie, model nie zostanie wypchnięty.

evaluator = Evaluator(
    model=trainer.outputs['model'],
    examples=example_gen.outputs['examples'],
    baseline_model=model_resolver.outputs['model'],
    eval_config=tfx.proto.EvalConfig(...)
)

infra_validator = InfraValidator(
    model=trainer.outputs['model'],
    serving_spec=tfx.proto.ServingSpec(...)
)

pusher = Pusher(
    model=trainer.outputs['model'],
    model_blessing=evaluator.outputs['blessing'],
    infra_blessing=infra_validator.outputs['blessing'],
    push_destination=tfx.proto.PushDestination(...)
)

Konfigurowanie komponentu InfraValidator.

Istnieją trzy rodzaje protosów do konfiguracji InfraValidator.

ServingSpec

ServingSpec to najważniejsza konfiguracja dla InfraValidator. Definiuje:

  • jaki typ serwera modelowego uruchomić
  • gdzie to uruchomić

Obsługiwane są typy serwerów modelowych (zwane obsługującymi plikami binarnymi).

Obecnie obsługiwane są następujące platformy obsługujące:

  • Lokalny Docker (Docker powinien zostać zainstalowany wcześniej)
  • Kubernetes (ograniczone wsparcie tylko dla KubeflowDagRunner)

Wyboru obsługi binarnej i platformy obsługującej dokonuje się poprzez określenie bloku oneof w ServingSpec . Na przykład, aby użyć pliku binarnego TensorFlow Serving działającego w klastrze Kubernetes, należy ustawić pola tensorflow_serving i kubernetes .

infra_validator=InfraValidator(
    model=trainer.outputs['model'],
    serving_spec=tfx.proto.ServingSpec(
        tensorflow_serving=tfx.proto.TensorFlowServing(
            tags=['latest']
        ),
        kubernetes=tfx.proto.KubernetesConfig()
    )
)

Aby dokładniej skonfigurować ServingSpec , sprawdź definicję protobuf .

ValidationSpec

Opcjonalna konfiguracja umożliwiająca dostosowanie kryteriów walidacji infrastruktury lub przepływu pracy.

infra_validator=InfraValidator(
    model=trainer.outputs['model'],
    serving_spec=tfx.proto.ServingSpec(...),
    validation_spec=tfx.proto.ValidationSpec(
        # How much time to wait for model to load before automatically making
        # validation fail.
        max_loading_time_seconds=60,
        # How many times to retry if infra validation fails.
        num_tries=3
    )
)

Wszystkie pola ValidationSpec mają prawidłową wartość domyślną. Sprawdź więcej szczegółów w definicji protobufa .

RequestSpec

Opcjonalna konfiguracja określająca sposób tworzenia przykładowych żądań podczas uruchamiania sprawdzania poprawności infrastruktury w trybie LOAD_AND_QUERY . Aby skorzystać z trybu LOAD_AND_QUERY należy w definicji komponentu określić zarówno właściwości wykonania request_spec jak i examples kanał wejściowy.

infra_validator = InfraValidator(
    model=trainer.outputs['model'],
    # This is the source for the data that will be used to build a request.
    examples=example_gen.outputs['examples'],
    serving_spec=tfx.proto.ServingSpec(
        # Depending on what kind of model server you're using, RequestSpec
        # should specify the compatible one.
        tensorflow_serving=tfx.proto.TensorFlowServing(tags=['latest']),
        local_docker=tfx.proto.LocalDockerConfig(),
    ),
    request_spec=tfx.proto.RequestSpec(
        # InfraValidator will look at how "classification" signature is defined
        # in the model, and automatically convert some samples from `examples`
        # artifact to prediction RPC requests.
        tensorflow_serving=tfx.proto.TensorFlowServingRequestSpec(
            signature_names=['classification']
        ),
        num_examples=10  # How many requests to make.
    )
)

Tworzenie zapisanego modelu z rozgrzewką

(Od wersji 0.30.0)

Ponieważ InfraValidator sprawdza model za pomocą rzeczywistych żądań, może z łatwością ponownie wykorzystać te żądania weryfikacji jako żądania rozgrzania SavedModel. InfraValidator udostępnia opcję ( RequestSpec.make_warmup ) eksportowania SavedModel z rozgrzewką.

infra_validator = InfraValidator(
    ...,
    request_spec=tfx.proto.RequestSpec(..., make_warmup=True)
)

Następnie wyjściowy artefakt InfraBlessing będzie zawierał SavedModel z rozgrzewką i może być również wypchnięty przez Pusher , podobnie jak artefakt Model .

Ograniczenia

Obecny program InfraValidator nie jest jeszcze kompletny i ma pewne ograniczenia.

  • Można sprawdzić tylko format modelu TensorFlow SavedModel .
  • Podczas uruchamiania TFX na Kubernetesie potok powinien zostać wykonany przez KubeflowDagRunner wewnątrz Kubeflow Pipelines. Serwer modelowy zostanie uruchomiony w tym samym klastrze Kubernetes i przestrzeni nazw, z której korzysta Kubeflow.
  • InfraValidator koncentruje się głównie na wdrożeniach w TensorFlow Serving i choć nadal jest przydatny, jest mniej dokładny w przypadku wdrożeń w TensorFlow Lite i TensorFlow.js lub innych platformach wnioskowania.
  • W trybie LOAD_AND_QUERY dostępna jest ograniczona obsługa podpisu metody Predict (która jest jedyną metodą, którą można eksportować w TensorFlow 2). InfraValidator wymaga podpisu Predict, aby wykorzystać serializowany plik tf.Example jako jedyne dane wejściowe.

    @tf.function
    def parse_and_run(serialized_example):
      features = tf.io.parse_example(serialized_example, FEATURES)
      return model(features)
    
    model.save('path/to/save', signatures={
      # This exports "Predict" method signature under name "serving_default".
      'serving_default': parse_and_run.get_concrete_function(
          tf.TensorSpec(shape=[None], dtype=tf.string, name='examples'))
    })