Orosz nyílt beszéd szöveggé
Különböző audioforrásokból származó beszédminták gyűjteménye. Az adathalmaz rövid, orosz nyelvű hangklipeket tartalmaz.
Feljegyzés
A Microsoft az Azure Open Datasets szolgáltatást "adott módon" biztosítja. A Microsoft nem vállal kifejezett vagy vélelmezett garanciát vagy feltételeket az adathalmazok Ön általi használatára vonatkozóan. A microsoft a helyi jogszabályok által megengedett mértékben kizár minden felelősséget az adathalmazok használatából eredő károkért vagy veszteségekért, beleértve a közvetlen, következményi, különleges, közvetett, incidenses vagy büntető jellegű károkat is.
Az adatkészletet a Microsoft forrásadataihoz tartozó eredeti feltételek szerint szolgáltatjuk. A készlet tartalmazhat Microsofttól származó adatokat.
Ez az orosz szövegfelolvasási (STT) adatkészlet a következőket tartalmazza:
- ~16 millió kimondott szöveg
- ~20 000 óra
- 2,3 TB (tömörítetlen .wav formátumban az int16-ban), 356G opusban
- Az összes fájl opusra lett átalakítva, kivéve az érvényesítési adatkészleteket
Az adatkészlet fő célja a beszédátírási modellek betanítása.
Az adatkészlet összetétele
Az adathalmaz mérete .wav fájlokhoz van megadva.
ADATKÉSZLET | KIMONDOTT SZÖVEGEK | ÓRA | GB | SECS/CHARS | MEGJEGYZÉST | MEGJEGYZÉS | MINŐSÉG/ZAJ |
---|---|---|---|---|---|---|---|
radio_v4 (*) | 7 603 192 | 10,430 | 1,195 | 5s / 68 | Választógomb | Igazítás | 95% / tiszta |
public_speech (*) | 1,700,060 | 2,709 | 301 | 6s / 79 | Nyilvános beszéd | Igazítás | 95% / tiszta |
audiobook_2 | 1,149,404 | 1,511 | 162 | 5s / 56 | Könyvek | Igazítás | 95% / tiszta |
radio_2 | 651,645 | 1,439 | 154 | 8s / 110 | Választógomb | Igazítás | 95% / tiszta |
public_youtube1120 | 1,410,979 | 1,104 | 237 | 3s / 34 | YouTube | Feliratok | 95% / ~tiszta |
public_youtube700 | 759,483 | 701 | 75 | 3s / 43 | YouTube | Feliratok | 95% / ~tiszta |
tts_russian_addresses | 1,741,838 | 754 | 81 | 2s / 20 | Címek | TTS 4-hangok | 100% / tiszta |
asr_public_phone_calls_2 | 603,797 | 601 | 66 | 4s / 37 | Telefonbeszélgetések | ASR | 70% / zajos |
public_youtube1120_hq | 369,245 | 291 | 31 | 3s / 37 | YouTube HQ | Feliratok | 95% / ~tiszta |
asr_public_phone_calls_1 | 233,868 | 211 | 23 | 3s / 29 | Telefonbeszélgetések | ASR | 70% / zajos |
radio_v4_add (*) | 92,679 | 157 | 18 | 6s / 80 | Választógomb | Igazítás | 95% / tiszta |
asr_public_stories_2 | 78,186 | 78 | 9 | 4s / 43 | Könyvek | ASR | 80% / tiszta |
asr_public_stories_1 | 46,142 | 38 | 4 | 3s / 30 | Könyvek | ASR | 80% / tiszta |
public_series_1 | 20,243 | 17 | 2 | 3s / 38 | YouTube | Feliratok | 95% / ~tiszta |
asr_calls_2_val | 12,950 | 7,7 | 2 | 2s / 34 | Telefonbeszélgetések | Manuális jegyzetek | 99% / tiszta |
public_lecture_1 | 6,803 | 6 | 0 | 3s / 47 | Előadások | Feliratok | 95% / tiszta |
buriy_audiobooks_2_val | 7,850 | 4,9 | 0 | 2s / 31 | Könyvek | Manuális jegyzetek | 99% / tiszta |
public_youtube700_val | 7,311 | 4,5 | 0 | 2s / 35 | YouTube | Manuális jegyzetek | 99% / tiszta |
(*) A txt-fájlokban csak egy mintaadat található.
Jegyzetkészítési módszertan
Az adathalmaz nyílt forrásokból áll össze. A hosszú szekvenciákat hangdarabokra osztottuk fel a hangtevékenység észlelésének és az igazítás használatával. Egyes hangtípusokat a rendszer automatikusan jegyzetel, és heurisztika használatával statisztikailag ellenőrzi.
Adatkötetek és frissítés gyakorisága
Az adathalmaz teljes mérete 350 GB. A nyilvánosan megosztott címkékkel rendelkező adathalmaz teljes mérete 130 GB.
Maga az adathalmaz valószínűleg nem frissül a visszamenőleges kompatibilitás érdekében. Kövesse az eredeti adattárat a teljesítménytesztekhez, és zárja ki a fájlokat.
Elképzelhető, hogy a jövőben új tartományokat és nyelveket is felveszünk majd.
Hangnormalizáció
Minden fájl normalizálva van a egyszerűbb és gyorsabb futtatókörnyezeti bővítés érdekében. A feldolgozás a következő:
- Szükség szerint monóra konvertálva;
- Szükség esetén 16 kHz-es mintavételi sebességre konvertálva;
- 16 bites egész számokban tárolva;
- OPUS-ra konvertálva;
Lemezes DB-módszer
Minden hangfájl (wav, bináris) kivonatolva van. A kivonat egy mappahierarchiát hoz létre az optimálisabb fs művelet érdekében.
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)
Letöltések
Az adatkészlet két formában érhető el:
- Az Azure Blob Storage-on és/vagy közvetlen hivatkozásokon keresztül elérhető archívumok;
- Az Azure Blob Storage-on keresztül elérhető eredeti fájlok; Minden a következő helyen van tárolva: "https://azureopendatastorage.blob.core.windows.net/openstt/"
Mappaszerkezet:
└── 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
ADATKÉSZLET | GB, WAV | GB, ARCHÍV | ARCHÍVUM | FORRÁS | JEGYZÉK |
---|---|---|---|---|---|
Betanítás | |||||
Rádiós és nyilvános beszédek minta | - | 11.4 | opus+txt | - | jegyzékfájl |
audiobook_2 | 162 | 25.8 | opus+txt | Internet + igazítás | jegyzékfájl |
radio_2 | 154 | 24.6 | opus+txt | Választógomb | jegyzékfájl |
public_youtube1120 | 237 | 19.0 | opus+txt | YouTube-videók | jegyzékfájl |
asr_public_phone_calls_2 | 66 | 9,4 | opus+txt | Internet + ASR | jegyzékfájl |
public_youtube1120_hq | 31 | 4.9 | opus+txt | YouTube-videók | jegyzékfájl |
asr_public_stories_2 | 9 | 1.4 | opus+txt | Internet + igazítás | jegyzékfájl |
tts_russian_addresses_rhvoice_4voices | 80.9 | 12.9 | opus+txt | TTS | jegyzékfájl |
public_youtube700 | 75,0 | 12.2 | opus+txt | YouTube-videók | jegyzékfájl |
asr_public_phone_calls_1 | 22,7 | 3.2 | opus+txt | Internet + ASR | jegyzékfájl |
asr_public_stories_1 | 4.1 | 0,7 | opus+txt | Nyilvános történetek | jegyzékfájl |
public_series_1 | 1,9 | 0.3 | opus+txt | Nyilvános sorozatok | jegyzékfájl |
public_lecture_1 | 0,7 | 0,1 | opus+txt | Internet + kézi | jegyzékfájl |
Val | |||||
asr_calls_2_val | 2 | 0,8 | wav+txt | Internet | jegyzékfájl |
buriy_audiobooks_2_val | 0 | 0,5 | wav+txt | Könyvek + manuális | jegyzékfájl |
public_youtube700_val | 2 | 0,13 | wav+txt | YouTube videos + kézi | jegyzékfájl |
Letöltési útmutató
Közvetlen letöltés
Az adatkészlet közvetlen letöltésével kapcsolatos utasításokért tekintse meg a GitHub letöltési útmutatójának oldalát.
További információk
Az adatokkal kapcsolatos segítségért vagy kérdésekért forduljon az adatszerző(k)hez a következő címen: aveysov@gmail.com
Ez a licenc lehetővé teszi, hogy a felhasználók bármilyen adathordozón vagy formában terjesztsék, remixelhetik, adaptálhassák és felhasználhassák az anyagot, csak akkor, ha az alkotónak meg van adva a hozzárendelés. A következő összetevőket tartalmazza:
- BY – Kreditet kell adni a létrehozónak
- NC – Csak a munka nem kereskedelmi célú felhasználása engedélyezett
CC-BY-NC, a kereskedelmi felhasználáshoz az adatkészlet szerzőivel kötött megállapodás szükséges.
Az adatok elérése
Azure Notebooks
Segédfüggvények /függőségek
Libsndfile létrehozása
A pysoundfile (a libsoundfile körüli Python CFFI-burkoló) használatával hatékonyan olvashatja el az opus-fájlokat a Pythonban, amely nem jár jelentős többletterheléssel.
Az Opus támogatása a felsőbb rétegben lett implementálva, de nem lett megfelelően kiadva. Ezért az egyéni build + majom javítást választottuk.
Ezt általában sudo-hozzáféréssel kell futtatnia a rendszerhéjban:
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 .
Segédfüggvények /függőségek
Telepítse az alábbi kódtárakat:
pandas
numpy
scipy
tqdm
soundfile
librosa
A jegyzékfájlok a következő oszlopokkal rendelkező CSV-fájlok:
- A hang elérési útja
- Szövegfájl elérési útja
- Időtartam
Ezek bizonyultak az adatok elérésének legegyszerűbb formátumának.
A könnyű használat érdekében az összes jegyzék már újra van űzve. A bennük lévő összes elérési út relatív, gyökérmappát kell megadnia.
# 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()
Lejátszás adatkészlettel
Fájlminta lejátszása
A legtöbb platformböngésző támogatja a natív hanglejátszást. Így HTML5-hang lejátszók használatával tekinthetjük meg az adatokat.
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)
Fájl beolvasása
!ls ru_open_stt_opus/manifests/*.csv
Néhány példa a wav- és opusfájlok legjobb olvasására.
Scipy a leggyorsabb hullámos. A Pysoundfile a legjobb az opushoz.
%matplotlib inline
import librosa
from scipy.io import wavfile
from librosa import display as ldisplay
from matplotlib import pyplot as plt
Hullám olvasása
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)
Opus olvasása
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)
Következő lépések
Tekintse meg a többi adathalmazt az Open Datasets katalógusban.