Как использовать RAPIDS для ускорения модулей, разделенных контейнером, в конвейере - PullRequest
4 голосов
/ 03 апреля 2019

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

Каждый модуль запускает контейнер (через k8s) для запуска, результаты, обработанные предыдущим модулем, сохраняются в cephfs в виде файла, а следующий модуль читает файл и затем выполняет операцию. Процесс сериализации / десериализации идет медленно. Мы планируем использовать RAPIDS для ускорения этого конвейера: для улучшения межмодульного обмена данными, помещая данные в MEM GPU. И использование cuDF / cuML вместо Pandas / SKLearn для ускорения обработки.

В настоящее время мы подтвердили, что эти модули могут быть портированы из Pandas / SKLearn в cuDF / cuML, но поскольку каждый модуль работает в контейнере, после завершения работы модуля контейнер исчезает и процесс тоже исчезает, поэтому соответствующие данные cuDF не могут продолжать существовать в MEM GPU.

В этом случае, если вы хотите использовать RAPIDS для улучшения конвейера, есть ли полезный совет?

Ответы [ 2 ]

2 голосов
/ 04 апреля 2019

Если вы хотите, чтобы процессы порождали и умирали, а доступ к памяти для них осуществлялся удаленно, вам нужно что-то, что хранит ваши данные в течение промежуточного периода.Одним из решений будет создание процесса, который будет выполнять ваши распределения, а затем вы создадите столбцы cudf из ipc.Я не уверен, как это сделать в Python.В c ++ это довольно просто.

Что-то вроде

//In the code handling your allocations
gdf_column col;

cudaMemHandle_t handle_data, handle_valid;
cudaIpcGetMemHandle(&handle,col.data);
cudaIpcGetMemHandle(&valid,col.valid);



//In the code consuming it
gdf_column col;

//deserialize these by reading from a file or however you want to make this 
//binary data avaialable
cudaMemHandle_t handle_data, handle_valid;

cudaIpcOpenMemHandle ( (void**) &col.data, cudaIpcMemHandle_t handle, cudaIpcMemLazyEnablePeerAccess );
cudaIpcOpenMemHandle ( (void**) &col.valid, cudaIpcMemHandle_t handle, cudaIpcMemLazyEnablePeerAccess );

Существуют также сторонние решения от разработчиков RAPID, такие как BlazingSQL, которые предоставляют эту функциональность в python, а также предоставляютинтерфейс SQL для cudfs.

Здесь вы бы сделали что-то вроде

#run this code in your service to basically select your entire table and get it
#as a cudf
from blazingsql import BlazingContext
import pickle
bc = BlazingContext()
bc.create_table('performance', some_valid_gdf) #you can also put a file or list of files here
result= bc.sql('SELECT * FROM main.performance', ['performance'])
with open('context.pkl', 'wb') as output:
    pickle.dump(bc, output, pickle.HIGHEST_PROTOCOL)
with open('result.pkl', 'wb') as output:
    pickle.dump(result, output, pickle.HIGHEST_PROTOCOL)


#the following code can be run on another process as long as result
# contains the same information from above, its existence is managed by blazingSQL 
from blazingsql import BlazingContext
import pickle
with open('context.pkl', 'rb') as input:
  bc = pickle.load(input)
with open('result.pkl', 'rb') as input:
  result = pickle.load(input)

#Get result object
result = result.get()
#Create GDF from result object
result_gdf = result.columns

Отказ от ответственности, я работаю на Blazing.

1 голос
/ 05 апреля 2019

Отказ от ответственности: я сотрудник NVIDIA и участник RAPIDS.

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

Каждый модуль запускает контейнер (через k8s), результаты которого обрабатываютсяпредыдущий модуль сохраняется в cephfs как файл, а следующий модуль читает файл и затем выполняет операцию.Процесс сериализации / десериализации идет медленно.Мы планируем использовать RAPIDS для ускорения этого конвейера: для улучшения межмодульного обмена данными, помещая данные в MEM GPU.И использование cuDF / cuML вместо Pandas / SKLearn для получения более быстрой скорости обработки.

В настоящее время мы подтвердили, что эти модули можно переносить с Pandas / SKLearn на cuDF / cuML, но поскольку каждый модуль работает вконтейнер, когда модуль завершает работу, контейнер исчезает и процесс тоже исчезает, поэтому соответствующие данные cuDF не могут продолжать существовать в MEM GPU.

В этом случае, если вы хотите использовать RAPIDS для улучшенияконвейер, есть ли полезный совет?

Контейнеры в модуле в Kubernetes совместно используют пространство имен IPC [[1]] [2,], которое позволяет CUDA IPC работать между контейнерами.То, что @ flips , представленное выше, было бы идеальным случаем для наиболее эффективного конвейера данных, но его нелегко реализовать с текущими ограничениями в Kubernetes с графическими процессорами.Разрешение запуска нескольких контейнеров, которые могут взаимодействовать с одним и тем же графическим процессором (ами), все еще находится на стадии исследования / эксперимента в Кубернетесе [2] .Это оставляет вам несколько вариантов:

  1. Попробуйте использовать обходные пути / решения, представленные в [2] , для запуска контейнера «sidecar», который долго работает, единственной целью которого являетсявыступать в качестве посредника для памяти GPU между различными контейнерами в модуле.
  2. Скопируйте объекты памяти GPU для размещения объектов памяти, таких как объекты Apache Arrow, а затем запустите контейнер "sidecar" без ресурсов GPU и памяти IPC в /из этого контейнера.Например, используя Arrow [3] .
  3. Продолжайте использовать файловую систему cephfs в том виде, в каком вы находитесь сегодня, и в будущем появятся средства записи с ускорением на GPU и надеетесь, что это поможет устранить текущее узкое место.
...