NTA

Многопотоковая обработка файлов

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

Мне потребовалось преобразовать достаточно большое количество аудио файлов для дальнейшей обработки моделью по распознанию аудио (SpeechToText). Для преобразования речи в текст я использовал достаточно популярный инструмент - VOSK для Python. Чтобы речь правильно распознавалась моделью, аудио файлы должны быть определенного формата и частоты дискретизации (битрейт), а файлы, которые были в наличии, не подходили и их необходимо было предварительно подготовить. Для обработки использовалась консольная программа ffmpeg, которая могла изменять битрейт аудио дорожки на необходимый для распознания речи. Запустив ее в командной строке с определенными параметрами (подробно останавливаться на параметрах запуска я не буду, все подробно описано в документации на сайте к самой программе), я опишу только те которые использовал: Данный пример позволяет преобразовать один файл.

ffmpeg –i file.wav –ar 16000 –ac 1 –f s16le new_file.wav
  • i – имя исходного файла, который предстоит с конвертировать;
  • ar – частота дискредитации;
  • ac – количество каналов;
  • f – формат аудио;

С помощью Python собираем список файлов и поочередно отправляем ffmpeg для обработки и получаем необходимый результат.

files_path= '/' for subdir, dirs, files in os.walk(files_path): print(subdir) for f in tqdm(files): if f.endswith('.wav'): process = subprocess.Popen( ['ffmpeg', '-loglevel', 'quiet', '-i',file,'-ar', '16000', '-ac', '1', '-f', 's16le', file.replace(path, new_path) ])

Но, если файлов достаточно много и мы будем обрабатывать их все по порядку, то обработка займет очень большое время, а нам надо еще передать эти файлы для распознания. Чтобы сократить время преобразования, аудио можно распараллелить работу. Сама программа ffmpeg это не умеет, и здесь в дело вступает модуль multiprocessing, с помощью этой библиотеки можно из python запускать несколько потоков (или дочерних процессов).

import multiprocessing as mp #импортируем библиотеку

В итоге я написал простенький код, который постарался подробно прокомментировать:

if __name__ == "__main__": path='files/' new_path='new_files/' file_collection = collect_files(path) #функция списка получения файлов count_t=5 #максимальное кол-во потоков count_p=len(file_collection)//count_t+1 #кол-во файлов для обработки в одном потоке procs=list() #Массив процессов list_path=[] #Список файлов для отправки в поток count=0 #Счетчик кол-ва файлов в потоке for file_path in file_collection: count+=1 list_path.append(file_path) if count_p==count: proc=mp.Process(target=stt_file, args=(list_path)) procs.append(proc) proc.start() count=0 list_path=[] for proc in procs: proc.join()

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

Как уже обратили внимание из прочтения кода, поток запускается следующими строками:

proc=mp.Process(target=stt_file, args=(list_path, path, new_path,))) proc.start() procs.append(proc)

Немного о параметрах передаваемых в mp.Process:

  • target=stt_file – это функция внутри файла, которая будет запускаться
  • args=(list_path, path, new_path,) – параметры передаваемые в функцию

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

Важно обратить внимание что, для правильной работы потоков, которые будет порождать наш скрипт, необходимо учесть одну вещь, основной код должен быть изолирован. Что это значит? Скрипт должен быть завернут в условие if __name__ == «__main__»: если этого не сделать, скрипт попросту не будет запускаться и будет выпадать ошибка:

if __name__ == '__main__': freeze_support() ... The "freeze_support()" line can be omitted if the program is not going to be frozen to produce an executable.

Для примера я запустил обработку на сервере в 20 потоков, самая долгая обработка у потока заняла 25 мин., обработка в один поток оценочно займет более 8 часов(см. скрин ниже).

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

Код, используемый в этой статье, можно найти по ссылке на Github’е: https://github.com/madeyneko/multi_audio

0
3 комментария
Популярные
По порядку

Потоки и процессы — не одно и то же.

0

А если просто запускать ffmpeg через xargs с ограничением числа параллельных запусков?

0

Да, такой вариант тоже возможен. В статье указана часть кода для примера. В своем проекте был использован ffmpeg для преобразования и вывода в модель VOSK.

0
Читать все 3 комментария
ЮMoney сделали виртуальные банковские карты с дизайном из Cyberpunk 2077

Их можно заказать до 7 декабря, чтобы принять участие в розыгрыше призов.

Владелец «Билайна» раскрыл сумму сделки по продаже своих сотовых вышек в России — $957 млн Статьи редакции

Новым владельцем стала группа компаний «Сервис-Телеком», которая обслуживает инфраструктуру всех операторов.

Совет управляющих ЕЦБ одобрил новую систему контроля за электронными платежами

После общественных обсуждений в 2020 году Совет управляющих Европейского центрального банка (ЕЦБ) утвердил новую Евросистему контроля за электронными платежами, схемами и устройствами (далее - PISA).

Как в 6 раз увеличить охваты в соцсетях и задать визуальные тренды в нише. Кейс «Мираж Синема»

Студия Чижова рассказывает, как делать SMM для кинотеатров: кейс федеральной сети «Мираж Синема»

В профиле на публикациях не видно дополнительных надписей, лента выглядит чисто и минималистично
Юбилей кешбэка: как в 130 лет выглядеть «на все сто»

Кешбэк — возврат определенного процента наличных на карточный счет клиента после покупок в магазинах-партнерах банка или полетах на самолетах авиакомпаний-партнеров-банка или вообще за любые покупки в конкретный период времени — очень популярен в народе. Он выглядит как современная модная финансовая фишка

«У нас есть Волож, который нам мозг клюет»: Тиньков посчитал, что в «Яндексе» испугались покупать «Тинькофф» Статьи редакции

В «Яндексе» не захотели, чтобы после сделки Олег Тиньков остался консультировать бизнес, рассказал основатель «Тинькофф банка» в документальном фильме.

Зимний набор на оплачиваемую стажировку в Тинькофф Старт: какие задачи решают стажеры

Стажировка пройдет по направлениям: аналитика, QA, бэкенд-разработка (Java, C++, Python, Scala, .Net, Golang), фронтенд, мобильная разработка (iOS и Android), ML, маркетинг и менеджмент образовательных проектов.

Ozon и «Яндекс» увеличили капиталы собственных банков в 1,6–2 раза за три месяца Статьи редакции

Компании планируют выдавать потребительские кредиты, считают эксперты.

Экологичный email-маркетинг: полный гайд, как продавать через рассылки и не раздражать пользователей

Мы подготовили для вас полный гайд по созданию экологичной и эффективной email-стратегии: от подготовки базы до работы с анализом результатов.

eBay: 64% покупателей не жалеют о своих покупках в Черную пятницу

Черная пятница — одно из главных событий этой недели: тысячи покупателей находятся в поиске лучших скидок. А что происходит после Черной пятницы? eBay опросил около 1000 россиян и выяснил, считают ли они выгодными покупки, совершенные во время самой большой распродажи года.

Кинокомпания Bazelevs Тимура Бекмамбетова разработала сервис для продажи товаров в фильмах и сериалах Статьи редакции

Платформа работает на базе собственного плеера кинокомпании и облачных технологий Microsoft.

null