עזרה להגן על שונית המחסום הגדולה עם TensorFlow על Kaggle הצטרפו אתגר

מיטוב ביצועי TensorFlow GPU עם פרופיל TensorFlow

סקירה כללית

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

קראו את מדריך Profiler כדי ללמוד עוד על איך להתחיל עם שימוש Profiler. כמו כן, לקרוא את מדריך Profiler כדי ללמוד עוד על כלי הפרופיל השונים ושיטות השונות העומדות בפני ביצועי אופטימיזציה TensorFlow על המארח (CPU).

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

זרימת עבודה למיטוב ביצועים

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

  1. בצע אופטימיזציה וניקוי באגים בביצועי GPU אחד
    1. בדוק אם צינור הקלט הוא צוואר בקבוק
    2. ניפוי ביצועים של GPU אחד
    3. אפשר fp16 והפעל XLA באופן אופציונלי
  2. בצע אופטימיזציה וניקוי באגים בביצועים של מארח יחיד עם מספר GPU

כבסיס להשגת קוד performant על GPU, מדריך זה מניח שאתה כבר משתמש tf.function . Keras ההידור / API בכושר יהיה לנצל tf.function אוטומטית ובמנוע. בעת כתיבת לולאת אימונים מותאמים אישית, עיין במדריך זה כיצד להפעיל tf.function .

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

מיטב ביצועים ב- GPU אחד

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

עמוד סקירה של Profiler TensorFlow מספק מושג כמה רחוק התוכנית שלך היא מן התרחיש האידיאלי.

TensorFlow Profiler Overview Page

מספרי המפתח שיש לחפש בדף הסקירה הם:

  1. כמה זמן הצעד הוא מביצוע המכשיר בפועל
  2. אחוז האופציות שמוצב במכשיר לעומת מארח
  3. כמה גרעינים משתמשים ב- fp16

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

להלן תמונה של תצוגת עקבות דגם הפועלת על GPU אחד. מתחולת Tensorflow שם וחתכים Ops Tensorflow, אתה יכול לזהות חלקים שונים של המודל, כמו לעבור קדימה, פונקצית ההפסד, לעבור אחורה / חישוב שיפוע, ואת עדכון משקל האופטימיזציה. אתה גם יכול לראות ops פועל על GPU אחד ליד הנחל, אשר מתייחס CUDA והנחלים. כל זרם משמש למשימות ספציפיות. בשנת עקבות זה, זרם # 118 משמש להשיק גרעינים מחשוב המכשיר עותקים במכשיר. להזרים # 119 משמשים מארח עותק מכשיר Stream # 120 עבור מכשיר עותק מארח.

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

image

