Ви проходите співбесіду на інженера машинного навчання в Google. Інтерв'юер: Нам потрібно навчити LLM на 1000 GPU. Як би ви переконалися, що всі GPU діляться тим, чого навчаються? Ви: Використовуйте центральний сервер параметрів для агрегування та перерозподілу ваг. Інтерв'ю закінчено. Ось що ви пропустили:
Одне з основних вузьких місць під час виконання в навчанні з кількома графічними процесорами трапляється під час синхронізації графічного процесора. Наприклад, у навчанні з кількома графічними процесорами за допомогою паралелізму даних: - Одна і та ж модель розподіляється на різні графічні процесори. - Кожен графічний процесор обробляє різну підмножину всього набору даних. Перевірте це 👇
Це призводить до різних градієнтів між різними пристроями. Отже, перед оновленням параметрів моделі на кожному GPU-пристрої ми повинні передати градієнти всім іншим пристроям для їх синхронізації. Давайте розберемося з двох поширених стратегій далі!
Алгоритм 1) All-reduce Очевидний спосіб — передавати градієнти з одного пристрою на всі інші пристрої для їх синхронізації. Але це використовує високу пропускну здатність. Якщо кожна GPU має елементи «N» і є «G» GPU, це дає загальний перенесення елементів 👇 G*(G-1)*N
Ми можемо оптимізувати це, перенісши всі елементи в одну GPU, обчисливши кінцеве значення і відправивши його назад на всі інші GPU. Це значне покращення. Але тепер одна GPU має приймати, обчислювати і передавати градієнти, тому це не масштабується.
Алгоритм 2) Зменшення кільця Фаза #1) Зменшення частки По-перше, градієнти поділяються на сегменти G на кожному GPU (G = загальна кількість GPU). Подивись на 👇 це
Під час ітерації кожен графічний процесор надсилає сегмент наступному графічному процесору: - GPU1 надсилає a₁ на GPU2, де він додається до b₁ - GPU2 надсилає b₂ на GPU3, де він додається до c₂ - GPU3 відправляє c₃ на GPU4, де він додається в d₃ - GPU4 надсилає d₄ на GPU1, де він додається до a₄ Перевірте це 👇
Цей процес повторюється: - GPU1 надсилає (d₄+a₄) у GPU2, де додається до b₄. - GPU2 передає (a₁+b₁) на GPU3, де додається до c₁. - GPU3 передає (b₂+c₂) на GPU4, де додається до d₂. - GPU4 передає (c₃+d₃) на GPU1, де додається до a₃. Подивись на 👇 це
У фінальній ітерації наступні сегменти передаються наступному графічному процесору. Це призводить до стану, коли кожен графічний процесор має один цілий сегмент, і ми можемо перенести ці повні сегменти на всі інші графічні процесори. Перевірте це 👇
Фаза #2) Виключно для спільного доступу Тепер, коли кожен GPU має один цілий сегмент, ми можемо перенести ці повні сегменти на всі інші GPU. Процес проводиться подібно до того, що ми обговорювали вище, тому ми не будемо вдаватися в деталі. Ітерація 1 показана нижче👇
Далі виконуємо ітерації 2 і 3. Вони виконуються подібно до того, що ми вивчили у Фазі 1. Подивись на 👇 це
Ось і все! Ваги моделей між GPU синхронізовані. Хоча загальна кількість переданих елементів залишається такою ж, як і в підході «один GPU-майстер», цей підхід із кільцем набагато масштабованіший, оскільки не перекладає все навантаження на одну відеокарту. Подивись на 👇 це
За замовчуванням моделі глибокого навчання використовують лише одну GPU для навчання, навіть якщо доступно кілька GPU. Ідеальний спосіб навчання моделей — розподілити навчальне навантаження між кількома GPU. Графік показує чотири стратегії навчання👇 мульти-GPU
364,8K