Vertex AI: שימוש באריזה אוטומטית כדי לכוונן את BERT עם חיבוק פנים באימון Vertex AI

1. סקירה כללית

בשיעור ה-Lab הזה תלמדו איך להריץ משימת אימון בהתאמה אישית ב-Vertex AI Training באמצעות התכונה 'אריזה אוטומטית'. משימות אימון בהתאמה אישית ב-Vertex AI משתמשות בקונטיינרים. אם אתם לא רוצים ליצור קובץ אימג' משלכם, תוכלו להשתמש ב-autopackaging. המערכת תיצור קובץ אימג' מותאם אישית של Docker על סמך הקוד שלכם, תעביר את קובץ האימג' ל-Container Registry ותפעיל CustomJob על סמך קובץ האימג'.

מה תלמדו

תלמדו איך:

העלות הכוללת להרצת שיעור ה-Lab הזה ב-Google Cloud היא כ-2$.

2. סקירה כללית של תרחיש לדוגמה

בעזרת ספריות מ-Hugging Face, תבצעו שיפורים ותכווננו מודל Bert במערך הנתונים של IMDB. המודל יחזה אם ביקורת על סרט היא חיובית או שלילית. מערך הנתונים יורד מספריית מערכי הנתונים של Hugging Face, ומודל Bert מספריית הטרנספורמרים של Hugging Face.

3. מבוא ל-Vertex AI

במעבדה הזו נעשה שימוש במוצרי ה-AI החדשים ביותר שזמינים ב-Google Cloud. Vertex AI משלבת את חבילות ה-ML ב-Google Cloud לחוויית פיתוח חלקה. בעבר, היה אפשר לגשת למודלים שהותאמו אישית ולמודלים שהותאמו באמצעות AutoML דרך שירותים נפרדים. המוצר החדש משלב את שניהם ב-API אחד, יחד עם מוצרים חדשים אחרים. אפשר גם להעביר פרויקטים קיימים ל-Vertex AI. יש לך משוב? אפשר להיכנס לדף התמיכה.

Vertex AI כולל הרבה מוצרים שונים לתמיכה בתהליכי עבודה של למידת מכונה מקצה לקצה. שיעור ה-Lab הזה יתמקד בהדרכה וב-Workbench.

סקירה כללית על מוצרי Vertex

4. הגדרת הסביבה

כדי להריץ את הקודלה הזה, צריך פרויקט ב-Google Cloud Platform שבו החיוב מופעל. כדי ליצור פרויקט, יש לפעול לפי ההוראות האלה.

שלב 1: מפעילים את Compute Engine API

עוברים אל Compute Engine ובוחרים באפשרות Enable (הפעלה) אם היא עדיין לא מופעלת.

שלב 2: מפעילים את Vertex AI API

עוברים אל הקטע Vertex AI במסוף Cloud ולוחצים על Enable Vertex AI API.

מרכז הבקרה של Vertex AI

שלב 3: מפעילים את Container Registry API

עוברים אל Container Registry ובוחרים באפשרות Enable (הפעלה) אם היא עדיין לא מסומנת. תשתמשו בו כדי ליצור קונטיינר למשימת האימון בהתאמה אישית.

שלב 4: יצירת מכונה של Vertex AI Workbench

בקטע Vertex AI במסוף Cloud, לוחצים על Workbench:

התפריט של Vertex AI

לאחר מכן, לוחצים על מאגרי הערות מנוהלים:

Notebooks_UI

לאחר מכן בוחרים באפשרות מחברות חדשה.

new_notebook

נותנים שם למחברת ולוחצים על הגדרות מתקדמות.

create_notebook

בקטע 'הגדרות מתקדמות', מפעילים את ההגדרה 'כיבוי במצב חוסר פעילות' ומגדירים את מספר הדקות ל-60. המשמעות היא שהמחשב הנייד יכבה באופן אוטומטי כשלא משתמשים בו, כדי שלא תחויבו בעלויות מיותרות.

idle_timeout

אפשר להשאיר את כל שאר ההגדרות המתקדמות כפי שהן.

לאחר מכן, לוחצים על יצירה.

אחרי שהמכונה נוצרה, בוחרים באפשרות Open JupyterLab.

open_jupyterlab

בפעם הראשונה שתשתמשו במכונה חדשה, תתבקשו לבצע אימות.

אימות

5. כתיבה של קוד אימון

כדי להתחיל, פותחים חלון Terminal במכונה של ה-notebook מתפריט מרכז האפליקציות:

launcher_terminal

יוצרים ספרייה חדשה בשם autopkg-codelab ומעבירים אליה את הספרייה באמצעות cd.

mkdir autopkg-codelab
cd autopkg-codelab

ב-Terminal, מריצים את הפקודות הבאות כדי ליצור ספרייה לקוד האימון וקובץ Python שבו תוסיפו את הקוד:

mkdir trainer
touch trainer/task.py

עכשיו אמורים להופיע בספרייה autopkg-codelab/:

+ trainer/
    + task.py

לאחר מכן, פותחים את הקובץ task.py שיצרתם ומעתיקים את הקוד שבהמשך.

import argparse

import tensorflow as tf
from datasets import load_dataset
from transformers import AutoTokenizer
from transformers import TFAutoModelForSequenceClassification

CHECKPOINT = "bert-base-cased"

def get_args():
  '''Parses args.'''

  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--epochs',
      required=False,
      default=3,
      type=int,
      help='number of epochs')
  parser.add_argument(
      '--job_dir',
      required=True,
      type=str,
      help='bucket to store saved model, include gs://')
  args = parser.parse_args()
  return args


def create_datasets():
    '''Creates a tf.data.Dataset for train and evaluation.'''

    raw_datasets = load_dataset('imdb')
    tokenizer = AutoTokenizer.from_pretrained(CHECKPOINT)
    tokenized_datasets = raw_datasets.map((lambda examples: tokenize_function(examples, tokenizer)), batched=True)

    # To speed up training, we use only a portion of the data.
    # Use full_train_dataset and full_eval_dataset if you want to train on all the data.
    small_train_dataset = tokenized_datasets['train'].shuffle(seed=42).select(range(1000))
    small_eval_dataset = tokenized_datasets['test'].shuffle(seed=42).select(range(1000))
    full_train_dataset = tokenized_datasets['train']
    full_eval_dataset = tokenized_datasets['test']

    tf_train_dataset = small_train_dataset.remove_columns(['text']).with_format("tensorflow")
    tf_eval_dataset = small_eval_dataset.remove_columns(['text']).with_format("tensorflow")

    train_features = {x: tf_train_dataset[x] for x in tokenizer.model_input_names}
    train_tf_dataset = tf.data.Dataset.from_tensor_slices((train_features, tf_train_dataset["label"]))
    train_tf_dataset = train_tf_dataset.shuffle(len(tf_train_dataset)).batch(8)

    eval_features = {x: tf_eval_dataset[x] for x in tokenizer.model_input_names}
    eval_tf_dataset = tf.data.Dataset.from_tensor_slices((eval_features, tf_eval_dataset["label"]))
    eval_tf_dataset = eval_tf_dataset.batch(8)

    return train_tf_dataset, eval_tf_dataset


def tokenize_function(examples, tokenizer):
    '''Tokenizes text examples.'''

    return tokenizer(examples['text'], padding='max_length', truncation=True)


def main():
    args = get_args()
    train_tf_dataset, eval_tf_dataset = create_datasets()
    model = TFAutoModelForSequenceClassification.from_pretrained(CHECKPOINT, num_labels=2)

    model.compile(
        optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),
        loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
        metrics=tf.metrics.SparseCategoricalAccuracy(),
    )

    model.fit(train_tf_dataset, validation_data=eval_tf_dataset, epochs=args.epochs)
    model.save(f'{args.job_dir}/model_output')


if __name__ == "__main__":
    main()

כמה הערות לגבי הקוד:

  • CHECKPOINT הוא המודל שרוצים לבצע לו כוונון עדין. במקרה כזה, אנחנו משתמשים ב-BERT.
  • שיטת TFAutoModelForSequenceClassification תטען את הארכיטקטורה של מודל השפה שצוינה ואת המשקלים ב-TensorFlow, ותוסיף 'ראש' (head) של סיווג עם משקלים שהוגדרו באופן אקראי. במקרה הזה, יש לנו בעיית סיווג בינארית (חיובית או שלילית), ולכן אנחנו מציינים את num_labels=2 עבור המסווג הזה.

6. יצירת קונטיינרים והרצה של קוד אימון באופן מקומי

אפשר להשתמש בפקודה gcloud ai custom-jobs local-run כדי ליצור קובץ אימג' בקונטיינר של Docker על סמך קוד האימון ולהריץ את קובץ האימג' כקונטיינר במחשב המקומי. כשמריצים קונטיינר באופן מקומי, קוד האימון מופעל באופן דומה לאופן שבו הוא פועל ב-Vertex AI Training. כך אפשר לנפות באגים בקוד לפני שמבצעים אימון בהתאמה אישית ב-Vertex AI.

