Skip to content

Commit 9cac6c4

Browse files
committed
feat: add Tencent Tokenhub ASR sync_transcribe credential and enhance verification code handling
1 parent 547772a commit 9cac6c4

7 files changed

Lines changed: 368 additions & 25 deletions

File tree

‎apps/locales/en_US/LC_MESSAGES/django.po‎

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8732,7 +8732,6 @@ msgstr ""
87328732
msgid "generate prompt"
87338733
msgstr ""
87348734

8735-
87368735
msgid "Watermark"
87378736
msgstr ""
87388737

@@ -9605,3 +9604,45 @@ msgstr ""
96059604

96069605
msgid "Get portal historical conversation by page"
96079606
msgstr ""
9607+
9608+
msgid "Too many verification code attempts, please try again later"
9609+
msgstr ""
9610+
9611+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:18
9612+
msgid "Recognition language"
9613+
msgstr ""
9614+
9615+
9616+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:18
9617+
msgid "Recognition language: zh / en, auto detected when omitted"
9618+
msgstr ""
9619+
9620+
9621+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:22
9622+
msgid "Auto detect"
9623+
msgstr ""
9624+
9625+
9626+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:23
9627+
msgid "Chinese"
9628+
msgstr ""
9629+
9630+
9631+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:30
9632+
msgid "Audio encoding"
9633+
msgstr ""
9634+
9635+
9636+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:30
9637+
msgid "pcm / wav / ogg / mp3, auto detected when omitted"
9638+
msgstr ""
9639+
9640+
9641+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:34
9642+
msgid "Auto"
9643+
msgstr ""
9644+
9645+
9646+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:76
9647+
msgid "Tokenhub sync_transcribe endpoint"
9648+
msgstr ""

‎apps/locales/zh_CN/LC_MESSAGES/django.po‎

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8837,7 +8837,6 @@ msgstr "系统资源授权"
88378837
msgid "This folder contains resources that you dont have permission"
88388838
msgstr "此文件夹包含您没有权限的资源"
88398839

8840-
88418840
msgid "Text to Video"
88428841
msgstr "文生视频"
88438842

@@ -9588,7 +9587,6 @@ msgstr "角色管理"
95889587
msgid "Chat User Group"
95899588
msgstr "对话用户组"
95909589

9591-
95929590
msgid "Create or update Workspace User Group"
95939591
msgstr "创建或更新工作空间用户组"
95949592

@@ -9747,4 +9745,46 @@ msgstr "分页获取门户历史会话"
97479745

97489746
#: apps/xpack/views/system_chat_user.py:101
97499747
msgid "Batch set chat user quota"
9750-
msgstr "批量设置对话用户配额"
9748+
msgstr "批量设置对话用户配额"
9749+
9750+
msgid "Too many verification code attempts, please try again later"
9751+
msgstr "验证码尝试次数过多,请稍后重试"
9752+
9753+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:18
9754+
msgid "Recognition language"
9755+
msgstr "识别语言"
9756+
9757+
9758+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:18
9759+
msgid "Recognition language: zh / en, auto detected when omitted"
9760+
msgstr "识别语言:zh / en,缺省时自动检测"
9761+
9762+
9763+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:22
9764+
msgid "Auto detect"
9765+
msgstr "自动检测"
9766+
9767+
9768+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:23
9769+
msgid "Chinese"
9770+
msgstr "中文"
9771+
9772+
9773+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:30
9774+
msgid "Audio encoding"
9775+
msgstr "音频编码"
9776+
9777+
9778+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:30
9779+
msgid "pcm / wav / ogg / mp3, auto detected when omitted"
9780+
msgstr "pcm / wav / ogg / mp3,缺省时自动检测"
9781+
9782+
9783+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:34
9784+
msgid "Auto"
9785+
msgstr "自动"
9786+
9787+
9788+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:76
9789+
msgid "Tokenhub sync_transcribe endpoint"
9790+
msgstr "Tokenhub 同步转写接口地址"

‎apps/locales/zh_Hant/LC_MESSAGES/django.po‎

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8837,7 +8837,6 @@ msgstr "系統資源授權"
88378837
msgid "This folder contains resources that you dont have permission"
88388838
msgstr "此資料夾包含您沒有許可權的資源"
88398839

8840-
88418840
msgid "Text to Video"
88428841
msgstr "文生視頻"
88438842

@@ -9702,7 +9701,6 @@ msgstr "刪除對話用戶 API 密鑰"
97029701
msgid "Quota Setting"
97039702
msgstr "配額設置"
97049703

9705-
97069704
#: apps/xpack/serializers/chat_user.py:746
97079705
msgid "Quota mode"
97089706
msgstr "配額模式"
@@ -9743,4 +9741,47 @@ msgid "The token quota for the current period has been exhausted. Please contact
97439741
msgstr "當前週期 Tokens 配額已用盡,請聯繫管理員。"
97449742

97459743
msgid "Get portal historical conversation by page"
9746-
msgstr "分頁獲取門戶歷史會話"
9744+
msgstr "分頁獲取門戶歷史會話"
9745+
9746+
msgid "Too many verification code attempts, please try again later"
9747+
msgstr "驗證碼嘗試次數過多,請稍後重試"
9748+
9749+
9750+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:18
9751+
msgid "Recognition language"
9752+
msgstr "識別語言"
9753+
9754+
9755+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:18
9756+
msgid "Recognition language: zh / en, auto detected when omitted"
9757+
msgstr "識別語言:zh / en,缺省時自動檢測"
9758+
9759+
9760+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:22
9761+
msgid "Auto detect"
9762+
msgstr "自動檢測"
9763+
9764+
9765+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:23
9766+
msgid "Chinese"
9767+
msgstr "中文"
9768+
9769+
9770+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:30
9771+
msgid "Audio encoding"
9772+
msgstr "音頻編碼"
9773+
9774+
9775+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:30
9776+
msgid "pcm / wav / ogg / mp3, auto detected when omitted"
9777+
msgstr "pcm / wav / ogg / mp3,缺省時自動檢測"
9778+
9779+
9780+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:34
9781+
msgid "Auto"
9782+
msgstr "自動"
9783+
9784+
9785+
#: apps/models_provider/impl/tencent_model_provider/credential/tokenhub_stt.py:76
9786+
msgid "Tokenhub sync_transcribe endpoint"
9787+
msgstr "Tokenhub 同步轉寫接口地址"
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# coding=utf-8
2+
"""
3+
@project: MaxKB
4+
@desc: Tencent Tokenhub ASR sync_transcribe credential (model: wand-asr-v1 / hy-asr-3.0-preview)
5+
"""
6+
7+
from django.utils.translation import gettext_lazy as _, gettext
8+
9+
from common import forms
10+
from common.exception.app_exception import AppApiException
11+
from common.forms import BaseForm, TooltipLabel
12+
from common.utils.logger import maxkb_logger
13+
from models_provider.base_model_provider import BaseModelCredential, ValidCode
14+
15+
16+
class TencentTokenhubSTTModelParams(BaseForm):
17+
source = forms.SingleSelect(
18+
label=TooltipLabel(_("Recognition language"), _("Recognition language: zh / en, auto detected when omitted")),
19+
text_field="value",
20+
value_field="value",
21+
option_list=[
22+
{"value": "", "label": _("Auto detect")},
23+
{"value": "zh", "label": _("Chinese")},
24+
{"value": "en", "label": _("English")},
25+
],
26+
required=False,
27+
default_value="",
28+
)
29+
voice_encode_format = forms.SingleSelect(
30+
label=TooltipLabel(_("Audio encoding"), _("pcm / wav / ogg / mp3, auto detected when omitted")),
31+
text_field="value",
32+
value_field="value",
33+
option_list=[
34+
{"value": "", "label": _("Auto")},
35+
{"value": "pcm", "label": "pcm"},
36+
{"value": "wav", "label": "wav"},
37+
{"value": "ogg", "label": "ogg"},
38+
{"value": "mp3", "label": "mp3"},
39+
],
40+
required=False,
41+
default_value="",
42+
)
43+
44+
45+
class TencentTokenhubSTTModelCredential(BaseForm, BaseModelCredential):
46+
def is_valid(self, model_type, model_name, model_credential, model_params, provider, raise_exception=False):
47+
model_type_list = provider.get_model_type_list()
48+
if not any(list(filter(lambda mt: mt.get("value") == model_type, model_type_list))):
49+
raise AppApiException(
50+
ValidCode.valid_error.value,
51+
gettext("{model_type} Model type is not supported").format(model_type=model_type),
52+
)
53+
if "api_key" not in model_credential:
54+
if raise_exception:
55+
raise AppApiException(ValidCode.valid_error.value, gettext("{key} is required").format(key="api_key"))
56+
return False
57+
try:
58+
model = provider.get_model(model_type, model_name, model_credential, **model_params)
59+
model.check_auth()
60+
except Exception as e:
61+
maxkb_logger.error(f"Exception: {e}", exc_info=True)
62+
if raise_exception:
63+
raise AppApiException(
64+
ValidCode.valid_error.value,
65+
gettext("Verification failed, please check whether the parameters are correct: {error}").format(
66+
error=str(e)
67+
),
68+
)
69+
return False
70+
return True
71+
72+
def encryption_dict(self, model):
73+
return {**model, "api_key": super().encryption(model.get("api_key", ""))}
74+
75+
base_url = forms.TextInputField(
76+
label=TooltipLabel(_("API URL"), _("Tokenhub sync_transcribe endpoint")),
77+
required=False,
78+
default_value="https://tokenhub.tencentmaas.com/v1/wand/asrproxy/sync_transcribe",
79+
)
80+
api_key = forms.PasswordInputField(_("API Key"), required=True)
81+
82+
def get_model_params_setting_form(self, model_name):
83+
return TencentTokenhubSTTModelParams()

