ניתוח נתונים מהיר יותר באמצעות Google Cloud ו-NVIDIA

1. מבוא

ב-Codelab הזה תלמדו איך להאיץ את תהליכי העבודה של ניתוח נתונים במערכי נתונים גדולים באמצעות מעבדי GPU של NVIDIA וספריות קוד פתוח ב-Google Cloud. תתחילו באופטימיזציה של התשתית, ואז תלמדו איך להשתמש בהאצת GPU בלי לבצע שינויים בקוד.

התמקדות תהיה ב-pandas, ספרייה פופולרית למניפולציה של נתונים, ותלמדו איך להאיץ אותה באמצעות הספרייה cuDF של NVIDIA. היתרון הכי גדול הוא שאפשר להשתמש בהאצת ה-GPU הזו בלי לשנות את קוד pandas הקיים.

מה תלמדו

  • הסבר על Colab Enterprise ב-Google Cloud.
  • אפשר להתאים אישית סביבת זמן ריצה של Colab עם הגדרות ספציפיות של GPU,‏ CPU וזיכרון.
  • האצת pandas ללא שינויים בקוד באמצעות NVIDIA cuDF.
  • יצירת פרופיל של הקוד כדי לזהות צווארי בקבוק בביצועים ולבצע אופטימיזציה שלהם.

2. למה כדאי להאיץ את עיבוד הנתונים?

כלל 80/20: למה הכנת הנתונים צורכת כל כך הרבה זמן

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

למזלכם, אתם יכולים להאיץ ספריות פופולריות בקוד פתוח כמו pandas,‏ Apache Spark ו-Polars ב-GPUs של NVIDIA באמצעות cuDF. גם עם ההאצה הזו, הכנת הנתונים עדיין אורכת זמן רב כי:

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

3. בחירת סביבת מחברת

מדעני נתונים רבים מכירים את Colab לשימוש בפרויקטים אישיים, אבל Colab Enterprise מספק חוויית מחברת מאובטחת, משולבת ושיתופית שמיועדת לעסקים.

ב-Google Cloud יש שתי אפשרויות עיקריות לסביבות notebook מנוהלות: Colab Enterprise ו-Vertex AI Workbench. הבחירה הנכונה תלויה בסדרי העדיפויות של הפרויקט.

מתי כדאי להשתמש ב-Vertex AI Workbench

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

  • ניהול התשתית הבסיסית ומחזור החיים של המכונות.
  • שימוש במאגרי תגים מותאמים אישית ובהגדרות רשת.
  • שילוב עם צינורות MLOps וכלים מותאמים אישית לניהול מחזור החיים.

מתי כדאי להשתמש ב-Colab Enterprise

כדאי לבחור ב-Colab Enterprise אם העדיפות שלכם היא הגדרה מהירה, קלות שימוש ושיתוף פעולה מאובטח. זהו פתרון מנוהל שמאפשר לצוות שלכם להתמקד בניתוח במקום בתשתית. ‫Colab Enterprise עוזר לכם:

  • פיתוח תהליכי עבודה של מדעי הנתונים שקשורים קשר הדוק למחסן הנתונים. אתם יכולים לפתוח ולנהל את מחברות ה-Notebook שלכם ישירות ב-BigQuery Studio.
  • אימון מודלים של למידת מכונה ושילוב עם כלי MLOps ב-Vertex AI.
  • ליהנות מחוויה גמישה ומאוחדת. אפשר לפתוח ולהפעיל ב-Vertex AI מחברת Colab Enterprise שנוצרה ב-BigQuery, ולהיפך.

התכונה של היום מ-Labs

ב-Codelab הזה נעשה שימוש ב-Colab Enterprise לניתוח נתונים מואץ.

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

4. הגדרת תבנית בזמן ריצה

ב-Colab Enterprise, מתחברים לסביבת זמן ריצה שמבוססת על תבנית מוגדרת מראש של סביבת זמן ריצה.

תבנית של זמן ריצה היא הגדרה לשימוש חוזר שמציינת את כל הסביבה של מחברת, כולל:

  • סוג המכונה (מעבד, זיכרון)
  • מאיץ (סוג ה-GPU ומספר ה-GPU)
  • גודל וסוג הדיסק
  • הגדרות רשת ומדיניות אבטחה
  • כללים אוטומטיים לכיבוי במצב המתנה

למה כדאי להשתמש בתבניות בזמן ריצה

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

יצירת תבנית בזמן ריצה

מגדירים תבנית זמן ריצה לשימוש חוזר לשיעור ה-Lab.

  1. במסוף Google Cloud, עוברים אל תפריט הניווט > Vertex AI > Colab Enterprise.

מעבר אל Colab Enterprise

  1. ב-Colab Enterprise, לוחצים על Runtime templates (תבניות של זמן ריצה) ואז על New Template (תבנית חדשה).

יצירת תבנית חדשה של זמן ריצה

  1. בקטע העקרונות הבסיסיים של זמן הריצה:
  • מגדירים את השם המוצג כ-gpu-template.
  • מגדירים את האזור המועדף.

הגדרות של שם ומיקום בזמן ריצה

  1. בקטע הגדרת מחשוב:
  • מגדירים את Machine type לערך g2-standard-4.
  • משנים את ההגדרה כיבוי במצב לא פעיל ל-60 דקות.
  1. לוחצים על יצירה כדי לשמור את תבנית זמן הריצה. התבנית החדשה אמורה להופיע בדף 'תבניות בזמן ריצה'.

הגדרת סוג המכונה של תבנית זמן הריצה ויצירת התבנית

5. הפעלת סביבת זמן ריצה

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

  1. ב-Colab Enterprise, לוחצים על Runtimes ואז על Create.

פתיחת התפריט ליצירת זמן ריצה

  1. בקטע Runtime template (תבנית של סביבת זמן הריצה), בוחרים באפשרות gpu-template. לוחצים על Create ומחכים עד שהסביבה תופעל.

הפעלת סביבת זמן ריצה חדשה

  1. אחרי כמה דקות, תוכלו לראות את זמן הריצה שזמין לכם.

בודק אם סביבת זמן הריצה זמינה לשימוש

6. הגדרת המחברת

עכשיו, כשהתשתית פועלת, צריך לייבא את מחברת ה-Lab ולחבר אותה לסביבת זמן הריצה.

ייבוא המחברת

  1. ב-Colab Enterprise, לוחצים על המחברות שלי ואז על ייבוא.

פתיחה של חלונית הייבוא של Notebook

  1. בוחרים בלחצן האפשרויות כתובת URL ומזינים את כתובת ה-URL הבאה:

https://github.com/GoogleCloudPlatform/ai-ml-recipes/blob/main/notebooks/analytics/gpu_accelerated_analytics.ipynb

  1. לוחצים על ייבוא. מערכת Colab Enterprise תעתיק את ה-notebook מ-GitHub לסביבה שלכם.

העתקת ה-Notebook ממאגר ציבורי

התחברות לסביבת זמן ריצה

  1. פותחים את ה-notebook החדש שיובא.
  2. לוחצים על החץ למטה לצד קישור.
  3. בוחרים באפשרות התחברות לסביבת זמן ריצה.

פתיחה של חלונית הייבוא של Notebook

  1. משתמשים בתפריט הנפתח ובוחרים את זמן הריצה שיצרתם קודם.
  2. לוחצים על חיבור.

פתיחה של חלונית הייבוא של Notebook

ה-notebook שלכם מחובר עכשיו לסביבת זמן ריצה עם GPU. עכשיו אפשר להתחיל להריץ שאילתות.

7. הכנת מערך הנתונים של מוניות בניו יורק

ב-Codelab הזה נעשה שימוש בנתוני רשומות נסיעה של NYC Taxi & Limousine Commission (TLC).

מערך הנתונים מכיל רשומות של נסיעות במוניות צהובות בניו יורק, וכולל שדות כמו:

  • תאריכים, שעות ומיקומים של איסוף והורדה
  • מרחקי הנסיעה
  • סכומי התעריפים המפורטים
  • מספר הנוסעים

