Paxa Labs

ใช้ OpenAI SDK กับ Paxa

POST /v1/audio/speech และ POST /v1/audio/transcriptions ใช้แทนเอนด์พอยต์เสียงพูดและถอดเสียงของ OpenAI ได้โดยตรง ชี้ base URL ของ SDK มาที่ Paxa API แล้วโค้ดเดิมทำงานได้โดยไม่ต้องแก้

ดูเป็น Markdown

ความเข้ากันได้กับ OpenAI หมายถึง Paxa API ให้บริการคำขอรูปแบบ audio.speech ของ OpenAI ที่ POST /v1/audio/speech ตั้ง base URL ของ SDK เป็น https://api.paxalabs.com/v1 ใช้คีย์ API ของ Paxa แล้ว audio.speech.create ทำงานได้โดยไม่ต้องแก้อะไร ราคา เฮดเดอร์ และโค้ดข้อผิดพลาดเหมือน POST /v1/tts ทุกประการ เอนด์พอยต์ถอดเสียงให้บริการด้วยวิธีเดียวกัน

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.paxalabs.com/v1",
    api_key=os.environ["PAXA_API_KEY"],
)

with client.audio.speech.with_streaming_response.create(
    model="paxa-tts-flash-v2",
    voice="khanomkrok",
    input="สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs",
) as response:
    response.stream_to_file("speech.mp3")

การจับคู่ฟิลด์#

ฟิลด์พฤติกรรม
modelจำเป็นต้องระบุ เช่นเดียวกับบน /v1/tts ใช้รหัสโมเดลของ Paxa เช่น paxa-tts-flash-v2 ชื่อโมเดลของ OpenAI อย่าง tts-1 tts-1-hd gpt-4o-mini-tts gpt-4o-mini-tts-2025-03-20 gpt-4o-mini-tts-2025-12-15 ก็ใช้ได้ และทำงานบน paxa-tts-flash-v2
inputข้อความที่จะสังเคราะห์ ขีดจำกัด ราคา แท็กคำกำกับ และแท็กอารมณ์บน paxa-tts-flash-v1 เหมือนฟิลด์ text ของ /v1/tts
voiceรหัสเสียงจาก GET /v1/voices เช่น "khanomkrok" ไม่สนตัวพิมพ์ใหญ่เล็ก เช่นเดียวกับ voice ของ /v1/tts เอนด์พอยต์นี้ยังรับชื่อของเสียง OpenAI เช่น alloy โดยจับคู่กับเสียงของ Paxa และเฮดเดอร์ x-voice-id ในคำตอบบอกว่าเสียงใดเป็นผู้พูด
response_formatmp3 (ค่าเริ่มต้น) opus wav pcm (โมโน 16 บิต little-endian ที่ 24 kHz แบบเดียวกับของ OpenAI เว้นแต่ sample_rate จะกำหนดอัตราอื่น) mulaw หรือ alaw เหมือนฟิลด์ format ของ /v1/tts โดย Paxa TTS Flash ตอบ mulaw และ alaw ด้วย unsupported_format ส่วนฟอร์แมตอื่นของ OpenAI ตอบ 400
sample_rateส่วนขยายของ Paxa ที่อ่านเฉพาะกับ pcm และ wav เหมือนบน /v1/tts และละเว้นเมื่อใช้ฟอร์แมตอื่น แต่ค่าที่ส่งต้องเป็นอัตราที่ Paxa TTS Flash v2 รองรับ กำหนดอัตราเป็น Hz โดย Paxa TTS Flash v2 รองรับ 8000, 16000, 22050, 24000, 32000, 44100, 48000 ส่วน Paxa TTS Flash รองรับเพียง 24000 ระบุเมื่อแพลตฟอร์มที่เล่นเสียงต้องการอัตราคงที่
temperatureส่วนขยายของ Paxa ที่อ่านเหมือนบน /v1/tts กำหนดว่าการอ่านแต่ละคำขอจะต่างกันมากแค่ไหน ตั้งแต่ 0 ถึง 2 บน Paxa TTS Flash v2 ดูรายละเอียดที่ Temperature
streamค่าเริ่มต้นคือ true ตามรูปแบบการส่งของ OpenAI ตั้ง false หากต้องการไฟล์เต็มพร้อม content-length

speed ใช้งานได้ โดยรับค่าในช่วงที่โมเดลนี้ให้บริการ ค่าที่อยู่นอกช่วงจะตอบ 400 ความเร็วที่โมเดลทำไม่ได้จึงไม่ถูกนำไปใช้เงียบ ๆ ส่วนฟิลด์ที่ OpenAI มีแต่ Paxa ไม่ได้ให้บริการ เช่น instructions ระบบจะละเว้น โค้ดเดิมที่ส่งฟิลด์เหล่านี้มายังทำงานได้ ในทางกลับกัน ส่วนขยายไทม์สแตมป์ มีเฉพาะบน /v1/tts หากต้องการข้อมูลเวลาให้ใช้เอนด์พอยต์หลัก

แอปที่เติมรายการเสียงหรือโมเดลจาก base URL จะอ่าน GET /v1/audio/voices และ GET /v1/audio/models ซึ่งแสดง Paxa TTS Flash v2 และเสียงของโมเดลนี้ โดยไม่ต้องใช้คีย์

ความต่างจาก POST /v1/tts#

