Prototyp do produkcji: rozproszone trenowanie w Vertex AI

1. Omówienie

W tym module użyjesz Vertex AI, aby uruchomić rozproszone zadanie treningowe w Vertex AI Training przy użyciu TensorFlow.

Ten moduł jest częścią serii filmów Prototype to Production. Zanim go wypróbujesz, ukończ poprzednie moduły. Aby dowiedzieć się więcej, możesz obejrzeć serię filmów towarzyszących:

.

Czego się nauczysz

Poznasz takie zagadnienia jak:

  • Uruchamiaj rozproszone trenowanie na jednej maszynie z wieloma GPU
  • Uruchamiaj rozproszone trenowanie na wielu maszynach

Całkowity koszt uruchomienia tego modułu w Google Cloud wynosi około 2 USD.

2. Wprowadzenie do Vertex AI

W tym module wykorzystano najnowszą ofertę usług AI dostępną w Google Cloud. Vertex AI integruje ofertę systemów uczących się z całego Google Cloud, tworząc bezproblemowe środowisko programistyczne. Wcześniej modele wytrenowane z użyciem AutoML i modele niestandardowe były dostępne w oddzielnych usługach. Nowa oferta jest łączona w 1 interfejs API wraz z innymi nowymi usługami. Możesz też przenieść istniejące projekty do Vertex AI.

Vertex AI obejmuje wiele różnych usług, które obsługują kompleksowe przepływy pracy ML. W tym module skupimy się na wymienionych poniżej usługach: Szkolenia i Workbench.

Omówienie usługi Vertex

3. Omówienie rozproszonego trenowania

Jeśli masz pojedynczy procesor graficzny, TensorFlow użyje tego akceleratora, aby przyspieszyć trenowanie modelu bez dodatkowych działań z Twojej strony. Jeśli jednak chcesz uzyskać dodatkowe korzyści dzięki używaniu kilku procesorów graficznych, musisz użyć interfejsu tf.distribute, który jest modułem TensorFlow do przeprowadzania obliczeń na wielu urządzeniach.

Pierwsza część tego modułu używa narzędzia tf.distribute.MirroredStrategy, które możesz dodać do aplikacji treningowych, wprowadzając kilka zmian w kodzie. Ta strategia tworzy kopię modelu w każdym GPU na Twoim komputerze. Kolejne aktualizacje gradientu będą odbywać się synchronicznie. Oznacza to, że każdy procesor graficzny oblicza ruch do przodu i do tyłu przez model na innym wycinku danych wejściowych. Obliczone gradienty z każdego z tych wycinków są następnie zagregowane dla wszystkich układów GPU i uśredniane w procesie znanym jako all-reduce. Parametry modelu są aktualizowane za pomocą tych uśrednionych gradientów.

Sekcja opcjonalna na końcu modułu używa polecenia tf.distribute.MultiWorkerMirroredStrategy, które jest podobne do MirroredStrategy, z tym że obsługuje więcej niż 1 maszynę. Każda z tych maszyn może też mieć wiele procesorów graficznych. Na przykład MirroredStrategy, MultiWorkerMirroredStrategy to synchroniczna strategia równoległości danych, której można używać, wprowadzając tylko kilka zmian w kodzie. Główną różnicą przy przejściu z synchronicznego równoległości danych na jednej maszynie do wielu jest to, że gradienty na końcu każdego kroku muszą być teraz synchronizowane we wszystkich układach GPU w maszynie i na wszystkich maszynach w klastrze.

Nie musisz znać szczegółów, aby ukończyć ten moduł, ale jeśli chcesz dowiedzieć się więcej o tym, jak działa rozproszone trenowanie w TensorFlow, obejrzyj film poniżej:

4. Konfigurowanie środowiska

Wykonaj czynności opisane w module Trenowanie modeli niestandardowych przy użyciu Vertex AI, aby skonfigurować środowisko.

5. Jedna maszyna, trenowanie z wieloma GPU

Prześlesz rozproszone zadanie treningowe do Vertex AI, umieszczając kod aplikacji treningowej w kontenerze Dockera i przenosząc ten kontener do Google Artifact Registry. Dzięki temu podejściu możesz wytrenować model utworzony za pomocą dowolnej platformy.