הורדת הנתונים

לאחר מכן, מורידים את נתוני הנסיעות לכל שנת 2024. הנתונים מאוחסנים בפורמט הקובץ Parquet.

בלוק הקוד הבא מבצע את השלבים האלה:

  1. ההגדרה קובעת את טווח השנים והחודשים להורדה.
  2. יוצר ספרייה מקומית בשם nyc_taxi_data לאחסון הקבצים.
  3. הסקריפט עובר על כל חודש, מוריד את קובץ ה-Parquet המתאים אם הוא עדיין לא קיים ושומר אותו בספרייה.

מריצים את הקוד הזה ב-notebook כדי לאסוף את הנתונים ולאחסן אותם בסביבת זמן הריצה:

from tqdm import tqdm
import requests
import time
import os

YEAR = 2024
DATA_DIR = "nyc_taxi_data"

os.makedirs(DATA_DIR, exist_ok=True)
print(f"Checking/Downloading files for {YEAR}...")


for month in tqdm(range(1, 13), unit="file"):
    
    # Define standardized filename for both local path and URL
    file_name = f"yellow_tripdata_{YEAR}-{month:02d}.parquet"
    local_path = os.path.join(DATA_DIR, file_name)
    url = f"https://d37ci6vzurychx.cloudfront.net/trip-data/{file_name}"

    if not os.path.exists(local_path):
        try:
            with requests.get(url, stream=True) as response:
                response.raise_for_status()
                with open(local_path, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=8192):
                        f.write(chunk)
            time.sleep(1)
        except requests.exceptions.HTTPError as e:

            print(f"\nSkipping {file_name}: {e}")

            if os.path.exists(local_path):
                os.remove(local_path)

print("\nDownload complete.")

8. עיון בנתוני הנסיעות במוניות

אחרי שהורדתם את מערך הנתונים, הגיע הזמן לבצע ניתוח ראשוני של הנתונים (EDA). המטרה של EDA היא להבין את מבנה הנתונים, למצוא חריגות ולגלות דפוסים פוטנציאליים.

טעינה של נתונים מחודש אחד

מתחילים בטעינת נתונים של חודש אחד. כך מתקבל מדגם גדול מספיק (מעל 3 מיליון שורות) כדי להיות משמעותי, ועדיין השימוש בזיכרון נשאר ברמה שמאפשרת ניתוח אינטראקטיבי.

import pandas as pd
import glob

# Load the last month of the downloaded data
df = pd.read_parquet("nyc_taxi_data/yellow_tripdata_2024-12.parquet")
df.head()

קבלת נתונים סטטיסטיים מסכמים

משתמשים בשיטה .describe() כדי ליצור נתונים סטטיסטיים של סיכום ברמה גבוהה עבור העמודות המספריות. זהו שלב ראשון מצוין לזיהוי בעיות פוטנציאליות באיכות הנתונים, כמו ערכי מינימום או מקסימום לא צפויים.

df.describe().round(2)

הצגת נתונים סטטיסטיים מסכמים

בדיקת איכות הנתונים

הפלט מ-.describe() חושף בעיה באופן מיידי. שימו לב שהערך min של tpep_pickup_datetime ושל tpep_dropoff_datetime הוא משנת 2008, וזה לא הגיוני למערך נתונים משנת 2024.

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

# Sort by the dropoff datetime to see the oldest records
df.sort_values("tpep_pickup_datetime").head()

המחשה חזותית של התפלגויות נתונים

לאחר מכן, אפשר ליצור היסטוגרמות של העמודות המספריות כדי להציג את ההתפלגויות שלהן באופן ויזואלי. כך תוכלו להבין את הפיזור וההטיה של תכונות כמו trip_distance ו-fare_amount. הפונקציה .hist() היא דרך מהירה לשרטוט היסטוגרמות לכל העמודות המספריות ב-DataFrame.

_ = df.hist(figsize=(20, 20))

