Speech-to-Text (STT)
녹음 파일이나 실시간 마이크 음성을 텍스트로 바꿉니다. Whisper 계열(OpenAI·Replicate)과 Meta Muse Voice Transcribe로 전사, 화자 구분, 타임스탬프, 실시간 부분 전사를 지원합니다.
텍스트 → 🔊 음성
- 입력
- 읽어 줄 문장 text + 목소리 voice_id / speaker
- 출력
- 오디오 파일 URL (mp3·wav 등)
- 용도
- 안내 멘트, 내레이션, 오디오북, 챗봇 음성 응답
🎙 음성 → 텍스트
- 입력
- 오디오 파일 URL audio (또는 실시간 PCM 스트림)
- 출력
- 전사 텍스트 + 구간·타임스탬프·화자 (JSON)
- 용도
- 회의록, 자막, 콜센터 녹취, 음성 명령
글자를 소리로 읽어 주려는 경우라면 이 문서가 아닙니다 — 음성 합성 (TTS) 문서로 가세요. 두 방향은 모델·입력 파라미터가 서로 다르며, 한쪽 모델에 다른 쪽 파라미터(text↔audio)를 넣으면 요청이 거부되거나 실패합니다.
호출 방식 고르기
STT는 호출 방식이 세 가지입니다. 모델보다 먼저 방식을 고르세요 — 엔드포인트·입력 형식·응답 받는 법이 모두 다릅니다.
| 방식 | 엔드포인트 | 오디오 입력 | 결과 받기 | 모델 |
|---|---|---|---|---|
| ① 파일 전사 대부분 이것 | POST /v1/predictions | 오디오 파일 URL (audio, whisper-diarization은 file_url) | job_id를 받고 GET /v1/predictions/{id} 폴링 | openai/gpt-transcribe, openai/whisper-1, openai/whisper, incredibly-fast-whisper, whisper-diarization, meta/muse-voice-transcribe-1.0 |
| ② 실시간 스트리밍 말하는 동안 자막 | wss://api.core.today/v1/realtime/asr | raw PCM 16-bit 모노 바이너리 프레임 (1배속) | 부분·최종 전사 이벤트가 같은 소켓으로 | meta/muse-voice-transcribe-1.0/realtime |
| ③ OpenAI SDK 호환 기존 OpenAI 코드 이전 | POST /llm/openai/v1/audio/transcriptions | 파일 직접 업로드 (multipart file, URL 아님) | 응답 본문으로 즉시 (폴링 없음) | gpt-transcribe, whisper-1 |
모델 비교표
| 모델 | 가격 | 호출 방식 | 제공 |
|---|---|---|---|
| openai/gpt-transcribe | 11크레딧 오디오 1분당 (초당 0.174375, 실측 길이로 정산) | 파일 전사 (비동기) | OpenAI |
| vaibhavs10/incredibly-fast-whisper | 10크레딧 실행당 | 파일 전사 (비동기) | Whisper |
| meta/muse-voice-transcribe-1.0 | 7크레딧 오디오 1분당 (초당 0.11625, 실측 길이로 정산) | 파일 전사 (비동기) | Meta |
| meta/muse-voice-transcribe-1.0/realtime | 35크레딧 5분 블록당 (초당 0.11625 크레딧) | 실시간 (WebSocket) | Meta |
| openai/whisper-1 | 14크레딧 오디오 1분당 (초당 0.2325, 실측 길이로 정산) | 파일 전사 (비동기) | OpenAI |
| openai/whisper | 14크레딧 오디오 1분당 (초당 0.2325, 최소 10크레딧, 실측 길이로 정산) | 파일 전사 (비동기) | OpenAI |
| thomasmol/whisper-diarization | 14크레딧 실행당 | 파일 전사 (비동기) | Whisper |
로컬 파일은 POST /v1/files/upload-url로 먼저 업로드한 뒤 그 URL을 audio에 넣으세요. 실행당 과금 모델은 처리 시간이 오디오 길이에 비례하고, 분당 과금 모델은 실측 길이로 정산해 차액을 환불합니다.
모델 상세 정보
각 모델의 전체 파라미터, 출력 형식, 예제는 개별 문서에서 확인하세요.
GPT Transcribe (OpenAI API)
OpenAI
whisper-1의 후속인 OpenAI gpt-transcribe 음성 인식입니다. 전사 텍스트와 감지된 언어를 반환하고, 언어 힌트와 키워드 철자 지정을 받습니다. 타임스탬프는 없습니다. 오디오 1초당 0.174375 크레딧(분당 약 10.5 크레딧)으로 과금되며 요청당 최대 1시간·25MB입니다.
Incredibly Fast Whisper
Whisper
속도에 최적화된 Whisper large-v3입니다 (3,800만+ 실행). 배치 추론으로 약 150분 분량 오디오를 100초 이내에 전사합니다. 청크/단어 단위 타임스탬프를 지원합니다.
Muse Voice Transcribe 1.0
Meta
Meta 개발자 API 직결로 제공되는 Meta Muse Voice Transcribe 음성 인식 모델입니다. 한국어를 포함한 25개 언어와 코드 스위칭, 화자 분리, 발화 구간 분할, 키워드·언어 바이어싱을 지원합니다. 오디오 1초당 0.11625 크레딧(분당 약 7 크레딧)으로 과금되며 요청당 최대 10분입니다.
Muse Voice Transcribe 1.0 (Realtime)
Meta
Meta Muse Voice Transcribe를 WebSocket으로 스트리밍합니다. 16-bit PCM(24kHz 또는 16kHz 모노) 오디오를 보내면 말하는 동안 부분·최종 전사를 실시간으로 받으며, 발화 구간 분할과 화자 분리를 지원합니다. Meta가 처리한 오디오 초 단위로 과금되고(초당 0.11625 크레딧, 5분 블록당 35 크레딧), 세션은 최대 20분입니다.
Whisper-1 (OpenAI API)
OpenAI
OpenAI API로 직접 호출하는 whisper-1 음성 인식입니다. OpenAI API 파라미터를 그대로 받습니다 — json·verbose_json 출력, 구간·단어 타임스탬프(timestamp_granularities), 언어 힌트와 프롬프트. 오디오 1초당 0.2325 크레딧(분당 약 14 크레딧)으로 과금되며 요청당 최대 1시간·25MB입니다.
Whisper
OpenAI
음성 전사의 표준인 OpenAI Whisper large-v3입니다 (1억 4,400만+ 실행). 약 100개 언어 자동 감지, 영어 번역, plain text/SRT/VTT 출력 형식을 지원합니다.
Whisper Diarization
Whisper
화자 분리(diarization)가 포함된 Whisper 전사입니다 (800만+ 실행). 누가 무엇을 말했는지 세그먼트별 화자 라벨과 타임스탬프로 반환합니다. 회의·인터뷰 전사의 정석입니다.
① 파일 전사 (비동기)
오디오 URL을 넣어 잡을 만들고, job_id로 완료될 때까지 폴링합니다. 타임스탬프가 포함된 JSON이 필요하면 openai/whisper-1의 verbose_json(2027-02-26 OpenAI 종료 예정 — 타임스탬프 없이 텍스트만 필요하면 더 저렴한 openai/gpt-transcribe):
curl -X POST https://api.core.today/v1/predictions \
-H "Content-Type: application/json" \
-H "X-API-Key: cdt_your_api_key" \
-d '{
"model": "openai/whisper-1",
"input": {
"audio": "https://example.com/meeting.mp3",
"response_format": "verbose_json",
"timestamp_granularities": ["segment"]
}
}'
# → {"job_id": "...", "status": "processing", ...}
curl https://api.core.today/v1/predictions/{job_id} -H "X-API-Key: cdt_your_api_key"완료되면 result에 OpenAI 응답 본문이 그대로 담깁니다. usage.seconds가 과금된 오디오 길이입니다:
{
"job_id": "91bGtKlfdpgiXxOKVQV6W9pb6r0oYwrD",
"status": "completed",
"result": {
"task": "transcribe",
"language": "english",
"duration": 52.41,
"text": "The little tales they tell are false. ...",
"segments": [
{ "id": 0, "start": 0.0, "end": 5.04, "text": " The little tales they tell are false." }
],
"usage": { "type": "duration", "seconds": 53 }
},
"credits_used": 13
}SRT·VTT 자막을 바로 받으려면 Replicate 배포의 openai/whisper (100개 언어 자동 감지):
curl -X POST https://api.core.today/v1/predictions \
-H "Content-Type: application/json" \
-H "X-API-Key: cdt_your_api_key" \
-d '{
"model": "openai/whisper",
"input": {
"audio": "https://example.com/meeting.mp3",
"transcription": "srt",
"language": "auto"
}
}'화자 구분·발화 구간이 필요하면 Meta Muse Voice Transcribe (한국어 포함 25개 언어, 요청당 최대 10분). 결과는 transcript·audioDurationMs·turns[]가 담긴 JSON입니다:
curl -X POST https://api.core.today/v1/predictions \
-H "Content-Type: application/json" \
-H "X-API-Key: cdt_your_api_key" \
-d '{
"model": "meta/muse-voice-transcribe-1.0",
"input": {
"audio": "https://example.com/meeting.m4a",
"mode": "DIARIZATION",
"language_bias": ["Korean", "English"]
}
}'② 실시간 스트리밍 (WebSocket)
말하는 동안 부분·최종 전사를 받아야 한다면 POST /predictions가 아니라 WebSocket으로 접속하세요. Meta Muse Voice Transcribe 1.0 (Realtime)만 지원하며, 이 모델은 POST /predictions를 400 realtime_only로 거부합니다. 엔드포인트는 wss://api.core.today/v1/realtime/asr입니다.
인증은 X-API-Key 헤더(접속 전에 검증됨)이거나, 헤더를 설정할 수 없는 런타임을 위해 핸드셰이크 JSON의 apiKey 필드입니다. 리셀러 팀은 X-Customer-Id 헤더(또는 핸드셰이크 customerId)가 필수이고, 키와 같은 소스(헤더↔헤더, JSON↔JSON)여야 합니다. 브라우저에 실제 API 키를 넣지 마세요 — 자체 서버에서 접속하고, 그 서버가 브라우저와는 별도 채널로 오디오를 중계해야 합니다.
접속 직후 첫 텍스트 프레임으로 핸드셰이크를 보냅니다(10초 안에 보내지 않으면 4400 handshake_timeout):
{
"model": "meta/muse-voice-transcribe-1.0/realtime",
"audioEncoding": "PCM_24KHZ",
"mode": "ENDPOINTING",
"partialMode": "CUMULATIVE",
"emitAudioProgress": false,
"keywords": ["Core.Today"],
"languageBias": ["Korean"],
"apiKey": "cdt_your_api_key",
"customerId": "member-123"
}이후 바이너리 프레임으로 raw PCM 16-bit 모노 오디오를 보냅니다(프레임당 최대 64 KiB). 실시간 속도(1x)로 보내고, 보낼 오디오가 없을 때는 무음으로 패딩하세요 — 10초 동안 오디오가 없으면 4408 idle_timeout이고, 실시간보다 5초 이상 앞서 보내면(페이싱 위반) 4400 pacing_violation으로 끊습니다. 전사를 마치려면 텍스트 프레임 {"type":"endStream"}을 보내세요.
우리가 보내는 이벤트: 접속 확정 session, Meta가 그대로 전달하는 transcript·speechStart·speechEnd·speechComplete·speaker(그리고 emitAudioProgress: true면 audioProgress), 마지막으로 정산이 끝난 뒤 보내는 usage입니다:
{"type":"session","sessionId":"rt_..."}
{"type":"transcript","transcript":"...","final":false}
{"type":"usage","sessionId":"rt_...","audioSeconds":73,"credits":9,"reason":"client_end"}Python 예시 — 24kHz WAV를 80ms 프레임으로 1배속 스트리밍하고 이벤트를 출력합니다:
import asyncio, json, os, wave, websockets
API_KEY = os.environ["AIAPI_API_KEY"]
ENDPOINT = "wss://api.core.today/v1/realtime/asr"
async def main():
async with websockets.connect(
ENDPOINT, additional_headers={"X-API-Key": API_KEY}
) as ws:
await ws.send(json.dumps({
"model": "meta/muse-voice-transcribe-1.0/realtime",
"audioEncoding": "PCM_24KHZ",
"mode": "ENDPOINTING",
"languageBias": ["Korean"],
}))
async def send_audio():
with wave.open("meeting-24khz-mono.wav", "rb") as wav:
frame_bytes = int(24000 * 2 * 0.08) # 80ms of 16-bit mono PCM
while chunk := wav.readframes(frame_bytes // 2):
await ws.send(chunk)
await asyncio.sleep(0.08) # pace at 1x — never send ahead
await ws.send(json.dumps({"type": "endStream"}))
async def recv_events():
async for msg in ws:
if isinstance(msg, str):
print(json.loads(msg))
await asyncio.gather(send_audio(), recv_events())
asyncio.run(main())close 코드:
| 코드 | 의미 |
|---|---|
| 1000 | 정상 종료 (클라이언트 종료, 20분 상한, 기능 정지) |
| 1011 | Meta 세션 오류 |
| 1012 | 서버 재배포 — 이번 세션은 최종 전사·usage 이벤트 없이 즉시 끊깁니다. 지수 백오프로 재접속하세요 |
| 4400 | 핸드셰이크·프레임 오류 또는 페이싱 위반 (invalid_handshake / model_not_found / ambiguous_auth / handshake_timeout / invalid_frame / pacing_violation) |
| 4401 | API 키 없음/무효 (unauthorized) |
| 4402 | 크레딧/고객 예산 부족 (insufficient_credits / reseller_account_insufficient / customer_wallet_insufficient) |
| 4403 | 리셀러 스코프·허용 모델·키 비활성 (invalid_customer_id / customer_suspended / customer_not_found / model_not_allowed / api_key_disabled) |
| 4408 | 10초 이상 오디오 무입력, 또는 이벤트를 충분히 빨리 읽지 않는 느린 클라이언트 (idle_timeout / client_slow) |
| 4413 | 바이너리 프레임이 64 KiB를 초과 (frame_too_large) |
| 4429 | 동시성·속도 제한 (customer_concurrency_exceeded / team_concurrency_exceeded / rate_limit_exceeded / customer_rate_limited / server_busy) |
| 4503 | 기능 정지 또는 업스트림/게이트웨이 장애 (feature_disabled / provider_unavailable / provider_rejected / provider_rate_limited / admission_unavailable) |
과금: 초당 0.11625크레딧, 5분(300초) 블록마다 35크레딧씩 예약되고 세션 진행에 따라 즉시 정산됩니다. 최종 청구는 Meta가 실제로 처리했다고 보고한 오디오 초 기준이며(연결 시간이 아님), 마지막 부분 블록은 그 초만큼만 청구됩니다(예: 73초 = 9크레딧, 300초 = 35크레딧). 세션은 최대 20분(1,200초)이고, 그 이상은 재접속해야 합니다. 배포 중 서버가 재시작되면 진행 중 세션은 1012로 즉시 끊기며(최종 전사·usage 이벤트는 받지 못함) 정산은 서버 쪽에서 처리되므로 지수 백오프로 재접속하면 됩니다.
③ OpenAI SDK 호환
이미 OpenAI SDK로 음성 인식을 쓰고 있다면 base_url과 API 키만 바꾸면 됩니다. 파일을 multipart로 직접 업로드하고(URL 아님) 결과는 응답 본문으로 바로 받으며, OpenAI가 보고한 오디오 길이로 초 단위 과금됩니다(LLM 게이트웨이 요율). 모델은 gpt-transcribe(분당 약 8.4크레딧, 텍스트만)와 whisper-1(분당 약 11크레딧, 타임스탬프)입니다.
whisper-1과 /audio/translations를 2027-02-26에 종료합니다. 텍스트 전사는 gpt-transcribe로 옮기세요(모델 이름만 바꾸면 됩니다). gpt-transcribe는 json만 답하고 타임스탬프가 없으므로, 구간·단어 타임스탬프가 필요하면 그 전까지 whisper-1을 쓰고 이후에는 ① 파일 전사의 openai/whisper(segments 포함)로 옮기세요.from openai import OpenAI
client = OpenAI(
base_url="https://api.core.today/llm/openai/v1",
api_key="cdt_your_api_key",
)
# gpt-transcribe: text + detected languages (no timestamps)
with open("meeting.mp3", "rb") as f:
result = client.audio.transcriptions.create(
model="gpt-transcribe",
file=f,
languages=["ko"], # openai>=3.x; older SDKs: extra_body={"languages": ["ko"]}
keywords=["Core.Today"],
)
print(result.text)타임스탬프가 필요하면 whisper-1의 verbose_json (2027-02-26 까지):
from openai import OpenAI
client = OpenAI(
base_url="https://api.core.today/llm/openai/v1",
api_key="cdt_your_api_key",
)
with open("meeting.mp3", "rb") as f:
result = client.audio.transcriptions.create(
model="whisper-1",
file=f,
response_format="verbose_json",
timestamp_granularities=["segment"],
)
print(result.text)
for seg in result.segments:
print(seg.start, seg.end, seg.text)SDK 없이 curl로 (OpenAI와 같은 multipart 형식, 키는 Authorization: Bearer):
curl https://api.core.today/llm/openai/v1/audio/transcriptions \
-H "Authorization: Bearer cdt_your_api_key" \
-F file=@meeting.mp3 \
-F model=gpt-transcribe \
-F "languages[]=ko"- 파일: mp3, mp4, mpeg, mpga, m4a, wav, webm (whisper-1은 flac·ogg도) · 최대 25MB (OpenAI 상한). 영어 번역은 whisper-1만, 같은 형식으로
POST /llm/openai/v1/audio/translations(2027-02-26 종료 예정) - gpt-transcribe:
languages[](예:ko)·keywords[](이름·용어 철자)·prompt, 응답은{text, languages, usage}. whisper-1:timestamp_granularities(segment·word)는verbose_json에서만 동작하고,language·prompt·temperature도 그대로 전달됩니다 - 400으로 거절되는 요청 (크레딧 차감 없음): 지원하지 않는
response_format(gpt-transcribe는json만, whisper-1은json·verbose_json만) →response_format_unsupported,stream=true→stream_not_supported, 두 모델 외(gpt-4o-transcribe 등) 또는 gpt-transcribe로 번역 →audio_model_unsupported - 과금: 응답
usage.seconds(verbose_json은duration) × 초당 gpt-transcribe 0.13935·whisper-1 0.1858크레딧. 요청 시 파일 크기로 추정해 예약하고 실제 길이로 정산합니다
파일 URL로 보내고 싶거나 크레딧을 잡 단위로 예약·환불받는 흐름이 필요하면 ① 파일 전사의 openai/gpt-transcribe·openai/whisper-1을 쓰세요 — 같은 OpenAI 모델이고 파라미터 이름도 같습니다.
모델 선택 가이드
- 타임스탬프 JSON (자막·검색 색인) — openai/whisper-1 (14크레딧 오디오 1분당 (초당 0.2325, 실측 길이로 정산)). 구간·단어 단위
verbose_json(2027-02-26 종료 예정 — 이후에는 openai/whisper의 segments) - 텍스트만, 가장 저렴하게 (OpenAI) — openai/gpt-transcribe (11크레딧 오디오 1분당 (초당 0.174375, 실측 길이로 정산)). whisper-1의 후속,
languages·keywords힌트 - SRT·VTT 자막 파일 바로 받기 — openai/whisper (14크레딧 오디오 1분당 (초당 0.2325, 최소 10크레딧, 실측 길이로 정산)). 긴 오디오를 빠르게는 incredibly-fast-whisper (10크레딧 실행당)
- 회의록 (누가 말했는지) — 한·영 혼용·키워드 바이어싱은 meta/muse-voice-transcribe-1.0 (7크레딧 오디오 1분당 (초당 0.11625, 실측 길이로 정산), 최대 10분/요청), Whisper 기반 화자 구분은 whisper-diarization (14크레딧 실행당)
- 말하는 동안 자막·음성 명령 — meta/muse-voice-transcribe-1.0/realtime (35크레딧 5분 블록당 (초당 0.11625 크레딧), WebSocket)
- 기존 OpenAI SDK 코드 이전 —
gpt-transcribe/whisper-1(OpenAI SDK 호환 경로, 코드 변경은base_url·키뿐)