1. Przegląd
W tym laboratorium dowiesz się, jak za pomocą Vertex AI uzyskiwać prognozy z wytrenowanego modelu klasyfikacji obrazów.
Czego się dowiesz
Poznasz takie zagadnienia jak:
- Importowanie modelu TensorFlow do rejestru modeli Vertex AI
- Uzyskiwanie prognoz online
- Aktualizowanie funkcji udostępniania TensorFlow
Całkowity koszt ukończenia tego laboratorium w Google Cloud wynosi około 1 USD.
2. Wprowadzenie do Vertex AI
W tym module wykorzystujemy najnowszą ofertę produktów AI dostępną w Google Cloud. Vertex AI integruje oferty ML w Google Cloud, zapewniając płynne środowisko programistyczne. Wcześniej modele wytrenowane za pomocą AutoML i modele niestandardowe były dostępne w ramach osobnych usług. Nowa oferta łączy je w jeden interfejs API wraz z innymi nowymi usługami. Możesz też przeprowadzić migrację istniejących projektów do Vertex AI.
Vertex AI obejmuje wiele różnych usług, które obsługują kompleksowe przepływy pracy związane z uczeniem maszynowym. Ten moduł skupia się na wyróżnionych poniżej usługach: Prognozy i Workbench.

3. Omówienie przypadku użycia
W tym laboratorium 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 zastosowań, takich jak wektory dystrybucyjne, generowanie tekstu, zamiana mowy na tekst, segmentacja obrazów i inne.
W tym module użyjemy modelu klasyfikacji obrazów MobileNet V1, który został wstępnie wytrenowany na zbiorze danych ImageNet. Korzystając z gotowych modeli z TensorFlow Hub lub innych podobnych repozytoriów deep learning, możesz wdrażać wysokiej jakości modele ML do wielu zadań prognozowania bez konieczności trenowania modeli.
4. Konfigurowanie środowiska
Aby wykonać to ćwiczenie, musisz mieć projekt w Google Cloud Platform z włączonymi płatnościami. Aby utworzyć projekt, postępuj zgodnie z instrukcjami.
Krok 1. Włącz interfejs Compute Engine API
Przejdź do Compute Engine i kliknij Włącz, jeśli nie jest jeszcze włączona.
Krok 2. Włącz interfejs Vertex AI API
Otwórz sekcję Vertex AI w konsoli Cloud i kliknij Włącz interfejs Vertex AI API.

Krok 3. Tworzenie instancji Vertex AI Workbench
W sekcji Vertex AI w konsoli Cloud kliknij Workbench:

Włącz interfejs Notebooks API, jeśli nie jest jeszcze włączony.

Po włączeniu kliknij ZARZĄDZANE NOTATNIKI:

Następnie wybierz NOWY NOTEBOOK.

Nadaj nazwę notatnikowi, 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.

Wszystkie pozostałe ustawienia zaawansowane możesz pozostawić bez zmian.
Następnie kliknij Utwórz. Udostępnienie instancji zajmie 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 z modelem MobileNet V1 wytrenowanym na zbiorze danych ImageNet.
Kliknij Pobierz, aby pobrać zapisane artefakty modelu.

W sekcji Cloud Storage w konsoli Google Cloud kliknij UTWÓRZ.

Nadaj zasobnikowi nazwę i wybierz region us-central1. Następnie kliknij UTWÓRZ.

Prześlij do zasobnika pobrany model z TensorFlow Hub. Najpierw rozpakuj plik.

Twój 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. Importowanie modelu do rejestru
W konsoli Cloud otwórz sekcję Vertex AI Rejestr modeli.

Kliknij IMPORT.
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, w której są przechowywane artefakty modelu.

Możesz pominąć sekcję Wyjaśnienie.
Następnie kliknij IMPORT.
Po zaimportowaniu model pojawi się w rejestrze modeli.

6. Wdrażanie modelu
W rejestrze modeli kliknij 3 kropki po prawej stronie modelu i wybierz Wdróż w punkcie końcowym.

W sekcji Zdefiniuj punkt końcowy wybierz 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. Pozostałe ustawienia pozostaw bez zmian. Następnie kliknij WDRAŻAJ.

Po wdrożeniu stan wdrożenia zmieni się na Wdrożono w Vertex AI.

7. Pobieraj prognozy
Otwórz notatnik Workbench utworzony w krokach konfiguracji. W programie uruchamiającym utwórz nowy notatnik TensorFlow 2.