לבסוף, יוצרים מטריצת פיזור כדי להמחיש את הקשרים בין כמה עמודות מרכזיות. שרטוט של מיליוני נקודות הוא תהליך איטי, ועלול להסתיר דפוסים. לכן, כדאי להשתמש ב-.sample() כדי ליצור את התרשים מדגימה אקראית של 100,000 שורות.

_ = pd.plotting.scatter_matrix(
    df[['passenger_count', 'trip_distance', 'tip_amount', 'total_amount']].sample(100_000),
    diagonal="kde",
    figsize=(15, 15)
)

9. למה כדאי להשתמש בפורמט הקובץ Parquet?

מערך הנתונים של מוניות בניו יורק מסופק בפורמט Apache Parquet. זו בחירה מכוונת שנעשתה לצורך ניתוח נתונים בקנה מידה גדול. ל-Parquet יש כמה יתרונות בהשוואה לסוגי קבצים כמו CSV:

  • יעיל ומהיר: כפורמט עמודתי, Parquet יעיל מאוד לאחסון ולקריאה. הוא תומך בשיטות דחיסה מודרניות שמניבות קבצים קטנים יותר וקלט/פלט מהיר יותר באופן משמעותי, במיוחד ב-GPU.
  • שומר על הסכימה: Parquet מאחסן את סוגי הנתונים במטא-נתונים של הקובץ. אתם לא צריכים לנחש את סוגי הנתונים כשאתם קוראים את הקובץ.
  • מאפשר קריאה סלקטיבית: המבנה העמודתי מאפשר לכם לקרוא רק את העמודות הספציפיות שאתם צריכים לניתוח. כך אפשר לצמצם באופן משמעותי את כמות הנתונים שצריך לטעון לזיכרון.

פרטים על התכונות של Parquet

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

בדיקת מטא-נתונים בלי לטעון את מערך הנתונים המלא

אי אפשר לראות קובץ Parquet בעורך טקסט רגיל, אבל אפשר לבדוק בקלות את הסכימה והמטא-נתונים שלו בלי לטעון נתונים לזיכרון. האפשרות הזו שימושית להבנת המבנה של קובץ במהירות.

from pyarrow.parquet import ParquetFile
import pyarrow as pa

# Open one of the downloaded files
pf = ParquetFile('nyc_taxi_data/yellow_tripdata_2024-12.parquet')

# Print the schema
print("File Schema:")
print(pf.schema)

# Print the file metadata
print("\nFile Metadata:")
print(pf.metadata)

קריאה רק של העמודות שצריך

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

import pandas as pd

# Read only four specific columns from the Parquet file
df_subset = pd.read_parquet(
    'nyc_taxi_data/yellow_tripdata_2024-12.parquet',
    columns=['passenger_count', 'trip_distance', 'tip_amount', 'total_amount']
)

df_subset.head()

10. האצת pandas באמצעות NVIDIA cuDF

NVIDIA CUDA for DataFrames (cuDF) היא ספרייה בקוד פתוח עם האצת GPU שמאפשרת לכם לקיים אינטראקציה עם DataFrames. בעזרת cuDF תוכלו לבצע פעולות נפוצות על נתונים כמו סינון, צירוף וקיבוץ ב-GPU עם מקביליות מסיבית.

התכונה העיקרית שבה משתמשים ב-Codelab הזה היא מצב ההאצה cudf.pandas. כשמפעילים את האפשרות הזו, קוד pandas הרגיל מופנה אוטומטית לשימוש בגרעיני cuDF שמבוססים על GPU, בלי שצריך לשנות את הקוד.

הפעלת האצת GPU

כדי להשתמש ב-NVIDIA cuDF במחברת Colab Enterprise, צריך לטעון את תוסף הקסם שלו לפני שמייבאים את pandas.

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

import pandas as pd
pd # Note the output for the standard pandas library

עכשיו, טוענים את התוסף cudf.pandas ומייבאים שוב את pandas. צופים בשינוי של הפלט של מודול pd – כך מוודאים שהגרסה עם האצת GPU פעילה עכשיו.

%load_ext cudf.pandas
import pandas as pd
pd # Note the new output, indicating cudf.pandas is active

דרכים אחרות להפעלה של cudf.pandas

