1. Omówienie
W tym module użyjesz Vertex AI do uzyskiwania prognoz z wytrenowanego wcześniej modelu klasyfikacji obrazów.
Czego się nauczysz
Poznasz takie zagadnienia jak:
- Importowanie modelu TensorFlow do rejestru modeli Vertex AI
- Pobieranie prognoz online
- Aktualizowanie funkcji obsługi TensorFlow
Całkowity koszt uruchomienia tego modułu w Google Cloud wynosi około 1 USD.
2. Wprowadzenie do Vertex AI
Ten moduł wykorzystuje najnowszą ofertę usług AI dostępną w Google Cloud. Vertex AI integruje rozwiązania ML w Google Cloud, zapewniając bezproblemowe środowisko programistyczne. Wcześniej modele wytrenowane za pomocą AutoML i modele niestandardowe były dostępne za pomocą oddzielnych usług. Nowa oferta łączy oba te interfejsy API z innymi nowymi usługami. Możesz też przenieść istniejące projekty do Vertex AI.
Vertex AI zawiera wiele różnych usług, które obsługują kompleksowe przepływy pracy związane z systemami uczącymi się. W tym module skupimy się na usługach wymienionych poniżej: Predictions i Workbench.
3. Omówienie przypadku użycia
W tym module dowiesz się, jak pobrać wytrenowany model z TensorFlow Hub i wdrożyć go w Vertex AI. TensorFlow Hub to repozytorium wytrenowanych modeli do różnych obszarów problemów, takich jak reprezentacje właściwościowe, generowanie tekstu, konwersja mowy na tekst czy podział obrazu na segmenty.
Przykład użyty w tym module to model klasyfikacji obrazów MobileNet V1 wytrenowany wstępnie na podstawie zbioru danych ImageNet. Korzystając z gotowych modeli z TensorFlow Hub lub innych podobnych repozytoriów głębokiego uczenia się, możesz wdrażać wysokiej jakości modele ML do wielu zadań prognozowania bez konieczności martwienia się o trenowanie modelu.
4. Konfigurowanie środowiska
Aby uruchomić to ćwiczenie, musisz mieć projekt Google Cloud Platform z włączonym rozliczeniem. Aby utworzyć projekt, postępuj zgodnie z tymi instrukcjami.
Krok 1. Włącz interfejs Compute Engine API
Przejdź do Compute Engine i wybierz Włącz, jeśli usługa nie jest jeszcze włączona.
Krok 2. Włącz interfejs Vertex AI API
Przejdź do sekcji Vertex AI w konsoli Cloud i kliknij Włącz interfejs Vertex AI API.
Krok 3. Utwórz instancję Vertex AI Workbench
W konsoli Cloud w sekcji Vertex AI kliknij Workbench:
Włącz interfejs Notebooks API, jeśli nie jest jeszcze włączony.
Po włączeniu tej opcji kliknij ZARZĄDZANE NOTATKI:
Następnie wybierz NOWY NOTATNIK.
Nadaj notebookowi nazwę, a w sekcji Uprawnienia wybierz Konto usługi.
Kliknij Ustawienia zaawansowane.
W sekcji Zabezpieczenia wybierz „Włącz terminal”, jeśli nie jest jeszcze włączony.
Pozostałe ustawienia zaawansowane możesz pozostawić bez zmian.
Następnie kliknij Utwórz. Przygotowanie instancji może potrwać kilka minut.
Po utworzeniu instancji kliknij OTWÓRZ JUPYTERLAB.
5. Zarejestruj model
Krok 1. Prześlij model do Cloud Storage
Kliknij ten link, aby przejść na stronę TensorFlow Hub modelu MobileNet V1 wytrenowanego na zbiorze danych ImagNet.
Aby pobrać zapisane artefakty modelu, kliknij Pobierz.
W sekcji Cloud Storage w konsoli Google Cloud wybierz UTWÓRZ.
Nazwij zasobnik i jako region wybierz us-central1. Następnie kliknij UTWÓRZ.
Prześlij do zasobnika pobrany model centrum TensorFlow. Pamiętaj, aby najpierw rozpakować plik.
Zasobnik powinien wyglądać mniej więcej tak:
imagenet_mobilenet_v1_050_128_classification_5/
saved_model.pb
variables/
variables.data-00000-of-00001
variables.index
Krok 2. Zaimportuj model do rejestru
W konsoli Google Cloud otwórz sekcję Rejestr modeli w Vertex AI.
Kliknij Importuj.
Kliknij Zaimportuj jako nowy model, a potem wpisz nazwę modelu.
W sekcji Ustawienia modelu podaj najnowszy gotowy kontener TensorFlow. Następnie wybierz ścieżkę w Cloud Storage, na której znajdują się artefakty modelu.
Możesz pominąć sekcję Wyjaśnialność.
Następnie kliknij IMPORTUJ.
Po zaimportowaniu model będzie widoczny w rejestrze modeli
6. Wdrażanie modelu
W rejestrze modeli wybierz 3 kropki po prawej stronie modelu i kliknij Wdróż w punkcie końcowym.
W sekcji Zdefiniuj punkt końcowy kliknij Utwórz nowy punkt końcowy, a następnie nadaj mu nazwę.
W sekcji Ustawienia modelu ustaw Maksymalną liczbę węzłów obliczeniowych na 1, a typ maszyny na n1-standard-2
. Pozostaw bez zmian wszystkie pozostałe ustawienia. Następnie kliknij WDRÓŻ.
Po wdrożeniu stan wdrożonego modelu zmieni się na Wdrożono w Vertex AI.
7. Pobieraj prognozy
Otwórz notatnik Workbench utworzony w ramach konfiguracji. W menu utwórz nowy notatnik TensorFlow 2.
Aby zaimportować niezbędne biblioteki, uruchom komórkę z poniższym kodem
from google.cloud import aiplatform
import tensorflow as tf
import numpy as np
from PIL import Image
Model MobileNet pobrany z TensorFlow Hub został wytrenowany na zbiorze danych ImageNet. Dane wyjściowe modelu MobileNet to liczba odpowiadająca etykiecie klasy w zbiorze danych ImageNet. Aby przekształcić ten numer w łańcuch znaków, musisz pobrać etykiety obrazów.
# Download image labels
labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())
Aby dotrzeć do punktu końcowego, musisz zdefiniować zasób punktu końcowego. Pamiętaj, aby zastąpić wartości {PROJECT_NUMBER}
i {ENDPOINT_ID}
.
PROJECT_NUMBER = "{PROJECT_NUMBER}"
ENDPOINT_ID = "{ENDPOINT_ID}"
endpoint = aiplatform.Endpoint(
endpoint_name=f"projects/{PROJECT_NUMBER}/locations/us-central1/endpoints/{ENDPOINT_ID}")
Numer projektu znajdziesz na stronie głównej konsoli.
Identyfikator punktu końcowego w sekcji Punkty końcowe w Vertex AI.
Następnie przetestuj punkt końcowy.
Najpierw pobierz ten obraz i prześlij go do instancji.
Otwórz obraz w PIL. Następnie zmień rozmiar i skalę o 255. Pamiętaj, że rozmiar obrazu oczekiwany przez model można znaleźć na stronie TensorFlow Hub.
IMAGE_PATH = "test-image.jpg"
IMAGE_SIZE = (128, 128)
im = Image.open(IMAGE_PATH)
im = im.resize(IMAGE_SIZE
im = np.array(im)/255.0
Następnie przekonwertuj dane NumPy na listę, aby można je było wysłać w treści żądania HTTP.
x_test = im.astype(np.float32).tolist()
Na koniec wywołaj funkcję przewidywania w punkcie końcowym, a potem wyszukaj odpowiednią etykietę ciągu.
# make prediction request
result = endpoint.predict(instances=[x_test]).predictions
# post process result
predicted_class = tf.math.argmax(result[0], axis=-1)
string_label = imagenet_labels[predicted_class]
print(f"label ID: {predicted_class}")
print(f"string label: {string_label}")
8. [Opcjonalnie] Użyj TF Serving do optymalizacji prognoz
Aby uzyskać bardziej realistyczne przykłady, lepiej wysyłać obraz bezpośrednio do punktu końcowego, zamiast wczytywać go najpierw w NumPy. Jest to bardziej wydajne, ale musisz zmodyfikować funkcję obsługi modelu TensorFlow. Ta modyfikacja jest niezbędna do konwertowania danych wejściowych na format spodziewany przez model.
Krok 1. Zmień funkcję serwowania
Otwórz nowy notatnik TensorFlow i zaimportuj niezbędne biblioteki.
from google.cloud import aiplatform
import tensorflow as tf
Zamiast pobierać zapisane artefakty modelu, tym razem wczytasz model do TensorFlow za pomocą funkcji hub.KerasLayer
, która otacza model TensorFlow SavedModel warstwą Keras. Aby utworzyć model, możesz użyć interfejsu Keras Sequential API z pobieranym modelem TF Hub jako warstwą i określić kształt danych wejściowych dla modelu.
tfhub_model = tf.keras.Sequential(
[hub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v1_050_128/classification/5")]
)
tfhub_model.build([None, 128, 128, 3])
Zdefiniuj identyfikator URI utworzonego wcześniej zasobnika.
BUCKET_URI = "gs://{YOUR_BUCKET}"
MODEL_DIR = BUCKET_URI + "/bytes_model"
Gdy wysyłasz żądanie do internetowego serwera prognoz, żądanie to jest odbierane przez serwer HTTP. Serwer HTTP wyodrębnia żądanie prognozy z treści żądania HTTP. Wyodrębnione żądanie prognozy jest przekazywane do funkcji wyświetlania. W przypadku gotowych kontenerów prognozowania Vertex AI zawartość żądania jest przekazywana do funkcji serwowania jako tf.string
.
Aby przekazywać obrazy do usługi prognozowania, musisz zakodować za pomocą kodu Base64 bajty skompresowanego obrazu. Dzięki temu treści będą bezpieczne przed modyfikacją podczas przesyłania danych binarnych przez sieć.
Rozwinięty model oczekuje danych wejściowych w postaci nieprzetworzonych (nieskompresowanych) bajtów, dlatego musisz upewnić się, że zakodowane dane Base64 zostaną przekonwertowane z powrotem na nieprzetworzone bajty (np. JPEG), a następnie wstępnie przetworzone, aby odpowiadały wymaganiom modelu, zanim zostaną przekazane jako dane wejściowe do rozwiniętego modelu.
Aby rozwiązać ten problem, zdefiniuj funkcję obsługi (serving_fn
) i dołącz ją do modelu jako krok wstępnej obróbki. Dodajesz dekorator @tf.function
, aby funkcja obsługi była połączona z podstawowym modelem (zamiast z usługą upstream na procesorze CPU).
CONCRETE_INPUT = "numpy_inputs"
def _preprocess(bytes_input):
decoded = tf.io.decode_jpeg(bytes_input, channels=3)
decoded = tf.image.convert_image_dtype(decoded, tf.float32)
resized = tf.image.resize(decoded, size=(128, 128))
return resized
@tf.function(input_signature=[tf.TensorSpec([None], tf.string)])
def preprocess_fn(bytes_inputs):
decoded_images = tf.map_fn(
_preprocess, bytes_inputs, dtype=tf.float32, back_prop=False
)
return {
CONCRETE_INPUT: decoded_images
} # User needs to make sure the key matches model's input
@tf.function(input_signature=[tf.TensorSpec([None], tf.string)])
def serving_fn(bytes_inputs):
images = preprocess_fn(bytes_inputs)
prob = m_call(**images)
return prob
m_call = tf.function(tfhub_model.call).get_concrete_function(
[tf.TensorSpec(shape=[None, 128, 128, 3], dtype=tf.float32, name=CONCRETE_INPUT)]
)
tf.saved_model.save(tfhub_model, MODEL_DIR, signatures={"serving_default": serving_fn})
Gdy wysyłasz dane do prognozowania w pakiecie żądania HTTP, dane obrazu są kodowane w formacie Base64, ale model TensorFlow przyjmuje dane wejściowe w formacie Numpy. Funkcja serwowania dokona konwersji z base64 na tablicę Numpy.
Przesyłając żądanie przewidywania, musisz je przekierować do funkcji obsługi, a nie do modelu, więc musisz znać nazwę warstwy wejściowej funkcji obsługi. Możemy ją odczytać z podpisu funkcji obsługującej.
loaded = tf.saved_model.load(MODEL_DIR)
serving_input = list(
loaded.signatures["serving_default"].structured_input_signature[1].keys()
)[0]
print("Serving function input name:", serving_input)
Krok 2. Zaimportuj dane do rejestru i wdróż
W poprzednich sekcjach pokazaliśmy, jak zaimportować model do rejestru modeli Vertex AI za pomocą interfejsu użytkownika. W tej sekcji omawiamy alternatywny sposób korzystania z pakietu SDK. Pamiętaj, że w razie potrzeby możesz nadal używać interfejsu.
model = aiplatform.Model.upload(
display_name="optimized-model",
artifact_uri=MODEL_DIR,
serving_container_image_uri="us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest",
)
print(model)
Zamiast interfejsu użytkownika możesz też wdrożyć model za pomocą pakietu SDK.
endpoint = model.deploy(
deployed_model_display_name='my-bytes-endpoint',
traffic_split={"0": 100},
machine_type="n1-standard-4",
accelerator_count=0,
min_replica_count=1,
max_replica_count=1,
)
Krok 3. Testowanie modelu
Możesz teraz przetestować punkt końcowy. Zmodyfikowaliśmy funkcję obsługi, więc tym razem możesz wysłać obraz bezpośrednio (zakodowany w formacie base64) w żądaniu zamiast najpierw wczytywać go do NumPy. Pozwoli Ci to też wysyłać większe obrazy bez przekraczania limitu rozmiaru prognoz Vertex AI.
Ponownie pobierz etykiety obrazów
import numpy as np
labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())
Kodowanie obrazu w formacie Base64.
import base64
with open("test-image.jpg", "rb") as f:
data = f.read()
b64str = base64.b64encode(data).decode("utf-8")
Wywołanie prognozy z podaniem nazwy warstwy wejściowej funkcji obsługującej, którą zdefiniowaliśmy wcześniej w zmiennej serving_input
.
instances = [{serving_input: {"b64": b64str}}]
# Make request
result = endpoint.predict(instances=instances).predictions
# Convert image class to string label
predicted_class = tf.math.argmax(result[0], axis=-1)
string_label = imagenet_labels[predicted_class]
print(f"label ID: {predicted_class}")
print(f"string label: {string_label}")
🎉 Gratulacje! 🎉
Poznałeś/poznałaś już te sposoby korzystania z Vertex AI:
- Hostowanie i wdrażanie wytrenowanego modelu
Więcej informacji o różnych częściach Vertex znajdziesz w dokumentacji.
9. Czyszczenie
Zarządzane notatniki Vertex AI Workbench mają funkcję wyłączania w czasie bezczynności, więc nie musisz się martwić o wyłączanie instancji. Jeśli chcesz ręcznie wyłączyć instancję, w konsoli Vertex AI Workbench kliknij przycisk Zatrzymaj. Jeśli chcesz całkowicie usunąć zeszyt, kliknij przycisk Usuń.
Aby usunąć zasobnik na dane, w menu nawigacyjnym w konsoli Cloud przejdź do Cloud Storage, wybierz swój zasobnik i kliknij Usuń: