KO ▾

음성 파이프라인용 무검열 텍스트 API

uncensoredhttps://api.xtts.cc/v1

TTS API 데모: 실시간 요청 및 응답 예시

이 데모는 1분 안에 실행할 수 있는 실제 요청과 반환되는 응답 형식을 보여줍니다. 이 API는 텍스트 모델이므로 출력물은 스크립트 텍스트, JSON 및 별도 음성 엔진이 읽어낼 수 있는 도구 호출입니다.

업데이트

텍스트, 데이터 및 함수 호출 스트림을 방출하는 터미널의 등각 도해

실행하기 전에

재생 버튼을 누르고 음성을 기대하는 모든 이들을 위한 정직한 경고: 이 TTS API 데모는 소리를 생성하지 않습니다. 이 서비스는 uncensored 모델을 통해 POST /v1/chat/completions로 텍스트를 반환합니다. GET /v1/models 엔드포인트는 사용 가능한 모델을 나열합니다. 오디오, 이미지 또는 임베딩을 반환하는 것은 없습니다.

그렇다면 왜 데모인가요? 많은 음성 프로젝트에 정확히 이 부분이 필요하기 때문입니다: 대본 작성기, 텍스트 정리기, 누가 무엇을 말하는지 결정하는 분할기. 하단의 예시는 이러한 작업을 보여주며, 출력 형식은 귀하의 음성 코드가 구문 분석하는 방식입니다.

API 키가 필요합니다. API 키 페이지에서 Google 또는 이메일과 비밀번호로 로그인한 후 한 번의 클릭으로 $0.50 무료 체험 크레딧을 사용하세요. 7일 동안 유효하며 카드가 필요하지 않습니다. 아래 명령어가 키를 읽을 수 있도록 내보내세요:

export XTTS_API_KEY="paste-your-key-here"
curl -s https://api.xtts.cc/v1/models -H "Authorization: Bearer $XTTS_API_KEY" | grep uncensored

해당 호출이 uncensored를 포함하는 JSON 목록을 반환하면 키가 작동하며 계속 진행할 수 있습니다.

데모 1: 일반 요청

가장 작은 유용한 호출은 짧은 구어체 단락을 요청합니다:

curl -s https://api.xtts.cc/v1/chat/completions \
  -H "Authorization: Bearer $XTTS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "uncensored",
    "messages": [
      {"role": "system", "content": "You write short lines for a voice actor. No stage directions."},
      {"role": "user", "content": "Welcome listeners to a show about lighthouses. Two sentences."}
    ],
    "temperature": 0.7,
    "max_tokens": 120
  }'

응답은 하단 샘플과 같습니다. content 내부의 텍스트는 실행할 때마다 다르므로 구조의 예시일 뿐 녹음된 출력이 아님을 유의하세요.

{
  "id": "chatcmpl-example",
  "object": "chat.completion",
  "model": "uncensored",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Welcome to the show. Tonight we climb the stairs of the world's loneliest lighthouses."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {"prompt_tokens": 38, "completion_tokens": 21, "total_tokens": 59}
}

귀하의 음성 코드는 choices[0].message.content를 읽습니다. finish_reason은 생성이 종료된 이유를 알려줍니다: 자연스러운 종료를 위해 stop, max_tokens이 단축한 경우 length. max_tokens을 생략하면 완료는 프롬프트와 완료를 합친 100,000개 토큰 창에 남아 있는 모든 것을 사용할 수 있습니다.

헤더가 알려주는 정보

curl 명령어에 -i를 추가하면 X-Request-Id, X-Balance-USD, X-RateLimit-Limit-Requests 및 X-RateLimit-Limit-Concurrency을 볼 수 있습니다. 데모에서 잔액 헤더는 각 호출 후 약간 떨어지는 것을 관찰할 수 있으므로 유용합니다. 이 요청의 사용량은 38 x $0.15 / 1,000,000 + 21 x $0.50 / 1,000,000으로 계산되며, 이는 $0.0000057 + $0.0000105, 약 $0.0000162입니다.

데모 2: 스크립트 스트리밍

오디오의 경우 전체 텍스트가 생성되기를 기다리는 경우가 드뭅니다. "stream": true를 추가하면 API는 서버 전송 이벤트를 통해 한 번에 작은 텍스트 조각 하나씩 전송합니다. 아래 Node 예제는 텍스트가 도착할 때마다 출력하며, 이는 문장 큐에 공급할 수 있는 지점입니다.

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.xtts.cc/v1",
  apiKey: process.env.XTTS_API_KEY,
});

const stream = await client.chat.completions.create({
  model: "uncensored",
  stream: true,
  messages: [
    { role: "user", content: "Read a four-line weather report for a coastal town." },
  ],
});