‎apps/models_provider/impl/tencent_model_provider/model/stt.py‎

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
import json
33
import os
44
import traceback
5-
from typing import Dict
5+
6+
import requests
7+
from typing import Dict, Optional
68

79
from tencentcloud.asr.v20190614 import asr_client, models
810
from tencentcloud.common import credential
@@ -81,3 +83,72 @@ def speech_to_text(self, audio_file):
8183
except TencentCloudSDKException as err:
8284
maxkb_logger.error(f":Error: {str(err)}: {traceback.format_exc()}")
8385
raise err
86+
87+
88+
DEFAULT_WAND_BASE_URL = "https://tokenhub.tencentmaas.com/v1/wand/asrproxy/sync_transcribe"
89+
90+
91+
class TencentWandSpeechToText(MaxKBBaseModel, BaseSpeechToText):
92+
api_key: str
93+
model: str
94+
params: dict
95+
base_url: Optional[str] = DEFAULT_WAND_BASE_URL
96+
97+
def __init__(self, **kwargs):
98+
super().__init__(**kwargs)
99+
self.api_key = kwargs.get("api_key")
100+
self.model = kwargs.get("model")
101+
self.params = kwargs.get("params") or {}
102+
self.base_url = kwargs.get("base_url") or DEFAULT_WAND_BASE_URL
103+
104+
@staticmethod
105+
def is_cache_model():
106+
return False
107+
108+
@staticmethod
109+
def new_instance(model_type, model_name, model_credential: Dict[str, object], **model_kwargs):
110+
instance_kwargs = {
111+
"api_key": model_credential.get("api_key"),
112+
"model": model_name,
113+
"params": model_kwargs,
114+
**model_kwargs,
115+
}
116+
base_url = model_credential.get("base_url")
117+
if base_url:
118+
instance_kwargs["base_url"] = base_url
119+
return TencentWandSpeechToText(**instance_kwargs)
120+
121+
def check_auth(self):
122+
cwd = os.path.dirname(os.path.abspath(__file__))
123+
with open(f"{cwd}/iat_mp3_16k.mp3", "rb") as f:
124+
self.speech_to_text(f)
125+
126+
def speech_to_text(self, audio_file):
127+
try:
128+
payload = {"model": self.model}
129+
# 仅使用上传音频文件的 base64 data,不提供 input_url 兜底
130+
audio_data = audio_file.read()
131+
payload["data"] = base64.b64encode(audio_data).decode("utf-8")
132+
for key in ("source", "voice_encode_format"):
133+
if self.params.get(key):
134+
payload[key] = self.params[key]
135+
136+
headers = {
137+
"Authorization": f"Bearer {self.api_key}",
138+
"Content-Type": "application/json",
139+
}
140+
response = requests.post(self.base_url, headers=headers, json=payload, timeout=300)
141+
response.raise_for_status()
142+
result = response.json()
143+
if result.get("status") != "completed":
144+
maxkb_logger.error(f"WAND ASR task not completed: {result}")
145+
raise Exception(f"WAND ASR task not completed: {result}")
146+
output = result.get("output") or {}
147+
text = output.get("text")
148+
if not text:
149+
sentences = output.get("sentences") or []
150+
text = " ".join([s.get("text", "") for s in sentences if s.get("text")])
151+
return text
152+
except Exception as e:
153+
maxkb_logger.error(f"WAND ASR Error: {str(e)}: {traceback.format_exc()}")
154+
raise e

