最速怪談選手権

作業環境(Windows10, Python3.6.8)

あるコマンドの実行をしたのですが、以下のようなエラーが出ます。


RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.

This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:

if __name__ == '__main__':
freeze_support()
...

http://iatlex.com/python/parallel_first
https://qiita.com/stkdev/items/91b12610dcb9782f3 …

上記のリンクにあるように if __name__ == '__main__':を追加する必要があるということは分かるのですが、以下のプログラムのどこに記述すればよいのかが分かりません。


import argparse
import glob
import multiprocessing
import re
from functools import partial
from pathlib import Path

import librosa
import numpy

from become_yukarin import AcousticConverter
from become_yukarin.config.config import create_from_json as create_config

parser = argparse.ArgumentParser()
parser.add_argument('model_names', nargs='+')
parser.add_argument('-md', '--model_directory', type=Path, default=Path('/mnt/dwango/hiroshiba/become-yukarin/'))
parser.add_argument('-iwd', '--input_wave_directory', type=Path,
default=Path('/mnt/dwango/hiroshiba/become-yukarin/dataset/hiho-wave/hiho-pause-atr503-subset/'))
parser.add_argument('-it', '--iteration', type=int)
parser.add_argument('-g', '--gpu', type=int)
args = parser.parse_args()

model_directory = args.model_directory # type: Path
input_wave_directory = args.input_wave_directory # type: Path
it = args.iteration
gpu = args.gpu

paths_test = list(Path('./test_data/').glob('*.wav'))


def extract_number(f):
s = re.findall("\d+", str(f))
return int(s[-1]) if s else -1


def process(p: Path, acoustic_converter: AcousticConverter):
try:
if p.suffix in ['.npy', '.npz']:
fn = glob.glob(str(input_wave_directory / p.stem) + '.*')[0]
p = Path(fn)
wave = acoustic_converter(p)
librosa.output.write_wav(str(output / p.stem) + '.wav', wave.wave, wave.sampling_rate, norm=True)
except:
import traceback
print('error!', str(p))
print(traceback.format_exc())


for model_name in args.model_names:
base_model = model_directory / model_name
config = create_config(base_model / 'config.json')

input_paths = list(sorted([Path(p) for p in glob.glob(str(config.dataset.input_glob))]))
numpy.random.RandomState(config.dataset.seed).shuffle(input_paths)
path_train = input_paths[0]
path_test = input_paths[-1]

if it is not None:
model_path = base_model / 'predictor_{}.npz'.format(it)
else:
model_paths = base_model.glob('predictor_*.npz')
model_path = list(sorted(model_paths, key=extract_number))[-1]
print(model_path)
acoustic_converter = AcousticConverter(config, model_path, gpu=gpu)

output = Path('./output').absolute() / base_model.name
output.mkdir(exist_ok=True)

paths = [path_train, path_test] + paths_test

process_partial = partial(process, acoustic_converter=acoustic_converter)
if gpu is None:
pool = multiprocessing.Pool()
pool.map(process_partial, paths)
else:
list(map(process_partial, paths))


https://github.com/Hiroshiba/become-yukarin/blob …より)


何卒ご教授のほどよろしくお願いいたします。

A 回答 (1件)

基本的に、



if __name__ == '__main__':
 何とやら

ってのは、ファイルの最後に記述しますが・・・このプログラムだと難しそうですねぇ。バッチプログラムなんだかどうなのかちょっと良く分からんカンジで混在してます。
こっちでは実行してないですが(何だか良く分からんプログラムで怖い・笑)、やるなら2つの関数定義(つまりprocess)の後かな?丁度その後がバッチ式で実行されてて、extract_numberもprocessもそこで呼び出されていますから。そして、以降のインデントを付け忘れないようにして・・・ですね。

まあでも、基本的には、このプログラムって「他から呼び出される前提の」ファイルな気がするんで(多分、単独で動く目的、と言うよりはライブラリを意図してる?)、マジメに考えるなら下手に弄くらない方が良いたぁ思いますけどね。
もちろん、遊びや実験ならその限りではありませんが。
    • good
    • 0
この回答へのお礼

ご教授本当にありがとうございます。

2つの関数定義の後のコードを
def main():

if __name__ == '__main__':
 main()
で囲っていったところ、ついにエラーを吐くことなく実行することができました。

お礼日時:2020/07/27 12:06

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!