음성 디자인으로 맞춤 음성 만들기

음성 디자인 기능을 사용하여 자연어 설명에서 맞춤 음성을 만들 수 있습니다. 사전 제작된 음성을 선택하거나 참조 오디오를 녹음하는 대신 캐릭터의 나이, 음색, 억양, 기본 전달을 설명하여 음성을 만듭니다. Voices API는 프로젝트에 음성을 저장하고 음성 생성 요청에 전달하는 재사용 가능한 voice_... ID를 반환합니다.

설계된 음성은 Gemini 3.8 Flash TTS(gemini-3.8-flash-tts)와 Gemini 3.8 Flash-Lite TTS(gemini-3.8-flash-lite-tts) 모두에서 작동합니다.

음성 디자인 작동 방식

  1. 프롬프트 음성 만들기: voice.type이 VOICE_TYPE_PROMPTED로 설정되고 store이 true로 설정된 Voices API create 메서드를 호출합니다.
  2. 음성 ID와 샘플 수신: Voices API는 음성을 생성하고 프로젝트에 저장하며 id 필드에 ID (예: voice_abc123...)를 반환하고 sample_audio 필드에 음성 샘플을 반환합니다.
  3. 음성 생성: generateContent 또는 streamGenerateContent를 호출할 때 speechConfig.voiceConfig.voice에 음성 ID를 전달합니다.

시작하기 전에

Gemini TTS 페이지의 시작하기 전에에 나온 단계를 완료합니다. Voices API는 v1beta1 API 버전을 통해 global 위치에서 사용할 수 있습니다.

설계된 음성 만들기

요청에서 다음 필드를 설정합니다.

  • store: true이어야 합니다. 설계된 음성은 항상 프로젝트에 저장됩니다.
  • voice.type: VOICE_TYPE_PROMPTED.
  • voice.prompted.input: 음성에 대한 자연어 설명입니다.
  • voice.display_name, voice.gender, voice.language_code: 선택사항인 음성 메타데이터입니다.

voice.model를 설정하지 마세요. store: true와 함께 모델을 설정하는 요청은 INVALID_ARGUMENT 오류와 함께 실패합니다.

음성을 디자인하는 데 몇 초 정도 걸릴 수 있습니다. Python 샘플은 요청 제한 시간을 60초로 설정합니다.

응답에는 다음 필드가 포함됩니다.

  • id: 새 음성의 ID입니다.
  • sample_audio: 음성 샘플입니다. data 필드에는 base64로 인코딩된 오디오가 포함되고 mime_type 필드에는 인코딩 이름이 지정됩니다. 예를 들어 audio/l16; rate=24000; channels=1는 24kHz의 헤더 없는 16비트 PCM이며 모노입니다.
  • usage: 요청에서 사용한 토큰 수입니다. 자세한 내용은 가격 책정을 참고하세요.

Python

import base64
import wave

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

voice = client.voices.create(
    store=True,
    voice={
        "type": "VOICE_TYPE_PROMPTED",
        "display_name": "Warm British Astronomer",
        "gender": "male",
        "language_code": "en-GB",
        "prompted": {
            "input": (
                "A warm, thoughtful astronomer in his late 60s with a gentle"
                " British accent, speaking with quiet wonder."
            )
        },
    },
    timeout=60,
)

print(f"Created voice ID: {voice.id}")

# Save the voice sample. The SDK returns sample_audio.data as a base64
# string. Raw 16-bit PCM (audio/l16) needs a WAV header.
sample = base64.b64decode(voice.sample_audio.data)
if voice.sample_audio.mime_type.lower().startswith("audio/l16"):
    with wave.open("voice_sample.wav", "wb") as wf:
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(24000)
        wf.writeframes(sample)
else:
    with open("voice_sample.wav", "wb") as f:
        f.write(sample)

REST

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices \
  -d '{
    "store": true,
    "voice": {
      "type": "VOICE_TYPE_PROMPTED",
      "displayName": "Warm British Astronomer",
      "gender": "male",
      "languageCode": "en-GB",
      "prompted": {
        "input": "A warm, thoughtful astronomer in his late 60s with a gentle British accent, speaking with quiet wonder."
      }
    }
  }' > created_voice.json

# Print the voice ID and the encoding of the voice sample.
jq -r '.id, .sample_audio.mime_type' created_voice.json

# Decode the voice sample.
jq -r '.sample_audio.data' created_voice.json | base64 --decode > voice_sample.pcm

sample_audio.mime_type가 audio/l16인 경우 voice_sample.pcm 파일에는 24kHz, 모노의 헤더 없는 16비트 PCM 오디오가 포함됩니다.

내 텍스트로 음성을 들으려면 다음 섹션에 표시된 대로 텍스트를 사용하여 음성을 생성하세요.

설계된 음성으로 음성 생성

speechConfig.voiceConfig.voice에서 음성 ID를 전달합니다.

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

