
Pythonã©ã€ãã©ãª(é³å£°èªè)ïŒWhisper
ïŒïŒç·èš
ïŒïŒïŒïŒæŠèŠ
ã2022幎9æ22æ¥ã«OpenAIããé«ç²ŸåºŠãªé³å£°èªèã¢ãã«ã®Whisperãå ¬éãããŸãããæ¬èšäºã§ã¯ãã¡ããå®è£ ããŠã¿ãŸãã
We've trained a neural net called Whisper that approaches human-level robustness and accuracy on English speech recognition. It performs well even on diverse accents and technical language. Whisper is open source for all to use. https://t.co/ueVywYPEkK
â OpenAI (@OpenAI) September 21, 2022
ãå®è£
ç¡ãã§è©Šãããæ¹åãã
ãããã«æ§èœã ãã§ã詊ãããæ¹ã¯äžèšãµã€ããããã©ã€ã¢ã«ã§ããŸãã
ïŒïŒïŒïŒã¢ãã«ã®æŠèŠ
ãå ¬åŒããäžå³åç §



ïŒïŒç°å¢æ§ç¯
ãWhisperã䜿çšã§ããããã«ç°å¢æ§ç¯ã宿œããŸããÂ
ãåèãŸã§ã«ããµã³ãã«ãã¡ã€ã«ã¯é³å£°ããŒã¿(mp3, wav, w4aãªã©ïŒã§ããã°ãªãã§ãããã§ããæ¬èšäºã§ã¯youtube-dlã䜿çšããŠyoutubeãããµã³ãã«ãªãŒãã£ãªãã¡ã€ã«ãååŸããŸããã
[TERMINAL]
pip install youtube-dl
youtube-dl --extract-audio https://www.youtube.com/watch?v=Yx1CqlmLJSs
[OUT]
åé³¥ã»ãããSKE48é ç°äºéŠéã«NGçºèšé£çºïŒïŒ åé³¥MCããã£ã³ã¹ã®æé # 129ã-Yx1CqlmLJSs.m4a ãçæããã
ïŒïŒïŒïŒã©ã€ãã©ãªã®ã€ã³ã¹ããŒã«
ããWhisperã®GitHubããåç §ããŠç°å¢æ§ç¯ããŸãã

ãGoogle Colabã§äœ¿çšããå Žåã¯äžèšã®ã¿ã§ååã§ãã
[IN]
pip install git+https://github.com/openai/whisper.git
[OUT]ïŒïŒïŒïŒWindowsã§ã®ç°å¢æ§ç¯
ãåºæ¬çãªç°å¢æ§ç¯ã¯äžèšèšèŒã®AnacondaïŒPytorchã®ç°å¢æ§ç¯ã®ã¿ã§ãããŸããã
ãè¬ã®ãšã©ãŒã
ãWhisperã€ã³ã¹ããŒã«åŸã«ã³ãŒãå®è¡ãããšäžèšãšã©ãŒãã§ãŸããã

ã念ã®ããäžèšå®è¡ããŸãããæ¢ã«AnacondaïŒã«ã¯æ¢ã«ã€ã³ã¹ããŒã«æžã¿ã§ãããšã©ãŒãæ¶ããŸããã§ããã念ã®ãã"pip freeze"ã§ã€ã³ã¹ããŒã«æžã¿ã©ã€ãã©ãªã確èªããŠãlockfileã¯åºãŸããã§ããã
ãäžåºŠIDE(VS CODE)ãéããŠå床å®è¡ãããäœæ
ããšã©ãŒã¯æ¶ããŸããã
[TERMINAL]
pip install filelock
pip freeze
ïŒïŒã¢ãã«ã®å®è£
ïŒïŒïŒïŒPythonã«ããå®è£ æ¹æ³ïŒã·ã³ãã«Ver.
ãæãã·ã³ãã«ãªæ¹æ³ã¯å ¬åŒèšäºããäžèšã®éãã§ããäžèšã®ã¿ã§ãããããªç²ŸåºŠïŒæ¬¡ç¯ã®largeã¢ãã«ã¯é«ç²ŸåºŠïŒã®é³å£°èªèãã§ããŠãããŸãã
[IN]
import whisper
path_audio = 'åé³¥ã»ãããSKE48é ç°äºéŠéã«NGçºèšé£çºïŒïŒ åé³¥MCããã£ã³ã¹ã®æé # 129ã-Yx1CqlmLJSs.m4a'
model = whisper.load_model('base')
result = model.transcribe(path_audio)
print(result["text"])
[OUT]
2人ç®ã¯ãã®äººæ°ã¢ã€ãã«ãç»å Ž é«æåºŠãé«ãããã®ã¶ã®ããã«ç¬¬äºãå
šãŠã®ãã©ã¹ã¡ã³ãã§èœãšãã«ãããã§ã¯ç¶ããŠã®æ¥œå±æšæ¶é«æåºŠ ã©ãã«ãŒãã£ã¬ã³ãžã§ããé¡ãããŸãã¯ããã§ãããããããã§ãããã女æ§ã ã¯ã倱瀌ããŸããã¯ããããããŸãçŽ é«ãã§ã倱瀌ããŸã女æ§ã ããå€ããããããããšãããããŸããã€ãããããšãããããŸãããããã»ã¯ã³ã«ãªããŸãç¶ããŠãã£ãŠããã®ã¯SK48ãšçŽ çŽãªã¢ã«ãªã¢ã¯ã·ã«ã€ã®äžã䌎ãã圌女ã ã䌞ã¶ã«å¯ŸããŠç¥å€ªéœãã€ãã¬ãããSKã®é²æ²ãä»ãªãªãŒã¹ãããŠããã§åãåã£ãŠããã ããŠãããã§ãããããããããã©æã«åã£ãŠãããªããããããšãããããŸããããªããããã§ãã?ã§ãDVã§ãå
¥ã£ãŠããã§çµæ§ç¹å®æŒå¥ãšããå
å®ããŠããã§åã¯ãã£ã±ã人ãæã£ãŠèžã£ãŠããã®ããããªãããã©ããªãã§ãã?ç§ã®ããšãèŠã€ããŠãã ãããããã¯ã²ã©ã倧ãããã°å€ãã»ã©ãããªãä»åºŠç§ããã®ä»£ãæã£ãããã€ãCDæã£ãŠããŸãããšã©ã€ãã©ãã©ãã©äœåãã«ã©ã³ãã¿ããã«ããã¹ããããŠãããããããããã°ãªãã§ãããšãšã©ã€ãã©ãã©ãã©ãã©äœåãã«ã©ã³ãã¿ããã«ããã¹ã£ãŠãããªãã€ããªã£ãŠãããããªãã§ãããã°ããé¡ãèŠãŠçµæ§ãã€ãçŸå³ããããã£ãŠãã ãã£ãŠãã£ã¡ããã¡ãæ©ãã«èèšè
èèšè
èèšè
äžçªèšãããããªããã坿ããªããŸããç§ããããããããŠãªãã§ãèèšè
ããŠãªãã§ããããã©ãã ãã§ã©ããå€ãã£ããšæããŸãããã坿ããªã£ããªã£ãŠæã£ãã£ãŠããšã§ãããããªã«é
åçã§ããç§ãããããããå«ã äœãã§ããæ¬åœã«å«ã ã¡ãã£ãšåœŒã«æ¢ãããªããŠãããã§ãžã¥ãã§ãžã¥ãã§ãžã¥ãã§ãžã¥ãã§ãžã¥ãžã¥ããžã¥ããžã¥ããžã¥ãã³ä»æ¥ãã£ãŠãªãã§ãããããã£ã¡ã®åãããªããã ããããžã¥ãã³ããããã©ããããã£ã¡ã®åãããªãã©ã£ã¡ãããäœã®è©±ãããŠããã§ããå
šéšå¿ããŠäœãèšããªãå
šéšå¿ããŠããã«ãèšããªãããããŸãã誰ã«ãèšããªãã¯ããäœã«ãçè§£ããŠãªããã§å€§äžå€«ã§ãå
æ¶²ã¢ã€ãã«ã«å¯Ÿã倱瀌ãªçºèšãé£çºããã®ã¶ããããããã«éããã¯ãšã¹ã«ã¬ãŒãããŠããããã°ãªãã§ããã©ç§æ¬éžæãããããã®ããšã詊ã£ãŠããããªãã§ãããããããã¢ã¯ã¢éžæãããããããããããã£ãŠããã詊åã£ãŠããç¹å¥èãããã€ãããäžæã€èãããã€ã®ãããäžã€å€§ã«èããŸããäžã€å€§ããäžã€å€§ããäžäººç¥ããŸããäžæã¡ãããåãããªããšæããŸãããããåãããããããããããããããããããæããæ©äŒããã£ãã確èªããšããŸãããã®ãåã®äžé·ãã®ãã¡ãã£ãšèããŠãããããããããããããåã®é·ãã®ãã©ãžãªèããŠããèããŠãªããšæããŸãããããããããããããããããããããããããããããããããããããã·ã¥ãŒã·ãŒç¬é¡ã ã£ãçŽ çŽãªã¢ã«ãªãã€ãã«é£ãã§ããããŠè©±é¡ã¯éé¡ã®ãã€ãã¿ãŒè©±ã«ããããã£ãããªãã§ããã©ãã®åçæ®ã£ãŠããã ããŠãããã§ããã¯ããããã§ãããã©ãã¯ãŒã¹ç¥ã£ãŠãã®ãã©ãã¯ãŒã¹ç¥ã£ãŠããããã§ããããŸãããŠããã©ãã¯ãŒã¹ã§ããŠã³ããæ®ãã®ããã«ããããåœæ°çã¢ã€ãã«ãçžæã«æ£æçºèšããããããããã€ã£ãŠåçæ®ã£ãŠãã£ãŠããããããªãã®åããããèŠãŠã¯ãã¯ãã¯ãã¯ãã¯ãã¯ãã¯ãããããããåçã¯åçå
šç¶æ®ã£ãŠããããã©ã¯ãããããã§ããåçããããããããªãã®SKEãšãAKVã°ã«ãã§ãªããã«ã«ãœãŒãªãã€ããããªãããã®SKEã¯ãSKEããªããã«ã«ãœãŒãªããã«ã«ãœã«ã«ãœãŒãªäººãããªãããã®CDèŠãªããGãããŒãããµã䞊ãã§ããã©ããªã«ã«ãœãŒãªåã«ã«ãœãŒå€ªæ ã§ããéãéãéãã¡ããã©ãªãããŒãããµãªãããŒãªãããŒããããã«ã«ãœãŒã«ã«ãœãŒã®åã¯10代ã§ããé¢ä¿ããããé¢ä¿ããããé¢ä¿ãããããªããããªãããã¯ã·ãããŒã«ããžã§ã€ã»ã£ã±ã確ãã«ãªãã§ã197710代ã¯ã·ãããŒã«ããžã§ã€éãããã€ãã£ãããã§ãã197719771977ã«ã«ã€ããäœãã§ããã»ãã¯ã¹ã泚æç¹ãšããŠãGPUãããã§äœ¿çšããªããš"FP16 is not supported on CPU; using FP32 insteadâãšãããšã©ãŒãçºçããŸãã

ãåèãŸã§ã«åºåããããã¹ãã¯ãã¡ã€ã«ãžã®æžã蟌ã¿ã§ä¿åã§ããŸãã
[IN]
with open('transcription.txt', 'w') as f:
f.write(result['text'])
[OUT]
transcription.txtãããçæïŒïŒïŒïŒã¢ãã«ã®èšå®
ãWhisperã§ã¯ã¢ãã«ã5çš®é¡(ãã¡4çš®ã¯è±èªãªã³ãªãŒã¢ãŒãããïŒãéžæå¯èœã§ããæãæ§èœãé«ãããª"large"ã䜿çšããŠ"base"ãšæ¯èŒããŸããã

[IN]
import whisper
path_audio = 'åé³¥ã»ãããSKE48é ç°äºéŠéã«NGçºèšé£çºïŒïŒ åé³¥MCããã£ã³ã¹ã®æé # 129ã-Yx1CqlmLJSs.m4a'
model = whisper.load_model('large')
result = model.transcribe(path_audio)
print(result["text"])
[OUT]
2人ç®ã¯ãã®äººæ°ã¢ã€ãã«ãç»å Žã奜æåºŠãé«ãããããã®ããã«ã倧åŸãå
šãŠã®ãã©ã¹ã¡ã³ãã§èœãšãã«ããããã§ã¯ç¶ããŠã®æ¥œå±æšæ¶å¥œæåºŠèœäžãã£ã¬ã³ãžã§ãããé¡ãããŸããæšæ¶ããããã§ããããã女æ§ã ãã¯ãã倱瀌ããŸãããã¯ããããããŸããé ç°ãããã§ãã倱瀌ããŸãã女æ§ã ããå€ããããããã¯ããããããŸãããã€ãããããšãããããŸãã仿¥ãäžè©±ã«ãªããŸããç¶ããŠãã£ãŠããã®ã¯SKE48é ç°ããããæ¡æäŒã®å¥³çãšãåŒã°ãã圌女ã ããããã«å¯ŸããŠç¥å¯Ÿå¿ã貫ããããSKEã®æ°æ²ãä»ãªãªãŒã¹ãããŠããã§ãåãåã£ãŠããã ããŠãããã§ãã?ããããã©ãæã«ãšã£ãŠèããªãããããããšãããããŸããèããªãããããã§ãããã§ãDVDãå
¥ã£ãŠããã§ãç¹å
žæ åãšããå
å®ããŠããã§ãåã¯ãã£ã±ã人ãæã£ãŠèžã£ãŠããã®ãèããªãããããªãã§ãããã§ãç§ã®ããšèŠã€ããŠãã ããããããã¯ã²ã©ããå€ããã°å€ãã»ã©èããªãããããä»åºŠç§ããœãã§æã£ãŠããã€ãCDæã£ãŠããŸããããããã€ãã€ãã€ãã€ããäœåã絡ãã ã¿ããã«åããããŠããããªãããããã°ãªãã§ããã©ããããã€ãã€ãã€ãã€ããäœåã絡ãã ã¿ããã«åã£ãŠãããªããã€ããäžè©±ã«ãªã£ãŠããããªãã§ããããã°ããé¡èŠãŠãçµæ§ãã€ãããããããã£ãŠãã ãã£ãŠããã¡ããã¡ãæ©ãã«ãæŽåœ¢ãããæŽåœ¢ãããããæŽåœ¢ãããã§ãããäžçªèšãããããªãããã坿ããªããŸããç§ãããããããããŠãªãã§ããæŽåœ¢ãããããŠãªãã§ãããããã©ããå€ãã£ããšæããŸããããã坿ããªã£ããªã£ãŠæã£ãã£ãŠããšã§ããããããªã«é
åçã§ããç§ããããããããããããããå«ã ãäœãã§ãããæ¬åœã«å«ã ãã¡ãã£ãšéæ¢ããµãããŠããã?ãã§ãžã¥ããã§ãžã¥ããã§ãžã¥?ãã§ãžã¥ã10äžã10äž?10äž!ã?10äžä»æ¥æã£ãŠãªãã§ãããããã£ã¡ã®åãããªããã ãããã10äž?ã?ãã£ã¡ã®åãããªããã©ã£ã¡?ããäœã®è©±ãããŠããã§ãããå
šéšå¿ããŠãäœãèšããªããå
šéšå¿ããŠã誰ã«ãèšããªããããããŸããã誰ã«ãèšããªããã¯ããäœãçè§£ããŠãªããã§å€§äžå€«ã§ããçŸåœ¹ã¢ã€ãã«ã«å¯Ÿã倱瀌ãªçºèšãé£çºãããããããããããã«éæ¿ãã¯ãšã¹ã«ã¬ãŒãããŠãããããããããã°ãªãã§ããã©ãç§å
å
çãããããã®ããšãèŸããŠããããªãã§ããããããè¯ãããã£ãŠãç§å
å
çã?ã¯ãããããããããè¯ãããã£ãŠèšã£ãŠããã£ããã£ãŠããã§ãã£ãŠãçŽæ¥èãããã€?çŽæ¥èãããã€?ããã人äŒãã«èããŸããã人äŒãããäžæã¡åºãŸããããäžæã¡ããããåãããªããšæããŸãããåãããã?ç§å
ããã£ãŠããããäŒãããæ©äŒããã£ãã確èªããŠãããŸããããåã®åå€å±ã®ã©ãžãªãèããŠããããã®?2åãããããç§å
ãããåã®åå€å±ã®ã©ãžãªèããŠãã®ã?èããŠãªããšæããŸãããåãããåãããåãããæ¬åœã«ãçµå§ç¬é¡ã ã£ãç æãã€ãã«ãã³åŒãããããŠè©±é¡ã¯çŠæã®Twitter話ã«ãããè¯ãã£ãããªãã§ããã©ããåçæ®ã£ãŠããã ããŠãããã§ãã?SNSã«ããè¯ãã£ããåçæ®ã£ãŠã¢ããããããªã£ãŠæããã§ããã©ãåç?åç?ã¯ããããã§ãã?ãã©ãã¯ãŒæ°ç¥ã£ãŠãã®?ãã©ãã¯ãŒæ°ç¥ã£ãŠã?ã¡ããã¡ãèšããããªã?ã®ã¶ããã§ãã?ãã©ãã¯ãŒæ°ãå€ãã§ãããããŸãããŠããã©ãã¯ãŒæ°ã§ããŠã³ããåãã®ã¶ãããã«ããããåœæ°çã¢ã€ãã«ãçžæã«è¡æçºèšãããªãããããã£ãŠåçæ®ã£ãŠãã£ãŠããããã©ããããªãã®ãããããã¿ãããªããåçã¯?åçå
šç¶æ®ã£ãŠããããã©ãã¯ããããã§ãã?ãããªãã®ããããã?SKEãšãAKBã°ã«ãŒãã§è»œãããªãã€ãã?SKE?ã¯ããSKEãã軜ãããªãã?軜ãã?軜ãããªäººãã?äœéã§ãã?CDèŠãªãããã£ã±ã倧ããããªèŠã€ããããããããã軜ãããªåã倪ãã§ãã?éãéãããã£ã±ã倧ããããã£ã±ããããã£ã±ã倧ãããããããã軜ã?軜ã?ãã®åãŸã 10代ã§ãããé¢ä¿ããã?é¢ä¿ããããããªããªãè¥ãã¡ã³ããŒããããæ³åŸããããé¢ä¿ããããã19代ã10代ããããæ³åŸãããããããæ³åŸããã£ãããã§ãããæè»æ£?17ãšãã17ãããã軜ã?äœãã§ãã?ã»ãã¯ã¹ãã"large"ã¢ãã«ã¯çްããåèªã®ç²ŸåºŠãæåèµ·ããã®èŠãããïŒã«ã¿ã«ãã§ã¯ãªã挢åãæ°å€ãžã®çœ®ãæãïŒã®ç²ŸåºŠãå§åçã«äžãã£ãŠããŸãã

ïŒïŒïŒïŒè©³çްãªåŒæ°ã®èšå®
ããã®ä»èšå®ã§ããããªåŒæ°ã¯äžèšã®ãããªãã®ããããŸãã
[whisper/transcribe.py]ãâ»äžéšæç²
def cli():
from . import available_models
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("audio", nargs="+", type=str, help="audio file(s) to transcribe")
parser.add_argument("--model", default="small", choices=available_models(), help="name of the Whisper model to use")
parser.add_argument("--model_dir", type=str, default=None, help="the path to save model files; uses ~/.cache/whisper by default")
parser.add_argument("--device", default="cuda" if torch.cuda.is_available() else "cpu", help="device to use for PyTorch inference")
parser.add_argument("--output_dir", "-o", type=str, default=".", help="directory to save the outputs")
parser.add_argument("--verbose", type=str2bool, default=True, help="whether to print out the progress and debug messages")
parser.add_argument("--task", type=str, default="transcribe", choices=["transcribe", "translate"], help="whether to perform X->X speech recognition ('transcribe') or X->English translation ('translate')")
parser.add_argument("--language", type=str, default=None, choices=sorted(LANGUAGES.keys()) + sorted([k.title() for k in TO_LANGUAGE_CODE.keys()]), help="language spoken in the audio, specify None to perform language detection")
parser.add_argument("--temperature", type=float, default=0, help="temperature to use for sampling")
parser.add_argument("--best_of", type=optional_int, default=5, help="number of candidates when sampling with non-zero temperature")
parser.add_argument("--beam_size", type=optional_int, default=5, help="number of beams in beam search, only applicable when temperature is zero")
parser.add_argument("--patience", type=float, default=None, help="optional patience value to use in beam decoding, as in https://arxiv.org/abs/2204.05424, the default (1.0) is equivalent to conventional beam search")
parser.add_argument("--length_penalty", type=float, default=None, help="optional token length penalty coefficient (alpha) as in https://arxiv.org/abs/1609.08144, uses simple length normalization by default")
parser.add_argument("--suppress_tokens", type=str, default="-1", help="comma-separated list of token ids to suppress during sampling; '-1' will suppress most special characters except common punctuations")
parser.add_argument("--initial_prompt", type=str, default=None, help="optional text to provide as a prompt for the first window.")
parser.add_argument("--condition_on_previous_text", type=str2bool, default=True, help="if True, provide the previous output of the model as a prompt for the next window; disabling may make the text inconsistent across windows, but the model becomes less prone to getting stuck in a failure loop")
parser.add_argument("--fp16", type=str2bool, default=True, help="whether to perform inference in fp16; True by default")
parser.add_argument("--temperature_increment_on_fallback", type=optional_float, default=0.2, help="temperature to increase when falling back when the decoding fails to meet either of the thresholds below")
parser.add_argument("--compression_ratio_threshold", type=optional_float, default=2.4, help="if the gzip compression ratio is higher than this value, treat the decoding as failed")
parser.add_argument("--logprob_threshold", type=optional_float, default=-1.0, help="if the average log probability is lower than this value, treat the decoding as failed")
parser.add_argument("--no_speech_threshold", type=optional_float, default=0.6, help="if the probability of the <|nospeech|> token is higher than this value AND the decoding has failed due to `logprob_threshold`, consider the segment as silence")
parser.add_argument("--threads", type=optional_int, default=0, help="number of threads used by torch for CPU inference; supercedes MKL_NUM_THREADS/OMP_NUM_THREADS")åèè³æ
åèè³æïŒïŒå®è£ é¢ä¿
åèè³æïŒïŒæè¡é¢ä¿
Whisperã®æ¥æ¬èªfine-tuningã«ã€ããŠãHugging Faceããã°ã«æ²¿ã£ãŠããæ¹æ³ãæžããŸããã
â nokomoro3 (@nokomoro3) November 9, 2022
èªç€ŸããŒã¿ã®æŽ»çšãããã§ã§ããããïŒ#DevelopersIO Hugging Faceã§OpenAIã®é³å£°èªèâWhisperâãFine Tuningããæ¹æ³ãå ¬éãããŸãã https://t.co/lvGGxH3uAn
ãã£ã±ã CPU æšè«ã ãã¯ãã£ãŠ GPU ããã¯é ãã£ãœããã©ãã°ã©ãäŸåãªãã«åãã®ã¯åŒ·ããª
â Torishima (@izutorishima) November 7, 2022
Whisper CPP ã§ C/C++ ã§é³å£°èªèãæ¥µãããã¡ã¢ https://t.co/EKhXdGnB8I #Qiita
ãªãã OpenAI ãåºãã髿§èœé³å£°èªè AI Whisper ã® C++ ç§»æ€çãåºãŠããã ãã©âŠïŒïŒïŒïŒïŒïŒïŒïŒ
â Torishima (@izutorishima) November 7, 2022
è¬ã®æé©åæè¡ã§ CPU ã ãã§ããããé«éã«æåèµ·ããã§ããããã«ãªã£ãŠãããããlarge ã¢ãã«ã§ãæå€§ã§ 4.7GB ã®ã¡ã¢ãªãã䜿ããªããããã®ãé©ç°çéãããé©åœhttps://t.co/ZfGKVDqrWK
ããšãã
ãåãæ¥ãå åºããèªå® PCã®GPU䜿ã£ãŠbaseã¢ãã«ã§å®è¡ãããš1.5minããããããã®ã§CPUã§ã®å®è¡ã¯éçŸå®çããšæãã®ã§èšèŒã¯åãããã