Qwen3.5-Omni API 활용법: 텍스트, 오디오, 비디오, 음성 복제

@apidog

@apidog

31 March 2026

Qwen3.5-Omni API 활용법: 텍스트, 오디오, 비디오, 음성 복제

Apidog 엔터프라이즈

온프레미스 배포

SSO & RBAC

SOC 2 준수

Apidog Enterprise 살펴보기

TL;DR

Qwen3.5-Omni는 텍스트, 이미지, 오디오, 비디오를 입력으로 받아들이고 텍스트 또는 실시간 음성으로 응답합니다. Alibaba Cloud DashScope API를 통해 액세스하거나 HuggingFace Transformers를 통해 로컬에서 실행할 수 있습니다. 이 가이드는 API 설정, 각 양식에 대한 작동 코드 예시, 음성 복제 및 Apidog로 요청을 테스트하는 방법을 다룹니다.

button

작업 개요

Qwen3.5-Omni는 텍스트, 이미지, 오디오, 비디오 등 네 가지 입력 유형을 동시에 처리하는 단일 모델입니다. 요청 구성에 따라 텍스트 또는 자연스러운 음성으로 응답합니다.

2026년 3월 30일에 출시된 이 모델은 MoE(Mixture-of-Experts) 백본을 가진 Thinker-Talker 아키텍처를 기반으로 구축되었습니다. Thinker는 다중 모달 입력을 처리하고 추론하며, Talker는 전체 응답이 완료되기 전에 오디오 스트리밍을 시작하는 다중 코드북 시스템을 사용하여 출력을 음성으로 변환합니다.

세 가지 변형을 사용할 수 있습니다:

이 가이드에서는 대부분의 예시에 Flash를 사용합니다. 이는 대부분의 애플리케이션에 적합한 시작점이기 때문입니다. 최대 품질이 필요한 경우 Plus로 전환하세요.

DashScope를 통한 API 액세스

Alibaba Cloud의 DashScope API는 Qwen3.5-Omni를 프로덕션에서 사용하는 주요 방법입니다. DashScope 계정과 API 키가 필요합니다.

1단계: DashScope 계정 생성

dashscope.aliyuncs.com으로 이동하여 가입하세요. 이미 Alibaba Cloud 계정이 있다면 해당 계정을 사용하세요.

2단계: API 키 가져오기

  1. DashScope 콘솔에 로그인합니다.
  2. 왼쪽 사이드바에서 API 키 관리를 클릭합니다.
  3. API 키 생성을 클릭합니다.
  4. 키(형식: sk-...)를 복사합니다.

3단계: SDK 설치

pip install dashscope

또는 openai SDK와 함께 OpenAI 호환 엔드포인트를 직접 사용할 수 있습니다:

pip install openai

DashScope는 https://dashscope.aliyuncs.com/compatible-mode/v1에서 OpenAI 호환 API를 노출하며, 이는 base_url을 스왑하고 OpenAI에 작성하는 것과 동일한 코드를 사용할 수 있음을 의미합니다.

텍스트 입력 및 출력

가장 간단한 경우부터 시작합니다: 텍스트 입력, 텍스트 출력.

from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": "Explain the difference between REST and GraphQL APIs in plain terms."
        }
    ],
)

print(response.choices[0].message.content)

더 어려운 추론 작업에는 qwen3.5-omni-plus로 전환하고, 지연 시간이 우선순위인 경우에는 qwen3.5-omni-light를 사용하세요.


오디오 입력: 전사 및 이해

오디오 파일 URL 또는 base64로 인코딩된 오디오를 전달합니다. 모델은 내용을 기본적으로 전사하고 이해하며 추론합니다. 별도의 ASR 단계가 필요 없습니다.

import base64
from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

# 로컬 오디오 파일 로드
with open("meeting_recording.wav", "rb") as f:
    audio_data = base64.b64encode(f.read()).decode("utf-8")

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": audio_data,
                        "format": "wav"
                    }
                },
                {
                    "type": "text",
                    "text": "Summarize the key decisions made in this meeting and list any action items."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)

