Appearance
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
| Scenario | Recommended model | Reason |
|---|---|---|
| Mandarin Chinese Recognition (meetings/live streaming) | fun-asr-realtime, fun-asr-realtime-2026-02-28, paraformer-realtime-v2 | Supports multiple formats, high sampling rates, and stable latency. |
| Multilingual Recognition (cross-border customer service, international meetings) | paraformer-realtime-v2 | Supports cross-border scenarios and seamless switching between languages. |
| Chinese Dialect Recognition (customer service/government services) | fun-asr-realtime-2026-02-28, paraformer-realtime-v2 | Covers multiple local dialects. |
| Mixed Chinese, English, and Japanese Recognition (classes/speeches) | fun-asr-realtime, fun-asr-realtime-2025-11-07 | Optimized for Chinese, English, and Japanese recognition. |
| Low-Bandwidth Phone Recording Transcription | fun-asr-flash-8k-realtime | Designed for Chinese-language call center scenarios. |
| Custom Hotwords (brand names/proprietary terms) | Latest versions of Fun-ASR and Paraformer models | Hotwords 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<HalfDuplexParamBase> 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<RecognitionResult> callback = new ResultCallback<RecognitionResult>() {
@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<ByteBuffer> 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<ByteBuffer> 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:
Catch exceptions: Implement the
on_errormethod in theCallbackclass. ThedashscopeSDK calls this method on network errors or other issues.Signal for reconnection: When
on_erroris triggered, set a reconnection signal. In Python, you can usethreading.Event, which is a thread-safe flag.Create a reconnection loop: Wrap the main logic in a
forloop (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-ASR | Paraformer |
|---|---|---|
| Language | Varies 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: Chinese | Varies 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 format | pcm, wav, mp3, opus, speex, aac, and amr | |
| Sample rate | Varies 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 kHz | Varies by model: - paraformer-realtime-v2: Any sample rate - paraformer-realtime-v1: 16 kHz - paraformer-realtime-8k-v2, paraformer-realtime-8k-v1: 8 kHz |
| Audio channel | Mono | |
| Input format | Binary audio stream | |
| Audio size/duration | Unlimited | Unlimited |
| Emotion recognition | Not supported | Varies 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 filtering | Not supported | |
| Speaker diarization | Not supported | |
| Filler word filtering | Not supported | Supported. Disabled by default but can be enabled. |
| Timestamp | Always enabled. | |
| Punctuation prediction | Always 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. |
| Hotwords | Supported ** **Important ** The hotwords feature is supported only in the default workspace. It is not currently supported in custom workspaces. | |
| ITN | Always enabled. | |
| VAD | Always enabled. | |
| Rate limit (RPS) | 20 | 20 |
| Access method | Java, Python, Android, and iOS SDKs; WebSocket API | |
| Price | Varies 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/second | Chinese mainland: $0.000012/second |