TH ▾

API ข้อความไม่เซ็นเซอร์สำหรับ Voice Pipeline

uncensoredhttps://api.xtts.cc/v1

การสาธิต API TTS: ตัวอย่างคำขอและการตอบกลับแบบสด

การสาธิตนี้แสดงคำขอจริงที่คุณสามารถรันได้ในหนึ่งนาที และรูปแบบการตอบกลับที่ได้รับ API เป็นโมเดลข้อความ ดังนั้นผลลัพธ์คือข้อความสคริปต์ JSON และการเรียกใช้ฟังก์ชันที่เครื่องมือสังเคราะห์เสียงแยกต่างหากสามารถอ่านออกเสียงได้

อัปเดต

ภาพประกอบแบบไอโซเมตริกของเทอร์มินัลที่ปล่อยข้อความ ข้อมูล และสตรีมการเรียกใช้ฟังก์ชัน

ก่อนที่คุณจะรันสิ่งใด

คำเตือนสำหรับผู้ที่คาดหวังว่าจะกดเล่นแล้วได้ยินเสียง: ตัวอย่าง API TTS นี้ไม่สร้างเสียง บริการส่งข้อความจากโมเดล 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

หากการเรียกนี้ส่งกลับรายการ JSON ที่รวม uncensored คีย์ใช้งานได้และคุณสามารถดำเนินการต่อได้

ตัวอย่างที่ 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 สำหรับจุดสิ้นสุดตามธรรมชาติ length หาก max_tokens ตัดข้อความสั้นลง หากไม่ระบุ max_tokens การสร้างอาจใช้โทเคนที่เหลืออยู่ในหน้าต่าง 100,000 โทเคน ซึ่งครอบคลุมทั้งพรอมต์และการสร้างข้อความ

สิ่งที่ส่วนหัวบอกคุณ

เพิ่ม -i ไปยังคำสั่ง curl แล้วคุณจะเห็น 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 และรัน node demo.mjs หลัง npm install openai) บนสายส่งแต่ละเหตุการณ์คือบรรทัดที่ขึ้นต้นด้วย 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 ดังนั้นให้แยกวิเคราะห์และตรวจสอบความถูกต้องก่อนใช้งาน โมเดลอาจผลิตสไตล์ที่ไม่อยู่ใน enum ของคุณหรือละเว้นฟิลด์ และค่าที่ไม่ได้ตรวจสอบไม่ควรไปถึงเอนจินของคุณ หากต้องการให้บทสนทนาดำเนินต่อ ให้เพิ่มข้อความผู้ช่วยและข้อความตอบกลับด้วย 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 โทเคน ซึ่งแบ่งใช้ระหว่างพรอมต์และการตอบกลับ ซึ่งเพียงพอสำหรับการส่งบทถอดเสียงที่ยาวหรือเรื่องสั้นทั้งเรื่องแล้วขอให้เขียนใหม่ในรูปแบบที่อ่านออกเสียงได้ ขนาดของ body ของคำขอสามารถสูงได้ถึง 8 MB ดังนั้นขนาดจึงไม่ใช่ข้อจำกัดหลัก แต่จำนวนโทเคนต่างหากที่เป็นข้อจำกัด

นี่คือค่าใช้จ่ายของคำขอที่ใช้ทรัพยากรสูง สมมติว่าคุณส่ง 80,000 โทเคนและได้รับผลลัพธ์กลับ 2,000 โทเคน: Input: 80,000 x $0.15 / 1,000,000 = $0.012 Output: 2,000 x $0.50 / 1,000,000 = $0.001 รวมเป็น $0.013 ดังนั้นเครดิตทดลองใช้ $0.50 จะครอบคลุมคำขอลักษณะนี้ได้ประมาณ 38 ครั้ง การป้อนข้อมูลยาวมีราคาถูกกว่าการรับผลลัพธ์ยาว ซึ่งเป็นเหตุผลที่การสรุปใจความหรือการเขียนใหม่จากข้อความขนาดใหญ่จึงมีราคาไม่แพง ในขณะที่การสร้างนวนิยายทั้งเรื่องในครั้งเดียวอาจมีค่าใช้จ่ายสูง

เคล็ดลับที่เป็นประโยชน์สำหรับการป้อนข้อมูลยาว: วางคำสั่งของคุณไว้ที่ต้นและทำซ้ำกฎสำคัญไว้ที่ท้ายสุด โมเดลมักจะปฏิบัติตามคำสั่งล่าสุดได้ดีที่สุด และการเตือนสั้นๆ หนึ่งบรรทัดหลังจากข้อความต้นฉบับ 80,000 โทเคนจะมีค่าใช้จ่ายเกือบเป็นศูนย์

การอ่านข้อผิดพลาดในตัวอย่าง

ลองทำให้มันผิดพลาดสักครั้งโดยเจตนาเพื่อให้คุณจดจำมันได้ในภายหลัง ส่งคำขอด้วยคีย์ที่ผิดและคุณจะได้รับข้อผิดพลาดการตรวจสอบสิทธิ์แทนที่จะเป็นการตอบกลับ ส่งคำขอสิบคำขอพร้อมกันในทันทีจากคีย์ทดลองและบางคำขอจะกลับคืนด้วยสถานะ HTTP 429

