Skip to content

to-text-Real-time speech recognition - Fun-ASR/Paraformer

The real-time speech recognition service converts an audio stream into punctuated text for a "text as you speak" experience. You can transcribe audio from a microphone, a meeting recording, or a local audio file. Common use cases include meeting transcription, live captions, voice chat, and intelligent customer service.

Core features

  • Recognizes speech in real time across multiple languages, including Chinese, English, and various dialects.

  • Supports hotword customization to improve recognition accuracy for specific terms.

  • Generates structured recognition results with timestamps.

  • Adapts to various recording environments with flexible sample rates and multiple audio formats.

  • Offers optional VAD (voice activity detection) to filter out silence and process long audio more efficiently.

  • Delivers low-latency, stable performance via SDK and WebSocket integration.

Applicability

Supported models:

International

In the international deployment mode, inference computing resources are dynamically scheduled globally (excluding the chinese mainland). Static data is stored in the region you select. Supported region: Singapore.

To call the following models, use an API key from Singapore:

  • Fun-ASR: fun-asr-realtime (stable, currently equivalent to fun-asr-realtime-2025-11-07), fun-asr-realtime-2025-11-07 (snapshot)

Chinese mainland

In the chinese mainland deployment mode, inference computing resources are restricted to the chinese mainland. Static data is stored in the region you select. Supported region: China (Beijing).

To call the following models, use an API key from China (Beijing):

  • Fun-ASR:

    • fun-asr-flash-8k-realtime (stable, currently equivalent to fun-asr-flash-8k-realtime-2026-01-28), fun-asr-flash-8k-realtime-2026-01-28
  • Paraformer: paraformer-realtime-v2, paraformer-realtime-v1, paraformer-realtime-8k-v2, paraformer-realtime-8k-v1

For more information, refer to the model list.

Model selection

ScenarioRecommended modelReason
Mandarin Chinese Recognition (meetings/live streaming)fun-asr-realtime, fun-asr-realtime-2026-02-28, paraformer-realtime-v2Supports multiple formats, high sampling rates, and stable latency.
Multilingual Recognition (cross-border customer service, international meetings)paraformer-realtime-v2Supports cross-border scenarios and seamless switching between languages.
Chinese Dialect Recognition (customer service/government services)fun-asr-realtime-2026-02-28, paraformer-realtime-v2Covers multiple local dialects.
Mixed Chinese, English, and Japanese Recognition (classes/speeches)fun-asr-realtime, fun-asr-realtime-2025-11-07Optimized for Chinese, English, and Japanese recognition.
Low-Bandwidth Phone Recording Transcriptionfun-asr-flash-8k-realtimeDesigned for Chinese-language call center scenarios.
Custom Hotwords (brand names/proprietary terms)Latest versions of Fun-ASR and Paraformer modelsHotwords can be enabled or disabled to simplify configuration and iteration.

For more details, see Model feature comparison.

Getting started

The following sections provide sample code for calling the API. For more code examples covering common use cases, refer to GitHub.

Create an API key and export the API key as an environment variable. If you use an SDK to make calls, install the DashScope SDK.

Fun-ASR

From microphone

Real-time speech recognition recognizes audio from a microphone and outputs transcription results, providing a "text-as-you-speak" experience.

Java

HELPCODEESCAPE-java
import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionResult;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.utils.Constants;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.TargetDataLine;

import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        // The following URL is for the Singapore region. If you use a model in the Beijing region, replace the URL with wss://dashscope.aliyuncs.com/api-ws/v1/inference.
        Constants.baseWebsocketApiUrl = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference";
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new RealtimeRecognitionTask());
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES);
        System.exit(0);
    }
}

class RealtimeRecognitionTask implements Runnable {
    @Override
    public void run() {
        RecognitionParam param = RecognitionParam.builder()
                .model("fun-asr-realtime")
                // The API keys for the Singapore and Beijing regions are different. To get an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key.
                // If you have not configured an environment variable, replace the following line with your Model Studio API key: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .format("wav")
                .sampleRate(16000)
                .build();
        Recognition recognizer = new Recognition();

        ResultCallback<RecognitionResult> callback = new ResultCallback<RecognitionResult>() {
            @Override
            public void onEvent(RecognitionResult result) {
                if (result.isSentenceEnd()) {
                    System.out.println("Final Result: " + result.getSentence().getText());
                } else {
                    System.out.println("Intermediate Result: " + result.getSentence().getText());
                }
            }

            @Override
            public void onComplete() {
                System.out.println("Recognition complete");
            }

            @Override
            public void onError(Exception e) {
                System.out.println("RecognitionCallback error: " + e.getMessage());
            }
        };
        try {
            recognizer.call(param, callback);
            // Create an audio format.
            AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
            // Match the default recording device based on the format.
            TargetDataLine targetDataLine =
                    AudioSystem.getTargetDataLine(audioFormat);
            targetDataLine.open(audioFormat);
            // Start recording.
            targetDataLine.start();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            long start = System.currentTimeMillis();
            // Record for 50 seconds and perform real-time transcription.
            while (System.currentTimeMillis() - start < 50000) {
                int read = targetDataLine.read(buffer.array(), 0, buffer.capacity());
                if (read > 0) {
                    buffer.limit(read);
                    // Send the recorded audio data to the streaming recognition service.
                    recognizer.sendAudioFrame(buffer);
                    buffer = ByteBuffer.allocate(1024);
                    // The recording rate is limited. Sleep for a short period to prevent high CPU usage.
                    Thread.sleep(20);
                }
            }
            recognizer.stop();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Close the WebSocket connection after the task is complete.
            recognizer.getDuplexApi().close(1000, "bye");
        }

        System.out.println(
                "[Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
    }
}

Python

Before you run the Python example, run the pip install pyaudio command to install the third-party audio playback and capture library.

HELPCODEESCAPE-python
import os
import signal  # for keyboard events handling (press "Ctrl+C" to terminate recording)
import sys

import dashscope
import pyaudio
from dashscope.audio.asr import *

mic = None
stream = None


sample_rate = 16000  # sampling rate (Hz)
channels = 1  # mono channel
dtype = 'int16'  # data type
format_pcm = 'pcm'  # the format of the audio data
block_size = 3200  # number of frames per buffer


# Real-time speech recognition callback
class Callback(RecognitionCallback):
    def on_open(self) -> None:
        global mic
        global stream
        print('RecognitionCallback open.')
        mic = pyaudio.PyAudio()
        stream = mic.open(format=pyaudio.paInt16,
                          channels=1,
                          rate=16000,
                          input=True)

    def on_close(self) -> None:
        global mic
        global stream
        print('RecognitionCallback close.')
        stream.stop_stream()
        stream.close()
        mic.terminate()
        stream = None
        mic = None

    def on_complete(self) -> None:
        print('RecognitionCallback completed.')  # recognition completed

    def on_error(self, message) -> None:
        print('RecognitionCallback task_id: ', message.request_id)
        print('RecognitionCallback error: ', message.message)
        # Stop and close the audio stream if it is running
        if 'stream' in globals() and stream.active:
            stream.stop()
            stream.close()
        # Forcefully exit the program
        sys.exit(1)

    def on_event(self, result: RecognitionResult) -> None:
        sentence = result.get_sentence()
        if 'text' in sentence:
            print('RecognitionCallback text: ', sentence['text'])
            if RecognitionResult.is_sentence_end(sentence):
                print(
                    'RecognitionCallback sentence end, request_id:%s, usage:%s'
                    % (result.get_request_id(), result.get_usage(sentence)))


def signal_handler(sig, frame):
    print('Ctrl+C pressed, stop recognition ...')
    # Stop recognition
    recognition.stop()
    print('Recognition stopped.')
    print(
        '[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
        .format(
            recognition.get_last_request_id(),
            recognition.get_first_package_delay(),
            recognition.get_last_package_delay(),
        ))
    # Forcefully exit the program
    sys.exit(0)


# main function
if __name__ == '__main__':
    # The API keys for the Singapore and Beijing regions are different. To get an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # If you have not configured an environment variable, replace the following line with your Model Studio API key: dashscope.api_key = "sk-xxx"
    dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')

    # The following is the URL for the Singapore region. If you use a model in the Beijing region, replace the URL with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
    dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'

    # Create the recognition callback
    callback = Callback()

    # Call recognition service by async mode, you can customize the recognition parameters, like model, format,
    # sample_rate
    recognition = Recognition(
        model='fun-asr-realtime',
        format=format_pcm,
        # 'pcm', 'wav', 'opus', 'speex', 'aac', 'amr'. You can check the supported formats in the document.
        sample_rate=sample_rate,
        # Supports 8000, 16000.
        semantic_punctuation_enabled=False,
        callback=callback)

    # Start recognition
    recognition.start()

    signal.signal(signal.SIGINT, signal_handler)
    print("Press 'Ctrl+C' to stop recording and recognition...")
    # Create a keyboard listener until "Ctrl+C" is pressed

    while True:
        if stream:
            data = stream.read(3200, exception_on_overflow=False)
            recognition.send_audio_frame(data)
        else:
            break

    recognition.stop()

From local file

Real-time speech recognition transcribes a local audio file and outputs the results. This interface is ideal for short, near-real-time speech recognition scenarios such as voice chats, control commands, voice input, and voice search.

Java

The audio file used in the example is asr_example.wav.

HELPCODEESCAPE-java
import com.alibaba.dashscope.api.GeneralApi;
import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionResult;
import com.alibaba.dashscope.base.HalfDuplexParamBase;
import com.alibaba.dashscope.common.GeneralListParam;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.protocol.GeneralServiceOption;
import com.alibaba.dashscope.protocol.HttpMethod;
import com.alibaba.dashscope.protocol.Protocol;
import com.alibaba.dashscope.protocol.StreamingMode;
import com.alibaba.dashscope.utils.Constants;

import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class TimeUtils {
    private static final DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    public static String getTimestamp() {
        return LocalDateTime.now().format(formatter);
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        // The following URL is for the Singapore region. If you use a model in the Beijing region, replace the URL with wss://dashscope.aliyuncs.com/api-ws/v1/inference.
        Constants.baseWebsocketApiUrl = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference";
        // In a real application, call this method only once at program startup.
        warmUp();

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new RealtimeRecognitionTask(Paths.get(System.getProperty("user.dir"), "asr_example.wav")));
        executorService.shutdown();

        // Wait for all tasks to complete.
        executorService.awaitTermination(1, TimeUnit.MINUTES);
        System.exit(0);
    }

    public static void warmUp() {
        try {
            // Lightweight GET request to establish a connection.
            GeneralServiceOption warmupOption = GeneralServiceOption.builder()
                    .protocol(Protocol.HTTP)
                    .httpMethod(HttpMethod.GET)
                    .streamingMode(StreamingMode.OUT)
                    .path("assistants")
                    .build();

            warmupOption.setBaseHttpUrl(Constants.baseHttpApiUrl);
            GeneralApi&lt;HalfDuplexParamBase&gt; api = new GeneralApi<>();
            api.get(GeneralListParam.builder().limit(1L).build(), warmupOption);
        } catch (Exception e) {
            // Allow retry if warm-up fails.
        }
    }
}

class RealtimeRecognitionTask implements Runnable {
    private Path filepath;

    public RealtimeRecognitionTask(Path filepath) {
        this.filepath = filepath;
    }

    @Override
    public void run() {
        RecognitionParam param = RecognitionParam.builder()
                .model("fun-asr-realtime")
                // The API keys for the Singapore and Beijing regions are different. To get an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key.
                // If you have not configured an environment variable, replace the following line with your Model Studio API key: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .format("wav")
                .sampleRate(16000)
                .build();
        Recognition recognizer = new Recognition();

        String threadName = Thread.currentThread().getName();

        ResultCallback&lt;RecognitionResult&gt; callback = new ResultCallback&lt;RecognitionResult&gt;() {
            @Override
            public void onEvent(RecognitionResult message) {
                if (message.isSentenceEnd()) {

                    System.out.println(TimeUtils.getTimestamp()+" "+
                            "[process " + threadName + "] Final Result:" + message.getSentence().getText());
                } else {
                    System.out.println(TimeUtils.getTimestamp()+" "+
                            "[process " + threadName + "] Intermediate Result: " + message.getSentence().getText());
                }
            }

            @Override
            public void onComplete() {
                System.out.println(TimeUtils.getTimestamp()+" "+"[" + threadName + "] Recognition complete");
            }

            @Override
            public void onError(Exception e) {
                System.out.println(TimeUtils.getTimestamp()+" "+
                        "[" + threadName + "] RecognitionCallback error: " + e.getMessage());
            }
        };

        try {
            recognizer.call(param, callback);
            // Replace the path with your audio file path.
            System.out.println(TimeUtils.getTimestamp()+" "+"[" + threadName + "] Input file_path is: " + this.filepath);
            // Read the file and send audio in chunks.
            FileInputStream fis = new FileInputStream(this.filepath.toFile());
            byte[] allData = new byte[fis.available()];
            int ret = fis.read(allData);
            fis.close();

            int sendFrameLength = 3200;
            for (int i = 0; i * sendFrameLength < allData.length; i ++) {
                int start = i * sendFrameLength;
                int end = Math.min(start + sendFrameLength, allData.length);
                ByteBuffer byteBuffer = ByteBuffer.wrap(allData, start, end - start);
                recognizer.sendAudioFrame(byteBuffer);
                Thread.sleep(100);
            }

            System.out.println(TimeUtils.getTimestamp()+" "+LocalDateTime.now());
            recognizer.stop();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Close the WebSocket connection after the task is complete.
            recognizer.getDuplexApi().close(1000, "bye");
        }

        System.out.println(
                "["
                        + threadName
                        + "][Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
    }
}

Python

The audio file used in the example is asr_example.wav.

HELPCODEESCAPE-python
import os
import time
import dashscope
from dashscope.audio.asr import *

# API keys differ between the Singapore and Beijing regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
# If you have not set an environment variable, replace the next line with your Model Studio API key: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')

# The following URL is for the Singapore region. To use the Beijing region model, replace it with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'

from datetime import datetime


def get_timestamp():
    now = datetime.now()
    formatted_timestamp = now.strftime("[%Y-%m-%d %H:%M:%S.%f]")
    return formatted_timestamp


class Callback(RecognitionCallback):
    def on_complete(self) -> None:
        print(get_timestamp() + ' Recognition completed')  # recognition complete

    def on_error(self, result: RecognitionResult) -> None:
        print('Recognition task_id: ', result.request_id)
        print('Recognition error: ', result.message)
        exit(0)

    def on_event(self, result: RecognitionResult) -> None:
        sentence = result.get_sentence()
        if 'text' in sentence:
            print(get_timestamp() + ' RecognitionCallback text: ', sentence['text'])
        if RecognitionResult.is_sentence_end(sentence):
            print(get_timestamp() +
                  'RecognitionCallback sentence end, request_id:%s, usage:%s'
                  % (result.get_request_id(), result.get_usage(sentence)))


callback = Callback()

recognition = Recognition(model='fun-asr-realtime',
                          format='wav',
                          sample_rate=16000,
                          callback=callback)

try:
    audio_data: bytes = None
    f = open("asr_example.wav", 'rb')
    if os.path.getsize("asr_example.wav"):
        # Read the entire file into a buffer
        file_buffer = f.read()
        f.close()
        print("Start Recognition")
        recognition.start()

        # Send data in chunks of 3200 bytes
        buffer_size = len(file_buffer)
        offset = 0
        chunk_size = 3200

        while offset < buffer_size:
            # Calculate the size of the current chunk
            remaining_bytes = buffer_size - offset
            current_chunk_size = min(chunk_size, remaining_bytes)

            # Extract the current chunk from the buffer
            audio_data = file_buffer[offset:offset + current_chunk_size]

            # Send the audio frame
            recognition.send_audio_frame(audio_data)
            # Update the offset
            offset += current_chunk_size

            # Add a delay to simulate real-time transmission
            time.sleep(0.1)

        recognition.stop()
    else:
        raise Exception(
            'The supplied file was empty (zero bytes long)')
except Exception as e:
    raise e

print(
    '[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
    .format(
        recognition.get_last_request_id(),
        recognition.get_first_package_delay(),
        recognition.get_last_package_delay(),
    ))

Paraformer

From microphone

Real-time speech recognition recognizes audio from a microphone and outputs transcription results, providing a "text-as-you-speak" experience.

Java

HELPCODEESCAPE-java
import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;

import java.nio.ByteBuffer;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.TargetDataLine;

public class Main {

    public static void main(String[] args) throws NoApiKeyException {
        // Create a Flowable**.
        Flowable&lt;ByteBuffer&gt; audioSource = Flowable.create(emitter -> {
            new Thread(() -> {
                try {
                    // Create an audio format.
                    AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
                    // Match the default recording device based on the format.
                    TargetDataLine targetDataLine =
                            AudioSystem.getTargetDataLine(audioFormat);
                    targetDataLine.open(audioFormat);
                    // Start recording.
                    targetDataLine.start();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    long start = System.currentTimeMillis();
                    // Record for 300 seconds and perform real-time transcription.
                    while (System.currentTimeMillis() - start < 300000) {
                        int read = targetDataLine.read(buffer.array(), 0, buffer.capacity());
                        if (read > 0) {
                            buffer.limit(read);
                            // Send the recorded audio data to the streaming recognition service.
                            emitter.onNext(buffer);
                            buffer = ByteBuffer.allocate(1024);
                            // Sleep for a short time to prevent high CPU usage.
                            Thread.sleep(20);
                        }
                    }
                    // Signal the end of transcription.
                    emitter.onComplete();
                } catch (Exception e) {
                    emitter.onError(e);
                }
            }).start();
        },
        BackpressureStrategy.BUFFER);

        // Create a Recognizer.
        Recognition recognizer = new Recognition();
        // Create a RecognitionParam and pass the created Flowable&lt;ByteBuffer&gt; to the audioFrames parameter.
        RecognitionParam param = RecognitionParam.builder()
            .model("paraformer-realtime-v2")
            .format("pcm")
            .sampleRate(16000)
            // If the API key is not set as an environment variable, uncomment the following line and replace "sk-xxx" with your API key.
            // .apiKey("sk-xxx")
            .build();

        // Call the interface in streaming mode.
        recognizer.streamCall(param, audioSource)
            // Call the subscribe method of Flowable to receive the results.
            .blockingForEach(
                result -> {
                    // Print the final result.
                    if (result.isSentenceEnd()) {
                        System.out.println("Fix:" + result.getSentence().getText());
                    } else {
                        System.out.println("Result:" + result.getSentence().getText());
                    }
                });
        System.exit(0);
    }
}

Python

Before running the Python example, run the pip install pyaudio command to install a third-party audio playback and recording suite.

HELPCODEESCAPE-python
import pyaudio
from dashscope.audio.asr import (Recognition, RecognitionCallback,
                                 RecognitionResult)

# If the API key is not set as an environment variable, uncomment the following line and replace "sk-xxx" with your API key.
# import dashscope
# dashscope.api_key = "sk-xxx"

mic = None
stream = None


class Callback(RecognitionCallback):
    def on_open(self) -> None:
        global mic
        global stream
        print('RecognitionCallback open.')
        mic = pyaudio.PyAudio()
        stream = mic.open(format=pyaudio.paInt16,
                          channels=1,
                          rate=16000,
                          input=True)

    def on_close(self) -> None:
        global mic
        global stream
        print('RecognitionCallback close.')
        stream.stop_stream()
        stream.close()
        mic.terminate()
        stream = None
        mic = None

    def on_event(self, result: RecognitionResult) -> None:
        print('RecognitionCallback sentence: ', result.get_sentence())


callback = Callback()
recognition = Recognition(model='paraformer-realtime-v2',
                          format='pcm',
                          sample_rate=16000,
                          callback=callback)
recognition.start()

while True:
    if stream:
        data = stream.read(3200, exception_on_overflow=False)
        recognition.send_audio_frame(data)
    else:
        break

recognition.stop()

From local file

Real-time speech recognition transcribes a local audio file and outputs the results. This interface is ideal for short, near-real-time speech recognition scenarios such as voice chats, control commands, voice input, and voice search.

Java

HELPCODEESCAPE-java
import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class Main {
    public static void main(String[] args) {
        // You can ignore the file download and use a local file for recognition.
        String exampleWavUrl =
                "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_female2.wav";
        try {
            InputStream in = new URL(exampleWavUrl).openStream();
            Files.copy(in, Paths.get("asr_example.wav"), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            System.out.println("error: " + e);
            System.exit(1);
        }

        // Create a Recognition instance.
        Recognition recognizer = new Recognition();
        // Create a RecognitionParam.
        RecognitionParam param =
                RecognitionParam.builder()
                        // If the API key is not set as an environment variable, uncomment the following line and replace "sk-xxx" with your API key.
                        // .apiKey("sk-xxx")
                        .model("paraformer-realtime-v2")
                        .format("wav")
                        .sampleRate(16000)
                        // The "language_hints" parameter is supported only by the paraformer-v2 and paraformer-realtime-v2 models.
                        .parameter("language_hints", new String[]{"zh", "en"})
                        .build();

        try {
            System.out.println("Recognition result: " + recognizer.call(param, new File("asr_example.wav")));
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.exit(0);
    }
}

Python

HELPCODEESCAPE-python
import requests
from http import HTTPStatus
from dashscope.audio.asr import Recognition

# If the API key is not set as an environment variable, uncomment the following line and replace "sk-xxx" with your API key.
# import dashscope
# dashscope.api_key = "sk-xxx"

# You can ignore the file download and use a local file for recognition.
r = requests.get(
    'https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/paraformer/hello_world_female2.wav'
)
with open('asr_example.wav', 'wb') as f:
    f.write(r.content)

recognition = Recognition(model='paraformer-realtime-v2',
                          format='wav',
                          sample_rate=16000,
                          # The "language_hints" parameter is supported only by the paraformer-v2 and paraformer-realtime-v2 models.
                          language_hints=['zh', 'en'],
                          callback=None)
result = recognition.call('asr_example.wav')
if result.status_code == HTTPStatus.OK:
    print('Recognition result:')
    print(result.get_sentence())
else:
    print('Error: ', result.message)

Production deployment

Improve recognition accuracy

  • Select a model with the correct sample rate: For 8 kHz telephone audio, use an 8 kHz model directly instead of upsampling it to 16 kHz for recognition. This approach prevents information distortion and yields better results.

  • Use custom hotwords : For business-specific proper nouns, names, and brand names, configure custom hotwords to significantly improve recognition accuracy. For more information, see custom hotwords.

  • Optimize input audio quality: Use a high-quality microphone and ensure the recording environment has a high signal-to-noise ratio (SNR) and no echo. At the application level, you can integrate algorithms for noise reduction (such as RNNoise) and acoustic echo cancellation (AEC) to preprocess the audio.

  • Specify the recognition language : For multilingual models like Paraformer-v2, specify the audio language in advance by using the Language_hints parameter, for example, ['zh','en']. This helps the model converge, prevents confusion between similarly pronounced languages, and improves accuracy.

  • Enable disfluency removal : For the Paraformer model, you can enable disfluency removal by setting the disfluency_removal_enabled parameter. This setting produces more formal and readable text results.

Fault tolerance

  • Implement client-side reconnection: Your client should implement an automatic reconnection mechanism to handle network jitter. For the Python SDK, we recommend the following:

    1. Catch exceptions: Implement the on_error method in the Callback class. The dashscope SDK calls this method on network errors or other issues.

    2. Signal for reconnection: When on_error is triggered, set a reconnection signal. In Python, you can use threading.Event, which is a thread-safe flag.

    3. Create a reconnection loop: Wrap the main logic in a for loop (for example, to retry 3 times). When the reconnection signal is detected, interrupt the current recognition round, clean up the resources, wait a few seconds, and then re-enter the loop to create a new connection.

  • Set a heartbeat to prevent disconnection: To maintain a persistent connection with the server, set the heartbeat parameter to true. This ensures the connection remains active even during long periods of silence in the audio.

  • Be aware of model rate limits : When calling the model API, be aware of the model's rate limiting rules.

API

  • Fun-ASR real-time speech recognition API reference

  • Paraformer real-time speech recognition API reference

Model features

Feature**Fun-ASRParaformer
LanguageVaries by model: - fun-asr-realtime, fun-asr-realtime-2026-02-28, fun-asr-realtime-2025-11-07: Chinese (Mandarin, Cantonese, Wu, Minnan, Hakka, Gan, Xiang, and Jin; supports Mandarin accents from regions such as the Central Plains, Southwest China, Ji-Lu, Jianghuai, Lan-Yin, Jiao-Liao, Northeast China, Beijing, Hong Kong, and Taiwan, including Henan, Shaanxi, Hubei, Sichuan, Chongqing, Yunnan, Guizhou, Guangdong, Guangxi, Hebei, Tianjin, Shandong, Anhui, Nanjing, Jiangsu, Hangzhou, Gansu, and Ningxia), English, and Japanese - fun-asr-realtime-2025-09-15: Chinese (Mandarin) and English - fun-asr-flash-8k-realtime, fun-asr-flash-8k-realtime-2026-01-28: ChineseVaries by model: - paraformer-realtime-v2: Chinese (Mandarin, Cantonese, Wu, Minnan, and dialects from Northeast, Gansu, Guizhou, Henan, Hubei, Hunan, Ningxia, Shanxi, Shaanxi, Shandong, Sichuan, Tianjin, Jiangxi, Yunnan, and Shanghai), English, Japanese, Korean, German, French, and Russian - paraformer-realtime-v1, paraformer-realtime-8k-v2, paraformer-realtime-8k-v1: Chinese (Mandarin)
Audio formatpcm, wav, mp3, opus, speex, aac, and amr
Sample rateVaries by model: - fun-asr-realtime, fun-asr-realtime-2026-02-28, fun-asr-realtime-2025-11-07, fun-asr-realtime-2025-09-15: 16 kHz - fun-asr-flash-8k-realtime, fun-asr-flash-8k-realtime-2026-01-28: 8 kHzVaries by model: - paraformer-realtime-v2: Any sample rate - paraformer-realtime-v1: 16 kHz - paraformer-realtime-8k-v2, paraformer-realtime-8k-v1: 8 kHz
Audio channelMono
Input formatBinary audio stream
Audio size/durationUnlimitedUnlimited
Emotion recognitionNot supportedVaries by model: - paraformer-realtime-v2, paraformer-realtime-v1, paraformer-realtime-8k-v1: Not supported - paraformer-realtime-8k-v2: Supported. Enabled by default and can be disabled.
Sensitive word filteringNot supported
Speaker diarizationNot supported
Filler word filteringNot supportedSupported. Disabled by default but can be enabled.
TimestampAlways enabled.
Punctuation predictionAlways enabled.Varies by model: - paraformer-realtime-v2, paraformer-realtime-8k-v2: Supported. Enabled by default and can be disabled. - paraformer-realtime-v1, paraformer-realtime-8k-v1: Always enabled.
HotwordsSupported ** **Important ** The hotwords feature is supported only in the default workspace. It is not currently supported in custom workspaces.
ITNAlways enabled.
VADAlways enabled.
Rate limit (RPS)2020
Access methodJava, Python, Android, and iOS SDKs; WebSocket API
PriceVaries by model: - fun-asr-realtime, fun-asr-realtime-2026-02-28, fun-asr-realtime-2025-11-07: Outside Chinese mainland: $0.00009/second - Chinese mainland: $0.000047/second - fun-asr-realtime-2025-09-15: Chinese mainland: $0.000047/second - fun-asr-flash-8k-realtime, fun-asr-flash-8k-realtime-2026-01-28: Chinese mainland: $0.000032/secondChinese mainland: $0.000012/second

Mirror of Alibaba Cloud Model Studio docs for reference and RAG. Not affiliated with Alibaba Cloud.