Skip to content

Commit 4377e9b

Browse files
iftaken吕志轩
authored andcommitted
update readme and fixed bug in ngpu (PaddlePaddle#2451)
* update readme and fixed ngpu bug * update png in readme * update readme and FT web ttsText
1 parent 6bba49d commit 4377e9b

File tree

18 files changed

+95
-635
lines changed

18 files changed

+95
-635
lines changed

demos/speech_web/README.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ Paddle Speech Demo 是一个以 PaddleSpeech 的语音交互功能为主体开
2828

2929
运行效果:
3030

31-
![效果](https://user-images.githubusercontent.com/30135920/191188766-12e7ca15-f7b4-45f8-9da5-0c0b0bbe5fcb.png)
31+
![效果](https://user-images.githubusercontent.com/30135920/192155349-9ef93d20-730b-413d-8d50-412fedf11d4b.png)
3232

3333

3434

3535
## 基础环境安装
3636

3737
### 后端环境安装
3838
```bash
39+
# 需要先安装 PaddleSpeech
3940
cd speech_server
4041
pip install -r requirements.txt -i https://mirror.baidu.com/pypi/simple
4142
cd ../
@@ -44,6 +45,8 @@ cd ../
4445
### 前端环境安装
4546
前端依赖 `node.js` ,需要提前安装,确保 `npm` 可用,`npm` 测试版本 `8.3.1`,建议下载[官网](https://nodejs.org/en/)稳定版的 `node.js`
4647

48+
如果因为网络问题,无法下载依赖库,可以参考 FAQ 部分,`npm / yarn 下载速度慢问题`
49+
4750
```bash
4851
# 进入前端目录
4952
cd web_client
@@ -70,7 +73,7 @@ mkdir -p source/model
7073
cd source/model
7174
# 下载IE模型
7275
wget https://bj.bcebos.com/paddlenlp/applications/speech-cmd-analysis/finetune/model_state.pdparams
73-
cd ../../
76+
cd ../../../
7477

7578
```
7679
#### 启动后端服务
@@ -84,6 +87,10 @@ python main.py --port 8010
8487

8588
### 启动 `vc.py` 后端服务
8689

90+
参照下面的步骤自行配置项目所需环境。
91+
92+
Aistudio 在线体验小样本合成后端功能:[【PaddleSpeech进阶】PaddleSpeech小样本合成方案体验](https://aistudio.baidu.com/aistudio/projectdetail/4573549?sUid=2470186&shared=1&ts=1664174385948)
93+
8794
#### 下载相关模型和音频
8895

8996
```bash
@@ -172,8 +179,19 @@ cd web_client
172179
yarn dev --port 8011
173180
```
174181

175-
默认配置下,前端中配置的后台地址信息是 localhost,确保后端服务器和打开页面的游览器在同一台机器上,不在一台机器的配置方式见下方的 FAQ:【后端如果部署在其它机器或者别的端口如何修改】
182+
默认配置下,前端配置的后台地址信息是 `localhost`,确保后端服务器和打开页面的游览器在同一台机器上,不在一台机器的配置方式见下方的 FAQ:【后端如果部署在其它机器或者别的端口如何修改】
183+
184+
#### 关于前端的一些说明
185+
186+
为了方便后期的维护,这里并没有给出打包好的 HTML 文件,而是 Vue3 的项目,使用 `yarn dev --port 8011` 的方式启动测试,方便大家debug,相当于是启动了一个前端服务器。
187+
188+
比如我们在本机启动的这个前端服务(运行 `yarn dev --port 8011` ),我们就可以通过在游览器中通过 `http://localhost:8011` 访问前端页面
189+
190+
如果我们在其它服务器上(例如:`*.*.*.*` )启动这个前端服务(运行 `yarn dev --port 8011` ),我们就可以通过在游览器中访问 `http://*.*.*.*:8011` 访问前端页面
176191

192+
那前端跟后端是什么关系呢? 两个是独立的,只要前端能够通过代理访问到后端的接口,那就没有问题。你可以在 A 机器上部署后端服务,然后在 B 机器上部署前端服务。我们在 `./web_client/vite.config.js` 中将 `/api` 映射到的是 `http://localhost:8010`,你可以把它配置成任意你想要访问后端地址。
193+
194+
当前端在以 `*.*.*.*` 这类以 IP 地址形式的网页中访问时,由于游览器的安全限制,会禁止录音,需要重新配置游览器的安全策略, 可以看下面 FAQ 部分: [【前端以IP地址的形式访问,无法录音】]
177195

178196

179197
## FAQ
@@ -210,12 +228,24 @@ ASR_SOCKET_RECORD: 'ws://localhost:8010/ws/asr/onlineStream', // Stream ASR 接
210228
TTS_SOCKET_RECORD: 'ws://localhost:8010/ws/tts/online', // Stream TTS 接口
211229
```
212230

213-
#### Q:后端以IP地址的形式,前端无法录音
231+
#### Q:前端以IP地址的形式访问,无法录音
214232

215233
A:这里主要是游览器安全策略的限制,需要配置游览器后重启。游览器修改配置可参考[使用js-audio-recorder报浏览器不支持getUserMedia](https://blog.csdn.net/YRY_LIKE_YOU/article/details/113745273)
216234

217235
chrome设置地址: chrome://flags/#unsafely-treat-insecure-origin-as-secure
218236

237+
#### Q: npm / yarn 配置淘宝镜像源
238+
239+
A: 配置淘宝镜像源,详细可以参考 [【yarn npm 设置淘宝镜像】](https://www.jianshu.com/p/f6f43e8f9d6b)
240+
241+
```bash
242+
# npm 配置淘宝镜像源
243+
npm config set registry https://registry.npmmirror.com
244+
245+
# yarn 配置淘宝镜像源
246+
yarn config set registry http://registry.npm.taobao.org/
247+
```
248+
219249
## 参考资料
220250

221251
vue实现录音参考资料:https://blog.csdn.net/qq_41619796/article/details/107865602#t1

demos/speech_web/speech_server/src/ernie_sat.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22

3+
from .util import get_ngpu
34
from .util import MAIN_ROOT
45
from .util import run_cmd
56

@@ -171,6 +172,7 @@ def get_cmd(self,
171172
output_name: str,
172173
source_lang: str,
173174
target_lang: str):
175+
ngpu = get_ngpu()
174176
cmd = f"""
175177
FLAGS_allocator_strategy=naive_best_fit \
176178
FLAGS_fraction_of_gpu_memory_to_use=0.01 \
@@ -189,7 +191,8 @@ def get_cmd(self,
189191
--voc_config={voc_config} \
190192
--voc_ckpt={voc_ckpt} \
191193
--voc_stat={voc_stat} \
192-
--output_name={output_name}
194+
--output_name={output_name} \
195+
--ngpu={ngpu}
193196
"""
194197

195198
return cmd

demos/speech_web/speech_server/src/finetune.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22

3+
from .util import get_ngpu
34
from .util import MAIN_ROOT
45
from .util import run_cmd
56

@@ -38,7 +39,7 @@ def finetune(self, input_dir, exp_dir='temp', epoch=100):
3839
dump_dir = os.path.join(exp_dir, 'dump')
3940
output_dir = os.path.join(exp_dir, 'exp')
4041
lang = "zh"
41-
ngpu = 1
42+
ngpu = get_ngpu()
4243

4344
cmd = f"""
4445
# check oov
@@ -91,7 +92,7 @@ def synthesize(self, text, wav_name, out_wav_dir, exp_dir='temp'):
9192
output_dir = os.path.join(exp_dir, 'exp')
9293
text_path = os.path.join(exp_dir, 'sentences.txt')
9394
lang = "zh"
94-
ngpu = 1
95+
ngpu = get_ngpu()
9596

9697
model_path = f"{output_dir}/checkpoints"
9798
ckpt = find_max_ckpt(model_path)
@@ -117,7 +118,8 @@ def synthesize(self, text, wav_name, out_wav_dir, exp_dir='temp'):
117118
--output_dir={out_wav_dir} \
118119
--phones_dict={dump_dir}/phone_id_map.txt \
119120
--speaker_dict={dump_dir}/speaker_id_map.txt \
120-
--spk_id=0
121+
--spk_id=0 \
122+
--ngpu={ngpu}
121123
"""
122124

123125
out_path = os.path.join(out_wav_dir, f"{wav_name}.wav")

demos/speech_web/speech_server/src/ge2e_clone.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import shutil
33

4+
from .util import get_ngpu
45
from .util import MAIN_ROOT
56
from .util import run_cmd
67

@@ -30,11 +31,12 @@ def vc(self, text, input_wav, out_wav):
3031
ref_audio_dir = os.path.realpath("tmp_dir/ge2e")
3132
if os.path.exists(ref_audio_dir):
3233
shutil.rmtree(ref_audio_dir)
33-
else:
34-
os.makedirs(ref_audio_dir, exist_ok=True)
35-
shutil.copy(input_wav, ref_audio_dir)
34+
35+
os.makedirs(ref_audio_dir, exist_ok=True)
36+
shutil.copy(input_wav, ref_audio_dir)
3637

3738
output_dir = os.path.dirname(out_wav)
39+
ngpu = get_ngpu()
3840

3941
cmd = f"""
4042
python3 {self.BIN_DIR}/voice_cloning.py \
@@ -50,7 +52,8 @@ def vc(self, text, input_wav, out_wav):
5052
--text="{text}" \
5153
--input-dir={ref_audio_dir} \
5254
--output-dir={output_dir} \
53-
--phones-dict={self.phones_dict}
55+
--phones-dict={self.phones_dict} \
56+
--ngpu={ngpu}
5457
"""
5558

5659
output_name = os.path.join(output_dir, full_file_name)

demos/speech_web/speech_server/src/tdnn_clone.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import shutil
33

4+
from .util import get_ngpu
45
from .util import MAIN_ROOT
56
from .util import run_cmd
67

@@ -27,11 +28,11 @@ def vc(self, text, input_wav, out_wav):
2728
ref_audio_dir = os.path.realpath("tmp_dir/tdnn")
2829
if os.path.exists(ref_audio_dir):
2930
shutil.rmtree(ref_audio_dir)
30-
else:
31-
os.makedirs(ref_audio_dir, exist_ok=True)
32-
shutil.copy(input_wav, ref_audio_dir)
31+
os.makedirs(ref_audio_dir, exist_ok=True)
32+
shutil.copy(input_wav, ref_audio_dir)
3333

3434
output_dir = os.path.dirname(out_wav)
35+
ngpu = get_ngpu()
3536

3637
cmd = f"""
3738
python3 {self.BIN_DIR}/voice_cloning.py \
@@ -47,7 +48,8 @@ def vc(self, text, input_wav, out_wav):
4748
--input-dir={ref_audio_dir} \
4849
--output-dir={output_dir} \
4950
--phones-dict={self.phones_dict} \
50-
--use_ecapa=True
51+
--use_ecapa=True \
52+
--ngpu={ngpu}
5153
"""
5254

5355
output_name = os.path.join(output_dir, full_file_name)

demos/speech_web/speech_server/src/util.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,19 @@
22
import random
33
import subprocess
44

5+
import paddle
6+
57
NOW_FILE_PATH = os.path.dirname(__file__)
68
MAIN_ROOT = os.path.realpath(os.path.join(NOW_FILE_PATH, "../../../../"))
79

810

11+
def get_ngpu():
12+
if paddle.device.get_device() == "cpu":
13+
return 0
14+
else:
15+
return 1
16+
17+
918
def randName(n=5):
1019
return "".join(random.sample('zyxwvutsrqponmlkjihgfedcba', n))
1120

demos/speech_web/speech_server/vc.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,15 +281,18 @@ async def VcCloneG2P(base: VcBaseText):
281281
if base.func == 'ge2e':
282282
wavName = base.wavName
283283
wavPath = os.path.join(VC_OUT_PATH, wavName)
284-
vc_model.vc(
284+
wavPath = vc_model.vc(
285285
text=base.text, input_wav=base.wavPath, out_wav=wavPath)
286286
else:
287287
wavName = base.wavName
288288
wavPath = os.path.join(VC_OUT_PATH, wavName)
289-
vc_model_tdnn.vc(
289+
wavPath = vc_model_tdnn.vc(
290290
text=base.text, input_wav=base.wavPath, out_wav=wavPath)
291-
res = {"wavName": wavName, "wavPath": wavPath}
292-
return SuccessRequest(result=res)
291+
if wavPath:
292+
res = {"wavName": wavName, "wavPath": wavPath}
293+
return SuccessRequest(result=res)
294+
else:
295+
return ErrorRequest(message="克隆失败,检查克隆脚本是否有效")
293296
except Exception as e:
294297
print(e)
295298
return ErrorRequest(message="克隆失败,合成过程报错")

demos/speech_web/web_client/src/components/Experience.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import FineTuneT from './SubMenu/FineTune/FineTune.vue'
4747
<el-tab-pane label="小数据微调" key="7">
4848
<FineTuneT></FineTuneT>
4949
</el-tab-pane>
50-
<el-tab-pane label="ENIRE SAT" key="8">
50+
<el-tab-pane label="ENIRE-SAT" key="8">
5151
<ENIRE_SATT></ENIRE_SATT>
5252
</el-tab-pane>
5353
</el-tabs>

demos/speech_web/web_client/src/components/SubMenu/ASR/RealTime/RealTime.vue

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,6 @@ export default {
5858
mounted () {
5959
this.wsUrl = apiURL.ASR_SOCKET_RECORD
6060
this.ws = new WebSocket(this.wsUrl)
61-
if(this.ws.readyState === this.ws.CONNECTING){
62-
this.$message.success("实时识别 Websocket 连接成功")
63-
}
6461
var _that = this
6562
this.ws.addEventListener('message', function (event) {
6663
var temp = JSON.parse(event.data);
@@ -78,7 +75,7 @@ export default {
7875
// 检查 websocket 状态
7976
// debugger
8077
if(this.ws.readyState != this.ws.OPEN){
81-
this.$message.error("websocket 链接失败,请检查链接地址是否正确")
78+
this.$message.error("websocket 链接失败,请检查 Websocket 后端服务是否正确开启")
8279
return
8380
}
8481

0 commit comments

Comments
 (0)