Ръководство за подготовка на TTS данни¶
Това ръководство обхваща критичната първа фаза на всеки TTS проект: подготовка на висококачествени, правилно форматирани аудио и текстови данни. Качеството на вашия набор от данни директно влияе върху качеството на крайния TTS модел.
Ако някой аудио термин е неясен, използвайте речника. Тази страница обяснява само термините, които пряко влияят върху текущата стъпка.
Стъпки за подготовка на набора от данни¶
1. Придобиване на аудио и първоначална обработка¶
- Събиране на аудио: Съберете вашите сурови аудио файлове (често срещаните формати включват WAV, MP3, FLAC, OGG, M4A). Уверете се, че имате правата да използвате това аудио.
- Конвертиране в WAV: Повечето TTS рамки очакват WAV формат. Използвайте инструменти като
ffmpegили аудио библиотеки (pydub,soundfile), за да конвертирате вашето аудио. Целете се към стандартно WAV кодиране като PCM 16-bit. - Стандартизиране на каналите (Моно): TTS моделите обикновено се обучават на едноканално (моно) аудио. Конвертирайте стерео записите в моно.
# Пример с използване на ffmpeg за конвертиране на стерео WAV в моно WAV ffmpeg -i stereo_input.wav -ac 1 mono_output.wav-ac 1: Задава броя на аудио каналите на 1.
- Ресемплиране на аудио: Уверете се, че всички аудио файлове имат точно същата честота на семплиране. Изберете целевата честота въз основа на целите на вашия проект и съвместимостта с рамката (напр. 16000 Hz, 22050 Hz, 48000 Hz). 22050 Hz е често срещана за много модели.
# Пример с използване на ffmpeg за ресемплиране до 22050 Hz ffmpeg -i input.wav -ar 22050 resampled_output.wav-ar 22050: Задава честотата на семплиране на 22050 Hz.
Малко, но важно предупреждение: не смесвайте различни честоти на семплиране, различни канални оформления или силно клипнати файлове в един и същ набор от данни с надеждата, че моделът ще се справи сам. Тези разлики обикновено се проявяват по-късно като шумна, нестабилна или неестествена реч.
2. Разширено почистване на аудио (премахване на шум и музика)¶
- Премахване на шума: Използвайте инструменти като SoX, Audacity или специализирани библиотеки за премахване на фонов шум.
- Нормализиране на силата на звука: Стандартизирайте нивата на силата на звука във всички файлове.
- Изрязване на тишината: Премахнете излишната тишина в началото и края на файловете.
# Пример с използване на ffmpeg за изрязване на тишината ffmpeg -i input.wav -af silenceremove=start_periods=1:start_duration=0.1:start_threshold=-60dB:detection=peak,aformat=dblp,areverse,silenceremove=start_periods=1:start_duration=0.1:start_threshold=-60dB:detection=peak,aformat=dblp,areverse trimmed_output.wav
3. Сегментиране на аудио (разделяне на сегменти)¶
- Разделяне на дълги записи: Разделете дълги аудио файлове на по-малки сегменти (обикновено 1-15 секунди). Това е критично за ефективно обучение.
- Използвайте инструменти като
pydub,librosaилиffmpegза автоматично сегментиране. - Сегментирайте при естествени паузи, когато е възможно.
- Избягвайте прекалено кратки (<1 секунда) или прекалено дълги (>15 секунди) сегменти.
- Използвайте инструменти като
# Пример за Python скрипт за сегментиране на аудио при тишина
from pydub import AudioSegment
from pydub.silence import split_on_silence
audio = AudioSegment.from_wav("long_recording.wav")
segments = split_on_silence(
audio,
# Определете тишината като звук с интензитет под -40 dBFS
min_silence_len=500, # Минимална дължина на тишината в ms
silence_thresh=-40, # Праг за тишина в dBFS
keep_silence=400 # Запазете малко тишина в началото и края
)
# Запазете всеки сегмент като отделен файл
for i, segment in enumerate(segments):
segment.export(f"segment_{i}.wav", format="wav")
4. Нормализиране на силата на звука¶
Целта е всички аудио сегменти да имат последователна сила на звука. Това намалява риска тихите и силните записи да повлияят неравномерно на обучението.
- Нормализиране на пиковете: бърз подход, който задава еднакво целево пиково ниво.
- Нормализиране по LUFS: по-добър ориентир за възприеманата сила на звука, когато записите са с различна естествена громкост.
- Прилагайте метода последователно: обработете всички сегменти по един и същ начин и запазете оригиналите отделно.
5. Транскрибиране: създаване на аудио-текстови двойки¶
- Създаване на транскрипции: За всеки аудио сегмент, създайте точна текстова транскрипция.
- Ръчно транскрибиране: Най-точният метод, но отнема време.
- Автоматично транскрибиране: Използвайте ASR (Automatic Speech Recognition) системи като Whisper, Vosk или Google Speech-to-Text, последвано от ръчна проверка.
# Пример с използване на OpenAI Whisper за транскрибиране import whisper model = whisper.load_model("base") # Изберете размер на модела: tiny, base, small, medium, large result = model.transcribe("audio_segment.wav") transcription = result["text"] # Запазете транскрипцията във файл with open("audio_segment.txt", "w", encoding="utf-8") as f: f.write(transcription)
- Почистване на текста: Стандартизирайте текста за последователност.
- Премахнете излишни интерпункционни знаци или форматиране.
- Стандартизирайте числа, съкращения и специални символи.
- Уверете се, че текстът съответства точно на говореното аудио.
- Предупреждение: Имената на моделите, API ограниченията и цените на външните услуги могат да се променят бързо. Винаги проверявайте актуалната документация, преди да изграждате цял работен процес около конкретна хоствана ASR услуга.
6. Структуриране на данните и създаване на manifest файл¶
- Структура на директорията: Създайте ясна структура на директорията за вашия набор от данни.
flowchart TD dataset["my_tts_dataset/"] audio["normalized_chunks/"] wav1["segment_00001.wav"] wav2["segment_00002.wav"] wavMore["..."] transcripts["transcripts/"] txt1["segment_00001.txt<br/>Съдържа: Здравей, свят."] txt2["segment_00002.txt<br/>Съдържа: Това е тестово изречение."] txtMore["..."] dataset --> audio audio --> wav1 audio --> wav2 audio --> wavMore dataset --> transcripts transcripts --> txt1 transcripts --> txt2 transcripts --> txtMore - Създаване на файл с метаданни: Повечето TTS рамки изискват CSV или JSON файл, свързващ аудио файловете с техните транскрипции.
Разделяне на набора от данни¶
- Разделяне на обучение/валидация/тест: Разделете вашия набор от данни на подмножества за обучение (обикновено 80-90%), валидация (5-10%) и тест (5-10%).
- Обучение: Използва се за обучение на модела.
- Валидация: Използва се за настройка на хиперпараметрите и мониторинг на обучението.
- Тест: Използва се за окончателна оценка на модела.
- Безопасен избор за начинаещи: Ако все още нямате по-добра стратегия, малък, но представителен валидационен набор е напълно достатъчен. Просто разделение 95/5 често е добро начало, стига да не допускате части от един и същ оригинален дълъг запис и в обучението, и във валидацията.
- Предупреждение за пътищата: Много TTS рамки очакват пътищата в manifest файловете да са относителни спрямо конкретната работна директория, а не спрямо самия manifest файл. Преди обучение отворете един ред от manifest файла и проверете дали
train.pyнаистина може да намери аудиото от директорията, от която ще стартирате обучението.
# Пример за Python скрипт за разделяне на набора от данни
import pandas as pd
from sklearn.model_selection import train_test_split
# Зареждане на метаданните
metadata = pd.read_csv("metadata.csv", sep="|", header=None,
names=["file", "speaker", "text"])
# Първо разделяне: 90% обучение+валидация, 10% тест
train_val, test = train_test_split(metadata, test_size=0.1, random_state=42)
# Второ разделяне: 90% обучение, 10% валидация от обуч_вал (което е 9% от общото)
train, val = train_test_split(train_val, test_size=0.1, random_state=42)
# Запазване на разделените метаданни
train.to_csv("metadata_train.csv", sep="|", header=False, index=False)
val.to_csv("metadata_val.csv", sep="|", header=False, index=False)
test.to_csv("metadata_test.csv", sep="|", header=False, index=False)
print(f"Общо записи: {len(metadata)}")
print(f"Записи за обучение: {len(train)} ({len(train)/len(metadata)*100:.1f}%)")
print(f"Записи за валидация: {len(val)} ({len(val)/len(metadata)*100:.1f}%)")
print(f"Записи за тест: {len(test)} ({len(test)/len(metadata)*100:.1f}%)")
Практически скриптове за проверка¶
Допълнителни практически съвети¶
- Последователност е ключова: Поддържайте последователно качество на записа, нива на силата на звука и фонов шум.
- Избягвайте ехо и реверберация: Записвайте в акустично третирани помещения, когато е възможно.
- Използвайте качествен микрофон: Инвестирайте в добър микрофон за по-чисти записи.
-
Мониторинг на клипиране: Избягвайте претоварване на аудиото, което води до изкривяване.
-
Последователност в стила: Решете как ще обработвате числа, съкращения, акроними и придържайте се към това.
- Фонетична точност: Уверете се, че транскрипциите отразяват точно произнесените думи, не предполагаемото намерение.
-
Обработка на шумове: Решете дали да включвате или изключвате нелингвистични звуци (кашляне, смях, въздишки).
-
Автоматизирайте процеса: Създайте скриптове за автоматизиране на повтарящи се задачи.
- Паралелна обработка: Използвайте многонишкова обработка за по-бързо преобразуване на големи набори от данни.
- Инкрементална проверка: Проверявайте качеството на малки партиди, докато напредвате, вместо да оставяте всичко за края.
Проверка на целостта на набора от данни¶
- Проверка на аудио файловете: Уверете се, че всички аудио файлове имат правилния формат, честота на семплиране и канали.
- Проверка на транскрипциите: Уверете се, че всички транскрипции са точни и съответстват на аудиото.
- Проверка на целостта на набора от данни: Уверете се, че всеки аудио файл има съответна транскрипция и обратно.
# Пример за Python скрипт за проверка на целостта на набора от данни
import os
import pandas as pd
# Зареждане на метаданните
metadata = pd.read_csv("metadata.csv", sep="|", header=None,
names=["file", "speaker", "text"])
# Проверка дали всички аудио файлове съществуват
audio_dir = "wavs/"
missing_files = []
for file in metadata["file"]:
full_path = os.path.join(audio_dir, file)
if not os.path.exists(full_path):
missing_files.append(file)
if missing_files:
print(f"Липсват {len(missing_files)} аудио файла!")
print(missing_files[:5]) # Показване на първите 5 липсващи файла
else:
print("Всички аудио файлове съществуват!")
# Проверка за празни транскрипции
empty_transcriptions = metadata[metadata["text"].isna() | (metadata["text"] == "")]
if not empty_transcriptions.empty:
print(f"Намерени {len(empty_transcriptions)} празни транскрипции!")
else:
print("Няма празни транскрипции!")
Проверка на свойствата на аудио файловете¶
Ето няколко полезни скрипта за проверка на качеството на вашите аудио данни:
# Скрипт за проверка на свойствата на аудио файловете
import os
import librosa
import pandas as pd
from tqdm import tqdm
audio_dir = "wavs/"
files = [f for f in os.listdir(audio_dir) if f.endswith('.wav')]
results = []
for file in tqdm(files, desc="Проверка на аудио файлове"):
full_path = os.path.join(audio_dir, file)
try:
# Зареждане на аудио файла
y, sr = librosa.load(full_path, sr=None)
# Изчисляване на продължителността
duration = librosa.get_duration(y=y, sr=sr)
# Проверка на броя канали (моно/стерео)
if y.ndim > 1:
channels = y.shape[0]
else:
channels = 1
# Изчисляване на RMS енергия (за нивото на силата на звука)
rms_energy = librosa.feature.rms(y=y).mean()
results.append({
'file': file,
'sample_rate': sr,
'duration': duration,
'channels': channels,
'rms_energy': rms_energy
})
except Exception as e:
print(f"Грешка при обработка на {file}: {str(e)}")
# Конвертиране на резултатите в DataFrame
df = pd.DataFrame(results)
# Показване на статистика
print("\nСтатистика за аудио файловете:")
print(f"Общ брой файлове: {len(df)}")
print(f"Уникални честоти на семплиране: {df['sample_rate'].unique()}")
print(f"Средна продължителност: {df['duration'].mean():.2f}s")
print(f"Мин. продължителност: {df['duration'].min():.2f}s")
print(f"Макс. продължителност: {df['duration'].max():.2f}s")
print(f"Файлове с повече от 1 канал: {(df['channels'] > 1).sum()}")
# Идентифициране на потенциални проблеми
problematic_files = df[
(df['duration'] < 0.5) | # Прекалено кратки файлове
(df['duration'] > 15) | # Прекалено дълги файлове
(df['channels'] > 1) | # Не-моно файлове
(df['sample_rate'] != df['sample_rate'].mode()[0]) | # Различна честота на семплиране
(df['rms_energy'] < 0.01) # Прекалено тихи файлове
]
if not problematic_files.empty:
print(f"\nНамерени {len(problematic_files)} потенциално проблемни файлове:")
print(problematic_files)
# Запазване на списъка с проблемни файлове
problematic_files.to_csv("problematic_audio_files.csv", index=False)
Контролен списък за качеството на данните¶
Преди да преминете към настройката на обучението, направете една последна бърза проверка на подготвения набор от данни:
- Всеки
.wavфайл, описан в manifest файловете, действително съществува. - Всеки аудио сегмент има правилната съответстваща транскрипция.
- Повечето сегменти са в очаквания диапазон на продължителност и няма много отклонения.
- Случайните sample проверки звучат чисто и не съдържат силен шум, музика, ехо или грешен говорител.
- Всички файлове използват една и съща честота на семплиране, едно и също канално оформление и очаквания формат.
- Нивата на звука са сравнително последователни в целия набор.
- Транскрипциите са чисти: без времеви маркери, без етикети на говорители и с последователна пунктуация.
- Manifest файловете са в правилния формат и пътищата им се разрешават коректно от директорията, от която ще стартирате
train.py. - Наборът за валидация не се припокрива с обучаващия набор.
С правилно подготвен набор от данни, вие сте готови да преминете към настройката на средата за обучение и конфигурирането на вашия TTS модел.