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

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

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

מה לומדים

במאמר הזה נסביר איך:

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

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

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

3. מבוא ל-Vertex AI

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

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

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

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

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

שלב 1: הפעלת Compute Engine API

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

שלב 2: הפעלת Vertex AI API

עוברים אל הקטע Vertex AI במסוף Cloud ולוחצים על הפעלת 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. המשמעות היא שמחברת ה-notebook תיסגר אוטומטית כשלא משתמשים בה, כדי שלא תצטברו עלויות מיותרות.

idle_timeout

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

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

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

open_jupyterlab

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

אימות

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

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

launcher_terminal

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

mkdir autopkg-codelab
cd autopkg-codelab

במסוף, מריצים את הפקודה הבאה כדי ליצור ספרייה לקוד האימון וקובץ 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 ותוסיף בראש שכבת סיווג עם משקלים מאותחלים באופן אקראי. במקרה הזה, יש לנו בעיית סיווג בינארית (חיובי או שלילי), ולכן אנחנו מציינים num_labels=2 עבור המסווג הזה.

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

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

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

PROJECT_ID='your-cloud-project'

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

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

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

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

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

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

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

מציינים את תמונת ה-GPU של TensorFlow שנוצרה מראש ב-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. ההגדרה הזו מגדירה את התצורה של מאגר העובדים שמשמשת את העבודה בהתאמה אישית. אתם יכולים לציין כמה מפרטים של מאגרי עובדים כדי ליצור משימה בהתאמה אישית עם כמה מאגרי עובדים לאימון מבוזר. בדוגמה הזו, אנחנו מציינים רק מאגר worker אחד, כי קוד האימון שלנו לא מוגדר לאימון מבוזר.

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

  • 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 Console, ובקטע CUSTOM JOBS אמורה להופיע המשימה שפועלת.

training_job

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

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

model_output

‫🎉 איזה כיף! 🎉

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

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

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

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

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

delete

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

מחיקת האחסון