すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Model Studio:マルチモーダル

最終更新日:Jun 14, 2025

Qwen-Omni は、動画、音声、画像、テキストなど、複数の入力モーダルをサポートしています。音声とテキストを出力できます。

概要と料金

Qwen-VLと比較して、Qwen-Omni は次のことができます。

  • 動画ファイルの視覚情報と音声情報を理解する。

  • マルチモーダルデータを理解する。

  • 音声を出力する。

Qwen-Omni は、視覚および音声理解能力にも優れています。

オープンソース

名前

コンテキストウィンドウ

最大入力

最大出力

無料枠

(注)

(トークン)

qwen2.5-omni-7b

32,768

30,720

2,048

100 万トークン (モーダルに関係なく)

アクティベーション後 180 日間有効

無料枠を使い切った後は、オープンソース Qwen-Omni を使用できません。最新情報にご期待ください。

音声、画像、動画のトークンを計算する

音声

1 秒あたり 25 トークンに相当します。音声が 1 秒未満の場合は、25 トークンとして計算されます。

画像

28 × 28 ピクセルごとに 1 トークンに相当します。各画像は少なくとも 4 トークン、最大 1,280 トークンに変換されます。次のコードを実行して、画像のトークンを推定します。

import math
# Pillow ライブラリをインストールするには、次のコマンドを使用します: pip install Pillow
from PIL import Image

def token_calculate(image_path):
    # 指定された PNG 画像ファイルを開きます
    image = Image.open(image_path)
    # 画像の元のディメンションを取得します
    height = image.height
    width = image.width
    # 高さを 28 の倍数に調整します
    h_bar = round(height / 28) * 28
    # 幅を 28 の倍数に調整します
    w_bar = round(width / 28) * 28
    # 画像トークンの下限: 4 トークン
    min_pixels = 28 * 28 * 4
    # 画像トークンの上限: 1280 トークン
    max_pixels = 1280 * 28 * 28
    # 画像をスケーリングして、ピクセル総数を [min_pixels, max_pixels] の範囲内に調整します
    if h_bar * w_bar > max_pixels:
        # スケーリング係数 beta を計算して、スケーリングされた画像のピクセル総数が max_pixels を超えないようにします
        beta = math.sqrt((height * width) / max_pixels)
        # 調整された高さを再計算し、28 の倍数であることを確認します
        h_bar = math.floor(height / beta / 28) * 28
        # 調整された幅を再計算し、28 の倍数であることを確認します
        w_bar = math.floor(width / beta / 28) * 28
    elif h_bar * w_bar < min_pixels:
        # スケーリング係数 beta を計算して、スケーリングされた画像のピクセル総数が min_pixels 以上になるようにします
        beta = math.sqrt(min_pixels / (height * width))
        # 調整された高さを再計算し、28 の倍数であることを確認します
        h_bar = math.ceil(height * beta / 28) * 28
        # 調整された幅を再計算し、28 の倍数であることを確認します
        w_bar = math.ceil(width * beta / 28) * 28
    print(f"スケーリングされた画像のディメンション: 高さ {h_bar}, 幅 {w_bar}")
    # 画像のトークン数を計算します: ピクセル総数を 28 * 28 で割ります
    token = int((h_bar * w_bar) / (28 * 28))
    # システムは自動的に視覚マーカー <|vision_bos|> と <|vision_eos|> (それぞれ 1 トークン) を追加します
    total_token = token + 2
    print(f"画像のトークン数は {total_token} です")    
    return total_token
if __name__ == "__main__":
    total_token = token_calculate(image_path="test.png")
// sharp をインストールするには、次のコマンドを使用します: npm install sharp
import sharp from 'sharp';

async function tokenCalculate(imagePath) {
    // 指定された PNG 画像ファイルを開きます
    const image = sharp(imagePath);
    const metadata = await image.metadata();

    // 画像の元のディメンションを取得します
    const height = metadata.height;
    const width = metadata.width;

    // 高さを 28 の倍数に調整します
    let hBar = Math.round(height / 28) * 28;
    // 幅を 28 の倍数に調整します
    let wBar = Math.round(width / 28) * 28;

    // 画像トークンの下限: 4 トークン
    const minPixels = 28 * 28 * 4;
    // 画像トークンの上限: 1280 トークン
    const maxPixels = 1280 * 28 * 28;

    // 画像をスケーリングして、ピクセル総数を [min_pixels, max_pixels] の範囲内に調整します
    if (hBar * wBar > maxPixels) {
        // スケーリング係数 beta を計算して、スケーリングされた画像のピクセル総数が max_pixels を超えないようにします
        const beta = Math.sqrt((height * width) / maxPixels);
        // 調整された高さを再計算し、28 の倍数であることを確認します
        hBar = Math.floor(height / beta / 28) * 28;
        // 調整された幅を再計算し、28 の倍数であることを確認します
        wBar = Math.floor(width / beta / 28) * 28;
    } else if (hBar * wBar < minPixels) {
        // スケーリング係数 beta を計算して、スケーリングされた画像のピクセル総数が min_pixels 以上になるようにします
        const beta = Math.sqrt(minPixels / (height * width));
        // 調整された高さを再計算し、28 の倍数であることを確認します
        hBar = Math.ceil(height * beta / 28) * 28;
        // 調整された幅を再計算し、28 の倍数であることを確認します
        wBar = Math.ceil(width * beta / 28) * 28;
    }
    console.log(`スケーリングされた画像のディメンション: 高さ ${hBar}, 幅 ${wBar}`);
    // 画像のトークン数を計算します: ピクセル総数を 28 * 28 で割ります
    const token = Math.floor((hBar * wBar) / (28 * 28));
    // システムは自動的に視覚マーカー <|vision_bos|> と <|vision_eos|> (それぞれ 1 トークン) を追加します
    console.log(`画像のトークン数は ${token + 2} です`);
    const totalToken = token + 2;
    return totalToken;
}

