Зачем использовать MPS, Time Slicing или MIG, если настройки Nvidia по умолчанию имеют более высокую производительность?

Я пытаюсь осознать последствия стратегий совместного использования графических процессоров Nvidia:

  • МИГ
  • Нарезка времени
  • МПС

Но, учитывая, насколько непрозрачной я нашел их документацию по этому вопросу, до сих пор я собирал воедино свое понимание каждого, экспериментируя с каждым вариантом и читая соответствующий исходный код, например. Плагин устройства nvidia.

Сейчас я рассматриваю сравнительный анализ каждой стратегии. Я запустил 7 реплик в k8 одного и того же приложения для всех четырех вариантов. Я использовал a100 с 80 ГБ видеопамяти.

import os

# Set YOLOv8 to quiet mode
os.environ['YOLO_VERBOSE'] = 'False'

from prometheus_client import start_http_server, Histogram
from ultralytics import YOLO
import torch

start_http_server(8000)

device = torch.device("cuda")

model = YOLO("yolov8n.pt").to(device=device)

h = Histogram('gpu_stress_inference_yolov8_milliseconds_duration', 'Description of histogram', buckets=(1, 5, 10, 15, 20, 25, 30, 35, 40, 50, 75, 100, 150, 200, 500, 1000, 5000))

def run_model():
    results = model("https://ultralytics.com/images/bus.jpg")
    # print(model.device.type)
    h.observe(results[0].speed['inference'])

while True:
    run_model()

Результаты приведены ниже:

Следовательно, если скорость вывода лучше всего при настройках по умолчанию и она уже может поддерживать взаимодействие нескольких приложений с одним графическим процессором, то зачем использовать какую-либо другую стратегию? Я понимаю, что в их документах говорится, что такая стратегия, как MIG, может обеспечить вам толерантность к памяти, т. е. одно приложение, использующее графический процессор, не может вывести из строя другое, но если отложить это в сторону, действительно ли есть веская причина использовать эти стратегии, если вы переустанавливаете приоритеты производительности?

Чтобы еще больше запутаться, если я создам матмул с двумя огромными матрицами, разница в производительности каждой стратегии будет равна нулю:

import torch
import time
from prometheus_client import start_http_server, Histogram

# Check if CUDA is available and Tensor Cores are supported
if not torch.cuda.is_available():
    raise SystemError("CUDA is not available on this system")

device = torch.device("cuda")

torch.cuda.set_sync_debug_mode(debug_mode = "warn")

torch.set_default_device(device) # ensure we actually use the GPU and don't do the calculations on the CPU

h = Histogram('gpu_stress_mat_mul_seconds_duration', 'Description of histogram', buckets=(0.001, 0.005, 0.01, 0.1, 0.25, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0))

def mat_mul(m1, m2):
    return torch.matmul(m1, m2)


# Function to perform matrix multiplication using Tensor Cores
def stress(matrix_size=16384):
    # Create random matrices on the GPU
    m1 = torch.randn(matrix_size, matrix_size, dtype=torch.float16)
    m2 = torch.randn(matrix_size, matrix_size, dtype=torch.float16)
    
    # Perform matrix multiplications indefinitely
    while True:
        start = time.time()
        output = torch.matmul(m1, m2)
        print(output.any())
        end = time.time()
        h.observe(end - start)            

if __name__ == "__main__":
    start_http_server(8000)
    stress()

Должно быть, меня здесь нет, так как их документы, например. MPS, похоже, подразумевает, что эти стратегии лучше подходят для совместного использования графических процессоров.

Обновлять

Благодаря ответу @robert-crovella я вернулся к результатам и обнаружил, что, хотя задержка и хуже, пропускная способность намного лучше.

Спасибо, я не видел первый пост, но прочитал второй. К сожалению, никаких критериев для этого не было.

Ronan Quigley 01.07.2024 10:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
221
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

TL;DR: Ваше первоначальное наблюдение может быть разумным, если учесть некоторое дополнительное определение тестового примера и отметить, что вы, похоже, измеряете задержку отдельного запроса на вывод. Вариант по умолчанию, вероятно, является лучшим вариантом, учитывая только задержку, измеряемую для каждого запроса.

дольше:

Определение терминов:

Вы четко не определили и не показали, что вы подразумеваете под случаями «По умолчанию» и «Разрез времени».

Данные вашего первого графика кажутся мне разумными при следующих определениях:

Типичный запрос ресурсов обеспечивает эксклюзивный доступ к графическим процессорам. Запрос на графический процессор с квантованием времени обеспечивает общий доступ.

Также важно отметить, что ваш тест измеряет (кажется) задержку вывода. Можно также измерить скорость вывода, и ранжирование случаев может быть другим. Вывод/предложение о преимуществах в случае MPS почти наверняка относится к пропускной способности в большей степени, чем к измерению задержки.

