Personalizacja na urządzeniu – sfederowana, deterministyczna kompilacja obliczeń

Do poświadczania zadań na urządzeniu wymagane są deterministyczne kompilacje Zaufane środowisko wykonawcze TEE Personalization (ODP), dostępne publicznie na Google Cloud jako poufnej przestrzeni (CS).

Obrazy zadań muszą generować deterministyczny hasz obrazu, którego może używać Oprogramowanie CS do poświadczania zadań (używające zdalnego poświadczania RFC 9334) oferowanego przez NIST architekturze RATS).

Omówimy w nim implementację i obsługę metod deterministycznych Google Play odp-federatedcompute z repozytorium. Usługi Agregatora ODP i Aktualizatora modeli będą działać w Poufna przestrzeń. Repozytorium obsługuje deterministyczne kompilacje dla wszystkich które są wymagane w środowiskach produkcyjnych.

Kompilacje deterministyczne

Kompilacje deterministyczne składają się z 2 głównych elementów:

  1. Kompilacja wymaganych plików binarnych. Są to między innymi pliki JAR, biblioteki udostępnione, i metadanych.
  2. Zależności obrazu podstawowego i środowiska wykonawczego. Podstawowe środowisko wykonawcze obrazu służącego do wykonywania skompilowanych plików binarnych.

Obecnie repozytorium ODP Federated Compute Compute obsługuje te typy typów zasobów zadania:

  • Zadania w Javie i Spring
    • Przypisanie zadania, zarządzanie zadaniami, kolektor
  • Java + Spring ze zbiorami zadań JNI Tensorflow
    • Aktualizacja modeli, agregator
  • Zadania w Pythonie
    • TaskBuilder

Zależności

Na liście poniżej znajdziesz zależności, na których opiera się ODP w celu utrzymania determinizmu i dostępność:

  • Bazel
  • GitHub
  • Maven
  • PyPi
  • Zrzuty Debiana
  • Rejestr DockerHub
  • Google Container Registry (GCR)

Zadania deterministyczne

Wszystkie zadania są skompilowane za pomocą algorytmu Bazel z łańcuchy narzędzi i obrazy kontenerów utworzone w wybranych językach rules_oci. Obszar roboczy plik definiuje wszystkie zależności z odpowiednimi wersjami i haszami.

Zrzuty Debiana

Wszystkie obrazy zadań powinny być skompilowane w podanym dockerfile bazuje na zrzutie Debiana. Debian udostępniają stabilny zrzut repozytorium z deterministycznym wskaźnikiem:

Zadania Java Spring

Bazel remotejdk_17 to wykorzystane do utworzenia hermetycznej biblioteki Java do kompilacji. Inne zależności Javy są następujące: zarządzane i zdefiniowane w obszarze WORKSPACE .

Zadania Java Spring kompilują się do pliku jar o nazwie <service>_application.jar Pakiet zawiera:

  • Pliki klasy Java
  • META-INF/
    • Dane manifestu w Bazelu
  • build-data.properties
    • Dane kompilacji w Bazelu
  • BOOT-INF/
    • Zależności pliku jar w pakiecie, wygenerowane przez rules_spring.

Warstwy obrazu

Obraz zadania Java Spring składa się z 2 warstw:

Konfiguracja obrazu

  • Punkt wejścia
    • java -jar <service>_application.jar

Zbiory zadań JNI Tensorflow

Zbiory zadań JNI Tensorflow są oparte na zadaniach Java Spring. O Hermetyczny łańcuch narzędzi Bazel Clang+LLVM jest udostępniany za pomocą gotowej platformy Clang+LLVM 16 z atrybutem sysroot udostępniany przez obraz zrzutu Debian w celu skompilowania kodu maszyny.

Zadania JNI są kompilowane do biblioteki udostępnionej o nazwie libtensorflow.so dzięki <service>_application.jar.

Warstwy obrazu

Obraz zadania JNI Tensorflow składa się z kilku warstw:

  • Warstwa obrazu podstawowego
  • Warstwy zależności pakietów Debiana. Warstwy są generowane przy użyciu deb pobrane z systemu Debian-snapshot i przepakowane jako warstwy obrazu
    • libc++1-16_amd64.tar
    • libc++abi1-16_amd64.tar
    • libc6_amd64.tar
    • libunwind-16_amd64.tar
    • libgcc-s1_amd64.tar
    • gcc-13-base_amd64.tar
  • Warstwa zbioru zadań
    • binary_tar.tar
      • <service>_application.jar
      • libtensorflow-jni.so
      • libaggregation-jni.so

