Fish Audio S2 Pro는 Novita AI에서 콜드 스타트 없이 사용할 수 있는 호스티드 TTS API로 제공됩니다. 이 빠른 시작 가이드는 개발자를 위한 과정을 다룹니다: API 키 발급, 엔드포인트 확인, 복제된 음성으로 첫 TTS 요청 전송, 그리고 음성 복제 및 감정 제어에 중요한 파라미터 이해하기. S2 Pro는 방대한 다국어 코퍼스로 학습된 Dual-Autoregressive 아키텍처를 기반으로 구축되었습니다 — 이 모델을 일반 TTS와 차별화하는 기능은 복제된 모든 음성이 재학습 없이 지원되는 모든 언어에서 작동한다는 점입니다.
이 빠른 시작 가이드를 사용해야 하는 경우
다음과 같은 경우에 이 가이드를 사용하세요:
- 다양한 지원 언어로 된 텍스트를 사용자 정의 복제 음성으로 음성 합성해야 하는 경우.
- 10~30초 길이의 오디오 샘플로 음성을 복제하고, 요청당 추가 비용 없이 여러 요청에 걸쳐 재사용해야 하는 경우.
- 자연어 대괄호 태그(
[whisper],[excited])를 사용하여 운율과 감정을 인라인으로 제어해야 하는 경우. - 언어별 개별 통합 없이 다국어 TTS가 필요한 파이프라인을 구축해야 하는 경우.
기본 제공 음성으로 복제 없이 기본적인 영어 TTS만 필요한 경우, 먼저 Fish Audio S1 모델 또는 GLM TTS를 평가해 보세요 — S2 Pro의 장점은 교차 언어 복제 또는 세밀한 감정 제어가 필요할 때 드러납니다.
1단계: Novita API 키 발급
Novita AI 계정을 생성하고 Novita AI 콘솔에서 API 키를 발급받으세요. 환경 변수로 저장합니다:
export NOVITA_API_KEY="your_api_key_here"
키는 클라이언트 측 코드, 프론트엔드 번들, 공개 저장소에 저장하지 마세요.
2단계: 모델 및 엔드포인트 확인
Fish Audio S2 Pro TTS에 대한 Novita AI 문서는 Fish Audio S2 Pro API 레퍼런스에서 확인할 수 있습니다. 코딩 전에 해당 레퍼런스에서 현재 엔드포인트 경로와 모델 식별자를 확인하세요 — 호스티드 엔드포인트 URL과 요청 스키마는 해당 레퍼런스에서 확인할 수 있습니다.
음성 복제를 위해 워크플로우 전반에 걸쳐 세 개의 Novita 엔드포인트가 사용됩니다:
| 단계 | 메서드 | 엔드포인트 |
|---|---|---|
| 오디오 샘플 업로드 | POST |
https://api.novita.ai/v1/files |
| 복제 생성 (비동기) | POST |
https://api.novita.ai/v1/async/voice-cloning |
| 결과 폴링 | GET |
https://api.novita.ai/v1/async/task-result |
| 복제 음성 TTS | POST |
https://api.novita.ai/v4beta/txt2speech |
음성 복제는 TTS 모델과 별도로 복제 생성 단계에서 fish-audio-voice-cloning 모델을 사용합니다.
3단계: 음성 복제
음성 복제는 세 번의 API 호출로 이루어집니다: 짧은 오디오 샘플 업로드, 복제 생성, voice_id 검색. voice_id를 획득하면 추가 비용 없이 TTS 요청에 무기한 재사용할 수 있습니다.
오디오 샘플 요구사항:
- 길이: 10~30초가 가장 좋은 결과를 제공합니다
- 형식: MP3 또는 WAV
- 내용: 배경 소음이 최소화된 깨끗한 음성
- 텍스트: 정확한 음성 텍스트를 제공하면 복제 정확도가 향상됩니다
Python: 전체 복제 워크플로우
import base64
import os
import time
import requests
API_KEY = os.environ["NOVITA_API_KEY"]
BASE_URL = "https://api.novita.ai"
# Step 1: 오디오 파일 업로드
with open("voice_sample.mp3", "rb") as f:
encoded_audio = base64.b64encode(f.read()).decode("utf-8")
upload_response = requests.post(
f"{BASE_URL}/v1/files",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"file": encoded_audio,
"purpose": "voice-cloning",
},
)
upload_response.raise_for_status()
file_id = upload_response.json()["file_id"]
print(f"업로드된 파일 ID: {file_id}")
# Step 2: 음성 복제 생성
clone_response = requests.post(
f"{BASE_URL}/v1/async/voice-cloning",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"model": "fish-audio-voice-cloning",
"audio_file_id": file_id,
"text": "오디오 샘플에서 말한 텍스트를 여기에 입력합니다.",
},
)
clone_response.raise_for_status()
task_id = clone_response.json()["task_id"]
print(f"복제 작업 ID: {task_id}")
# Step 3: voice_id 폴링
voice_id = None
while True:
result = requests.get(
f"{BASE_URL}/v1/async/task-result",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"task_id": task_id},
).json()
if result["status"].endswith("SUCCEED"):
voice_id = result["result"]["voice_id"]
print(f"복제된 음성 ID: {voice_id}")
break
elif "FAILED" in result["status"]:
raise RuntimeError(f"복제 실패: {result}")
time.sleep(2)
voice_id를 저장하세요. 모든 TTS 호출에서 reference_id로 사용됩니다.
cURL: 복제 생성 (파일 업로드 후)
curl -s -X POST https://api.novita.ai/v1/async/voice-cloning \
-H "Authorization: Bearer $NOVITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "fish-audio-voice-cloning",
"audio_file_id": "YOUR_FILE_ID",
"text": "오디오 샘플에서 말한 텍스트를 여기에 입력합니다."
}'
4단계: TTS 요청 전송
3단계에서 voice_id를 획득한 후, TTS 요청에서 reference_id로 전달하세요. 모델은 복제된 음성으로 음성을 생성합니다.
Python
import os
import requests
API_KEY = os.environ["NOVITA_API_KEY"]
VOICE_ID = "your_cloned_voice_id" # 3단계에서 획득
response = requests.post(
"https://api.novita.ai/v4beta/txt2speech",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"text": "데모에 오신 것을 환영합니다. 이 음성은 짧은 오디오 샘플에서 복제되었습니다.",
"reference_id": VOICE_ID,
"format": "mp3",
"sample_rate": 44100,
},
)
response.raise_for_status()
audio_url = response.json()["audio_url"]
print(f"오디오 URL: {audio_url}")
cURL
curl -s -X POST https://api.novita.ai/v4beta/txt2speech \
-H "Authorization: Bearer $NOVITA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "데모에 오신 것을 환영합니다. 이 음성은 짧은 오디오 샘플에서 복제되었습니다.",
"reference_id": "YOUR_CLONED_VOICE_ID",
"format": "mp3",
"sample_rate": 44100
}'
응답에는 생성된 오디오 파일을 가리키는 사전 서명된 URL인 audio_url이 포함됩니다.
5단계: 가격, 제한 사항 및 일반 오류 확인
가격 (최신 요금은 novita.ai/pricing에서 확인):
| 작업 | 가격 |
|---|---|
| TTS 생성 | ~$15.00 / 100만 문자 |
| 음성 복제 | 음성당 $0.10 (일회성) |
음성 복제는 복제당 한 번 청구되며, TTS 요청당 청구되지 않습니다. 복제 후 TTS 호출에서 voice_id를 사용하면 문자 기반 TTS 요금만 부과됩니다.
요청당 제한:
| 제한 | 값 |
|---|---|
| 최대 입력 길이 | 10,000자 |
| 복제 권장 샘플 길이 | 10~30초 |
| 지원 출력 형식 | mp3, opus, wav, pcm |
| 오디오 샘플 레이트 | 최대 44,100 Hz |
일반 오류:
| 오류 | 원인 | 해결 방법 |
|---|---|---|
401 Unauthorized |
API 키가 유효하지 않거나 누락됨 | NOVITA_API_KEY가 설정되어 있고 올바른지 확인 |
파일 업로드 시 400 Bad Request |
오디오 파일이 너무 크거나 형식이 잘못됨 | MP3/WAV 사용, 수 MB 이하 유지 |
복제 작업 FAILED 상태 |
오디오 샘플이 너무 짧거나 노이즈가 많음 | 10~30초의 깨끗한 음성 사용 |
| 빈 오디오 또는 깨진 오디오 | text 필드가 비어 있거나 제한 초과 |
입력을 10,000자 미만으로 유지 |
감정 제어 태그
S2 Pro는 인라인 [bracket] 태그를 지원하여 모델이 특정 단어나 구문을 렌더링하는 방식을 제어합니다. 이 태그는 생성 중 자연어 명령으로 해석되며 — 고정된 토큰 목록에 제한되지 않습니다.
text_with_emotion = (
"[cheerful] 다시 오신 것을 환영합니다! [pause] "
"정말 반갑습니다. "
"[whisper] 우리끼리만 하는 말인데, 이 부분은 비밀입니다. [normal] "
"어쨌든, 시작해 볼까요."
)
response = requests.post(
"https://api.novita.ai/v4beta/txt2speech",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"text": text_with_emotion,
"reference_id": VOICE_ID,
"format": "mp3",
"sample_rate": 44100,
},
)
모델이 이해하는 대괄호 태그 예시:
| 태그 | 효과 |
|---|---|
[whisper] |
속삭이는 전달 |
[excited] |
높은 에너지, 빠른 속도 |
[calm] |
느리고 절제된 톤 |
[laughs] |
음성에 포함된 웃음 |
[professional broadcast tone] |
앵커 스타일 전달 |
[pitch up] |
다음 텍스트의 피치 높임 |
[pause] |
짧은 멈춤 |
태그는 고정된 열거형 값이 아닌 자유 형식의 설명입니다. 모델은 학습 데이터에서 태그-음향 매핑을 학습했으므로 설명적인 구문도 작동합니다. 사용 사례에 맞는 특정 태그를 실험해 보세요. 일반적이지 않은 표현의 경우 결과가 다를 수 있습니다.
주요 파라미터
| 파라미터 | 타입 | 설명 |
|---|---|---|
text |
string | 필수. 최대 10,000자. |
reference_id |
string | 필수. 음성 모델 ID — 복제된 voice_id 또는 시스템 음성 레퍼런스. |
format |
string | 출력 형식: mp3, opus, wav, pcm. 기본값: mp3. |
sample_rate |
integer | 오디오 샘플 레이트(Hz). 고음질을 위해 44100 권장. |
temperature |
number | 생성 랜덤성 제어. 높을수록 더 다양한 운율. |
top_p |
number | Nucleus 샘플링 임계값. |
전체 파라미터 스키마 및 추가 S2 Pro 관련 옵션은 Novita AI Fish Audio S2 Pro API 레퍼런스를 참조하세요.
문제 해결
복제된 음성이 로봇처럼 들리거나 일관성이 없습니다.
샘플이 너무 짧거나 배경 소음이 있을 가능성이 높습니다. 일관된 속도와 중첩 없는 깨끗한 20~30초 클립을 녹음하세요. 복제 요청에 샘플의 정확한 text 내용을 제공하면 음소 정렬이 개선됩니다.
폴링 후 오디오 URL이 404를 반환합니다. 사전 서명된 URL은 만료됩니다. URL을 받은 후 즉시 오디오를 다운로드하거나 처리하세요.
감정 태그가 예상한 효과를 내지 못합니다.
태그 동작은 학습 데이터 분포에 따라 다릅니다. [quiet] 대신 [very softly, barely audible]과 같이 더 설명적인 표현을 시도해 보세요. 일부 태그는 다른 태그보다 더 잘 작동합니다. 짧은 입력으로 먼저 테스트하세요.
복제 작업 상태가 보류 상태로 유지됩니다.
작업 결과 엔드포인트의 속도 제한을 피하기 위해 폴링 간격(확인 사이에 1~2초)을 추가하세요. 작업이 2분 이상 보류 상태로 남아 있으면 파일 업로드 단계를 확인하세요 — file_id가 만료되었을 수 있습니다.
여러 언어에서 동일한 음성을 사용해야 합니다.
지원되는 모든 언어의 텍스트와 함께 동일한 voice_id를 전달하세요. S2 Pro는 별도의 복제 없이 복제된 음색을 새 언어에 적용합니다. 지원되는 언어 목록은 S2 Pro API 레퍼런스를 확인하세요.
자주 묻는 질문
S2 Pro가 Fish Audio S1과 다른 점은 무엇인가요? S2 Pro는 방대한 다국어 코퍼스로 학습된 더 큰 Dual-Autoregressive 아키텍처를 사용합니다. 실질적인 차이점은 더 넓은 언어 지원, 대괄호 태그를 통한 인라인 감정 제어, S1에서는 사용할 수 없는 다중 화자 합성 기능입니다. 현재 언어 목록은 S2 Pro API 레퍼런스를 참조하세요.
음성을 한 번 복제하여 지원되는 모든 언어에 사용할 수 있나요?
네. 영어 샘플에서 복제된 음성은 동일한 voice_id를 사용하여 일본어, 스페인어, 아랍어 또는 지원되는 다른 모든 언어로 음성을 생성할 수 있습니다. 모델은 추가 학습 없이 언어 간에 음색을 전송합니다.
음성 샘플은 얼마나 길어야 하나요? 10~30초의 깨끗하고 일관된 음성이 좋습니다. 더 짧은 샘플도 작동할 수 있지만 결과가 덜 안정적일 수 있습니다. 30초가 넘는 샘플은 복제 품질을 의미 있게 향상시키지 않습니다.
음성 복제는 TTS 요청당 청구되나요?
아니요. $0.10의 음성 복제 비용은 복제당 일회성 요금입니다. 생성 후 TTS 요청에서 해당 voice_id를 사용하면 문자당 TTS 요금만 부과됩니다.
reference_id를 생략하면 어떻게 되나요?
현재 기본 동작은 S2 Pro API 레퍼런스를 확인하세요 — 모델이 기본 음성을 사용하거나 레퍼런스가 필요할 수 있습니다.
API 키는 어떻게 받나요? novita.ai에 가입하고 Novita AI 콘솔에서 키를 생성하세요.