במשימת האימון, נייצא את המודל המאומן שלנו לקטגוריה של Cloud Storage. ב-Terminal, מריצים את הפקודה הבאה כדי להגדיר משתנה סביבה לפרויקט. חשוב להחליף את your-cloud-project במזהה הפרויקט:

PROJECT_ID='your-cloud-project'

לאחר מכן יוצרים קטגוריה. אם יש לכם קטגוריה קיימת, אתם יכולים להשתמש בה במקום זאת.

BUCKET_NAME="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET_NAME

כשנריץ משימת אימון מותאמת אישית בהדרכה של Vertex AI, נשתמש ב-GPU. אבל מכיוון שלא צייינו את מכונה של Workbench עם מעבדי GPU, נשתמש בתמונה מבוססת-מעבד לבדיקה מקומית. בדוגמה הזו אנחנו משתמשים בקונטיינר מובנה מראש של Vertex AI Training.

מריצים את הפקודה הבאה כדי להגדיר את ה-URI של קובץ אימג' ב-Docker שישמש כבסיס של הקונטיינר.

BASE_CPU_IMAGE=us-docker.pkg.dev/vertex-ai/training/tf-cpu.2-7:latest

לאחר מכן, מגדירים שם לקובץ האימג' של Docker שנוצר באמצעות פקודת ה-run המקומית.

OUTPUT_IMAGE=$PROJECT_ID-local-package-cpu:latest

קוד האימון שלנו משתמש בספריות הטרנספורמציות ובמערכי הנתונים של Hugging Face. הספריות האלה לא כלולות בתמונה שבחרנו כתמונה הבסיסית, לכן נצטרך לציין אותן כדרישה. לשם כך, נוצר קובץ requirements.txt בספרייה autopkg-codelab.

עליך לוודא שנמצאים בספרייה autopkg-codelab ולהקליד את הפקודה הבאה במסוף.

touch requirements.txt

עכשיו אמורים להופיע בספרייה autopkg-codelab:

+ requirements.txt
+ trainer/
    + task.py

יש לפתוח את קובץ הדרישות ולהדביק את הפרטים הבאים

datasets==1.18.2
transformers==4.16.2

לבסוף, מריצים את הפקודה gcloud ai custom-jobs local-run כדי להתחיל את האימון במכונה המנוהלת של Workbench.

gcloud ai custom-jobs local-run \
--executor-image-uri=$BASE_CPU_IMAGE \
--python-module=trainer.task \
--output-image-uri=$OUTPUT_IMAGE \
-- \
--job_dir=$BUCKET_NAME

קובץ האימג' של Docker אמור להיבנות. יחסי התלות שהוספנו לקובץ requirements.txt יותקנו באמצעות pip. בפעם הראשונה שתפעילו את הפקודה הזו, השלמת הפעולה עשויה להימשך כמה דקות. אחרי יצירת התמונה, הקובץ task.py יתחיל לפעול ותראו את אימון המודל. התוצאה אמורה להיראות כך:

local_training

מכיוון שאנחנו לא משתמשים ב-GPU באופן מקומי, אימון המודלים יימשך זמן רב. אפשר להקיש על Ctrl+c ולבטל את האימון המקומי במקום להמתין לסיום המשימה.

שימו לב: אם אתם רוצים לבצע בדיקות נוספות, אתם יכולים גם להריץ ישירות את התמונה שנוצרה למעלה, בלי לארוז אותה מחדש.

gcloud beta ai custom-jobs local-run \
--executor-image-uri=$OUTPUT_IMAGE \
-- \
--job_dir=$BUCKET_NAME \
--epochs=1

7. יצירת משרה בהתאמה אישית

עכשיו, אחרי שבדקנו את המצב המקומי, נשתמש בתכונה של האריזה האוטומטית כדי להפעיל את משימת האימון בהתאמה אישית ב-Vertex AI Training. בעזרת פקודה אחת, התכונה הזו תאפשר לכם:

  • יצירת קובץ אימג' של Docker בהתאמה אישית על סמך הקוד שלכם.
  • מעבירים את קובץ האימג' ל-Container Registry.
  • צריך להתחיל CustomJob על סמך התמונה.

חוזרים למסוף ומזינים את הפקודה cd כדי לעבור רמה אחת למעלה מהספרייה autopkg-codelab.

+ autopkg-codelab
  + requirements.txt
  + trainer/
      + task.py

מציינים את קובץ האימג' המובנה מראש של TensorFlow GPU ב-Vertex AI Training בתור קובץ האימג' הבסיסי של משימת האימון בהתאמה אישית.