สถานะ 429 มีสามสาเหตุ และรหัสข้อผิดพลาดจะแยกแยะสาเหตุเหล่านั้นออกจากกัน:

  • rate_limited หมายถึงมีการส่งคำขอมากเกินไปในหนึ่งนาที: 60 สำหรับคีย์ทดลอง และ 300 สำหรับคีย์เต็ม
  • concurrency หมายถึงมีคำขอที่กำลังดำเนินการอยู่พร้อมกันมากเกินไป: 2 สำหรับคีย์ทดลอง และ 8 สำหรับคีย์เต็ม
  • สถานะ 429 พร้อมหัวข้อความ Retry-After: 5 หมายถึงบริการมีภาระเกินชั่วคราว ให้รอห้าวินาทีแล้วส่งคำขออีกครั้ง

คำขอที่ล้มเหลวหรือถูกปฏิเสธจะไม่ถูกเรียกเก็บเงิน ดังนั้นข้อผิดพลาดจึงไม่เสียค่าใช้จ่าย เพื่อดูขีดจำกัดที่คีย์ของคุณมี ให้อ่าน X-RateLimit-Limit-Requests และ X-RateLimit-Limit-Concurrency ในการตอบกลับปกติใดๆ ลูปลองใหม่ขนาดเล็กที่หยุดชั่วคราวตามค่า Retry-After หรือห้าวินาทีหากไม่มี เป็นสิ่งที่สคริปต์การสาธิตต้องการ

สิ่งที่ควรลองต่อไป

เมื่อการเรียกทั้งสี่นี้ทำงานได้ คุณจะมีชิ้นส่วนของกระบวนการทำงานของสคริปต์ ห่อหุ้มคำขอธรรมดาในฟังก์ชัน รันลูปสตรีมมิงเข้าคิว และเชื่อมต่อคิวกับเครื่องมือพูดที่คุณเลือก เครื่องมือแตกต่างกันในราคา ใบอนุญาตและคุณภาพ ดังนั้นอ่านข้อกำหนดปัจจุบันของพวกเขา บริการนี้ไม่ได้ให้หนึ่งและไม่ได้ระบุอะไรเกี่ยวกับพวกเขา

ค่าใช้จ่ายต่ำระหว่างทดลองใช้ที่ $0.15 ต่อ input token ล้านตัว และ $0.50 ต่อ output token ล้านตัว ค่าใช้จ่ายต่อคำขอ demo น้อยกว่า 1 เซนต์ และเครดิตทดลอง $0.50 ครอบคลุมหลายร้อยคำขอ ดูหน้าราคาเพื่อเติมเงิน $20-$500 พร้อมโบนัส 5-15% จ่ายด้วยคริปโต docs ระบุพารามิเตอร์ ขีดจำกัดอัตรา (8 คำขอพร้อมกัน และ 300 ต่อนาทีต่อคีย์เต็ม) และรหัสข้อผิดพลาด

ลำดับการทำงานที่เหมาะสมสำหรับช่วงบ่ายแรก: รันคำขอพื้นฐานจนกว่าน้ำเสียงจะถูกต้อง สลับไปใช้สตรีมมิงและพิมพ์ประโยคเมื่อเสร็จสิ้น จากนั้นเพิ่มการเรียกใช้ฟังก์ชันหรือโหมด JSON อย่างใดอย่างหนึ่ง ขึ้นอยู่กับว่าโค้ดสร้างเสียงของคุณต้องการข้อมูลในรูปแบบใด เก็บพรอมต์ทั้งหมดไว้ในไฟล์ภายใต้การควบคุมเวอร์ชัน เมื่อประโยคใดฟังดูผิดในไฟล์เสียงสุดท้าย คุณสามารถติดตามย้อนกลับไปยังคำสั่งเฉพาะที่สร้างประโยคนั้นและเปลี่ยนแปลงทีละสิ่งได้

ถาม-ตอบ

ฉันสามารถฟังเสียงตัวอย่างในตัวอย่างนี้หรือไม่?

ไม่ API ส่งเฉพาะข้อความ JSON และการเรียกใช้เครื่องมือเท่านั้น คุณต้องจัดหาเครื่องมือแปลงเสียงแยกต่างหากเพื่อเปลี่ยนข้อความเป็นเสียง

ฉันควรส่งรหัสโมเดลอะไร?

ส่ง uncensored เป็นค่าโมเดล พร้อม URL ฐาน https://api.xtts.cc/v1 และคีย์ของคุณในหัวข้อความ Authorization: Bearer

ตัวอย่างเหล่านี้ทำงานกับคีย์ทดลองได้หรือไม่?

ได้ คีย์ทดลองอนุญาตให้ส่งคำขอพร้อมกัน 2 คำขอและ 60 คำขอต่อนาที ซึ่งเพียงพอสำหรับตัวอย่างเหล่านี้ ให้รันคำขอทีละคำ

ทำไมฉันจึงได้รับสถานะ 429?

คุณเกินขีดจำกัดคำขอต่อนาที (rate_limited) มีคำขอที่เปิดค้างไว้พร้อมกันมากเกินไป (concurrency) หรือบริการมีภาระเกินชั่วคราว ให้รอค่า Retry-After หากมี แล้วลองส่งใหม่

คีย์ของคุณอยู่ห่างแค่แบบฟอร์มเดียว

สร้างบัญชี คัดลอกคีย์ และเปลี่ยน base URL นั่นคือการตั้งค่าทั้งหมด