Uruchom poniższą komórkę, aby zaimportować niezbędne biblioteki.
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ć tę liczbę w etykietę tekstową, 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ć zmienne {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.

oraz 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 za pomocą biblioteki PIL. Następnie zmień rozmiar i skalę o 255. Rozmiar obrazu oczekiwany przez model znajdziesz na stronie modelu w 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 było je wysłać w treści żądania HTTP.
x_test = im.astype(np.float32).tolist()
Na koniec wywołaj punkt końcowy, aby uzyskać prognozę, a potem wyszukaj odpowiednią etykietę tekstową.
# 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żywanie TF Serving do optymalizacji prognoz
Aby uzyskać bardziej realistyczne przykłady, prawdopodobnie lepiej będzie wysłać sam obraz bezpośrednio do punktu końcowego, zamiast najpierw wczytywać go do NumPy. Jest to bardziej wydajne, ale musisz zmodyfikować funkcję obsługi modelu TensorFlow. Ta modyfikacja jest potrzebna do przekształcenia danych wejściowych w format oczekiwany przez model.
Krok 1. Zmodyfikuj funkcję wyświetlania
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 załadujesz model do TensorFlow za pomocą funkcji hub.KerasLayer, która opakowuje model TensorFlow SavedModel jako warstwę Keras. Aby utworzyć model, możesz użyć interfejsu Keras Sequential API z pobranym modelem TF Hub jako warstwą i określić kształt danych wejściowych 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])
Określ URI utworzonego wcześniej zasobnika.
BUCKET_URI = "gs://{YOUR_BUCKET}"
MODEL_DIR = BUCKET_URI + "/bytes_model"
Gdy wysyłasz żądanie do serwera prognozowania online, jest ono odbierane przez serwer HTTP. Serwer HTTP wyodrębnia żądanie prognozy z treści żądania HTTP. Wyodrębnione żądanie prognozy jest przekazywane do funkcji obsługi. W przypadku gotowych kontenerów prognozowania Vertex AI treść żądania jest przekazywana do funkcji obsługi jako tf.string.
Aby przekazać obrazy do usługi prognozowania, musisz zakodować skompresowane bajty obrazu w formacie Base64, co zabezpiecza treść przed modyfikacją podczas przesyłania danych binarnych przez sieć.
Wdrożony model oczekuje danych wejściowych w postaci surowych (nieskompresowanych) bajtów, dlatego musisz zadbać o to, aby dane zakodowane w formacie Base64 zostały przekonwertowane z powrotem na surowe bajty (np. JPEG), a następnie wstępnie przetworzone w taki sposób, aby spełniały wymagania modelu. Dopiero wtedy można je przekazać jako dane wejściowe do wdrożonego modelu.
Aby rozwiązać ten problem, zdefiniuj funkcję udostępniania (serving_fn) i dołącz ją do modelu jako krok przetwarzania wstępnego. Dodajesz dekorator @tf.function, aby funkcja udostępniania była połączona z modelem bazowym (zamiast z procesorem).
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 jako pakiet żądania HTTP, dane obrazu są kodowane w formacie Base64, ale model TensorFlow przyjmuje dane wejściowe numpy. Funkcja obsługi będzie konwertować dane z formatu base64 na tablicę NumPy.
W przypadku żądania prognozy musisz kierować je do funkcji obsługującej zamiast do modelu, więc musisz znać nazwę warstwy wejściowej funkcji obsługującej. Możemy uzyskać tę nazwę z sygnatury 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 do rejestru i wdroż
W poprzednich sekcjach pokazaliśmy, jak zaimportować model do Vertex AI Model Registry za pomocą interfejsu. W tej sekcji znajdziesz alternatywny sposób korzystania z pakietu SDK. Pamiętaj, że jeśli wolisz, możesz nadal korzystać z 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)
Model możesz też wdrożyć za pomocą pakietu SDK zamiast interfejsu.
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. Przetestuj model
Teraz możesz przetestować punkt końcowy. Ponieważ zmodyfikowaliśmy funkcję obsługi, tym razem możesz wysłać obraz bezpośrednio (zakodowany w formacie base64) w żądaniu, zamiast najpierw wczytywać go do NumPy. Umożliwi to również wysyłanie większych obrazów bez przekraczania limitu rozmiaru prognoz Vertex AI.
Ponowne pobieranie etykiet 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())
Zakoduj obraz w formacie Base64.
import base64
with open("test-image.jpg", "rb") as f:
data = f.read()
b64str = base64.b64encode(data).decode("utf-8")
Wywołaj prognozę, podając nazwę 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! 🎉
Dowiedziałeś się, jak używać Vertex AI do:
- Hostowanie i wdrażanie wstępnie 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 przypadku braku aktywności, więc nie musimy się martwić o wyłączenie instancji. Jeśli chcesz ręcznie wyłączyć instancję, kliknij przycisk Zatrzymaj w sekcji Vertex AI Workbench w konsoli. Jeśli chcesz całkowicie usunąć notatnik, kliknij przycisk Usuń.

Aby usunąć zasobnik Storage, w menu nawigacyjnym w konsoli Cloud otwórz Storage, wybierz zasobnik i kliknij Usuń:
