qwen-audio-3.0-realtime-plus
Reaaliaikaisen puhedialogin malli, joka vastaanottaa puhetta ja tekstiä ja vastaa puheella tai tekstillä. Suunniteltu luonnolliseen keskustelurytmiin ja työkalujen käyttöön.
Tietoa mallista
Tämä kuvaus kattaa mallin ominaisuudet. Ailootissa saatavilla olevat syötteet, tulosteet ja asetukset luetellaan alla valitulle menetelmälle.
Qwen-Audio-3.0-Realtime-Plus on Alibaban malli reaaliaikaiseen puhedialogiin. Se vastaanottaa puhetta ja tekstiä, vastaa äänellä ja tekstillä ja tukee kaksisuuntaista keskustelua luonnollisine vuoroineen. Ääntä voidaan lähettää ja vastaanottaa osissa, joten vuorovaikutus kehittyy keskustelun aikana.
Kun keskustelukumppani on saanut ajatuksensa valmiiksi
Puheenvuoron rajoja voidaan määrittää ääniaktiivisuuden, puheenvuoron sisällöllisen päättymisen tai suoran ohjauksen perusteella. Valmistajan tilassa valinta tehdään ennen ensimmäistä äänisyötettä; vaihtaminen keskustelun alettua vaatii uuden yhteyden. Ohjauksen tuki riippuu valitusta menetelmästä. Merkitykseen perustuva tila huomioi tauot ja täytesanat: lyhyt epäröinti ei välttämättä tarkoita ajatuksen päättymistä. Käyttäjän uusi puhe voi keskeyttää muodostuvan vastauksen ja jatkaa keskustelua seuraavan vuoron perusteella. Tässä tilassa tunnistus voidaan kohdistaa valitun puhujan puhenäytteeseen, jotta muut äänet ja taustamelu häiritsevät vähemmän.
Ohjeet määrittävät avustajan roolin ja keskustelutyylin. Ääni voi huomioida sävyn, tempon ja tunteen; versio 3.0 tarjoaa viisi järjestelmä-ääntä ja puhenäytteeseen perustuvia ääniä. Malli tukee 11 kieltä, myös venäjää, sekä valmistajan ilmoittamia kiinan murrevariantteja. Valmistajalla ääni asetetaan istuntoasetusten ensimmäisessä päivityksessä; myöhempi uusi ääni samassa keskustelussa ohitetaan. Asetukset vaativat valitun käyttötavan tuen.
Työkalut ja keskusteluhistoria
Funktiokutsut ovat tuettuja. Malli muodostaa tarvittavan toiminnon, liitetty sovellus suorittaa sen ja palauttaa tuloksen dialogiin. Keskustelu voi näin perustua todelliseen tietoon ja jatkua tehdyn toiminnon jälkeen. Puheavustaja voi hyödyntää työkalutuloksia ja säilyttää kontekstin. Valmistajan ominaisuuksiin kuuluu myös sisäinen verkkohaku, jos valittu menetelmä tarjoaa sen. Verkkohakua ja funktiokutsuja ei voi ottaa yhtä aikaa käyttöön samassa istunnossa.
Historiassa on oletuksena 20 keskustelukierrosta, ja sallittu määrä on yhdestä 50:een. Kertyneen äänen raja on 300 sekuntia; vanhat osat poistetaan rajojen ylittyessä. Tämä eroaa yksittäisen puheenvuoron kestosta: historia määrittää, mikä aiempi aineisto pysyy käytettävissä dialogin jatkuessa.
Tekstikonteksti ja ääni
Muodollinen konteksti on 40 960 tokenia. Syötteen enimmäispituus on 16 384 tokenia ja tulosteen 8192; samat rajat ilmoitetaan päättelytilalle erillisellä 1024 tokenin päättelyketjurajalla.
Äänen suoratoistoon käytetään yksikanavaista PCM-ääntä 16-bittisenä: syötteessä 16 kHz ja tulosteessa 24 kHz. Teksti ja ääni kuuluvat samaan keskusteluun. Tälle mallille ei ole kuvattu visuaalista syötettä tai kuvatulostetta; sen erikoisala on puhe, teksti ja äänivuorovaikutus.
Ailoot · Reaaliaikainen puhe GET /v1/realtime?model=qwen-audio-3.0-realtime-plus qwen-audio-3.0-realtime-plus
qwen-audio-3.0-realtime-plusAloitus
Reaaliaikaisen puhedialogin malli, joka vastaanottaa puhetta ja tekstiä ja vastaa puheella tai tekstillä. Suunniteltu luonnolliseen keskustelurytmiin ja työkalujen käyttöön.
- Hyväksytyt syötteet
- Teksti · Ääni
- Tulokset
- Teksti · Ääni
Saatavilla Ailootissa · syötteet & menetelmät
Ailoot · Reaaliaikainen puhe GET /v1/realtime?model=qwen-audio-3.0-realtime-plus
- Syötetyypit
text,audio- Tulostyypit
text,audio- Tulosteen muoto
- istuntotapahtumat
| Kenttä | Tyyppi | Vaatimus | Arvot & rajat | Oletus |
|---|---|---|---|---|
Kenttäquery.model | Tyyppistring | VaatimusPakollinen | Arvot & rajat qwen-audio-3.0-realtime-plus | Oletus— |
Kenttäsession.input_audio_format | Tyyppistring | VaatimusValinnainen | Arvot & rajat pcm16, pcm | Oletus— |
Kenttäsession.output_audio_format | Tyyppistring | VaatimusValinnainen | Arvot & rajat pcm16, pcm | Oletus— |
Kenttäsession.instructions | Tyyppistring | VaatimusValinnainen | Arvot & rajat Rajoitus koskee: valittu istuntokäytäntö | Oletus— |
Kenttäsession.max_history_turns | Tyyppiinteger | VaatimusValinnainen | Arvot & rajat Vähimmäismäärä: 1 Rajoitus koskee: valittu istuntokäytäntö | Oletus— |
Kenttäinput_audio_buffer.append.audio | Tyyppibase64_string | VaatimusPakollinen | Arvot & rajat Syötteen sisältö: PCM16-mono; syöte 16 kHz, tulos 24 kHz; ei-tyhjä parillinen tavupituus | Oletus— |
Syöteaineistojen yhdistelmät
realtime_text_audio
Menetelmän parametrit ja elinkaari
| Parametri | Sopimus |
|---|---|
Parametrimaterial_types | Sopimustext, audio |
Parametrirequired | Sopimusnull |
Parametrioptional_controls | Sopimusnull |
Parametricontent_type | SopimusWebSocket |
Elinkaari: exact retained published method
Menetelmien rakenteet ja ID:t ovat täsmällisiä; toimittajan kyvykkyys on erillinen pyynnön hyväksymisestä.
Hinnoittelu
Ailoot-menetelmien hinnat
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus- Syöte
- 0,0008 $ / 1K
- Tuloste
- 0,0064 $ / 1K
- Syöte
- 0,0048 $ ääniminuuttia kohden
- Tuloste
- 0,018 $ tulosäänen minuuttia kohden
Ailoot varaa arvioidun summan ennen pyyntöä. Tuloksen jälkeen lopullinen veloitus toteutetaan mitatun käytön perusteella. Suoratoiston veloituksessa käytetään lopullista käyttötietuetta. Varauksen ja lopullisen veloituksen toiminta →
Esimerkkipyynnöt
Ailoot · Reaaliaikainen puhe
# Install the documented client once: python3 -m pip install websockets
import base64, json, os, time, wave
from pathlib import Path
from websockets.sync.client import connect
key = os.environ.get("AILOOT_API_KEY", "")
if not key.strip():
raise SystemExit("Set your AILOOT_API_KEY before connecting")
file = Path(os.environ.get("AILOOT_TEXT_FILE", ""))
if not file.is_file(): raise SystemExit("Set AILOOT_TEXT_FILE to your actual UTF-8 material")
material = file.read_text(encoding="utf-8")
if not material.strip(): raise SystemExit("Text material must not be empty")
out = Path("realtime-results")
out.mkdir(exist_ok=True)
audio, texts, complete = {}, {}, []
current_response = None
pending = False
deadline = time.monotonic() + 570 # Local client bound; lower server/session limits still apply.
def receive(ws, log):
global current_response, pending
left = deadline - time.monotonic()
if left <= 0:
raise TimeoutError("Client session limit; preserve IDs and partial results, do not replay")
event = json.loads(ws.recv(timeout=min(60, left)))
log.write(json.dumps(event, ensure_ascii=False) + "\n")
log.flush()
kind = event.get("type")
if kind == "error":
raise RuntimeError(json.dumps(event, ensure_ascii=False))
if kind == "response.created":
current_response = event["response"]["id"]
if kind in {"response.audio.delta", "response.output_audio.delta", "response.text.delta", "response.output_text.delta", "response.audio_transcript.delta", "response.output_audio_transcript.delta", "response.text.done", "response.audio_transcript.done"}:
identity = (event["response_id"], event["item_id"], event["output_index"], event["content_index"])
if kind in {"response.audio.delta", "response.output_audio.delta"}:
raw = base64.b64decode(event["delta"], validate=True)
if len(raw) % 2: raise ValueError("Output PCM16 chunk must have an even byte length")
audio.setdefault(identity, bytearray()).extend(raw)
elif kind.endswith(".done"):
texts[identity] = event.get("text", event.get("transcript", ""))
else:
texts[identity] = texts.get(identity, "") + event["delta"]
print(event["delta"], end="", flush=True)
if kind == "response.done":
response = event["response"]
complete.append(response)
if current_response is None: current_response = response["id"]
if response["id"] == current_response: pending = False
return event
def wait_for(ws, log, kind):
while True:
event = receive(ws, log)
if event.get("type") == kind: return event
def send(ws, event):
ws.send(json.dumps(event, ensure_ascii=False))
try:
# One exact model query; no reconnect/retry loop and no provider credentials.
with connect("wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus", additional_headers={"Authorization": "Bearer " + key}) as ws:
with (out / "events.jsonl").open("w", encoding="utf-8") as log:
wait_for(ws, log, "session.created")
send(ws, {"type":"session.update", "session":{"modalities":["audio","text"], "input_audio_format":"pcm", "output_audio_format":"pcm", "turn_detection":None}})
wait_for(ws, log, "session.updated")
send(ws, {"type":"conversation.item.create", "item":{"type":"message", "role":"user", "content":[{"type":"input_text", "text":material}]}})
send(ws, {"type":"response.create"})
pending = True
try:
while pending: receive(ws, log)
except KeyboardInterrupt:
# Cancel the actual current inference, then preserve its returned status.
send(ws, {"type":"response.cancel"})
while pending: receive(ws, log)
if not complete or complete[-1].get("status") != "completed":
raise RuntimeError("Response did not complete normally; inspect saved events and status")
finally:
manifest = {"responses":complete, "parts":[]}
for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):
record = {"response_id":identity[0], "item_id":identity[1], "output_index":identity[2], "content_index":identity[3]}
if identity in audio:
raw = bytes(audio[identity])
pcm_file = out / ("audio-" + str(number) + ".pcm")
wav_file = out / ("audio-" + str(number) + ".wav")
pcm_file.write_bytes(raw)
with wave.open(str(wav_file), "wb") as wav:
wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)
record.update({"pcm":str(pcm_file), "wav":str(wav_file), "sample_rate_hz":24000})
if identity in texts:
text_file = out / ("text-" + str(number) + ".txt")
text_file.write_text(texts[identity], encoding="utf-8")
record["text"] = str(text_file)
manifest["parts"].append(record)
(out / "results.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8")
print("\nSaved every received event and result in", out)
# Install the documented client once: python3 -m pip install websockets
import base64, json, os, time, wave
from pathlib import Path
from websockets.sync.client import connect
key = os.environ.get("AILOOT_API_KEY", "")
if not key.strip():
raise SystemExit("Set your AILOOT_API_KEY before connecting")
file = Path(os.environ.get("AILOOT_AUDIO_FILE", ""))
if not file.is_file(): raise SystemExit("Set AILOOT_AUDIO_FILE to your raw PCM16 mono 16-kHz recording")
material = file.read_bytes()
if not material or len(material) % 2 or material.startswith(b"RIFF"):
raise SystemExit("Use nonempty signed little-endian PCM16 mono 16-kHz bytes, not a WAV header")
out = Path("realtime-results")
out.mkdir(exist_ok=True)
audio, texts, complete = {}, {}, []
current_response = None
pending = False
deadline = time.monotonic() + 570 # Local client bound; lower server/session limits still apply.
def receive(ws, log):
global current_response, pending
left = deadline - time.monotonic()
if left <= 0:
raise TimeoutError("Client session limit; preserve IDs and partial results, do not replay")
event = json.loads(ws.recv(timeout=min(60, left)))
log.write(json.dumps(event, ensure_ascii=False) + "\n")
log.flush()
kind = event.get("type")
if kind == "error":
raise RuntimeError(json.dumps(event, ensure_ascii=False))
if kind == "response.created":
current_response = event["response"]["id"]
if kind in {"response.audio.delta", "response.output_audio.delta", "response.text.delta", "response.output_text.delta", "response.audio_transcript.delta", "response.output_audio_transcript.delta", "response.text.done", "response.audio_transcript.done"}:
identity = (event["response_id"], event["item_id"], event["output_index"], event["content_index"])
if kind in {"response.audio.delta", "response.output_audio.delta"}:
raw = base64.b64decode(event["delta"], validate=True)
if len(raw) % 2: raise ValueError("Output PCM16 chunk must have an even byte length")
audio.setdefault(identity, bytearray()).extend(raw)
elif kind.endswith(".done"):
texts[identity] = event.get("text", event.get("transcript", ""))
else:
texts[identity] = texts.get(identity, "") + event["delta"]
print(event["delta"], end="", flush=True)
if kind == "response.done":
response = event["response"]
complete.append(response)
if current_response is None: current_response = response["id"]
if response["id"] == current_response: pending = False
return event
def wait_for(ws, log, kind):
while True:
event = receive(ws, log)
if event.get("type") == kind: return event
def send(ws, event):
ws.send(json.dumps(event, ensure_ascii=False))
try:
# One exact model query; no reconnect/retry loop and no provider credentials.
with connect("wss://api.ailoot.ai/v1/realtime?model=qwen-audio-3.0-realtime-plus", additional_headers={"Authorization": "Bearer " + key}) as ws:
with (out / "events.jsonl").open("w", encoding="utf-8") as log:
wait_for(ws, log, "session.created")
send(ws, {"type":"session.update", "session":{"modalities":["audio","text"], "input_audio_format":"pcm", "output_audio_format":"pcm", "turn_detection":None}})
wait_for(ws, log, "session.updated")
for offset in range(0, len(material), 640):
send(ws, {"type":"input_audio_buffer.append", "audio":base64.b64encode(material[offset:offset+640]).decode("ascii")})
time.sleep(0.02)
send(ws, {"type":"input_audio_buffer.commit"})
wait_for(ws, log, "input_audio_buffer.committed")
send(ws, {"type":"response.create"})
pending = True
try:
while pending: receive(ws, log)
except KeyboardInterrupt:
# Cancel the actual current inference, then preserve its returned status.
send(ws, {"type":"response.cancel"})
while pending: receive(ws, log)
if not complete or complete[-1].get("status") != "completed":
raise RuntimeError("Response did not complete normally; inspect saved events and status")
finally:
manifest = {"responses":complete, "parts":[]}
for number, identity in enumerate(dict.fromkeys(list(audio) + list(texts))):
record = {"response_id":identity[0], "item_id":identity[1], "output_index":identity[2], "content_index":identity[3]}
if identity in audio:
raw = bytes(audio[identity])
pcm_file = out / ("audio-" + str(number) + ".pcm")
wav_file = out / ("audio-" + str(number) + ".wav")
pcm_file.write_bytes(raw)
with wave.open(str(wav_file), "wb") as wav:
wav.setnchannels(1); wav.setsampwidth(2); wav.setframerate(24000); wav.writeframes(raw)
record.update({"pcm":str(pcm_file), "wav":str(wav_file), "sample_rate_hz":24000})
if identity in texts:
text_file = out / ("text-" + str(number) + ".txt")
text_file.write_text(texts[identity], encoding="utf-8")
record["text"] = str(text_file)
manifest["parts"].append(record)
(out / "results.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8")
print("\nSaved every received event and result in", out)
Vastaanota ja tallenna tulokset
Ailoot · Reaaliaikainen puhe
istuntotapahtumat
Säilytä kaikki valmistuneet tulokset
Säilytä jokainen kokonainen palautettu vastaus, tiedosto ja sisällön osa.
Kokoa jokainen palautettu äänen delta ja teksti- tai tapahtumatulos jokaiselle todelliselle vastaustunnisteelle.
Jos alkuperäinen vastaus on tarkistettava
Säilytä todelliset istunto-, vastaus- ja tapahtumatunnisteet sekä tositteet.
Virheet ja seuraavat vaiheet
| Vastaus | Ehto | Seuraava vaihe |
|---|---|---|
Vastaus426 · invalid_request_error | EhtoEi yhteyden vaihtamista WebSocket-protokollaan | Seuraava vaiheKäytä WebSocket-asiakasta ja otsaketta Upgrade: websocket. |
Aliakset
Mallin aliakset
Ailoot qwen-audio-3.0-realtime-plus
Menetelmäpolkujen aliakset
Käytä yllä näytettyjä menetelmäpolkuja.
Liittyvät kutsujan ID:t
FAQ · qwen-audio-3.0-realtime-plus
- Mitä syötteitä ja tuloksia on saatavilla?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:text,audio→text,audio- Mitä rajoja sovelletaan?
GET /v1/realtime?model=qwen-audio-3.0-realtime-plus·qwen-audio-3.0-realtime-plus:session.max_history_turns.minimum:1