// test.png をローカル画像パスに置き換えます
tokenCalculate('test.png').catch(err => {
    console.error('画像の処理中にエラーが発生しました:', err);
});

動画

ビデオファイル内のトークンは、video_tokensaudio_tokens に分割されます。

  • video_tokens

    計算は比較的複雑です。サンプルコード:

    # 使用前にインストールしてください: pip install opencv-python
    import math
    import os
    import logging
    import cv2
    
    logger = logging.getLogger(__name__)
    
    # 固定パラメーター
    FRAME_FACTOR = 2
    IMAGE_FACTOR = 28
    # ビデオフレームの縦横比
    MAX_RATIO = 200
    
    # ビデオフレームトークンの下限
    VIDEO_MIN_PIXELS = 128 * 28 * 28
    # ビデオフレームトークンの上限
    VIDEO_MAX_PIXELS = 768 * 28 * 28
    
    # Qwen-Omni モデルの FPS は 2 です
    FPS = 2
    # 抽出する最小フレーム数
    FPS_MIN_FRAMES = 4
    # 抽出する最大フレーム数
    FPS_MAX_FRAMES = 512
    
    # ビデオ入力の最大ピクセル値
    VIDEO_TOTAL_PIXELS = 65536 * 28 * 28
    
    def round_by_factor(number, factor):
        return round(number / factor) * factor
    
    def ceil_by_factor(number, factor):
        return math.ceil(number / factor) * factor
    
    def floor_by_factor(number, factor):
        return math.floor(number / factor) * factor
    
    def get_video(video_path):
        cap = cv2.VideoCapture(video_path)
        frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
        total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        video_fps = cap.get(cv2.CAP_PROP_FPS)
        cap.release()
        return frame_height, frame_width, total_frames, video_fps
    
    def smart_nframes(total_frames, video_fps):
        min_frames = ceil_by_factor(FPS_MIN_FRAMES, FRAME_FACTOR)
        max_frames = floor_by_factor(min(FPS_MAX_FRAMES, total_frames), FRAME_FACTOR)
        duration = total_frames / video_fps if video_fps != 0 else 0
        if duration - int(duration) > (1 / FPS):
            total_frames = math.ceil(duration * video_fps)
        else:
            total_frames = math.ceil(int(duration) * video_fps)
        nframes = total_frames / video_fps * FPS
        nframes = int(min(min(max(nframes, min_frames), max_frames), total_frames))
        if not (FRAME_FACTOR <= nframes <= total_frames):
            raise ValueError(f"nframes should in interval [{FRAME_FACTOR}, {total_frames}], but got {nframes}.")
        return nframes
    
    def smart_resize(height, width, nframes, factor=IMAGE_FACTOR):
        min_pixels = VIDEO_MIN_PIXELS
        total_pixels = VIDEO_TOTAL_PIXELS
        max_pixels = max(min(VIDEO_MAX_PIXELS, total_pixels / nframes * FRAME_FACTOR), int(min_pixels * 1.05))
        if max(height, width) / min(height, width) > MAX_RATIO:
            raise ValueError(f"absolute aspect ratio must be smaller than {MAX_RATIO}, got {max(height, width) / min(height, width)}")
        h_bar = max(factor, round_by_factor(height, factor))
        w_bar = max(factor, round_by_factor(width, factor))
        if h_bar * w_bar > max_pixels:
            beta = math.sqrt((height * width) / max_pixels)
            h_bar = floor_by_factor(height / beta, factor)
            w_bar = floor_by_factor(width / beta, factor)
        elif h_bar * w_bar < min_pixels:
            beta = math.sqrt(min_pixels / (height * width))
            h_bar = ceil_by_factor(height * beta, factor)
            w_bar = ceil_by_factor(width * beta, factor)
        return h_bar, w_bar
    
    def video_token_calculate(video_path):
        height, width, total_frames, video_fps = get_video(video_path)
        nframes = smart_nframes(total_frames, video_fps)
        resized_height, resized_width = smart_resize(height, width, nframes)
        video_token = int(math.ceil(nframes / FPS) * resized_height / 28 * resized_width / 28)
        video_token += 2  # ビジュアルマーカー
        return video_token
    
    if __name__ == "__main__":
        video_path = "spring_mountain.mp4"  # ビデオパス
        video_token = video_token_calculate(video_path)
        print("video_tokens:", video_token)
    // 使用前にインストールしてください: npm install node-ffprobe @ffprobe-installer/ffprobe
    import ffprobeInstaller from '@ffprobe-installer/ffprobe';
    import ffprobe from 'node-ffprobe';
    // ffprobe パスを設定します
    ffprobe.FFPROBE_PATH = ffprobeInstaller.path;
    
    // ビデオ情報を取得します
    async function getVideoInfo(videoPath) {
      try {
        const probeData = await ffprobe(videoPath);
        const videoStream = probeData.streams.find(s => s.codec_type === 'video');
        if (!videoStream) throw new Error('ビデオストリームが見つかりません');
        const { width, height, nb_frames: totalFrames, avg_frame_rate } = videoStream;
        const [numerator, denominator] = avg_frame_rate.split('/');
        const frameRate = parseFloat(numerator) / parseFloat(denominator);
        return { width, height, totalFrames: parseInt(totalFrames), frameRate };
      } catch (error) {
        console.error('ビデオ情報の取得に失敗しました:', error.message);
        throw error;
      }
    }
    
    // 定数設定
    const CONFIG = {
      FRAME_FACTOR: 2,
      IMAGE_FACTOR: 28,
      MAX_RATIO: 200,
      VIDEO_MIN_PIXELS: 128 * 28 * 28,
      VIDEO_MAX_PIXELS: 768 * 28 * 28,
      FPS: 2,
      FPS_MIN_FRAMES: 4,
      FPS_MAX_FRAMES: 512,
      VIDEO_TOTAL_PIXELS: 65536 * 28 * 28,
    };
    
    // 因子丸めユーティリティ
    function byFactor(number, factor, mode = 'round') {
      if (mode === 'ceil') return Math.ceil(number / factor) * factor;
      if (mode === 'floor') return Math.floor(number / factor) * factor;
      return Math.round(number / factor) * factor;
    }
    
    // フレーム抽出数を計算します
    function smartNFrames(ele, totalFrames, frameRate) {
      const fps = ele.fps || CONFIG.FPS;
      const minFrames = byFactor(ele.min_frames || CONFIG.FPS_MIN_FRAMES, CONFIG.FRAME_FACTOR, 'ceil');
      const maxFrames = byFactor(
        ele.max_frames || Math.min(CONFIG.FPS_MAX_FRAMES, totalFrames),
        CONFIG.FRAME_FACTOR,
        'floor'
      );
      const duration = frameRate ? totalFrames / frameRate : 0;
      let totalFramesAdjusted = duration % 1 > (1 / fps)
        ? Math.ceil(duration * frameRate)
        : Math.ceil(Math.floor(duration) * frameRate);
      const nframes = (totalFramesAdjusted / frameRate) * fps;
      const finalNFrames = Math.min(
        Math.max(nframes, minFrames),
        Math.min(maxFrames, totalFramesAdjusted)
      );
      if (finalNFrames < CONFIG.FRAME_FACTOR || finalNFrames > totalFramesAdjusted) {
        throw new Error(`フレーム数は ${CONFIG.FRAME_FACTOR} から ${totalFramesAdjusted} の間である必要があります。現在: ${finalNFrames}`);
      }
      return Math.floor(finalNFrames);
    }
    
    // スマート解像度調整
    async function smartResize(ele, videoInfo) {
      const { height, width, totalFrames, frameRate } = videoInfo;
      const minPixels = CONFIG.VIDEO_MIN_PIXELS;
      const nframes = smartNFrames(ele, totalFrames, frameRate);
      const maxPixels = Math.max(
        Math.min(CONFIG.VIDEO_MAX_PIXELS, CONFIG.VIDEO_TOTAL_PIXELS / nframes * CONFIG.FRAME_FACTOR),
        Math.floor(minPixels * 1.05)
      );
      const ratio = Math.max(height, width) / Math.min(height, width);
      if (ratio > CONFIG.MAX_RATIO) throw new Error(`縦横比 ${ratio} が制限 ${CONFIG.MAX_RATIO} を超えています`);
      let hBar = Math.max(CONFIG.IMAGE_FACTOR, byFactor(height, CONFIG.IMAGE_FACTOR));
      let wBar = Math.max(CONFIG.IMAGE_FACTOR, byFactor(width, CONFIG.IMAGE_FACTOR));
      if (hBar * wBar > maxPixels) {
        const beta = Math.sqrt((height * width) / maxPixels);
        hBar = byFactor(height / beta, CONFIG.IMAGE_FACTOR, 'floor');
        wBar = byFactor(width / beta, CONFIG.IMAGE_FACTOR, 'floor');
      } else if (hBar * wBar < minPixels) {
        const beta = Math.sqrt(minPixels / (height * width));
        hBar = byFactor(height * beta, CONFIG.IMAGE_FACTOR, 'ceil');
        wBar = byFactor(width * beta, CONFIG.IMAGE_FACTOR, 'ceil');
      }
      return { hBar, wBar };
    }
    
    // トークン数を計算します
    async function tokenCalculate(videoPath) {
      const messages = [{ content: [{ video: videoPath, FPS: CONFIG.FPS }] }];
      const visionInfos = extractVisionInfo(messages);
      const videoInfo = await getVideoInfo(videoPath);
      const { hBar, wBar } = await smartResize(visionInfos[0], videoInfo);
      const { totalFrames, frameRate } = videoInfo;
      const numFrames = smartNFrames(visionInfos[0], totalFrames, frameRate);
      const videoToken = Math.ceil(numFrames / 2) * Math.floor(hBar / 28) * Math.floor(wBar / 28) + 2;
      return videoToken;
    }
    
    // ビジュアル情報を抽出します
    function extractVisionInfo(conversations) {
      const visionInfos = [];
      if (!Array.isArray(conversations)) conversations = [conversations];
      conversations.forEach(conversation => {
        if (!Array.isArray(conversation)) conversation = [conversation];
        conversation.forEach(message => {
          if (Array.isArray(message.content)) {
            message.content.forEach(ele => {
              if (ele.image || ele.image_url || ele.video || ['image', 'image_url', 'video'].includes(ele.type)) {
                visionInfos.push(ele);
              }
            });
          }
        });
      });
      return visionInfos;
    }
    
    async function main() {
      try {
        const videoPath = "spring_mountain.mp4"; // ローカルパスに置き換えてください
        const videoToken = await tokenCalculate(videoPath);
        console.log('ビデオトークン:', videoToken);
      } catch (error) {
        console.error('エラー:', error.message);
      }
    }
    
    main();
  • audio_tokens

    音声 1 秒ごとに 25 トークンに相当します。音声が 1 秒未満の場合は、25 トークンとして計算されます。

