🎯 功能目标

✅ 服务器上运行 Whisper(用 GPU 加速)
✅ 网页界面登录(账号密码)
✅ 上传音频文件进行识别
✅ 可选语言(或自动检测)
✅ 返回文本结果


🟢 一、服务器准备

1️⃣ 硬件

  • GPU:NVIDIA
  • 内存:≥ 8 GB
  • 系统:Linux (推荐 Ubuntu 20.04+ / Arch Linux)

2️⃣ 驱动 & CUDA

安装 NVIDIA 驱动 + CUDA(以 Ubuntu 为例):

sudo apt update
sudo apt install nvidia-driver-535 nvidia-cuda-toolkit

验证:

nvidia-smi

🟢 二、Python 环境

1️⃣ 安装 Python

建议 Python 3.9+

sudo apt install python3 python3-venv python3-pip

2️⃣ 创建虚拟环境

python3 -m venv ~/whisper-env
source ~/whisper-env/bin/activate

🟢 三、安装依赖

pip install --upgrade pip
pip install openai-whisper flask flask-login werkzeug

🟢 四、Flask 应用目录结构

在服务器上建一个项目目录,比如:

~/whisper-web/
├── app.py
├── templates/
│ ├── login.html
│ ├── upload.html
│ └── result.html
├── static/
│ └── style.css
├── users.json

🟢 五、核心代码(示例)

app.py

import os
import whisper
from flask import Flask, render_template, request, redirect, url_for, flash, session
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user

app = Flask(__name__)
app.secret_key = 'your_secret_key'

login_manager = LoginManager()
login_manager.init_app(app)

# 简单用户表(示例)
USERS = {'admin': {'password': 'test123'}}

class User(UserMixin):
def __init__(self, id):
self.id = id

@login_manager.user_loader
def load_user(user_id):
if user_id in USERS:
return User(user_id)
return None

# 加载 Whisper 模型(可改成 large / medium)
model = whisper.load_model("medium", device="cuda")

@app.route("/", methods=["GET", "POST"])
def login():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
if username in USERS and USERS[username]['password'] == password:
user = User(username)
login_user(user)
return redirect(url_for("upload"))
else:
flash("Invalid credentials")
return render_template("login.html")

@app.route("/upload", methods=["GET", "POST"])
@login_required
def upload():
if request.method == "POST":
if "file" not in request.files:
flash("No file uploaded")
return redirect(request.url)
file = request.files["file"]
language = request.form.get("language", "auto")

if file.filename == "":
flash("No selected file")
return redirect(request.url)

filename = os.path.join("uploads", file.filename)
os.makedirs("uploads", exist_ok=True)
file.save(filename)

# 处理识别
if language == "auto":
result = model.transcribe(filename)
else:
result = model.transcribe(filename, language=language)

os.remove(filename) # 可保留文件也行

return render_template("result.html", text=result["text"])
return render_template("upload.html")

@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(url_for("login"))

if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)

HTML 文件

templates/login.html

<!doctype html>
<title>Login</title>
<h2>Login</h2>
<form method="post">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" value="Login">
</form>

templates/upload.html

<!doctype html>
<title>Upload Audio</title>
<h2>Upload Audio File</h2>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file"><br>
Language:
<select name="language">
<option value="auto">Auto Detect</option>
<option value="en">English</option>
<option value="ja">Japanese</option>
<option value="zh">Chinese</option>
<!-- 可添加其他 -->
</select><br>
<input type="submit" value="Upload and Transcribe">
</form>
<a href="{{ url_for('logout') }}">Logout</a>

templates/result.html

<!doctype html>
<title>Result</title>
<h2>Transcription Result</h2>
<pre>{{ text }}</pre>
<a href="{{ url_for('upload') }}">Transcribe Another</a> |
<a href="{{ url_for('logout') }}">Logout</a>

🟢 六、运行测试

source ~/whisper-env/bin/activate
python app.py

浏览器访问:

http://<你的服务器IP>:5000

🟢 七、(可选) Nginx + Gunicorn 部署

如果需要生产环境上线,可用 Gunicorn + Nginx:

pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:5000 app:app

然后 Nginx 配置一个反向代理到 127.0.0.1:5000


✅ 总结

🎯 功能

  • 登录验证
  • 上传音频文件
  • 语言选择
  • Whisper GPU 推理
  • 网页返回结果

🔥 未来可扩展

  • 添加任务队列(Celery)
  • 文件历史管理
  • 多用户注册
  • Docker 一键部署

Leave a Reply

Your email address will not be published. Required fields are marked *