原因
OpenWebUI 在未开启 WS 之前,使用的是 Fetch 的 Stream 来拉取回复内容,这个方式存在较多的原因会导致响应的内容是大块流式,而不是字符流式
解决方式
启用 WebSocket,使得数据能够真正的流式传输,让“每个字”都有独立的数据包
解决步骤
部署 Redis
源代码中,Redis 似乎不是开启 WS 的必要条件,但我并未测试这样的场景,并且,基于 Redis 来处理 WS 会话会更稳定且不易丢失,并适用于多副本部署的情况,所以仍然建议通过 Redis 来管理 WS 会话
# Docker 命令
# 你的密码 替换为真实密码,比如 linuxdo
# /data/redis-data 替换为存储 Redis 数据的路径
docker run -itd --name redis -p 6379:6379 -v /data/redis-data:/data redis:latest redis-server --requirepass 你的密码
# Docker Compose
# 你的密码 替换为真实密码,比如 linuxdo
# /data/redis-data 替换为存储 Redis 数据的路径
services:
redis:
image: redis:latest
container_name: redis
restart: always
ports:
- "6379:6379"
volumes:
- /data/redis-data:/data
command: redis-server --requirepass 你的密码 --appendonly yes
注意:请务必设置密码,避免 Redis 被他人使用;如有技术能力,也请通过设置安全组或者 iptables 确保 Redis 只能在内网访问,尽量不要将 Redis 暴露到公网
配置 OpenWebUI 环境变量
增加如下的几个环境变量
# 启用 WS
# 必须是 True,不能是 1,yes 或者其他
ENABLE_WEBSOCKET_SUPPORT=True
# 设置 WS 会话管理,我们使用 Redis
WEBSOCKET_MANAGER=redis
# 设置 Redis 的链接地址
# 如果是容器部署,这里的 127.0.0.1 需要换成容器名,例如 redis
# 实在连不上可以配置成 VPS 的内网 IP
WEBSOCKET_REDIS_URL=redis://:你的密码@127.0.0.1:6379/0
重启 OpenWebUI
重启的方式就多种多样了,根据你的部署方式不同自行选择
# 例子1
# openwebui 换成容器名
docker restart openwebui
# 例子2
# openwebui Service 名
docker compose up openwebui -d
打开 Nginx 的 WS 支持
如果你有使用 Nginx 进行反向代理,或者使用了 CF 这类的 CDN,请打开对应的 WS 支持,具体的配置因人而异,可以把你的配置直接发给 GPT 修改,下面给一个例子
location /ws {
proxy_pass http://your_websocket_server;
proxy_http_version 1.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;
}
观察网页状态
打开你的浏览器的控制台,具体方式是 F12
或者 右键-检查
,切换到 Network
,点击 WS
然后,刷新页面,如果你的配置是没问题的,这里会看到有一个 WS 的连接,状态是 “挂起 (Pending)”
此时,请发送消息,观察是否更加平滑
如果启用后仍然是大块回复,建议对比一下,是不是所有模型都是这样,比如拿 gpt-4o 来看看,是不是能流畅一些,如果 gpt-4o 是流畅的,那说明,是大块回复的那个模型本身的问题,建议咨询上游提供商