कॉन्टेंट पर जाएं

टेक्स्ट टू स्पीच API इंटीग्रेशन: स्ट्रीमिंग, बैचिंग, रिट्राई

प्रकाशित

सुनेंइस आर्टिकल को सुनें

टेक्स्ट टू स्पीच API इंटीग्रेट करना आसान है… लेकिन कुछ फैसले लेने होते हैं: कौन सा ट्रांसफर मोड चुनें, कौन सा मॉडल और आउटपुट फॉर्मेट लें, स्ट्रीमिंग कैसे करें, ज्यादा वॉल्यूम कैसे भेजें बिना अपनी कंकरेंसी लिमिट पार किए, कैसे कैश और रिट्राई करें ताकि एक ही ऑडियो के लिए दो बार पे न करना पड़े, और कैसे टाइम-टू-फर्स्ट-बाइट का बेंचमार्क करें।

टेक्स्ट टू स्पीच API इंटीग्रेशन में आपकी मदद के लिए, हमने हर आर्किटेक्चरल फैसले को आसान भाषा में समझाया है। यह गाइड ElevenLabs टेक्स्ट टू स्पीच API को इंटीग्रेट करने और स्केल करने में आपकी मदद करेगा, साथ में कोड स्निपेट्स भी हैं जिन्हें आप सीधे प्रोडक्शन में इस्तेमाल कर सकते हैं।

यहां बताए गए कॉन्सेप्ट्स की पूरी जानकारी के लिए हमारे गाइड्स देखें: ऑडियो स्ट्रीमिंग समझना, लेटेंसी ऑप्टिमाइज़ करना, और ElevenLabs मॉडल ओवरव्यू

सारांश

  • ElevenLabs टेक्स्ट टू स्पीच API का एक ही एंडपॉइंट है, जिसे आप तीन तरीकों से एक्सेस कर सकते हैं: बैच कन्वर्ट, HTTP स्ट्रीम, और स्ट्रीम-इनपुट वेब सॉकेट।
  • HTTP पर, हर इन-फ्लाइट रिक्वेस्ट आपकी कंकरेंसी लिमिट में गिनी जाती है, जबकि वेब सॉकेट पर सिर्फ एक्टिव जेनरेशन ही गिनी जाती है।
  • अपनी पैरेलल रिक्वेस्ट्स को प्लान लिमिट से थोड़ा कम रखें, और हर आउटपुट-इफेक्टिंग पैरामीटर का हैश कैश करें ताकि एक ही टेक्स्ट के लिए दो बार बिल न हो।
  • 429 और 5xx एरर पर एक्सपोनेंशियल बैकऑफ और फुल जिटर के साथ रिट्राई करें ताकि कंकरेंसी वॉल से पहले ही लोड कम हो जाए।

टेक्स्ट टू स्पीच API इंटीग्रेट करने के तीन तरीके

टेक्स्ट टू स्पीच का एक ही एंडपॉइंट है, लेकिन आप उसे कैसे इंटीग्रेट करते हैं, इससे लेटेंसी, कॉम्प्लेक्सिटी और कॉस्ट तय होती है।

POST /v1/text-to-speech/{voice_id} कॉल तीन तरीकों से काम करता है, हर तरीका अलग जरूरत के लिए सही है। यहां तीनों इंटीग्रेशन के तरीके दिए गए हैं:

  • बैच (कन्वर्ट) सबसे सिंपल इंटीग्रेशन है: आप एक रिक्वेस्ट भेजते हैं और एक ऑडियो रिस्पॉन्स मिलता है। यह सबसे कम कॉम्प्लेक्स है, लेकिन इसमें फर्स्ट ऑडियो आने में सबसे ज्यादा समय लगता है क्योंकि पूरा क्लिप बनने के बाद ही डेटा मिलता है।
  • HTTP स्ट्रीमिंग (स्ट्रीम) में रिक्वेस्ट वही रहती है, लेकिन रिस्पॉन्स चंक्स में आता है: आप पाथ में /stream जोड़ते हैं, स्ट्रीम मेथड कॉल करते हैं, और ऑडियो चंक्स में मिलता है। कोड लगभग एक जैसा रहता है, और लेटेंसी काफी कम महसूस होती है।
  • वेब सॉकेट (स्ट्रीम-इनपुट) में पर्सिस्टेंट कनेक्शन रहता है: आप टेक्स्ट धीरे-धीरे भेजते हैं और जैसे-जैसे ऑडियो चंक्स बनते हैं, वैसे-वैसे रिसीव करते हैं। यह इंटरएक्टिव एजेंट्स और LLM के आउटपुट को लाइव स्पीच में बदलने के लिए बना है।