Краткое описание режимов при вышеуказанном условии:

  • MIG: графический процессор физически разделен на аппаратном уровне. Каждый секционированный экземпляр (в настоящее время их может быть до 7) имеет часть возможностей графического процессора с точки зрения вычислительной производительности, размера памяти и пропускной способности памяти. По сравнению с работой на неразделенном графическом процессоре выполнение того же отдельного теста/измерения на экземпляре MIG почти наверняка будет выполняться медленнее. Это похоже на работу на графическом процессоре, который имеет (например) 1/7 возможностей неразделенного графического процессора.

  • По умолчанию: графический процессор и его поведение не изменяются. Обычное поведение/поведение по умолчанию для графического процессора CUDA — разрешить нескольким арендаторам совместно использовать графический процессор практически неуказанным образом. Однако обратите внимание на приведенное выше утверждение об использовании K8 с оператором графического процессора — случай по умолчанию подразумевает эксклюзивный доступ к графическому процессору для каждого процесса. Это означает, что для каждого запроса вывода запрос будет иметь доступ ко всему графическому процессору для этого запроса. Но множественные запросы от разных клиентов потребуют некоторой сериализации.

  • MPS: К графическому процессору подключен дополнительный «переходник», подключенный к интерфейсной части работы-доставки. Работа передается графическому процессору так, как если бы она исходила от одного процесса. Это означает, что отдельные арендаторы не получают эксклюзивный доступ к графическому процессору; каким-то образом графический процессор является общим. Кроме того, может произойти некоторое перекрытие действий, чего в противном случае не произошло бы в случае по умолчанию для мультитенантности/мультипроцесса. В частности, в случае MPS возможно перекрытие выполнения ядра.

  • Временной интервал: как упоминалось ранее, для изменения поведения графического процессора используется либо виртуальный графический процессор, либо оператор графического процессора K8s . На высоком уровне эффект от этого аналогичен моему описанию случая по умолчанию без вмешательства K8s/оператора: графический процессор используется каким-то неопределенным образом. На современных графических процессорах, по наблюдению, совместное использование осуществляется с разделением по времени, даже на уровне ядра CUDA (т. е. может использоваться упреждение ядра CUDA).

Описание производительности:

Важно отметить, что вы измеряете задержку вывода (я полагаю). Я думаю, что лучший способ объяснить, почему результаты кажутся разумными, — это попарное сравнение случаев.

В случае по умолчанию, включая эксклюзивное примечание выше, каждый запрос вывода выполняется так, как если бы ему принадлежал весь графический процессор A100. С точки зрения задержки (время, затраченное на выполнение конкретного запроса), это, несомненно, лучший сценарий.

В случае MIG (представим, что вы разделили графический процессор на 7 экземпляров) каждый запрос на вывод будет использовать 1/7 графического процессора для выполнения. Это, безусловно, займет больше времени, чем в случае по умолчанию, учитывая только задержку каждого запроса.

В случае MPS и случае с квантованием времени графический процессор больше не является исключительным для одного запроса вывода. Несколько запросов могут использовать графический процессор в определенное время, и один запрос вывода может быть остановлен в середине обработки, чтобы позволить продолжить выполнение другого запроса. Такова природа разделения времени. Учитывая задержку конкретного запроса, он, безусловно, будет медленнее, если в середине обработки он будет прерван срезом времени, чтобы позволить обработать другой запрос.

Таким образом, значение по умолчанию, вероятно, является лучшим параметром, учитывая только задержку на запрос.

Но другой показатель, который иногда волнует людей, — это пропускная способность. Сколько запросов в секунду выполняется независимо или без учета времени, необходимого для выполнения каждого запроса (т. е. без учета задержки)? Для вывода больших объемов информации это, по сути, показатель эффективности. В этом случае настройки по умолчанию могут быть не лучшими. Это приводит к наименьшему перекрытию обработки запросов (т. е. сериализация активности самая высокая).

Используйте предложения:

MIG особенно эффективен, когда вы хотите предоставить фиксированные ресурсы каждому арендатору/клиенту/процессу. Это означает, что активность одного клиента мало влияет на наблюдаемое поведение другого клиента. Но в случае вывода большого объема это не обязательно минимизирует задержку и не увеличивает пропускную способность. Одним из наиболее важных преимуществ является качество обслуживания в общей среде.

MPS почти наверняка лучше, чем вариант по умолчанию, в любое время, когда вас интересует пропускная способность или эффективность в случае с несколькими клиентами/арендаторами/процессами. Однако это не повышает производительность какого-либо отдельного клиента. Это повышает производительность только при использовании совокупного представления, такого как пропускная способность или эффективность. Более того, если вы можете эквивалентно разделить свою работу таким образом, чтобы один процесс мог отправлять всю работу на графический процессор, а не несколько процессов, совместно использующих один графический процессор, по моему опыту, случай с одним процессом (и без MPS) обычно более эффективен. . Но во многих случаях мы по своей сути используем или должны использовать многопроцессную структуру работы, и MPS помогает в этих случаях повысить эффективность/пропускную способность.

При выводе больших объемов показатель качества, который иногда завышается, представляет собой максимальную пропускную способность (или эффективность) с учетом максимальной/верхней границы задержки для каждого запроса. Ни одна из вышеперечисленных технологий сама по себе не позволит этого сделать. В этом случае может представлять интерес дополнительная технология, такая как Triton Inference Server.

Спасибо за подробный ответ. Я назначил награду, чтобы избежать истечения срока ее действия, но мне нужно оставить несколько дополнительных комментариев, как только у меня появится возможность сделать это на этих выходных.

Ronan Quigley 27.06.2024 23:16

[Предисловие: я просто использую плагин устройства nvidia, а не оператор графического процессора] - Да, по умолчанию я просто имею в виду настройки по умолчанию, то есть просто оставляю драйверы cuda/nvidia как есть. - Для разделения времени я настраиваю параметр совместного использования плагина устройства nvidia для использования параметра timeSlicing. - Когда вы говорите, что по умолчанию выполняется эксклюзивный запуск каждого процесса, почему nvidia-smi не показывает этот режим как эксклюзивный процесс . Это две разные вещи? Я вернулся к результатам и увидел совершенно другой результат, глядя на пропускную способность. Обновил свой ответ скриншотом.

Ronan Quigley 01.07.2024 10:48

мои комментарии касались использования оператора GPU. Я не рассматривал и не смотрел плагин устройства. Более того, я не думаю, что оператор графического процессора на самом деле переводит устройство в эксклюзивный режим вычислений, я считаю, что он регулирует работу диспетчеризации K8.

Robert Crovella 01.07.2024 17:06

Другие вопросы по теме