first commit
This commit is contained in:
commit
119ed70b69
45
README.md
Normal file
45
README.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# TTS小模型
|
||||||
|
|
||||||
|
## 依赖
|
||||||
|
|
||||||
|
### 模型
|
||||||
|
* nari-labs/dia-1.6b
|
||||||
|
下载地址:https://huggingface.com/nari-labs/dia-1.6b
|
||||||
|
|
||||||
|
* dac/weights.pth
|
||||||
|
下载地址:i
|
||||||
|
1) https://github.com/descriptinc/descript-audio-codec/releases/download/0.0.1/weights.pth
|
||||||
|
2) https://github.com/descriptinc/descript-audio-codec/releases/download/0.0.4/weights_24khz.pth
|
||||||
|
3) https://github.com/descriptinc/descript-audio-codec/releases/download/0.0.5/weights_16khz.pth
|
||||||
|
4) https://github.com/descriptinc/descript-audio-codec/releases/download/1.0.0/weights_44khz_16kbps.pth
|
||||||
|
|
||||||
|
### 模块
|
||||||
|
服务方
|
||||||
|
* [dia](https://github.com/nari-labs/dia)
|
||||||
|
* [appPublic](https://git.kaiyuancloud.cn/yumoqing/apppublic)
|
||||||
|
* [sqlor](https://git.kaiyuancloud.cn/yumoqing/sqlor)
|
||||||
|
* [ahserever](https://git.kaiyuancloud.cn/yumoqing/ahserver)
|
||||||
|
客户方
|
||||||
|
* [bricks](https://git.kaiyuancloud.cn/yumoqing/bricks)
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
执行以下命令
|
||||||
|
```
|
||||||
|
git clone https://git.kaiyuancloud.cn/yumoqing/dia16b
|
||||||
|
cd dia16b
|
||||||
|
python3 -m venv py3
|
||||||
|
source py3/bin/activate
|
||||||
|
pip install git+https://github.com/nari-labs/dia
|
||||||
|
pip install git+https://git.kaiyuancloud.cn/yumoqing/apppublic
|
||||||
|
pip install git+https://git.kaiyuancloud.cn/yumoqing/sqlor
|
||||||
|
pip install git+https://git.kaiyuancloud.cn/yumoqing/ahserver
|
||||||
|
```
|
||||||
|
## 下载依赖的模型
|
||||||
|
|
||||||
|
## 配置conf/config.json文件
|
||||||
|
主要修改下载模型存放目录
|
||||||
|
```
|
||||||
|
"dia_model_path" : "/share/models/nari-labs/dia-1___6b",
|
||||||
|
"dac_model_path": "/share/models/dac/weights.pth",
|
||||||
|
```
|
||||||
|
|
64
app/diaapp.py
Normal file
64
app/diaapp.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import os
|
||||||
|
import asyncio
|
||||||
|
import numpy as np
|
||||||
|
from traceback import format_exc
|
||||||
|
from dia.model import Dia
|
||||||
|
from appPublic.worker import awaitify
|
||||||
|
from appPublic.hf import hf_socks5proxy
|
||||||
|
from appPublic.folderUtils import _mkdir
|
||||||
|
from appPublic.uniqueID import getID
|
||||||
|
from appPublic.log import debug, exception, error
|
||||||
|
from appPublic.jsonConfig import getConfig
|
||||||
|
from ahserver.filestorage import FileStorage
|
||||||
|
from ahserver.webapp import webapp
|
||||||
|
from ahserver.serverenv import ServerEnv
|
||||||
|
import dac
|
||||||
|
hf_socks5proxy()
|
||||||
|
|
||||||
|
class DiaTTS:
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
config = getConfig()
|
||||||
|
# self.model = Dia.from_local(config.dia_model_path, compute_dtype="float16")
|
||||||
|
self.model = Dia.from_local(config.dia_model_path+'/config.json',
|
||||||
|
device=config.device or 'cpu',
|
||||||
|
load_dac=False,
|
||||||
|
checkpoint_path=config.dia_model_path + '/dia-v0_1.pth',
|
||||||
|
compute_dtype="float16")
|
||||||
|
self.load_dac(config.dac_model_path)
|
||||||
|
self.lock = asyncio.Lock()
|
||||||
|
self.fs = FileStorage()
|
||||||
|
|
||||||
|
def load_dac(self, dac_model_path):
|
||||||
|
dac_model = dac.DAC.load(dac_model_path).to(self.model.device)
|
||||||
|
dac_model.eval() # Ensure DAC is in eval mode
|
||||||
|
self.model.dac_model = dac_model
|
||||||
|
|
||||||
|
def _generate(self, prompt):
|
||||||
|
name = getID() + '.wav'
|
||||||
|
fp = self.fs._name2path(name)
|
||||||
|
webpath = self.fs.webpath(fp)
|
||||||
|
debug(f'{prompt=}')
|
||||||
|
output = self.model.generate(prompt, use_torch_compile=True, verbose=True)
|
||||||
|
output = output.astype(np.float32)
|
||||||
|
if output is None:
|
||||||
|
e = Exception(f'"{prompt}" to audio null')
|
||||||
|
exception(f'{e}\n{format_exc()}')
|
||||||
|
raise e
|
||||||
|
debug(f'{output.dtype.name=}')
|
||||||
|
_mkdir(os.path.dirname(fp))
|
||||||
|
self.model.save_audio(fp, output)
|
||||||
|
return webpath
|
||||||
|
|
||||||
|
async def generate(self, prompt):
|
||||||
|
async with self.lock:
|
||||||
|
f = awaitify(self._generate)
|
||||||
|
return await f(prompt)
|
||||||
|
|
||||||
|
def init():
|
||||||
|
g = ServerEnv()
|
||||||
|
g.etts_engine = DiaTTS()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
webapp(init)
|
||||||
|
|
48
conf/config.json
Normal file
48
conf/config.json
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"dia_model_path" : "/share/models/nari-labs/dia-1___6b",
|
||||||
|
"dac_model_path": "/share/models/dac/weights.pth",
|
||||||
|
"device" : "cuda",
|
||||||
|
"logger":{
|
||||||
|
"name":"dia",
|
||||||
|
"levelname":"info",
|
||||||
|
"logfile":"$[workdir]$/logs/dia.log"
|
||||||
|
},
|
||||||
|
"filesroot":"$[workdir]$/files",
|
||||||
|
"website":{
|
||||||
|
"paths":[
|
||||||
|
["$[workdir]$/wwwroot",""]
|
||||||
|
],
|
||||||
|
"client_max_size":10000,
|
||||||
|
"host":"0.0.0.0",
|
||||||
|
"port":9996,
|
||||||
|
"coding":"utf-8",
|
||||||
|
"indexes":[
|
||||||
|
"index.html",
|
||||||
|
"index.tmpl",
|
||||||
|
"index.ui",
|
||||||
|
"index.dspy",
|
||||||
|
"index.md"
|
||||||
|
],
|
||||||
|
"startswiths":[
|
||||||
|
{
|
||||||
|
"leading":"/idfile",
|
||||||
|
"registerfunction":"idfile"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"processors":[
|
||||||
|
[".dspy","dspy"],
|
||||||
|
[".ui","ui"]
|
||||||
|
],
|
||||||
|
"session_max_time":3000,
|
||||||
|
"session_issue_time":2500,
|
||||||
|
"session_redis_notuse":{
|
||||||
|
"url":"redis://127.0.0.1:6379"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"langMapping":{
|
||||||
|
"zh-Hans-CN":"zh-cn",
|
||||||
|
"zh-CN":"zh-cn",
|
||||||
|
"en-us":"en",
|
||||||
|
"en-US":"en"
|
||||||
|
}
|
||||||
|
}
|
1177
logs/dia.log
Normal file
1177
logs/dia.log
Normal file
File diff suppressed because it is too large
Load Diff
6
wwwroot/v1/generate/index.dspy
Normal file
6
wwwroot/v1/generate/index.dspy
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
debug(f'{request.path}:{params_kw=}')
|
||||||
|
f = await etts_engine.generate(params_kw.prompt)
|
||||||
|
return {
|
||||||
|
'audio_url':entire_url('/idfile') + f'?path={f}',
|
||||||
|
'status': 'ok'
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user