for await (const chunk of stream) {
  const piece = chunk.choices[0]?.delta?.content ?? "";
  process.stdout.write(piece);
}
process.stdout.write("\n");

ES 모듈로 실행하세요 (demo.mjs로 저장하고 npm install openai 후 node demo.mjs로 실행). 네트워크 상에서 각 이벤트는 data:로 시작하는 줄과 JSON으로 구성되며, 스트림은 최종 마커로 종료됩니다. 토큰 사용량은 스트림 끝에 보고됩니다. 계획 시 한 가지가 중요합니다: 스트리밍 요청은 스트림이 끝날 때까지 동시성 슬롯을 유지하므로, 느린 소비자가 다음 요청을 차단할 수 있습니다.

데모 3: 음성 라우터로서의 함수 호출

함수 호출은 모델이 산문 대신 구조화된 지시를 반환하게 합니다. 음성 프로젝트에서는 줄마다 전달 스타일을 선택하는 깔끔한 방법입니다. say라는 함수를 정의하고 모델이 인수를 채웁니다. 귀하의 코드는 이를 처리할 방법을 결정합니다. 모델은 자체적으로 아무것도 실행하지 않습니다.

import json
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.xtts.cc/v1", api_key=os.environ["XTTS_API_KEY"])

tools = [{
    "type": "function",
    "function": {
        "name": "say",
        "description": "Queue one line for the voice engine.",
        "parameters": {
            "type": "object",
            "properties": {
                "text": {"type": "string"},
                "style": {"type": "string", "enum": ["calm", "urgent", "whisper"]},
            },
            "required": ["text", "style"],
        },
    },
}]

messages = [
    {"role": "system", "content": "Always answer by calling say, once per line."},
    {"role": "user", "content": "The alarm sounds. The guard tells everyone to leave."},
]

r = client.chat.completions.create(
    model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)

msg = r.choices[0].message
for call in msg.tool_calls or []:
    args = json.loads(call.function.arguments)
    print(args["style"], "->", args["text"])

인수는 JSON 문자열로 제공되므로 사용 전에 구문 분석하고 검증해야 합니다. 모델은 열거형 외부의 스타일을 생성하거나 필드를 생략할 수 있으며, 검증되지 않은 값이 엔진에 도달해서는 안 됩니다. 대화를 계속하려면 어시스턴트 메시지와 role: "tool" 및 일치하는 tool_call_id을 포함하는 응답을 추가한 후 API를 다시 호출하세요.

스트리밍 중에는 함수 호출이 조각으로 도착합니다. 함수 이름이 먼저 오고 인수 문자열은 청크에 걸쳐 구축되므로, 스트림이 끝날 때까지 인덱스별로 조각을 수집한 후 한 번에 구문 분석하세요.

데모 4: 캐스트 목록을 위한 JSON 모드

함수 정의를 건너뛰고 싶다면 JSON 모드가 메시지 콘텐츠에 유효한 JSON을 제공합니다. 이는 대략적인 장면을 화자별 줄로 변환하는 데 적합합니다.

curl -s https://api.xtts.cc/v1/chat/completions \
  -H "Authorization: Bearer $XTTS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "uncensored",
    "response_format": {"type": "json_object"},
    "temperature": 0.2,
    "messages": [
      {"role": "system", "content": "Return JSON: {\"lines\": [{\"speaker\": string, \"text\": string}]}"},
      {"role": "user", "content": "Ana asks Ben to hold the ladder. Ben agrees reluctantly."}
    ]
  }'

JSON 모드는 출력이 구문 분석됨을 보장하지만 형식과 일치함을 보장하지는 않습니다. 프롬프트에서 형식을 설명하고 코드에서 키를 확인하세요. 낮은 온도는 구조를 안정적으로 유지합니다.

데모 5: 단일 요청으로 긴 문서 처리

컨텍스트 창은 프롬프트와 생성 결과가 함께 사용하는 100,000 토큰입니다. 이는 긴 대본이나 짧은 소설 전체를 보내고 귀에 맞게 작성된 버전을 요청하기에 충분합니다. 요청 본문은 최대 8 MB까지 가능하므로 크기가 제한이 되는 경우는 드뭅니다. 토큰 수가 제한입니다.

무거운 호출의 비용은 다음과 같습니다. 80,000 토큰을 보내고 2,000 토큰을 받는다고 가정합니다. 입력: 80,000 x $0.15 / 1,000,000 = $0.012. 출력: 2,000 x $0.50 / 1,000,000 = $0.001. 총합은 $0.013이므로 $0.50 무료 체험 크레딧은 약 38회 호출을 커버합니다. 긴 입력은 긴 출력에 비해 저렴하므로 큰 텍스트의 요약과 수정은 저렴하지만 한 번에 전체 소설을 생성하는 것은 비쌉니다.