स्ट्रीमिंग से मॉडल की स्पीड नहीं बढ़ती; इंफरेंस टाइम वही रहता है। फर्क सिर्फ इतना है कि पहला चंक पूरा क्लिप बनने से पहले ही मिल जाता है, जिससे यूज़र को कम इंतजार लगता है।

बैच vs. स्ट्रीमिंग vs. वेब सॉकेट डिसीजन टेबल

इन तीनों तरीकों में से चुनते समय कुछ बातें ध्यान में रखनी चाहिए।

जल्दी गाइड: ऑफलाइन रेंडरिंग के लिए बैच चुनें, यूज़र के लिए वेटिंग टेक्स्ट के लिए HTTP स्ट्रीमिंग, और एजेंट्स या लाइव LLM टू स्पीच के लिए वेब सॉकेट।

नीचे दी गई टेबल में स्केल पर जरूरी फैक्टर्स के हिसाब से फायदे-नुकसान बताए गए हैं।

Batch (convert)
Time-to-first-audio
Highest (wait for full clip)
Implementation complexity
Lowest
Text known up front?
Required
Streaming LLM output into TTS
Awkward
Concurrency cost
Each request counts fully
Best for
Offline rendering, audiobooks, caching
HTTP streaming
Time-to-first-audio
Low
Implementation complexity
Low
Text known up front?
Required
Streaming LLM output into TTS
Awkward
Concurrency cost
Each request counts fully
Best for
Web/app playback of known text
WebSocket (stream-input)
Time-to-first-audio
Lowest
Implementation complexity
Highest (connection lifecycle, framing)
Text known up front?
Not required - send incrementally
Streaming LLM output into TTS
Native fit
Concurrency cost
Only active generation counts
Best for
Voice agents, live LLM to speech

HTTP पर, चाहे बैच हो या स्ट्रीमिंग, हर इन-फ्लाइट रिक्वेस्ट पूरी अवधि के लिए आपकी प्लान कंकरेंसी लिमिट में गिनी जाती है। वेब सॉकेट पर सिर्फ वही समय गिना जाता है जब मॉडल ऑडियो बना रहा हो; ओपन लेकिन आइडल सॉकेट का कोई खास खर्चा नहीं है।

अगर आप कास्केडेड वॉइस एजेंट बना रहे हैं जो पूरी बातचीत के दौरान कनेक्शन ओपन रखता है लेकिन सिर्फ एजेंट की बारी पर ऑडियो बनाता है, तो यह फर्क बहुत मायने रखता है। एजेंट्स के लिए वेब सॉकेट्स का यही मुख्य कारण है। पूरा प्रोटोकॉल रियलटाइम टेक्स्ट टू स्पीच वेब सॉकेट गाइड में दिया गया है।

मॉडल और आउटपुट फॉर्मेट चुनना

TTS API इंटीग्रेशन से मिलने वाले ऑडियो को दो चीजें तय करती हैं: मॉडल (क्वालिटी और स्पीड सेट करता है) और आउटपुट फॉर्मेट (कंटेनर, बिटरेट, सैंपल रेट सेट करता है)।

शुरुआत से ही दोनों सही चुनने से बाद की चीजें जैसे लेटेंसी और टेलीफोनी कम्पैटिबिलिटी अपने आप सही हो जाती हैं।