Konfiguracja obrazu

  • Etykiety (tylko w przypadku obrazów utworzonych na potrzeby TEE)
    • "tee.launch_policy.allow_env_override": "FCP_OPTS"
      • Umożliwia ustawienie zmiennej środowiskowej FCP_OPTS w poufne Spacja. Aby skonfigurować zadanie, zadanie będzie wykorzystywać FCP_OPTS podczas uruchamiania .
      • Zmienna środowiskowa FCP_OPTS jest ustawiana podczas uruchamiania obrazu (zamiast budować), aby podtrzymać determinizm budowania.
    • "tee.launch_policy.log_redirect": "always"
    • "tee.launch_policy.monitoring_memory_allow": "always"
  • Punkt wejścia
    • java -Djava.library.path=. -jar <service>_application.jar

Zadania w Pythonie

Parametr rules_python Bazel służy do: udostępnić hermetyczny łańcuch narzędzi w języku Python 3.10. Wymagania dotyczące zablokowanego potoku plik służy do deterministycznego pobierania zależności pip. Zrzut systemu Debian gwarantuje, że rozkłady deterministyczne są pobierane w oparciu o platformę zgodność i udostępnia łańcuch narzędzi C++ do kompilowania dystrybucji źródeł.

Zadania w Pythonie zostaną spakowane do zbioru pobranych pakietów pip, Dystrybucja Pythona 3.10, kod źródłowy Pythona ODP i start w języku Python skrypt.

  • <service>.runfiles/
    • Dystrybucja Pythona jest przechowywana w domenie python_x86_64-unknown-linux-gnu/
    • Kod źródłowy jest przechowywany w com_google_ondevicepersonalization_federatedcompute/
    • Pakiety PIP są przechowywane w ramach domeny pypi_<dependency_name>/
  • <service>.runfiles_manifest
    • Plik manifestu dla katalogu <service>.runfiles/
  • <service>
    • Skrypt Pythona do uruchamiania zbioru zadań Pythona za pomocą plików runfiles

Warstwy obrazu

Obraz zadania w Pythonie składa się z 4 warstw:

  • Warstwa obrazu podstawowego
  • Warstwa tłumaczenia rozmowy
    • interpreter_layer.jar
      • <service>/<service>.runfiles/python_x86_64-unknown-linux-gnu/**
  • Warstwa pakietów
    • packages_layer.jar
      • <service>/<service>.runfiles/**/site-packages/**
  • Warstwa zbioru zadań
    • app_tar_manifest.tar
      • Zawiera kod źródłowy, skrypt startowy i plik manifestu.
        • <service>/<service>.runfiles_manifest
        • <service>/<service>
        • <service>/<service>.runfiles/com_google_ondevicepersonalization_federatedcompute/**

Konfiguracja obrazu

  • Punkt wejścia
    • /<service>/<service>

Utwórz obrazy

Po wybraniu zbiorów zadań możesz zacząć budować i publikować obrazów.

Wymagania wstępne

Procedura

Obrazy powinny być tworzone w kontenerze Dockera utworzonym przez dostarczony dockerfile, Podane są 2 skrypty, które pomagają w tworzeniu ostatecznych deterministycznych obrazów.

  • docker_run.sh
    • docker_run.sh skompiluje obraz Dockera z pliku Dockerfile, w katalogu roboczym, podłącz demona Dockera i uruchom Dockera z użyciem można użyć polecenia bash. Wszystkie zmienne przekazywane przed poleceniem bash będą być traktowane jak flagi uruchomienia Dockera.
  • build_images.sh
    • build_images.sh uruchomi bazel build dla wszystkich obrazów i wyświetli wygenerowane hasze obrazów dla każdego kompilowanego obrazu.

Utwórz wszystkie obrazy

./scripts/docker/docker_run.sh "./scripts/build_images.sh"

Oczekiwane hasze obrazów każdej wersji znajdziesz w GitHub sfederowany przez odp .

Opublikuj obrazy

Publikowanie jest skonfigurowane za pomocą oci_push Bazel przestrzega zasad. W przypadku każdej usługi repozytorium docelowe powinno być skonfigurowane pod kątem wszystkie:

  • agregator
  • kolektor
  • model_updater
  • task_assignment
  • task_management
  • task_scheduler
  • task_builder

Opublikuj pojedynczy obraz

Aby opublikować pojedynczy obraz:

./scripts/docker/docker_run.sh "bazel run //shuffler/services/<servicename_no_underscore>:<servicename_with_underscore>_image_publish"

Utworzone obrazy

Wszystkie utworzone obrazy muszą być przechowywane i hostowane przez twórcę, np. w GCP Artifact Registry.