使用方法

入力

入力モダリティ

次の入力の組み合わせがサポートされています。

複数の非テキストモダリティを 1 つのユーザーメッセージに含めないでください。

入力方法

画像、音声、動画ファイルは Base64 エンコーディングとパブリック URL をサポートしています。次のサンプルコードはパブリック URL を使用しています。Base64 エンコードされたファイルを使用するには、Base64 エンコードされたローカルファイルを入力するを参照してください。

出力

現在、Qwen-Omni はストリーミング出力のみをサポートしています。

出力モダリティ

出力には、テキストと音声が含まれる場合があります。modalities パラメーターを使用して制御できます。

出力モダリティ

modalities

応答スタイル

テキスト

["text"] (デフォルト)

比較的フォーマル。

テキスト + 音声

["text","audio"]

カジュアルで、ユーザーにさらなるコミュニケーションを促します。

出力モダリティに音声が含まれる場合は、システムメッセージを設定しないでください。
出力音声は Base64 エンコードされているため、デコードが必要です。Base64 エンコードされた音声出力を解析するを参照してください。

音声言語

現在、出力音声は中国語(標準語)と英語のみをサポートしています。

音声ボイス

audio パラメーターは、音声とファイル形式("wav" のみをサポート)を制御します。例:audio={"voice": "Chelsie", "format": "wav"}

