Skip to content

Ръководство за подготовка на TTS данни

Това ръководство обхваща критичната първа фаза на всеки TTS проект: подготовка на висококачествени, правилно форматирани аудио и текстови данни. Качеството на вашия набор от данни директно влияе върху качеството на крайния TTS модел.

Ако някой аудио термин е неясен, използвайте речника. Тази страница обяснява само термините, които пряко влияят върху текущата стъпка.


Стъпки за подготовка на набора от данни

1. Придобиване на аудио и първоначална обработка

  • Събиране на аудио: Съберете вашите сурови аудио файлове (често срещаните формати включват WAV, MP3, FLAC, OGG, M4A). Уверете се, че имате правата да използвате това аудио.
  • Конвертиране в WAV: Повечето TTS рамки очакват WAV формат. Използвайте инструменти като ffmpeg или аудио библиотеки (pydub, soundfile), за да конвертирате вашето аудио. Целете се към стандартно WAV кодиране като PCM 16-bit.
    # Пример с използване на ffmpeg за конвертиране на MP3 в WAV
    ffmpeg -i input_audio.mp3 output_audio.wav
    
  • Стандартизиране на каналите (Моно): 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 или специализирани библиотеки за премахване на фонов шум.
    # Пример с използване на SoX за премахване на шума
    # Първо, създайте профил на шума от тих сегмент
    sox quiet_segment.wav -n noiseprof noise_profile
    # След това приложете филтъра за намаляване на шума
    sox noisy_input.wav cleaned_output.wav noisered noise_profile 0.21
    
  • Нормализиране на силата на звука: Стандартизирайте нивата на силата на звука във всички файлове.
    # Пример с използване на ffmpeg за нормализиране на силата на звука
    ffmpeg -i input.wav -filter:a loudnorm normalized_output.wav
    
  • Изрязване на тишината: Премахнете излишната тишина в началото и края на файловете.
    # Пример с използване на 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 файл, свързващ аудио файловете с техните транскрипции.
    # Пример за формат на metadata.csv
    # Формат: <име_на_файл>|<говорител_id>|<текст>
    segment_0001.wav|speaker1|Това е пример за транскрибиран текст.
    segment_0002.wav|speaker1|Друг пример за транскрибиран текст.
    

Разделяне на набора от данни

  • Разделяне на обучение/валидация/тест: Разделете вашия набор от данни на подмножества за обучение (обикновено 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}%)")

Практически скриптове за проверка

Допълнителни практически съвети

  • Последователност е ключова: Поддържайте последователно качество на записа, нива на силата на звука и фонов шум.
  • Избягвайте ехо и реверберация: Записвайте в акустично третирани помещения, когато е възможно.
  • Използвайте качествен микрофон: Инвестирайте в добър микрофон за по-чисти записи.
  • Мониторинг на клипиране: Избягвайте претоварване на аудиото, което води до изкривяване.

  • Последователност в стила: Решете как ще обработвате числа, съкращения, акроними и придържайте се към това.

  • Фонетична точност: Уверете се, че транскрипциите отразяват точно произнесените думи, не предполагаемото намерение.
  • Обработка на шумове: Решете дали да включвате или изключвате нелингвистични звуци (кашляне, смях, въздишки).

  • Автоматизирайте процеса: Създайте скриптове за автоматизиране на повтарящи се задачи.

  • Паралелна обработка: Използвайте многонишкова обработка за по-бързо преобразуване на големи набори от данни.
  • Инкрементална проверка: Проверявайте качеството на малки партиди, докато напредвате, вместо да оставяте всичко за края.

Проверка на целостта на набора от данни

  • Проверка на аудио файловете: Уверете се, че всички аудио файлове имат правилния формат, честота на семплиране и канали.
    # Пример с използване на ffprobe за проверка на аудио файл
    ffprobe -v error -show_entries stream=sample_rate,channels,codec_name -of default=noprint_wrappers=1 audio_file.wav
    
  • Проверка на транскрипциите: Уверете се, че всички транскрипции са точни и съответстват на аудиото.
  • Проверка на целостта на набора от данни: Уверете се, че всеки аудио файл има съответна транскрипция и обратно.
# Пример за 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 модел.