Многопроцессорность работает на Windows, но не работает на Ubuntu

Рейтинг: 0Ответов: 1Опубликовано: 05.04.2023

Я пытаюсь разделить загрузку файлов с сервера и их обработку с использованием модели transformer на отдельные процессы. Чтобы попрактиковаться в работе с очередью в многопроцессорной обработке, я написал небольшой пример, который прекрасно работает в Windows, но не работает в Ubuntu. В Ubuntu, во время передачи файла в transformer, процесс перестает что-либо делать и, кажется, приостанавливается. В терминале на Ubuntu я вижу надпись "Take" только дважды (зависит от аргумента num_process)

Процесс как-будто встает на паузу на строчке predicted_ids = model.generate(input_features)

import multiprocessing as mc
import os
import time

import librosa
from transformers import WhisperProcessor, WhisperForConditionalGeneration

processor = WhisperProcessor.from_pretrained("openai/whisper-tiny")
model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny")
model.config.forced_decoder_ids = None


def speech_to_text(path_to_audio):
    sound, sr = librosa.load(path_to_audio, sr=16000)
    input_features = processor(sound, sampling_rate=sr,
                               return_tensors="pt").input_features
    predicted_ids = model.generate(input_features)
    transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True)
    return transcription


class Test:
    def __init__(self):
        self.queue = mc.Queue()

    def put_items(self):
        for i in range(100):
            self.queue.put((i, 'speech.wav'))
            time.sleep(2)

    def process(self):
        while True:
            if self.queue.empty():
                time.sleep(1)
                continue

            i, item = self.queue.get()
            print("Take", i, os.getpid())
            print(i, speech_to_text(item)[0], os.getpid())

    def run(self, num_process):
        put = mc.Process(target=self.put_items)
        put.start()

        processes = []
        for _ in range(num_process):
            p = mc.Process(target=self.process)
            processes.append(p)
            p.start()

        put.join()


if __name__ == '__main__':
    t = Test()
    t.run(num_process=2)

Ответы

▲ 2Принят

Дали ответ на оригинальном stackoverflow

Нужно использовать spawn-метод для создания процесса. Это значение по умолчанию для Windows, но не для Unix.

if __name__ == '__main__':
    mc.set_start_method('spawn')
    t = Test()
    t.run(num_process=2)