मॉडल्स

हम कई टेक्स्ट टू स्पीच मॉडल्स देते हैं। ये बेस्ट-टू-वर्स्ट नहीं हैं; हर एक के अपने फायदे-नुकसान हैं।

Best for
eleven_flash_v2_5
Real-time, agents, bulk throughput (~75ms model inference)
eleven_flash_v2
Real-time, English only (~75ms)
eleven_multilingual_v2
Highest stable fidelity, narration
eleven_v3
Most expressive, widest language range
Languages
eleven_flash_v2_5
32
eleven_flash_v2
English
eleven_multilingual_v2
29
eleven_v3
70+
Character limit
eleven_flash_v2_5
40,000
eleven_flash_v2
30,000
eleven_multilingual_v2
10,000
eleven_v3
5,000

ध्यान दें, ~75ms का आंकड़ा मॉडल इंफरेंस का है, नेटवर्क और ऐप लेटेंसी को छोड़कर। लंबा इनपुट या ज्यादा लोड होने पर यह बढ़ सकता है। हमेशा अपने ऐप से मापें, बेंचमार्क नंबर से नहीं।

Flash मॉडल छोटे होते हैं और इंफरेंस टाइम कम करने के लिए ज्यादा एप्रॉक्सिमेशन करते हैं। Eleven v3 और Multilingual v2 बड़े मॉडल हैं, जो ज्यादा समय लेकर बेहतर आउटपुट देते हैं। कोई ऐसा सेटिंग नहीं है जो Eleven v3 जैसी क्वालिटी Flash की स्पीड पर दे सके, क्योंकि क्वालिटी के लिए ज्यादा कंप्यूटेशन चाहिए।

रियलटाइम या एजेंट के लिए eleven_flash_v2_5 यूज़ करें; यह सबसे कम लेटेंसी वाला मल्टीलिंगुअल ऑप्शन है। नैरेशन, ऑडियोबुक या मार्केटिंग वॉइसओवर के लिए eleven_multilingual_v2 लें जब आपको स्टेबल हाई फिडेलिटी चाहिए, या eleven_v3 लें जब आपको ज्यादा एक्सप्रेसिवनेस और इमोशनल रेंज चाहिए।

जहां उच्चारण जरूरी है, जैसे फोन नंबर, तारीख या करंसी, वहां नंबर नॉर्मलाइजेशन अपने ऐप में खुद करें, ताकि API तक पहुंचने से पहले टेक्स्ट सही फॉर्म में हो। जो बोलना है, वही लिखें।

खुद नॉर्मलाइज करने से उच्चारण हर मॉडल में एक जैसा रहता है और मॉडल-डिफॉल्ट्स पर निर्भरता नहीं रहती।

आउटपुट फॉर्मेट

output_format पैरामीटर कंटेनर, सैंपल रेट और बिटरेट तय करता है। सबसे ज्यादा यूज़ होने वाले वैल्यूज:

Use case
mp3_44100_128
General playback, downloads, highest mp3 quality shown here
mp3_22050_32
Lower-bandwidth playback, smaller files
pcm_24000 / pcm_16000
Raw PCM for your own audio pipeline or further processing
ulaw_8000
Telephony - the format used with Twilio and similar systems
Languages
mp3_44100_128
32
mp3_22050_32
English
pcm_24000 / pcm_16000
29
ulaw_8000
70+
Character limit
mp3_44100_128
40,000
mp3_22050_32
30,000
pcm_24000 / pcm_16000
10,000
ulaw_8000
5,000

वॉइस सेटिंग्स

