Non-real-time speech recognition

更新时间:
复制 MD 格式

Non-real-time speech recognition models convert recorded audio into text. They support multilingual recognition, singing recognition, noise rejection, and speaker diarization, which makes them suitable for meeting transcription, call analysis, subtitle generation, and similar scenarios.

Overview

Transcribe recorded audio and video files in batches through asynchronous tasks.

  • Context enhancement improves recognition accuracy through configurable context.

  • Custom hotwords improve the recognition accuracy of proper nouns through a preset word list.

  • Configurable features include speaker diarization, sensitive-word filtering, and sentence-level or word-level timestamps.

  • Asynchronous transcription supports a single audio file of up to 12 hours in duration and up to 2 GB in size.

  • Any sample rate is supported, along with mainstream audio and video formats such as AAC, WAV, and MP3.

For real-time scenarios such as live subtitles, online meetings, and voice assistants, use Real-time speech recognition. For model selection guidance, see Speech-to-text.

Prerequisites

Quick start

Important

In non-real-time speech recognition, Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, Qwen3-ASR-Flash-Filetrans, and Paraformer use asynchronous calls. Set the request header X-DashScope-Async: enable, submit the task, and then poll the query API to retrieve the result. Other models, such as Fun-ASR-Flash and Qwen3-ASR-Flash, use synchronous calls.

If you call a dedicated deployment of the model service and receive the error current user api does not support asynchronous calls, the deployment supports synchronous calls only. Change the request header to X-DashScope-Async: disable and keep the rest of the call unchanged.

Qwen-Audio-3.0-ASR-Flash-Filetrans/Fun-ASR

Because audio and video files can be large, the file transcription API uses asynchronous calls: submit a task, poll the query API for its status, and retrieve the recognition result after the task completes.

cURL

When you call the API with cURL, first submit the task to get a task_id, and then query the task result by using that ID.

Submit a task

The following configuration is for the China (Beijing) region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.

curl -X POST 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/asr/transcription' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-H "X-DashScope-Async: enable" \
-d '{
    "model": "qwen-audio-3.0-asr-flash-filetrans",
    "input": {
        "file_urls": [
            "{YOUR_AUDIO_URL}"
        ]
    },
    "parameters": {
        "channel_id": [0],
        "language_hints": ["zh", "en"]
    }
}'

Get the task result

This query API allows 20 QPS by default and can scale up to 100 QPS. For a higher frequency, or to avoid throttling from polling, configure an asynchronous task callback (see High-concurrency scenarios: use callbacks instead of polling).

The following configuration is for the China (Beijing) region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.

curl -X GET 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/tasks/{task_id}' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json"

Download the recognition result

After the task succeeds, the output.results[].transcription_url returned by the query API points to a publicly downloadable JSON file that contains the complete recognition result. This URL is valid for 24 hours by default, so download and save it promptly.

# Replace {transcription_url} with the transcription_url value returned by the query API
curl -sS '{transcription_url}' -o transcription.json
cat transcription.json | jq .

Python

from http import HTTPStatus
from dashscope.audio.asr import Transcription
from urllib import request
import dashscope
import os
import json

# The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'

# The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
# If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")

task_response = Transcription.async_call(
    model='qwen-audio-3.0-asr-flash-filetrans',
    file_urls=['{YOUR_AUDIO_URL}'],
    language_hints=['zh', 'en']  # language_hints is an optional parameter used to specify the language codes of the audio to be recognized. For the value range, see the API reference documentation.
)

transcription_response = Transcription.wait(task=task_response.output.task_id)

if transcription_response.status_code == HTTPStatus.OK:
    for transcription in transcription_response.output['results']:
        if transcription['subtask_status'] == 'SUCCEEDED':
            url = transcription['transcription_url']
            result = json.loads(request.urlopen(url).read().decode('utf8'))
            print(json.dumps(result, indent=4,
                            ensure_ascii=False))
        else:
            print('transcription failed!')
            print(transcription)
else:
        print('Error: ', transcription_response.output.message)

Java

import com.alibaba.dashscope.audio.asr.transcription.*;
import com.alibaba.dashscope.utils.Constants;
import com.google.gson.*;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";
        // Create the transcription request parameters.
        TranscriptionParam param =
                TranscriptionParam.builder()
                        // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
                        // If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .model("qwen-audio-3.0-asr-flash-filetrans")
                        // language_hints is an optional parameter used to specify the language codes of the audio to be recognized. For the value range, see the API reference documentation.
                        .parameter("language_hints", new String[]{"zh", "en"})
                        .fileUrls(
                                Arrays.asList(
                                        "{YOUR_AUDIO_URL}"))
                        .build();
        try {
            Transcription transcription = new Transcription();
            // Submit the transcription request
            TranscriptionResult result = transcription.asyncCall(param);
            System.out.println("RequestId: " + result.getRequestId());
            // Check whether the task was submitted successfully
            if (result.getTaskId() == null) {
                System.out.println("Error: " + result.getOutput());
                System.exit(1);
            }
            // Block and wait for the task to complete and get the result
            result = transcription.wait(
                    TranscriptionQueryParam.FromTranscriptionParam(param, result.getTaskId()));
            // Get the transcription result
            List<TranscriptionTaskResult> taskResultList = result.getResults();
            if (taskResultList != null && taskResultList.size() > 0) {
                for (TranscriptionTaskResult taskResult : taskResultList) {
                    String transcriptionUrl = taskResult.getTranscriptionUrl();
                    HttpURLConnection connection =
                            (HttpURLConnection) new URL(transcriptionUrl).openConnection();
                    connection.setRequestMethod("GET");
                    connection.connect();
                    BufferedReader reader =
                            new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    Gson gson = new GsonBuilder().setPrettyPrinting().create();
                    JsonElement jsonResult = gson.fromJson(reader, JsonObject.class);
                    System.out.println(gson.toJson(jsonResult));
                }
            }
        } catch (Exception e) {
            System.out.println("error: " + e);
        }
        System.exit(0);
    }
}

The complete recognition result is printed to the console in JSON format. It contains the transcribed text along with each segment's start and end time in the audio or video file, in milliseconds.

  • Recognition result

    {
        "file_url": "{YOUR_AUDIO_URL}",
        "properties": {
            "audio_format": "pcm_s16le",
            "channels": [
                0
            ],
            "original_sampling_rate": 16000,
            "original_duration_in_milliseconds": 3834
        },
        "transcripts": [
            {
                "channel_id": 0,
                "content_duration_in_milliseconds": 2480,
                "text": "Hello World, this is the Alibaba Speech Lab.",
                "sentences": [
                    {
                        "begin_time": 760,
                        "end_time": 3240,
                        "text": "Hello World, this is the Alibaba Speech Lab.",
                        "sentence_id": 1,
                        "words": [
                            {
                                "begin_time": 760,
                                "end_time": 1000,
                                "text": "Hello",
                                "punctuation": ""
                            },
                            {
                                "begin_time": 1000,
                                "end_time": 1120,
                                "text": " World",
                                "punctuation": ","
                            },
                            {
                                "begin_time": 1400,
                                "end_time": 1920,
                                "text": "this is",
                                "punctuation": ""
                            },
                            {
                                "begin_time": 1920,
                                "end_time": 2520,
                                "text": "the Alibaba",
                                "punctuation": ""
                            },
                            {
                                "begin_time": 2520,
                                "end_time": 2840,
                                "text": "Speech",
                                "punctuation": ""
                            },
                            {
                                "begin_time": 2840,
                                "end_time": 3240,
                                "text": "Lab",
                                "punctuation": "."
                            }
                        ]
                    }
                ]
            }
        ]
    }

Qwen-Audio-3.0-ASR-Flash/Fun-ASR-Flash

The Qwen-Audio-3.0-ASR-Flash and Fun-ASR-Flash model series support synchronous calls for audio files shorter than 5 minutes, and can return recognition results in streaming or non-streaming mode.

The following configuration is for the China (Beijing) region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.

curl --location --request POST 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
     --header "Authorization: Bearer $DASHSCOPE_API_KEY" \
     --header "Content-Type: application/json" \
     --header "X-DashScope-SSE: disable" \
     --data '{
    "model": "qwen-audio-3.0-asr-flash",
    "input": {
        "messages": [
            {
                "role": "user",
                "content": [
                    {
                        "type": "input_audio",
                        "input_audio": {
                            "data": "{YOUR_AUDIO_URL}"
                        }
                    }
                ]
            }
        ]
    },
    "parameters": {
        "format": "wav",
        "sample_rate": "16000"
    }
}'
Important

Note: The response structure returned by the Qwen-Audio-3.0-ASR-Flash and Fun-ASR-Flash model series through the DashScope synchronous API (the multimodal-generation endpoint) differs from the standard DashScope multimodal response format. The actual response structure is as follows:

{
  "output": {
    "output": {
      "sentence": {
        "text": "Recognized text content"
      }
    },
    "text": "Hello World, this is the Alibaba Speech Lab."
  },
  "request_id": "..."
}

Here, output.output.sentence.text and the top-level output.text are the recognized-text fields, and there is no choices field. Parse the response accordingly.

Qwen3-ASR-Flash-Filetrans

Qwen3-ASR-Flash-Filetrans is designed for asynchronous transcription of audio files and supports recordings up to 12 hours long. It accepts only public audio file URLs and does not support local file uploads. When the task completes, it returns the entire recognition result at once.

cURL

When you call the API with cURL, first submit the task to get a task_id, and then query the task result by using that ID.

Submit a task

The following configuration is for the China (Beijing) region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.

curl -X POST 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/asr/transcription' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-H "X-DashScope-Async: enable" \
-d '{
    "model": "qwen3-asr-flash-filetrans",
    "input": {
        "file_url": "{YOUR_AUDIO_URL}"
    },
    "parameters": {
        "channel_id":[
            0
        ],
        "enable_itn": false,
        "enable_words": true
    }
}'

Get the task result

This query API allows 20 QPS by default and can scale up to 100 QPS. For a higher frequency, or to avoid throttling from polling, configure an asynchronous task callback (see High-concurrency scenarios: use callbacks instead of polling).

The following configuration is for the China (Beijing) region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.

curl -X GET 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/tasks/{task_id}' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json"

Download the recognition result

After the task succeeds, the output.result.transcription_url returned by the query API points to a publicly downloadable JSON file that contains the complete recognition result. This URL is valid for 24 hours by default, so download and save it promptly.

# Replace {transcription_url} with the transcription_url value returned by the query API
curl -sS '{transcription_url}' -o transcription.json
cat transcription.json | jq .

Full example

