DEV Community

Cover image for Qwen3.5-Omni API活用ガイド:テキスト、音声、動画、声のクローン作成
Akira
Akira

Posted on • Originally published at apidog.com

Qwen3.5-Omni API活用ガイド:テキスト、音声、動画、声のクローン作成

TL;DR

Qwen3.5-Omni は、テキスト・画像・音声・ビデオを入力でき、テキストまたはリアルタイム音声を返すマルチモーダルAIモデルです。Alibaba Cloud DashScope API を通じて利用でき、ローカルは HuggingFace Transformers で実行可能です。本記事では、APIセットアップ・各モダリティのコード例・音声クローン・Apidog を使ったリクエストテスト方法を具体的に解説します。

Apidog を今すぐ試す

扱うもの

Qwen3.5-Omni は、テキスト・画像・音声・ビデオの4種類の入力を同時に処理できる単一モデルです。リクエスト設定に応じてテキストまたは自然音声を返します。

Qwen3.5-Omni モダリティ

2026年3月30日リリース。MoEバックボーンのThinker-Talkerアーキテクチャを採用。Thinkerがマルチモーダル入力を受け推論し、Talkerがマルチコードブックシステムで音声出力をストリーミングします。

3バリアント:

  • Plus: 最高品質。推論・音声クローン用途
  • Flash: 速度と品質のバランス。ほとんどの用途に推奨
  • Light: 最低遅延。モバイルやエッジ用途

以降の例では主にFlashを使用。用途に応じてPlus/Lightも選択可能です。

DashScope を介した API アクセス

DashScope API は Qwen3.5-Omni の本番利用に最適です。DashScope アカウントと API キーを準備してください。

ステップ1: DashScope アカウント作成

https://dashscope.aliyuncs.com でサインアップ。Alibaba Cloud アカウントがあれば流用可能です。

ステップ2: API キー取得

  1. DashScope コンソールにログイン
  2. サイドバーから API キー管理 を選択
  3. API キーを作成 をクリック
  4. sk-... 形式のキーをコピー

ステップ3: SDK インストール

pip install dashscope
Enter fullscreen mode Exit fullscreen mode

またはOpenAI互換API利用なら:

pip install openai
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

高度な推論には 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)
Enter fullscreen mode Exit fullscreen mode
  • 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

with open("response.wav", "wb") as f:
    f.write(base64.b64decode(audio_data))

print(f"Text: {text_content}")
print("Audio saved to response.wav")
Enter fullscreen mode Exit fullscreen mode
  • 内蔵音声は 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)
Enter fullscreen mode Exit fullscreen mode

ローカル画像の場合はbase64エンコードしてデータURL形式:

import base64

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

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?"
                }
            ]
        }
    ],
)
Enter fullscreen mode Exit fullscreen mode

ビデオ入力: 録画・スクリーンキャプチャ理解

ビデオ入力は視覚+音声同時推論が可能です。

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",
    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)
Enter fullscreen mode Exit fullscreen mode

オーディオビジュアルによるバイブコーディング

スクリーン録画からコード生成:

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",  # コード生成品質重視
    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)
Enter fullscreen mode Exit fullscreen mode
  • 256Kトークン=約400秒の720pビデオ。長い場合は分割/トリミング

音声クローン

音声クローン機能で、独自音声の応答が可能(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",
)

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))
Enter fullscreen mode Exit fullscreen mode

品質向上ポイント:

  • ノイズのないクリア録音
  • 15~30秒推奨
  • WAV形式16kHz以上
  • 読み上げより自然会話サンプル

ストリーミング応答

リアルタイム音声チャットやインタラクティブ用途はストリーミングを活用。

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)
Enter fullscreen mode Exit fullscreen mode
  • 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?"}]))
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode
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)
Enter fullscreen mode Exit fullscreen mode

ローカルデプロイのGPUメモリ要件:

バリアント 精度 最小VRAM
Plus (30B MoE) BF16 ~40GB
Flash BF16 ~20GB
Light BF16 ~10GB

本番環境ではHuggingFace TransformersよりvLLM利用を推奨。MoEモデルはvLLMのルーティング最適化で高速化。

Apidog で Qwen3.5-Omni リクエストをテスト

マルチモーダルAPIは、base64やネスト配列、複合応答などターミナルでのデバッグが煩雑です。

Apidogでのマルチモーダルテスト

Apidog なら、DashScopeエンドポイントを新規コレクション登録し、APIキーは環境変数化、各モダリティのリクエストテンプレートを構築できます。

各バリアント(Plus/Flash/Light)ごとにリクエストを複製し、モデルパラメータだけ切り替えて応答・レイテンシ・品質を一括比較できます。

テストアサーション例:

  • テキスト応答: 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,
)

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}回の試行後に失敗しました")
Enter fullscreen mode Exit fullscreen mode

100MB超ビデオ入力の場合は

  • 関連部分にトリミング
  • 解像度を480pなどに下げる
  • 長い録画はセグメント分割し集計

よくある問題と解決策

数字や専門用語の音声出力が聞き取りにくい

Qwen3.5-Omni(最新版)利用を確認。自己ホスト時はHuggingFaceの最新モデルウェイトを使用。

音声割り込みが効かない

FlashまたはPlusバリアントを利用し、ストリーミング応答を有効化。

音声クローンの品質が低い

クリーンなサンプルを15秒以上、WAV形式16kHz以上で用意。ノイズ除去も推奨。

ビデオ入力でトークン制限エラー

256Kトークン=約400秒/720p対応。より長い場合は短縮・分割。

ローカルデプロイが遅い

本番ではvLLM推奨。MoEモデルはvLLMのルーティング最適化必須。

よくある質問

Qwen3.5-Omni の DashScope モデルIDは?

qwen3.5-omni-plusqwen3.5-omni-flashqwen3.5-omni-light のいずれか。基本はFlashから始めるとよいでしょう。

DashScope で OpenAI Python SDK を使えますか?

可能です。base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" を指定し、DashScopeキーを api_key へセット。リクエスト・応答形式はOpenAI APIと同等です。

複数ファイル(音声+画像)を一度に送るには?

content 配列に型付きオブジェクトとして複数モダリティを追加。4つ全てを組み合わせ可能。

音声・ビデオファイルのサイズ制限は?

DashScopeのリクエスト毎のペイロード制限あり。大きなファイルはURL参照を推奨。ファイルを公開ストレージに置き、audiovideo_urlフィールドにURLを渡す。

音声出力を無効にしてテキストのみ取得するには?

modalities=["text"] 指定、または modalities 未指定でテキストのみ返却。コストも高速・低価格。

関数/ツール呼び出しはサポートされていますか?

はい。OpenAI互換の tools パラメータ・関数定義が利用可能。構造化ツール呼び出しオブジェクトを返却。

長い音声録音はどう処理すべき?

10時間未満は単一リクエストでOK。長い場合は適切な分割点で分割し、アプリ側で集約。

アプリ構築前にマルチモーダルリクエストを検証したい

Apidog で各モダリティのテンプレを作り、出力検証用アサーションも記述可能。モデルバリアントや応答構造もGUIで細かく検証できます。

Top comments (0)