नीचे दी गई सेटिंग्स से जेनरेटेड स्पीच का डिलीवरी तरीका कंट्रोल होता है:

  • Stability: कंसिस्टेंसी बनाम एक्सप्रेसिवनेस कंट्रोल करता है। कम वैल्यू पर स्पीच ज्यादा एक्सप्रेसिव होती है, ज्यादा वैल्यू पर डिलीवरी ज्यादा स्टेबल और प्रेडिक्टेबल रहती है।
  • SimilarityBoost: आउटपुट को रेफरेंस वॉइस से कितनी नजदीकी चाहिए, यह कंट्रोल करता है।
  • Style: वॉइस के नैचुरल बोलने के स्टाइल को बढ़ाता है।
  • useSpeakerBoost: ओरिजिनल स्पीकर से मिलती-जुलती आवाज़ बनाता है, थोड़ी लेटेंसी बढ़ती है।
  • Speed: डिलीवरी की स्पीड को डिफॉल्ट 1.0 के आसपास एडजस्ट करता है।

इन सेटिंग्स में Stability का असर सबसे ज्यादा होता है। कम वैल्यू पर आउटपुट ज्यादा एक्सप्रेसिव लेकिन कम कंसिस्टेंट होता है, ज्यादा वैल्यू पर कंसिस्टेंसी और प्रेडिक्टेबिलिटी बढ़ती है।

वॉइस चुनते समय, सबसे कम लेटेंसी Flash और Instant Voice Clone या डिफॉल्ट वॉइस के साथ मिलती है; प्रोफेशनल वॉइस क्लोनिंग में क्वालिटी बढ़ती है लेकिन हर जेनरेशन में थोड़ा ओवरहेड जुड़ता है।

इस गाइड में सैंपल वॉइस id है JBFqnCBsd6RMkjVDRZzb (George)।

स्ट्रीमिंग इंटीग्रेशन (HTTP और वेब सॉकेट)

इस सेक्शन में हम टेक्स्ट टू स्पीच API इंटीग्रेशन के प्रैक्टिकल हिस्से पर बात करते हैं। इसमें SDK इंस्टॉल करना, स्ट्रीम खोलना और ऑडियो चंक्स को कंज्यूम करना शामिल है। HTTP पाथ वेब और ऐप प्लेबैक के लिए है, वेब सॉकेट पाथ एजेंट्स और लाइव LLM आउटपुट के लिए।

दोनों पाथवे मानते हैं कि आपने नीचे दिया गया ElevenLabs क्लाइंट इनिशियलाइज़ किया है।

npm install @elevenlabs/elevenlabs-js
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

स्ट्रीमिंग पाथ में स्ट्रीम ओपन होती है और चंक्स जैसे-जैसे आते हैं, वैसे-वैसे कंज्यूम होते हैं। voiceId पहला आर्ग्युमेंट है, फिर ऑप्शंस ऑब्जेक्ट आता है जिसमें camelCase कीज (modelId, outputFormat, voiceSettings) होती हैं:

const stream = await elevenlabs.textToSpeech.stream("JBFqnCBsd6RMkjVDRZzb", {
  text,
  modelId: "eleven_flash_v2_5",
  outputFormat: "mp3_44100_128",
  voiceSettings: { stability: 0, similarityBoost: 1.0, style: 0, useSpeakerBoost: true, speed: 1.0 },
});

for await (const chunk of stream) {
  // chunk is a Buffer; feed it to the player as it arrives
}

वेब सॉकेट वेरिएंट के लिए, wss://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream-input से कनेक्ट करें, पहली मैसेज में वॉइस सेटिंग्स और एक लीडिंग स्पेस भेजें, फिर जैसे-जैसे टेक्स्ट मिलता है, वैसे-वैसे भेजें और JSON फ्रेम्स पढ़ें जिनके audio फील्ड में base64-encoded चंक्स होते हैं।

हाई थ्रूपुट के लिए बैचिंग और कंकरेंसी लिमिट्स

हाई-थ्रूपुट इंटीग्रेशन में कंकरेंसी मायने रखती है, यानी एक साथ कितनी रिक्वेस्ट्स ऑडियो जेनरेट कर रही हैं। हर प्लान में हर मॉडल फैमिली के लिए अलग लिमिट होती है।