Java

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import okhttp3.*;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class Main {
    // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
    private static final String API_URL_SUBMIT = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/asr/transcription";
    // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
    private static final String API_URL_QUERY = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/tasks/";
    private static final Gson gson = new Gson();

    public static void main(String[] args) {
        // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
        // If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: String apiKey = "sk-xxx"
        String apiKey = System.getenv("DASHSCOPE_API_KEY");

        OkHttpClient client = new OkHttpClient();

        // 1. Submit the task
        /*String payloadJson = """
                {
                    "model": "qwen3-asr-flash-filetrans",
                    "input": {
                        "file_url": "{YOUR_AUDIO_URL}"
                    },
                    "parameters": {
                        "channel_id": [0],
                        "enable_itn": false,
                        "language": "zh"
                    }
                }
                """;*/
        String payloadJson = """
                {
                    "model": "qwen3-asr-flash-filetrans",
                    "input": {
                        "file_url": "{YOUR_AUDIO_URL}"
                    },
                    "parameters": {
                        "channel_id": [0],
                        "enable_itn": false,
                        "enable_words": true
                    }
                }
                """;

        RequestBody body = RequestBody.create(payloadJson, MediaType.get("application/json; charset=utf-8"));
        Request submitRequest = new Request.Builder()
                .url(API_URL_SUBMIT)
                .addHeader("Authorization", "Bearer " + apiKey)
                .addHeader("Content-Type", "application/json")
                .addHeader("X-DashScope-Async", "enable")
                .post(body)
                .build();

        String taskId = null;

        try (Response response = client.newCall(submitRequest).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                String respBody = response.body().string();
                ApiResponse apiResp = gson.fromJson(respBody, ApiResponse.class);
                if (apiResp.output != null) {
                    taskId = apiResp.output.taskId;
                    System.out.println("Task submitted, task_id: " + taskId);
                } else {
                    System.out.println("Submission response content: " + respBody);
                    return;
                }
            } else {
                System.out.println("Task submission failed! HTTP code: " + response.code());
                if (response.body() != null) {
                    System.out.println(response.body().string());
                }
                return;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        // 2. Poll the task status
        boolean finished = false;
        while (!finished) {
            try {
                TimeUnit.SECONDS.sleep(2);  // Wait 2 seconds before querying again
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            }

            String queryUrl = API_URL_QUERY + taskId;
            Request queryRequest = new Request.Builder()
                    .url(queryUrl)
                    .addHeader("Authorization", "Bearer " + apiKey)
                    .addHeader("X-DashScope-Async", "enable")
                    .addHeader("Content-Type", "application/json")
                    .get()
                    .build();

            try (Response response = client.newCall(queryRequest).execute()) {
                if (response.body() != null) {
                    String queryResponse = response.body().string();
                    ApiResponse apiResp = gson.fromJson(queryResponse, ApiResponse.class);

                    if (apiResp.output != null && apiResp.output.taskStatus != null) {
                        String status = apiResp.output.taskStatus;
                        System.out.println("Current task status: " + status);
                        if ("SUCCEEDED".equalsIgnoreCase(status)
                                || "FAILED".equalsIgnoreCase(status)
                                || "UNKNOWN".equalsIgnoreCase(status)) {
                            finished = true;
                            System.out.println("Task completed, final result: ");
                            System.out.println(queryResponse);
                        }
                    } else {
                        System.out.println("Query response content: " + queryResponse);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
        }
    }

    static class ApiResponse {
        @SerializedName("request_id")
        String requestId;
        Output output;
    }

    static class Output {
        @SerializedName("task_id")
        String taskId;
        @SerializedName("task_status")
        String taskStatus;
    }
}

Python

import os
import time
import requests
import json

# The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
API_URL_SUBMIT = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/asr/transcription"
# The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
API_URL_QUERY_BASE = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/tasks/"

def main():
    # The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
    # If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: api_key = "sk-xxx"
    api_key = os.getenv("DASHSCOPE_API_KEY")

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
        "X-DashScope-Async": "enable"
    }

    # 1. Submit the task
    payload = {
        "model": "qwen3-asr-flash-filetrans",
        "input": {
            "file_url": "{YOUR_AUDIO_URL}"
        },
        "parameters": {
            "channel_id": [0],
            # "language": "zh",
            "enable_itn": False,
            "enable_words": True
        }
    }

    print("Submitting ASR transcription task...")
    try:
        submit_resp = requests.post(API_URL_SUBMIT, headers=headers, data=json.dumps(payload))
    except requests.RequestException as e:
        print(f"Failed to request task submission: {e}")
        return

    if submit_resp.status_code != 200:
        print(f"Task submission failed! HTTP code: {submit_resp.status_code}")
        print(submit_resp.text)
        return

    resp_data = submit_resp.json()
    output = resp_data.get("output")
    if not output or "task_id" not in output:
        print("Abnormal submission response content:", resp_data)
        return

    task_id = output["task_id"]
    print(f"Task submitted, task_id: {task_id}")

    # 2. Poll the task status
    finished = False
    while not finished:
        time.sleep(2)  # Wait 2 seconds before querying again

        query_url = API_URL_QUERY_BASE + task_id
        try:
            query_resp = requests.get(query_url, headers=headers)
        except requests.RequestException as e:
            print(f"Failed to request task query: {e}")
            return

        if query_resp.status_code != 200:
            print(f"Task query failed! HTTP code: {query_resp.status_code}")
            print(query_resp.text)
            return

        query_data = query_resp.json()
        output = query_data.get("output")
        if output and "task_status" in output:
            status = output["task_status"]
            print(f"Current task status: {status}")

            if status.upper() in ("SUCCEEDED", "FAILED", "UNKNOWN"):
                finished = True
                print("Task completed. The final result is as follows:")
                print(json.dumps(query_data, indent=2, ensure_ascii=False))
        else:
            print("Query response content:", query_data)

if __name__ == "__main__":
    main()

Java SDK

import com.alibaba.dashscope.audio.qwen_asr.*;
import com.alibaba.dashscope.utils.Constants;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";
        QwenTranscriptionParam param =
                QwenTranscriptionParam.builder()
                        // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
                        // If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .model("qwen3-asr-flash-filetrans")
                        .fileUrl("{YOUR_AUDIO_URL}")
                        //.parameter("language", "zh")
                        //.parameter("channel_id", new ArrayList<String>(){{add("0");add("1");}})
                        .parameter("enable_itn", false)
                        .parameter("enable_words", true)
                        .build();
        try {
            QwenTranscription transcription = new QwenTranscription();
            // Submit the task
            QwenTranscriptionResult result = transcription.asyncCall(param);
            System.out.println("create task result: " + result);
            // Check whether the task was submitted successfully
            if (result.getTaskId() == null) {
                System.out.println("Error: " + result.getOutput());
                return;
            }
            // Query the task status
            result = transcription.fetch(QwenTranscriptionQueryParam.FromTranscriptionParam(param, result.getTaskId()));
            System.out.println("task status: " + result);
            // Wait for the task to complete
            result =
                    transcription.wait(
                            QwenTranscriptionQueryParam.FromTranscriptionParam(param, result.getTaskId()));
            System.out.println("task result: " + result);
            // Get the speech recognition result
            QwenTranscriptionTaskResult taskResult = result.getResult();
            if (taskResult != null) {
                // Get the URL of the recognition result
                String transcriptionUrl = taskResult.getTranscriptionUrl();
                // Get the result corresponding to the URL
                HttpURLConnection connection =
                        (HttpURLConnection) new URL(transcriptionUrl).openConnection();
                connection.setRequestMethod("GET");
                connection.connect();
                BufferedReader reader =
                        new BufferedReader(new InputStreamReader(connection.getInputStream()));
                // Format and output the json result
                Gson gson = new GsonBuilder().setPrettyPrinting().create();
                System.out.println(gson.toJson(gson.fromJson(reader, JsonObject.class)));
            }
        } catch (Exception e) {
            System.out.println("error: " + e);
        }
    }
}

Python SDK

import json
import os
import sys
from http import HTTPStatus

import dashscope
from dashscope.audio.qwen_asr import QwenTranscription
from dashscope.api_entities.dashscope_response import TranscriptionResponse

# run the transcription script
if __name__ == '__main__':
    # The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
    # If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: dashscope.api_key = "sk-xxx"
    dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")

    # The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
    dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'
    task_response = QwenTranscription.async_call(
        model='qwen3-asr-flash-filetrans',
        file_url='{YOUR_AUDIO_URL}',
        #language="",
        enable_itn=False,
        enable_words=True
    )
    print(f'task_response: {task_response}')
    print(task_response.output.task_id)
    query_response = QwenTranscription.fetch(task=task_response.output.task_id)
    print(f'query_response: {query_response}')
    task_result = QwenTranscription.wait(task=task_response.output.task_id)
    print(f'task_result: {task_result}')

Qwen3-ASR-Flash

Qwen3-ASR-Flash supports recordings up to 5 minutes long, accepts a public audio file URL or a local file upload as input, and can return recognition results in streaming mode.

Input: audio file URL

Python SDK

import os
import dashscope

# The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'

messages = [
    {"role": "user", "content": [{"audio": "{YOUR_AUDIO_URL}"}]}
]

response = dashscope.MultiModalConversation.call(
    # The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
    # If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: api_key = "sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # If you use a model in the US region, add the "-us" suffix after the model name, for example, qwen3-asr-flash-us
    model="qwen3-asr-flash",
    messages=messages,
    result_format="message",
    asr_options={
        # "language": "zh", # Optional. If you know the language of the audio, you can use this parameter to specify the language to recognize, to improve recognition accuracy
        "enable_itn":False
    }
)
print(response)

Java SDK

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;

public class Main {
    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage userMessage = MultiModalMessage.builder()
                .role(Role.USER.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("audio", "{YOUR_AUDIO_URL}")))
                .build();

        Map<String, Object> asrOptions = new HashMap<>();
        asrOptions.put("enable_itn", false);
        // asrOptions.put("language", "zh"); // Optional. If you know the language of the audio, you can use this parameter to specify the language to recognize, to improve recognition accuracy
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
                // If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                // If you use a model in the US region, add the "-us" suffix after the model name, for example, qwen3-asr-flash-us
                .model("qwen3-asr-flash")
                .message(userMessage)
                .parameter("asr_options", asrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(JsonUtils.toJson(result));
    }
    public static void main(String[] args) {
        try {
            // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
            Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}

cURL

The following configuration is for the China (Beijing) region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.

curl -X POST "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation" \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen3-asr-flash",
    "input": {
        "messages": [
            {
                "content": [
                    {
                        "audio": "{YOUR_AUDIO_URL}"
                    }
                ],
                "role": "user"
            }
        ]
    },
    "parameters": {
        "asr_options": {
            "enable_itn": false
        }
    }
}'

Input: Base64-encoded audio file

You can pass in Base64-encoded data (Data URL) in the format data:<mediatype>;base64,<data>.

  • <mediatype>: the MIME type.

    It varies by audio format, for example:

    • WAV: audio/wav

    • MP3: audio/mpeg

  • <data>: the Base64-encoded string of the audio.

    Base64 encoding increases the file size, so keep the original file small enough that the encoded result still meets the input audio size limit (10 MB).

  • Example: data:audio/wav;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjI5LjEwMAAAAAAAAAAAAAAA//PAxABQ/BXRbMPe4IQAhl9

    Click to view the sample code

    import base64, pathlib
    
    # input.mp3 is the local audio file used for voice cloning. Replace it with the path to your own audio file and make sure it meets the audio requirements.
    file_path = pathlib.Path("{YOUR_AUDIO_FILE}")
    base64_str = base64.b64encode(file_path.read_bytes()).decode()
    data_uri = f"data:audio/mpeg;base64,{base64_str}"
    import java.nio.file.*;
    import java.util.Base64;
    
    public class Main {
        /**
         * filePath is the local audio file used for voice cloning. Replace it with the path to your own audio file and make sure it meets the audio requirements.
         */
        public static String toDataUrl(String filePath) throws Exception {
            byte[] bytes = Files.readAllBytes(Paths.get(filePath));
            String encoded = Base64.getEncoder().encodeToString(bytes);
            return "data:audio/mpeg;base64," + encoded;
        }
    
        // Usage example
        public static void main(String[] args) throws Exception {
            System.out.println(toDataUrl("{YOUR_AUDIO_FILE}"));
        }
    }

Python SDK

import base64
import dashscope
import os
import pathlib

# The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'

# Replace with the actual audio file path
file_path = "{YOUR_AUDIO_FILE}"
# Replace with the actual MIME type of the audio file
audio_mime_type = "audio/mpeg"

file_path_obj = pathlib.Path(file_path)
if not file_path_obj.exists():
    raise FileNotFoundError(f"Audio file does not exist: {file_path}")

base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
data_uri = f"data:{audio_mime_type};base64,{base64_str}"

messages = [
    {"role": "user", "content": [{"audio": data_uri}]}
]
response = dashscope.MultiModalConversation.call(
    # The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
    # If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: api_key = "sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # If you use a model in the US region, add the "-us" suffix after the model name, for example, qwen3-asr-flash-us
    model="qwen3-asr-flash",
    messages=messages,
    result_format="message",
    asr_options={
        # "language": "zh", # Optional. If you know the language of the audio, you can use this parameter to specify the language to recognize, to improve recognition accuracy
        "enable_itn":False
    }
)
print(response)

Java SDK

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;

public class Main {
    // Replace with the actual audio file path
    private static final String AUDIO_FILE = "{YOUR_AUDIO_FILE}";
    // Replace with the actual MIME type of the audio file
    private static final String AUDIO_MIME_TYPE = "audio/mpeg";

    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException, IOException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage userMessage = MultiModalMessage.builder()
                .role(Role.USER.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("audio", toDataUrl())))
                .build();

        Map<String, Object> asrOptions = new HashMap<>();
        asrOptions.put("enable_itn", false);
        // asrOptions.put("language", "zh"); // Optional. If you know the language of the audio, you can use this parameter to specify the language to recognize, to improve recognition accuracy
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
                // If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                // If you use a model in the US region, add the "-us" suffix after the model name, for example, qwen3-asr-flash-us
                .model("qwen3-asr-flash")
                .message(userMessage)
                .parameter("asr_options", asrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(JsonUtils.toJson(result));
    }

    public static void main(String[] args) {
        try {
            // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
            Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException | IOException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }

    // Generate the data URI
    public static String toDataUrl() throws IOException {
        byte[] bytes = Files.readAllBytes(Paths.get(AUDIO_FILE));
        String encoded = Base64.getEncoder().encodeToString(bytes);
        return "data:" + AUDIO_MIME_TYPE + ";base64," + encoded;
    }
}

Input: absolute path of a local audio file

When you process a local audio file with the DashScope SDK, pass in the file path. Refer to the following table to build the path based on your call method and operating system.

System

SDK

File path to pass in

Example

Linux or macOS

Python SDK

file://{absolute path of the file}

file:///home/images/test.png

Java SDK

Windows

Python SDK

file://{absolute path of the file}

file://D:/images/test.png

Java SDK

file:///{absolute path of the file}

file:///D:/images/test.png

Important

Local file calls are capped at 100 QPS and cannot be scaled up, so they are not suitable for production, high-concurrency, or stress-testing scenarios. For higher concurrency, upload the file to OSS and call it through a URL.

Python SDK

import os
import dashscope

# The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'

# Replace ABSOLUTE_PATH/{YOUR_AUDIO_FILE} with the absolute path of your local audio file
audio_file_path = "file://ABSOLUTE_PATH/{YOUR_AUDIO_FILE}"

messages = [
    {"role": "user", "content": [{"audio": audio_file_path}]}
]
response = dashscope.MultiModalConversation.call(
    # The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
    # If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: api_key = "sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # If you use a model in the US region, add the "-us" suffix after the model name, for example, qwen3-asr-flash-us
    model="qwen3-asr-flash",
    messages=messages,
    result_format="message",
    asr_options={
        # "language": "zh", # Optional. If you know the language of the audio, you can use this parameter to specify the language to recognize, to improve recognition accuracy
        "enable_itn":False
    }
)
print(response)

Java SDK

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;

public class Main {
    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        // Replace ABSOLUTE_PATH/{YOUR_AUDIO_FILE} with the absolute path of your local file
        String localFilePath = "file://ABSOLUTE_PATH/{YOUR_AUDIO_FILE}";
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage userMessage = MultiModalMessage.builder()
                .role(Role.USER.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("audio", localFilePath)))
                .build();

        Map<String, Object> asrOptions = new HashMap<>();
        asrOptions.put("enable_itn", false);
        // asrOptions.put("language", "zh"); // Optional. If you know the language of the audio, you can use this parameter to specify the language to recognize, to improve recognition accuracy
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
                // If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                // If you use a model in the US region, add the "-us" suffix after the model name, for example, qwen3-asr-flash-us
                .model("qwen3-asr-flash")
                .message(userMessage)
                .parameter("asr_options", asrOptions)
                .build();
        MultiModalConversationResult result = conv.call(param);
        System.out.println(JsonUtils.toJson(result));
    }
    public static void main(String[] args) {
        try {
            // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
            Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}

Streaming output

The model generates intermediate results step by step, and the final result is assembled from them. A non-streaming call waits for all results to be generated and then returns them at once, whereas a streaming call returns results as they are generated, which significantly reduces the time to first token. Choose the streaming parameter that matches your call method:

  • DashScope Python SDK: set the stream parameter to true.

  • DashScope Java SDK: call the streamCall API.

  • DashScope HTTP: set the X-DashScope-SSE header to enable.

Python SDK

import os
import dashscope

# The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'

messages = [
    {"role": "user", "content": [{"audio": "{YOUR_AUDIO_URL}"}]}
]
response = dashscope.MultiModalConversation.call(
    # The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
    # If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: api_key = "sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # If you use a model in the US region, add the "-us" suffix after the model name, for example, qwen3-asr-flash-us
    model="qwen3-asr-flash",
    messages=messages,
    result_format="message",
    asr_options={
        # "language": "zh", # Optional. If you know the language of the audio, you can use this parameter to specify the language to recognize, to improve recognition accuracy
        "enable_itn":False
    },
    stream=True
)

for response in response:
    try:
        print(response["output"]["choices"][0]["message"].content[0]["text"])
    except:
        pass

Java SDK

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.utils.Constants;
import io.reactivex.Flowable;

public class Main {
    public static void simpleMultiModalConversationCall()
            throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage userMessage = MultiModalMessage.builder()
                .role(Role.USER.getValue())
                .content(Arrays.asList(
                        Collections.singletonMap("audio", "{YOUR_AUDIO_URL}")))
                .build();

        Map<String, Object> asrOptions = new HashMap<>();
        asrOptions.put("enable_itn", false);
        // asrOptions.put("language", "zh"); // Optional. If you know the language of the audio, you can use this parameter to specify the language to recognize, to improve recognition accuracy
        MultiModalConversationParam param = MultiModalConversationParam.builder()
                // The API Key differs between the Singapore/US regions and the Beijing region. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
                // If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                // If you use a model in the US region, add the "-us" suffix after the model name, for example, qwen3-asr-flash-us
                .model("qwen3-asr-flash")
                .message(userMessage)
                .parameter("asr_options", asrOptions)
                .build();
        Flowable<MultiModalConversationResult> resultFlowable = conv.streamCall(param);
        resultFlowable.blockingForEach(item -> {
            try {
                System.out.println(item.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
            } catch (Exception e){
                System.exit(0);
            }
        });
    }

    public static void main(String[] args) {
        try {
            // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
            Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";
            simpleMultiModalConversationCall();
        } catch (ApiException | NoApiKeyException | UploadFileException e) {
            System.out.println(e.getMessage());
        }
        System.exit(0);
    }
}

cURL

The following configuration is for the China (Beijing) region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.

curl -X POST "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation" \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-H "X-DashScope-SSE: enable" \
-d '{
    "model": "qwen3-asr-flash",
    "input": {
        "messages": [
            {
                "content": [
                    {
                        "audio": "{YOUR_AUDIO_URL}"
                    }
                ],
                "role": "user"
            }
        ]
    },
    "parameters": {
        "incremental_output": true,
        "asr_options": {
            "enable_itn": false
        }
    }
}'

Paraformer

The Paraformer sample code is similar to the asynchronous call for Fun-ASR. Replace the model value with a Paraformer model name.

Advanced features

Use the OpenAI-compatible API

Important

The US region does not support the OpenAI-compatible mode.

Only the Qwen3-ASR-Flash series models support calls through the OpenAI-compatible mode. This mode accepts only publicly accessible audio file URLs. It does not accept the absolute path of a local audio file.

Use OpenAI Python SDK 1.52.0 or later, or Node.js SDK 4.68.0 or later. To install or upgrade the SDK, run:

# Python
pip install -U "openai>=1.52.0"

# Node.js
npm install openai@^4.68.0

asr_options is not a standard OpenAI parameter. With the OpenAI Python SDK, pass it through extra_body. With the Node.js OpenAI SDK, pass asr_options directly as a top-level parameter in the request body.

Input: audio file URL

Python SDK

from openai import OpenAI
import os

try:
    client = OpenAI(
        # The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
        # If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: api_key = "sk-xxx",
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        # The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
        base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
    )
    

    stream_enabled = False  # Whether to enable streaming output
    completion = client.chat.completions.create(
        model="qwen3-asr-flash",
        messages=[
            {
                "content": [
                    {
                        "type": "input_audio",
                        "input_audio": {
                            "data": "{YOUR_AUDIO_URL}"
                        }
                    }
                ],
                "role": "user"
            }
        ],
        stream=stream_enabled,
        # When stream is set to False, the stream_options parameter cannot be set
        # stream_options={"include_usage": True},
        extra_body={
            "asr_options": {
                # "language": "zh",
                "enable_itn": False
            }
        }
    )
    if stream_enabled:
        full_content = ""
        print("The streaming output is:")
        for chunk in completion:
            # If stream_options.include_usage is True, the choices field of the last chunk is an empty list and needs to be skipped (you can get the Token usage via chunk.usage)
            print(chunk)
            if chunk.choices and chunk.choices[0].delta.content:
                full_content += chunk.choices[0].delta.content
        print(f"The complete content is: {full_content}")
    else:
        print(f"The non-streaming output is: {completion.choices[0].message.content}")
except Exception as e:
    print(f"Error message: {e}")

Node.js SDK

// Preparations before running:
// Common to Windows/Mac/Linux:
// 1. Make sure Node.js is installed (version >= 14 recommended)
// 2. Run the following command to install the required dependencies: npm install openai

import OpenAI from "openai";

const client = new OpenAI({
  // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
  // If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: apiKey: "sk-xxx",
  apiKey: process.env.DASHSCOPE_API_KEY,
  // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
  baseURL: "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1", 
});

async function main() {
  try {
    const streamEnabled = false; // Whether to enable streaming output
    const completion = await client.chat.completions.create({
      model: "qwen3-asr-flash",
      messages: [
        {
          role: "user",
          content: [
            {
              type: "input_audio",
              input_audio: {
                data: "{YOUR_AUDIO_URL}"
              }
            }
          ]
        }
      ],
      stream: streamEnabled,
      // When stream is set to False, the stream_options parameter cannot be set
      // stream_options: {
      //   "include_usage": true
      // },
      asr_options: {
        // language: "zh",
        enable_itn: false
      }
    });

    if (streamEnabled) {
      let fullContent = "";
      console.log("The streaming output is:");
      for await (const chunk of completion) {
        console.log(JSON.stringify(chunk));
        if (chunk.choices && chunk.choices.length > 0) {
          const delta = chunk.choices[0].delta;
          if (delta && delta.content) {
            fullContent += delta.content;
          }
        }
      }
      console.log(`The complete content is: ${fullContent}`);
    } else {
      console.log(`The non-streaming output is: ${completion.choices[0].message.content}`);
    }
  } catch (err) {
    console.error(`Error message: ${err}`);
  }
}

main();

cURL

The following configuration is for the China (Beijing) region. Replace {WorkspaceId} with your actual Workspace ID. The configuration differs by region.

curl -X POST 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1/chat/completions' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "qwen3-asr-flash",
    "messages": [
        {
            "content": [
                {
                    "type": "input_audio",
                    "input_audio": {
                        "data": "{YOUR_AUDIO_URL}"
                    }
                }
            ],
            "role": "user"
        }
    ],
    "stream":false,
    "asr_options": {
        "enable_itn": false
    }
}'

Input: Base64-encoded audio file

Pass Base64-encoded data as a Data URL in the format data:<mediatype>;base64,<data>.

  • <mediatype>: the MIME type.

    The MIME type varies by audio format. For example:

    • WAV: audio/wav

    • MP3: audio/mpeg

  • <data>: the Base64-encoded string of the audio.

    Base64 encoding increases the data size. Keep the source file small enough that the encoded result still meets the input audio size limit (10 MB).

  • Example: data:audio/wav;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjI5LjEwMAAAAAAAAAAAAAAA//PAxABQ/BXRbMPe4IQAhl9

    Click to view sample code

    import base64, pathlib
    
    # input.mp3 is the local audio file used for voice cloning. Replace it with the path to your own audio file and make sure it meets the audio requirements.
    file_path = pathlib.Path("{YOUR_AUDIO_FILE}")
    base64_str = base64.b64encode(file_path.read_bytes()).decode()
    data_uri = f"data:audio/mpeg;base64,{base64_str}"
    import java.nio.file.*;
    import java.util.Base64;
    
    public class Main {
        /**
         * filePath is the local audio file used for voice cloning. Replace it with the path to your own audio file and make sure it meets the audio requirements.
         */
        public static String toDataUrl(String filePath) throws Exception {
            byte[] bytes = Files.readAllBytes(Paths.get(filePath));
            String encoded = Base64.getEncoder().encodeToString(bytes);
            return "data:audio/mpeg;base64," + encoded;
        }
    
        // Usage example
        public static void main(String[] args) throws Exception {
            System.out.println(toDataUrl("{YOUR_AUDIO_FILE}"));
        }
    }

Python SDK

import base64
from openai import OpenAI
import os
import pathlib

try:
    # Replace with the actual audio file path
    file_path = "{YOUR_AUDIO_FILE}"
    # Replace with the actual MIME type of the audio file
    audio_mime_type = "audio/mpeg"

    file_path_obj = pathlib.Path(file_path)
    if not file_path_obj.exists():
        raise FileNotFoundError(f"Audio file does not exist: {file_path}")

    base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
    data_uri = f"data:{audio_mime_type};base64,{base64_str}"

    client = OpenAI(
        # The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
        # If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: api_key = "sk-xxx",
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        # The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
        base_url="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
    )
    

    stream_enabled = False  # Whether to enable streaming output
    completion = client.chat.completions.create(
        model="qwen3-asr-flash",
        messages=[
            {
                "content": [
                    {
                        "type": "input_audio",
                        "input_audio": {
                            "data": data_uri
                        }
                    }
                ],
                "role": "user"
            }
        ],
        stream=stream_enabled,
        # When stream is set to False, the stream_options parameter cannot be set
        # stream_options={"include_usage": True},
        extra_body={
            "asr_options": {
                # "language": "zh",
                "enable_itn": False
            }
        }
    )
    if stream_enabled:
        full_content = ""
        print("The streaming output is:")
        for chunk in completion:
            # If stream_options.include_usage is True, the choices field of the last chunk is an empty list and needs to be skipped (you can get the Token usage via chunk.usage)
            print(chunk)
            if chunk.choices and chunk.choices[0].delta.content:
                full_content += chunk.choices[0].delta.content
        print(f"The complete content is: {full_content}")
    else:
        print(f"The non-streaming output is: {completion.choices[0].message.content}")
except Exception as e:
    print(f"Error message: {e}")

Node.js SDK

// Preparations before running:
// Common to Windows/Mac/Linux:
// 1. Make sure Node.js is installed (version >= 14 recommended)
// 2. Run the following command to install the required dependencies: npm install openai

import OpenAI from "openai";
import { readFileSync } from 'fs';

const client = new OpenAI({
  // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://help.aliyun.com/zh/model-studio/get-api-key
  // If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio API Key: apiKey: "sk-xxx",
  apiKey: process.env.DASHSCOPE_API_KEY,
  // The following is the configuration for the China (Beijing) region. When calling, replace "{WorkspaceId}" with your actual workspace ID. The configuration differs by region.
  baseURL: "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
});

const encodeAudioFile = (audioFilePath) => {
    const audioFile = readFileSync(audioFilePath);
    return audioFile.toString('base64');
};

// Replace with the actual audio file path
const dataUri = `data:audio/mpeg;base64,${encodeAudioFile("{YOUR_AUDIO_FILE}")}`;

async function main() {
  try {
    const streamEnabled = false; // Whether to enable streaming output
    const completion = await client.chat.completions.create({
      model: "qwen3-asr-flash",
      messages: [
        {
          role: "user",
          content: [
            {
              type: "input_audio",
              input_audio: {
                data: dataUri
              }
            }
          ]
        }
      ],
      stream: streamEnabled,
      // When stream is set to False, the stream_options parameter cannot be set
      // stream_options: {
      //   "include_usage": true
      // },
      asr_options: {
        // language: "zh",
        enable_itn: false
      }
    });

    if (streamEnabled) {
      let fullContent = "";
      console.log("The streaming output is:");
      for await (const chunk of completion) {
        console.log(JSON.stringify(chunk));
        if (chunk.choices && chunk.choices.length > 0) {
          const delta = chunk.choices[0].delta;
          if (delta && delta.content) {
            fullContent += delta.content;
          }
        }
      }
      console.log(`The complete content is: ${fullContent}`);
    } else {
      console.log(`The non-streaming output is: ${completion.choices[0].message.content}`);
    }
  } catch (err) {
    console.error(`Error message: ${err}`);
  }
}

main();

Process long audio files

Non-real-time speech recognition supports asynchronous transcription of long audio files. This suits scenarios such as meeting minutes, interview transcripts, and call playback.

Limitations:

  • Qwen-Audio-3.0-ASR-Flash-Filetrans/Fun-ASR / Qwen3-ASR-Flash-Filetrans / Paraformer: a single audio file can be up to 2 GB in size and 12 hours in duration.

  • Qwen-Audio-3.0-ASR-Flash/Fun-ASR-Flash/Qwen3-ASR-Flash: a single audio file can be up to 10 MB in size and 5 minutes in duration. For longer audio, use Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, or Qwen3-ASR-Flash-Filetrans.

  • When speaker diarization is enabled: keep the audio duration within 2 hours. Longer audio may cause recognition failures or timeouts. For more information, see Speaker diarization.

Call flow: long audio transcription uses an asynchronous task model with three steps:

  1. Submit the transcription task and get a task_id.

  2. Poll the query API for the task status, or use the SDK's wait method to block until the task completes.

  3. After the task completes, download the recognition result JSON from the returned URL.

For sample code, see the Quick start code in Non-real-time speech recognition.

Streaming output

Qwen-Audio-3.0-ASR-Flash/Fun-ASR-Flash/Qwen3-ASR-Flash support streaming output: they return intermediate results as recognition proceeds. This suits scenarios that need real-time progress feedback.

Asynchronous transcription models such as Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, Qwen3-ASR-Flash-Filetrans, and Paraformer do not support streaming output. Get the final result by polling the task (for more information, see Process long audio files).

How to enable:

  • DashScope Python SDK: set the stream parameter to True.

  • DashScope Java SDK: call the streamCall API.

  • DashScope HTTP: set the X-DashScope-SSE header to enable.

  • OpenAI-compatible SDK: set the stream parameter to True.

For streaming output sample code, see the Non-real-time speech recognition section for Qwen3-ASR-Flash in the Quick start.

Improve accuracy with hotwords

Hotwords improve recognition accuracy for domain-specific proper nouns such as names, place names, and product names. For details on how to create and use hotwords, see Improve recognition accuracy.

Different SDKs use different naming conventions for these parameters, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference for each SDK.

Improve accuracy with context enhancement

Context enhancement passes the conversation history to the ASR model, which significantly improves transcription accuracy for proper nouns. For details on how to use this feature and for example results, see Context enhancement.

Speaker diarization

Speaker diarization automatically identifies different speakers in the audio and labels each sentence in the transcription result with a speaker tag. This suits scenarios such as multi-party meetings and interview recordings.

Supported models: the Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, and Paraformer series models.

How to enable: set the diarization_enabled parameter to true in the API request. In the result, each sentence includes a speaker_id field that identifies the speaker.

Example return structure (excerpt):

{
  "transcripts": [
    {
      "sentences": [
        { "begin_time": 100, "end_time": 3820, "text": "Hello, let's discuss the project progress today.", "speaker_id": 0 },
        { "begin_time": 3820, "end_time": 6500, "text": "Sure, let me give a quick report first.", "speaker_id": 1 }
      ]
    }
  ]
}

Different SDKs use different naming conventions for these fields, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference for each SDK.

Important

When speaker diarization is enabled, keep the audio duration within 2 hours. Longer audio may cause recognition failures or timeouts. For the audio length limits when diarization is disabled, see Process long audio files. Speaker diarization supports mono audio only.

For the full field definitions, see the API reference.

Sensitive word filtering

Sensitive word filtering replaces or removes sensitive words in the recognition result. This suits scenarios such as customer service quality inspection, content compliance, and subtitle moderation.

Supported models: the Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, and Paraformer series models.

Default behavior: when the special_word_filter parameter is not passed, the system uses the built-in Model Studio sensitive word list. Matched words are replaced with an equal-length string of *.

Custom configuration: special_word_filter is a JSON object with three subfields:

  • filter_with_signed.word_list: a string array of sensitive words to replace with an equal-length string of *. For example, with ["test"], "Please help me test this" becomes "Please help me **** this".

  • filter_with_empty.word_list: a string array of sensitive words to remove entirely from the result. For example, with ["start"], "Is the game about to start now" becomes "Is the game about to now".

  • system_reserved_filter: a boolean value that defaults to true. It controls whether to also apply the system's built-in sensitive word list, which takes effect together with your custom list.

Configuration example:

{
  "special_word_filter": {
    "filter_with_signed": {
      "word_list": ["test"]
    },
    "filter_with_empty": {
      "word_list": ["start", "happen"]
    },
    "system_reserved_filter": true
  }
}

Different SDKs use different naming conventions for these parameters, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference.

Emotion recognition

The Qwen3-ASR-Flash-Filetrans and Qwen3-ASR-Flash series models have emotion recognition permanently enabled, with no additional configuration required. The result includes an emotion tag for the speaker, chosen from seven fine-grained emotions: surprised, neutral, happy, sad, disgusted, angry, and fearful.

Field paths (vary by API):

  • OpenAI-compatible API (Qwen3-ASR-Flash real-time transcription): nested in choices[].delta.annotations[].emotion (streaming output) or choices[].message.annotations[].emotion (non-streaming).

  • DashScope synchronous API (Qwen3-ASR-Flash): nested in output.choices[].message.annotations[].emotion.

  • DashScope asynchronous task API (Qwen3-ASR-Flash-Filetrans recording file transcription): nested in transcripts[].sentences[].emotion, alongside the timestamp, speaker, and other fields in each sentence object.

Example return structure (excerpt from the DashScope asynchronous task API):

{
  "transcripts": [{
    "sentences": [{
      "begin_time": 0,
      "end_time": 1440,
      "text": "Welcome to Alibaba Cloud.",
      "emotion": "neutral",
      "language": "en"
    }]
  }]
}

Different SDKs use different naming conventions for these fields, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference.

Important

The Qwen-Audio-3.0-ASR-Flash-Filetrans, Qwen-Audio-3.0-ASR-Flash, Fun-ASR-Flash, Fun-ASR, and Paraformer non-real-time models do not support emotion recognition. To use emotion recognition in real-time recognition, see the corresponding section in Real-time speech recognition.

Get timestamps

Non-real-time speech recognition can output timestamps in the transcription result, which helps with subtitle generation, keyword highlighting, and audio/video editing. Qwen-Audio-3.0-ASR-Flash-Filetrans, Qwen-Audio-3.0-ASR-Flash, Fun-ASR, Fun-ASR-Flash, Qwen3-ASR-Flash-Filetrans, and Paraformer all support timestamps, but the default behavior and control method differ by model:

  • Qwen-Audio-3.0-ASR-Flash-Filetrans/Qwen-Audio-3.0-ASR-Flash/Fun-ASR/Fun-ASR-Flash/Paraformer: timestamps are permanently enabled and cannot be turned off.

  • Qwen3-ASR-Flash-Filetrans: only the DashScope asynchronous call supports timestamps, and timestamps are permanently enabled. Use the enable_words request parameter to control the timestamp level: set it to false (default) to return sentence-level timestamps, or true to return word-level timestamps. Word-level timestamps support only the following languages: Chinese, English, Japanese, Korean, German, French, Spanish, Italian, Portuguese, and Russian. Accuracy is not guaranteed for other languages.

Important

When you call Qwen3-ASR-Flash through the OpenAI-compatible API, the output form is chat.completion, which does not return timestamp fields. For timestamps, use Qwen3-ASR-Flash-Filetrans (the asynchronous task API).

Timestamps are in milliseconds and are returned at two levels:

  • Sentence level: sentences[].begin_time and sentences[].end_time mark the start and end time of each sentence in the audio.

  • Word level: the sentences[].words[] array, where each element contains begin_time, end_time, and text (the text of that word).

Example return structure (excerpt from the DashScope asynchronous task API):

{
  "transcripts": [{
    "sentences": [{
      "begin_time": 100,
      "end_time": 3820,
      "text": "Hello, let's discuss the project progress today.",
      "words": [
        { "begin_time": 100, "end_time": 596, "text": "Hello," },
        { "begin_time": 596, "end_time": 844, "text": "let's" }
      ]
    }]
  }]
}
Important

The in-audio timestamp is a millisecond integer (such as 100). Do not confuse it with the task-level end_time (the task completion time, a string date such as "2024-09-12 15:11:40.903"). These are different fields.

Different SDKs use different naming conventions for these fields, such as dictionary keys, object properties, or methods. For the full field mapping, see the API reference.

Apply in production

When you apply non-real-time speech recognition in production, the following best practices improve recognition quality and system stability.

High-concurrency scenarios: use callbacks instead of polling

For asynchronous transcription tasks (Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, Qwen3-ASR-Flash-Filetrans, and Paraformer), you submit the task through POST /api/v1/services/audio/asr/transcription and then usually get the result by periodically calling the query API GET /api/v1/tasks/{task_id}. This query API defaults to 20 QPS and scales up to 100 QPS. In high-concurrency batch scenarios, frequent polling easily triggers throttling.

Configure callback notifications through EventBridge. When a task completes, Model Studio automatically pushes a dashscope:System:AsyncTaskFinish event to your configured target (an HTTP/HTTPS endpoint or a RocketMQ topic). After the consumer receives the event, it no longer needs to call the query API, which avoids the throttling risk of frequent polling. For more information, see Configure EventBridge callback notifications.

Supported models

  • Supported: Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, Qwen3-ASR-Flash-Filetrans, and Paraformer (all asynchronous transcription tasks).

  • Not supported: Qwen3-ASR-Flash (synchronous or streaming calls, which are not asynchronous tasks).

Callback message content

For all three models, the callback message body has data.contain_result set to true, and data.output_result directly carries transcription_url. After the consumer receives the callback, it can get the recognition result without calling GET /api/v1/tasks/{task_id} again. However, the result field path and structure differ across the three models. See the following table.

Note

When you write the consumer, choose the correct path for the model you use. Do not hardcode a single path. In failure scenarios, data.output_result.output no longer contains results/result; instead it contains code and message fields. Check data.task_status first, then read the result.

Model

Submission parameter

Result field path (based on the callback body)

usage field

Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR

input.file_urls (array; only 1 URL per call)

data.output_result.output.results[ ].transcription_url (array, one entry per file, with subtask_status; also includes task_metrics)

duration

Paraformer

input.file_urls (array; only 1 URL per call)

Same as Qwen-Audio-3.0-ASR-Flash-Filetrans/Fun-ASR: data.output_result.output.results[ ].transcription_url

duration

Qwen3-ASR-Flash-Filetrans

input.file_url (single object; only 1 URL per call)

data.output_result.output.result.transcription_url (single object, without results[ ] / task_metrics)

seconds

Usage notes

Security (HTTP/HTTPS delivery): in production, verify the X-Eventbridge-Signature* header fields in the callback request before you consume it. Otherwise, any external IP can forge an AsyncTaskFinish event and inject fake recognition results. Also set a receive timeout of at least 5 seconds on the receiver. The RocketMQ delivery method has no message-level signature; its security is guaranteed by the RocketMQ authentication mechanism.

Delivery latency: from task completion (end_time) to when the delivery target (an HTTP/HTTPS endpoint or a RocketMQ topic) receives the message, the delay is typically about 1 to 90 seconds. The exact latency depends on the real-time load of EventBridge.

Idempotency: the same event may be delivered multiple times due to retries. Implement idempotent processing on the consumer, using the CloudEvents data.id or data.task_id as the deduplication key.

Production recommendations

  • File hosting: upload audio files to Alibaba Cloud OSS and call the API by URL. Avoid local file uploads (local file calls are capped at 100 QPS and cannot be scaled up).

  • Asynchronous polling: long audio transcription uses an asynchronous model. Set a reasonable polling interval (such as 2 to 5 seconds) to avoid frequent queries that consume your quota. To exceed the 20 to 100 QPS query limit, switch to event callback notifications. For more information, see High-concurrency scenarios: use callbacks instead of polling.

  • Error handling: implement a robust retry mechanism. For network timeouts or temporary server-side errors (5xx), retry with an exponential backoff strategy.

  • Noise reduction: for noisy audio, preprocess it with a tool such as FFmpeg before you submit it for recognition.

  • Model selection: choose the right model based on audio duration. For short audio within 5 minutes, use Qwen3-ASR-Flash. For long audio over 5 minutes, use Qwen-Audio-3.0-ASR-Flash-Filetrans, Fun-ASR, or Qwen3-ASR-Flash-Filetrans.

Supported models and regions

China (Beijing)

To call the following models, use an API Key for the Beijing region:

  • Qwen-Audio-3.0-ASR-Flash-Filetrans: qwen-audio-3.0-asr-flash-filetrans

  • Qwen-Audio-3.0-ASR-Flash: qwen-audio-3.0-asr-flash

  • Fun-ASR: fun-asr (stable version, currently equivalent to fun-asr-2025-11-07), fun-asr-2025-11-07 (snapshot version), fun-asr-2025-08-25 (snapshot version), fun-asr-mtl (stable version, currently equivalent to fun-asr-mtl-2025-08-25), fun-asr-mtl-2025-08-25 (snapshot version)

  • Fun-ASR-Flash: fun-asr-flash-2026-06-15

  • Qwen3-ASR-Flash-Filetrans: qwen3-asr-flash-filetrans (stable version, currently equivalent to qwen3-asr-flash-filetrans-2025-11-17), qwen3-asr-flash-filetrans-2025-11-17 (snapshot version)

  • Qwen3-ASR-Flash: qwen3-asr-flash (stable version, currently equivalent to qwen3-asr-flash-2025-09-08), qwen3-asr-flash-2026-02-10 (latest snapshot version), qwen3-asr-flash-2025-09-08 (snapshot version)

  • Paraformer: paraformer-v2, paraformer-8k-v2, paraformer-v1, paraformer-8k-v1, paraformer-mtl-v1

Singapore

To call the following models, use an API Key for the Singapore region:

  • Qwen-Audio-3.0-ASR-Flash-Filetrans: qwen-audio-3.0-asr-flash-filetrans

  • Qwen-Audio-3.0-ASR-Flash: qwen-audio-3.0-asr-flash

  • Fun-ASR: fun-asr (stable version, currently equivalent to fun-asr-2025-11-07), fun-asr-2025-11-07 (snapshot version), fun-asr-2025-08-25 (snapshot version), fun-asr-mtl (stable version, currently equivalent to fun-asr-mtl-2025-08-25), fun-asr-mtl-2025-08-25 (snapshot version)

  • Fun-ASR-Flash: fun-asr-flash-2026-06-15

  • Qwen3-ASR-Flash-Filetrans: qwen3-asr-flash-filetrans (stable version, currently equivalent to qwen3-asr-flash-filetrans-2025-11-17), qwen3-asr-flash-filetrans-2025-11-17 (snapshot version)

  • Qwen3-ASR-Flash: qwen3-asr-flash (stable version, currently equivalent to qwen3-asr-flash-2025-09-08), qwen3-asr-flash-2026-02-10 (latest snapshot version), qwen3-asr-flash-2025-09-08 (snapshot version)

US (Virginia)

To call the following models, use an API Key for the US region:

Qwen3-ASR-Flash: qwen3-asr-flash-us (stable version, currently equivalent to qwen3-asr-flash-2025-09-08-us), qwen3-asr-flash-2025-09-08-us (snapshot version)

API reference

FAQ

Q: How do I provide a publicly accessible audio URL to the API?

Use Alibaba Cloud Object Storage Service (OSS). OSS provides highly available and reliable storage, and lets you generate a public access URL.

Verify that the generated URL is accessible over the public network: open the URL in a browser or with the curl command to confirm that the audio file downloads or plays (HTTP status code 200).

Q: How do I check whether the audio format meets the requirements?

Use the open-source tool ffprobe to quickly get detailed audio information:

# Query the container format (format_name), codec (codec_name), sample rate (sample_rate), and number of channels (channels) of the audio
ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 your_audio_file.mp3

Q: How do I process audio to meet the model requirements?

Use the open-source tool FFmpeg to trim or convert the audio:

  • Trim audio: extract a clip from a long audio file

    # -i: input file
    # -ss 00:01:30: set the trim start time (start at 1 minute 30 seconds)
    # -t 00:02:00: set the trim duration (trim 2 minutes)
    # -c copy: copy the audio stream directly without re-encoding, which is fast
    # output_clip.wav: output file
    ffmpeg -i long_audio.wav -ss 00:01:30 -t 00:02:00 -c copy output_clip.wav
  • Convert the format

    For example, convert any audio to a 16 kHz, 16-bit, mono WAV file:

    # -i: input file
    # -ac 1: set the number of channels to 1 (mono)
    # -ar 16000: set the sample rate to 16000 Hz (16 kHz)
    # -sample_fmt s16: set the sample format to 16-bit signed integer PCM
    # output.wav: output file
    ffmpeg -i input.mp3 -ac 1 -ar 16000 -sample_fmt s16 output.wav

Q: How do I improve recognition accuracy?

The following factors affect recognition accuracy. Check each one and optimize accordingly.

Main factors:

  1. Audio quality: the quality of the recording device, the sample rate, and environmental noise directly affect audio clarity. High-quality audio input is the foundation of accurate recognition.

  2. Speaker characteristics: pitch, speech rate, accent, and dialect differences (especially rare dialects or strong accents) increase recognition difficulty.

  3. Language and vocabulary: mixed languages, technical terms, or slang increase recognition difficulty. Configure hotwords to improve accuracy for domain-specific terms.

Optimization methods:

  1. Improve audio quality: use a high-performance microphone, record at the recommended sample rate, and minimize environmental noise and echo.

  2. Adapt to the speaker: for audio with strong accents or noticeable dialects, choose a model that supports the corresponding dialect.

  3. Configure hotwords: set hotwords for technical terms, proper nouns, and similar words.

Model application listing and filing

For more information, see Application compliance filing.