核心内容摘要
DeerFlow 项目笔记
SenseVoice Small语音转文字生产环境部署Nginx反向代理配置
为什么需要Nginx反向代理你可能已经成功在本地跑通了SenseVoice Small的Streamlit服务输入streamlit run app.py后浏览器打开http://localhost:8501上传一段粤语播客音频几秒钟就生成了准确的中文文本——体验很丝滑。
但当你想把它部署到公司内网供团队共用或者对外提供一个简洁域名如https://asr.example.com时问题就来了。
Streamlit原生WebUI默认只监听localhost不支持HTTPS、无法处理高并发请求、没有访问控制、不能自动重定向HTTP到HTTPS更关键的是——它压根没考虑生产环境的安全与稳定性需求。
这时候Nginx就不是“可选项”而是必选项。
它像一位经验丰富的门卫兼调度员把外部用户发来的HTTPS请求安全地接进来去掉加密层再以高效、稳定的方式转发给后端的Streamlit服务同时还能做负载均衡、静态资源缓存、请求限流、日志审计……而这一切只需要几行配置就能完成。
本篇不讲理论不堆参数只聚焦一件事如何用最简、最稳、最贴近真实生产环境的方式把SenseVoice Small接入Nginx反向代理并确保多用户、长时间、高频率使用下不崩、不卡、不出错。
部署前的关键准备
1 环境确认别让基础问题拖慢进度在动Nginx之前请花2分钟确认以下三点。
这比后面调试半小时更省时间GPU可用性已验证运行nvidia-smi能看到显卡信息且torch.cuda.is_available()返回True。
SenseVoice Small依赖CUDA加速若GPU不可用Nginx配得再好识别也会慢如蜗牛。
Streamlit服务已稳定运行先不走Nginx在服务器终端执行streamlit run app.py --server.port8501 --server.address
0.
0.
0然后从另一台机器用浏览器访问http://你的服务器IP:8501能正常上传、识别、显示结果。
这一步验证模型、依赖、路径全部OK。
防火墙已放行端口确认服务器防火墙如ufw或firewalld已开放8501Streamlit和80/443Nginx端口。
常见命令sudo ufw allow 8501 sudo ufw allow 80 sudo ufw allow 443注意--server.address
0.
0.
0是关键。
Streamlit默认只绑定
127.
0.
1不加这句Nginx根本连不上后端。
2 Nginx安装与基础服务检查Ubuntu/Debian系统一行搞定sudo apt update sudo apt install -y nginxCentOS/RHEL系统sudo yum install -y nginx # 或新版sudo dnf install -y nginx安装完成后立即检查Nginx状态sudo systemctl status nginx看到active (running)且无报错说明基础服务已就绪。
此时访问http://你的服务器IP应看到Nginx默认欢迎页——这是你和Nginx建立信任的第一步。
核心Nginx配置详解
1 创建专属配置文件推荐做法不要直接修改/etc/nginx/nginx.conf主配置。
生产环境最佳实践是为每个服务创建独立配置文件放在/etc/nginx/conf.d/目录下由主配置include加载。
这样清晰、易维护、防误操作。
创建文件sudo nano /etc/nginx/conf.d/sensevoice.conf粘贴以下完整配置已针对SenseVoice Small深度优化upstream sensevoice_backend { server
127.
0.
1:8501; keepalive 32; } server { listen 80; server_name asr.example.com; # ← 替换为你自己的域名 # 强制HTTPS重定向启用SSL后取消注释此行 # return 301 https://$server_name$request_uri; location / { proxy_pass http://sensevoice_backend; proxy_http_version
1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 关键解决Streamlit WebSocket长连接问题 proxy_read_timeout 300; proxy_send_timeout 300; # 缓冲区调优避免大音频上传失败 client_max_body_size 200M; proxy_buffering on; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; } # 静态资源缓存Streamlit会动态生成JS/CSS location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control public, immutable; } }
2 配置逐项解读每一行都为SenseVoice而设upstream sensevoice_backend定义后端服务池。
这里只有一台
127.
0.
1:8501但未来可轻松扩展为多实例负载均衡。
proxy_read_timeout 300和proxy_send_timeout 300重中之重。
SenseVoice Small处理长音频如30分钟会议录音可能耗时超过60秒。
默认Nginx超时是60秒不改就会中断连接前端显示“网络错误”。
300秒5分钟是安全余量。
client_max_body_size 200M允许上传最大200MB的音频文件。
mp3/wav原始录音常达百MB远超Nginx默认的1MB限制。
proxy_buffer_*系列Streamlit响应体较大含大量JS、CSS、Base64图标缓冲区太小会导致502 Bad Gateway。
此处配置经实测可稳定承载高清UI。
Upgrade $http_upgradeConnection upgrade支持WebSocket协议。
Streamlit UI的实时状态更新如“ 正在听写...”动画、文件上传进度条都依赖它。
缺了这两行UI会卡死或功能异常。
X-Forwarded-*头确保后端Python代码如app.py中能正确获取用户真实IP、协议类型对后续加访问日志、限流等至关重要。
3 启用配置并重启Nginx保存文件后先语法检查sudo nginx -t输出syntax is ok且test is successful说明配置无误。
然后重载Nginx非restart避免服务中断sudo systemctl reload nginx此时访问http://asr.example.com或你的IP应该和直接访问http://IP:8501效果完全一致——但所有流量已由Nginx接管。
HTTPS安全加固生产必备没有HTTPS的语音服务就像没锁门的保险柜。
音频内容敏感传输过程必须加密。
1 使用Certbot一键获取免费SSL证书安装Certbotsudo apt install -y certbot python3-certbot-nginx执行签发假设你已将域名asr.example.com解析到该服务器IPsudo certbot --nginx -d asr.example.com全程交互式引导按提示操作即可。
Certbot会自动向Let’s Encrypt申请证书修改/etc/nginx/conf.d/sensevoice.conf添加HTTPS server块配置自动续期systemd timer
2 手动配置HTTPS备用方案若Certbot不可用可手动编辑配置。
在sensevoice.conf末尾追加server { listen 443 ssl http2; server_name asr.example.com; ssl_certificate /path/to/fullchain.pem; # ← 替换为你的证书路径 ssl_certificate_key /path/to/privkey.pem; # ← 替换为你的私钥路径 # 推荐的安全协议与加密套件 ssl_protocols TLSv
2 TLSv
3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; # HSTS强制浏览器只走HTTPS add_header Strict-Transport-Security max-age31536000; includeSubDomains always; location / { proxy_pass http://sensevoice_backend; # 复制上面HTTP块中的所有proxy_*配置 proxy_http_version
1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 300; proxy_send_timeout 300; client_max_body_size 200M; proxy_buffering on; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; } } # HTTP自动跳转HTTPS取消前面的注释 server { listen 80; server_name asr.example.com; return 301 https://$server_name$request_uri; }证书路径提示若用Certbot证书通常在/etc/letsencrypt/live/asr.example.com/下fullchain.pem和privkey.pem即所需文件。
生产级健壮性增强
1 防止Streamlit进程意外退出Streamlit服务在后台运行但默认没有进程守护。
服务器重启或OOM内存溢出可能导致服务消失。
用systemd守护是最简单可靠的方案。
创建服务文件sudo nano /etc/systemd/system/sensevoice.service内容如下[Unit] DescriptionSenseVoice Small ASR Service Afternetwork.target [Service] Typesimple Useryour_username # ← 替换为实际运行用户如ubuntu、csdn WorkingDirectory/path/to/your/sensevoice/project # ← 替换为app.py所在目录 ExecStart/usr/bin/streamlit run app.py --server.port8501 --server.address
0.
0.
0 --server.headlesstrue Restartalways RestartSec10 EnvironmentPATH/home/your_username/.local/bin:/usr/local/bin:/usr/bin:/bin EnvironmentPYTHONPATH/path/to/your/sensevoice/project [Install] WantedBymulti-user.target启用并启动sudo systemctl daemon-reload sudo systemctl enable sensevoice.service sudo systemctl start sensevoice.service sudo systemctl status sensevoice.service # 检查是否active现在即使Streamlit崩溃systemd也会在10秒内自动拉起真正实现“永不掉线”。
2 Nginx日志精细化管理默认Nginx日志过于笼统。
为快速定位问题建议单独记录SenseVoice访问日志包含关键字段在sensevoice.conf的server块内添加access_log /var/log/nginx/sensevoice_access.log main_ext; error_log /var/log/nginx/sensevoice_error.log warn; log_format main_ext $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent rt$request_time uct$upstream_connect_time uht$upstream_header_time urt$upstream_response_time;然后创建日志目录并赋权sudo mkdir -p /var/log/nginx sudo touch /var/log/nginx/sensevoice_access.log /var/log/nginx/sensevoice_error.log sudo chown www-data:www-data /var/log/nginx/sensevoice_*.log重启Nginx后/var/log/nginx/sensevoice_access.log将记录每次识别的耗时rt、后端响应时间urt帮你精准判断是网络慢、GPU慢还是模型本身慢。
实际效果验证与
常见问题排查
1 三步验证法确保万无一失基础连通性curl -I http://asr.example.com→ 应返回HTTP/
1 200 OK且Server: nginx头存在。
HTTPS与重定向curl -I http://asr.example.com→ 应返回301 Moved PermanentlyLocation: https://...。
curl -I https://asr.example.com→ 应返回200 OK且Strict-Transport-Security头存在。
端到端功能用浏览器访问https://asr.example.com上传一个10秒MP3点击“开始识别 ⚡”。
观察UI是否流畅显示“ 正在听写...”是否在10秒内返回高亮文本右上角是否显示“GPU: True”证明CUDA生效
2 高频问题速查表现象可能原因快速解决访问域名显示502 Bad GatewayStreamlit未运行或Nginx无法连接
127.
0.
1:8501sudo systemctl status sensevoice.servicetelnet
127.
0.