first commit
This commit is contained in:
commit
7f50380e52
0
app/README.md
Normal file
0
app/README.md
Normal file
BIN
app/__pycache__/asyncproxy.cpython-310.pyc
Normal file
BIN
app/__pycache__/asyncproxy.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/const.cpython-310.pyc
Normal file
BIN
app/__pycache__/const.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/ext.cpython-310.pyc
Normal file
BIN
app/__pycache__/ext.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/llm_client.cpython-310.pyc
Normal file
BIN
app/__pycache__/llm_client.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/rf.cpython-310.pyc
Normal file
BIN
app/__pycache__/rf.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/streamproxy.cpython-310.pyc
Normal file
BIN
app/__pycache__/streamproxy.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/syncproxy.cpython-310.pyc
Normal file
BIN
app/__pycache__/syncproxy.cpython-310.pyc
Normal file
Binary file not shown.
40
app/asr.py
Normal file
40
app/asr.py
Normal file
@ -0,0 +1,40 @@
|
||||
import os, sys
|
||||
import argparse
|
||||
from appPublic.log import MyLogger, info, debug, warning
|
||||
from appPublic.folderUtils import ProgramPath
|
||||
from appPublic.jsonConfig import getConfig
|
||||
from appPublic.registerfunction import RegisterFunction
|
||||
from ahserver.configuredServer import ConfiguredServer
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from whisper_model import WhisperFile
|
||||
from asr_engine import generate
|
||||
|
||||
__version__ = '0.0.1'
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(prog="Sage")
|
||||
parser.add_argument('-w', '--workdir')
|
||||
parser.add_argument('-p', '--port')
|
||||
args = parser.parse_args()
|
||||
print(args)
|
||||
workdir = args.workdir or os.getcwd()
|
||||
p = ProgramPath()
|
||||
config = getConfig(workdir, NS={'workdir':workdir, 'ProgramPath':p})
|
||||
if config.logger:
|
||||
logger = MyLogger(config.logger.name or 'sage',
|
||||
levelname=config.logger.levelname or 'debug',
|
||||
logfile=config.logger.logfile or None)
|
||||
else:
|
||||
logger = MyLogger('sage', levelname='debug')
|
||||
|
||||
info(f'========sage version={__version__}========')
|
||||
# server = ConfiguredServer(auth_klass=MyAuthAPI, workdir=workdir)
|
||||
server = ConfiguredServer(workdir=workdir)
|
||||
rf = RegisterFunction()
|
||||
rf.register('generate', generate)
|
||||
g = ServerEnv()
|
||||
g.whisper_engine = WhisperFile()
|
||||
port = args.port or config.website.port or 8080
|
||||
port = int(port)
|
||||
server.run(port=port)
|
||||
|
||||
76
app/asr_engine.py
Normal file
76
app/asr_engine.py
Normal file
@ -0,0 +1,76 @@
|
||||
import os
|
||||
import time
|
||||
from traceback import print_exc
|
||||
import base64
|
||||
import wave
|
||||
from appPublic.log import info, debug, warning, error, exception, critical
|
||||
from appPublic.dictObject import DictObject
|
||||
from appPublic.folderUtils import temp_file
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from aiohttp.web import StreamResponse
|
||||
from ahserver.globalEnv import realpath
|
||||
|
||||
def save_base64_wav(base64_data, output_file,sample_rate=16000, num_channels=1):
|
||||
# Decode the base64 data
|
||||
wav_data = base64.b64decode(base64_data)
|
||||
|
||||
# Open a new WAV file for writing
|
||||
with wave.open(output_file, 'wb') as wf:
|
||||
# Set the parameters of the WAV file
|
||||
wf.setnchannels(num_channels) # Mono channel
|
||||
wf.setsampwidth(2) # 16-bit sample width
|
||||
wf.setframerate(sample_rate) # 44.1 kHz sample rate
|
||||
# Write the decoded data to the WAV file
|
||||
wf.writeframes(wav_data)
|
||||
|
||||
async def generate(request, kw):
|
||||
params_kw = kw.get('params_kw', DictObject())
|
||||
info(f'{params_kw=}')
|
||||
model = params_kw.model
|
||||
audio_file = params_kw.audio_file
|
||||
if not audio_file:
|
||||
audio = params_kw.audio
|
||||
if audio is None:
|
||||
return {
|
||||
'status':'error',
|
||||
'message':'audio is null'
|
||||
}
|
||||
audio_file = temp_file(suffix='.wav')
|
||||
save_base64_wav(audio, audio_file)
|
||||
else:
|
||||
audio_file = realpath(audio_file)
|
||||
|
||||
engine = None
|
||||
g = ServerEnv()
|
||||
if model=='whisper':
|
||||
engine = g.whisper_engine
|
||||
|
||||
if engine is None:
|
||||
return {
|
||||
'status':'error',
|
||||
'message':f'model={model} is not defined'
|
||||
}
|
||||
try:
|
||||
t1 = time.time()
|
||||
dic = await engine.stt(audio_file)
|
||||
t2 = time.time()
|
||||
os.remove(audio_file)
|
||||
ret = {
|
||||
"status":"ok",
|
||||
"time_cost":t2-t1,
|
||||
"content":dic['text'],
|
||||
"segments":dic['segments'],
|
||||
"language":dic['language']
|
||||
}
|
||||
info(f'{dic=}, {ret=}')
|
||||
return ret
|
||||
except Exception as e:
|
||||
exception(f'{e}')
|
||||
print_exc()
|
||||
return {
|
||||
'status':'error',
|
||||
'message':f'{e}'
|
||||
}
|
||||
|
||||
g = ServerEnv()
|
||||
g.generate = generate
|
||||
0
app/sensevoice/__init__.py
Normal file
0
app/sensevoice/__init__.py
Normal file
22
app/sensevoice/load_model.py
Normal file
22
app/sensevoice/load_model.py
Normal file
@ -0,0 +1,22 @@
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from appPublic.worker import awaitify
|
||||
from appPublic.jsonConfig import getConfig, get_definition
|
||||
from funasr import AutoModel
|
||||
from funasr.utils.postprocess_utils import rich_transcription_postprocess
|
||||
|
||||
class SenseVoiceBase:
|
||||
def __init__(self):
|
||||
model_dir = get_definition('sensevoice_path')
|
||||
self.model = AutoModel(model=model_dir)
|
||||
|
||||
def _stt(self, x):
|
||||
pass
|
||||
stt = awaitify(_stt)
|
||||
|
||||
class SenseVoiceFile(SenseVoiceBase):
|
||||
def _stt(self, filepath):
|
||||
res = this.model.generate(input=filepath,language="auto",
|
||||
use_itn=True,
|
||||
batch_size_s=60
|
||||
)
|
||||
return rich_transcription_postprocess(res[0]["text"])
|
||||
54
app/whisper_model.py
Normal file
54
app/whisper_model.py
Normal file
@ -0,0 +1,54 @@
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from appPublic.worker import awaitify
|
||||
from appPublic.log import info, debug, warning, error, exception, critical
|
||||
|
||||
from ahserver.globalEnv import get_definition
|
||||
import numpy as np
|
||||
import base64
|
||||
import whisper
|
||||
|
||||
# 编码
|
||||
def base64_encode(text):
|
||||
text_bytes = text.encode('utf-8')
|
||||
encoded_bytes = base64.b64encode(text_bytes)
|
||||
encoded_text = encoded_bytes.decode('utf-8')
|
||||
return encoded_text
|
||||
|
||||
# 解码
|
||||
def base64_decode(encoded_text):
|
||||
encoded_bytes = encoded_text.encode('utf-8')
|
||||
decoded_bytes = base64.b64decode(encoded_bytes)
|
||||
decoded_text = decoded_bytes.decode('utf-8')
|
||||
return decoded_text
|
||||
|
||||
class WhisperBase:
|
||||
def __init__(self):
|
||||
model_name = get_definition('whisper_model')
|
||||
self.model = whisper.load_model(model_name)
|
||||
|
||||
def _stt(self, filepath):
|
||||
e = Exception(f'{filepath=} WhisperBase can not use')
|
||||
exception(f'{e=}')
|
||||
raise e
|
||||
|
||||
|
||||
class WhisperFile(WhisperBase):
|
||||
def _stt(self, filepath):
|
||||
return self.model.transcribe(filepath)
|
||||
|
||||
stt = awaitify(_stt)
|
||||
|
||||
class WhisperBase64(WhisperBase):
|
||||
def _stt(self, audio):
|
||||
audiolist = audio.values()
|
||||
nparr = np.array(audiolist, dtype=np.float32)
|
||||
nparr=np.vstack(nparr).astype(np.float)
|
||||
"""
|
||||
|
||||
raw = base64_decode(audio_base64)
|
||||
ndarr = np.frombuffer(raw, dtype=np.float32)
|
||||
"""
|
||||
info(f'ndarr={nparr}')
|
||||
return self.model.transcribe(nparr)
|
||||
|
||||
stt = awaitify(_stt)
|
||||
86
conf/config.json
Executable file
86
conf/config.json
Executable file
@ -0,0 +1,86 @@
|
||||
{
|
||||
"logger":{
|
||||
"name":"asr",
|
||||
"levelname":"info",
|
||||
"logfile":"$[workdir]$/logs/asr.log"
|
||||
},
|
||||
"definitions":{
|
||||
"whisper_model":"/d/ymq/osc/models/whisper/large-v3.pt"
|
||||
},
|
||||
"filesroot":"$[workdir]$/files",
|
||||
"databases":{
|
||||
"sage":{
|
||||
"driver":"aiomysql",
|
||||
"async_mode":true,
|
||||
"coding":"utf8",
|
||||
"maxconn":100,
|
||||
"dbname":"sage",
|
||||
"kwargs":{
|
||||
"user":"test",
|
||||
"db":"sage",
|
||||
"password":"QUZVcXg5V1p1STMybG5Ia6mX9D0v7+g=",
|
||||
"host":"localhost"
|
||||
}
|
||||
}
|
||||
},
|
||||
"website":{
|
||||
"paths":[
|
||||
["$[workdir]$/wwwroot",""]
|
||||
],
|
||||
"client_max_size":10000,
|
||||
"host":"0.0.0.0",
|
||||
"port":9091,
|
||||
"coding":"utf-8",
|
||||
"ssl_gg":{
|
||||
"crtfile":"$[workdir]$/conf/www.bsppo.com.pem",
|
||||
"keyfile":"$[workdir]$/conf/www.bsppo.com.key"
|
||||
},
|
||||
"indexes":[
|
||||
"index.html",
|
||||
"index.tmpl",
|
||||
"index.ui",
|
||||
"index.dspy",
|
||||
"index.md"
|
||||
],
|
||||
"startswiths":[
|
||||
{
|
||||
"leading":"/generate",
|
||||
"registerfunction":"generate"
|
||||
}
|
||||
],
|
||||
"processors":[
|
||||
[".ws","ws"],
|
||||
[".xterm","xterm"],
|
||||
[".proxy","proxy"],
|
||||
[".llm", "llm"],
|
||||
[".llms", "llms"],
|
||||
[".llma", "llma"],
|
||||
[".xlsxds","xlsxds"],
|
||||
[".sqlds","sqlds"],
|
||||
[".tmpl.js","tmpl"],
|
||||
[".tmpl.css","tmpl"],
|
||||
[".html.tmpl","tmpl"],
|
||||
[".bcrud", "bricks_crud"],
|
||||
[".tmpl","tmpl"],
|
||||
[".bui","bui"],
|
||||
[".ui","bui"],
|
||||
[".dspy","dspy"],
|
||||
[".md","md"]
|
||||
],
|
||||
"rsakey":{
|
||||
"privatekey":"$[workdir]$/conf/rsa_private_key.pem",
|
||||
"publickey":"$[workdir]$/conf/rsa_public_key.pem"
|
||||
},
|
||||
"session_max_time":3000,
|
||||
"session_issue_time":2500,
|
||||
"session_redis_oops":{
|
||||
"url":"redis://127.0.0.1:6379"
|
||||
}
|
||||
},
|
||||
"langMapping":{
|
||||
"zh-Hans-CN":"zh-cn",
|
||||
"zh-CN":"zh-cn",
|
||||
"en-us":"en",
|
||||
"en-US":"en"
|
||||
}
|
||||
}
|
||||
0
files/README.md
Normal file
0
files/README.md
Normal file
0
i18n/README.md
Normal file
0
i18n/README.md
Normal file
0
logs/README.md
Normal file
0
logs/README.md
Normal file
0
plugins/README.md
Normal file
0
plugins/README.md
Normal file
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
openai-whisper
|
||||
|
||||
0
wwwroot/README.md
Normal file
0
wwwroot/README.md
Normal file
Loading…
x
Reference in New Issue
Block a user