использовали все доступные ядра (идея чтобы на кажом ядре сидела копия модели и как следствие увеличить throughput)?
Пробовала через FastAPI и workers, но результат маленький.
Golang можно использовать.
А у меня модели оптимизированные (onnx_runtime). Go вроде не поддерживает пока их достаточно хорошо. У меня transformers модели (по типу BERTa)
Горутина может запускать питон как шелл
А сейчас инференс в одном потоке происходит? Вроде она сама должна параллелить вычисления
Хотел написать, но понял что много и стало лень. Спросил у gpt-то что хотел написать 😁- Если вам нужно распараллелить процессы и эффективно использовать все доступные ядра CPU для деплоя моделей, есть несколько подходов: 1️⃣ Многопоточность (Multithreading): Вы можете использовать многопоточные библиотеки, такие как threading в Python, каждый из которых будет обслуживать запросы на основе вашей модели. При правильной реализации это позволит использовать все доступные ядра CPU. 2️⃣ Многопроцессорность (Multiprocessing): Вместо использования потоков, вы можете рассмотреть использование многопроцессорности, где каждый процесс будет выполняться на отдельном ядре CPU. Для этого вы можете использовать модуль multiprocessing в Python. Каждый процесс будет содержать копию вашей модели и обрабатывать запросы параллельно, увеличивая пропускную способность. 3️⃣ Контейнеризация: Вы можете использовать платформы контейнеризации, такие как Docker или Kubernetes, для масштабирования вашего деплоя моделей. Они позволяют запускать несколько контейнеров, каждый из которых содержит копию модели, и автоматически масштабировать количество контейнеров в зависимости от нагрузки или доступных ресурсов. 4️⃣ Использование библиотек и фреймворков: Некоторые библиотеки и фреймворки для глубокого обучения уже имеют встроенную поддержку для многопоточности и многопроцессорности. Например, TensorFlow и PyTorch предлагают специальные инструменты для многопоточного или многопроцессорного выполнения.
Ну GPT как всегда выдаёт максимально общие ответы. Мне было интересно, как более опытные люди в реальной жизни на своих проектах делают с transformers моделями, чтобы не пробовать все возможные варианты.
https://youtu.be/ROE9PG8YaWA тут есть секция про практику ускорения на видюхах и в презе разные ссылки прлезные есть, с которыми можно ознакомиться и узнать что-то полезное https://m.youtube.com/watch?v=d8ACZ0nQzss тут другая практика, но тоже скорее про видюхи https://m.youtube.com/watch?v=UeTDHVZ3Ft0 тут первый же доклад про процессоры, но не про трансформеры
Так там же подробно наоборот-докером можно распараллелить, библиотеку использовать многопоточную, готовые фрейворки-кому что нравится.
Тут идея в том, чтобы модели работали на питоне, как обычно, но ими рулил оркестратор на go (или ещё каком языке, который нормально с concurrency работает). Если просто на FastAPI или serving каком-нибудь, тогда отдельно надо решать задачи: (1) timeouts (2) model pool management - warming, recycling (3) просто следить, чтобы большая пачка параллельных запросов не завесила всю систему нафиг, а встала в очередь (4) request batching, чтобы ресурсы эффективнее использовать (5) логгирование и телеметрия запросов, чтобы видеть состояние
Кстати, как решали задачу синхронного инференса в асинхронном фреймворке?
inference и вся ML логика на python. никакого асинхрона там, для простоты и надежности. оркестратор - полностью асинхронный. Чисто на go. Но, там без бизнес логики. Он просто рулит пулом из питоновских моделей/процессов и распределяет между ними ресурсы.
То есть запрос -> fast api -> http -> пулл -> модель ?
HTTP Запрос -> API оркестратора (async) ---> python process (sync) Общение между оркестратором и моделями в пуле - просто по STDIN/STDOUT. Он же сам их запустил, может с ними напрямую общаться. Так и отлаживать проще модели индивидуально.
А всё вопросов нет
А с воркерами что не так? Воркер гуникорна (скорее всего его используете) это и есть отдельный процесс на отдельном ядре
Да, его и попробовала. Но у меня 10 ядер на компьютере. Поставила 4 worker-а и разница - стало процентов на 15% быстрее (запросы слала асинхронно, сразу 64 и тестировала вариант с 1 worker-ом и с 4. Разница 15%).
Ощущение, что это как-то странно. Если бы модель распаралелиравалась на все ядра сама - то ускорения не должно было бы быть вообще. А вот если её worker-ами на ядра распарраллелить, то должно было стать в 4 раза быстрее, а не на 10-15%.
Исходная модель была переведена в инференс в однопоточном режиме? Если запускать несколько многопоточных моделей, то они будут конкурировать за ресурсы
https://docs.ray.io/en/latest/serve/index.html Все из коробки есть. Хороший hands-on туториал https://medium.com/distributed-computing-with-ray/how-to-scale-up-your-fastapi-application-using-ray-serve-c9a7b69e786
Потом, если надо и обернете в куб. (я лично не пробовал интегрировать, но ребята интегрировали успешно)
А вот это я как раз уже пробовала! Могу даже опытом поделиться. Существенно замедлило модель, очень существенно. Писала им в чат - сказали, что это нормально, т.к. рассчитано на кластер.
torch сам умеет, лучше собирайте запросы в batch
На CPU вроде не должно быть разницы - батч/не батч. На GPU собирала. А на CPU смысла нет вроде
А какую модель деплоили и какие указали параметры batch_size | num_replicas | num_cpu_per_replica | num_gpu_per_replica, если не секрет, разумеется?
Примерно как на скринах, на 1 компьютере Ray даёт серьезное замедление по сравнению с просто FastAPI
Обсуждают сегодня