自定义热词

更新时间:
复制为 MD 格式

通过预定义词汇表,提升语音识别中专业术语、产品名称等特定词汇的准确率。本文介绍热词的创建与使用方法。

重要

新加坡地域的子业务空间暂不支持热词功能。

概述

部分业务词汇(如产品名、专有名词、行业术语)不在模型通用词表中,识别准确率较低。提交一份热词列表后,模型在解码时优先匹配列表中的词,从而提升这些词的识别准确率。

热词格式

热词以 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

语言代码,限定该热词作用的语种。语种未知时可省略。

注意:language_hints 是语音识别接口的参数(非热词接口),用于声明音频语种。一旦设置,仅匹配 language_hints 所指定语种的热词生效,其他语种的热词将被忽略。

前提条件

快速开始

工作流程

先创建热词列表,再在语音识别时引用其 ID:

  1. 创建热词列表。

    调用创建热词列表接口,必须指定 target_model(Java 中为 targetModel),表明该列表所属的语音识别模型。

    如已有热词列表(可通过查询所有热词列表接口查看),跳过此步。

  2. 调用语音识别接口并传入热词列表 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://help.aliyun.com/zh/model-studio/get-api-key
# 未配置环境变量时,将下行替换为:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')

# 北京地域 URL;新加坡地域改为:https://dashscope-intl.aliyuncs.com/api/v1
dashscope.base_http_api_url = 'https://dashscope.aliyuncs.com/api/v1'

# 北京地域 WebSocket URL;新加坡地域改为:wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url = 'wss://dashscope.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://help.aliyun.com/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;新加坡地域改为:https://dashscope-intl.aliyuncs.com/api/v1
        Constants.baseHttpApiUrl = "https://dashscope.aliyuncs.com/api/v1";
        // 北京地域 WebSocket URL;新加坡地域改为:wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference
        Constants.baseWebsocketApiUrl = "wss://dashscope.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;
    }
}

进阶用法

调整热词权重

权重控制模型对热词的偏好程度,合理设置可在提升目标词识别率的同时避免误识别。

权重

效果

适用场景

1~2

轻微偏好

热词与常用词发音相似,需避免过度纠偏

3~4

明显偏好(推荐)

大多数场景的最佳起始值

5

强制偏好

该词在音频中频繁出现且几乎不会与其他词混淆。权重过高可能导致发音相近的其他词被错误识别为热词。

建议从 weight=4 起测,根据识别效果逐步调整。

热词文本规范

热词文本必须为实际词语,长度限制如下:

  • 含非 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 个片段

设计热词表

  • 按场景分组:为不同业务场景建立独立的热词列表(如医疗术语、产品名称各建一个),便于维护与复用。

  • 多语种混合:同一热词列表可混入不同语种的热词,通过 lang 字段区分。语音识别时指定 language_hints 后,仅匹配该语种的热词生效。

  • 定期清理:删除不再使用的热词列表以释放额度(每账号上限 10 个)。

限制与计费

限制项

说明

热词列表数量

每账号 10 个,所有模型共享。需要扩容时提交工单申请。

单个列表热词数

每个热词列表最多 500 个热词。

计费

免费。

适用范围

不同服务部署范围支持的模型不同

中国内地(北京)

  • Fun-ASR:

    • 实时语音识别:fun-asr-realtime、fun-asr-realtime-2026-02-28、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

国际(新加坡)

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

API 参考

定制热词 API 参考

常见问题

Q:设置热词后识别效果没有改善?

依次排查:

  1. 模型是否匹配:创建时指定的 target_model 必须与语音识别接口使用的模型一致。两者不一致时接口不会报错,识别仍能返回结果,但热词不生效;识别结果未命中预期热词时应优先排查此项。

  2. 模型是否支持:模型必须为 Fun-ASR 或 Paraformer 系列,其他系列不支持热词。在不支持的系列上调用时接口同样不会报错,但识别结果可能为空或不含热词增强;使用 SenseVoice 等系列时应优先排查此项。

  3. 权重是否合适:将权重从 4 提到 5 观察效果。如果出现发音相近的其他词被误识别为热词,回调到 4。

  4. 热词列表状态:通过查询接口确认 statusOK

Q:热词在实时和非实时语音识别中的使用方式是否相同?

创建方式相同,调用时存在差异:

  • 实时语音识别:在 Recognition 或 WebSocket 连接参数中传入 vocabulary_id

  • 录音文件识别:在 Transcription 请求参数中传入 vocabulary_id

两种场景的 target_model 都必须与实际调用的语音识别模型一致。

Q:如何提升识别准确率?

除热词外,可从以下方向优化:

  • 音频质量:采样率匹配模型要求(16 kHz 或 8 kHz),降低背景噪声。

  • 选择合适的模型:不同场景适用模型不同,详见语音识别选型指南。

  • 指定语种:通过 language_hints 声明音频语种,可提升单语种场景的准确率。