Whisper - poprawiam skrypt

Korzystam z programu Whisper już półtora miesiąca i od momentu zastosowania RTX3060 bardzo sobie to chwalę. Jako programista i zwolennik pisania skryptów w Pythonie, wolę właśnie surową instalację Whispera zamiast okienkowej nakładki, Speech Translate. Jednak sprawiedliwie trzeba przyznać, że Speech Translate ma w pewnej istotnej kwestii przewagę - potrafi tworzyć pliki srt z napisami. Na szczęście użytkownicy Whispera nie stoją na straconej pozycji, do czego wrócę za chwilę, bo najpierw na rozwiązanie czeka inny problem.

Pasek postępu

Ze względu na to, że transkrypcja swoje trwa, bardzo brakowało mi informacji, ile czasu zajmie przetwarzanie danego pliku dźwiękowego. Domyślny, najprostszy skrypt, który podawałem w pierwszym poście, wyglądał dla przypomnienia tak:

import whisper;

model = whisper.load_model("base")
result = model.transcribe("f:\\podcast_010049.mp3")
print(result["text"])

Skrypt ten, przerobiony na model large (zamiast base) i wykonywany w środowisku z wspierającą przetwarzanie kartą graficzną wygląda tak:

import whisper;

model = whisper.load_model("large", "cuda")
result = model.transcribe("f:\\podcast_010049.mp3")
print(result["text"])

Aby wyświetlić pasek postępu przetwarzania, należy do parametrów metody transcribe dodać ustawiony na False parametr verbose, a przy okazji można też dodać parametr language, aby Whisper nie musiał sam analizować i rozpoznawać języka:

import whisper;

model = whisper.load_model("large", "cuda")
result = model.transcribe("f:\\podcast_010049.mp3", verbose=False, language="Polish")
print(result["text"])

W efekcie tej zmiany, po uruchomieniu przetwarzania zobaczymy tekstowy pasek postępu, informujący na bieżąco, na jakim etapie znajduje się transkrypcja:

Napisy

Cóż jednak zrobić z napisami? Czy trzeba jakoś przetworzyć wynik, pobierany i wyświetlany za pomocą linii:

print(result["text"])

Okazuje się, że nie jest tak źle. Wystarczy odpowiednio przetworzyć dane, które są także zawarte w mapie result, ale pod kluczem segments:

content = ''
for segment in result["segments"]:
	startTime = str(0) + str(datetime.timedelta(seconds=int(segment['start']))) + ',000'
	endTime = str(0) + str(datetime.timedelta(seconds=int(segment['end']))) + ',000'
	text = segment['text']
	segmentId = segment['id'] + 1
	line = f"{segmentId}\n{startTime} --> {endTime}\n{text[1:] if text[0] == ' ' else text}\n\n"
	content = content + line

Aby to zadziałało, trzeba, rzecz jasna, dodać do sekcji import moduł datetime.

Powyższy kod przejrzy wyniki i wygeneruje na ich podstawie dane zgodne z formatem srt - wystarczy zapisać je do pliku.

Żeby było łatwiej

Sam od mniej więcej dwóch tygodni posługuję się skryptem singlewhisper.py, który jest stosunkowo prosty w obsłudze. Wystarczy wywołać go w linii poleceń:

python singlewhisper.py c:\jakas\sciezka\do\pliku.mp3

Oczywiście, warto wyedytować sobie ten plik, zmienić np. model large na medium czy small, jeśli zależy nam na przyspieszeniu pracy Whispera kosztem dokładności transkrypcji. Także parametr cuda można zamienić na cpu, jeśli nie dysponujemy odpowiednią kartą graficzną.

Myślę, że nawet początkujący programiści Pythona będą w stanie przerobić skrypt tak, by przetworzył wszystkie pliki dźwiękowe z zadanego katalogu - można wtedy zostawić komputer na noc, by wykonał transkrypcje dokumentów, nie utrudniając nam pracy.

Komentarze