Aby rozpocząć, w menu Menu z aplikacjami w notatniku Workbench utworzonym w poprzednich modułach otwórz okno terminala.

Otwórz terminal w notatniku

Krok 1. Napisz kod trenowania

Utwórz nowy katalog o nazwie flowers-multi-gpu i znajdź do niego dysk CD:

mkdir flowers-multi-gpu
cd flowers-multi-gpu

Uruchom następujące polecenie, aby utworzyć katalog na kod trenowania i plik Pythona, w którym umieścisz poniższy kod.

mkdir trainer
touch trainer/task.py

W katalogu flowers-multi-gpu/ powinny znajdować się teraz te elementy:

+ trainer/
    + task.py

Następnie otwórz utworzony przed chwilą plik task.py i skopiuj poniższy kod.

Musisz zastąpić zmienną {your-gcs-bucket} w tabeli BUCKET_ROOT zasobnikiem Cloud Storage, w którym w Laboratorium 1 został zapisany zbiór danych kwiatów.

import tensorflow as tf
import numpy as np
import os

## Replace {your-gcs-bucket} !!
BUCKET_ROOT='/gcs/{your-gcs-bucket}'

# Define variables
NUM_CLASSES = 5
EPOCHS=10
BATCH_SIZE = 32

IMG_HEIGHT = 180
IMG_WIDTH = 180

DATA_DIR = f'{BUCKET_ROOT}/flower_photos'

def create_datasets(data_dir, batch_size):
  '''Creates train and validation datasets.'''

  train_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  validation_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  train_dataset = train_dataset.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
  validation_dataset = validation_dataset.cache().prefetch(buffer_size=tf.data.AUTOTUNE)

  return train_dataset, validation_dataset