‎apps/models_provider/impl/tencent_model_provider/tencent_model_provider.py‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
from models_provider.impl.tencent_model_provider.credential.image import TencentVisionModelCredential
1515
from models_provider.impl.tencent_model_provider.credential.llm import TencentLLMModelCredential
1616
from models_provider.impl.tencent_model_provider.credential.stt import TencentSTTModelCredential
17+
from models_provider.impl.tencent_model_provider.credential.tokenhub_stt import TencentTokenhubSTTModelCredential
1718
from models_provider.impl.tencent_model_provider.credential.tti import TencentTTIModelCredential
1819
from models_provider.impl.tencent_model_provider.model.embedding import TencentEmbeddingModel
1920
from models_provider.impl.tencent_model_provider.model.image import TencentVision
2021
from models_provider.impl.tencent_model_provider.model.llm import TencentModel
21-
from models_provider.impl.tencent_model_provider.model.stt import TencentSpeechToText
22+
from models_provider.impl.tencent_model_provider.model.stt import TencentSpeechToText, TencentWandSpeechToText
2223
from models_provider.impl.tencent_model_provider.model.tti import TencentTextToImageModel
2324
from maxkb.conf import PROJECT_DIR
2425
from django.utils.translation import gettext as _
@@ -105,6 +106,12 @@ def _initialize_model_info():
105106
TencentSTTModelCredential,
106107
TencentSpeechToText,
107108
),
109+
_create_model_info(
110+
"wand-asr-v1", _(""), ModelTypeConst.STT, TencentTokenhubSTTModelCredential, TencentWandSpeechToText
111+
),
112+
_create_model_info(
113+
"hy-asr-3.0-preview", _(""), ModelTypeConst.STT, TencentTokenhubSTTModelCredential, TencentWandSpeechToText
114+
),
108115
]
109116

110117
tencent_embedding_model_info = _create_model_info(
@@ -162,6 +169,12 @@ def __init__(self):
162169
def get_model_info_manage(self):
163170
return self._model_info_manage
164171

172+
def get_model(self, model_type, model_name, model_credential, **model_kwargs):
173+
# STT 模型:模型名不以 asr- 开头的一律走 Tencent Tokenhub WAND 识别
174+
if model_type == ModelTypeConst.STT.name and not model_name.startswith("asr-"):
175+
return TencentWandSpeechToText.new_instance(model_type, model_name, model_credential, **model_kwargs)
176+
return super().get_model(model_type, model_name, model_credential, **model_kwargs)
177+
165178
def get_model_provide_info(self):
166179
icon_path = _get_tencent_icon_path()
167180
icon_data = get_file_content(icon_path)

0 commit comments

Comments
 (0)