Ryskt öppet tal till text
En samling talprov från olika ljudkällor. Datamängden innehåller korta ljudklipp på ryska.
Kommentar
Microsoft tillhandahåller Azure Open Datasets i befintligt fall. Microsoft ger inga garantier, uttryckliga eller underförstådda garantier eller villkor för din användning av datauppsättningarna. I den utsträckning som tillåts enligt din lokala lag frånsäger sig Microsoft allt ansvar för eventuella skador eller förluster, inklusive direkt, följdriktig, särskild, indirekt, tillfällig eller straffbar, till följd av din användning av datauppsättningarna.
Datamängden tillhandahålls enligt de ursprungliga villkor som gällde när Microsoft tog emot källdatan. Datamängden kan innehålla data från Microsoft.
Den här datauppsättningen för ryskt tal till text (STT) innehåller:
- ~16 miljoner yttranden
- ~20 000 timmar
- 2,3 TB (okomprimerad i .wav format i int16), 356 G i opus
- Alla filer omvandlades till opus, förutom valideringsdatauppsättningar
Huvudsyftet med datamängden är att träna tal-till-text-modeller.
Sammansättning av datamängd
Datamängdens storlek anges för .wav filer.
DATAMÄNGD | UTTALANDEN | TIMMAR | GB | SECS/CHARS | COMMENT | ANTECKNING | KVALITET/BRUS |
---|---|---|---|---|---|---|---|
radio_v4 (*) | 7 603 192 | 10 430 | 1 195 | 5 sek/68 | Radio | Justera | 95 %/tydligt |
public_speech (*) | 1 700 060 | 2 709 | 301 | 6 sek/79 | Offentligt tal | Justera | 95 %/tydligt |
audiobook_2 | 1 149 404 | 1 511 | 162 | 5 sek/56 | Böcker | Justera | 95 %/tydligt |
radio_2 | 651 645 | 1 439 | 154 | 8 sek/110 | Radio | Justera | 95 %/tydligt |
public_youtube1120 | 1 410 979 | 1 104 | 237 | 3 sek/34 | YouTube | Underrubriker | 95 %/~tydligt |
public_youtube700 | 759 483 | 701 | 75 | 3 sek/43 | YouTube | Underrubriker | 95 %/~tydligt |
tts_russian_addresses | 1 741 838 | 754 | 81 | 2 sek/20 | Adresser | TTS 4-röster | 100 %/tydligt |
asr_public_phone_calls_2 | 603 797 | 601 | 66 | 4 sek/37 | Telefonsamtal | ASR | 70 %/otydligt |
public_youtube1120_hq | 369 245 | 291 | 31 | 3 sek/37 | YouTube HQ | Underrubriker | 95 %/~tydligt |
asr_public_phone_calls_1 | 233 868 | 211 | 23 | 3 sek/29 | Telefonsamtal | ASR | 70 %/otydligt |
radio_v4_add (*) | 92 679 | 157 | 18 | 6 sek/80 | Radio | Justera | 95 %/tydligt |
asr_public_stories_2 | 78 186 | 78 | 9 | 4 sek/43 | Böcker | ASR | 80 %/tydligt |
asr_public_stories_1 | 46 142 | 38 | 4 | 3 sek/30 | Böcker | ASR | 80 %/tydligt |
public_series_1 | 20 243 | 17 | 2 | 3 sek/38 | YouTube | Underrubriker | 95 %/~tydligt |
asr_calls_2_val | 12 950 | 7,7 | 2 | 2 sek/34 | Telefonsamtal | Manuell anteckning | 99 %/tydligt |
public_lecture_1 | 6 803 | 6 | 1 | 3 sek/47 | Föreläsningar | Underrubriker | 95 %/tydligt |
buriy_audiobooks_2_val | 7 850 | 4,9 | 1 | 2 sek/31 | Böcker | Manuell anteckning | 99 %/tydligt |
public_youtube700_val | 7 311 | 4,5 | 1 | 2 sek/35 | YouTube | Manuell anteckning | 99 %/tydligt |
(*) Endast ett dataexempel medföljer txt-filerna.
Anteckningsmetod
Datamängden kompileras med öppna källkoder. Långa sekvenser delas upp i ljudsegment med hjälp av identifiering och justering av röstaktivitet. Vissa ljudtyper kommenteras automatiskt och verifieras statistiskt med hjälp av heuristik.
Datavolymer och uppdateringsfrekvens
Datamängdens totala storlek är 350 GB. Den totala storleken på datamängden med offentligt delade etiketter är 130 GB.
Själva datauppsättningen kommer sannolikt inte att uppdateras för bakåtkompatibilitet. Följ den ursprungliga lagringsplatsen för benchmarks och exkludera filer.
Nya domäner och språk kan komma att läggas till i framtiden.
Ljudnormalisering
Alla filer normaliseras för enklare och snabbare körningsförstoringar. Bearbetningen är följande:
- Konverteras till mono, om det behövs,
- Konverterad till 16 kHz samplingsfrekvens, om det behövs;
- Lagras som 16-bitars heltal,
- Konverteras till OPUS,
Databasmetod på disk
Alla ljudfiler (wav, binära) hashkodas. Hashen används för att skapa en mapphierarki för en mer optimal fs-åtgärd.
target_format = 'wav'
wavb = wav.tobytes()
f_hash = hashlib.sha1(wavb).hexdigest()
store_path = Path(root_folder,
f_hash[0],
f_hash[1:3],
f_hash[3:15] + '.' + target_format)
Nedladdningar
Datauppsättningen tillhandahålls i två former:
- Arkiv som är tillgängliga via Azure Blob Storage och/eller direktlänkar;
- Ursprungliga filer som är tillgängliga via Azure Blob Storage; Allt lagras ihttps://azureopendatastorage.blob.core.windows.net/openstt/
Mappstruktur:
└── ru_open_stt_opus <= archived folders
│ │
│ ├── archives
│ │ ├── asr_calls_2_val.tar.gz <= tar.gz archives with opus and wav files
│ │ │ ... <= see the below table for enumeration
│ │ └── tts_russian_addresses_rhvoice_4voices.tar.gz
│ │
│ └── manifests
│ ├── asr_calls_2_val.csv <= csv files with wav_path, text_path, duration (see notebooks)
│ │ ...
│ └── tts_russian_addresses_rhvoice_4voices.csv
│
└── ru_open_stt_opus_unpacked <= a separate folder for each uploaded domain
├── public_youtube1120
│ ├── 0 <= see "On disk DB methodology" for details
│ ├── 1
│ │ ├── 00
│ │ │ ...
│ │ └── ff
│ │ ├── *.opus <= actual files
│ │ └── *.txt
│ │ ...
│ └── f
│
├── public_youtube1120_hq
├── public_youtube700_val
├── asr_calls_2_val
├── radio_2
├── private_buriy_audiobooks_2
├── asr_public_phone_calls_2
├── asr_public_stories_2
├── asr_public_stories_1
├── public_lecture_1
├── asr_public_phone_calls_1
├── public_series_1
└── public_youtube700
DATAMÄNGD | GB, WAV | GB, ARKIV | ARKIV | KÄLLA | MANIFEST |
---|---|---|---|---|---|
Utbilda | |||||
Exempel på radio och offentligt tal | - | 11,4 | opus+txt | - | manifest |
audiobook_2 | 162 | 25,8 | opus+txt | Internet + justering | manifest |
radio_2 | 154 | 24,6 | opus+txt | Radio | manifest |
public_youtube1120 | 237 | 19,0 | opus+txt | YouTube-videor | manifest |
asr_public_phone_calls_2 | 66 | 9,4 | opus+txt | Internet + ASR | manifest |
public_youtube1120_hq | 31 | 4,9 | opus+txt | YouTube-videor | manifest |
asr_public_stories_2 | 9 | 1.4 | opus+txt | Internet + justering | manifest |
tts_russian_addresses_rhvoice_4voices | 80,9 | 12,9 | opus+txt | TTS | manifest |
public_youtube700 | 75,0 | 12,2 | opus+txt | YouTube-videor | manifest |
asr_public_phone_calls_1 | 22,7 | 3.2 | opus+txt | Internet + ASR | manifest |
asr_public_stories_1 | 4.1 | 0,7 | opus+txt | Offentliga artiklar | manifest |
public_series_1 | 1,9 | 0,3 | opus+txt | Offentliga serier | manifest |
public_lecture_1 | 0,7 | 0,1 | opus+txt | Internet + handbok | manifest |
Val | |||||
asr_calls_2_val | 2 | 0,8 | wav+txt | Internet | manifest |
buriy_audiobooks_2_val | 1 | 0,5 | wav+txt | Böcker + handbok | manifest |
public_youtube700_val | 2 | 0,13 | wav+txt | YouTube-video + handbok | manifest |
Nedladdningsanvisningar
Direkt nedladdning
Anvisningar om hur du laddar ned datauppsättningen direkt finns på sidan med instruktioner för GitHub-nedladdning.
Ytterligare information
Om du vill ha hjälp eller frågor om data kontaktar du dataförfattaren på aveysov@gmail.com
Den här licensen gör det möjligt för användare att distribuera, remixa, anpassa och bygga vidare på materialet i alla medier eller format endast för icke-kommersiella ändamål, och endast så länge som tillskrivning ges till skaparen. Den omfattar följande delar:
- BY – Kredit måste ges till skaparen
- NC – Endast icke-kommersiell användning av arbetet tillåts
CC-BY-NC och kommersiell användning är tillgänglig enligt avtal med datamängdens författare.
Dataåtkomst
Azure Notebooks
Hjälpfunktioner/beroenden
Skapa libsndfile
Ett effektivt sätt att läsa opus-filer i Python som inte medför betydande omkostnader är att använda pysoundfile (en Python CFFI-omslutning runt libsoundfile).
Opus-stöd har implementerats uppströms, men det har inte släppts korrekt. Därför valde vi anpassad build + apkorrigering.
Vanligtvis måste du köra detta i gränssnittet med sudo-åtkomst:
apt-get update
apt-get install cmake autoconf autogen automake build-essential libasound2-dev \
libflac-dev libogg-dev libtool libvorbis-dev libopus-dev pkg-config -y
cd /usr/local/lib
git clone https://github.com/erikd/libsndfile.git
cd libsndfile
git reset --hard 49b7d61
mkdir -p build && cd build
cmake .. -DBUILD_SHARED_LIBS=ON
make && make install
cmake --build .
Hjälpfunktioner/beroenden
Installera följande bibliotek:
pandas
numpy
scipy
tqdm
soundfile
librosa
Manifest är csv-filer med följande kolumner:
- Sökväg till ljud
- Sökväg till textfil
- Varaktighet
De visade sig vara det enklaste formatet för att komma åt data.
För enkel användning är alla manifest redan återrotade. Alla sökvägar i dem är relativa. Du måste ange en rotmapp.
# manifest utils
import os
import numpy as np
import pandas as pd
from tqdm import tqdm
from urllib.request import urlopen
def reroot_manifest(manifest_df,
source_path,
target_path):
if source_path != '':
manifest_df.wav_path = manifest_df.wav_path.apply(lambda x: x.replace(source_path,
target_path))
manifest_df.text_path = manifest_df.text_path.apply(lambda x: x.replace(source_path,
target_path))
else:
manifest_df.wav_path = manifest_df.wav_path.apply(lambda x: os.path.join(target_path, x))
manifest_df.text_path = manifest_df.text_path.apply(lambda x: os.path.join(target_path, x))
return manifest_df
def save_manifest(manifest_df,
path,
domain=False):
if domain:
assert list(manifest_df.columns) == ['wav_path', 'text_path', 'duration', 'domain']
else:
assert list(manifest_df.columns) == ['wav_path', 'text_path', 'duration']
manifest_df.reset_index(drop=True).sort_values(by='duration',
ascending=True).to_csv(path,
sep=',',
header=False,
index=False)
return True
def read_manifest(manifest_path,
domain=False):
if domain:
return pd.read_csv(manifest_path,
names=['wav_path',
'text_path',
'duration',
'domain'])
else:
return pd.read_csv(manifest_path,
names=['wav_path',
'text_path',
'duration'])
def check_files(manifest_df,
domain=False):
orig_len = len(manifest_df)
if domain:
assert list(manifest_df.columns) == ['wav_path', 'text_path', 'duration']
else:
assert list(manifest_df.columns) == ['wav_path', 'text_path', 'duration', 'domain']
wav_paths = list(manifest_df.wav_path.values)
text_path = list(manifest_df.text_path.values)
omitted_wavs = []
omitted_txts = []
for wav_path, text_path in zip(wav_paths, text_path):
if not os.path.exists(wav_path):
print('Dropping {}'.format(wav_path))
omitted_wavs.append(wav_path)
if not os.path.exists(text_path):
print('Dropping {}'.format(text_path))
omitted_txts.append(text_path)
manifest_df = manifest_df[~manifest_df.wav_path.isin(omitted_wavs)]
manifest_df = manifest_df[~manifest_df.text_path.isin(omitted_txts)]
final_len = len(manifest_df)
if final_len != orig_len:
print('Removed {} lines'.format(orig_len-final_len))
return manifest_df
def plain_merge_manifests(manifest_paths,
MIN_DURATION=0.1,
MAX_DURATION=100):
manifest_df = pd.concat([read_manifest(_)
for _ in manifest_paths])
manifest_df = check_files(manifest_df)
manifest_df_fit = manifest_df[(manifest_df.duration>=MIN_DURATION) &
(manifest_df.duration<=MAX_DURATION)]
manifest_df_non_fit = manifest_df[(manifest_df.duration<MIN_DURATION) |
(manifest_df.duration>MAX_DURATION)]
print(f'Good hours: {manifest_df_fit.duration.sum() / 3600:.2f}')
print(f'Bad hours: {manifest_df_non_fit.duration.sum() / 3600:.2f}')
return manifest_df_fit
def save_txt_file(wav_path, text):
txt_path = wav_path.replace('.wav','.txt')
with open(txt_path, "w") as text_file:
print(text, file=text_file)
return txt_path
def read_txt_file(text_path):
#with open(text_path, 'r') as file:
response = urlopen(text_path)
file = response.readlines()
for i in range(len(file)):
file[i] = file[i].decode('utf8')
return file
def create_manifest_from_df(df, domain=False):
if domain:
columns = ['wav_path', 'text_path', 'duration', 'domain']
else:
columns = ['wav_path', 'text_path', 'duration']
manifest = df[columns]
return manifest
def create_txt_files(manifest_df):
assert 'text' in manifest_df.columns
assert 'wav_path' in manifest_df.columns
wav_paths, texts = list(manifest_df['wav_path'].values), list(manifest_df['text'].values)
# not using multiprocessing for simplicity
txt_paths = [save_txt_file(*_) for _ in tqdm(zip(wav_paths, texts), total=len(wav_paths))]
manifest_df['text_path'] = txt_paths
return manifest_df
def replace_encoded(text):
text = text.lower()
if '2' in text:
text = list(text)
_text = []
for i,char in enumerate(text):
if char=='2':
try:
_text.extend([_text[-1]])
except:
print(''.join(text))
else:
_text.extend([char])
text = ''.join(_text)
return text
# reading opus files
import os
import soundfile as sf
# Fx for soundfile read/write functions
def fx_seek(self, frames, whence=os.SEEK_SET):
self._check_if_closed()
position = sf._snd.sf_seek(self._file, frames, whence)
return position
def fx_get_format_from_filename(file, mode):
format = ''
file = getattr(file, 'name', file)
try:
format = os.path.splitext(file)[-1][1:]
format = format.decode('utf-8', 'replace')
except Exception:
pass
if format == 'opus':
return 'OGG'
if format.upper() not in sf._formats and 'r' not in mode:
raise TypeError("No format specified and unable to get format from "
"file extension: {0!r}".format(file))
return format
#sf._snd = sf._ffi.dlopen('/usr/local/lib/libsndfile/build/libsndfile.so.1.0.29')
sf._subtypes['OPUS'] = 0x0064
sf.SoundFile.seek = fx_seek
sf._get_format_from_filename = fx_get_format_from_filename
def read(file, **kwargs):
return sf.read(file, **kwargs)
def write(file, data, samplerate, **kwargs):
return sf.write(file, data, samplerate, **kwargs)
# display utils
import gc
from IPython.display import HTML, Audio, display_html
pd.set_option('display.max_colwidth', 3000)
#Prepend_path is set to read directly from Azure. To read from local replace below string with path to the downloaded dataset files
prepend_path = 'https://azureopendatastorage.blob.core.windows.net/openstt/ru_open_stt_opus_unpacked/'
def audio_player(audio_path):
return '<audio preload="none" controls="controls"><source src="{}" type="audio/wav"></audio>'.format(audio_path)
def display_manifest(manifest_df):
display_df = manifest_df
display_df['wav'] = [audio_player(prepend_path+path) for path in display_df.wav_path]
display_df['txt'] = [read_txt_file(prepend_path+path) for path in tqdm(display_df.text_path)]
audio_style = '<style>audio {height:44px;border:0;padding:0 20px 0px;margin:-10px -20px -20px;}</style>'
display_df = display_df[['wav','txt', 'duration']]
display(HTML(audio_style + display_df.to_html(escape=False)))
del display_df
gc.collect()
Spela upp med en datauppsättning
Spela upp ett exempel på filer
De flesta plattformar har stöd för inbyggd ljuduppspelning. Så vi kan använda HTML5-ljudspelare för att visa våra data.
manifest_df = read_manifest(prepend_path +'/manifests/public_series_1.csv')
#manifest_df = reroot_manifest(manifest_df,
#source_path='',
#target_path='../../../../../nvme/stt/data/ru_open_stt/')
sample = manifest_df.sample(n=20)
display_manifest(sample)
Läs en fil
!ls ru_open_stt_opus/manifests/*.csv
Några exempel som visar hur du bäst läser wav- och opus-filer.
Scipy är snabbast för wav. Pysoundfile är den bästa övergripande för opus.
%matplotlib inline
import librosa
from scipy.io import wavfile
from librosa import display as ldisplay
from matplotlib import pyplot as plt
Läsa en wav
manifest_df = read_manifest(prepend_path +'manifests/asr_calls_2_val.csv')
#manifest_df = reroot_manifest(manifest_df,
#source_path='',
#target_path='../../../../../nvme/stt/data/ru_open_stt/')
sample = manifest_df.sample(n=5)
display_manifest(sample)
from io import BytesIO
wav_path = sample.iloc[0].wav_path
response = urlopen(prepend_path+wav_path)
data = response.read()
sr, wav = wavfile.read(BytesIO(data))
wav.astype('float32')
absmax = np.max(np.abs(wav))
wav = wav / absmax
# shortest way to plot a spectrogram
D = librosa.amplitude_to_db(np.abs(librosa.stft(wav)), ref=np.max)
plt.figure(figsize=(12, 6))
ldisplay.specshow(D, y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Log-frequency power spectrogram')
# shortest way to plot an envelope
plt.figure(figsize=(12, 6))
ldisplay.waveplot(wav, sr=sr, max_points=50000.0, x_axis='time', offset=0.0, max_sr=1000, ax=None)
Läs opus
manifest_df = read_manifest(prepend_path +'manifests/asr_public_phone_calls_2.csv')
#manifest_df = reroot_manifest(manifest_df,
#source_path='',
#target_path='../../../../../nvme/stt/data/ru_open_stt/')
sample = manifest_df.sample(n=5)
display_manifest(sample)
opus_path = sample.iloc[0].wav_path
response = urlopen(prepend_path+opus_path)
data = response.read()
wav, sr = sf.read(BytesIO(data))
wav.astype('float32')
absmax = np.max(np.abs(wav))
wav = wav / absmax
# shortest way to plot a spectrogram
D = librosa.amplitude_to_db(np.abs(librosa.stft(wav)), ref=np.max)
plt.figure(figsize=(12, 6))
ldisplay.specshow(D, y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Log-frequency power spectrogram')
# shortest way to plot an envelope
plt.figure(figsize=(12, 6))
ldisplay.waveplot(wav, sr=sr, max_points=50000.0, x_axis='time', offset=0.0, max_sr=1000, ax=None)
Nästa steg
Visa resten av datauppsättningarna i katalogen Öppna datamängder.