เอนด์พอยต์แบบเข้ากันได้ครอบคลุมกรณีพื้นฐาน คือส่งข้อความเข้า รับเสียงออก และสตรีมเป็นค่าเริ่มต้น ความสามารถอื่นทั้งหมดอยู่บนเอนด์พอยต์หลัก ทั้ง timestamps และ language ซึ่งมีเฉพาะบน /v1/tts และ /v1/tts/live และรูปแบบคำขอฉบับเต็มที่ข้อมูลอ้างอิง API อธิบายทีละฟิลด์ หากส่ง timestamps หรือ language มาที่เอนด์พอยต์นี้ ระบบจะละเว้น คำตอบเป็นเสียงล้วน และทุกคำขออ่านแบบ auto

ทั้งสองเอนด์พอยต์รับ Idempotency-Key รายงานค่าบริการจริงผ่าน x-credits-charged และตอบข้อผิดพลาดจากแคตตาล็อกเดียวกัน โค้ด retry และโค้ดคิดเงินที่เขียนกับตัวหนึ่งจึงใช้กับอีกตัวได้ทันที

การถอดเสียง#

POST /v1/audio/transcriptions ให้บริการคำขอรูปแบบ audio.transcriptions.create ของ OpenAI ใช้ base URL และคีย์ชุดเดียวกัน ไฟล์เสียงส่งเป็นส่วนไฟล์แบบ multipart จึงไม่ต้องเข้ารหัส base64

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.paxalabs.com/v1",
    api_key=os.environ["PAXA_API_KEY"],
)

with open("meeting.m4a", "rb") as file:
    subtitles = client.audio.transcriptions.create(
        file=file,
        model="paxa-stt-lite-v1-preview",
        response_format="srt",
    )

with open("meeting.srt", "w") as out:
    out.write(subtitles)
ฟิลด์พฤติกรรม
fileไฟล์เสียงในรูปส่วนไฟล์ รองรับ 7 ฟอร์แมต ระบบอ่านรูปแบบและความยาวจากไบต์ของไฟล์ เพดานและราคาเหมือนฟิลด์ audio ของ /v1/stt
modelจำเป็นต้องระบุ ใช้รหัสโมเดลของ Paxa เช่น paxa-stt-lite-v1-preview ชื่อโมเดลของ OpenAI อย่าง whisper-1 gpt-4o-transcribe gpt-4o-mini-transcribe gpt-4o-mini-transcribe-2025-03-20 gpt-4o-mini-transcribe-2025-12-15 ก็ใช้ได้ และทำงานบน paxa-stt-lite-v1-preview
languageแท็ก BCP 47 เป็นเพียงคำใบ้ ฟิลด์เดียวกับบน /v1/stt หากไม่ระบุ โมเดลจะตรวจภาษาเอง
response_formatjson (ค่าเริ่มต้น) verbose_json text srt หรือ vtt โดย verbose_json เพิ่มความยาวของไฟล์ ช่วงข้อความ และรายการคำเมื่อ timestamp_granularities ระบุ word

ค่าบริการรายงานผ่าน x-credits-charged เพราะเนื้อหาคำตอบรูปแบบ OpenAI ไม่มีที่ให้รายงาน ส่วน prompt และ temperature ระบบจะละเว้น และอ่าน timestamp_granularities เฉพาะเมื่อใช้ verbose_json ส่วน stream ที่ตั้งเป็น true จะได้คำตอบ 400 validation หากต้องการถอดเสียงขณะเสียงเข้ามา ให้ใช้ WS /v1/stt/live รูปแบบการเขียนสองแบบ สไตล์สองแบบ ช่วงผู้พูด คลังคำศัพท์ และความยาวบรรทัดคำบรรยาย เป็นส่วนขยายของ POST /v1/stt และไม่ได้อ่านที่นี่ ไฟล์ที่ยาวจนอาจเกินเวลารอของพร็อกซีระหว่างทาง ควรใช้เอนด์พอยต์หลักซึ่งคงการเชื่อมต่อไว้ระหว่างทำงาน

ย้ายระบบที่ใช้งานอยู่#

  • ชี้ base URL ของ SDK ไปที่ https://api.paxalabs.com/v1
  • เปลี่ยนคีย์ OpenAI เป็นคีย์ API จากแดชบอร์ด
  • ใช้ชื่อโมเดลของ OpenAI ต่อได้ ซึ่งทำงานบน paxa-tts-flash-v2 หรือตั้ง model เป็น paxa-tts-flash-v2 หรือ paxa-tts-flash-v1
  • ใช้ชื่อของเสียง OpenAI ต่อได้ หรือตั้ง voice เป็นรหัสเสียงที่โมเดลที่เลือกให้บริการ จาก GET /v1/voices เสียงที่ไม่อยู่ในรายชื่อของโมเดลนั้นได้คำตอบ 400 unknown_voice
  • ตั้ง response_format เป็น mp3 opus wav หรือ pcm หรือ mulaw และ alaw สำหรับสายโทรศัพท์ ฟอร์แมตอื่นของ OpenAI ไม่ให้บริการ

หมายเหตุ

ข้อผิดพลาดใช้รูปแบบของ API นี้ SDK โยน HTTP error ตามปกติ และเนื้อหาการตอบกลับมีโค้ดคงที่อยู่ในฟิลด์ title