긴 입력을 위한 실용적인 팁: 지시를 먼저 넣고 핵심 규칙을 끝에 반복하세요. 모델은 가장 최근의 지시를 따르는 경향이 있으며, 80,000개 토큰의 소스 텍스트 뒤에 한 줄의 알림을 추가하는 비용은 거의 들지 않습니다.

데모에서 오류 읽기

의도적으로 무언가를 깨뜨려 나중에 식별할 수 있게 하세요. 잘못된 키로 요청을 보내면 완료가 아닌 인증 오류가 발생합니다. 체험 키로 동시에 10개의 요청을 보내면 일부가 HTTP 429로 반환됩니다.

429는 세 가지 원인이 있으며, 오류 코드가 이를 구분합니다:

  • rate_limited은 1분당 요청이 너무 많음을 의미합니다: 체험 키는 60개, 전체 키는 300개.
  • concurrency는 동시에 처리 중인 요청이 너무 많음을 의미합니다: 체험 키는 2개, 전체 키는 8개입니다.
  • Retry-After: 5 헤더가 있는 429는 서비스가 일시적으로 과부하 상태였음을 의미합니다. 5초를 기다린 후 다시 전송하세요.

실패하거나 거부된 요청은 요금이 부과되지 않으므로 오류는 비용이 들지 않습니다. 키의 제한을 확인하려면 일반 응답에서 X-RateLimit-Limit-Requests 및 X-RateLimit-Limit-Concurrency을 읽으세요. Retry-After 값만큼 일시 중지하거나 누락된 경우 5초 동안 대기하는 작은 재시도 루프는 데모 스크립트에 필요한 모든 것입니다.

다음에 시도할 항목

이 네 가지 호출이 작동하면 스크립트 파이프라인의 구성 요소를 갖추게 됩니다. 일반 요청을 함수로 감싸고 스트리밍 루프를 큐에 보내며 큐를 선택한 음성 엔진에 연결합니다. 엔진은 가격, 라이선스 및 품질이 다르므로 현재 약관을 읽어보십시오. 이 서비스는 엔진을 제공하지 않으며 엔진에 대해 아무것도 명시하지 않습니다.

실험하는 동안 비용은 작게 유지됩니다. 입력 토큰 100만 개당 $0.15, 출력 토큰 100만 개당 $0.50으로 일반적인 데모 호출은 센트의 일부 비용이 들며 $0.50 무료 체험 크레딧은 수백 건을 커버합니다. $20부터 $500까지 보너스 5%에서 15%를 제공하는 가격 책정 페이지에서 선불 크레딧을 충전하세요. 문서에는 전체 매개변수 목록, 속도 제한(전체 키 기준 동시 8회 및 분당 300회) 및 오류 코드가 포함되어 있습니다. 프롬프트는 학습에 사용되지 않습니다.

첫 번째 오후를 위한 적절한 순서는 다음과 같습니다: 음성이 맞을 때까지 일반 요청을 실행한 후 스트리밍으로 전환하고 문장이 완료될 때마다 출력한 다음, 음성 코드가 입력을 원하는 방식에 맞는 함수 호출 또는 JSON 모드 중 하나를 추가합니다. 버전 관리 시스템 하에 있는 파일에 모든 프롬프트를 유지합니다. 최종 오디오에서 줄이 잘못 들리면 이를 생성한 정확한 지시로 거슬러 올라가 한 번에 한 가지씩 변경할 수 있습니다.

질문과 답변

이 데모에서 샘플 음성을 들을 수 있나요?

아니요. API는 텍스트, JSON 및 함수 호출만 반환합니다. 텍스트를 오디오로 변환하려면 별도의 음성 엔진을 제공해야 합니다.

어떤 모델 ID를 보내야 하나요?

기본 URL https://api.xtts.cc/v1과 Authorization: Bearer 헤더에 API 키를 포함하여 모델 값으로 uncensored를 전송합니다.

체험 키로 데모를 실행할 수 있나요?

네. 체험 키는 분당 60회, 동시 2개의 요청을 허용하므로 이 예시들을 실행하기에 충분합니다. 한 번에 하나씩 실행하세요.

429 응답을 받는 이유는 무엇인가요?

분당 요청 수(rate_limited)를 초과했거나 동시에 열린 요청이 너무 많았거나(concurrency) 서비스의 일시적 과부하가 발생했습니다. Retry-After가 제공되면 해당 값을 기다린 후 다시 시도합니다.

키는 양식 하나만 작성하면 받을 수 있습니다

계정을 생성하고 키를 복사한 후 기본 URL을 변경하세요. 설정은 이것으로 끝입니다.