הפקודה הקסומה (%load_ext) היא השיטה הכי פשוטה ב-notebook, אבל אפשר להפעיל את המאיץ גם בסביבות אחרות:

  • בתסריטי Python: קוראים ל-import cudf.pandas ול-cudf.pandas.install() לפני הייבוא של pandas.
  • מסביבות שאינן מחברות: מריצים את הסקריפט באמצעות python -m cudf.pandas your_script.py.

11. השוואה בין ביצועי המעבד (CPU) לבין ביצועי המעבד הגרפי (GPU)

עכשיו לחלק הכי חשוב: השוואת הביצועים של pandas רגיל במעבד עם cudf.pandas במעבד גרפי.

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

import IPython

IPython.Application.instance().kernel.do_shutdown(True)

הגדרת צינור עיבוד הנתונים לניתוח

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

import time
import glob
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def run_analytics_pipeline(pd_module):
    """Loads, sorts, and summarizes data using the provided pandas module."""
    timings = {}

    # 1. Load all 2024 Parquet files from the directory
    t0 = time.time()
    df = pd_module.concat(
        [pd_module.read_parquet(f) for f in glob.glob("nyc_taxi_data/*_2024*.parquet")],
        ignore_index=True
    )
    timings["load"] = time.time() - t0

    # 2. Sort the data by multiple columns
    t0 = time.time()
    df = df.sort_values(
        ['tpep_pickup_datetime', 'trip_distance', 'passenger_count'],
        ascending=[False, True, False]
    )
    timings["sort"] = time.time() - t0

    # 3. Perform a groupby and aggregation
    t0 = time.time()
    df['tpep_pickup_datetime'] = pd_module.to_datetime(df['tpep_pickup_datetime'])
    _ = (
        df.loc[df.tpep_pickup_datetime > '2024-11-01']
          .groupby(['VendorID', 'tpep_pickup_datetime'])
          [['passenger_count', 'fare_amount']]
          .agg(['min', 'mean', 'max'])
    )
    timings["summarize"] = time.time() - t0

    return timings

הפעלת ההשוואה

קודם מריצים את צינור העיבוד באמצעות pandas רגיל במעבד. לאחר מכן מפעילים את cudf.pandas ומריצים אותו שוב ב-GPU.

# --- Run on CPU ---
print("Running analytics pipeline on CPU...")
# Ensure we are using standard pandas
import pandas as pd
assert "cudf" not in str(pd), "Error: cuDF is still active. Please restart the kernel."

cpu_times = run_analytics_pipeline(pd)
print(f"CPU times: {cpu_times}")

# --- Run on GPU ---
print("\nEnabling cudf.pandas and running on GPU...")
# Load the extension
%load_ext cudf.pandas
import pandas as gpu_pd

gpu_times = run_analytics_pipeline(gpu_pd)
print(f"GPU times: {gpu_times}")

הצגה חזותית של התוצאות

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

# Create a DataFrame for plotting
results_df = pd.DataFrame([cpu_times, gpu_times], index=["CPU", "GPU"]).T
total_cpu_time = results_df['CPU'].sum()
total_gpu_time = results_df['GPU'].sum()
speedup = total_cpu_time / total_gpu_time

print("--- Performance Results ---")
print(results_df)
print(f"\nTotal CPU Time: {total_cpu_time:.2f} seconds")
print(f"Total GPU Time: {total_gpu_time:.2f} seconds")
print(f"Overall Speedup: {speedup:.2f}x")

# Plot the results
fig, ax = plt.subplots(figsize=(10, 6))
results_df.plot(kind='bar', ax=ax, color={"CPU": "tab:blue", "GPU": "tab:green"})

ax.set_ylabel("Time (seconds)")
ax.set_title(f"CPU vs. GPU Runtimes (Overall Speedup: {speedup:.2f}x)", fontsize=14)
ax.tick_params(axis='x', rotation=0)

# Add numerical labels to the bars
for container in ax.containers:
    ax.bar_label(container, fmt="%.2f", padding=3)

plt.tight_layout()
plt.show()

תוצאות לדוגמה:

הצגת הביצועים של המעבד לעומת המעבד הגרפי

ה-GPU מספק עלייה ברורה במהירות ביחס למעבד.

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

גם עם האצת GPU, יכול להיות שחלק מהפעולות של pandas יחזרו ל-CPU אם הן עדיין לא נתמכות על ידי cuDF. המעברים האלה ל-CPU עלולים להפוך לצווארי בקבוק בביצועים.

כדי לעזור לכם לזהות את התחומים האלה, cudf.pandas כולל שני פרופילים מובנים. אפשר להשתמש בהם כדי לראות בדיוק אילו חלקים בקוד פועלים ב-GPU ואילו חוזרים ל-CPU.

  • %%cudf.pandas.profile: משתמשים באפשרות הזו כדי לקבל סיכום כללי של הקוד, פונקציה אחר פונקציה. היא מתאימה במיוחד לקבלת סקירה מהירה של הפעולות שפועלות בכל מכשיר.
  • %%cudf.pandas.line_profile: משתמשים באפשרות הזו לניתוח מפורט של כל שורה. זה הכלי הכי טוב לזיהוי מדויק של השורות בקוד שגורמות לחזרה ל-CPU.

אפשר להשתמש בפרופילים האלה כ-cell magics בחלק העליון של תא ב-notebook.

פרופיל ברמת הפונקציה באמצעות %%cudf.pandas.profile

קודם מריצים את פרופילר הפונקציות באותו צינור ניתוח מהקטע הקודם. הפלט מציג טבלה של כל פונקציה שנקראה, המכשיר שהיא פעלה בו (GPU או CPU) וכמה פעמים היא נקראה.

%load_ext cudf.pandas
import pandas as pd
import glob

pd.DataFrame({"a": [1]})

אחרי שמוודאים ש-cudf.pandas פעיל, אפשר להריץ פרופיל.

%%cudf.pandas.profile

df = pd.concat([pd.read_parquet(f) for f in glob.glob("nyc_taxi_data/*2024*.parquet")], ignore_index=True)

df = df.sort_values(['tpep_pickup_datetime', 'trip_distance', 'passenger_count'], ascending=[False, True, False])

summary = (
    df
        .loc[(df.tpep_pickup_datetime > '2024-11-01')]
        .groupby(['VendorID','tpep_pickup_datetime'])
        [['passenger_count', 'fare_amount']]
        .agg(['min', 'mean', 'max'])
)

הצגת פרטי פרופיל של pandas

יצירת פרופיל שורה אחר שורה באמצעות %%cudf.pandas.line_profile

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

%%cudf.pandas.line_profile

df = pd.concat([pd.read_parquet(f) for f in glob.glob("nyc_taxi_data/*2024*.parquet")], ignore_index=True)

df = df.sort_values(['tpep_pickup_datetime', 'trip_distance', 'passenger_count'], ascending=[False, True, False])

summary = (
    df
        .loc[(df.tpep_pickup_datetime > '2024-11-01')]
        .groupby(['VendorID','tpep_pickup_datetime'])
        [['passenger_count', 'fare_amount']]
        .agg(['min', 'mean', 'max'])
)

הצגת מידע על פרופיל פנדות (לפי שורה)

יצירת פרופיל משורת הפקודה

הפרופילים האלה זמינים גם משורת הפקודה, וזה שימושי לבדיקות אוטומטיות ולפרופילים של סקריפטים של Python.

אפשר להשתמש בפקודות הבאות בממשק שורת הפקודה:

  • python -m cudf.pandas --profile your_script.py
  • python -m cudf.pandas --line_profile your_script.py

13. שילוב עם Google Cloud Storage

Google Cloud Storage‏ (GCS) הוא שירות אחסון אובייקטים עמיד וניתן להרחבה. כשמשתמשים ב-Colab Enterprise,‏ GCS הוא מקום מצוין לאחסון של מערכי נתונים, נקודות ביקורת של מודלים ופריטים אחרים.

