为什么要在本地跑 AI

用大模型 API(OpenAI/Claude/国内各大模型)虽然方便,但有几个痛点:

  1. 隐私:对话数据会到第三方
  2. 费用:用多了账单吓人
  3. 可用性: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 就够了。我搞这么复杂主要是为了练手网络架构。