Cara menggunakan OpenAis Whisper untuk menyalin dan membuat film audio membuat film audio
Whisper adalah sistem pengenalan ucapan canggih dari OpenAI yang telah dilatih pada 680.000 jam data yang diawasi multibahasa dan multibuual yang dikumpulkan dari web. Dataset besar dan beragam ini mengarah pada peningkatan ketahanan terhadap aksen, kebisingan latar belakang, dan bahasa teknis. Selain itu, ini memungkinkan transkripsi dalam berbagai bahasa, serta terjemahan dari bahasa -bahasa tersebut ke dalam bahasa Inggris. OpenAI merilis model dan kode untuk berfungsi sebagai fondasi untuk membangun aplikasi yang berguna yang memanfaatkan pengenalan suara.
Salah satu kerugian besar dari Whisper adalah, bahwa itu tidak bisa memberi tahu Anda siapa yang berbicara dalam percakapan. Itu masalah saat menganalisis percakapan. Di sinilah Diarization masuk. Diarization adalah proses mengidentifikasi siapa yang berbicara dalam percakapan.
Dalam tutorial ini Anda akan belajar bagaimana mengidentifikasi speaker, dan kemudian mencocokkannya dengan transkripsi Whisper. Kami akan menggunakan pyannote-audio
untuk mencapai ini. Mari kita mulai!
Pertama, kita perlu menyiapkan file audio. Kami akan menggunakan 20 menit pertama podcast Lex Fridmans dengan unduhan Yann. Untuk mengunduh video dan mengekstrak audio, kami akan menggunakan paket yt-dlp
.
! pip install -U yt-dlp
Kami juga perlu diinstal FFMPEG
! wget -O - -q https://github.com/yt-dlp/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz | xz -qdc | tar -x
Sekarang kita dapat melakukan ekstraksi unduhan dan audio yang sebenarnya melalui baris perintah.
! yt-dlp -xv --ffmpeg-location ffmpeg-master-latest-linux64-gpl/bin --audio-format wav -o download.wav -- https://youtu.be/SGzMElJ11Cc
Sekarang kami memiliki file download.wav
di direktori kerja kami. Mari kita potong 20 menit pertama audio. Kita dapat menggunakan paket pydub untuk ini hanya dengan beberapa baris kode.
! pip install pydub
from pydub import AudioSegment
t1 = 0 * 1000 # works in milliseconds
t2 = 20 * 60 * 1000
newAudio = AudioSegment . from_wav ( "download.wav" )
a = newAudio [ t1 : t2 ]
a . export ( "audio.wav" , format = "wav" )
audio.wav
sekarang adalah 20 menit pertama dari file audio.
pyannote.audio
adalah alat open-source yang ditulis dalam Python untuk Diarization Speaker. Berdasarkan kerangka pembelajaran mesin Pytorch, ini menyediakan serangkaian blok bangunan saraf end-to-end yang dapat dilatih yang dapat digabungkan dan dioptimalkan bersama untuk membangun pipa diarization speaker. pyannote.audio
juga dilengkapi dengan model dan jaringan pipa yang sudah pretrain yang mencakup berbagai domain untuk deteksi aktivitas suara, segmentasi speaker, deteksi bicara yang tumpang tindih, penyematan pembicara mencapai kinerja canggih untuk sebagian besar dari mereka.
Menginstal Pyannote dan menjalankannya pada audio video untuk menghasilkan diarizations.
! pip install pyannote.audio
from pyannote . audio import Pipeline
pipeline = Pipeline . from_pretrained ( 'pyannote/speaker-diarization' )
DEMO_FILE = { 'uri' : 'blabal' , 'audio' : 'audio.wav' }
dz = pipeline ( DEMO_FILE )
with open ( "diarization.txt" , "w" ) as text_file :
text_file . write ( str ( dz ))
Mari kita cetak ini untuk melihat seperti apa rasanya.
print(*list(dz.itertracks(yield_label = True))[:10], sep="n")
Output:
(<Segment(2.03344, 36.8128)>, 0, 'SPEAKER_00')
(<Segment(38.1122, 51.3759)>, 0, 'SPEAKER_00')
(<Segment(51.8653, 90.2053)>, 1, 'SPEAKER_01')
(<Segment(91.2853, 92.9391)>, 1, 'SPEAKER_01')
(<Segment(94.8628, 116.497)>, 0, 'SPEAKER_00')
(<Segment(116.497, 124.124)>, 1, 'SPEAKER_01')
(<Segment(124.192, 151.597)>, 1, 'SPEAKER_01')
(<Segment(152.018, 179.12)>, 1, 'SPEAKER_01')
(<Segment(180.318, 194.037)>, 1, 'SPEAKER_01')
(<Segment(195.016, 207.385)>, 0, 'SPEAKER_00')
Ini sudah terlihat cukup bagus, tapi mari kita bersihkan data sedikit:
def millisec ( timeStr ):
spl = timeStr . split ( ":" )
s = ( int )(( int ( spl [ 0 ]) * 60 * 60 + int ( spl [ 1 ]) * 60 + float ( spl [ 2 ]) ) * 1000 )
return s
import re
dz = open ( 'diarization.txt' ). read (). splitlines ()
dzList = []
for l in dz :
start , end = tuple ( re . findall ( '[0-9]+:[0-9]+:[0-9]+.[0-9]+' , string = l ))
start = millisec ( start ) - spacermilli
end = millisec ( end ) - spacermilli
lex = not re . findall ( 'SPEAKER_01' , string = l )
dzList . append ([ start , end , lex ])
print ( * dzList [: 10 ], sep = ' n ' )
[33, 34812, True]
[36112, 49375, True]
[49865, 88205, False]
[89285, 90939, False]
[92862, 114496, True]
[114496, 122124, False]
[122191, 149596, False]
[150018, 177119, False]
[178317, 192037, False]
[193015, 205385, True]
Sekarang kami memiliki data diarisasi dalam daftar. Dua angka pertama adalah waktu awal dan akhir dari segmen pembicara dalam milidetik. Angka ketiga adalah boolean yang memberi tahu kita apakah pembicara adalah Lex atau tidak.
Selanjutnya, kami akan melampirkan segmen audio sesuai dengan diarisasi, dengan spacer sebagai pembatas.
from pydub import AudioSegment
import re
sounds = spacer
segments = []
dz = open ( 'diarization.txt' ). read (). splitlines ()
for l in dz :
start , end = tuple ( re . findall ( '[0-9]+:[0-9]+:[0-9]+.[0-9]+' , string = l ))
start = int ( millisec ( start )) #milliseconds
end = int ( millisec ( end )) #milliseconds
segments . append ( len ( sounds ))
sounds = sounds . append ( audio [ start : end ], crossfade = 0 )
sounds = sounds . append ( spacer , crossfade = 0 )
sounds . export ( "dz.wav" , format = "wav" ) #Exports to a wav file in the current path.
print ( segments [: 8 ])
[2000, 38779, 54042, 94382, 98036, 121670, 131297, 160702]
Selanjutnya, kami akan menggunakan Whisper untuk menuliskan berbagai segmen file audio. PENTING: Ada konflik versi dengan pyannote.Audio yang mengakibatkan kesalahan. Solusi kami adalah pertama -tama menjalankan Pyannote dan kemudian berbisik. Anda dapat mengabaikan kesalahan dengan aman.
Menginstal AI Whisper Open.
! pip install git+https://github.com/openai/whisper.git
Menjalankan Buka AI Whisper pada file audio yang disiapkan. Itu menulis transkripsi ke dalam file. Anda dapat menyesuaikan ukuran model dengan kebutuhan Anda. Anda dapat menemukan semua model pada kartu model di GitHub.
! whisper dz.wav --language en --model base
[00:00.000 --> 00:04.720] The following is a conversation with Yann LeCun,
[00:04.720 --> 00:06.560] his second time on the podcast.
[00:06.560 --> 00:11.160] He is the chief AI scientist at Meta, formerly Facebook,
[00:11.160 --> 00:15.040] professor at NYU, touring award winner,
[00:15.040 --> 00:17.600] one of the seminal figures in the history
[00:17.600 --> 00:20.460] of machine learning and artificial intelligence,
...
Untuk bekerja dengan file .vtt, kita perlu menginstal pustaka webvtt-py.
! pip install -U webvtt-py
Mari kita lihat data:
import webvtt
captions = [[( int )( millisec ( caption . start )), ( int )( millisec ( caption . end )), caption . text ] for caption in webvtt . read ( 'dz.wav.vtt' )]
print ( * captions [: 8 ], sep = ' n ' )
[0, 4720, 'The following is a conversation with Yann LeCun,']
[4720, 6560, 'his second time on the podcast.']
[6560, 11160, 'He is the chief AI scientist at Meta, formerly Facebook,']
[11160, 15040, 'professor at NYU, touring award winner,']
[15040, 17600, 'one of the seminal figures in the history']
[17600, 20460, 'of machine learning and artificial intelligence,']
[20460, 23940, 'and someone who is brilliant and opinionated']
[23940, 25400, 'in the best kind of way,']
...
Selanjutnya, kami akan mencocokkan setiap baris transkripsi dengan beberapa diarizasi, dan menampilkan semuanya dengan menghasilkan file HTML. Untuk mendapatkan waktu yang tepat, kita harus merawat bagian -bagian dalam audio asli yang tidak ada diarization segmen. Kami menambahkan div baru untuk setiap segmen di audio kami.
# we need this fore our HTML file (basicly just some styling)
preS = '<!DOCTYPE html>n<html lang="en">n <head>n <meta charset="UTF-8">n <meta name="viewport" content="width=device-width, initial-scale=1.0">n <meta http-equiv="X-UA-Compatible" content="ie=edge">n <title>Lexicap</title>n <style>n body {n font-family: sans-serif;n font-size: 18px;n color: #111;n padding: 0 0 1em 0;n }n .l {n color: #050;n }n .s {n display: inline-block;n }n .e {n display: inline-block;n }n .t {n display: inline-block;n }n #player {nttposition: sticky;ntttop: 20px;nttfloat: right;nt}n </style>n </head>n <body>n <h2>Yann LeCun: Dark Matter of Intelligence and Self-Supervised Learning | Lex Fridman Podcast #258</h2>n <div id="player"></div>n <script>n var tag = document.createElement('script');n tag.src = "https://www.youtube.com/iframe_api";n var firstScriptTag = document.getElementsByTagName('script')[0];n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);n var player;n function onYouTubeIframeAPIReady() {n player = new YT.Player('player', {n height: '210',n width: '340',n videoId: 'SGzMElJ11Cc',n });n }n function setCurrentTime(timepoint) {n player.seekTo(timepoint);n player.playVideo();n }n </script><br>n'
postS = 't</body>n</html>'
from datetime import timedelta
html = list(preS)
for i in range(len(segments)):
idx = 0
for idx in range(len(captions)):
if captions[idx][0] >= (segments[i] - spacermilli):
break;
while (idx < (len(captions))) and ((i == len(segments) - 1) or (captions[idx][1] < segments[i+1])):
c = captions[idx]
start = dzList[i][0] + (c[0] -segments[i])
if start < 0:
start = 0
idx += 1
start = start / 1000.0
startStr = '{0:02d}:{1:02d}:{2:02.2f}'.format((int)(start // 3600),
(int)(start % 3600 // 60),
start % 60)
html.append('ttt<div class="c">n')
html.append(f'tttt<a class="l" href="#{startStr}" id="{startStr}">link</a> |n')
html.append(f'tttt<div class="s"><a href="javascript:void(0);" onclick=setCurrentTime({int(start)})>{startStr}</a></div>n')
html.append(f'tttt<div class="t">{"[Lex]" if dzList[i][2] else "[Yann]"} {c[2]}</div>n')
html.append('ttt</div>nn')
html.append(postS)
s = "".join(html)
with open("lexicap.html", "w") as text_file:
text_file.write(s)
print(s)
Di Lablab Discord, kami membahas repo ini dan banyak topik lain yang terkait dengan kecerdasan buatan! Periksa acara hackathons intelijen buatan yang akan datang