Спасибо за ответ @TomFenech, я должен был действительно добавить информацию об использовании процессора:
- Локальный (4 ВЦП): один вызов = ~ 390%, двойной вызов ~ 190-200% каждый
- Кластер Google (8 виртуальных ЦП): один вызов ~ 400%, двойной вызов ~ 400% каждый (как и ожидалось)
Вывод из игрушечного примера :Вы правы.Когда я звоню htop
, я на самом деле вижу 4 процесса на запущенное задание, а не 1. Так что задание распределяется внутри себя.Я думаю это связано, распределение происходит для (матричного) умножения на BLAS / MKL.
Продолжение настоящей работы : Итак, вышеприведенный пример с игрушкой был на самом деле более сложным и не идеальным случаем для моего настоящего сценария.Мой настоящий (машинное обучение) сценарий только частично полагается на Numpy (не для умножения матриц), но большинство тяжелых вычислений выполняется в PyTorch.Когда я вызываю мой скрипт локально (4 vCPU), он использует ~ 220% CPU.Когда я вызываю этот сценарий в кластере Google Cloud (8 vCPU), он, что удивительно, достигает даже ~ 700% (htop
действительно показывает 7-8 процессов).Таким образом, PyTorch, кажется, делает еще лучшую работу по распространению себя.(Версию Numpy BLAS можно получить с помощью np.__config__.show()
. Мой локальный Numpy использует OpenBlas , кластер Google использует MKL (установка Conda). Я не могу найти аналогичную команду дляпроверьте версию PyTorch для BLAS, но предположите, что она использует то же самое.)
В общем, кажется, что как Numpy, так и сам PyTorch уже заботятся о распределении кода, когда дело доходит до умножения матриц (и все процессоры видны локально, то есть без настройки кластера / сервера).Поэтому, если большая часть вашего сценария является матричным умножением, то есть меньше причин, чем (по крайней мере, я), чтобы распространять сценарии самостоятельно.
Однако не весь мой код является матричным умножением.Следовательно, теоретически я все еще должен быть в состоянии ускорить параллельные процессы.Я написал новый тест с 50/50 кодом линейного и матричного умножения:
(speed_test2.py)
import time
import torch
import random
now = time.time()
for i in range(12000):
[random.random() for k in range(10000)]
print('Linear time',round(time.time()-now,1))
now = time.time()
for j in range(350):
torch.matmul(torch.rand(1000,1000),torch.rand(1000,1000))
print('Matrix time',round(time.time()-now,1))
Запуск этого в Google Cloud (8 vCPU):
- Один процесс дает Линейное время 12,6, матричное время 9,2 .(ЦП во время первой части 100%, вторая часть 500%)
- Параллельный процесс
python3 speed_test2.py & python3 speed_test2.py
дает Линейное время 12,6, Матричное время 15,4 для обоих процессов. - Добавление третьего процесса дает Линейное время ~ 12,7, Матричное время 25,2
Заключение : Хотя здесь имеется 8 vCPU,Pytorch / матричная (вторая) часть кода на самом деле становится медленнее с более чем 2 процессами.Линейная часть кода, конечно, увеличивается (до 8 параллельных процессов).Я думаю, что это в целом объясняет, почему на практике код Numpy / PyTorch может не показать такого большого улучшения, когда вы запускаете несколько параллельных процессов.И что не всегда полезно наивно запускать 8 процессов, когда вы видите 8 виртуальных ЦП.Пожалуйста, поправьте меня, если я ошибаюсь где-то здесь.