voice の有効な値:["Ethan", "Chelsie"]

ボイス名

音声効果

Ethan

Chelsie

始める

前提条件

Qwen-Omni は、OpenAI 互換メソッドのみをサポートしています。最初に API キーを取得 し、API キーを環境変数として設定する必要があります。 OpenAI SDK を使用している場合は、SDK をインストールする必要もあります。 このトピック に従って最新バージョンをインストールすることをお勧めします。そうしないと、リクエストが失敗する可能性があります。

OpenAI Python SDK バージョン 1.52.0 以降、または OpenAI Node.js SDK バージョン 4.68.0 以降が必要です。

テキスト入力

Qwen-Omni は、プレーンテキストを入力として受け入れることができます。現在、ストリーミング出力のみがサポートされています。

OpenAI 互換

import os
from openai import OpenAI

client = OpenAI(
    # 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[{"role": "user", "content": "Who are you"}],
    # 出力データのモダリティを設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています。
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合はエラーが発生します
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [
        { role: "user", content: "Who are you?" }
    ],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});

for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen2.5-omni-7b",
    "messages": [
        {
            "role": "user", 
            "content": "Who are you?"
        }
    ],
    "stream":true,
    "stream_options":{
        "include_usage":true
    },
    "modalities":["text","audio"],
    "audio":{"voice":"Chelsie","format":"wav"}
}'

画像 + テキスト入力

Qwen-Omni は一度に複数の画像を受け入れることができます。入力画像の要件は次のとおりです。

  • 単一画像ファイルのサイズは 10 MB を超えてはなりません。

  • 画像の数は、モデルのテキストと画像の合計トークン制限(つまり、最大入力)によって制限されます。すべての画像の合計トークン数は、モデルの最大入力より少なくなければなりません。

  • 画像の幅と高さは 10 ピクセルより大きくなければなりません。縦横比は 200:1 または 1:200 を超えてはなりません。

サポートされている画像形式について学ぶ

現在、ストリーミング出力のみがサポートされています。

次のサンプルコードは、パブリック画像 URL を使用しています。ローカルファイルを使用するには、Base64 エンコードされたローカルファイルを入力するを参照してください。

OpenAI 互換

import os
from openai import OpenAI