לזמן הריצה של Colab Enterprise יש את ההרשאות הנדרשות לקריאה ולכתיבה של נתונים ישירות בקטגוריות של GCS, והפעולות האלה מואצות על ידי GPU כדי להשיג ביצועים מקסימליים.

יצירת קטגוריה ב-GCS

קודם יוצרים קטגוריית GCS חדשה. שמות של קטגוריות GCS הם ייחודיים באופן גלובלי, לכן צריך לצרף UUID לשם.

from google.cloud import storage
import uuid

unique_suffix = uuid.uuid4().hex[:12]
bucket_name = f'nyc-taxi-codelab-{unique_suffix}'
project_id = storage.Client().project

client = storage.Client()

try:
    bucket = client.create_bucket(bucket_name)
    print(f"Successfully created bucket: gs://{bucket.name}")
except Exception as e:
    print(f"Bucket creation failed. You may already own it or the name is taken: {e}")

כתיבת נתונים ישירות ל-GCS

עכשיו שומרים את DataFrame ישירות בקטגוריה החדשה של GCS. אם המשתנה df לא זמין מהקטעים הקודמים, הקוד טוען קודם נתונים של חודש אחד.

%%cudf.pandas.line_profile

# Ensure the DataFrame exists before saving to GCS
if 'df' not in locals():
    print("DataFrame not found, loading a sample file...")
    df = pd.read_parquet('nyc_taxi_data/yellow_tripdata_2024-12.parquet')

print(f"Writing data to gs://{bucket_name}/nyc_taxi_data.parquet...")
df.to_parquet(f"gs://{bucket_name}/nyc_taxi_data.parquet", index=False)
print("Write operation complete.")

אימות הקובץ ב-GCS

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

from IPython.display import Markdown

gcs_url = f"https://console.cloud.google.com/storage/browser/{bucket_name}?project={project_id}"
Markdown(f'**[Click here to view your GCS bucket in the Google Cloud Console]({gcs_url})**')

קריאת נתונים ישירות מ-GCS

לבסוף, קוראים נתונים ישירות מנתיב GCS לתוך DataFrame. הפעולה הזו מואצת באמצעות GPU, ולכן אפשר לטעון מערכי נתונים גדולים מאחסון בענן במהירות גבוהה.

%%cudf.pandas.line_profile

print(f"Reading data from gs://{bucket_name}/nyc_taxi_data.parquet...")
df_from_gcs = pd.read_parquet(f"gs://{bucket_name}/nyc_taxi_data.parquet")

df_from_gcs.head()

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

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

מחיקת הנתונים שהורדתם:

# Permanately delete the GCS bucket
print(f"Deleting GCS bucket: gs://{bucket_name}...")
!gsutil rm -r -f gs://{bucket_name}
print("Bucket deleted.")

# Remove NYC taxi dataset on the Colab runtime
print("Deleting local 'nyc_taxi_data' directory...")
!rm -rf nyc_taxi_data
print("Local files deleted.")

כיבוי של סביבת זמן הריצה ב-Colab

  • במסוף Google Cloud, עוברים לדף Runtimes של Colab Enterprise.
  • בתפריט Region (אזור), בוחרים את האזור שבו נמצא זמן הריצה.
  • בוחרים את זמן הריצה שרוצים למחוק.
  • לוחצים על מחיקה.
  • לוחצים על אישור.

מחיקת ה-Notebook

  • במסוף Google Cloud, נכנסים לדף My Notebooks של Colab Enterprise.
  • בתפריט Region (אזור), בוחרים את האזור שבו נמצא ה-Notebook.
  • בוחרים את המחברת שרוצים למחוק.
  • לוחצים על מחיקה.
  • לוחצים על אישור.

15. מזל טוב

מעולה! הצלחתם להאיץ תהליך עבודה של ניתוח נתונים ב-pandas באמצעות NVIDIA cuDF ב-Colab Enterprise. למדתם איך להגדיר סביבות זמן ריצה עם GPU, להפעיל את cudf.pandas להאצה ללא שינוי קוד, ליצור פרופיל קוד לזיהוי צווארי בקבוק ולבצע שילוב עם Google Cloud Storage.

מסמכים לדוגמה