हर प्लान में अलग कंकरेंसी लिमिट होती है:

  • फ्री: 4 कंकरेन्ट Flash रिक्वेस्ट्स।
  • स्टार्टर: 6 कंकरेन्ट Flash रिक्वेस्ट्स।
  • क्रिएटर: 10 कंकरेन्ट Flash रिक्वेस्ट्स।
  • प्रो: 20 कंकरेन्ट Flash रिक्वेस्ट्स।
  • स्केल और बिज़नेस: 30 कंकरेन्ट Flash रिक्वेस्ट्स, एंटरप्राइज लिमिट्स कस्टम होती हैं।

Multilingual v2 की लिमिट्स ऊपर दी गई लिमिट्स की लगभग आधी हैं।

एक बाउंडेड पूल एक बार में चलने वाली रिक्वेस्ट्स की संख्या को लिमिट करके मदद करता है:

// Set MAX_CONCURRENCY at or below your plan's Flash concurrency limit.
const MAX_CONCURRENCY = 8;

async function synthMany(texts: string[]): Promise<Buffer[]> {
  const results: Buffer[] = [];
  for (let i = 0; i < texts.length; i += MAX_CONCURRENCY) {
    const batch = texts.slice(i, i + MAX_CONCURRENCY);
    results.push(...(await Promise.all(batch.map(eachSingleRequest)))); // never more than MAX_CONCURRENCY in flight
  }
  return results;

MAX_CONCURRENCY को अपनी प्लान लिमिट से थोड़ा कम सेट करें, बिल्कुल बराबर नहीं। इससे आपके पास थोड़ा हेडरूम रहेगा और 429 एरर से बचेंगे।

कैरेक्टर लिमिट्स और लंबा टेक्स्ट स्प्लिट करना

हर मॉडल एक रिक्वेस्ट में एक्सेप्ट होने वाले कैरेक्टर्स की लिमिट रखता है। लंबे टेक्स्ट के लिए आपको उसे स्प्लिट करना और ऑडियो को फिर से जोड़ना होगा।

हर मॉडल के लिए पर-रिक्वेस्ट कैरेक्टर लिमिट्स:

  • Flash v2.5: एक रिक्वेस्ट में 40,000 कैरेक्टर्स तक एक्सेप्ट करता है।
  • Flash v2: एक रिक्वेस्ट में 30,000 कैरेक्टर्स तक एक्सेप्ट करता है।
  • Multilingual v2: एक रिक्वेस्ट में 10,000 कैरेक्टर्स तक एक्सेप्ट करता है।
  • Eleven v3: एक रिक्वेस्ट में 5,000 कैरेक्टर्स तक एक्सेप्ट करता है।

इससे लंबा टेक्स्ट आपको कई रिक्वेस्ट्स में स्प्लिट करना होगा। कोशिश करें कि सेंटेंस बाउंड्री पर स्प्लिट करें ताकि चंक्स के बीच प्रोसोड़ी बनी रहे।

function splitText(text: string, maxChars: number): string[] {
  const sentences = text.trim().split(/(?<=[.!?])\s+/);
  const chunks: string[] = [];
  let current = "";
  for (let sentence of sentences) {
    if (current.length + sentence.length + 1 > maxChars) {
      if (current) chunks.push(current.trim());
      // A single sentence longer than the limit is hard-split.
      while (sentence.length > maxChars) {
        chunks.push(sentence.slice(0, maxChars));
        sentence = sentence.slice(maxChars);
      }
      current = sentence;
    } else {
      current = `${current} ${sentence}`.trim();
    }
  }
  if (current) chunks.push(current.trim());
  return chunks;
}

चंक्स को क्रम में रेंडर करें और ऑडियो को जोड़ें। लंबी नैरेशन में जहां हर चंक अलग है, वहां splitText आउटपुट को ऊपर बताए गए बाउंडेड पूल में डालें और बाकी काम उसे करने दें।

कैशिंग और आइडेम्पोटेंसी

टेक्स्ट टू स्पीच आउटपुट इतना डिटरमिनिस्टिक है कि एक ही टेक्स्ट, वॉइस, मॉडल और सेटिंग्स के साथ दोबारा रेंडर करना बेकार है। ऐसे में इनपुट्स का हैश बनाकर कैश करें, और यही की रिट्राई पर आइडेम्पोटेंसी टोकन का काम करता है।

यह दोनों काम ऐसे करें:

import { createHash } from "node:crypto";

function cacheKey(text: string, voiceId: string, modelId: string,
                  outputFormat: string, settings: object): string {
  // Every parameter that changes the audio must be in the key.
  const payload = JSON.stringify({ text, voiceId, modelId, outputFormat, settings });
  return createHash("sha256").update(payload).digest("hex");
}

async function cachedSynth(text: string, voiceId: string, modelId: string,
                           outputFormat: string, settings: object): Promise<Buffer> {
  const key = cacheKey(text, voiceId, modelId, outputFormat, settings);
  const cached = await cacheGet(key);          // e.g. read from disk or S3
  if (cached) return cached;

  const audio = await elevenlabs.textToSpeech.convert(voiceId, { text, modelId, outputFormat });
  await cachePut(key, audio);                   // store the bytes under the key
  return audio;
}

इसका नियम है कि हर पैरामीटर जो ऑडियो बदलता है, उसे की में शामिल करें, जैसे outputFormat और voice settings। सही से करने पर वही की आइडेम्पोटेंसी टोकन बन जाती है। जब क्लाइंट पहले से सक्सेसफुल रिक्वेस्ट को रिट्राई करता है, तो आप फिर से जेनरेट करने की बजाय कैश्ड बाइट्स लौटा सकते हैं।

एरर हैंडलिंग और रेट लिमिट्स (429)

प्रोडक्शन क्लाइंट में बैकऑफ और जिटर के साथ रिट्राई चाहिए, और स्टेटस कोड के हिसाब से हैंडलिंग, क्योंकि कुछ फेल्योर दोबारा ट्राई करने लायक होते हैं और कुछ नहीं।

नीचे दी गई टेबल हर स्टेटस के लिए सही एक्शन बताती है, और यह सेक्शन समझाता है कि 429 सॉफ्ट लिमिट है, हार्ड वॉल नहीं।

Meaning
401
Authentication failed
422
Invalid request
429
Concurrency exceeded
5xx
Transient server error
Action
401
Do not retry. Check the xi-api-key header and key validity.
422
Do not retry. Fix the payload (bad voice id, unsupported format, text over limit).
429
Retry with exponential backoff and jitter.
5xx
Retry with backoff.
Character limit
401
40,000
422
30,000
429
10,000
5xx
5,000

429 हार्ड वॉल नहीं है, और इसका मैकेनिज्म जानना फायदेमंद है। जब आप कंकरेंसी लिमिट से ऊपर जाते हैं, तो रिक्वेस्ट्स पहले प्रायोरिटी के हिसाब से कतार में लगती हैं, जिससे लगभग 50ms जुड़ता है। अगर फिर भी कैपेसिटी से ऊपर हैं, तभी 429 मिलता है।

रिस्पॉन्स में current-concurrent-requests और maximum-concurrent-requests हेडर भी होते हैं, जिससे आप लाइव हेडरूम देख सकते हैं और लिमिट से पहले ही लोड कम कर सकते हैं।

const RETRYABLE = new Set([429, 500, 502, 503, 504]);

async function synthWithRetry(text: string, voiceId: string, maxRetries = 5): Promise<Buffer> {
  let delay = 500; // ms, base for exponential backoff
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await elevenlabs.textToSpeech.convert(voiceId, {
        text, modelId: "eleven_flash_v2_5", outputFormat: "mp3_44100_128",
      });
    } catch (err: any) {
      const status = err.statusCode;
      // 401/422 and exhausted retries are not recoverable here.
      if (!RETRYABLE.has(status) || attempt === maxRetries) throw err;
      // Exponential backoff with full jitter.
      await new Promise((r) => setTimeout(r, Math.random() * delay));
      delay = Math.min(delay * 2, 8000);
    }
  }
  throw new Error("unreachable");
}

