Задача: Собрать управляемый TTS-пайплайн для учебных слогов и слов
Собрать управляемый TTS-пайплайн для учебных слогов и слов
Настроить собственный контролируемый TTS-процесс и заранее генерировать аудио для букв, слогов и слов вместо зависимости от непредсказуемого браузерного SpeechSynthesis.
Контекст
Связанная задача к браузерной озвучке cmu326hnm0bbpqw0qh5fgsv2f.
Эксперименты показали, что SpeechSynthesisUtterance приемлемо произносит многие целые слова, но плохо и непредсказуемо работает с отдельными буквами, короткими слогами и искусственно вырезанными частями слов.
Наблюдаемые примеры:
Собака— нормально;Со— звучит примерно какС;Р— ближе кЭ;Ры— нормально;Свинь— может разваливаться на чтение названий букв;Пель— нормально;Ковь,Солн— могут читаться по буквам;Ко→ примерноКа;Ар→ примерноА;Ре→ примерноЭ;Де→Дэ.
Вывод: браузерный TTS нельзя считать надёжным источником педагогически корректного произношения для механики буква → слог → слово.
Цель
Собрать собственный управляемый TTS-пайплайн, через который заранее генерировать и проверять учебное аудио.
Основная идея:
контент карточки
↓
буквы / слоги / слова
↓
контролируемый TTS
↓
ручная/автоматическая проверка
↓
готовые аудиофайлы
↓
приложение только воспроизводит заранее подготовленный звук
В рантайме учебного приложения не полагаться на системный голос пользователя для критичного произношения.
Что нужно генерировать
Минимум:
- отдельные буквы, где это педагогически уместно;
- учебные слоги;
- отдельные слова к карточкам с картинками;
- при необходимости короткие инструкции/реплики персонажей.
Особенно важно заранее генерировать все слоги и слова, которые реально используются в статическом учебном контенте.
Не нужен универсальный генератор всех возможных комбинаций русского языка. Генерируем только тот словарь, который реально входит в приложение.
Требования к TTS
Нужен движок/сервис, где можно лучше контролировать произношение, чем в браузерном SpeechSynthesis.
Желательные возможности:
- стабильный голос между генерациями;
- контроль языка
ru-RU; - контроль
rate; - контроль
pitch, если поддерживается; - SSML или аналогичный механизм управления произношением;
- возможность задавать паузы;
- возможность влиять на чтение отдельных букв/слогов;
- экспорт результата в WAV/MP3/OGG;
- воспроизводимый результат при пакетной генерации.
Если конкретный TTS плохо читает отдельный слог, должна быть возможность задавать специальную TTS-строку отдельно от отображаемого текста.
Например:
type PronunciationAsset = {
text: string
ttsText?: string
audioSrc: string
}
где:
{
text: 'КО',
ttsText: '<специальная строка/SSML для нужного произношения>',
audioSrc: '/audio/syllables/ko.mp3',
}
Пайплайн контента
Предусмотреть реестр генерируемых единиц:
type TtsSourceItem = {
id: string
text: string
kind: 'letter' | 'syllable' | 'word'
ttsText?: string
voiceId?: string
rate?: number
pitch?: number
}
Пример:
const items: TtsSourceItem[] = [
{
id: 'word-dog',
text: 'СОБАКА',
kind: 'word',
},
{
id: 'syllable-so',
text: 'СО',
kind: 'syllable',
ttsText: '...',
},
{
id: 'letter-r',
text: 'Р',
kind: 'letter',
ttsText: '...',
},
]
Дальше отдельный script/build-step:
items
→ TTS API
→ audio files
→ manifest
Manifest готового аудио
После генерации приложение должно работать уже не с TTS, а с готовыми asset'ами.
Например:
type AudioAsset = {
id: string
text: string
kind: 'letter' | 'syllable' | 'word'
src: string
}
export const audioAssets: AudioAsset[] = [
{
id: 'word-dog',
text: 'СОБАКА',
kind: 'word',
src: '/audio/words/sobaka.mp3',
},
{
id: 'syllable-so',
text: 'СО',
kind: 'syllable',
src: '/audio/syllables/so.mp3',
},
]
В UI:
const audio = new Audio(asset.src)
audio.play()
Важная архитектурная идея
Разделить три слоя:
Display text
≠
TTS input
≠
Generated audio asset
Это позволит показывать ребёнку СО, но отправлять в TTS другую техническую строку/SSML, если только так удаётся получить правильное произношение.
То есть не делать предположение:
что написано на экране
=
что нужно буквально передать TTS
Проверка качества
Для каждой единицы нужен простой статус проверки:
type AudioReviewStatus =
| 'generated'
| 'approved'
| 'rejected'
Минимальный workflow:
- сгенерировать пачку;
- прослушать;
- отметить плохие варианты;
- подобрать
ttsText/ voice / параметры; - перегенерировать только отклонённые;
- после
approvedиспользовать asset в приложении.
Особенно внимательно проверять:
- отдельные согласные;
- двухбуквенные слоги;
- слоги с
ь/ъ; - обрезанные части слов;
- сочетания, которые TTS может принять за аббревиатуры.
Связь с персонажами
Система голосовых персонажей может использовать тот же пайплайн.
Если персонажи должны отличаться голосом/темпом/высотой, для каждого персонажа можно либо:
- генерировать отдельный комплект asset'ов;
- либо использовать персонажей только для некритичных реплик, а учебные буквы/слоги оставить в одном эталонном голосе.
Это нужно решить отдельно после оценки объёма generated assets.
Первый практический этап
Не выбирать сразу окончательный TTS.
Сначала сравнить несколько кандидатов на коротком тестовом наборе проблемных строк:
Р
СО
РЫ
РЕ
ДЕ
КО
АР
СВИНЬ
ПЕЛЬ
КОВЬ
СОЛН
СОБАКА
СВИНЬЯ
Для каждого кандидата оценить:
- корректность произношения;
- стабильность;
- наличие SSML/phoneme hints;
- качество русского голоса;
- возможность пакетной генерации;
- стоимость;
- лицензионные ограничения;
- удобство сохранения результата в аудиофайлы.
После этого выбрать основной TTS и уже строить production pipeline.
Критерий готовности
Есть воспроизводимый процесс, который из статического списка учебных букв/слогов/слов генерирует проверенные аудиофайлы, сохраняет их как assets приложения и позволяет отдельно переопределять техническую TTS-строку для проблемных случаев.