def create_model():
  '''Creates model.'''

  model = tf.keras.Sequential([
    tf.keras.layers.Resizing(IMG_HEIGHT, IMG_WIDTH),
    tf.keras.layers.Rescaling(1./255, input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
    tf.keras.layers.Conv2D(16, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')
  ])
  return model

def main():  

  # Create distribution strategy
  strategy = tf.distribute.MirroredStrategy()

  # Get data
  GLOBAL_BATCH_SIZE = BATCH_SIZE * strategy.num_replicas_in_sync
  train_dataset, validation_dataset = create_datasets(DATA_DIR, BATCH_SIZE)

  # Wrap model creation and compilation within scope of strategy
  with strategy.scope():
    model = create_model()
    model.compile(optimizer=tf.keras.optimizers.Adam(),
                  loss=tf.keras.losses.SparseCategoricalCrossentropy(),
                  metrics=['accuracy'])

  history = model.fit(
    train_dataset,
    validation_data=validation_dataset,
    epochs=EPOCHS
  )

  model.save(f'{BUCKET_ROOT}/model_output')


if __name__ == "__main__":
    main()

Zanim utworzysz kontener, przyjrzyjmy się kodowi. Korzystanie z trenowania rozproszonego wiąże się z kilkoma komponentami.

  • W funkcji main() tworzony jest obiekt MirroredStrategy. Następnie dodajesz zmienne modelu do zakresu strategii. Ten krok informuje TensorFlow, które zmienne powinny być powielone w GPU.
  • Wielkość wsadu jest skalowana w górę o num_replicas_in_sync. Skalowanie rozmiaru wsadu jest sprawdzoną metodą w przypadku korzystania ze strategii synchronicznego równoległości danych w TensorFlow. Więcej informacji możesz uzyskać tutaj.

Krok 2. Utwórz plik Dockerfile

Aby skonteneryzować kod, musisz utworzyć plik Dockerfile. W pliku Dockerfile znajdziesz wszystkie polecenia potrzebne do uruchomienia obrazu. Zainstaluje wszystkie niezbędne biblioteki i skonfiguruje punkt wejścia dla kodu trenowania.

W terminalu utwórz pusty plik Dockerfile w katalogu głównym katalogu kwiatów:

touch Dockerfile

W katalogu flowers-multi-gpu/ powinny znajdować się teraz te elementy:

+ Dockerfile
+ trainer/
    + task.py

Otwórz plik Dockerfile i skopiuj do niego poniższy plik:

FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-8

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"]

Krok 3. 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'

Utwórz repozytorium w Artifact Registry. Użyjemy repozytorium utworzonego w pierwszym module.

REPO_NAME='flower-app'

Zdefiniuj zmienną za pomocą identyfikatora URI obrazu kontenera w Artifact Registry:

IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/flower_image_distributed:single_machine

Skonfiguruj Dockera

gcloud auth configure-docker \
    us-central1-docker.pkg.dev

Następnie utwórz kontener, uruchamiając to polecenie z poziomu głównego katalogu flowers-multi-gpu:

docker build ./ -t $IMAGE_URI

Na koniec przekaż go do Artifact Registry:

docker push $IMAGE_URI

Po przeniesieniu kontenera do Artifact Registry możesz rozpocząć zadanie trenowania.

Krok 4. Uruchom zadanie za pomocą pakietu SDK

W tej sekcji dowiesz się, jak skonfigurować i uruchomić rozproszone zadanie trenowania za pomocą pakietu SDK Vertex AI Python.

W Menu z aplikacjami utwórz notatnik TensorFlow 2.

new_notebook

Zaimportuj pakiet Vertex AI SDK.

from google.cloud import aiplatform

Następnie określ CustomContainerTrainingJob.

Musisz zastąpić reguły {PROJECT_ID} w: container_uri i {YOUR_BUCKET} w: staging_bucket.

job = aiplatform.CustomContainerTrainingJob(display_name='flowers-multi-gpu',
                                            container_uri='us-central1-docker.pkg.dev/{PROJECT_ID}/flower-app/flower_image_distributed:single_machine',
                                            staging_bucket='gs://{YOUR_BUCKET}')

Po zdefiniowaniu zadania możesz je uruchomić. Ustaw liczbę akceleratorów na 2. Gdyby używany był tylko 1 GPU, nie zostałoby to uznane za trenowanie rozproszone. W przypadku rozproszonego trenowania na jednej maszynie używasz co najmniej 2 akceleratorów.

my_custom_job.run(replica_count=1,
                  machine_type='n1-standard-4',
                  accelerator_type='NVIDIA_TESLA_V100',
                  accelerator_count=2)

W konsoli możesz zobaczyć postęp zadania.

multigpu_job

6. [Opcjonalnie] Szkolenie wielu pracowników

Po wypróbowaniu rozproszonego trenowania na jednej maszynie z wieloma procesorami graficznymi możesz teraz jeszcze bardziej rozwinąć swoje umiejętności trenowania rozproszonego, trenując na wielu komputerach. Aby obniżyć koszty, nie będziemy dodawać do tych maszyn GPU, ale jeśli chcesz, możesz poeksperymentować, dodając nowe układy GPU.

Otwórz nowe okno terminala w instancji notatnika:

Otwórz terminal w notatniku

Krok 1. Napisz kod trenowania

Utwórz nowy katalog o nazwie flowers-multi-machine i znajdź do niego dysk CD:

mkdir flowers-multi-machine
cd flowers-multi-machine

Uruchom następujące polecenie, aby utworzyć katalog na kod trenowania i plik Pythona, w którym umieścisz poniższy kod.

mkdir trainer
touch trainer/task.py

W katalogu flowers-multi-machine/ powinny znajdować się teraz te elementy:

+ trainer/
    + task.py

Następnie otwórz utworzony przed chwilą plik task.py i skopiuj poniższy kod.

Musisz zastąpić zmienną {your-gcs-bucket} w tabeli BUCKET_ROOT zasobnikiem Cloud Storage, w którym w Laboratorium 1 został zapisany zbiór danych kwiatów.

import tensorflow as tf
import numpy as np
import os

## Replace {your-gcs-bucket} !!
BUCKET_ROOT='/gcs/{your-gcs-bucket}'

# Define variables
NUM_CLASSES = 5
EPOCHS=10
BATCH_SIZE = 32

IMG_HEIGHT = 180
IMG_WIDTH = 180

DATA_DIR = f'{BUCKET_ROOT}/flower_photos'
SAVE_MODEL_DIR = f'{BUCKET_ROOT}/multi-machine-output'

def create_datasets(data_dir, batch_size):
  '''Creates train and validation datasets.'''

  train_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  validation_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  train_dataset = train_dataset.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
  validation_dataset = validation_dataset.cache().prefetch(buffer_size=tf.data.AUTOTUNE)

  return train_dataset, validation_dataset


def create_model():
  '''Creates model.'''

  model = tf.keras.Sequential([
    tf.keras.layers.Resizing(IMG_HEIGHT, IMG_WIDTH),
    tf.keras.layers.Rescaling(1./255, input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
    tf.keras.layers.Conv2D(16, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')
  ])
  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 distribution strategy
  strategy = tf.distribute.MultiWorkerMirroredStrategy()

  # Get data
  GLOBAL_BATCH_SIZE = BATCH_SIZE * strategy.num_replicas_in_sync
  train_dataset, validation_dataset = create_datasets(DATA_DIR, BATCH_SIZE)

  # Wrap variable creation within strategy scope
  with strategy.scope():
    model = create_model()
    model.compile(optimizer=tf.keras.optimizers.Adam(),
                  loss=tf.keras.losses.SparseCategoricalCrossentropy(),
                  metrics=['accuracy'])

  history = model.fit(
    train_dataset,
    validation_data=validation_dataset,
    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(SAVE_MODEL_DIR, task_type, task_id)
  model.save(write_model_path)

if __name__ == "__main__":
    main()

Zanim utworzysz kontener, przyjrzyjmy się kodowi. W kodzie jest kilka komponentów, które są niezbędne, aby aplikacja do trenowania działała z MultiWorkerMirroredStrategy.

  • W funkcji main() tworzony jest obiekt MultiWorkerMirroredStrategy. Następnie dodajesz zmienne modelu do zakresu strategii. Ten kluczowy krok informuje TensorFlow, które zmienne powinny być powielone w replikach.
  • Wielkość wsadu jest skalowana w górę o num_replicas_in_sync. Skalowanie rozmiaru wsadu jest sprawdzoną metodą w przypadku korzystania ze strategii synchronicznego równoległości danych w TensorFlow.
  • Zapisywanie modelu jest nieco bardziej skomplikowane w przypadku wielu instancji roboczych, ponieważ miejsce docelowe musi być różne dla każdej z tych instancji roboczych. Główna instancja robocza zapisze model w wybranym katalogu modelu, a pozostałe instancje robocze zapiszą model w katalogach tymczasowych. Takie katalogi tymczasowe muszą być unikalne, ponieważ dzięki temu wielu instancji roboczych nie będzie mogło zapisywać danych w tej samej lokalizacji. Zapis może obejmować operacje zbiorowe, co oznacza, że wszyscy pracownicy muszą ocalić, a nie tylko szefa. Funkcje _is_chief(), _get_temp_dir(), write_filepath() oraz main() zawierają stały kod, który pomaga zapisać model.

Krok 2. Utwórz plik Dockerfile

Aby skonteneryzować kod, musisz utworzyć plik Dockerfile. W pliku Dockerfile znajdziesz wszystkie polecenia potrzebne do uruchomienia obrazu. Zainstaluje wszystkie niezbędne biblioteki i skonfiguruje punkt wejścia dla kodu trenowania.

W terminalu utwórz pusty plik Dockerfile w katalogu głównym katalogu kwiatów:

touch Dockerfile

W katalogu flowers-multi-machine/ powinny znajdować się teraz te elementy:

+ Dockerfile
+ trainer/
    + task.py

Otwórz plik Dockerfile i skopiuj do niego poniższy plik:

FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-8

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"]

Krok 3. 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'

Utwórz repozytorium w Artifact Registry. Użyjemy repozytorium utworzonego w pierwszym module.

REPO_NAME='flower-app'

Zdefiniuj zmienną za pomocą identyfikatora URI obrazu kontenera w Google Artifact Registry:

IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/flower_image_distributed:multi_machine

Skonfiguruj Dockera

gcloud auth configure-docker \
    us-central1-docker.pkg.dev

Następnie utwórz kontener, uruchamiając to polecenie z poziomu głównego katalogu flowers-multi-machine:

docker build ./ -t $IMAGE_URI

Na koniec przekaż go do Artifact Registry:

docker push $IMAGE_URI

Po przeniesieniu kontenera do Artifact Registry możesz rozpocząć zadanie trenowania.

Krok 4. Uruchom zadanie za pomocą pakietu SDK

W tej sekcji dowiesz się, jak skonfigurować i uruchomić rozproszone zadanie trenowania za pomocą pakietu SDK Vertex AI Python.

W Menu z aplikacjami utwórz notatnik TensorFlow 2.

new_notebook

Zaimportuj pakiet Vertex AI SDK.

from google.cloud import aiplatform

Następnie określ worker_pool_specs.

Vertex AI udostępnia 4 pule instancji roboczych do obsługi różnych typów zadań maszyn.

Pula instancji roboczych 0 konfiguruje główną, główną, algorytm szeregowania lub instancję główną. W MultiWorkerMirroredStrategy wszystkie maszyny są oznaczone jako instancje robocze, czyli fizyczne maszyny, na których są wykonywane zreplikowane obliczenia. Oprócz tego, że każda maszyna jest maszyną roboczą, musi istnieć jeszcze jedna instancja robocza, która wykonuje dodatkowe czynności, takie jak zapisywanie punktów kontrolnych i zapisywanie plików podsumowania w TensorBoard. Ta maszyna jest nazywana główną. Istnieje tylko 1 główna instancja robocza, więc liczba instancji roboczych w puli instancji roboczych 0 zawsze będzie wynosić 1.

Pula instancji roboczych 1 to miejsce, w którym konfigurujesz dodatkowe instancje robocze klastra.

Pierwszy słownik na liście worker_pool_specs reprezentuje pulę instancji roboczych 0, a drugi słownik – pulę instancji roboczych 1. W tym przykładzie obie konfiguracje są identyczne. Jeśli jednak chcesz trenować na 3 maszynach, musisz dodać kolejnych instancji roboczych do puli instancji roboczych 1, ustawiając replica_count na 2. Jeśli chcesz dodać GPU, musisz dodać argumenty accelerator_type i accelerator_count do funkcji machine_spec w przypadku obu pul instancji roboczych. Pamiętaj, że jeśli z MultiWorkerMirroredStrategy chcesz używać układów GPU, każda maszyna w klastrze musi mieć taką samą liczbę GPU. W przeciwnym razie zadanie się nie powiedzie.

Musisz zastąpić regułę {PROJECT_ID} w: image_uri.

# The spec of the worker pools including machine type and Docker image
# Be sure to replace PROJECT_ID in the "image_uri" with your project.

worker_pool_specs=[
     {
        "replica_count": 1,
        "machine_spec": {
          "machine_type": "n1-standard-4",
        },
        "container_spec": {"image_uri": "us-central1-docker.pkg.dev/{PROJECT_ID}/flower-app/flower_image_distributed:multi_machine"}
      },
      {
        "replica_count": 1,
        "machine_spec": {
          "machine_type": "n1-standard-4",
        },
        "container_spec": {"image_uri": "us-central1-docker.pkg.dev/{PROJECT_ID}/flower-app/flower_image_distributed:multi_machine"}
      }
          ]

Następnie utwórz i uruchom CustomJob, zastępując {YOUR_BUCKET} w staging_bucket zasobnikiem na potrzeby testowania.

my_custom_job = aiplatform.CustomJob(display_name='flowers-multi-worker',
                                     worker_pool_specs=worker_pool_specs,
                                     staging_bucket='gs://{YOUR_BUCKET}')

my_custom_job.run()

W konsoli możesz zobaczyć postęp zadania.

multi_worker_job

🎉 Gratulacje! 🎉

Wiesz już, jak używać Vertex AI do:

  • Uruchamiaj rozproszone zadania treningowe za pomocą TensorFlow

Więcej informacji o różnych częściach Vertex znajdziesz w dokumentacji.

7. 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ę, kliknij przycisk Zatrzymaj w sekcji Vertex AI Workbench w konsoli. Jeśli chcesz całkowicie usunąć notatnik, kliknij przycisk Usuń.

Zatrzymaj instancję

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

Usuń miejsce na dane