अगर आपको ज्यादा हेडरूम चाहिए, तो बेहतर रिट्राई की बजाय अपना प्लान अपग्रेड करें। एंटरप्राइज कस्टमर्स अपने अकाउंट मैनेजर से लिमिट बढ़ाने की रिक्वेस्ट कर सकते हैं।

लेटेंसी और टाइम-टू-फर्स्ट-बाइट का बेंचमार्किंग

लेटेंसी आपके रीजन, इनपुट और मौजूदा लोड पर निर्भर करती है, यानी सिर्फ वही लेटेंसी नंबर मायने रखता है जो आपने खुद अपने एनवायरनमेंट में मापा हो।

इस सेक्शन में Flash स्ट्रीमिंग एंडपॉइंट के लिए टाइम-टू-फर्स्ट-बाइट (TTFB) बताया गया है, और इसे ऐसे बनाया गया है कि आप इसी टूल से किसी और प्रोवाइडर को भी टेस्ट कर सकें।

इसे मेथडोलॉजी की तरह लें, पब्लिश्ड रिजल्ट की तरह नहीं। एक रन कुछ भी गारंटी नहीं देता।

टेक्स्ट टू स्पीच API इंटीग्रेशन की लेटेंसी बेंचमार्क करते समय ये बातें ध्यान रखें:

  • नेटवर्क राउंड-ट्रिप शामिल करें: TTFB आपके जियोग्राफी और प्रोवाइडर के नजदीकी क्लस्टर पर निर्भर करता है, इसलिए टेस्ट वहीं से करें जहां आपके सर्वर चलते हैं।
  • वार्मअप रन छोड़ दें: कोल्ड कनेक्शन पर पहली रिक्वेस्ट स्लो होती है और नंबर बिगाड़ सकती है।
  • इनपुट फिक्स रखें: इनपुट लेंथ, वॉइस, मॉडल और लोड रिजल्ट को बदलते हैं, इसलिए सब प्रोवाइडर्स में एक जैसे रखें।
  • डिस्ट्रिब्यूशन रिपोर्ट करें: नंबर हर रन में बदलते हैं, इसलिए सिर्फ एक वैल्यू की बजाय मीडियन और p95 पब्लिश करें।