이 모델은 113개 언어의 음성 인식을 지원합니다. 언어를 지정할 필요가 없으며, 자동으로 감지합니다.

지원되는 오디오 형식: WAV, MP3, M4A, OGG, FLAC.

오디오 출력: 응답 내 텍스트 음성 변환

텍스트 대신 음성을 받으려면 modalities 매개변수를 설정하고 오디오 출력을 구성합니다:

from openai import OpenAI
import base64

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    messages=[
        {
            "role": "user",
            "content": "Describe the steps to authenticate a REST API using OAuth 2.0."
        }
    ],
)

# 응답에는 텍스트와 오디오가 모두 포함됩니다.
text_content = response.choices[0].message.content
audio_data = response.choices[0].message.audio.data  # base64로 인코딩된 WAV

# 오디오 저장
with open("response.wav", "wb") as f:
    f.write(base64.b64decode(audio_data))

print(f"Text: {text_content}")
print("Audio saved to response.wav")

두 가지 내장 음성인 Chelsie(여성)와 Ethan(남성)을 사용할 수 있습니다. 음성 생성은 36개 언어로 작동합니다.

이미지 입력: 시각적 이해

텍스트 질문과 함께 이미지 URL 또는 base64로 인코딩된 이미지를 전달합니다:

from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://example.com/api-diagram.png"
                    }
                },
                {
                    "type": "text",
                    "text": "Describe this API architecture diagram and identify any potential bottlenecks."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)

로컬 이미지는 base64로 인코딩합니다:

import base64

with open("screenshot.png", "rb") as f:
    image_data = base64.b64encode(f.read()).decode("utf-8")

# 데이터 URL 형식 사용
image_url = f"data:image/png;base64,{image_data}"

response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": image_url}
                },
                {
                    "type": "text",
                    "text": "What error is shown in this screenshot?"
                }
            ]
        }
    ],
)

비디오 입력: 녹화 및 화면 캡처 이해

비디오 입력은 Qwen3.5-Omni가 텍스트 또는 이미지 모델이 할 수 없는 작업을 수행하는 부분입니다: 시각 및 오디오 트랙 모두에서 동시에 추론합니다.

from openai import OpenAI
import base64

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

# 비디오 URL 전달
response = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video_url",
                    "video_url": {
                        "url": "https://example.com/product-demo.mp4"
                    }
                },
                {
                    "type": "text",
                    "text": "Describe what the developer is building in this demo and write equivalent code."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)

오디오-시각적 바이브 코딩

"바이브 코딩" 사용 사례는 화면 녹화를 전달하고 모델에 보이는 것을 바탕으로 코드를 생성하도록 요청하는 것입니다:

with open("screen_recording.mp4", "rb") as f:
    video_data = base64.b64encode(f.read()).decode("utf-8")

response = client.chat.completions.create(
    model="qwen3.5-omni-plus",  # 최고의 코드 생성 품질을 위해 Plus 사용
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video_url",
                    "video_url": {
                        "url": f"data:video/mp4;base64,{video_data}"
                    }
                },
                {
                    "type": "text",
                    "text": "Watch this screen recording and write the complete code that replicates what you see being built. Include all the UI components and their interactions."
                }
            ]
        }
    ],
)

print(response.choices[0].message.content)

256K 토큰 컨텍스트 창은 오디오가 포함된 720p 비디오 약 400초에 해당합니다. 이보다 긴 녹화는 잘라내거나 분할해야 합니다.

음성 복제

음성 복제는 모델에 대상 음성을 제공하고 해당 음성으로 응답하도록 하는 기능입니다. 이 기능은 API를 통해 Plus 및 Flash에서 사용할 수 있습니다.

import base64
from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

# 복제를 위해 10-30초 음성 샘플 로드
with open("voice_sample.wav", "rb") as f:
    voice_sample = base64.b64encode(f.read()).decode("utf-8")

response = client.chat.completions.create(
    model="qwen3.5-omni-plus",
    modalities=["text", "audio"],
    audio={
        "voice": "custom",
        "format": "wav",
        "voice_sample": {
            "data": voice_sample,
            "format": "wav"
        }
    },
    messages=[
        {
            "role": "user",
            "content": "Welcome to the Apidog developer portal. How can I help you today?"
        }
    ],
)

audio_data = response.choices[0].message.audio.data
with open("cloned_response.wav", "wb") as f:
    f.write(base64.b64decode(audio_data))

음성 복제 품질을 위한 팁:

스트리밍 응답

실시간 음성 채팅 또는 대화형 애플리케이션의 경우 스트리밍을 사용하세요. 전체 응답이 생성되기 전에 모델이 오디오를 반환하기 시작합니다:

from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

stream = client.chat.completions.create(
    model="qwen3.5-omni-flash",
    modalities=["text", "audio"],
    audio={"voice": "Ethan", "format": "pcm16"},
    messages=[
        {
            "role": "user",
            "content": "Explain how WebSocket connections differ from HTTP polling."
        }
    ],
    stream=True,
)

audio_chunks = []
text_chunks = []

for chunk in stream:
    delta = chunk.choices[0].delta
    if hasattr(delta, "audio") and delta.audio:
        if delta.audio.get("data"):
            audio_chunks.append(delta.audio["data"])
    if delta.content:
        text_chunks.append(delta.content)
        print(delta.content, end="", flush=True)

print()  # 스트리밍 텍스트 후 줄 바꿈

# 오디오 청크 결합 및 저장
if audio_chunks:
    import base64
    full_audio = b"".join(base64.b64decode(chunk) for chunk in audio_chunks)
    with open("streamed_response.pcm", "wb") as f:
        f.write(full_audio)

PCM16 형식은 완전한 파일을 기다릴 필요 없이 오디오 출력 버퍼로 직접 파이프할 수 있으므로 스트리밍에 적합합니다.

다중 모달이 혼합된 다중 턴 대화

실제 대화는 턴마다 입력을 섞습니다. 다양한 모달리티로 대화 기록을 관리하는 방법은 다음과 같습니다:

from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
)

conversation = []

def send_message(content_parts):
    conversation.append({"role": "user", "content": content_parts})
    
    response = client.chat.completions.create(
        model="qwen3.5-omni-flash",
        messages=conversation,
    )
    
    reply = response.choices[0].message.content
    conversation.append({"role": "assistant", "content": reply})
    return reply

# 턴 1: 텍스트
print(send_message([{"type": "text", "text": "I have an API that keeps returning 503 errors."}]))

# 턴 2: 이미지 추가 (오류 로그 스크린샷)
import base64
with open("error_log.png", "rb") as f:
    img = base64.b64encode(f.read()).decode()

print(send_message([
    {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img}"}},
    {"type": "text", "text": "Here's the error log screenshot. What's causing this?"}
]))

# 턴 3: 후속 텍스트
print(send_message([{"type": "text", "text": "How do I fix the connection pool exhaustion you mentioned?"}]))

256K 컨텍스트 창은 이미지 및 오디오가 포함된 긴 대화도 잘림 문제 없이 처리할 수 있음을 의미합니다.

HuggingFace를 사용한 로컬 배포

Qwen3.5-Omni를 자체 인프라에서 실행해야 하는 경우:

pip install transformers==4.57.3
pip install accelerate
pip install qwen-omni-utils -U
pip install -U flash-attn --no-build-isolation
import soundfile as sf
from transformers import Qwen3OmniMoeForConditionalGeneration, Qwen3OmniMoeProcessor
from qwen_omni_utils import process_mm_info

model_path = "Qwen/Qwen3-Omni-30B-A3B-Instruct"

model = Qwen3OmniMoeForConditionalGeneration.from_pretrained(
    model_path,
    device_map="auto",
    attn_implementation="flash_attention_2",
)
processor = Qwen3OmniMoeProcessor.from_pretrained(model_path)

conversation = [
    {
        "role": "system",
        "content": [
            {"type": "text", "text": "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."}
        ],
    },
    {
        "role": "user",
        "content": [
            {"type": "audio", "audio": "path/to/your/audio.wav"},
            {"type": "text", "text": "What is being discussed in this audio?"}
        ],
    },
]

text = processor.apply_chat_template(
    conversation,
    add_generation_prompt=True,
    tokenize=False,
)
audios, images, videos = process_mm_info(conversation, use_audio_in_video=True)
inputs = processor(
    text=text,
    audio=audios,
    images=images,
    videos=videos,
    return_tensors="pt",
    padding=True,
)
inputs = inputs.to(model.device).to(model.dtype)

text_ids, audio_output = model.generate(**inputs, speaker="Chelsie")

text_response = processor.batch_decode(text_ids, skip_special_tokens=True)[0]
sf.write("local_response.wav", audio_output.reshape(-1).cpu().numpy(), samplerate=24000)

print(text_response)

로컬 배포를 위한 GPU 메모리 요구 사항:

변형 정밀도 최소 VRAM
Plus (30B MoE) BF16 ~40GB
Flash BF16 ~20GB
Light BF16 ~10GB

프로덕션 로컬 추론을 위해서는 HuggingFace Transformers 대신 vLLM을 사용하세요. MoE 모델은 vLLM의 라우팅 최적화 아래에서 더 빠르게 실행됩니다.

Apidog로 Qwen3.5-Omni 요청 테스트

다중 모달 API 요청은 일반 JSON보다 디버깅하기 더 어렵습니다. base64로 인코딩된 오디오 및 비디오, 중첩된 콘텐츠 배열, 그리고 텍스트와 오디오를 모두 포함할 수 있는 응답을 다루기 때문에 터미널에서 작업하는 것은 빠르게 지루해집니다.

Apidog는 이를 깔끔하게 처리합니다. DashScope 엔드포인트를 새 컬렉션으로 설정하고, API 키를 환경 변수로 저장하고, 작업 중인 각 모달리티에 대한 요청 템플릿을 만드세요.

각 변형(Plus, Flash, Light)에 대해 기본 요청을 복제하고 모델 매개변수를 변경할 수 있습니다. 세 가지를 순서대로 실행하고 하나의 보기에서 응답, 지연 시간 및 출력 품질을 비교하세요.

또한 Apidog에서 테스트 어설션을 작성하여 다중 모달 응답을 확인할 수 있습니다:

이는 프로덕션에서 사용할 변형을 결정할 때 유용합니다.

오류 처리 및 재시도 로직

속도 제한 및 시간 초과는 특히 비디오 입력의 경우 대규모 다중 모달 모델에서 흔히 발생합니다. 처음부터 재시도 처리를 구축하세요:

import time
import random
from openai import OpenAI, RateLimitError, APITimeoutError, APIConnectionError

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key="sk-YOUR_DASHSCOPE_KEY",
    timeout=120,  # 대용량 비디오 입력의 경우 2분 시간 초과
)

def call_with_retry(messages, model="qwen3.5-omni-flash", max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model=model,
                messages=messages,
            )
        except RateLimitError:
            wait = (2 ** attempt) + random.uniform(0, 1)
            print(f"속도 제한에 도달했습니다. {wait:.1f}초 동안 기다립니다...")
            time.sleep(wait)
        except (APITimeoutError, APIConnectionError) as e:
            if attempt == max_retries - 1:
                raise
            wait = (2 ** attempt) + random.uniform(0, 1)
            print(f"연결 오류: {e}. {wait:.1f}초 후에 다시 시도합니다...")
            time.sleep(wait)
    raise RuntimeError(f"{max_retries}번 시도 후 실패했습니다.")

100MB보다 큰 비디오 입력의 경우 다음을 고려하세요:


일반적인 문제 및 해결 방법

"숫자나 전문 용어에서 오디오 출력이 엉망입니다."이것은 ARIA 기술이 해결하는 문제입니다. Qwen3.5-Omni(이전 버전 아님)를 사용하고 있는지 확인하세요. 자체 호스팅하는 경우 HuggingFace에서 최신 모델 가중치를 사용하세요.