BASE_GPU_IMAGE=us-docker.pkg.dev/vertex-ai/training/tf-gpu.2-7:latest

לאחר מכן, מריצים את הפקודה gcloud ai custom-jobs create. קודם, הפקודה הזו תיצור קובץ אימג' מותאם אישית של Docker על סמך קוד האימון. קובץ האימג' הבסיסי הוא הקונטיינר המובנה מראש של Vertex AI Training שהגדרתם כ-BASE_GPU_IMAGE. לאחר מכן, תכונת האריזה האוטומטית תתקין את מערכי הנתונים ואת ספריות הטרנספורמטורים באמצעות pip, כפי שצוין בקובץ requirements.txt.

gcloud ai custom-jobs create \
--region=us-central1 \
--display-name=fine_tune_bert \
--args=--job_dir=$BUCKET_NAME \
--worker-pool-spec=machine-type=n1-standard-4,replica-count=1,accelerator-type=NVIDIA_TESLA_V100,executor-image-uri=$BASE_GPU_IMAGE,local-package-path=autopkg-codelab,python-module=trainer.task

בואו נבחן את הארגומנט worker-pool-spec. כאן מגדירים את תצורת מאגר העובדים שבו משתמשת המשימה בהתאמה אישית. אפשר לציין כמה מפרטי מאגרי עובדים כדי ליצור משימה בהתאמה אישית עם כמה מאגרי עובדים לאימון מבוזבז. בדוגמה הזו מצוין רק מאגר עובדים אחד, כי קוד האימון לא מוגדר לאימון מבוזבז.

אלה כמה מהשדות העיקריים במפרט הזה:

  • machine-type (חובה): סוג המכונה. כאן אפשר למצוא את הסוגים הנתמכים.
  • replica-count: מספר הרפליקות של העובדים לשימוש במאגר העובדים הזה. כברירת מחדל הערך הוא 1.
  • accelerator-type: סוג יחידות ה-GPU. כאן אפשר למצוא סוגים נתמכים. בדוגמה הזו ציינתם יחידת GPU אחת מסוג NVIDIA Tesla V100.
  • accelerator-count: מספר יחידות ה-GPU שכל מכונה וירטואלית במאגר העובדים תשתמש בהן. כברירת מחדל, הערך הוא 1.
  • executor-image-uri: ה-URI של קובץ אימג' של קונטיינר שיפעיל את החבילה שסופקה. ההגדרה הזו מוגדרת לתמונת הבסיס שלנו.
  • local-package-path: הנתיב המקומי של תיקייה שמכילה קוד אימון.
  • python-module: שם המודול של Python להרצה בחבילה שצוינה.

בדומה להרצה של הפקודה המקומית, תראו את תמונת ה-Docker בתהליך הבנייה ואז משימת האימון מתחילה. אלא שבמקום לראות את הפלט של משימת האימון, תופיע ההודעה הבאה שמאשרת שמשימת האימון שלכם התחילה. שימו לב: בפעם הראשונה שתפעילו את הפקודה custom-jobs create, יכול להיות שיעברו כמה דקות עד שהאימג' ייוצר ויישלח.

training_started

חוזרים לקטע Vertex AI Training במסוף Cloud, ובקטע CUSTOM JOBS אמורה להופיע המשימה שפועלת.

training_job

השלמת המשימה תימשך כ-20 דקות.

בסיום, הארטיפקטים הבאים של המודל השמורים אמורים להופיע בספרייה model_output בקטגוריה.

model_output

🎉 מזל טוב! 🎉

למדתם איך להשתמש ב-Vertex AI כדי:

  • הכנסת קוד אימון לקונטיינרים והרצה שלו באופן מקומי
  • שליחת משימות אימון ל-Vertex AI Training באמצעות אריזה אוטומטית

מידע נוסף על החלקים השונים של Vertex AI זמין במסמכי התיעוד.

8. הסרת המשאבים

מכיוון שהגדרתנו ל-notebook זמן תפוגה של 60 דקות חוסר פעילות, אין צורך לדאוג לגבי כיבוי המכונה. כדי לכבות את המכונה באופן ידני, לוחצים על הלחצן Stop בקטע Vertex AI Workbench במסוף. כדי למחוק את המחברות כולה, לוחצים על הלחצן 'מחיקה'.

delete

כדי למחוק את הקטגוריה של האחסון, עוברים לתפריט הניווט במסוף Cloud, לוחצים על Storage, בוחרים את הקטגוריה ולוחצים על Delete:

מחיקת האחסון