安装whisper

国产系统部署(麒麟)

国产系统注意事项

1.先确认 Python 环境:

bash

bash 复制代码
# 查看 Python 版本(需要 3.8+)
python3 --version

# 查看 pip3 是否已安装
pip3 --version

如果显示 -bash: pip3: command not found,先安装 pip3:

bash

bash 复制代码
sudo yum install -y python3-pip

2 升级 Python 3.8+

1.检查系统架构(重要)

首先确认你的系统架构,这会影响后续下载哪个源码包:

bash

复制代码
uname -m

输出可能是:

  • x86_64:Intel/AMD 64位架构

  • aarch64:ARM 64位架构(飞腾、鲲鹏处理器)

本系统是x86_64

2.安装编译依赖下载 Python 3.8 源码解压并编译安装
bash 复制代码
# 1. 安装编译依赖-说明:这些依赖确保 Python 编译后能正常使用 pip、SSL、压缩等功能。
sudo yum install -y gcc make zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel libffi-devel xz-devel wget

# 2. 下载源码
cd /usr/local/src
sudo wget https://www.python.org/ftp/python/3.8.18/Python-3.8.18.tgz

# 3. 解压并编译
sudo tar -xzf Python-3.8.18.tgz
cd Python-3.8.18
sudo ./configure --prefix=/usr/local/python3.8 --enable-optimizations
sudo make -j$(nproc)
sudo make altinstall

# 4. 创建软链接
sudo ln -sf /usr/local/python3.8/bin/python3.8 /usr/bin/python3.8
sudo ln -sf /usr/local/python3.8/bin/pip3.8 /usr/bin/pip3.8

# 5. 验证
python3.8 --version

为什么用 altinstall 这样安装后,Python 3.8 的可执行文件是 /usr/local/python3.8/bin/python3.8,不会覆盖系统自带的 python3(可能是 3.7),避免破坏系统工具。
⚠️ 注意 :切换默认 python3 可能会影响依赖 Python 3.7 的系统工具(如 yum)。建议保留系统默认,使用 python3.8 命令专门运行 FunASR。

1. 安装 whisper

bash

bash 复制代码
# 使用 python3.8 安装
python3.8 -m pip install openai-whisper

2. 创建服务

bash

bash 复制代码
cat > whisper_server.py << 'EOF'
#!/usr/bin/env python3
import json
import tempfile
import os
from http.server import HTTPServer, BaseHTTPRequestHandler
import cgi
import sys

print("正在加载 Whisper...")
sys.stdout.flush()

try:
    import whisper
    print("Whisper 导入成功")
    print("正在加载模型...")
    model = whisper.load_model("base")
    print("模型加载完成!")
except Exception as e:
    print(f"加载失败: {e}")
    sys.exit(1)

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/health':
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps({"status": "ok"}).encode())
        else:
            self.send_response(404)
            self.end_headers()
    
    def do_POST(self):
        if self.path == '/recognition':
            try:
                form = cgi.FieldStorage(
                    fp=self.rfile,
                    headers=self.headers,
                    environ={'REQUEST_METHOD': 'POST'}
                )
                
                if 'audio' not in form:
                    self.send_error(400, "No audio file")
                    return
                
                file_item = form['audio']
                with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
                    tmp.write(file_item.file.read())
                    tmp_path = tmp.name
                
                # 识别
                result = model.transcribe(tmp_path, language="zh")
                os.unlink(tmp_path)
                
                self.send_response(200)
                self.send_header('Content-type', 'application/json')
                self.end_headers()
                response = json.dumps({"code": 0, "text": result["text"]})
                self.wfile.write(response.encode())
                
            except Exception as e:
                self.send_response(500)
                self.end_headers()
                self.wfile.write(json.dumps({"code": 1, "msg": str(e)}).encode())
        else:
            self.send_response(404)
            self.end_headers()

if __name__ == "__main__":
    port = 8000
    server = HTTPServer(('0.0.0.0', port), Handler)
    print(f"✅ HTTP 服务启动成功!")
    print(f"📍 地址: http://0.0.0.0:{port}")
    print(f"✅ 健康检查: http://localhost:{port}/health")
    print(f"✅ 识别接口: POST http://localhost:{port}/recognition")
    print("\n按 Ctrl+C 停止服务")
    sys.stdout.flush()
    server.serve_forever()
EOF

python3 whisper_server.py

如果失败安装 ffmpeg

bash

复制代码
# 安装 ffmpeg(解决音频处理问题)
yum install ffmpeg -y
# 或
apt install ffmpeg -y

# 重新安装 whisper
python3 -m pip install --upgrade openai-whisper

安装 ffmpeg失败,使用 Python 音频处理