इन बातों के साथ आप बेंचमार्क के लिए तैयार हैं।

const TEXT = "This is a fixed benchmark sentence used for every provider.";

async function measureElevenLabs(): Promise<number> {
  const start = performance.now();
  const res = await fetch(
    "https://api.elevenlabs.io/v1/text-to-speech/JBFqnCBsd6RMkjVDRZzb/stream?output_format=mp3_44100_128",
    {
      method: "POST",
      headers: { "xi-api-key": process.env.ELEVENLABS_API_KEY!, "Content-Type": "application/json" },
      body: JSON.stringify({ text: TEXT, model_id: "eleven_flash_v2_5" }),
    },
  );
  for await (const _ of res.body!) {
    return performance.now() - start; // first chunk received
  }
  throw new Error("no audio returned");
}

किसी और प्रोवाइडर से तुलना करने के लिए, उसी शेप की एक फंक्शन लिखें। फिर दोनों को एक छोटे रनर से चलाएं, एक वार्म-अप कॉल छोड़ें, ~20 टाइम्ड सैंपल लें जो एक-दूसरे से दूर हों, और मीडियन व p95 मिलीसेकंड में रिपोर्ट करें।

फेयर तुलना का मतलब है वेरिएबल्स को कंट्रोल करना।

दोनों प्रोवाइडर्स को एक ही मशीन और नेटवर्क से चलाएं, बेहतर है कि उसी रीजन के सर्वर से जहां आप डिप्लॉय करते हैं, न कि घर के लैपटॉप से। एक ही इनपुट टेक्स्ट यूज़ करें, और ऑडियो छोटा रखें ताकि मॉडल इंफरेंस ही नंबर को डॉमिनेट करे। कई रन में मीडियन और p95 रिपोर्ट करें, क्योंकि एक माप शोर है।

ध्यान रखें कि पब्लिक इंटरनेट पर TTFB में 20-200ms नेटवर्क राउंड-ट्रिप शामिल होता है, जिसका मॉडल से कोई लेना-देना नहीं। हम नॉर्थ अमेरिका, यूरोप और साउथईस्ट एशिया में क्लस्टर से सर्व करते हैं और नजदीकी क्लस्टर पर रूट करते हैं, इसलिए टेस्ट क्लाइंट को वहीं रखें, वरना आप सिर्फ डेटा सेंटर की दूरी माप रहे होंगे।

टेक्स्ट टू स्पीच API इंटीग्रेशन के लिए मुख्य बातें

प्रोडक्शन टेक्स्ट टू स्पीच API इंटीग्रेशन कुछ अहम फैसलों पर निर्भर करता है।

अगर ये सही हो जाएं, तो बाकी सब अपने आप सही हो जाता है:

  • काम के हिसाब से मॉडल चुनें: इंटरएक्टिव के लिए Flash v2.5 यूज़ करें और ज्यादा फिडेलिटी के लिए Multilingual v2 या Eleven v3 ऑफलाइन रेंडरिंग के लिए, जहां लेटेंसी कम मायने रखती है।
  • जब यूज़र इंतजार कर रहा हो तो स्ट्रीम करें: नॉन-इंटरएक्टिव टेक्स्ट के लिए HTTP स्ट्रीमिंग और एजेंट्स के लिए वेब सॉकेट यूज़ करें, ताकि आइडल टाइम आपकी कंकरेंसी लिमिट में न गिने।
  • पैरेलल रिक्वेस्ट्स को प्लान लिमिट तक सीमित रखें: कंकरेन्ट रिक्वेस्ट्स को प्लान लिमिट से थोड़ा कम रखें, और हर आउटपुट-इफेक्टिंग पैरामीटर के हैश पर कैश करें ताकि एक ही ऑडियो के लिए दो बार बिल न हो।
  • 429 और 5xx पर एक्सपोनेंशियल बैकऑफ और फुल जिटर के साथ रिट्राई करें: 429 और 5xx पर फुल जिटर के साथ बैकऑफ करें, और कंकरेंसी हेडर देखें कि आप लिमिट के कितने करीब हैं।
  • लंबे टेक्स्ट को सेंटेंस बाउंड्री पर स्प्लिट करें: हर मॉडल की कैरेक्टर लिमिट के अंदर सेंटेंस बाउंड्री पर ब्रेक करें ताकि प्रोसोड़ी बनी रहे।

अगर आप और गहराई में जाना चाहते हैं, तो देखें स्ट्रीमिंग कैसे करें, ऑडियो स्ट्रीमिंग कॉन्सेप्ट, ऑथेंटिकेशन, और क्लाइंट-साइड के लिए सिंगल-यूज़ टोकन

अपनी टेक्स्ट टू स्पीच इंटीग्रेशन ElevenAPI के साथ बनाएं

यह गाइड पढ़ने के बाद आपके पास प्रोडक्शन टेक्स्ट टू स्पीच API इंटीग्रेशन के लिए हर जरूरी पैटर्न है। स्ट्रीमिंग, बैचिंग, कैशिंग, रिट्राई और बेंचमार्किंग—हर चीज़ के लिए आप तैयार हैं।

शुरुआत करें और और जानें टेक्स्ट टू स्पीच API या साइन अप करें और आज ही ElevenAPI के साथ अपनी पहली कॉल करें।

टेक्स्ट टू स्पीच API इंटीग्रेशन FAQ

संबंधित लेख

उच्चतम गुणवत्ता वाले AI ऑडियो के साथ बनाएं