client = OpenAI(
    # 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"
                    },
                },
                {"type": "text", "text": "What scene is depicted in this image?"},
            ],
        },
    ],
    # 出力データのモダリティを設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています。
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合はエラーが発生します
    stream=True,
    stream_options={
        "include_usage": True
    }
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [
        {
            "role": "user",
            "content": [{
                "type": "image_url",
                "image_url": { "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg" },
            },
            { "type": "text", "text": "What scene is depicted in this image?" }]
        }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});

for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen2.5-omni-7b",
    "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "image_url",
          "image_url": {
            "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"
          }
        },
        {
          "type": "text",
          "text": "What scene is depicted in this image?"
        }
      ]
    }
  ],
    "stream":true,
    "stream_options":{
        "include_usage":true
    },
    "modalities":["text","audio"],
    "audio":{"voice":"Chelsie","format":"wav"}
}'

音声 + テキスト入力

Qwen-Omni は、一度に 1 つの音声ファイルのみを受け入れることができ、サイズ制限は 10 MB、時間制限は 3 分です。現在、ストリーミング出力のみがサポートされています。

次のサンプルコードはパブリック音声 URL を使用しています。ローカルファイルを使用するには、Base64 エンコードされたローカルファイルを入力するを参照してください。

OpenAI 互換

import os
from openai import OpenAI

client = OpenAI(
    # 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
                        "format": "wav",
                    },
                },
                {"type": "text", "text": "What is this audio saying"},
            ],
        },
    ],
    # 出力データのモダリティを設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています。
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合はエラーが発生します
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [
        {
            "role": "user",
            "content": [{
                "type": "input_audio",
                "input_audio": { "data": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav", "format": "wav" },
            },
            { "type": "text", "text": "What is this audio saying" }]
        }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});

for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen2.5-omni-7b",
    "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "input_audio",
          "input_audio": {
            "data": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250211/tixcef/cherry.wav",
            "format": "wav"
          }
        },
        {
          "type": "text",
          "text": "What is this audio saying"
        }
      ]
    }
  ],
    "stream":true,
    "stream_options":{
        "include_usage":true
    },
    "modalities":["text","audio"],
    "audio":{"voice":"Chelsie","format":"wav"}
}'

動画 + テキスト入力

Qwen-Omni は、画像シーケンス または 動画ファイル(動画内の音声を理解できます)として動画を受け入れることができます。現在、ストリーミング出力のみがサポートされています。

  • 画像シーケンス

    少なくとも 4 枚の画像、最大 80 枚の画像。

  • 動画ファイル

    動画ファイルは 1 つのみで、サイズ制限は 150 MB、時間制限は 40 秒です。

    動画ファイルの視覚情報と音声情報は別々に課金されます。

次のサンプルコードはパブリック動画 URL を使用しています。ローカルファイルを使用するには、Base64 エンコードされたローカルファイルを入力するを参照してください。

画像シーケンス

OpenAI 互換

import os
from openai import OpenAI

client = OpenAI(
    # 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video",
                    "video": [
                        "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
                        "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
                        "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
                        "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg",
                    ],
                },
                {"type": "text", "text": "Describe the specific process in this video"},
            ],
        }
    ],
    # 出力データのモダリティを設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています。
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合はエラーが発生します
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [{
        role: "user",
        content: [
            {
                type: "video",
                video: [
                    "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
                    "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
                    "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
                    "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg"
                ]
            },
            {
                type: "text",
                text: "Describe the specific process in this video"
            }
        ]
    }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});

for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen2.5-omni-7b",
    "messages": [
        {
            "role": "user",
            "content": [
                {
                    "type": "video",
                    "video": [
                        "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
                        "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
                        "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
                        "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg"
                    ]
                },
                {
                    "type": "text",
                    "text": "Describe the specific process in this video"
                }
            ]
        }
    ],
    "stream": true,
    "stream_options": {
        "include_usage": true
    },
    "modalities": ["text", "audio"],
    "audio": {
        "voice": "Chelsie",
        "format": "wav"
    }
}'

動画ファイル(Qwen-Omni は動画内の音声を理解できます)

OpenAI 互換

import os
from openai import OpenAI

client = OpenAI(
    # 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video_url",
                    "video_url": {
                        "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241115/cqqkru/1.mp4"
                    },
                },
                {"type": "text", "text": "What is the content of the video?"},
            ],
        },
    ],
    # 出力データのモダリティを設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています。
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合はエラーが発生します
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 環境変数が構成されていない場合は、以下の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [
        {
            "role": "user",
            "content": [{
                "type": "video_url",
                "video_url": { "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241115/cqqkru/1.mp4" },
            },
            { "type": "text", "text": "What is the content of the video?" }]
        }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});


for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen2.5-omni-7b",
    "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "video_url",
          "video_url": {
            "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241115/cqqkru/1.mp4"
          }
        },
        {
          "type": "text",
          "text": "What is the content of the video"
        }
      ]
    }
  ],
    "stream":true,
    "stream_options": {
        "include_usage": true
    },
    "modalities":["text","audio"],
    "audio":{"voice":"Chelsie","format":"wav"}
}'

複数ラウンドの会話

Qwen-Omni の複数ラウンド会話機能を使用する場合は、次の点に注意してください。

  • アシスタントメッセージ

    messages 配列に追加されたアシスタントメッセージには、テキストのみを含めることができます。

  • ユーザーメッセージ

    ユーザーメッセージには、テキストと 1 つのタイプのテキスト以外のデータのみを含めることができます。複数ラウンドの会話では、異なるタイプのデータを異なるユーザーメッセージに配置できます。

OpenAI 互換

import os
from openai import OpenAI

client = OpenAI(
    # 環境変数が構成されていない場合は、次の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": "https://dashscope.oss-cn-beijing.aliyuncs.com/audios/welcome.mp3",
                        "format": "mp3",
                    },
                },
                {"type": "text", "text": "What is this audio saying"},
            ],
        },
        {
            "role": "assistant",
            "content": [{"type": "text", "text": "This audio is saying: Welcome to Alibaba Cloud"}],
        },
        {
            "role": "user",
            "content": [{"type": "text", "text": "Can you introduce this company?"}],
        },
    ],
    # 出力データのモダリティを設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています
    modalities=["text"],
    # stream は True に設定する必要があります。そうでない場合はエラーが発生します
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 環境変数が構成されていない場合は、次の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [
        {
            "role": "user",
            "content": [
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": "https://dashscope.oss-cn-beijing.aliyuncs.com/audios/welcome.mp3",
                        "format": "mp3",
                    },
                },
                { "type": "text", "text": "What is this audio saying" },
            ],
        },
        {
            "role": "assistant",
            "content": [{ "type": "text", "text": "This audio is saying: Welcome to Alibaba Cloud" }],
        },
        {
            "role": "user",
            "content": [{ "type": "text", "text": "Can you introduce this company?" }]
        }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text"]
});


for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "model": "qwen2.5-omni-7b",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "input_audio",
          "input_audio": {
            "data": "https://dashscope.oss-cn-beijing.aliyuncs.com/audios/welcome.mp3"
          }
        },
        {
          "type": "text",
          "text": "What is this audio saying"
        }
      ]
    },
    {
      "role": "assistant",
      "content": [
        {
          "type": "text",
          "text": "This audio is saying: Welcome to Alibaba Cloud"
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Can you introduce this company?"
        }
      ]
    }
  ],
  "stream": true,
  "stream_options": {
    "include_usage": true
  },
  "modalities": ["text"]
}'

Base64 エンコードされたオーディオ出力の解析

Qwen-Omni は、Base64 エンコードされたデータをストリームで出力します。モデル生成中に文字列変数を維持し、各チャンクの Base64 エンコードを文字列変数に追加してからデコードできます。または、各チャンクの Base64 エンコードをリアルタイムでデコードして再生することもできます。

# pyaudio のインストール手順:
# APPLE Mac OS X
#   brew install portaudio
#   pip install pyaudio
# Debian/Ubuntu
#   sudo apt-get install python-pyaudio python3-pyaudio
#   or
#   pip install pyaudio
# CentOS
#   sudo yum install -y portaudio portaudio-devel && pip install pyaudio
# Microsoft Windows
#   python -m pip install pyaudio

import os
from openai import OpenAI
import base64
import numpy as np
import soundfile as sf

client = OpenAI(
    # 環境変数が構成されていない場合は、次の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[{"role": "user", "content": "Who are you"}],
    # 出力データのモダリティを設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています。
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合はエラーが発生します
    stream=True,
    stream_options={"include_usage": True},
)

# 方法 1: 生成完了後にデコードする
audio_string = ""
for chunk in completion:
    if chunk.choices:
        if hasattr(chunk.choices[0].delta, "audio"):
            try:
                audio_string += chunk.choices[0].delta.audio["data"]
            except Exception as e:
                print(chunk.choices[0].delta.audio["transcript"])
    else:
        print(chunk.usage)

wav_bytes = base64.b64decode(audio_string)
audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
sf.write("audio_assistant_py.wav", audio_np, samplerate=24000)

# 方法 2: 生成中にデコードする(方法 2 を使用する場合、方法 1 のコードをコメントアウトします)
# # PyAudio を初期化する
# import pyaudio
# import time
# p = pyaudio.PyAudio()
# # オーディオストリームを作成する
# stream = p.open(format=pyaudio.paInt16,
#                 channels=1,
#                 rate=24000,
#                 output=True)

# for chunk in completion:
#     if chunk.choices:
#         if hasattr(chunk.choices[0].delta, "audio"):
#             try:
#                 audio_string = chunk.choices[0].delta.audio["data"]
#                 wav_bytes = base64.b64decode(audio_string)
#                 audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
#                 # オーディオデータを直接再生する
#                 stream.write(audio_np.tobytes())
#             except Exception as e:
#                 print(chunk.choices[0].delta.audio["transcript"])

# time.sleep(0.8)
# # リソースをクリーンアップする
# stream.stop_stream()
# stream.close()
# p.terminate()
// 実行前の準備:
// Windows/Mac/Linux 共通:
// 1. Node.js がインストールされていることを確認します (推奨バージョン >= 14)
// 2. 以下のコマンドを実行して必要な依存関係をインストールします。
//    npm install openai wav
// 
// リアルタイム再生 (方法 2) を使用する場合、以下も必要です。
// Windows:
//    npm install speaker
// Mac:
//    brew install portaudio
//    npm install speaker
// Linux (Ubuntu/Debian):
//    sudo apt-get install libasound2-dev
//    npm install speaker

import OpenAI from "openai";

const openai = new OpenAI(
    {
        // 環境変数が構成されていない場合は、次の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);
const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [
        {
            "role": "user",
            "content": "Who are you?"
        }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});

// 方法 1: 生成完了後にデコードする
// インストールが必要: npm install wav
import { createWriteStream } from 'node:fs';  // node:fs は組み込みの Node.js モジュールなので、インストールは不要です
import { Writer } from 'wav';

async function convertAudio(audioString, audioPath) {
    try {
        // Base64 文字列を Buffer にデコードする
        const wavBuffer = Buffer.from(audioString, 'base64');
        // WAV ファイル書き込みストリームを作成する
        const writer = new Writer({
            sampleRate: 24000,  // サンプルレート
            channels: 1,        // モノラルチャンネル
            bitDepth: 16        // 16 ビット深度
        });
        // 出力ファイルストリームを作成し、パイプ接続を確立する
        const outputStream = createWriteStream(audioPath);
        writer.pipe(outputStream);

        // PCM データを書き込み、書き込みを終了する
        writer.write(wavBuffer);
        writer.end();

        // Promise を使用してファイルの書き込みが完了するのを待つ
        await new Promise((resolve, reject) => {
            outputStream.on('finish', resolve);
            outputStream.on('error', reject);
        });

        // オーディオが確実に完了するように追加の待機時間を追加する
        await new Promise(resolve => setTimeout(resolve, 800));

        console.log(`オーディオファイルは ${audioPath} として正常に保存されました`);
    } catch (error) {
        console.error('処理中にエラーが発生しました:', error);
    }
}

let audioString = "";
for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        if (chunk.choices[0].delta.audio) {
            if (chunk.choices[0].delta.audio["data"]) {
                audioString += chunk.choices[0].delta.audio["data"];
            }
        }
    } else {
        console.log(chunk.usage);
    }
}
// 変換を実行する
convertAudio(audioString, "audio_assistant_mjs.wav");


// 方法 2: 生成中にリアルタイム再生する
// 上記のシステム手順に従って必要なコンポーネントをインストールする必要があります
// import Speaker from 'speaker'; // オーディオ再生ライブラリをインポートする

// // speaker インスタンスを作成する (WAV ファイルパラメータと一致する構成)
// const speaker = new Speaker({
//     sampleRate: 24000,  // サンプルレート
//     channels: 1,        // サウンドチャンネル数
//     bitDepth: 16,       // ビット深度
//     signed: true        // 符号付き PCM
// });
// for await (const chunk of completion) {
//     if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
//         if (chunk.choices[0].delta.audio) {
//             if (chunk.choices[0].delta.audio["data"]) {
//                 const pcmBuffer = Buffer.from(chunk.choices[0].delta.audio.data, 'base64');
//                 // 再生するために speaker に直接書き込む
//                 speaker.write(pcmBuffer);
//             }
//         }
//     } else {
//         console.log(chunk.usage);
//     }
// }
// speaker.on('finish', () => console.log('再生完了'));
// speaker.end(); // 実際の API ストリーム終了条件に基づいて呼び出す

Base64 エンコードされたローカルファイルを入力

画像

eagle.png をローカルに保存したものを例として使用します。

import os
from openai import OpenAI
import base64

client = OpenAI(
    # 環境変数が設定されていない場合は、次の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)


#  Base64 エンコード形式
def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode("utf-8")


base64_image = encode_image("eagle.png")

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": f"data:image/png;base64,{base64_image}"},
                },
                {"type": "text", "text": "What scene is depicted in this image?"},
            ],
        },
    ],
    # 出力データモダリティを設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています。
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合は、エラーが発生します
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";
import { readFileSync } from 'fs';

const openai = new OpenAI(
    {
        // 環境変数が設定されていない場合は、次の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);

const encodeImage = (imagePath) => {
    const imageFile = readFileSync(imagePath);
    return imageFile.toString('base64');
};
const base64Image = encodeImage("eagle.png")

const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [
        {
            "role": "user",
            "content": [{
                "type": "image_url",
                "image_url": { "url": `data:image/png;base64,${base64Image}` },
            },
            { "type": "text", "text": "What scene is depicted in this image?" }]
        }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});

for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}

音声

welcome.mp3 をローカルに保存したものを例として使用します。

import os
from openai import OpenAI
import base64
import numpy as np
import soundfile as sf
import requests

client = OpenAI(
    # 環境変数が設定されていない場合は、次の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます。
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)


def encode_audio(audio_path):
    with open(audio_path, "rb") as audio_file:
        return base64.b64encode(audio_file.read()).decode("utf-8")


base64_audio = encode_audio("welcome.mp3")

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": f"data:;base64,{base64_audio}",
                        "format": "mp3",
                    },
                },
                {"type": "text", "text": "What is this audio saying"},
            ],
        },
    ],
    # 出力データ形式を設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合は、エラーが発生します
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";
import { readFileSync } from 'fs';

const openai = new OpenAI(
    {
        // 環境変数が設定されていない場合は、次の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);

const encodeAudio = (audioPath) => {
    const audioFile = readFileSync(audioPath);
    return audioFile.toString('base64');
};
const base64Audio = encodeAudio("welcome.mp3")

const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [
        {
            "role": "user",
            "content": [{
                "type": "input_audio",
                "input_audio": { "data": `data:;base64,${base64Audio}`, "format": "mp3" },
            },
            { "type": "text", "text": "What is this audio saying" }]
        }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});

for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}

動画

動画ファイル

spring_mountain.mp4 をローカルに保存したものを例として使用します。

import os
from openai import OpenAI
import base64
import numpy as np
import soundfile as sf

client = OpenAI(
    # 環境変数が設定されていない場合は、次の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

#  Base64 エンコード形式
def encode_video(video_path):
    with open(video_path, "rb") as video_file:
        return base64.b64encode(video_file.read()).decode("utf-8")


base64_video = encode_video("spring_mountain.mp4")

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video_url",
                    "video_url": {"url": f"data:;base64,{base64_video}"},
                },
                {"type": "text", "text": "What is she singing"},
            ],
        },
    ],
    # 出力データ形式を設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合は、エラーが発生します。
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";
import { readFileSync } from 'fs';

const openai = new OpenAI(
    {
        // 環境変数が設定されていない場合は、次の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);

const encodeVideo = (videoPath) => {
    const videoFile = readFileSync(videoPath);
    return videoFile.toString('base64');
};
const base64Video = encodeVideo("spring_mountain.mp4")

const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [
        {
            "role": "user",
            "content": [{
                "type": "video_url",
                "video_url": { "url": `data:;base64,${base64Video}` },
            },
            { "type": "text", "text": "What is she singing" }]
        }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});

for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}

画像シーケンス

football1.jpgfootball2.jpgfootball3.jpgfootball4.jpg をローカルに保存したものを例として使用します。

import os
from openai import OpenAI
import base64
import numpy as np
import soundfile as sf

client = OpenAI(
    # 環境変数が設定されていない場合は、次の行を Model Studio API キーを使用して api_key="sk-xxx" に置き換えます
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)


#  Base64 エンコード形式
def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode("utf-8")


base64_image_1 = encode_image("football1.jpg")
base64_image_2 = encode_image("football2.jpg")
base64_image_3 = encode_image("football3.jpg")
base64_image_4 = encode_image("football4.jpg")

completion = client.chat.completions.create(
    model="qwen2.5-omni-7b",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "video",
                    "video": [
                        f"data:image/jpeg;base64,{base64_image_1}",
                        f"data:image/jpeg;base64,{base64_image_2}",
                        f"data:image/jpeg;base64,{base64_image_3}",
                        f"data:image/jpeg;base64,{base64_image_4}",
                    ],
                },
                {"type": "text", "text": "Describe the specific process of this video"},
            ],
        }
    ],
    # 出力データ形式を設定します。現在、["text","audio"]、["text"] の 2 つのタイプをサポートしています
    modalities=["text", "audio"],
    audio={"voice": "Chelsie", "format": "wav"},
    # stream は True に設定する必要があります。そうでない場合は、エラーが発生します
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in completion:
    if chunk.choices:
        print(chunk.choices[0].delta)
    else:
        print(chunk.usage)
import OpenAI from "openai";
import { readFileSync } from 'fs';

const openai = new OpenAI(
    {
        // 環境変数が設定されていない場合は、次の行を Model Studio API キーを使用して apiKey: "sk-xxx" に置き換えます
        apiKey: process.env.DASHSCOPE_API_KEY,
        baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
    }
);

const encodeImage = (imagePath) => {
    const imageFile = readFileSync(imagePath);
    return imageFile.toString('base64');
  };
const base64Image1 = encodeImage("football1.jpg")
const base64Image2 = encodeImage("football2.jpg")
const base64Image3 = encodeImage("football3.jpg")
const base64Image4 = encodeImage("football4.jpg")

const completion = await openai.chat.completions.create({
    model: "qwen2.5-omni-7b",
    messages: [{
        role: "user",
        content: [
            {
                type: "video",
                video: [
                    `data:image/jpeg;base64,${base64Image1}`,
                    `data:image/jpeg;base64,${base64Image2}`,
                    `data:image/jpeg;base64,${base64Image3}`,
                    `data:image/jpeg;base64,${base64Image4}`
                ]
            },
            {
                type: "text",
                text: "Describe the specific process of this video"
            }
        ]
    }],
    stream: true,
    stream_options: {
        include_usage: true
    },
    modalities: ["text", "audio"],
    audio: { voice: "Chelsie", format: "wav" }
});

for await (const chunk of completion) {
    if (Array.isArray(chunk.choices) && chunk.choices.length > 0) {
        console.log(chunk.choices[0].delta);
    } else {
        console.log(chunk.usage);
    }
}

エラーコード

呼び出しが失敗し、エラーメッセージが返された場合は、「エラーメッセージ」をご参照ください。