修改服务代码,不依赖 ffmpeg:

bash

bash 复制代码
cat > no_ffmpeg_server.py << 'EOF'
#!/usr/bin/env python3
import json
import tempfile
import os
import wave
import numpy as np
from http.server import HTTPServer, BaseHTTPRequestHandler
import cgi
import sys
import io

print("正在加载 Whisper...")
sys.stdout.flush()

try:
    import whisper
    print("Whisper 导入成功")
    print("正在加载模型...")
    model = whisper.load_model("base")
    print("模型加载完成!")
except Exception as e:
    print(f"加载失败: {e}")
    traceback.print_exc()
    sys.exit(1)

def convert_to_wav(audio_data):
    """尝试将音频数据转换为 wav 格式"""
    try:
        # 如果已经是 wav,直接返回
        if audio_data[:4] == b'RIFF':
            return audio_data
        
        # 尝试用 soundfile 处理
        try:
            import soundfile as sf
            import io
            data, sr = sf.read(io.BytesIO(audio_data))
            with io.BytesIO() as buf:
                sf.write(buf, data, sr, format='wav')
                return buf.getvalue()
        except:
            pass
        
        # 如果都失败,返回原始数据
        return audio_data
    except:
        return audio_data

class Handler(BaseHTTPRequestHandler):
    def send_cors_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
    
    def do_OPTIONS(self):
        self.send_response(200)
        self.send_cors_headers()
        self.end_headers()
    
    def do_GET(self):
        if self.path == '/health':
            self.send_response(200)
            self.send_cors_headers()
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps({"status": "ok"}).encode())
        else:
            self.send_response(404)
            self.end_headers()
    
    def do_POST(self):
        if self.path == '/recognition':
            try:
                form = cgi.FieldStorage(
                    fp=self.rfile,
                    headers=self.headers,
                    environ={'REQUEST_METHOD': 'POST'}
                )
                
                if 'audio' not in form:
                    self.send_error(400, "No audio file")
                    return
                
                file_item = form['audio']
                audio_data = file_item.file.read()
                
                print(f"收到音频,大小: {len(audio_data)} 字节")
                
                with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
                    tmp.write(audio_data)
                    tmp_path = tmp.name
                
                # 识别
                result = model.transcribe(tmp_path, language="zh")
                os.unlink(tmp_path)
                
                print(f"识别结果: {result['text'][:50]}...")
                
                self.send_response(200)
                self.send_cors_headers()
                self.send_header('Content-type', 'application/json')
                self.end_headers()
                response = json.dumps({"code": 0, "text": result["text"]})
                self.wfile.write(response.encode())
                
            except Exception as e:
                print(f"错误: {e}")
                import traceback
                traceback.print_exc()
                self.send_response(500)
                self.send_cors_headers()
                self.end_headers()
                self.wfile.write(json.dumps({"code": 1, "msg": str(e)}).encode())
        else:
            self.send_response(404)
            self.end_headers()

if __name__ == "__main__":
    port = 8000
    server = HTTPServer(('0.0.0.0', port), Handler)
    print(f"✅ HTTP 服务启动成功!")
    print(f"📍 地址: http://0.0.0.0:{port}")
    print(f"✅ 健康检查: http://localhost:{port}/health")
    print(f"✅ 识别接口: POST http://localhost:{port}/recognition")
    print("\n按 Ctrl+C 停止服务")
    sys.stdout.flush()
    server.serve_forever()
EOF

python3 no_ffmpeg_server.py

识别结果显示的是繁体中文,这是因为 Whisper 模型默认输出的文字格式。如果你需要简体中文,可以添加转换。

✅ 添加繁转简功能

安装 opencc 完整繁转简

bash

bash 复制代码
# 使用 python3 -m pip 安装
python3 -m pip install opencc-python-reimplemented

# 如果网络慢,使用国内镜像
python3 -m pip install opencc-python-reimplemented -i https://pypi.tuna.tsinghua.edu.cn/simple

📝 更新服务代码

bash

bash 复制代码
cat > final_server.py << 'EOF'
#!/usr/bin/env python3
import json
import tempfile
import os
from http.server import HTTPServer, BaseHTTPRequestHandler
import cgi
import sys

print("正在加载 Whisper...")
sys.stdout.flush()

try:
    import whisper
    print("Whisper 导入成功")
    print("正在加载模型...")
    model = whisper.load_model("base")
    print("模型加载完成!")
except Exception as e:
    print(f"加载失败: {e}")
    sys.exit(1)

# 尝试导入 opencc
try:
    from opencc import OpenCC
    cc = OpenCC('t2s')  # 繁体转简体
    print("OpenCC 加载成功,将自动转换繁体到简体")
except:
    cc = None
    print("OpenCC 未安装,将使用简单转换")

# 简单繁转简映射(备用)
def simple_convert(text):
    mapping = {
        '沒': '没', '應': '应', '該': '该', '讓': '让', '們': '们', '這': '这',
        '個': '个', '為': '为', '會': '会', '對': '对', '於': '于', '從': '从',
        '來': '来', '說': '说', '話': '话', '電': '电', '腦': '脑', '機': '机',
        '體': '体', '國': '国', '際': '际', '關': '关', '係': '系', '開': '开',
        '門': '门', '問': '问', '題': '题', '點': '点', '時': '时', '間': '间',
        '長': '长', '短': '短', '高': '高', '低': '低', '熱': '热', '愛': '爱',
        '學': '学', '習': '习', '書': '书', '寫': '写', '讀': '读', '聽': '听',
        '視': '视', '頻': '频', '資': '资', '訊': '讯', '網': '网', '路': '路'
    }
    for trad, simp in mapping.items():
        text = text.replace(trad, simp)
    return text

def to_simplified(text):
    if cc:
        return cc.convert(text)
    else:
        return simple_convert(text)

class Handler(BaseHTTPRequestHandler):
    def send_cors_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
    
    def do_OPTIONS(self):
        self.send_response(200)
        self.send_cors_headers()
        self.end_headers()
    
    def do_GET(self):
        if self.path == '/health':
            self.send_response(200)
            self.send_cors_headers()
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps({"status": "ok"}).encode())
        else:
            self.send_response(404)
            self.end_headers()
    
    def do_POST(self):
        if self.path == '/recognition':
            try:
                form = cgi.FieldStorage(
                    fp=self.rfile,
                    headers=self.headers,
                    environ={'REQUEST_METHOD': 'POST'}
                )
                
                if 'audio' not in form:
                    self.send_error(400, "No audio file")
                    return
                
                file_item = form['audio']
                with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
                    tmp.write(file_item.file.read())
                    tmp_path = tmp.name
                
                result = model.transcribe(tmp_path, language="zh")
                os.unlink(tmp_path)
                
                text = to_simplified(result["text"])
                print(f"识别: {text[:50]}...")
                
                self.send_response(200)
                self.send_cors_headers()
                self.send_header('Content-type', 'application/json')
                self.end_headers()
                response = json.dumps({"code": 0, "text": text})
                self.wfile.write(response.encode())
                
            except Exception as e:
                print(f"错误: {e}")
                self.send_response(500)
                self.send_cors_headers()
                self.end_headers()
                self.wfile.write(json.dumps({"code": 1, "msg": str(e)}).encode())
        else:
            self.send_response(404)
            self.end_headers()

if __name__ == "__main__":
    port = 8000
    server = HTTPServer(('0.0.0.0', port), Handler)
    print(f"✅ HTTP 服务启动成功!")
    print(f"📍 地址: http://0.0.0.0:{port}")
    print(f"✅ 健康检查: http://localhost:{port}/health")
    print(f"✅ 识别接口: POST http://localhost:{port}/recognition")
    print("\n按 Ctrl+C 停止服务")
    sys.stdout.flush()
    server.serve_forever()
EOF

python3 final_server.py

语音识别不准确

语音识别不准确是常见问题,可能有以下几个原因和解决方案:

🔍 原因分析

原因 说明 解决方案
音频质量 背景噪音、说话距离远 使用降噪麦克风,靠近说话
采样率 Whisper 需要 16kHz 前端录音设置采样率
模型大小 base 模型准确率有限 升级到 larger 模型
语言设置 未指定中文 设置 language="zh"
发音问题 方言、口音 使用更大的模型

✅ 解决方案

1. 升级 Whisper 模型

python

复制代码
# 使用更大的模型(准确率更高)
model = whisper.load_model("medium")  # 或 "large"
模型 大小 准确率 速度
tiny 39MB 一般 最快
base 74MB 较好
small 244MB 中等
medium 769MB 很好
large 1.5GB 最好 最慢

修改服务代码

bash

bash 复制代码
cat > accurate_server.py << 'EOF'
#!/usr/bin/env python3
import json
import tempfile
import os
from http.server import HTTPServer, BaseHTTPRequestHandler
import cgi
import sys
import wave
import numpy as np

print("正在加载 Whisper medium 模型...")
sys.stdout.flush()

try:
    import whisper
    # 使用 medium 模型,准确率更高
    model = whisper.load_model("medium")
    print("模型加载完成!")
except Exception as e:
    print(f"加载失败: {e}")
    sys.exit(1)

# 繁转简
try:
    from opencc import OpenCC
    cc = OpenCC('t2s')
