SSML и управление просодикой
Speech Synthesis Markup Language: паузы, расстановка акцентов, скорость и высота тона.
«SSML и управление просодикой» — бесплатный урок AI Prompt Engineering на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Prompt Engineering, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Prompt Engineering содержит 4 уроков всего.
Что такое SSML
SSML — это язык разметки речи на основе XML, который обеспечивает детальный контроль над тем, как движки преобразования текста в речь читают текст. Он поддерживается облачным TTS от Гугл, Амазон Полли, TTS от Майкрософт Азур и многими другими системами.
Обычный текст даёт Вам только слова, а SSML позволяет управлять паузами, акцентом, скоростью, высотой тона, произношением и многим другим.
Базовая структура SSML
Все документы SSML заключаются в тег <speak>. Внутри него обычный текст сочетается с элементами разметки SSML. Движки TTS обрабатывают SSML и соответственно создают аудио.
# SSML document structure
SSML_BASIC = """
<speak>
Welcome to the course.
<break time="500ms"/>
Today we will cover three topics.
First, we will discuss SSML basics.
<break time="300ms"/>
Second, we will explore prosody control.
<break time="300ms"/>
And third, we will look at advanced features.
</speak>
"""
# Send to Google Cloud TTS
from google.cloud import texttospeech
client_tts = texttospeech.TextToSpeechClient()
input_text = texttospeech.SynthesisInput(ssml=SSML_BASIC)
voice = texttospeech.VoiceSelectionParams(
language_code='en-US',
ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL
)
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.MP3
)
print('SSML document ready to synthesize')Элемент паузы
<break> вставляет паузу в речь. Используйте его для создания естественного ритма, разделения элементов списка или добавления драматического эффекта. Атрибут time принимает миллисекунды (мс) или секунды (с).
# break element examples
BREAK_EXAMPLES = """
<speak>
Are you ready?
<break time="1s"/>
Let us begin.
The three rules are:
number one,
<break time="300ms"/>
always test your code.
<break time="200ms"/>
Number two,
<break time="300ms"/>
write clear documentation.
<break time="200ms"/>
And number three,
<break time="300ms"/>
review before you ship.
<break strength="x-strong"/>
That is all for today.
</speak>
"""
# break strength values: none, x-weak, weak, medium, strong, x-strong
# These map to approximate pause durations defined by the engine
print('break time: explicit duration (e.g. 500ms)')
print('break strength: semantic pause level (weak/medium/strong)')Элемент выделения
<emphasis> добавляет акцент к словам, заставляя движок произносить их громче, медленнее или более высоким тоном. Используйте его умеренно: чрезмерный акцент звучит неестественно.
EMPHASIS_EXAMPLES = """
<speak>
This update is
<emphasis level="strong">critically important</emphasis>.
Please read it carefully.
The deadline is
<emphasis level="moderate">this Friday</emphasis>,
not next week.
We
<emphasis level="reduced">recommend</emphasis>
enabling this feature, but it is optional.
</speak>
"""
# emphasis level values:
# strong — much more stress (louder, slower, higher pitch)
# moderate — some additional stress (default if level omitted)
# reduced — less stress (quieter, faster)
print('Use strong for critical information')
print('Use reduced for parenthetical or secondary information')Элемент интонации: темп
<prosody rate> управляет скоростью речи. Замедляйте речь для важной информации и ускоряйте для второстепенных сведений или отказов от ответственности.
PROSODY_RATE_EXAMPLES = """
<speak>
<prosody rate="slow">
This is the most important thing to remember.
Take a moment to let it sink in.
</prosody>
<prosody rate="medium">
Now, for some context about how we got here.
</prosody>
<prosody rate="fast">
And now a quick summary of less critical details that you
can refer back to in the documentation.
</prosody>
</speak>
"""
# rate values:
# x-slow, slow, medium (default), fast, x-fast
# Or percentage: rate="75%" (75% of normal speed)
# Or absolute: rate="200 words per minute"
print('Slow: for emphasis, complex information, or pauses for thought')
print('Fast: for disclaimers, secondary info, rapid listing')Элемент интонации: высота тона
<prosody pitch> регулирует основную частоту голоса. Используйте его, чтобы обозначать изменения тональности: вопросы, воодушевление или мрачное содержание.
PROSODY_PITCH_EXAMPLES = """
<speak>
<prosody pitch="high" rate="medium">
Exciting news! We just launched a brand new feature!
</prosody>
<prosody pitch="low" rate="slow">
Unfortunately, this service will be discontinued.
We apologize for any inconvenience.
</prosody>
<prosody pitch="+20%">
Did you know that our users save three hours per week on average?
</prosody>
<prosody pitch="-15%">
Please review the terms and conditions carefully.
</prosody>
</speak>
"""
# pitch values:
# x-low, low, medium, high, x-high
# Or relative: +20%, -15%
# Or semitones: +2st, -4st
print('High pitch: excitement, questions, announcements')
print('Low pitch: serious, cautionary, or somber content')Элемент интерпретации
<say-as> сообщает движку TTS, как интерпретировать текст: как дату, номер телефона, денежную сумму, отдельные символы и так далее. Это надёжный способ исправить произношение чисел и специальных значений.
SAY_AS_EXAMPLES = """
<speak>
Your appointment is on
<say-as interpret-as="date" format="mdy">01/15/2025</say-as>.
Call us at
<say-as interpret-as="telephone">1-800-555-1234</say-as>.
Your confirmation code is
<say-as interpret-as="characters">XK7T9</say-as>.
The total is
<say-as interpret-as="currency" language="en-US">$47.50</say-as>.
This is version
<say-as interpret-as="characters">2.3.1</say-as>
of the software.
</speak>
"""
# interpret-as values:
# characters — spell out each character
# cardinal — number as cardinal ("forty-seven")
# ordinal — "forty-seventh"
# fraction — "three halves"
# date — format string controls order
# telephone — phone number formatting
# currency — monetary value with currency name
print('say-as is the most reliable way to control number pronunciation')Элемент фонемы
<phoneme> задаёт явное фонетическое произношение слов, которые движок TTS регулярно произносит неправильно, например названий брендов, технических терминов или иностранных слов.
PHONEME_EXAMPLES = """
<speak>
Welcome to
<phoneme alphabet="ipa" ph="ent.ro.pi">Entropiq</phoneme>,
the leading analytics platform.
Our CEO,
<phoneme alphabet="ipa" ph="joo.serf">Josef</phoneme>,
will present the results.
This API uses
<phoneme alphabet="ipa" ph="kwer.i">GraphQL</phoneme>
for data fetching.
</speak>
"""
# IPA (International Phonetic Alphabet) is the most precise
# x-sampa is an alternative ASCII-friendly phonetic alphabet
# Use an IPA converter tool to find the right phonemes:
# - https://tophonetics.com
# - Dictionary.com pronunciation guides use IPA
print('Use phoneme for brand names, technical terms, proper nouns')
print('Test with multiple phoneme values until it sounds right')SSML с Амазон Полли
Амазон Полли поддерживает стандартный SSML и расширения, специфичные для этого сервиса. Использование интерфейса немного отличается от облачного TTS от Гугл, но сама разметка SSML одинакова.
import boto3
polly = boto3.client('polly', region_name='us-east-1')
SSML_CONTENT = """
<speak>
<prosody rate="slow" pitch="low">
Welcome to our quarterly earnings call.
</prosody>
<break time="1s"/>
We are pleased to report
<emphasis level="strong">record revenue</emphasis>
of
<say-as interpret-as="currency" language="en-US">$4200000</say-as>
this quarter.
</speak>
"""
response = polly.synthesize_speech(
Text=SSML_CONTENT,
TextType='ssml', # Tell Polly this is SSML
OutputFormat='mp3',
VoiceId='Joanna', # US English female voice
)
if 'AudioStream' in response:
with open('output.mp3', 'wb') as f:
f.write(response['AudioStream'].read())
print('Audio saved to output.mp3')Создание SSML с помощью LLM
Вы можете использовать LLM, чтобы преобразовать обычный текст в сценарии речи с разметкой SSML. Это позволяет сначала писать содержание обычным способом, а затем обрабатывать его для оптимальной передачи через TTS.
import anthropic
client = anthropic.Anthropic(api_key='sk-ant-...')
SSML_GENERATION_PROMPT = (
'Convert the following text into an SSML document for Google Cloud TTS.\n\n'
'Rules:\n'
'- Wrap the entire output in <speak> tags\n'
'- Add <break time="500ms"/> between major points\n'
'- Add <emphasis level="strong"> around key terms or critical information\n'
'- Use <prosody rate="slow"> for important warnings or summaries\n'
'- Use <say-as interpret-as="date"> for all dates\n'
'- Use <say-as interpret-as="telephone"> for phone numbers\n'
'- Return only the SSML, no explanation\n\n'
'Text: {text}'
)
def text_to_ssml(text):
prompt = SSML_GENERATION_PROMPT.format(text=text)
r = client.messages.create(
model='claude-opus-4-5',
max_tokens=2000,
messages=[{'role': 'user', 'content': prompt}]
)
return r.content[0].textПроверка и тестирование SSML
Неправильно сформированный SSML вызывает ошибки интерфейса TTS или приводит к тому, что необработанные теги XML произносятся вслух. Всегда проверяйте SSML перед отправкой в рабочую среду.
import xml.etree.ElementTree as ET
def validate_ssml(ssml_string):
"""
Basic SSML validation: checks XML is well-formed
and has a <speak> root element.
"""
try:
root = ET.fromstring(ssml_string)
if root.tag != 'speak':
return False, 'Root element must be <speak>'
# Check for common misuse patterns
warnings = []
for elem in root.iter():
if elem.tag == 'break' and 'time' not in elem.attrib and 'strength' not in elem.attrib:
warnings.append('<break> has no time or strength attribute')
return True, warnings if warnings else 'Valid'
except ET.ParseError as e:
return False, f'XML parse error: {e}'
# Test
valid_ssml = '<speak>Hello <break time="500ms"/> world.</speak>'
bad_ssml = '<speak>Hello <break> world.</speak>' # break not self-closed
print(validate_ssml(valid_ssml))
print(validate_ssml(bad_ssml))Проверка знаний: интерпретация say-as
Каково основное назначение элемента SSML <say-as>?
Итоги: SSML и управление интонацией
SSML обеспечивает детальный контроль над выводом TTS. Основные элементы: <break> — паузы по времени или уровню воздействия; <emphasis> — уровни акцента: сильный, умеренный и сниженный; <prosody rate> — скорость речи; <prosody pitch> — частота голоса; <say-as> — смысловая интерпретация чисел, дат и номеров телефонов; <phoneme> — явное произношение в IPA. И облачный TTS от Гугл, и сервис Полли от Амазон поддерживают SSML с одним и тем же набором основных тегов. Используйте LLM для автоматического создания SSML из обычного текста и всегда проверяйте корректность XML перед отправкой в рабочую среду.
Изучай AI Prompt Engineering с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 53
- Уроки
- 199
Часто задаваемые вопросы
Урок «SSML и управление просодикой» бесплатный?
Да — полный текст урока «SSML и управление просодикой» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Prompt Engineering, подпишись на CoddyKit PRO. Курс AI Prompt Engineering содержит 4 уроков всего.
Чему я научусь в уроке «SSML и управление просодикой»?
Speech Synthesis Markup Language: паузы, расстановка акцентов, скорость и высота тона. Ты практикуешь AI Prompt Engineering с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Prompt Engineering?
Предыдущий опыт не требуется. AI Prompt Engineering на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «SSML и управление просодикой»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Prompt Engineering?
Да. Каждый урок AI Prompt Engineering включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Шаблоны запросов TTS для естественной речи
- SSML и управление просодикой
- Проектирование персоны голосового искусственного интеллекта
- Мультимодальные голосовые и текстовые агенты