【前編】ChatGPT(OpenAI API)とfaster-Whisperを使ったYouTube文字起こしの精度改善: #足立康史 衆議院議員(@adachiyasushi)の #あだトーク (ゲスト: #一谷勇一郎 衆議院議員(@y_ichitani)・兵庫1区)回を事例に
こんにちは。
障害児福祉(児童発達支援)に携わる文系アラサー社会人です。
技術系記事は初投稿になります。
間違い等あればご指摘くださいませ。
LLMによる文字起こし(出力結果)はこちら
今回使用するデータ
#あだトーク 第24回 少子高齢化社会に必要な改革とは?【ゲスト】#日本維新の会 #一谷勇一郎 衆議院議員 #足立康史 #あだち康史 #あだチャン https://www.youtube.com/live/ik4_jzuD9jI?si=CSLcvzz4Ly9V3_Q4
1、この記事で実現したいこと
・YouTube動画の文字起こしを自動で行う
・API以外、完全無料で実現する
・出力したテキストは、できるだけそのままネットにアップできるレベルの品質にする
・Python(Google Colaboratory)を使用する
なお、個人的AI文字起こし最強ツールのVrewはお金がかかるので断念です。
(APIの方が高くつくし面倒なのですが、この人は何を言ってるんでしょう…しかもgpt-4を使ってますね…)
※本記事では「OpenAI API」並びにそのリクエスト・結果をまとめて「ChatGPT」と表記します。
完成版コード
!pip install -U yt-dlp
!pip install -U faster_whisper
!pip install srt
!pip install langchain
from yt_dlp import YoutubeDL
from moviepy.editor import *
import os
from datetime import timedelta
from srt import Subtitle
import srt
import subprocess
from faster_whisper import WhisperModel
url = 'https://www.youtube.com/watch?v=ik4_jzuD9jI'
ydl_opts = {
'outtmpl' : '%(title)s.mp3',
'format' : 'bestaudio/best'
}
#メタデータ取得
with YoutubeDL(ydl_opts) as ydl:
res = ydl.extract_info(url, download=False)
ydl.download(url)
audio_file_name = res['title'] + ".mp3"
# Whisperのモデル指定
model_size = "large-v2"
# GPU, FP16で実行
model = WhisperModel(model_size, device="cuda", compute_type="float16")
# faster-Whisperの準備
# パラメータ https://qiita.com/reriiasu/items/5ad8e1a7dbc425de7bb0
segments, info = model.transcribe(audio_file_name, beam_size=2, best_of=2, temperature=0, language="ja")
# 文字起こし格納用変数
subs= ""
texts = ""
# 繰り返し処理
for segment in segments:
# 全文文字起こし処理
text = segment.text
texts += text + "\n"
# texts += f"{text[1:] if text[0] is ' ' else text}\n"
# print("普通のはOK")
# srtファイル作成処理
startTime = str(0)+str(timedelta(seconds=int(segment.start)))+',000'
endTime = str(0)+str(timedelta(seconds=int(segment.end)))+',000'
segmentId = segment.id
sub = f"{segmentId}\n{startTime} --> {endTime}\n{text[1:] if text[0] is ' ' else text}\n\n"
subs += sub
print(sub)
# srtファイル書き出し
srt_filename = "【字幕】" + audio_file_name
with open("/content/drive/MyDrive/足立康史/文字起こし/" + srt_filename + ".srt", mode="w", encoding="utf-8") as f:
f.write(subs)
f.close
with open("/content/drive/MyDrive/足立康史/文字起こし/" + srt_filename + ".txt", mode="w", encoding="utf-8") as f:
f.write(texts)
f.c lose
# テキスト分割
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(
separator = "\n",
chunk_size = 1000,
chunk_overlap = 200,
length_function = len,
is_separator_regex = False,
)
# テキストロード
from langchain.document_loaders import TextLoader
loader = TextLoader("/content/drive/MyDrive/足立康史/文字起こし/" + srt_filename + .txt")
documents = loader.load()
print(documents)
document = str(documents[0].page_content)
# print(document)
texts = text_splitter.split_text(document)
# print(texts[0])
# 修正処理
import os
import openai
openai.api_key = "<YOUR_OPENAI_API_KEY>" # ここにAPIキーを入れる
system_message = """
大阪府選出の衆議院議員「足立康史(あだちやすし)」のYouTube配信「あだトーク」の文字起こしです。
下記のブラッシュアップを行います。
step by stepで実行してください。
###制約###
・出力は本文のみ。一切の説明文を禁ずる
・文法構造の変換は禁止。原文を保つこと。
・文体は変えず、原文準拠
・話者名の記載は禁止
・後半に連れてあなたは精度が下がっているため、品質を担保し続けてください
###修正・適正化指示###
・適正語彙一覧に応じた人名の修正 適正語彙:(「足立康史」「一谷勇一郎」「日本維新の会」「一谷さん」「東徹(あずまとおる)」)
・句読点の挿入
・改行の適正化
・段落の挿入:多めに挿入せよ
・「あの」などのフィラーを削除または適正化
・結果を作成後、再度プロンプトに合ってるか再検討
"""
responseText = ""
for text in texts:
response = openai.ChatCompletion.create(
# model="gpt-3.5-turbo",
model="gpt-4",
temperature= 0,
messages=[
{"role": "system", "content": system_message},
{"role": "user", "content": text}
],
)
# print(response.choices[0].message.content)
responseText += response.choices[0].message.content + "\n"
print(responseText)
with open("/content/drive/MyDrive/足立康史/文字起こし/【修正字幕】#あだトーク 第24回 少子高齢化社会に必要な改革とは?【ゲスト】#日本維新の会 #一谷勇一郎 衆議院議員 #足立康史 #あだち康史 #あだチャン.txt", mode="w", encoding="utf-8") as f:
f.write(responseText)
f.close
2、下準備
faster-WhisperでYouTubeを文字起こし
・ゴール:字幕ファイルとテキストファイルの2つを作成
・精度:こちらの記事を参考に、無音区間・反復単語対応を調整
# ライブラリ準備
!pip install -U yt-dlp
!pip install -U faster_whisper
!pip install srt
from yt_dlp import YoutubeDL
from moviepy.editor import *
import os
from datetime import timedelta
from srt import Subtitle
import srt
import subprocess
from faster_whisper import WhisperModel
# ここにYouTube動画のURLを貼り付ける
url = 'https://www.youtube.com/watch?v=ik4_jzuD9jI'
ydl_opts = {
'outtmpl' : '%(title)s.mp3',
'format' : 'bestaudio/best'
}
#メタデータ取得
with YoutubeDL(ydl_opts) as ydl:
res = ydl.extract_info(url, download=False)
ydl.download(url)
audio_file_name = res['title'] + ".mp3"
# Whisperのモデル指定
model_size = "large-v2"
# GPU, FP16で実行
model = WhisperModel(model_size, device="cuda", compute_type="float16")
# faster-Whisperの準備
segments, info = model.transcribe(audio_file_name, beam_size=2, best_of=2, temperature=0, language="ja")
# 文字起こし格納用変数
subs= ""
texts = ""
# 繰り返し処理
for segment in segments:
# 全文文字起こし処理
text = segment.text
texts += text + "\n"
# texts += f"{text[1:] if text[0] is ' ' else text}\n"
# print("普通のはOK")
# srtファイル作成処理
startTime = str(0)+str(timedelta(seconds=int(segment.start)))+',000'
endTime = str(0)+str(timedelta(seconds=int(segment.end)))+',000'
segmentId = segment.id
sub = f"{segmentId}\n{startTime} --> {endTime}\n{text[1:] if text[0] is ' ' else text}\n\n"
subs += sub
print(sub)
# srtファイル書き出し
srt_filename = "【字幕】" + audio_file_name
with open("/content/drive/MyDrive/足立康史/文字起こし/" + srt_filename + ".srt", mode="w", encoding="utf-8") as f:
f.write(subs)
f.close
with open("/content/drive/MyDrive/足立康史/文字起こし/" + srt_filename + ".txt", mode="w", encoding="utf-8") as f:
f.write(texts)
f.close
ここまでで、Google Driveの「足立康史/文字起こし」フォルダ内に、YouTube動画タイトルがついたsrtファイルとtxtファイルが作成されました。
srtファイルの一部部分を見てみましょう。
誤字はやはり見られますが、YouTube公式の字幕よりは格段に高い精度ですね。
3、テキスト修正
このままでも十分素晴らしいのですが、問題があります。
それは、「テキストファイルは、字幕の時間区分によって改行されている」「句読点・段落・改行がない」ということです。
ここでは、テキストをChatGPTが受け取り可能な一定文字数に区切り、テキストを整形してもらいます。
分割数だけレスポンスが、文字数だけトークン消費が発生するので、時間と金額にはご注意ください。
テキスト分割
!pip install langchain
# テキスト分割
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(
separator = "\n",
chunk_size = 1000,
chunk_overlap = 200,
length_function = len,
is_separator_regex = False,
)
# テキストロード
from langchain.document_loaders import TextLoader
loader = TextLoader("/content/drive/MyDrive/足立康史/文字起こし/【字幕】#あだトーク 第24回 少子高齢化社会に必要な改革とは?【ゲスト】#日本維新の会 #一谷勇一郎 衆議院議員 #足立康史 #あだち康史 #あだチャン.mp3.txt")
documents = loader.load()
print(documents)
# 分割テキストを作成
document = str(documents[0].page_content)
texts = text_splitter.split_text(document)
ChatGPTにリクエスト
!pip install openai
import os
import openai
openai.api_key = "api_key" # ここにAPIキーを入れる
当初のプロンプト
system_message = """
大阪府選出の衆議院議員「足立康史」のYouTube配信「あだトーク」の文字起こしです。
下記のブラッシュアップを行います。
・句読点の挿入
・改行の挿入
・段落の挿入
・「あの」などのフィラーを削除または適正化
・出力は本文のみ。一切の説明文を禁ずる
・文法構造の変換は禁止。原文を保つこと。
"""
メイン
# レスポンスごとの修正文字起こし格納変数
responseText = ""
for text in texts:
text = text.page_content
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
temperature= 0,
messages=[
{"role": "system", "content": system_message},
{"role": "user", "content": text}
],
)
responseText += response.choices[0].message.content
print(responseText)
出力結果
4、改善点
・「あの」「その」などのフィラーが目立つ
・固有名詞(人名等)は修正可能みがある
・noteに貼り付けるには、もう少し改行・段落が多い方がベター
・話者がわかるとよい
修正プロンプト
system_message = """
大阪府選出の衆議院議員「足立康史(あだちやすし)」のYouTube配信「あだトーク」の文字起こしです。
下記のブラッシュアップを行います。
# step by stepで実行してください。
###修正指示###
・人名の修正(適正語彙;「足立康史」「一谷勇一郎」「東徹(あずまとおる・参議院議員)」)
・句読点の挿入
・改行の適正化
・段落の挿入:多めに挿入せよ
・「あの」などのフィラーを削除または適正化
・段落の冒頭、話者を(足立:)(一谷:)と表示
・結果を作成後、再度プロンプトに合ってるか再検討
###制約###
・出力は本文のみ。一切の説明文を禁ずる
・文法構造の変換は禁止。原文を保つこと。
"""
出力
話者分割は非常に不満が残りますが、段落挿入はまっとうですね。
今回は話者分割をあきらめ、さらにmodelをgpt-4に変更して実行してみます。出力結果がこちらです。
東さんのお弟子さんが足立さんになってしまいましたね。
さらに修正すると、お二人がとても標準語ユーザーになってしまいました。
system_message = """
大阪府選出の衆議院議員「足立康史(あだちやすし)」のYouTube配信「あだトーク」の文字起こしです。
下記のブラッシュアップを行います。
step by stepで実行してください。
###修正指示###
・市谷さんではなく「一谷勇一郎」さんです
・「市谷」を「一谷」に置換せよ
・人名の修正(適正語彙;「足立康史」「一谷勇一郎」「一谷さん」「東徹(あずまとおる)」)
・句読点の挿入:文末では必ず改行せよ
・改行の適正化
・段落の挿入:多めに挿入せよ
・「あの」などのフィラーを削除または適正化
・結果を作成後、再度プロンプトに合ってるか再検討
・冒頭に話者名は付けない
###制約###
・出力は本文のみ。一切の説明文を禁ずる
・文法構造の変換は禁止。原文を保つこと。
・後半に連れてあなたは精度が下がっているため、品質を担保し続けてください
"""
これはこれで、書きことばとしてはきれいなんですがね。
しかも、リクエストごとに出力形式が変わるのは仕方ないとしましょう。
後編(出力結果)をお楽しみに。