response = client.models.generate_content(
    model="gemini-3.8-flash-tts",
    contents=[{
        "role": "user",
        "parts": [{
            "text": (
                "Look out past the rings of Saturn. Those faint photons left"
                " their source millions of years ago."
            ),
            "speech_metadata": {"style": "reflective and awe-inspired"},
        }],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {"voice_config": {"voice": "VOICE_ID"}},
    },
)

# The SDK has already decoded the base64 audio, so inline_data.data is a
# complete WAV file by default.
with open("designed_voice.wav", "wb") as f:
    f.write(response.candidates[0].content.parts[0].inline_data.data)

REST

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.8-flash-tts:generateContent \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [{
        "text": "Look out past the rings of Saturn. Those faint photons left their source millions of years ago.",
        "speechMetadata": {"style": "reflective and awe-inspired"}
      }]
    }],
    "generationConfig": {
      "responseModalities": ["AUDIO"],
      "speechConfig": {
        "voiceConfig": {"voice": "VOICE_ID"}
      }
    }
  }' | jq -r '.candidates[0].content.parts[0].inlineData.data' | base64 --decode > designed_voice.wav

VOICE_ID를 create 메서드에서 반환한 음성 ID로 바꿉니다.

저장된 음성 관리

설계된 음성 및 저장된 복제 음성을 비롯하여 프로젝트에 저장된 음성을 나열하고 가져오고 삭제할 수 있습니다. list 메서드는 프로젝트에 저장된 음성을 반환한 다음 사전 빌드된 음성과 확장 음성 라이브러리 음성을 반환합니다. 프로젝트에 저장된 음성만 나열하려면 다음 샘플과 같이 type 필터를 prompted 및 replicated로 설정합니다. get 메서드는 설계된 음성의 샘플도 sample_audio 필드에 반환합니다.

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

# List the voices stored in your project.
for voice in client.voices.list(type_=["prompted", "replicated"]).voices or []:
    print(voice.id, voice.display_name, voice.type)

# Get a voice by ID.
voice = client.voices.get(id="VOICE_ID")

# Delete a voice.
client.voices.delete(id="VOICE_ID")

REST

# List the voices stored in your project.
curl -G \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices \
  --data-urlencode "type=prompted" \
  --data-urlencode "type=replicated"

# Get a voice by ID.
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices/VOICE_ID

# Delete a voice.
curl -X DELETE \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices/VOICE_ID

한도

  • 저장된 음성은 마지막으로 사용한 후 1년이 지나면 만료됩니다. 음성으로 음성을 생성하면 이 기간이 다시 시작되므로 정기적으로 사용하는 음성은 만료되지 않습니다. 더 이상 필요하지 않은 음성을 삭제합니다.
  • 음성 생성 요청에는 프로젝트별 분당 할당량이 적용됩니다. 이 한도를 초과하면 create 메서드가 RESOURCE_EXHAUSTED 오류를 반환합니다. 기다렸다가 다시 시도하세요. 자세한 내용은 할당량 및 시스템 한도를 참고하세요.

가격 책정

설계된 음성 생성은 Gemini 3.8 Flash TTS 요율로 텍스트 입력 토큰 및 오디오 출력 토큰으로 청구됩니다. 오디오 출력 토큰은 Voices API가 생성하는 음성 샘플을 포함합니다. create 응답의 usage 필드는 두 개수를 모두 보고합니다. 예를 들어 샘플 만들기의 한 문장 설명은 약 220개의 입력 토큰과 약 1,100개의 출력 토큰을 사용합니다.

get, list, delete 메서드는 청구되지 않습니다. 설계된 음성으로 생성한 음성은 호출한 모델의 요율로 청구됩니다.

토큰 요금은 Gemini Enterprise 가격 책정을 참고하세요.

프롬프트 권장사항

  • 음성 설명에 영구적인 특징 넣기: speech_metadata.style이 아닌 음성을 만들 때 연령, 성별, 음색, 보컬 질감, 지역 사투리를 정의합니다.
  • 상황에 맞는 감정을 표현할 때 speech_metadata.style 사용: 음성을 만든 후 "whispered urgently" 또는 "cheerful and energetic"와 같은 짧은 style 값을 사용하여 화자의 신원을 변경하지 않고 각 턴을 지시합니다.
  • 구체적이고 간결하게 작성: '30대 초반의 활기차고 명쾌한 스포츠 아나운서, 중서부 사투리가 약간 있음'과 같이 명확한 1~2문장 설명이 길거나 모순된 단락보다 더 일관된 결과를 생성합니다.

다음 단계

  • 음성 복제를 사용하여 기존 화자의 음성을 복제합니다.
  • Gemini TTS로 음성 생성에서 턴 수준 스타일 지정, 인라인 태그, 다중 화자 대화에 대해 알아보세요.