"오디오 중단을 보내도 모델이 계속 말합니다."의미론적 중단은 Flash 또는 Plus 변형이 필요합니다. Light는 이 기능이 없을 수 있습니다. 또한 중단이 작동하려면 응답을 스트리밍(배치가 아님)하고 있는지 확인하세요.

"음성 복제 품질이 좋지 않습니다."음성 샘플은 깨끗해야 합니다. 업로드하기 전에 Audacity와 같은 도구로 배경 소음을 제거하세요. 최소 15초의 오디오를 사용하세요. 16kHz 또는 44.1kHz의 WAV가 가장 잘 작동합니다.

"비디오 입력에서 토큰 제한에 대한 오류가 반환됩니다."256K 토큰은 대략 400초의 720p 비디오에 해당합니다. 더 긴 비디오는 트리밍하거나 해상도를 낮춰야 합니다. 비디오 길이를 확인하고 안전을 위해 6분 미만으로 줄이세요.

"로컬 배포가 매우 느립니다."프로덕션 로컬 추론에는 HuggingFace Transformers 대신 vLLM을 사용하세요. MoE 모델은 합리적인 처리량을 위해 vLLM의 라우팅 최적화가 필요합니다.

FAQ

Qwen3.5-Omni에 어떤 DashScope 모델 ID를 사용해야 하나요?

품질 및 지연 시간 요구 사항에 따라 qwen3.5-omni-plus, qwen3.5-omni-flash 또는 qwen3.5-omni-light를 사용하세요. 대부분의 사용 사례에서는 Flash로 시작하세요.

DashScope와 함께 OpenAI Python SDK를 사용할 수 있나요?

예. base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"을 설정하고 DashScope 키를 api_key로 사용하세요. 요청 및 응답 형식은 OpenAI API와 동일합니다.

하나의 요청으로 여러 파일(오디오 + 이미지)을 어떻게 보내나요?

텍스트 프롬프트와 함께 별도의 유형화된 객체로 content 배열에 넣으세요. 네 가지 모달리티 모두 동일한 메시지에 나타날 수 있습니다.

오디오 또는 비디오 파일의 크기 제한이 있나요?

DashScope에는 요청당 페이로드 제한이 있습니다. 큰 파일의 경우 base64 인코딩 대신 URL 참조를 사용하세요. 접근 가능한 스토리지에 파일을 호스팅하고 audio 또는 video_url 필드에 URL을 전달하세요.

오디오 출력을 비활성화하고 텍스트만 받으려면 어떻게 해야 하나요?

modalities=["text"]를 설정하거나 modalities 매개변수를 생략하세요. 텍스트 전용 응답이 더 빠르고 저렴합니다.

함수/도구 호출을 지원하나요?

예. 다른 OpenAI 호환 모델과 마찬가지로 함수 정의와 함께 표준 tools 매개변수를 사용하세요. 모델은 자체 코드에서 실행하는 구조화된 도구 호출 객체를 반환합니다.

긴 오디오 녹음을 처리하는 가장 좋은 방법은 무엇인가요?

10시간 미만의 녹음은 단일 요청으로 보냅니다. 더 긴 녹음의 경우 자연스러운 일시 정지 지점에서 분할하고 각 세그먼트를 개별적으로 처리합니다. 애플리케이션 레이어에서 결과를 집계합니다.

전체 애플리케이션을 구축하기 전에 다중 모달 요청을 어떻게 테스트하나요?

Apidog를 사용하여 각 모달리티에 대한 요청 템플릿을 구축하고 저장하세요. 먼저 애플리케이션 코드를 작성하지 않고도 모델 변형 간에 전환하고, 전체 응답 구조를 검사하고, 출력 품질을 확인하는 어설션을 작성할 수 있습니다.

button

Apidog에서 API 설계-첫 번째 연습

API를 더 쉽게 구축하고 사용하는 방법을 발견하세요

Qwen3.5-Omni API 활용법: 텍스트, 오디오, 비디오, 음성 복제