TL;DR
Qwen3.5-Omni は、テキスト、画像、音声、ビデオを入力として受け入れ、テキストまたはリアルタイムの音声を返します。Alibaba Cloud DashScope API を通じてアクセスするか、HuggingFace Transformers を介してローカルで実行できます。このガイドでは、API のセットアップ、各モダリティの動作コード例、音声クローン作成、および Apidog を使用したリクエストのテスト方法について説明します。
扱うもの
Qwen3.5-Omni は、テキスト、画像、音声、ビデオの4種類の入力を同時に処理できる単一のモデルです。リクエストの設定に応じて、テキストまたは自然な音声を返します。

2026年3月30日にリリースされたこのモデルは、MoEバックボーンを持つThinker-Talkerアーキテクチャに基づいて構築されています。Thinkerはマルチモーダル入力を処理し、それに基づいて推論します。Talkerは、応答が完了する前にオーディオストリーミングを開始するマルチコードブックシステムを使用して、出力を音声に変換します。
3つのバリアントが利用可能です:
- Plus: 最高品質で、推論と音声クローン作成に最適
- Flash: 速度と品質のバランスが取れており、ほとんどの運用環境で推奨
- Light: 最低遅延で、モバイルおよびエッジシナリオ向け
このガイドでは、ほとんどのアプリケーションに適した出発点であるFlashをほとんどの例で使用します。最高の品質が必要な場合はPlusに切り替えてください。
DashScope を介した API アクセス
Alibaba Cloud の DashScope API は、Qwen3.5-Omni を本番環境で使用するための主要な方法です。DashScope アカウントと API キーが必要です。
ステップ1: DashScope アカウントを作成する
dashscope.aliyuncs.com にアクセスしてサインアップしてください。すでに Alibaba Cloud アカウントをお持ちの場合は、それを使用してください。
ステップ2: API キーを取得する
- DashScope コンソールにログインします
- 左側のサイドバーで API キー管理 をクリックします
- API キーを作成 をクリックします
- キー (形式:
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 (男性) の2種類が利用可能です。音声生成は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トークンのコンテキストウィンドウは、約400秒の720pビデオ(音声付き)に対応します。それより長い録画の場合は、トリミングまたは分割してください。
音声クローン
音声クローン機能を使用すると、モデルに目標の音声を学習させ、その音声で応答させることができます。これはPlusとFlashモデルでAPI経由で利用可能です。
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))
音声クローン品質向上のためのヒント:
- バックグラウンドノイズのないクリアな録音を使用する
- 非常に短いクリップよりも15〜30秒の方が良い結果が得られる
- 16kHz以上のWAV形式
- 音声サンプルは、プロソディ(抑揚)の一致を良くするため、読み上げられたテキストではなく自然な会話であるべき
ストリーミング応答
リアルタイムの音声チャットやインタラクティブなアプリケーションでは、ストリーミングを使用します。モデルは、完全な応答が生成される前に音声の返却を開始します。
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)について、基本リクエストを複製してモデルパラメータを変更できます。3つすべてを順番に実行し、応答、レイテンシ、出力品質を1つのビューで比較できます。
Apidog でテストアサーションを記述して、マルチモーダル応答を検証することもできます。
- テキスト応答の場合、
choices[0].message.contentが空でないことを確認する - 音声出力がリクエストされた場合、
choices[0].message.audio.dataが存在することを確認する - Flash の応答レイテンシが目標閾値未満であることをアサートする
これは、本番環境でどのバリアントを使用するかを決定する際に役立ちます。
エラー処理とリトライロジック
レート制限とタイムアウトは、特にビデオ入力の場合、大規模なマルチモーダルモデルでよく発生します。最初からリトライ処理を組み込みましょう。
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を超えるビデオ入力の場合、以下を検討してください:
- 送信する前に、関連する部分にトリミングする
- 視覚コンテンツが高解像度を必要としない場合、解像度を480pに下げる
- 長い録画をセグメントに分割し、結果を集計する
よくある問題と解決策
「数字や専門用語で音声出力が聞き取りにくい」これはARIAテクノロジーが対処する問題です。Qwen3.5-Omni(以前のバージョンではない)を使用していることを確認してください。自己ホストしている場合は、HuggingFaceの最新モデルウェイトを使用してください。
「音声割り込みを送信してもモデルが話し続ける」セマンティック割り込みにはFlashまたはPlusバリアントが必要です。Lightにはこの機能がない場合があります。また、割り込みが機能するように、応答をストリーミング(バッチではない)していることを確認してください。
「音声クローンの品質が低い」音声サンプルはクリーンである必要があります。アップロードする前に、Audacityなどのツールでバックグラウンドノイズを除去してください。少なくとも15秒の音声を使用してください。WAV形式の16kHzまたは44.1kHzが最適です。
「ビデオ入力がトークン制限に関するエラーを返す」256Kトークンは約400秒の720pビデオに対応します。より長いビデオは、トリミングするか、解像度を下げる必要があります。ビデオの長さを確認し、安全のため6分未満に短縮してください。
「ローカルデプロイが非常に遅い」本番環境でのローカル推論には、HuggingFace Transformers ではなく vLLM を使用してください。MoEモデルは、妥当なスループットを得るために vLLM のルーティング最適化が必要です。
よくある質問
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 と同じです。
複数のファイル(音声+画像)を1つのリクエストで送信するにはどうすればよいですか?
それらを content 配列内に、テキストプロンプトと一緒に個別の型付きオブジェクトとして配置します。4つのモダリティすべてが同じメッセージ内に存在できます。
音声またはビデオファイルのサイズ制限はありますか?
DashScope には、リクエストごとのペイロード制限があります。大きなファイルの場合は、base64エンコードの代わりにURL参照を使用してください。アクセス可能なストレージにファイルをホストし、audio または video_url フィールドにURLを渡します。
音声出力を無効にしてテキストのみを取得するにはどうすればよいですか?
modalities=["text"] を設定するか、modalities パラメータを省略します。テキストのみの応答は高速で安価です。
関数/ツール呼び出しをサポートしていますか?
はい。他のOpenAI互換モデルと同様に、標準の tools パラメータと関数定義を使用します。モデルは、独自のコードで実行する構造化されたツール呼び出しオブジェクトを返します。
長い音声録音を処理する最善の方法は何ですか?
10時間未満の録音は、単一のリクエストとして送信します。より長い録音は、自然な一時停止箇所で分割し、各セグメントを個別に処理します。アプリケーション層で結果を集約します。
完全なアプリケーションを構築する前に、マルチモーダルリクエストをテストするにはどうすればよいですか?
Apidog を使用して、各モダリティのリクエストテンプレートを構築して保存します。モデルのバリアントを切り替えたり、完全な応答構造を検査したり、アプリケーションコードを事前に書くことなく出力品質を検証するアサーションを記述したりできます。
