提升識別準確率
阿里雲百鍊語音辨識提供自訂熱詞和上下文增強兩種方式,提升專業術語、產品名稱等特定詞彙的識別準確率。本文介紹兩種方式的適用範圍與使用方法。
僅主業務空間支援熱詞功能,子業務空間暫不支援。
概述
部分業務詞彙(如產品名、專有名詞、行業術語)不在模型通用詞表中,識別準確率較低。阿里雲百鍊語音辨識提供自訂熱詞和上下文增強兩種方式,提升這類詞彙的識別效果。
自訂熱詞與上下文增強區別
阿里雲百鍊語音辨識提供兩種處理專業術語的方式,適用模型和介面不同:
|
維度 |
自訂熱詞 |
上下文增強 |
|
原理 |
提供帶權重的詞彙表,模型在解碼時提升匹配機率 |
傳入對話歷史或領域語料,模型利用上下文修正識別結果 |
|
適用模型 |
Fun-ASR、Paraformer 系列(即時 + 非即時) |
fun-asr-flash-2026-06-15(僅非即時) |
|
適用情境 |
詞彙已知且相對穩定,需要跨請求複用同一詞表(如產品名、醫學術語) |
詞彙隨對話動態變化,或需要通過上下文協助模型理解專有名詞(如會議紀要中的參會人、客服對話中的業務術語) |
|
配置方式 |
預先建立熱詞列表,調用時傳入列表 ID |
每次請求時通過 |
前提條件
自訂熱詞
支援的模型與地區
新加坡
調用以下模型時,請選擇新加坡地區的API Key:
Fun-ASR:
-
即時語音辨識:fun-asr-realtime、fun-asr-realtime-2025-11-07
-
非即時語音辨識:fun-asr、fun-asr-2025-11-07、fun-asr-2025-08-25、fun-asr-mtl、fun-asr-mtl-2025-08-25
華北2(北京)
調用以下模型時,請選擇北京地區的API Key:
-
Fun-ASR:
-
即時語音辨識: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
-
非即時語音辨識:fun-asr、fun-asr-2025-11-07、fun-asr-2025-08-25、fun-asr-mtl、fun-asr-mtl-2025-08-25
-
-
Paraformer:
-
即時語音辨識:paraformer-realtime-v2、paraformer-realtime-8k-v2
-
非即時語音辨識:paraformer-v2、paraformer-8k-v2
-
快速開始
工作流程
先建立熱詞列表,再在語音辨識時引用其 ID:
-
建立熱詞列表。
調用建立熱詞列表介面,必須指定
target_model(Java 中為targetModel),表明該列表所屬的語音辨識模型。如已有熱詞列表(可通過查詢所有熱詞列表介面查看),跳過此步。
-
調用語音辨識介面並傳入熱詞列表 ID。
語音辨識使用的模型必須與建立時指定的
target_model(Java 中為targetModel)一致,否則熱詞不生效。
範例程式碼
完整流程樣本:建立熱詞列表 → 調用語音辨識 → 刪除列表。樣本音頻:asr_example.wav。
熱詞管理 API 與語音辨識 API 必須使用同一帳號,否則識別介面無法訪問對應的熱詞列表。
Python
import dashscope
from dashscope.audio.asr import *
import os
# 北京與新加坡地區的 API Key 不同。擷取 API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 未配置環境變數時,將下行替換為:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# 以下為新加坡地區URL,調用時請將WorkspaceId替換為真實的業務空間ID,各地區的URL不同。
dashscope.base_http_api_url = 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1'
# 以下為新加坡地區WebSocket URL,調用時請將WorkspaceId替換為真實的業務空間ID,各地區的URL不同。
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": "語音實驗室", "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:
# 無論識別成功與否都刪除熱詞列表,避免佔用配額
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 {
// 北京與新加坡地區的 API Key 不同。擷取 API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// 未配置環境變數時,將下行替換為:public static String apiKey = "sk-xxx"
public static String apiKey = System.getenv("DASHSCOPE_API_KEY");
public static void main(String[] args) throws NoApiKeyException, InputRequiredException {
// 以下為新加坡地區URL,調用時請將WorkspaceId替換為真實的業務空間ID,各地區的URL不同。
Constants.baseHttpApiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
// 以下為新加坡地區WebSocket URL,調用時請將WorkspaceId替換為真實的業務空間ID,各地區的URL不同。
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("語音實驗室", 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("識別結果:" + recognizer.call(param, new File("asr_example.wav")));
} catch (Exception e) {
e.printStackTrace();
} finally {
// 關閉 WebSocket 串連
recognizer.getDuplexApi().close(1000, "bye");
}
}
} finally {
// 無論識別成功與否都刪除熱詞列表,避免佔用配額
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;
}
}
熱詞格式
熱詞以 JSON 數組提交,數組元素定義單個熱詞及其屬性。
樣本:提升電影名稱的識別率。
[
{"text": "賽德克巴萊", "weight": 4, "lang": "zh"},
{"text": "Seediq Bale", "weight": 4, "lang": "en"},
{"text": "夏洛特煩惱", "weight": 4, "lang": "zh"},
{"text": "Goodbye Mr. Loser", "weight": 4, "lang": "en"},
{"text": "闕裡人家", "weight": 4, "lang": "zh"},
{"text": "Confucius' Family", "weight": 4, "lang": "en"}
]
欄位說明:
|
欄位 |
類型 |
是否必填 |
說明 |
|
text |
string |
是 |
熱詞文本,需為實際詞語而非任一字元組合,且語言必須在所選模型的支援範圍內。長度限制參見熱詞文本規範。 |
|
weight |
int |
是 |
熱詞權重。取值範圍 [1, 5],推薦 4。權重越高,模型越傾向於輸出該詞。調優參見調整熱詞權重。 |
|
lang |
string |
否 |
語言代碼,限定該熱詞作用的語種。語種未知時可省略。 注意: |
熱詞文本規範
熱詞文本必須為實際詞語,長度限制如下:
-
含非 ASCII 字元時:總字元數(漢字、日文假名、韓文諺文、西裡爾字母等非 ASCII 字元與 ASCII 字元合計)不超過 15 個。
樣本:
-
✅
"厄洛替尼鹽酸鹽"(7 字元) -
✅
"EGFR抑製劑"(7 字元,其中 EGFR 占 4 個 ASCII 字元) -
✅
"こんにちは"(5 字元) -
✅
"Фенибут Белфарм"(15 字元,含中間空格) -
❌
"Клофелин Белмедпрепараты"(24 字元)
-
-
純 ASCII 字元時:按空格切分後的片段數不超過 7 個。
樣本:
-
✅
"Exothermic reaction"→ 2 個片段 -
✅
"Human immunodeficiency virus type 1"→ 5 個片段 -
❌
"The effect of temperature variations on enzyme activity in biochemical reactions"→ 11 個片段
-
調優熱詞效果
調整熱詞權重
權重控制模型對熱詞的偏好程度,合理設定可在提升目標詞識別率的同時避免誤識別。
|
權重 |
效果 |
適用情境 |
|
1~2 |
輕微偏好 |
熱詞與常用詞發音相似,需避免過度糾偏 |
|
3~4 |
明顯偏好(推薦) |
大多數情境的最佳起始值 |
|
5 |
強制偏好 |
該詞在音頻中頻繁出現且幾乎不會與其他詞混淆。權重過高可能導致發音相近的其他詞被錯誤識別為熱詞。 |
建議從 weight=4 起測,根據識別效果逐步調整。
設計熱詞表
-
按情境分組:為不同業務情境建立獨立的熱詞列表(如醫學術語、產品名稱各建一個),便於維護與複用。
-
多語種混合:同一熱詞列表可混入不同語種的熱詞,通過
lang欄位區分。語音辨識時指定language_hints後,僅匹配該語種的熱詞生效。 -
定期清理:刪除不再使用的熱詞列表以釋放額度(每帳號上限 10 個)。
限制與計費
|
限制項 |
說明 |
|
熱詞列表數量 |
每帳號 10 個,所有模型共用。 |
|
單個列表熱詞數 |
每個熱詞列表最多 500 個熱詞。 |
|
計費 |
免費。 |
API 參考:定製熱詞 API 參考
上下文增強
支援的模型與地區
新加坡
調用以下模型時,請選擇新加坡地區的API Key:
Fun-ASR:
-
非即時語音辨識:fun-asr-flash-2026-06-15
華北2(北京)
調用以下模型時,請選擇北京地區的API Key:
Fun-ASR:
-
非即時語音辨識:fun-asr-flash-2026-06-15
快速開始
使用情境:通過 input.messages 傳入上下文資訊,可顯著提升專有詞彙(人名、地名、產品術語等)的轉寫準確率。適用於以下情境:
-
詞表增強:識別單條音頻時,通過
user(input_text)傳入領域相關的詞表或術語,協助模型準確識別專業詞彙。 -
多輪對話上下文:在 ASR 與大語言模型結合的語音互動情境中,將前幾輪的識別結果(
user/input_text)和大模型回複(assistant/text)傳入,利用對話歷史提升當前輪次的識別準確率。
用法
通過 input.messages 傳入上下文。其中 user 角色 + input_text 類型用於傳入前幾輪的識別結果或領域相關的詞表,assistant 角色用於傳入前幾輪大模型的回複內容(可選)。上下文訊息置於音頻訊息之前,詳見DashScope同步調用(Fun-ASR-Flash)。
-
訊息條數限制:引擎最多保留最近 5 輪的上下文內容。詞表增強通常只需 1 條訊息,不受此限制影響。超出時,早期訊息會被自動忽略,不會報錯。
-
文本長度限制:每輪內容相關的文本總長度(同一輪中所有
user和assistant訊息的text欄位長度之和)不超過 400 個字元(按字元數計算,每個字元計為 1,包括字母、漢字、數字、空格和標點等)。超出部分會從末尾截斷,不會返回錯誤。多輪上下文中,每輪獨立計算,互不影響。 -
上下文機制:上下文通過詞表匹配方式生效,
text欄位中需包含音頻裡待識別的原詞(如"Kubernetes"、"Bulge Bracket")。僅傳入語義相關但不包含原詞的描述不會生效。
詞表增強
通過 user(input_text)傳入領域術語詞表,無需 assistant 訊息。
{
"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": "當前待識別的音頻URL或Base64"
}
}
]
}
]
},
"parameters": {}
}
多輪對話上下文
傳入前幾輪的識別結果(user / input_text)和大模型回複(assistant / text)。
{
"model": "fun-asr-flash-2026-06-15",
"input": {
"messages": [
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "前輪使用者語音的識別結果"
}
]
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "前輪大模型的回複內容"
}
]
},
{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": "當前待識別的音頻URL或Base64"
}
}
]
}
]
},
"parameters": {}
}
效果樣本
內容相關的 text 欄位內容格式靈活,可以是詞表、自然語言段落或兩者的混合,對無關文本的容錯性極高。
某段音頻正確識別結果應該為“投行圈內部的那些黑話,你瞭解哪些?首先,外資九大投行,Bulge Bracket,BB ...”。
|
不使用上下文增強 未使用上下文增強時,部分投行公司名稱識別有誤,例如 “Bird Rock” 正確應為 “Bulge Bracket”。 識別結果:“投行圈內部的那些黑話,你瞭解哪些?首先,外資九大投行,Bird Rock,BB ...” |
使用上下文增強 使用上下文增強,對投行公司名稱識別正確。 識別結果:“投行圈內部的那些黑話,你瞭解哪些?首先,外資九大投行,Bulge Bracket,BB ...” |
上述樣本中,在內容相關的 text 欄位中加入包含"Bulge Bracket"等專業術語的詞表或自然語言段落即可實現增強效果。
常見問題
Q:設定熱詞後識別效果沒有改善?
依次排查:
-
模型是否匹配:建立時指定的
target_model必須與語音辨識介面使用的模型一致。兩者不一致時介面不會報錯,識別仍能返回結果,但熱詞不生效;識別結果未命中預期熱詞時應優先排查此項。 -
模型是否支援:模型必須為 Fun-ASR 或 Paraformer 系列,其他系列不支援熱詞。在不支援的系列上調用時介面同樣不會報錯,但識別結果可能為空白或不含熱詞增強;使用 SenseVoice 等系列時應優先排查此項。
-
權重是否合適:將權重從 4 提到 5 觀察效果。如果出現發音相近的其他詞被誤識別為熱詞,回調到 4。
-
熱詞列表狀態:通過查詢介面確認
status為OK。
Q:熱詞在即時和非即時語音辨識中的使用方式是否相同?
建立方式相同,調用時存在差異:
-
即時語音辨識:在 Recognition 或 WebSocket 串連參數中傳入
vocabulary_id。 -
錄音檔案識別:在 Transcription 請求參數中傳入
vocabulary_id。
兩種情境的 target_model 都必須與實際調用的語音辨識模型一致。
Q:除了熱詞和上下文增強,還有哪些方式可以提升識別準確率?
還可從以下方向最佳化:
-
音頻品質:採樣率匹配模型要求(16 kHz 或 8 kHz),降低背景雜訊。
-
選擇合適的模型:不同情境適用模型不同,詳見語音辨識選型指南。
-
指定語種:通過
language_hints聲明音頻語種,可提升單語種情境的準確率。