本地AI实验室从零到精通:IT大叔的多节点分布式AI架构完全手册
本地AI实验室从零到精通:IT大叔的多节点分…
本地AI实验室从零到精通:IT大叔的多节点分布式AI架构完全手册
教程看了、Ollama装了、ComfyUI跑了,结果显存爆了、内存炸了、模型加载慢到怀疑人生——不是你不行,是架构没想清楚。这篇把一台服务器到多节点集群的完整思路和实操全给你。
一、先泼冷水:一台机器扛所有AI服务,大概率翻车
写这个标题之前,我已经踩过不止一次坑。
最初的想法很简单——一台主力机,插两块显卡,Docker Compose 一把梭,Ollama、ComfyUI、RAG 知识库、Whisper 语音识别全塞进去。结果呢?
- 显存争夺:ComfyUI 生图吃到 12GB 显存,Ollama 推理立刻开始 swap
- PCIe 瓶颈:两块显卡抢 PCIe 通道,带宽砍半
- 内存溢出:Embedding 模型 + 向量数据库 + ComfyUI 节点缓存,32GB 内存直接干满
- 磁盘 IO 打架:模型加载、ComfyUI 缓存、数据库写入抢同一块 SSD
解决方案不是「再买一台」,而是 把服务拆开,分散到不同节点。下面是我跑了三个月验证过的架构。
二、硬件选型:别拿游戏机当服务器
很多人的误区是拿自己打游戏的主机跑 AI 服务。不是不行,但性能损失大、稳定性差。
核心原则
- 显存是第一生产力:推理/生图都吃显存,显存不够一切免谈
- PCIe 通道数决定多卡效率:消费级主板插两张卡,第二张大概率 x4/x8 而非 x16
- 内存容量决定并发上限:除了推理,还有 embedding、缓存、系统开销
我的推荐配置
如果只有一台机器:至少 64GB 内存 + 1×24GB 显存,用 Docker 限制每个服务的最大资源,务必给每个容器设置 –memory 和 –cpus
三、操作系统与虚拟化:PVE 是最好选择
用裸机 Linux 跑也行,但一旦要加机器、迁移服务、备份整机,Proxmox VE (PVE) 的好处就出来了。
为什么选 PVE
- 快照回滚:装 ComfyUI 插件前打个快照,炸了秒回
- 迁移无忧:服务从一台搬到另一台,在线热迁移
- 资源超分:AI 服务不是 24×7 满载,可以超分 CPU/内存
- 嵌套 Docker:PVE 里开 LXC 或 VM 跑 Docker,隔离性好,爆了不影响宿主机
我的 PVE 规划
PVE Cluster
├── 推理节点 VM (4核/32GB/512GB) → Ollama + Open WebUI
├── 生图节点 VM (6核/32GB/256GB) → ComfyUI + Stable Diffusion
├── 服务节点 LXC (2核/16GB/200GB) → Caddy + PostgreSQL + Redis
└── NAS 容器 → TrueNAS Scale 或 直接 NFS 共享
关键操作:给 AI 推理的 VM 开启 PCIe Passthrough,把显卡直通给 VM,避免虚拟化层损耗。
# 查看显卡 IOMMU 分组
lspci -vnn | grep -i nvidia
# 在 PVE 的 /etc/default/grub 开启 IOMMU
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"
# 更新 grub 后重启
update-grub && pve reboot
四、Docker 编排:别再一个 docker-compose.yml 管所有
每类服务应该有自己的 compose 文件,通过网络相互通信。
标准的目录结构
/opt/docker/
├── ollama/
│ ├── docker-compose.yml
│ └── volumes/
├── comfyui/
│ ├── docker-compose.yml
│ └── volumes/
├── caddy/
│ ├── docker-compose.yml
│ ├── Caddyfile
│ └── data/
├── postgres/
│ ├── docker-compose.yml
│ └── data/
└── vllm/
├── docker-compose.yml
└── models/
Ollama 节点的 docker-compose.yml
version: '3.8'
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- ./volumes/ollama:/root/.ollama
deploy:
resources:
reservations:
devices:
- driver: nvidia
capabilities: [gpu]
count: 1
environment:
- OLLAMA_NUM_PARALLEL=2
- OLLAMA_MAX_LOADED_MODELS=1
open-webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
restart: unless-stopped
ports:
- "3000:8080"
volumes:
- ./volumes/open-webui:/app/backend/data
environment:
- OLLAMA_BASE_URL=http://ollama:11434
关键优化:
- OLLAMA_NUM_PARALLEL=2:限制并行请求数,避免显存炸裂
- OLLAMA_MAX_LOADED_MODELS=1:一次只加载一个模型,切换模型自动卸载
- 给 ComfyUI 也加上类似限制,
--max-memory不要超过显存的 85%
五、网络互连:跨节点服务怎么通信
多节点之间用 Docker overlay 网络 或 Tailscale/WireGuard 打通内网。
方案一:Tailscale(最省心)
# 每个节点安装 Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up
# 所有节点加入同一个 Tailnet,自动分配 100.x.x.x 地址
# 容器里通过 100.x.x.x:端口 直接访问其他节点
方案二:WireGuard(全内网场景)
在 PVE 宿主机上配置 WireGuard,每个 VM 通过宿主机转发。
# 服务节点配置 Caddy 反向代理
cat > /opt/docker/caddy/Caddyfile << 'EOF'
ai.internal.lab {
reverse_proxy 100.64.0.2:11434 # 推理节点
}
draw.internal.lab {
reverse_proxy 100.64.0.3:8188 # 生图节点
}
EOF
方案三:K3s / Nomad(进阶用户)
如果节点超过 3 台,直接上 K3s 轻量 Kubernetes,用 Service 发现和 Ingress 统一入口。
六、模型管理:别一口气下一堆模型
这是最常见的坑——看到 HuggingFace 上有人说这个模型好就下,那个也不放过。结果 500GB 硬盘一周就满了。
我的模型选择策略
不要超过手里的显存上限去跑大模型。14B 模型如果只有 8GB 显存,强行加载会切到 CPU 推理,速度慢 10 倍以上。
模型热切换技巧
在 Open WebUI 里配置多个模型,让用户根据场景手动选择。后台用 ollama run 时,Ollama 会自动卸载闲置模型。
# 查看当前已加载模型
curl http://localhost:11434/api/tags
# 手动卸载模型释放显存
ollama stop qwen2.5:7b
七、ComfyUI 工作流优化:生图更快、不爆显存
ComfyUI 是显存大户,尤其是用了 ControlNet、IP-Adapter、Tiled VAE 这些节点后。
必装节点
- ComfyUI-Manager:装插件、更新、管理一键搞定
- Tiled VAE:高分辨率生图时,把 VAE 解码分块处理,显存占用从 12GB 降到 3GB
- Efficient Loader:一键切换模型和 VAE,避免手动改配置
启动参数优化
# ComfyUI 容器启动命令
python main.py --listen 0.0.0.0 --port 8188 \
--highvram # 如果你有 24GB+ 显存
# --lowvram # 如果显存 <= 8GB,用低速模式
# --novram # 只有 4GB 显存时,全部用系统内存(极慢)
工作流设计原则
1. 先低分辨率出图,再用 Tiled Upscale:直接出 1024×1024 比先出 512×512 再放大,显存占用高 3 倍
2. ControlNet 只开必要的:一个 ControlNet 大约吃掉 2-3GB 额外显存
3. Batch Size 别贪:batch=1 最稳,batch=2 显存翻倍,收益不大
八、性能监控:知道瓶颈在哪才能优化
没有监控就像闭着眼睛开车。部署完成后,第一时间搭建监控。
最简单的方案:netdata + cAdvisor
# netdata 一键监控系统资源
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# cAdvisor 监控容器资源
docker run -d --name cadvisor \
-p 9110:8080 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /sys:/sys:ro \
-v /var/lib/docker/:/var/lib/docker/:ro \
gcr.io/cadvisor/cadvisor:latest
需要重点关注的指标
九、数据备份:别等炸了才想起
AI 服务的数据远比系统本身珍贵——模型配置、工作流、数据库里的对话记录、RAG 知识库。
我的备份策略
# 每天凌晨 3 点,自动备份关键数据到 NAS
0 3 * * * /opt/scripts/backup-ai-data.sh
备份脚本核心逻辑:
#!/bin/bash
BACKUP_DIR="/mnt/nas/backups/ai-$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# Ollama 模型列表和配置
ollama list > $BACKUP_DIR/models.txt
# ComfyUI 工作流和自定义节点
tar czf $BACKUP_DIR/comfyui-workflows.tar.gz /opt/docker/comfyui/volumes/
# 数据库
docker exec postgres pg_dump -U user -d ragdb > $BACKUP_DIR/ragdb.sql
# 保留最近 7 天,删除更早的
find /mnt/nas/backups/ -name "ai-*" -mtime +7 -exec rm -rf {} \;
十、避坑清单:我交过的学费都列在这里
1. 不要用消费级 SSD 当系统盘+模型盘 — 模型反复加载会快速磨损 TLC 颗粒,建议系统用 Optane 或企业级 U.2
2. Docker 日志不限制 — 默认日志驱动不限制大小,跑一个月日志文件能吃掉几十 GB。加 --log-opt max-size=10m --log-opt max-file=3
3. Ollama 默认不加 CORS — 跨节点调用时必须配置 OLLAMA_ORIGINS=*
4. ComfyUI 不设置 –listen — 默认只监听 localhost,跨节点访问需要手动改
5. PVE 不配置 IOMMU 就装 GPU Passthrough — 装好发现透传不了,又要重启重配
6. 不做 Swap 限制 — 系统认为可以用 swap,实际 AI 推理 swap 后慢到不可用
# 关闭所有 swap
swapoff -a
# 或者设置 vm.swappiness=1
echo "vm.swappiness=1" >> /etc/sysctl.conf
十一、常见问题排雷(实战 FAQ)
Q1:Ollama 响应特别慢,有时候十几秒才回复
排查顺序:先查显存,再看模型大小,最后看是否在 swap。
# 第一步:看显存是不是爆了
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
# 第二步:看是否在用 swap
free -h
# 第三步:看加载的模型是否太大
curl http://localhost:11434/api/tags
大概率是显存不足导致切 CPU 推理。解决方案:换 Q4 量化的小模型(如 Qwen2.5-7B-Q4),或者加一块显卡做负载分担。
Q2:ComfyUI 生图到一半报 CUDA Out of Memory
最直接的原因:显存碎片化。连续生图多次后,显存里的缓存没有被彻底清理。
# ComfyUI 重启前先清理显存缓存
sudo fuser -v /dev/nvidia0
nvidia-smi --gpu-reset # 慎用,会杀掉所有 GPU 进程
# 更温和的方式:在 ComfyUI 节点里加一个定时清理脚本
更根本的解决方案:换 Tiled VAE 分块处理,或者降分辨率到 768×768 先用,再看效果决定是否放大。
Q3:Open WebUI 连不上 Ollama
三步定位法:
# 1. 容器内部能通吗?
docker exec open-webui curl http://ollama:11434/api/tags
# 2. 宿主机能通吗?
curl http://localhost:11434/api/tags
# 3. 跨节点能通吗?(替换为实际 IP)
curl http://100.64.0.2:11434/api/tags
哪一步不通,问题就在哪一层。最常见原因:Docker 网络没配置对,或者 OLLAMA_HOST 没设置成 0.0.0.0。
Q4:PVE 里 GPU 透传后 VM 启动报错
# 检查 IOMMU 是否开启
dmesg | grep -i iommu
# 检查显卡是否在独立的 IOMMU 组
find /sys/kernel/iommu_groups/ -type l | grep 0000:0
# 如果跟其他设备绑在一个组里,需要 ACS 补丁或调整 PCIe 槽位
Q5:docker-compose up 报 port already allocated
90% 的情况是之前退出没清理干净:
# 看谁占了端口
ss -tlnp | grep 11434
# 停掉旧容器
docker stop ollama && docker rm ollama
# 或者换端口映射
十二、写在最后
这套架构我跑了三个月,从一台服务器到三台节点,从裸机 Linux 到 PVE 集群,从一个人本地玩到能稳定服务全家。
最大的感受是:AI 能力的瓶颈从来不是模型本身,而是你愿不愿意花时间把基础设施搭扎实。
如果刚开始,只做两件事:
1. 一台机器先跑 Ollama + Open WebUI
2. 加一台机器(或二手工作站)跑 ComfyUI
两个节点之间用 Tailscale 打通,比堆在一台机器上好十倍。等觉得管理起来麻烦了,再上 PVE + Docker 编排。
*如果你正在搭建本地 AI 环境,有踩坑经历或者好方案,欢迎在评论区分享。大叔会挑有价值的问答整理成后续文章。*
