diff --git a/main/manager-api/src/main/resources/db/changelog/202604211700.sql b/main/manager-api/src/main/resources/db/changelog/202604211700.sql new file mode 100644 index 00000000..1f5f0d37 --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202604211700.sql @@ -0,0 +1,45 @@ +-- 修复豆包语音合成模型2.0 provider_code 重复问题,添加 ASR 2.0 支持 + +-- ==================== 豆包语音合成模型2.0 ==================== +-- 删除 TTS 2.0 供应器(不再需要单独的供应器) +delete from `ai_model_provider` where id = 'SYSTEM_TTS_HSDSTTS_V2'; + +-- ==================== 豆包语音识别(流式) ==================== +-- 修正原有豆包语音识别(流式)供应器,移除cluster字段,添加resource_id字段 +UPDATE `ai_model_provider` SET `fields` = '[{"key":"appid","type":"string","label":"应用ID"},{"key":"access_token","type":"string","label":"访问令牌"},{"key":"boosting_table_name","type":"string","label":"热词文件名称"},{"key":"correct_table_name","type":"string","label":"替换词文件名称"},{"key":"output_dir","type":"string","label":"输出目录"},{"key":"end_window_size","type":"number","label":"静音判定时长(ms)"},{"key":"enable_multilingual","type":"boolean","label":"是否开启多语种识别模式"},{"key":"language","type":"string","label":"指定语言编码"},{"key":"resource_id","type":"string","label":"资源ID"}]' WHERE `id` = 'SYSTEM_ASR_DoubaoStreamASR'; + +-- 修正原有豆包语音识别(流式)配置,移除cluster字段,添加resource_id默认值 +UPDATE `ai_model_config` SET `config_json` = JSON_REMOVE(JSON_SET(`config_json`, '$.resource_id', 'volc.bigasr.sauc.duration'), '$.cluster') WHERE `id` = 'ASR_DoubaoStreamASR'; + +-- ==================== 豆包语音识别模型2.0 ==================== + +-- 插入豆包语音识别模型2.0配置 +delete from `ai_model_config` where id = 'ASR_DoubaoStreamASRV2'; +INSERT INTO `ai_model_config` VALUES ('ASR_DoubaoStreamASRV2', 'ASR', 'DoubaoStreamASRV2', '豆包语音识别模型2.0', 0, 1, '{ + "type": "doubao_stream", + "appid": "", + "access_token": "", + "resource_id": "volc.seedasr.sauc.duration", + "end_window_size": 200, + "enable_multilingual": false, + "language": "zh-CN", + "output_dir": "tmp/" +}', NULL, NULL, 6, NULL, NULL, NULL, NULL); + +-- 豆包语音识别模型2.0配置说明文档 +UPDATE `ai_model_config` SET +`doc_link` = 'https://www.volcengine.com/docs/6561/109979', +`remark` = '豆包语音识别模型2.0配置说明(基于火山引擎seed-asr): +1. 访问 https://www.volcengine.com/ 注册并开通火山引擎账号 +2. 访问 https://console.volcengine.com/speech/service/10038 开通豆包流式语音识别模型2.0 +3. 在页面底部获取appid和access_token +4. 资源ID有两种:小时版(volc.seedasr.sauc.duration)和并发版(volc.seedasr.sauc.concurrent) + - 小时版:固定为:volc.seedasr.sauc.duration(豆包语音识别模型2.0) + - 并发版:固定为:volc.seedasr.sauc.concurrent(豆包语音识别模型2.0) + +详细参数文档:https://www.volcengine.com/docs/6561/109979 + +注意: +- 豆包语音识别模型2.0使用volc.seedasr.sauc.duration资源ID,与豆包语音识别(流式)(volc.bigasr.sauc.duration)不同 +- 语音识别模型2.0价格更为便宜,建议在高并发场景下使用并发版资源ID +' WHERE `id` = 'ASR_DoubaoStreamASRV2'; diff --git a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml index 9770b029..dff9e0ea 100755 --- a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml @@ -620,3 +620,10 @@ databaseChangeLog: - sqlFile: encoding: utf8 path: classpath:db/changelog/202604201719.sql + - changeSet: + id: 202604211700 + author: RanChen + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202604211700.sql diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml index cc4df131..e82d15f0 100644 --- a/main/xiaozhi-server/config.yaml +++ b/main/xiaozhi-server/config.yaml @@ -396,7 +396,28 @@ ASR: type: doubao_stream appid: 你的火山引擎语音合成服务appid access_token: 你的火山引擎语音合成服务access_token - cluster: volcengine_input_common + # 资源ID:小时版 volc.bigasr.sauc.duration,并发版 volc.bigasr.sauc.concurrent + resource_id: volc.bigasr.sauc.duration + # 热词、替换词使用流程:https://www.volcengine.com/docs/6561/155738 + boosting_table_name: (选填)你的热词文件名称 + correct_table_name: (选填)你的替换词文件名称 + # 是否开启多语种识别模式 + enable_multilingual: False + # 多语种识别当该键为空时,该模型支持中英文、上海话、闽南语,四川、陕西、粤语识别。当将其设置为特定键时,它可以识别指定语言。 + # 详细语言列表参考 https://www.volcengine.com/docs/6561/1354869 + # language: zh-cn + # 静音判定时长(ms),默认200ms + end_window_size: 200 + output_dir: tmp/ + DoubaoStreamASRV2: + # 豆包语音识别模型2.0(基于火山引擎seed-asr) + # 开通地址:https://console.volcengine.com/speech/service/10038 + # 价格更为便宜,建议在高并发场景下使用 + type: doubao_stream + appid: 你的火山引擎语音合成服务appid + access_token: 你的火山引擎语音合成服务access_token + # 资源ID:小时版 volc.seedasr.sauc.duration,并发版 volc.seedasr.sauc.concurrent + resource_id: volc.seedasr.sauc.duration # 热词、替换词使用流程:https://www.volcengine.com/docs/6561/155738 boosting_table_name: (选填)你的热词文件名称 correct_table_name: (选填)你的替换词文件名称 diff --git a/main/xiaozhi-server/core/providers/asr/doubao_stream.py b/main/xiaozhi-server/core/providers/asr/doubao_stream.py index a1d520de..d9a36f4d 100644 --- a/main/xiaozhi-server/core/providers/asr/doubao_stream.py +++ b/main/xiaozhi-server/core/providers/asr/doubao_stream.py @@ -29,8 +29,10 @@ class ASRProvider(ASRProviderBase): # 配置参数 self.appid = str(config.get("appid")) - self.cluster = config.get("cluster") self.access_token = config.get("access_token") + # 资源ID,用于区分不同的ASR模型(默认1.0模型小时版,v2版本使用seed-asr) + self.resource_id = config.get("resource_id", "volc.bigasr.sauc.duration") + self.boosting_table_name = config.get("boosting_table_name", "") self.correct_table_name = config.get("correct_table_name", "") self.output_dir = config.get("output_dir", "tmp/") @@ -44,7 +46,7 @@ class ASRProvider(ASRProviderBase): if self.enable_multilingual: self.ws_url = "wss://openspeech.bytedance.com/api/v3/sauc/bigmodel_nostream" else: - self.ws_url = "wss://openspeech.bytedance.com/api/v3/sauc/bigmodel" + self.ws_url = "wss://openspeech.bytedance.com/api/v3/sauc/bigmodel_async" self.uid = config.get("uid", "streaming_asr_service") self.workflow = config.get( "workflow", "audio_in,resample,partition,vad,fe,decode,itn,nlu_punctuate" @@ -283,7 +285,6 @@ class ASRProvider(ASRProviderBase): req = { "app": { "appid": self.appid, - "cluster": self.cluster, "token": self.access_token, }, "user": {"uid": self.uid}, @@ -322,7 +323,7 @@ class ASRProvider(ASRProviderBase): return { "X-Api-App-Key": self.appid, "X-Api-Access-Key": self.access_token, - "X-Api-Resource-Id": "volc.bigasr.sauc.duration", + "X-Api-Resource-Id": self.resource_id, "X-Api-Connect-Id": str(uuid.uuid4()), } @@ -385,9 +386,17 @@ class ASRProvider(ASRProviderBase): "payload_msg": error_msg, } - # 获取JSON数据(跳过12字节头部) + # 获取JSON数据 try: - json_data = res[12:].decode("utf-8") + # 检查字节8-11是否为有效的JSON长度字段 + # 格式:4字节头 + 4字节序列号 + 4字节长度 + JSON数据 + length = int.from_bytes(res[8:12], "big") + if length > 0 and length <= len(res) - 12: + # 有长度字段,从字节12开始读取指定长度的JSON + json_data = res[12:12 + length].decode("utf-8") + else: + # 无长度字段或长度无效,尝试直接解析 + json_data = res[8:].decode("utf-8") result = json.loads(json_data) logger.bind(tag=TAG).debug(f"成功解析JSON响应: {result}") return {"payload_msg": result}