目录
一、部署Whisper模型。
二、oneapi配置
三、修改镜像中的webservice.py文件,开放跨域请求。
四、修改FastGPT代码修改
FastGPT地址:https://github.com/labring/FastGPT
fastgpt默认的语音转文字模型使用的openai里面的whisper,由于我没有openai 的token故需要自己部署本地的语音转文字模型,经研究发现可以部署本地的whisper,但是该接口无法接入到oneapi(我目前没研究出来)。故直接修改fastgpt代码直接调用接口获取语音转文字内容。
注:fastgpt的麦克风权限是本地部署的才能用,或者有HTTPS证书的才可以用(麦克风权限比较重要可能涉及隐私,故浏览器对这个要求比较严格)。我目前是本地部署的fastgpt。
一、部署Whisper模型。
我部署的是whisper-asr-webservicehttps://github.com/ahmetoner/whisper-asr-webservice,地址https://github.com/ahmetoner/whisper-asr-webservice。直接docker部署的,运行如下指令
docker run -d -p 9000:9000 -e ASR_MODEL=base onerahmet/openai-whisper-asr-webservice:latest
二、oneapi配置
fastgpt中project\app\data\config.local.json中关于语音模型的配置的模型名称是whisper-1,如下图:
所以在oneapi中配置时模型名称也要写whisper-1。模型名称是一一对应的(早期版的oneapi不支持多个模型,新版本应该是修复这个问题了。我这里还是延续之前我的配置方法习惯,只写一个)
三、修改镜像中的webservice.py文件,开放跨域请求。
也可以直接修改文件再生成镜像继续后面的步骤。我是先部署了容器后,才发现跨域问题。
1、开启容器
2、进入容器 docker exec -ti 容器id /bin/bahs
3、找到要修改的文件并修改,一般容器都没有安装vim\nano等编辑器。故需要将文件复制出来修改后在传上去。
docker cp <container_name_or_id>:/app/app/webservice.py /usr/local/yxq/webservice.py
docker cp <container_name_or_id>:/app/Dockerfile /usr/local/yxq/Dockerfile
修改完后再传上去
docker cp /usr/local/yxq/webservice.py <container_name_or_id>:/app/app/webservice.py
docker cp /usr/local/yxq/Dockerfile <container_name_or_id>:/app/Dockerfile
webservice.py修改如下:
增加如下代码:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
代码位置如图:
Dockerfile修改如下:RUN $POETRY_VENV/bin/pip install starlette==0.15.0
修改dockerfile镜像后,镜像启动会先将需要的包下载下来。
4、**将修改后的容器保存为新的镜像:** 使用以下命令将修改后的容器保存为新的镜像:
`docker commit 容器id <new_image_name>:<tag>`
将 `<new_image_name>:<tag>` 替换为你要保存的新镜像的名称和标签。
5、**删除临时容器:** 容器已经保存为新的镜像后,你可以删除临时容器:
`docker rm temp_container`
这将删除临时容器,释放资源。
保存完新镜像后,重建容器。我使用的1panel直接更换的镜像就可以用了。先把容器停止,然后更换镜像后保存即可。
可使用postman验证下接口。如下:
四、修改FastGPT代码修改
1、先开启应用的语音输入配置,如图
2、修改文件useSpeech.ts。由于代码中使用的封装的post请求方法,而封装的requets.ts中将返回结果取值为data.data,但是上面的whisper-asr-webservice接口返回的数据只有一层data(可通过上面的postman接口截图可以看出只有一层结构),故需要单独修改下,方法如下:
// const result = await POST<string>('http://192.168.1.39:9000/asr', formData2, {
// timeout: 6000000,
// headers: {
// 'Content-Type': 'multipart/form-data; charset=utf-8'
// }
// });
// console.log("语音转文字完毕:", result);
// 发送 POST 请求
const response = await axios.post('http://192.168.1.39:9000/asr', formData2, {
timeout: 60000, // 6000秒
headers: {
// 当发送 'Content-Type': 'multipart/form-data'时,不需要指定具体的boundary
// Browser/Axios会为你处理
// 'Content-Type': 'multipart/form-data; charset=utf-8' // 不推荐手动设置
},
// 告诉axios,即使返回的内容是文本,也不需要进行任何转换处理
responseType: 'text' // 明确指定响应类型为"text",以获得文本响应
});
// 使用 Axios,成功的响应数据在 response 中
console.log("语音转文字完毕:", response);
onFinish(response.data);
注释掉的是原先的代码,由于返回结果取值是data.data导致取值是undefined。故使用后面的代码代替 。超时时间尽量长点,如果部署模型的服务器配置低则接口会响应较慢。
效果如下: