1. Omówienie
W tym module użyjesz Vertex AI do uruchomienia zadania trenowania z wieloma pracownikami dla modelu TensorFlow.
Czego się nauczysz
Poznasz takie zagadnienia jak:
- Modyfikowanie kodu aplikacji do trenowania wielowątkowego
- Konfigurowanie i uruchamianie zadania treningowego z wieloma wątkami w interfejsie Vertex AI
- Konfigurowanie i uruchamianie zadania trenowania z wieloma wątkami za pomocą pakietu Vertex SDK
Łączny koszt przeprowadzenia tego laboratorium w Google Cloud wynosi około 5 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 jest łączona w 1 interfejs API wraz z innymi nowymi usługami. Możesz też przenieść istniejące projekty do Vertex AI. Jeśli chcesz podzielić się opinią, odwiedź stronę pomocy.
Vertex AI zawiera wiele różnych usług, które obsługują kompleksowe przepływy pracy związane z systemami uczącymi się. Ten moduł będzie dotyczył podanych niżej usług: szkolenia i Workbench.
3. Omówienie przypadku użycia
W tym module użyjesz uczenia transferowego do wytrenowania modelu klasyfikacji obrazów na podstawie zbioru danych Cassava z Zbiorów danych TensorFlow. Architektura, której użyjesz, to model ResNet50 z biblioteki tf.keras.applications
wstępnie wytrenowany na zbiorze danych ImageNet.
Dlaczego warto trenować rozproszonym?
Jeśli masz tylko 1 kartę GPU, TensorFlow będzie używać tego akceleratora do przyspieszania trenowania modelu bez konieczności wykonywania przez Ciebie dodatkowych czynności. Jeśli jednak chcesz uzyskać dodatkowe korzyści dzięki używaniu kilku procesorów graficznych na 1 maszynie lub na kilku komputerach (każda z potencjalnie większą liczbą procesorów graficznych), musisz użyć tf.distribute
– biblioteki TensorFlow, która służy do przeprowadzania obliczeń na wielu urządzeniach. Urządzenie to procesor lub akcelerator (np. procesor graficzny czy TPU) na komputerze, na którym TensorFlow może wykonywać operacje.
Najprostszym sposobem na rozpoczęcie trenowania rozproszonego jest użycie pojedynczego komputera z wieloma GPU. Strategia dystrybucji TensorFlow z modułu tf.distribute
będzie zarządzać koordynacją dystrybucji danych i aktualizacji gradientów na wszystkich procesorach graficznych. Jeśli opanowałeś już trenowanie na jednym hoście i chcesz jeszcze bardziej zwiększyć skalę, dodanie do klastra większej liczby maszyn może jeszcze bardziej zwiększyć wydajność. Możesz użyć klastra maszyn z procesorem CPU lub z co najmniej 1 procesorem graficznym. Ten moduł dotyczy tego drugiego przypadku i pokazuje, jak używać MultiWorkerMirroredStrategy
do rozproszonego trenowania modelu TensorFlow na wielu maszynach w Vertex AI.
MultiWorkerMirroredStrategy
to strategia synchronicznego przetwarzania równoległego danych, której możesz użyć po wprowadzeniu zaledwie kilku zmian w kodzie. Na każdym urządzeniu w klastrze tworzona jest kopia modelu. Kolejne aktualizacje gradientu będą przeprowadzane synchronicznie. Oznacza to, że każde urządzenie robocze oblicza przejścia do przodu i wstecz przez model na innym fragmencie danych wejściowych. Obliczone gradienty z każdego z tych wycinków są następnie agregowane na wszystkich urządzeniach na maszynie i na wszystkich maszynach w klastrze, a następnie zredukowane (zwykle do średniej) w ramach procesu zwanego all-reduce. Następnie optymalizator aktualizuje parametry z tymi zmniejszonymi gradientami, dzięki czemu urządzenia pozostają zsynchronizowane. Aby dowiedzieć się więcej o rozproszonych treningach z TensorFlow, obejrzyj film poniżej:
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. Potrzebujesz go do utworzenia instancji notatnika.
Krok 2. Włącz Container Registry API
Otwórz Container Registry i wybierz Włącz, jeśli nie jest jeszcze włączony. Użyjesz go do utworzenia kontenera na potrzeby niestandardowego zadania trenowania.
Krok 3. Włącz interfejs Vertex AI API
Przejdź do sekcji Vertex AI w konsoli Cloud i kliknij Włącz interfejs Vertex AI API.
Krok 4. 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 zeszytowi nazwę, a potem kliknij Ustawienia zaawansowane.
W sekcji Ustawienia zaawansowane włącz funkcję wyłączania bezczynności i ustaw liczbę minut na 60. Oznacza to, że Twój notatnik automatycznie wyłączy się, gdy nie będzie używany, aby nie ponosić niepotrzebnych kosztów.
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. Udostępnienie instancji zajmie kilka minut.
Po utworzeniu instancji kliknij Otwórz JupyterLab.
Gdy po raz pierwszy użyjesz nowego wystąpienia, zostaniesz poproszony o uwierzytelnienie. Aby to zrobić, wykonaj czynności wyświetlane w interfejsie.
5. Umieszczenie kodu aplikacji do trenowania w kontenerze
Prześlesz to zadanie trenowania do Vertex, umieszczając kod aplikacji treningowej w kontenerze Dockera i wypchając ten kontener do Google Container Registry. Dzięki temu podejściu możesz wytrenować model utworzony za pomocą dowolnej platformy.
Aby rozpocząć, w menu Launcher otwórz okno Terminala w instancji notatek:
Utwórz nowy katalog o nazwie cassava
i przejdź do niego:
mkdir cassava
cd cassava
Krok 1. Utwórz plik Dockerfile
Pierwszym krokiem w konteneryzacji kodu jest utworzenie pliku Dockerfile. W pliku Dockerfile musisz umieścić wszystkie polecenia potrzebne do uruchomienia obrazu. Spowoduje to zainstalowanie wszystkich niezbędnych bibliotek i ustawienie punktu wejścia dla kodu trenowania.
W terminalu utwórz pusty plik Dockerfile:
touch Dockerfile
Otwórz plik Dockerfile i wklej do niego ten kod:
FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-7
WORKDIR /
# Copies the trainer code to the docker image.
COPY trainer /trainer
# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]
Ten plik Dockerfile używa obrazu Dockera TensorFlow Enterprise 2.7 na potrzeby głębokiego uczenia się na GPU. Kontenery do głębokiego uczenia się w Google Cloud są dostarczane z wstępnie zainstalowanymi popularnymi platformami do tworzenia systemów uczących się i narzędzi do analizy danych. Po pobraniu tego obrazu plik Dockerfile konfiguruje punkt wejścia dla kodu trenowania. Te pliki nie zostały jeszcze utworzone – w następnym kroku dodasz kod do trenowania i dostrajania modelu.
Krok 2. Utwórz zasobnik Cloud Storage
W tym zadaniu treningowym wyeksportujesz wytrenowany model TensorFlow do zasobnika Cloud Storage. W terminalu uruchom to polecenie, aby zdefiniować zmienną środowiskową dla projektu. Pamiętaj, aby zastąpić your-cloud-project
identyfikatorem projektu:
PROJECT_ID='your-cloud-project'
Następnie uruchom w terminalu to polecenie, aby utworzyć nowy zasobnik w projekcie.
BUCKET="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET
Krok 3. Dodaj kod trenowania modelu
Aby utworzyć katalog z kodem szkoleniowym i plik Pythona, w którym dodasz kod, uruchom w terminalu następujące polecenie:
mkdir trainer
touch trainer/task.py
W katalogu cassava/
powinien teraz znajdować się ten plik:
+ Dockerfile
+ trainer/
+ task.py
Następnie otwórz utworzony plik task.py
i skopiuj kod poniżej. Zastąp {your-gcs-bucket}
nazwą utworzonego właśnie zasobnika Cloud Storage.
import tensorflow as tf
import tensorflow_datasets as tfds
import os
PER_REPLICA_BATCH_SIZE = 64
EPOCHS = 2
# TODO: replace {your-gcs-bucket} with the name of the Storage bucket you created earlier
BUCKET = 'gs://{your-gcs-bucket}/mwms'
def preprocess_data(image, label):
'''Resizes and scales images.'''
image = tf.image.resize(image, (300,300))
return tf.cast(image, tf.float32) / 255., label
def create_dataset(batch_size):
'''Loads Cassava dataset and preprocesses data.'''
data, info = tfds.load(name='cassava', as_supervised=True, with_info=True)
number_of_classes = info.features['label'].num_classes
train_data = data['train'].map(preprocess_data,
num_parallel_calls=tf.data.experimental.AUTOTUNE)
train_data = train_data.shuffle(1000)
train_data = train_data.batch(batch_size)
train_data = train_data.prefetch(tf.data.experimental.AUTOTUNE)
# Set AutoShardPolicy
options = tf.data.Options()
options.experimental_distribute.auto_shard_policy = tf.data.experimental.AutoShardPolicy.DATA
train_data = train_data.with_options(options)
return train_data, number_of_classes
def create_model(number_of_classes):
'''Creates and compiles pretrained ResNet50 model.'''
base_model = tf.keras.applications.ResNet50(weights='imagenet', include_top=False)
x = base_model.output
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = tf.keras.layers.Dense(1016, activation='relu')(x)
predictions = tf.keras.layers.Dense(number_of_classes, activation='softmax')(x)
model = tf.keras.Model(inputs=base_model.input, outputs=predictions)
model.compile(
loss='sparse_categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(0.0001),
metrics=['accuracy'])
return model
def _is_chief(task_type, task_id):
'''Helper function. Determines if machine is chief.'''
return task_type == 'chief'
def _get_temp_dir(dirpath, task_id):
'''Helper function. Gets temporary directory for saving model.'''
base_dirpath = 'workertemp_' + str(task_id)
temp_dir = os.path.join(dirpath, base_dirpath)
tf.io.gfile.makedirs(temp_dir)
return temp_dir
def write_filepath(filepath, task_type, task_id):
'''Helper function. Gets filepath to save model.'''
dirpath = os.path.dirname(filepath)
base = os.path.basename(filepath)
if not _is_chief(task_type, task_id):
dirpath = _get_temp_dir(dirpath, task_id)
return os.path.join(dirpath, base)
def main():
# Create strategy
strategy = tf.distribute.MultiWorkerMirroredStrategy()
# Get data
global_batch_size = PER_REPLICA_BATCH_SIZE * strategy.num_replicas_in_sync
train_data, number_of_classes = create_dataset(global_batch_size)
# Wrap variable creation within strategy scope
with strategy.scope():
model = create_model(number_of_classes)
model.fit(train_data, epochs=EPOCHS)
# Determine type and task of the machine from
# the strategy cluster resolver
task_type, task_id = (strategy.cluster_resolver.task_type,
strategy.cluster_resolver.task_id)
# Based on the type and task, write to the desired model path
write_model_path = write_filepath(BUCKET, task_type, task_id)
model.save(write_model_path)
if __name__ == "__main__":
main()
Zanim skompilujesz kontener, przyjrzyj się bliżej kodom, które korzystają z interfejsu API MultiWorkerMirroredStrategy
.tf.distribute.Strategy
Kod musi zawierać kilka komponentów, które są niezbędne do współdziałania z MultiWorkerMirroredStrategy
.
- Dane muszą być podzielone na fragmenty, co oznacza, że każdemu procesowi przypisany jest podzbiór całego zbioru danych. Dlatego na każdym kroku każdy proces roboczy przetwarza globalny rozmiar zbiorczego przetwarzania elementów zbioru danych, które nie nakładają się na siebie. Dzielenie na fragmenty następuje automatycznie za pomocą parametru
tf.data.experimental.AutoShardPolicy
, który może być ustawiony naFILE
lubDATA
. W tym przykładzie funkcjacreate_dataset()
ustawia wartośćAutoShardPolicy
naDATA
, ponieważ zbiór danych cassava nie jest pobierany jako kilka plików. Jeśli jednak nie ustawisz wartościDATA
, zadziałają domyślne zasadyAUTO
, a efekt końcowy będzie taki sam. Więcej informacji o dzieleniu zbiorów danych za pomocąMultiWorkerMirroredStrategy
znajdziesz tutaj. - W funkcji
main()
tworzony jest obiektMultiWorkerMirroredStrategy
. Następnie dodajesz zmienne modelu do zakresu strategii. Ten kluczowy krok informuje TensorFlow, które zmienne powinny być powielone w replikach. - Wielkość wsadu jest zwiększana o
num_replicas_in_sync
. Dzięki temu każda replika przetwarza taką samą liczbę przykładów na każdym kroku. Skalowanie rozmiaru wsadu jest sprawdzoną metodą w przypadku korzystania ze strategii synchronicznego równoległości danych w TensorFlow. - W przypadku wielu instancji roboczych zapisywanie modelu jest nieco bardziej skomplikowane, ponieważ miejsce docelowe musi być inne dla każdej instancji. Główny pracownik zapisze model w wybranym katalogu, a pozostałe osoby zapiszą go w tymczasowych katalogach. Te katalogi tymczasowe muszą być unikalne, aby zapobiec zapisywaniu danych przez wielu pracowników w tym samym miejscu. Zapisy mogą zawierać operacje zbiorcze, co oznacza, że wszyscy pracownicy muszą je zapisać, a nie tylko szef. Funkcje
_is_chief()
,_get_temp_dir()
,write_filepath()
imain()
zawierają kod szablonowy, który pomaga zapisać model.
Jeśli używasz MultiWorkerMirroredStrategy
w innym środowisku, możesz mieć skonfigurowaną zmienną środowiskową TF_CONFIG
. Vertex AI automatycznie ustawia zmienną TF_CONFIG
, więc nie musisz definiować tej zmiennej na każdym komputerze w klastrze.
Krok 4. Utwórz kontener
W terminalu uruchom to polecenie, aby zdefiniować zmienną env dla swojego projektu, pamiętając o zastąpieniu your-cloud-project
identyfikatorem projektu:
PROJECT_ID='your-cloud-project'
Zdefiniuj zmienną z identyfikatorem URI obrazu kontenera w Google Container Registry:
IMAGE_URI="gcr.io/$PROJECT_ID/multiworker:cassava"
Skonfiguruj Dockera
gcloud auth configure-docker
Następnie utwórz kontener, uruchamiając to polecenie w katalogu głównym cassava
:
docker build ./ -t $IMAGE_URI
Na koniec prześlij go do Google Container Registry:
docker push $IMAGE_URI
Po przeniesieniu kontenera do Container Registry możesz rozpocząć zadanie trenowania.
6. Uruchamianie zadania treningowego z wieloma wątkami w Vertex AI
W tym laboratorium korzystamy z niestandardowego trenowania za pomocą kontenera niestandardowego w Google Container Registry, ale możesz też uruchomić zadanie trenowania z gotowymi kontenerami.
Zacznij od sekcji Trenowanie w sekcji Vertex w konsoli Cloud:
Krok 1. Skonfiguruj zadanie trenowania
Aby podać parametry zadania trenowania, kliknij Utwórz.
- W sekcji Zbiór danych wybierz Brak zarządzanego zbioru danych.
- Następnie jako metodę trenowania wybierz Trenowanie niestandardowe (zaawansowane) i kliknij Dalej.
- W polu Nazwa modelu wpisz
multiworker-cassava
(lub inną nazwę modelu) - Kliknij Dalej.
W kroku „Ustawienia kontenera” wybierz Kontener niestandardowy:
W pierwszym polu (Obraz kontenera) wpisz wartość zmiennej IMAGE_URI
z poprzedniej sekcji. Powinien on mieć postać gcr.io/your-cloud-project/multiworker:cassava
z identyfikatorem Twojego projektu. Pozostałe pola pozostaw puste i kliknij Dalej.
Pomiń krok dotyczący hiperparametrów H, klikając ponownie Dalej.
Krok 2. Skonfiguruj klaster obliczeniowy
Vertex AI udostępnia 4 pule instancji roboczych, które obsługują różne typy zadań maszynowych.
Pula instancji roboczych 0 konfiguruje instancję główną, główną, planującą lub „główną”. W MultiWorkerMirroredStrategy
wszystkie maszyny są oznaczone jako workery, czyli fizyczne maszyny, na których wykonywane są obliczenia powielone. Oprócz tego, że każda maszyna jest pracownikiem, musi być jeden pracownik, który wykonuje dodatkowe zadania, takie jak zapisywanie punktów kontrolnych i zapisywanie plików podsumowania w TensorBoard. Ten komputer nosi nazwę głównego. Zawsze jest tylko 1 główny pracownik, więc liczba pracowników w puli instancji roboczych 0 będzie zawsze 1.
W sekcji Obliczenia i ceny pozostaw wybrany region bez zmian i skonfiguruj Pula instancji roboczych 0 w ten sposób:
W puli instancji roboczych 1 konfigurujesz instancje robocze na potrzeby klastra.
Skonfiguruj pulę instancji roboczych 1 w ten sposób:
Klaster jest teraz skonfigurowany tak, aby zawierać 2 maszyny z procesorem CPU. Gdy uruchomisz kod aplikacji do trenowania, MultiWorkerMirroredStrategy
rozprowadzi trenowanie na obu maszynach.
MultiWorkerMirroredStrategy
ma tylko typy zadań głównych i podrzędnych, więc nie trzeba konfigurować dodatkowych puli zadań. Jeśli jednak używasz biblioteki ParameterServerStrategy
TensorFlow, serwery parametrów musisz skonfigurować w puli instancji roboczych 2. Jeśli chcesz dodać do klastra oceniającego, skonfiguruj tę maszynę w puli instancji roboczych 3.
Kliknij Rozpocznij trenowanie, aby rozpocząć zadanie dostrajania hiperparametrów. W sekcji Szkolenia w konsoli na karcie POTOKI SZKOLENIOWE zobaczysz nowo uruchomione zadanie:
🎉 Gratulacje! 🎉
Poznałeś/poznałaś już te sposoby korzystania z Vertex AI:
- Uruchom zadanie treningowe z wieloma instancjami roboczymi dla kodu treningowego udostępnionego w niestandardowym kontenerze. W tym przykładzie użyto modelu TensorFlow, ale możesz wytrenować model utworzony za pomocą dowolnej platformy za pomocą niestandardowych lub wbudowanych kontenerów.
Więcej informacji o różnych elementach Vertex znajdziesz w dokumentacji.
7. [Opcjonalnie] Użyj pakietu Vertex SDK
W poprzedniej sekcji pokazaliśmy, jak uruchomić zadanie treningowe za pomocą interfejsu użytkownika. W tej sekcji zobaczysz alternatywny sposób przesyłania zadania treningowego za pomocą interfejsu Vertex Python API.
Wróć do instancji notatnika i utwórz notatnik TensorFlow 2 za pomocą programu uruchamiającego:
Zaimportuj pakiet Vertex AI SDK.
from google.cloud import aiplatform
Aby uruchomić zadanie treningowe z wieloma instancjami roboczymi, musisz najpierw zdefiniować specyfikację puli instancji roboczych. Pamiętaj, że użycie procesorów graficznych w specyfikacji jest całkowicie opcjonalne. Jeśli chcesz utworzyć klaster tylko z procesorami CPU, jak pokazano w poprzedniej sekcji, możesz usunąć accelerator_type
i accelerator_count
.
# The spec of the worker pools including machine type and Docker image
# Be sure to replace {YOUR-PROJECT-ID} with your project ID.
worker_pool_specs=[
{
"replica_count": 1,
"machine_spec": {
"machine_type": "n1-standard-8", "accelerator_type": "NVIDIA_TESLA_V100", "accelerator_count": 1
},
"container_spec": {"image_uri": "gcr.io/{YOUR-PROJECT-ID}/multiworker:cassava"}
},
{
"replica_count": 1,
"machine_spec": {
"machine_type": "n1-standard-8", "accelerator_type": "NVIDIA_TESLA_V100", "accelerator_count": 1
},
"container_spec": {"image_uri": "gcr.io/{YOUR-PROJECT-ID}/multiworker:cassava"}
}
]
Następnie utwórz i uruchom CustomJob
. Musisz zastąpić {YOUR_BUCKET}
zasobnikiem w projekcie na potrzeby testowania. Możesz użyć tego samego zasobnika, który został utworzony wcześniej.
# Replace YOUR_BUCKET
my_multiworker_job = aiplatform.CustomJob(display_name='multiworker-cassava-sdk',
worker_pool_specs=worker_pool_specs,
staging_bucket='gs://{YOUR_BUCKET}')
my_multiworker_job.run()
W sekcji Training w konsoli na karcie CUSTOM ZADANIA zobaczysz swoje zadanie trenowania:
8. Czyszczenie
Skonfigurowaliśmy notatnik tak, aby przekraczał limit czasu po 60 minutach bezczynności, więc nie musimy się martwić wyłączeniem 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 Cloud Storage, w menu nawigacyjnym konsoli Cloud przejdź do usługi Storage, wybierz zasobnik i kliknij Usuń: