Improve recognition accuracy
Model Studio speech recognition provides custom hotwords and context enhancement to improve recognition accuracy for domain-specific terms, product names, and specialized vocabulary. This topic describes the supported models, regions, and usage of both approaches.
The hotword feature is supported only in the primary workspace. Sub-workspaces don't support hotwords.
Overview
Some business-specific vocabulary — such as product names, proper nouns, and industry terms — isn't in the model's general lexicon and is often recognized incorrectly. Model Studio speech recognition provides custom hotwords and context enhancement to improve recognition accuracy for these terms.
Custom hotwords vs. context enhancement
Model Studio speech recognition provides two approaches for handling specialized terms. Each applies to different models and interfaces:
|
Dimension |
Custom hotwords |
Context enhancement |
|
How it works |
Provides a weighted word list. The model raises the match probability of listed terms during decoding. |
Passes conversation history or domain text as context. The model uses it to correct recognition results. |
|
Supported models |
Fun-ASR and Paraformer families (real-time + non-real-time) |
fun-asr-flash-2026-06-15 (non-real-time only) |
|
Best for |
Known, relatively stable terms that you want to reuse across requests (such as product names and medical terms) |
Terms that change dynamically per conversation, or proper nouns that the model can better recognize with contextual hints (such as attendee names in meetings or domain terms in support calls) |
|
Configuration |
Create a vocabulary list in advance and pass its ID at recognition time. |
Pass conversation history or domain text through |
Prerequisites
-
Obtain an API key obtained and configured as an environment variable.
-
If calling through the DashScope SDK, install the latest SDK version.
Custom hotwords
Supported models and regions
Singapore
To call the following models, select an API Key from the Singapore region:
Fun-ASR:
-
Real-time speech recognition: fun-asr-realtime, fun-asr-realtime-2025-11-07
-
Non-real-time speech recognition: fun-asr, fun-asr-2025-11-07, fun-asr-2025-08-25, fun-asr-mtl, fun-asr-mtl-2025-08-25
China (Beijing)
To call the following models, select an API Key from the Beijing region:
-
Fun-ASR:
-
Real-time speech recognition: fun-asr-realtime, fun-asr-realtime-2025-11-07, fun-asr-realtime-2025-09-15, fun-asr-flash-8k-realtime, fun-asr-flash-8k-realtime-2026-01-28
-
Non-real-time speech recognition: fun-asr, fun-asr-2025-11-07, fun-asr-2025-08-25, fun-asr-mtl, fun-asr-mtl-2025-08-25
-
-
Paraformer:
-
Real-time speech recognition: paraformer-realtime-v2, paraformer-realtime-8k-v2
-
Non-real-time speech recognition: paraformer-v2, paraformer-8k-v2
-
Quick start
How it works
Create a vocabulary list first, then reference its ID when calling speech recognition:
-
Create a vocabulary list.
Call the Create Vocabulary List API. Specify target_model (targetModel in Java) to indicate which speech recognition model the list applies to.
Skip this step if a vocabulary list already exists. Use the Query All Vocabulary Lists API to check.
-
Call the speech recognition API with the vocabulary list ID.
The speech recognition model must match the target_model (targetModel in Java) set when the list was created; otherwise, hotwords don't take effect.
Sample code
End-to-end example: create a vocabulary list, call speech recognition, then delete the list. Sample audio file: asr_example.wav.
The hotword management API and the speech recognition API must use the same account. Otherwise, the recognition API can't access the vocabulary list.
Python
import dashscope
from dashscope.audio.asr import *
import os
# The API Keys for the Beijing and Singapore regions are different. Obtain an API Key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
# If the environment variable is not configured, replace the following line with: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. Configurations vary by region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1'
# The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. Configurations vary by region.
dashscope.base_websocket_api_url = 'wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference'
prefix = 'testpfx'
target_model = "fun-asr-realtime"
my_vocabulary = [
{"text": "Speech Laboratory", "weight": 4}
]
service = VocabularyService()
vocabulary_id = service.create_vocabulary(
prefix=prefix,
target_model=target_model,
vocabulary=my_vocabulary)
try:
if service.query_vocabulary(vocabulary_id)['status'] == 'OK':
recognition = Recognition(model=target_model,
format='wav',
sample_rate=16000,
callback=None,
vocabulary_id=vocabulary_id)
result = recognition.call('asr_example.wav')
print(result.output)
finally:
# Delete the hotword list regardless of whether recognition succeeded, to avoid occupying quota
service.delete_vocabulary(vocabulary_id)
Java
import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.audio.asr.vocabulary.Vocabulary;
import com.alibaba.dashscope.audio.asr.vocabulary.VocabularyService;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Main {
// The API Keys for the Beijing and Singapore regions are different. Obtain an API Key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
// If the environment variable is not configured, replace the following line with: public static String apiKey = "sk-xxx"
public static String apiKey = System.getenv("DASHSCOPE_API_KEY");
public static void main(String[] args) throws NoApiKeyException, InputRequiredException {
// The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. Configurations vary by region.
Constants.baseHttpApiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
// The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. Configurations vary by region.
Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference";
String targetModel = "fun-asr-realtime";
JsonArray vocabularyJson = new JsonArray();
List<Hotword> wordList = new ArrayList<>();
wordList.add(new Hotword("Speech Laboratory", 4));
for (Hotword word : wordList) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("text", word.text);
jsonObject.addProperty("weight", word.weight);
vocabularyJson.add(jsonObject);
}
VocabularyService service = new VocabularyService(apiKey);
Vocabulary vocabulary = service.createVocabulary(targetModel, "testpfx", vocabularyJson);
try {
if ("OK".equals(service.queryVocabulary(vocabulary.getVocabularyId()).getStatus())) {
Recognition recognizer = new Recognition();
RecognitionParam param =
RecognitionParam.builder()
.model(targetModel)
.apiKey(apiKey)
.format("wav")
.sampleRate(16000)
.vocabularyId(vocabulary.getVocabularyId())
.build();
try {
System.out.println("Recognition result: " + recognizer.call(param, new File("asr_example.wav")));
} catch (Exception e) {
e.printStackTrace();
} finally {
// Close the WebSocket connection
recognizer.getDuplexApi().close(1000, "bye");
}
}
} finally {
// Delete the hotword list regardless of whether recognition succeeded, to avoid occupying quota
service.deleteVocabulary(vocabulary.getVocabularyId());
}
System.exit(0);
}
}
class Hotword {
String text;
int weight;
public Hotword(String text, int weight) {
this.text = text;
this.weight = weight;
}
}
Hotword format
Submit hotwords as a JSON array. Each element defines a single hotword and its properties. A vocabulary list (referred to as vocabulary in the API) groups these hotwords for use with a specific model.
Example: Improve the recognition accuracy of movie titles.
[
{"text": "Seediq Bale", "weight": 4, "lang": "en"},
{"text": "Goodbye Mr. Loser", "weight": 4, "lang": "en"},
{"text": "Confucius' Family", "weight": 4, "lang": "en"}
]
Field description:
|
Field |
Type |
Required |
Description |
|
text |
string |
Yes |
The hotword text. Must be an actual word or phrase rather than an arbitrary character combination. The language must be supported by the selected model. For length limits, see Hotword text rules. |
|
weight |
int |
Yes |
Hotword weight. Valid values: [1, 5]. Recommended: 4. A higher weight makes the model more likely to output the term. For tuning guidelines, see Adjust hotword weights. |
|
lang |
string |
No |
Language code that restricts the hotword to a specific language. If the language is unknown, omit this field. Note: |
Hotword text rules
Hotword text must be an actual word or phrase. Length limits are as follows:
-
Contains non-ASCII characters: The total character count — including non-ASCII characters (such as Chinese, Japanese kana, Korean Hangul, and Cyrillic) and ASCII characters combined — must not exceed 15.
Examples:
-
✅
"厄洛替尼盐酸盐"(7 characters) -
✅
"EGFR抑制剂"(7 characters, of which EGFR accounts for 4 ASCII characters) -
✅
"こんにちは"(5 characters) -
✅
"Фенибут Белфарм"(15 characters, including the space) -
❌
"Клофелин Белмедпрепараты"(24 characters)
-
-
Pure ASCII characters: The number of space-delimited segments must not exceed 7.
Examples:
-
✅
"Exothermic reaction"= 2 segments -
✅
"Human immunodeficiency virus type 1"= 5 segments -
❌
"The effect of temperature variations on enzyme activity in biochemical reactions"= 11 segments
-
Tune hotword performance
Adjust hotword weights
Weight controls how strongly the model favors a hotword. Set it appropriately to improve target word accuracy without introducing false recognitions.
|
Weight |
Effect |
Best for |
|
1-2 |
Slight preference |
Hotwords that sound similar to common words, where overcorrection must be avoided |
|
3-4 |
Clear preference (recommended) |
The best starting point for most scenarios |
|
5 |
Forced preference |
Use only when the term appears frequently in the audio and is unlikely to be confused with other words. Note: An excessively high weight can cause phonetically similar words to be misrecognized as the hotword. |
Start with weight=4 and adjust incrementally based on recognition results.
Design hotword lists
-
Group by scenario: Create separate vocabulary lists for different business scenarios (for example, one for medical terms and another for product names) to simplify maintenance and reuse.
-
Mix multiple languages: A single vocabulary list can contain terms in different languages. Use the
langfield to distinguish them. Whenlanguage_hintsis specified during speech recognition, only hotwords that match the specified language take effect. -
Clean up regularly: Delete unused vocabulary lists to free up quota. Each account supports up to 10 lists.
Limits and billing
|
Limit |
Description |
|
Number of vocabulary lists |
10 per account, shared across all models. |
|
Hotwords per list |
Up to 500 hotwords per vocabulary list. |
|
Billing |
Free of charge. |
Context enhancement
Supported models and regions
Singapore
To call the following models, select an API Key from the Singapore region:
Fun-ASR:
-
Non-real-time speech recognition: fun-asr-flash-2026-06-15
China (Beijing)
To call the following models, select an API Key from the Beijing region:
Fun-ASR:
-
Non-real-time speech recognition: fun-asr-flash-2026-06-15
Quick start
Context enhancement requires no pre-created resources. Simply pass context parameters in your speech recognition request:
-
Non-real-time speech recognition: Pass context messages in
input.messagesof the HTTP request, placed before the audio message.
Use cases: By passing conversation history or domain terminology as context, you can significantly improve transcription accuracy for specialized terms such as names, locations, and product terminology. This feature supports the following scenarios:
-
Word list enhancement: Pass domain-specific word lists or terminology through
user(input_text) to help the model accurately recognize specialized vocabulary. -
Multi-turn conversation context: In voice interaction scenarios that combine ASR with large language models, pass prior recognition results (
user/input_text) and model responses (assistant/text) to improve recognition accuracy for the current turn.
-
Message count limit: The engine retains up to the 5 most recent turns of context. Word list enhancement typically requires only 1 message and is not affected by this limit. When exceeded, earlier messages are automatically ignored without returning an error.
-
Text length limit: The total text length per turn of context (the combined length of all
userandassistanttextfields in the same turn) must not exceed 400 characters (counted per character, where each character counts as 1, including letters, Chinese characters, digits, spaces, and punctuation). Excess content is silently truncated from the end without returning an error. In multi-turn contexts, each turn is counted independently. -
Context mechanism: Context works primarily through word matching. The
textfield should contain the exact words to be recognized in the audio (such as "Kubernetes" or "Bulge Bracket"). Passing only semantically related descriptions without the target words will have limited effect.
Non-real-time speech recognition
Pass context through input.messages. Use the user role with input_text type for prior speech recognition results or domain-specific word lists. Use the assistant role for prior model responses (optional). Place context messages before the audio message. For details, see DashScope synchronous calls (Fun-ASR-Flash).
Word list enhancement
Pass domain-specific terminology through user (input_text). No assistant message is needed.
{
"model": "fun-asr-flash-2026-06-15",
"input": {
"messages": [
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Kubernetes Istio Envoy service mesh sidecar proxy"
}
]
},
{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": "Audio URL or Base64 of the current audio to recognize"
}
}
]
}
]
},
"parameters": {}
}
Multi-turn conversation context
Pass prior recognition results (user / input_text) and model responses (assistant / text).
{
"model": "fun-asr-flash-2026-06-15",
"input": {
"messages": [
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Prior user speech recognition result"
}
]
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "Prior model response content"
}
]
},
{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": "Audio URL or Base64 of the current audio to recognize"
}
}
]
}
]
},
"parameters": {}
}
Effect example
The text field content format is flexible — it can be a word list, natural language paragraph, or a mix of both. It has high tolerance for unrelated text.
An audio clip should be correctly recognized as: "The jargon within investment banking circles, how much do you know? First, the nine major foreign investment banks, Bulge Bracket, BB ..."
|
Without context enhancement Without context enhancement, some investment bank names are recognized incorrectly. For example, "Bird Rock" should be "Bulge Bracket". Recognition result: "The jargon within investment banking circles, how much do you know? First, the nine major foreign investment banks, Bird Rock, BB ..." |
With context enhancement With context enhancement, investment bank names are recognized correctly. Recognition result: "The jargon within investment banking circles, how much do you know? First, the nine major foreign investment banks, Bulge Bracket, BB ..." |
In the example above, adding a word list or natural language paragraph containing terms like "Bulge Bracket" to the text field achieves the enhancement effect.
API reference
FAQ
Q: Why don't hotwords improve recognition accuracy?
Check the following in order:
-
Model mismatch: The
target_modelspecified when creating the list must match the model used by the speech recognition API. A mismatch doesn't cause an error, and recognition still returns results, but the hotwords don't take effect. If the results don't contain expected hotwords, check this first. -
Unsupported model: The model must belong to the Fun-ASR or Paraformer family. Other families don't support hotwords. Calling the API with an unsupported model doesn't return an error, but the results may be empty or lack hotword enhancement. If using a model such as SenseVoice, check this first.
-
Inappropriate weight: Increase the weight from 4 to 5 and observe the results. If phonetically similar words start being misrecognized as the hotword, reduce it back to 4.
-
Hotword list status: Use the Query API to confirm that
statusisOK.
Q: Are hotwords used differently in real-time and file-based recognition?
Hotword lists are created the same way. The calling method differs:
-
Real-time speech recognition: Pass
vocabulary_idin the Recognition or WebSocket connection parameters. -
File-based speech recognition: Pass
vocabulary_idin the Transcription request parameters.
In both cases, target_model must match the speech recognition model used in the API call.
Q: How to improve recognition accuracy beyond hotwords?
In addition to hotwords and context enhancement, consider the following:
-
Audio quality: Match the sample rate to the model requirements (16 kHz or 8 kHz) and reduce background noise.
-
Choose the right model: Different scenarios call for different models. For details, see the Speech-to-text model selection guide.
-
Specify the language: Declare the audio language through
language_hintsto improve accuracy in single-language scenarios.