为什么要在本地跑 AI
用大模型 API(OpenAI/Claude/国内各大模型)虽然方便,但有几个痛点:
- 隐私:对话数据会到第三方
- 费用:用多了账单吓人
- 可用性:API 服务不稳定时很头疼
所以干脆自己搭一套,硬件是一次性投入,后续零成本(除了电费)。
硬件层
实验环境配置:
- 显卡: GTX 750 Ti 2GB
- 内存: 16GB
- 系统: Windows
- 用途: 跑 Ollama + 当远程桌面用
这台机器其实还有一块屏幕坏了的笔记本,打算拆电池当无头服务器用,通过 frp 暴露到公网。
软件架构(三层)
Layer 1: Windows 主机
└─ Ollama(运行 Qwen2.5-3B 模型)
port 11434
↓
Layer 2: UGREEN NAS(Docker)
└─ OpenWebUI
port 8080
↓
Layer 3: 阿里云 ECS(Nginx + Tailscale)
└─ Nginx 反向代理
公网: ai.ttc.sx.cn
为什么分层?
- Ollama 在 Win 上:Windows 跑 Ollama 比 Linux 方便,模型文件管理简单
- OpenWebUI 在 NAS 上:NAS 长期在线,Docker 管理方便,Web 界面体验好
- Nginx 在 ECS 上:做 HTTPS 终结和域名路由,还能复用 ECS 的公网 IP
三者之间通过 Tailscale 组网(Headscale 自建协调服务器),全链路加密,不暴露公网端口。
部署步骤
Step 1: Windows 上装 Ollama
从 ollama.com 下载安装包,一行命令跑起来:
# 下载模型
ollama pull qwen2.5:3b
# 启动服务(默认 11434)
ollama serve
3B 模型约 1.8GB,GTX 750 Ti 2G 勉强能跑,速度约 10~15 token/s,日常对话够用。
Step 2: NAS 上装 OpenWebUI
docker run -d \
--network host \
-v open-webui:/app/backend/data \
-e OLLAMA_BASE_URL=http://<Win主机Tailscale IP>:11434 \
--name open-webui \
ghcr.io/open-webui/open-webui:main
关键是 OLLAMA_BASE_URL 要填 Win 主机的 Tailscale IP(这里是 100.64.0.x 网段)。
Step 3: ECS 上配 Nginx 反代
ECS 装了 Tailscale 作为出口节点,OpenWebUI 的请求通过 Nginx 转发到 NAS 的 OpenWebUI:
location / {
proxy_pass http://100.64.0.x:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
域名 ai.ttc.sx.cn 配了 Let's Encrypt 证书(HTTPS 自动续期)。
监控方案
- Uptime Kuma(ECS:3001):监控所有 Tailscale 节点在线状态
- Netdata:计划装在 Win 上,监控主机资源
遇到的问题
GTX 750 Ti 显存不够跑大模型
2GB 显存只能跑 3B,7B 需要 6GB 以上。解决方案是等预算够了换张卡,或者用量化模型减少显存占用。
Tailscale 节点之间连接不稳定
有时 Win 主机关机再开,Tailscale IP 不变但连接会断。需要手动重启 Tailscale 服务或等几分钟自动恢复。目前通过 Uptime Kuma 告警来及时发现。
跨网络传输延迟
Win → NAS → ECS 三层转发,每次请求会有 50~100ms 额外延迟。解决方案是把常用的 Prompt 缓存到 OpenWebUI 里,减少重复请求。
总结
这套架构的优点是:
- 全自托管:数据不出本地网络
- 成本低:ECS 只跑 Nginx(约 20MB 内存),Tailscale 免费版够用
- 可扩展:以后换更强的显卡,Ollama 直接支持
缺点是:
- 延迟比直连慢:毕竟转了三层
- 运维复杂:出问题要排查三个节点
如果只是自己用,其实单机跑 Ollama + OpenWebUI 就够了。我搞这么复杂主要是为了练手网络架构。