当前位置: 首页 > news >正文

cpu运行 kokoro tts 服务器语音转化首选

处理一些简单的语音不在话下,关键可以cpu 模式运行,也挺快的 ,实测占用内存大概2g ,意味着再一台 4c4g 的服务器就可以跑了,初始化需要下载

# pip install kokoro>=0.8.1 "misaki[zh]>=0.8.1"

在这里插入图片描述

from flask import Flask, request, jsonify, send_file
from kokoro import KModel, KPipeline
from pathlib import Path
import numpy as np
import soundfile as sf
import torch
import io
import base64app = Flask(__name__)# 初始化模型(在应用启动时只执行一次)
REPO_ID = 'hexgrad/Kokoro-82M-v1.1-zh'
SAMPLE_RATE = 24000
VOICE = 'zf_005'def init_model():global model, zh_pipeline# 设备配置device = 'cuda' if torch.cuda.is_available() else 'cpu'# 初始化模型和管道model = KModel(repo_id=REPO_ID).to(device).eval()# 定义英文处理函数en_pipeline = KPipeline(lang_code='a', repo_id=REPO_ID, model=False)def en_callable(text):if text == 'Kokoro':return 'kˈOkəɹO'elif text == 'Sol':return 'sˈOl'try:return next(en_pipeline(text)).phonemesexcept:return text  # 如果处理失败,返回原始文本zh_pipeline = KPipeline(lang_code='z', repo_id=REPO_ID, model=model, en_callable=en_callable)# 初始化模型
init_model()# HACK: Mitigate rushing caused by lack of training data beyond ~100 tokens
# Simple piecewise linear fn that decreases speed as len_ps increases
def speed_callable(len_ps):speed = 0.8if len_ps <= 83:speed = 1elif len_ps < 183:speed = 1 - (len_ps - 83) / 500return speed * 1.5def generate_tts(text):"""生成TTS音频的通用函数"""try:# 生成语音generator = zh_pipeline(text, voice=VOICE, speed=speed_callable)result = next(generator)wav = result.audio# 将 numpy 数组转换为 WAV 格式的字节流buffer = io.BytesIO()sf.write(buffer, wav, SAMPLE_RATE, format='WAV')buffer.seek(0)return bufferexcept Exception as e:raise Exception(f"TTS生成失败: {str(e)}")@app.route('/tts', methods=['POST'])
def text_to_speech():try:# 获取请求数据data = request.get_json()if not data or 'text' not in data:return jsonify({'error': 'Missing text parameter'}), 400text = data['text']if not text:return jsonify({'error': 'Text cannot be empty'}), 400buffer = generate_tts(text)# 返回音频文件return send_file(buffer,mimetype='audio/wav',as_attachment=True,download_name='output.wav')except Exception as e:return jsonify({'error': str(e)}), 500@app.route('/tts_get')
def text_to_speech_get():try:# 从查询参数获取文本text = request.args.get('text', '')if not text:return jsonify({'error': 'Missing text parameter'}), 400buffer = generate_tts(text)# 返回音频文件return send_file(buffer,mimetype='audio/wav',as_attachment=True,download_name='output.wav')except Exception as e:return jsonify({'error': str(e)}), 500@app.route('/tts_base64', methods=['POST'])
def text_to_speech_base64():try:# 获取请求数据data = request.get_json()if not data or 'text' not in data:return jsonify({'error': 'Missing text parameter'}), 400text = data['text']if not text:return jsonify({'error': 'Text cannot be empty'}), 400buffer = generate_tts(text)# 转换为 base64 编码wav_base64 = base64.b64encode(buffer.read()).decode('utf-8')# 返回 base64 编码的音频return jsonify({'status': 'success','audio': wav_base64,'format': 'wav'})except Exception as e:return jsonify({'error': str(e)}), 500@app.route('/tts_base64_get')
def text_to_speech_base64_get():try:# 从查询参数获取文本text = request.args.get('text', '')if not text:return jsonify({'error': 'Missing text parameter'}), 400buffer = generate_tts(text)# 转换为 base64 编码wav_base64 = base64.b64encode(buffer.read()).decode('utf-8')# 返回 base64 编码的音频return jsonify({'status': 'success','audio': wav_base64,'format': 'wav'})except Exception as e:return jsonify({'error': str(e)}), 500@app.route('/health', methods=['GET'])
def health_check():return jsonify({'status': 'healthy'})if __name__ == '__main__':# 禁用调试模式以避免重新加载问题app.run(host='0.0.0.0', port=5000, debug=False)
http://www.dtcms.com/a/308827.html

相关文章:

  • 为什么 Batch Normalization 放在全连接/卷积层的输出之后?
  • linux如何将两份hdmi edid合并
  • 硬件电路基础学习
  • Cesium 快速入门(五)坐标系
  • LangGraph底层原理与基础应用入门
  • vue3可编辑表格
  • linux自动构建工具make/makefile
  • 【计算机网络】5传输层
  • MySQL 中的 JOIN 操作有哪些类型?它们之间有什么区别?
  • 国标gb28181 SIP协商详细分析
  • 《嵌入式C语言笔记(十七):进制转换、结构体与位运算精要》
  • .map文件中的0x40f (size before relaxing)是什么意思?
  • 这个项目有多急?
  • MySQL常用函数总结
  • 经典算法之美:冒泡排序的优雅实现
  • 多场景-阶梯式碳交易机制下考虑需求响应的综合能源系统优化(MATLAB模型)
  • 智能Agent场景实战指南 Day 27:Agent部署与可扩展性
  • 本地部署VMware ESXi,并实现无公网IP远程访问管理服务器
  • C++手撕简单KNN
  • 如何使用自定义@DS注解切换数据源
  • 中小企业数据保护指南:如何用群晖NAS构建高效备份体系?
  • pytorch程序语句固定开销分析
  • hive新增列之后插入新数据时,新列为NULL的解决办法
  • 火焰图(Flame Graph)深度指南:CPU性能分析与瓶颈定位
  • 2025.8-12月 AI相关国内会议
  • C基础 12_day
  • XL2422 无线收发芯片,可用于遥控玩具和智能家居等应用领域
  • 网络层概述
  • LLM残差流为何会超过1?
  • Lombok 字段魔法:用 @FieldDefaults 解锁“隐身+锁死”双重特效