except:
    cc = None

def to_simplified(text):
    if cc:
        return cc.convert(text)
    # 简单转换
    mapping = {'沒': '没', '應': '应', '該': '该', '讓': '让', '們': '们', '這': '这', '個': '个'}
    for t, s in mapping.items():
        text = text.replace(t, s)
    return text

class Handler(BaseHTTPRequestHandler):
    def send_cors_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
    
    def do_OPTIONS(self):
        self.send_response(200)
        self.send_cors_headers()
        self.end_headers()
    
    def do_GET(self):
        if self.path == '/health':
            self.send_response(200)
            self.send_cors_headers()
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps({"status": "ok"}).encode())
        else:
            self.send_response(404)
            self.end_headers()
    
    def do_POST(self):
        if self.path == '/recognition':
            try:
                form = cgi.FieldStorage(
                    fp=self.rfile,
                    headers=self.headers,
                    environ={'REQUEST_METHOD': 'POST'}
                )
                
                if 'audio' not in form:
                    self.send_error(400, "No audio file")
                    return
                
                file_item = form['audio']
                with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
                    tmp.write(file_item.file.read())
                    tmp_path = tmp.name
                
                # 使用更高的参数提升准确率
                result = model.transcribe(
                    tmp_path,
                    language="zh",
                    task="transcribe",
                    temperature=0,
                    best_of=5,           # 尝试5次取最佳
                    beam_size=5,         # 束搜索宽度
                    patience=2.0,
                    condition_on_previous_text=True,
                    compression_ratio_threshold=2.4,
                    logprob_threshold=-1.0,
                    no_speech_threshold=0.6
                )
                os.unlink(tmp_path)
                
                text = to_simplified(result["text"])
                print(f"识别: {text[:80]}...")
                
                self.send_response(200)
                self.send_cors_headers()
                self.send_header('Content-type', 'application/json')
                self.end_headers()
                response = json.dumps({"code": 0, "text": text})
                self.wfile.write(response.encode())
                
            except Exception as e:
                print(f"错误: {e}")
                self.send_response(500)
                self.send_cors_headers()
                self.end_headers()
                self.wfile.write(json.dumps({"code": 1, "msg": str(e)}).encode())
        else:
            self.send_response(404)
            self.end_headers()

if __name__ == "__main__":
    port = 8000
    server = HTTPServer(('0.0.0.0', port), Handler)
    print(f"✅ HTTP 服务启动成功!")
    print(f"📍 地址: http://0.0.0.0:{port}")
    print(f"✅ 使用模型: medium (更高准确率)")
    print("按 Ctrl+C 停止服务")
    server.serve_forever()
EOF

python3 accurate_server.py

前端优化:提升录音质量

修改 Vue 组件的录音参数:

typescript

复制代码
// 获取高质量音频
const stream = await navigator.mediaDevices.getUserMedia({
  audio: {
    sampleRate: 16000,      // 16kHz 采样率
    channelCount: 1,        // 单声道
    echoCancellation: true, // 回声消除
    noiseSuppression: true, // 噪声抑制
    autoGainControl: true   // 自动增益
  }
});
相关推荐
Jay星晴1 天前
Whisper-large-v3语音识别效果对比:与Whisper v2/v1在中文长语音场景差异
whisper·语音识别·asr·星图gpu
FishPotatoChen4 天前
【OpenAI】Whisper 模型架构详解
whisper
weixin_446260855 天前
[特殊字符] Insanely Fast Whisper - 超快音频转录工具!
whisper·音视频
x-cmd6 天前
[260326] x-cmd v0.8.10:跨 Shell 统一配置命令短名;自动装好依赖运行 WhisperLiveKit 实时语音转写
linux·人工智能·ai·whisper·shortcut·x-cmd
ughome16 天前
我做了一个本地字幕提取工具:软字幕优先 + Whisper 转写回退(支持链接/本地文件)
whisper·视频字幕提取
PengShuaiD521 天前
【AI编码】用ChatGPT基于Whisper+ffmpeg实现一个根据视频字幕执行自动化裁剪本地小工具
人工智能·chatgpt·ffmpeg·whisper
susu10830189112 个月前
OpenAI Whisper 把mp3语音转文字
whisper
lili-felicity2 个月前
CANN加速Whisper语音识别推理:流式处理与实时转录优化
人工智能·whisper·语音识别
阿里巴啦2 个月前
python+yt-dlp开源项目,支持 YouTube, Bilibili, TikTok/抖音,快手 等多个平台的视频/音频/字幕下载/ai摘要等功能
python·ffmpeg·whisper·音视频·视频处理·ai摘要·音视频转录