Rusça açık konuşmayı metne dönüştürme
Çeşitli ses kaynaklarından toplanan konuşma örnekleri koleksiyonu. Veri kümesi Rusça kısa ses klipleri içerir.
Not
Microsoft, Azure Open Datasets'i "olduğu gibi" sağlar. Microsoft, veri kümelerini kullanımınızla ilgili olarak açık veya zımni hiçbir garanti veya koşul sağlamaz. Yerel yasalarınız kapsamında izin verilen ölçüde, Microsoft veri kümelerini kullanımınızdan kaynaklanan doğrudan, sonuçsal, özel, dolaylı, arızi veya cezai dahil olmak üzere tüm zarar veya kayıplar için tüm sorumluluğu kabul etmez.
Bu veri kümesi Microsoft’un kaynak verileri aldığı orijinal hükümler kapsamında sağlanır. Veri kümesi Microsoft’tan alınan verileri içerebilir.
Bu Rusça konuşmayı metne dönüştürme (STT) veri kümesi şunları içerir:
- Yaklaşık 16 milyon konuşma
- Yaklaşık 20.000 saat
- 2,3 TB (int16'da .wav biçimde sıkıştırılmamış), opus'ta 356G
- Doğrulama veri kümeleri dışında tüm dosyalar opus'a dönüştürüldü
Veri kümesinin temel amacı konuşmayı metne dönüştürme modellerini eğitmektir.
Veri kümesi bileşimi
veri kümesi boyutu, .wav dosyalar için verilir.
VERİ KÜMESİ | KONUŞMALAR | SAAT | GB | SECS/CHARS | YORUM | EK AÇIKLAMA | KALITE/GÜRÜLTÜ |
---|---|---|---|---|---|---|---|
radio_v4 (*) | 7.603.192 | 10.430 | 1.195 | 5 sn / 68 | Radyo | Align | %95 / net |
public_speech (*) | 1.700.060 | 2.709 | 301 | 6 sn / 79 | Genel konuşma | Align | %95 / net |
audiobook_2 | 1.149.404 | 1.511 | 162 | 5 sn / 56 | Defterler | Align | %95 / net |
radio_2 | 651.645 | 1.439 | 154 | 8 sn / 110 | Radyo | Align | %95 / net |
public_youtube1120 | 1.410.979 | 1.104 | 237 | 3 sn / 34 | YouTube | Alt başlıklar | %95 / ~net |
public_youtube700 | 759.483 | 701 | 75 | 3 sn / 43 | YouTube | Alt başlıklar | %95 / ~net |
tts_russian_addresses | 1.741.838 | 754 | 81 | 2 sn / 20 | Adresler | TTS 4 sesleri | %100 / net |
asr_public_phone_calls_2 | 603.797 | 601 | 66 | 4 sn / 37 | Telefon görüşmeleri | ASR | %70 / gürültülü |
public_youtube1120_hq | 369.245 | 291 | 31 | 3 sn / 37 | YouTube HQ | Alt başlıklar | %95 / ~net |
asr_public_phone_calls_1 | 233.868 | 211 | 23 | 3 sn / 29 | Telefon görüşmeleri | ASR | %70 / gürültülü |
radio_v4_add (*) | 92.679 | 157 | 18 | 6 sn / 80 | Radyo | Align | %95 / net |
asr_public_stories_2 | 78.186 | Kategori 78 | 9 | 4 sn / 43 | Defterler | ASR | %80 / net |
asr_public_stories_1 | 46.142 | 38 | 4 | 3 sn / 30 | Defterler | ASR | %80 / net |
public_series_1 | 20.243 | 17 | 2 | 3 sn / 38 | YouTube | Alt başlıklar | %95 / ~net |
asr_calls_2_val | 12.950 | 7,7 | 2 | 2 sn / 34 | Telefon görüşmeleri | El ile ek açıklama | %99 / net |
public_lecture_1 | 6.803 | 6 | 1 | 3 sn / 47 | Konuşmalar | Alt başlıklar | %95 / net |
buriy_audiobooks_2_val | 7.850 | 4,9 | 1 | 2 sn / 31 | Defterler | El ile ek açıklama | %99 / net |
public_youtube700_val | 7.311 | 4,5 | 1 | 2 sn / 35 | YouTube | El ile ek açıklama | %99 / net |
(*) Txt dosyalarıyla yalnızca örnek veriler sağlanır.
Ek açıklama metodolojisi
Veri kümesi açık kaynaklar kullanılarak derlenmiştir. Uzun diziler ses etkinliği algılama ve hizalama kullanılarak ses öbeklerine ayrılır. Bazı ses türlerine otomatik olarak açıklama eklenir ve buluşsal yöntemler kullanılarak istatistiksel olarak doğrulanır.
Veri birimleri ve güncelleştirme sıklığı
Veri kümesinin toplam boyutu 350 GB'tır. Genel olarak paylaşılan etiketler içeren veri kümesinin toplam boyutu 130 GB'tır.
Geriye dönük uyumluluk için veri kümesinin güncelleştirilmesi olası değildir. Karşılaştırmalar için özgün depoyu izleyin ve dosyaları hariç tutun.
Gelecekte yeni etki alanları ve diller eklenebilir.
Ses normalleştirme
Tüm dosyalar daha kolay ve daha hızlı çalışma zamanı geliştirmeleri için normalleştirilir. İşleme aşağıdaki gibidir:
- Gerekirse monoya dönüştürülür;
- Gerekirse 16 kHz örnekleme hızına dönüştürülür;
- 16 bit tamsayılar olarak depolanır;
- OPUS’a dönüştürülür;
Disk üzerinde veritabanı metodolojisi
Her ses dosyasına (wav, ikili) karma işlemi uygulanır. Karma, daha iyi fs işlemi için bir klasör hiyerarşisi oluşturmak için kullanılır.
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)
İndirmeler
Veri kümesi iki biçimde sağlanır:
- Azure blob depolama ve/veya doğrudan bağlantılar aracılığıyla kullanılabilen arşivler;
- Azure blob depolama aracılığıyla kullanılabilen özgün dosyalar; Her şey 'https://azureopendatastorage.blob.core.windows.net/openstt/' içinde depolanır
Klasör yapısı:
└── 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
VERİ KÜMESİ | GB, WAV | GB, ARŞİV | ARŞİV | KAYNAK | BİLDİRİM |
---|---|---|---|---|---|
Eğitim | |||||
Radyo ve genel konuşma örneği | - | 11,4 | opus+txt | - | bildirim |
audiobook_2 | 162 | 25,8 | opus+txt | İnternet + hizalama | bildirim |
radio_2 | 154 | 24,6 | opus+txt | Radyo | bildirim |
public_youtube1120 | 237 | 19,0 | opus+txt | YouTube videoları | bildirim |
asr_public_phone_calls_2 | 66 | 9.4 | opus+txt | İnternet + ASR | bildirim |
public_youtube1120_hq | 31 | 4,9 | opus+txt | YouTube videoları | bildirim |
asr_public_stories_2 | 9 | 1.4 | opus+txt | İnternet + hizalama | bildirim |
tts_russian_addresses_rhvoice_4voices | 80,9 | 12,9 | opus+txt | TTS | bildirim |
public_youtube700 | 75.0 | 12,2 | opus+txt | YouTube videoları | bildirim |
asr_public_phone_calls_1 | 22.7 | 3.2 | opus+txt | İnternet + ASR | bildirim |
asr_public_stories_1 | 4.1 | 0.7 | opus+txt | Genel hikayeler | bildirim |
public_series_1 | 1.9 | 0.3 | opus+txt | Genel seriler | bildirim |
public_lecture_1 | 0.7 | 0,1 | opus+txt | İnternet + el kitabı | bildirim |
Val | |||||
asr_calls_2_val | 2 | 0.8 | wav+txt | İnternet | bildirim |
buriy_audiobooks_2_val | 1 | 0,5 | wav+txt | Kitaplar + el kitabı | bildirim |
public_youtube700_val | 2 | 0,13 | wav+txt | YouTube videoları + el kitabı | bildirim |
İndirme yönergeleri
Doğrudan indirme
Veri kümesini doğrudan indirme yönergeleri için GitHub indirme yönergeleri sayfasına bakın.
Ek bilgi
Veriler hakkında yardım veya sorular için adresinden veri yazarları ile iletişime geçin aveysov@gmail.com
Bu lisans, kullanıcıların malzemeyi yalnızca ticari olmayan amaçlarla ve yalnızca içerik oluşturucuya verildiği sürece herhangi bir ortamda veya biçimde dağıtmasına, karıştırmasına, uyarlamasına ve üzerine inşa etmesine olanak tanır. Bu, aşağıdaki öğeleri içerir:
- BY – Krediyi oluşturana verilmelidir
- NC – Yalnızca çalışmanın ticari olmayan kullanımlarına izin verilir
CC-BY-NC ve ticari kullanım, veri kümesi yazarlarıyla anlaşma yapıldıktan sonra gerçekleştirilebilir.
Veri erişimi
Azure Notebooks
Yardımcı işlevler / bağımlılıklar
Libsndfile oluşturma
Python'da önemli bir yük doğurmayan opus dosyalarını okumanın verimli bir yolu, pysoundfile (libsoundfile çevresinde python CFFI sarmalayıcı) kullanmaktır.
Opus desteği yukarı akışa uygulandı, ancak düzgün bir şekilde yayımlanmadı. Bu nedenle, özel derleme + maymun düzeltme eki uygulamayı seçtik.
Genellikle bunu sudo erişimiyle kabuğunuzda çalıştırmanız gerekir:
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 .
Yardımcı işlevler / bağımlılıklar
Aşağıdaki kitaplıkları yükleyin:
pandas
numpy
scipy
tqdm
soundfile
librosa
Bildirimler, aşağıdaki sütunlara sahip csv dosyalarıdır:
- Ses yolu
- Metin dosyasının yolu
- Süre
Verilere erişmenin en basit biçimi olduğunu kanıtladılar.
Kullanım kolaylığı için tüm bildirimler zaten yeniden köklenmiştir. İçlerindeki tüm yollar görelidir, bir kök klasör sağlamanız gerekir.
# 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()
Veri kümesiyle yürütme
Dosya örneğini yürütme
Çoğu platform tarayıcısı yerel ses kayıttan yürütmeyi destekler. Böylece verilerimizi görüntülemek için HTML5 ses oynatıcıları kullanabiliriz.
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)
Dosya okuma
!ls ru_open_stt_opus/manifests/*.csv
Wav ve opus dosyalarını en iyi şekilde okumayı gösteren bazı örnekler.
Scipy, wav için en hızlı olandır. Pysoundfile, opus için en iyi geneldir.
%matplotlib inline
import librosa
from scipy.io import wavfile
from librosa import display as ldisplay
from matplotlib import pyplot as plt
Dalgalı okuma
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)
Oku 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)
Sonraki adımlar
Açık Veri Kümeleri kataloğundaki diğer veri kümelerini görüntüleyin.