לדוגמה, ציר הזמן מחשוב GPU (Stream # 118) נראה עסוק עם פערים מעט מאוד. ישנם עותקים מינימאליים ממנחה המכשיר (Stream # 119) ו מהמכשיר מארח (Stream # 120), כמו גם פערים מינימאליים בין שלבים. כאשר אתה מריץ את פרופיל TensorFlow עבור התוכנית שלך, ייתכן שלא תראה מאפיינים אידיאליים אלה בתצוגת העקבות שלך. שאר המדריך הזה מכסה תרחישים נפוצים וכיצד לתקן אותם.

איתור באגים בצינור קלט

השלב הראשון בדיבוג ביצועי GPU הוא לקבוע אם התוכנית שלך קשורה לקלט. הדרך הקלה ביותר להבין זאת היא להשתמש של TensorFlow Profiler Analyzer קלט-צינור , אשר נותן סקירה של הזמן המושקע בצנרת קלט.

image

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

  • עיין tf.data הספציפי המדריך ללמוד איך באגים צינור ההזנה שלך.
  • דרך מהירה נוספת לבדוק אם צינור הקלט הוא צוואר הבקבוק היא להשתמש בנתוני קלט שנוצרו באופן אקראי ואינם זקוקים לעיבוד מקדים. הנה דוגמא של שימוש בטכניקה זו עבור מודל ResNet. אם צינור הקלט אופטימלי אתה אמור לראות ביצועים דומים עם נתונים אמיתיים ועם נתונים אקראיים / סינתטיים שנוצרו. התקורה היחידה במקרה של נתונים סינתטיים תיגרם מהעתקת נתוני קלט ששוב ניתן לשלוף מראש ולבצע אופטימיזציה.

ראה גם הנחיה כאן .

ניפוי באגים של GPU אחד

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

ניתוח פערים בין שלבים

תצפית נפוצה כאשר התוכנית שלך אינה פועלת בצורה מיטבית היא פערים בין שלבי האימון. בתמונה למטה, יש פער גדול בין השלבים 8 ל- 9, מה שאומר שה- GPU אינו פעיל בזמן הזה.

image

אם מציג העקבות שלך מציג פערים גדולים בין השלבים, זה יכול להיות אינדיקציה לכך שהתוכנית שלך קשורה לקלט. במקרה כזה עליכם להתייחס לסעיף הקודם בנושא איתור באגים בצינור הקלט שלכם אם עדיין לא עשיתם זאת. עם זאת, גם עם צינור קלט ממוטב, אתה עדיין יכול לראות פערים בין סוף שלב אחד לתחילת שלב אחר עקב מחלוקת חוט המעבד. tf.data עושה שימוש אשכולות רקע לְמַקְבֵּל עיבוד צינור. שרשורים אלה עשויים להפריע לפעילות בצד המארח של GPU המתרחשת בתחילת כל שלב, כגון העתקת נתונים או תזמון פעולות GPU.

אם אתם רואים פערים גדולים בצד המארח, אשר לוחות זמנים ops אלה על ה- GPU, אתה יכול להגדיר את משתנה הסביבה TF_GPU_THREAD_MODE=gpu_private . מבטיחה זה כי גרעיני GPU משוגרים אשכולות הייעודיים משלהם, ואיננו מקבלים בתור מאחורי tf.data עבודה.

פערים בין השלבים יכול להיגרם גם על ידי חישובים מטרי, הגיעו ליעדן Keras, או ops מחוץ tf.function שמופעלים על המארח. לאופציות אלו אין ביצועים טובים כמו לאופציות בתוך גרף TensorFlow. בנוסף, חלק מהפעולות הללו פועלות על המעבד ומעתיקות טנזורים קדימה ואחורה מה- GPU.

אם לאחר אופטימיזציה של צינור הקלט שלך אתה עדיין מבחין בפערים בין השלבים במציג העקבות, עליך להסתכל על קוד הדגם בין השלבים, ולראות אם השבתת קריאות חוזרות / מדדים משפרת את הביצועים. פרטים מסוימים של אופים אלה נמצאים גם במציג העקיבה (הן בצד המכשיר והן בצד המארח). ההמלצה בתרחיש זה היא להפחית את תקורת האופציות הללו על ידי ביצוען לאחר מספר קבוע של צעדים במקום כל שלב. בעת שימוש compile השיטה של tf.keras API, הגדרת experimental_steps_per_execution הדגל עושה זאת באופן אוטומטי. לולאות אימונים מותאמים אישית, השימוש tf.while_loop .

השג ניצול מכשירים גבוה יותר

גרעיני GPU קטנים ועיכובים בהשקת ליבה מארחת

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

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

image

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

image

על ידי השקת הרבה אופים קטנים ב- GPU (כמו להוסיף סקלרי למשל), ייתכן שהמארח לא יתעדכן עם ה- GPU. סטטיסטיקות Tensorflow דף מאותן הופעות TensorFlow בפרופיל 126,224 פעולות מול לקיחת 2.77 שניות. לפיכך, כל גרעין הוא כ- 21.9 מיקרו-שניות, שהוא קטן מאוד (בערך באותו זמן כמו חביון השקה) ועלול לגרום לעיכובים בהשקת גרעין מארח.

image

אם מציג המעקב שלך מציג פערים קטנים רבים בין אופס ב- GPU כמו התמונה לעיל, אתה יכול:

  • שרשור טנזרים קטנים והשתמש באופציות וקטוריות או השתמש בגודל אצווה גדול יותר כדי לגרום לכל גרעין שהושק לעשות יותר עבודה, מה שיעסיק את ה- GPU זמן רב יותר.
  • ודא שאתה משתמש tf.function ליצור גרפים TF ולא פועל Ops במצב להוט טהור. שימוש tf.keras.Model.compile עושה זאת באופן אוטומטי.
  • נתיך גרעינים באמצעות XLA. לפרטים נוספים, ראה סעיף בהמשך כיצד להפעיל XLA כדי לקבל ביצועים גבוהים יותר. זו תכונה ניסיונית, אך מובילה לשימוש גבוה במכשירים.
מיקום אופנסור זורם

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

image

באופן אידיאלי, רוב האופציות האינטנסיביות לחישוב צריכות להיות מונחות על ה- GPU. כדי לגלות אילו מכשירים פעולות ו tensors במודל שלך מוקצים, סט tf.debugging.set_log_device_placement(True) כמו ההצהרה הראשונה של התוכנית שלך. יצוין, כי במקרים מסוימים, גם אם תציין אופ להציב במכשיר מסוים, יישומו עשוי לעקוף מצב זה (למשל: tf.unique ). אפילו לאימוני GPU בודדים, ציון אסטרטגיית הפצה, כגון tf.distribute.OneDeviceStrategy , יכול לגרום שמה דטרמיניסטית יותר של חיילים מיחידים במכשיר.

אחת הסיבות לכך שמרבית האופציות ממוקמות ב- GPU היא למנוע עותקי זיכרון מוגזמים בין מארח למכשיר (צפויות עותקי זיכרון עבור נתוני קלט / פלט מודל בין מארח למכשיר). דוגמה להעתקה מוגזמת ניתן לראות בתצוגת עקבות מתחת על GPU ונחלים # 167, # 168, ו # 169.

image

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

גרעינים יעילים יותר ב- GPUs

ברגע שהשימוש ב- GPU של התוכנית שלך מקובל, השלב הבא הוא לבדוק את הגברת היעילות של גרעיני ה- GPU על ידי שימוש ב Toresor Cores או פיוזינג אופ.

ניצול ליבות טנסור

ל- GPUs מודרניים ליבות טנסור מיוחדות שיכולות לשפר משמעותית את ביצועי הגרעינים הזכאים. דף נתון הסטטיסטיים הקרנל GPU מציין איזה גרעיני GPU זכאים Core המותח, ואשר גרעיני משתמש Core המותח. הפעלת fp16 (ראה הפעלת סעיף Precision מעורבת בהמשך) היא אחת דרכים לעשות כפל מטריקס הכללי של התכנית שלך (GEMM) גרעינים (ops matmul) לנצל את הליבה המותחת. גרעיני GPU להשתמש הליבות המותחות ביעילות כאשר הדיוק הוא fp16 קלט / פלט ממדים מותחים המתחלקים 8 או 16 (עבור int8 ).

לקבלת המלצות מפורטות בנוגע לעשות גרעינים יעילים עבור GPUs, עיינו ביצועי למידת NVIDIA העמוקה המדריך.

נתיכים

השתמש tf.xla.experimental_compile למזג ops הקטן כדי ליצור גרעינים גדולים שמובילים שיפור בביצועים משמעותי.

אפשר דיוק מעורב ו- XLA

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

אפשר דיוק מעורב

TensorFlow Precision המעורבת מופעי המדריך כיצד להפעיל fp16 דיוק על GPUs. אפשר AMP על NVIDIA® GPUs להשתמש ליבות מותחות מבין עד פי 3 speedups הכוללת בהשוואה באמצעות רק fp32 דיוק על וולטה וארכיטקטורות GPU חדשות.

ודא שממדי המטריצה ​​/ טנסור עונים על הדרישות להתקשרות לליבות המשתמשות ב ליבות טנסור. גרעיני GPU משתמשים בפקדות Tensor ביעילות כאשר הדיוק הוא fp16 ומידות קלט / פלט מתחלקים ב 8 או 16 (ל- int8). שים לב שעם cuDNN v7.6.3 ואילך, ממדי הפיתול יהיו מרופדים באופן אוטומטי במידת הצורך למינוף ליבות טנסור.

בצע את שיטות העבודה המומלצות שלהלן כדי למקסם את יתרונות הביצועים של fp16 דיוק.

השתמש בגרעיני fp16 אופטימליים

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

image

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

קנה מידה דינמי לעומת אובדן סטטי

קנה המידה הפסד הכרחי בעת שימוש fp16 למנוע underflow בשל דיוק נמוך. ישנם שני סוגים של אובדן קנה מידה, דינמי וסטטית, אשר שניהם מוסברים בפירוט רב יותר מדריך Precision המעורב . אתה יכול להשתמש mixed_float16 מדיניות כדי לאפשר שינוי גודל הפסד אוטומטי בתוך האופטימיזציה Keras.

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

אפשר XLA

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

אתה יכול להגדיר את רמת JIT העולמית -1 (off), 1 , או 2 . רמה גבוהה יותר היא אגרסיבית יותר ועשויה להפחית את ההקבלה ולהשתמש בזיכרון רב יותר. כדי להגדיר את הערך 1 אם יש לך מגבלות זיכרון. שים לב ש- XLA לא מתפקד היטב עבור מודלים עם צורות טנסור קלט משתנות, שכן מהדר ה- XLA יצטרך לשמור על הידור גרעינים בכל פעם שהוא נתקל בצורות חדשות.

אופטימיזציה של ביצועים במארח יחיד מרובה GPU

tf.distribute.MirroredStrategy API יכול לשמש לאימון דגם מוקטן מ 1 GPU כדי GPUs המרובה על שורה אחת. כדי ללמוד עוד על איך לעשות אימונים מופצים עם Tensorflow, עיין הכשרה מבוזרת עם Keras מדריך. למרות שהמעבר מ- GPU אחד למספר GPUs אמור להיות מדרגי מחוץ לארגון, לפעמים אתה יכול להיתקל בבעיות ביצועים.

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

image

רשימת הבדיקה הבאה תסייע לך להשיג ביצועים טובים יותר בעת ביצוע אופטימיזציה לביצועים בתרחיש מרובה GPU:

  1. נסה למקסם את גודל האצווה, מה שיוביל לשימוש גבוה יותר במכשירים ולהפחית את עלויות התקשורת בין מספר GPUs. באמצעות מאבחן זיכרון עוזר לקבל תחושה של כמה קרוב התוכנית שלך היא ניצול זיכרון השיא. שים לב שלמרות שגודל אצווה גבוה יותר יכול להשפיע על ההתכנסות, בדרך כלל זה עולה על יתרונות הביצועים.
  2. כשעוברים מ- GPU יחיד למספר GPUs, אותו מארח צריך כעת לעבד הרבה יותר נתוני קלט. אז אחרי (1) מומלץ לבדוק מחדש את ביצועי צינור הקלט ולוודא שזה לא צוואר בקבוק.
  3. בדוק את ציר הזמן של GPU בתצוגת המעקב של התוכנית שלך כדי לראות אם קיימות שיחות AllReduce מיותרות, מכיוון שהדבר גורם לסינכרון בין כל המכשירים. בתצוגת המעקב המוצגת לעיל, ה- AllReduce מתבצע דרך ליבת NCCL, ויש רק קריאת NCCL אחת בכל GPU עבור השיפועים בכל שלב.
  4. בדוק אם קיימות פעולות העתקה מיותרות D2H, H2D ו- D2D ובדוק אם ניתן למזער אותן.
  5. בדוק את זמן הצעד כדי לוודא שכל העתק מבצע את אותה העבודה. זה יכול לקרות ש- GPU אחד (בדרך כלל GPU0) מנויים יתר על המידה מכיוון שהמארח בסופו של דבר מביא עליו יותר עבודה.
  6. לבסוף, בדוק את שלב האימון בכל גרפי ה- GPU בתצוגת העקיבה שלך עבור כל אופציות שמבוצעות ברצף. בדרך כלל זה קורה כאשר התוכנית שלך כוללת תלות בקרה מ- GPU אחד למשנהו. ביצועי ניפוי באגים במצב זה נפתרו בעבר על ידי כל מקרה לגופו. אם אתה מבחין בהתנהגות זו בתכנית שלך, דווח על בעיה עם Github עם תמונות של נוף העקבות שלך.

בצע אופטימיזציה של Gradient AllReduce

כאשר מתאמנים באסטרטגיה סינכרונית, כל מכשיר מקבל חלק מנתוני הקלט. לאחר חישוב העובר קדימה ואחורה במודל, יש לצבור ולהפחית את הדרגתיות המחושבות על כל מכשיר. שיפוע AllReduce זה מתרחש לאחר חישוב השיפוע בכל מכשיר, ולפני שהאופטימיזציה מעדכן את משקולות הדגם. כל GPU ראשון שמשרשרת ההדרגתית לאורך שכבות המודל, מתקשר אלי ברחבי GPUs באמצעות tf.distribute.CrossDeviceOps ( tf.distribute.NcclAllReduce היא ברירת המחדל), ולאחר מכן מחזיר את הדרגתיים לאחר הפחתה לכל שכבה. מיטוב האופטימיזציה ישתמש בהדרגות מופחתות אלה כדי לעדכן את משקולות הדגם שלך. באופן אידיאלי, תהליך זה אמור לקרות באותו זמן בכל GPUs כדי למנוע תקורה. הזמן ל- AllReduce צריך להיות זהה לזה של:

(number of parameters * 4bytes)/ (communication bandwidth)

חישוב זה שימושי כבדיקה מהירה כדי להבין אם הביצועים שאתה רואה בעת הפעלת עבודת אימונים מבוזרת הם כצפוי, או אם עליך לבצע ניפוי איתור ביצועים נוסף. אתה יכול לקבל את מספר הפרמטרים במודל שלך tf.keras.Model.summary .

שים לב שכל פרמטר של מודל הוא 4 בתים שכן Tensorflow משתמש ב- fp32 כדי לתקשר שיפועים. גם כאשר הפעלת את fp16, NCCL AllReduce משתמש בפרמטרים של fp32. בעתיד, Tensorflow יתמוך בפעולות AllReduce באמצעות fp16, כמו גם בקו הצינור של שיפוע AllReduce כך שהוא חופף לחישוב השיפוע.

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

מחלוקת חוט מארח GPU

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

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

image

תצוגת העקיבה של המארח מראה שהמארח משגר גרעינים ב- GPU2 לפני שהוא משיק אותם ב- GPU1 (שימו לב שה- tf_Compute * ops להלן אינם מעידים על שרשור המעבד).

image

אם אתה רואה את הזעזוע הזה של גרעיני GPU בתצוגת העקבות של התוכנית שלך, הפעולה המומלצת היא:

  • הגדר את משתנה הסביבה TensorFlow TF_GPU_THREAD_MODE כדי gpu_private . משתנה סביבה זה יגיד למארח לשמור על אשכולות עבור GPU פרטי.
  • כברירת מחדל, TF_GPU_THREAD_MODE=gpu_private קובעת את מספר אשכולות 2, אשר מספיק ברוב המקרים. עם זאת, מספר כי ניתן לשנות על ידי הגדרת משתנה הסביבה TensorFlow TF_GPU_THREAD_COUNT אל המספר הרצוי של האשכולות.