共计 3741 个字符,预计需要花费 10 分钟才能阅读完成。
很多人家里的 NAS 组装好后,大部分时间都在跑几个 Docker 挂 PT 刷剧,CPU 和总线常年处于闲置状态。去年底我给家里的自建 2U 机架式 NAS(TrueNAS SCALE,底层为 Debian)塞进去了一张拆机的 RTX 3090 24G,原本只打算给 Jellyfin 做实时硬件转码,但很快我发现:这套 24 小时开机的低功耗 Linux 平台,搭配现阶段成熟的开源推理栈,简直是搭建局域网私有化大模型 Agent 与企业级 RAG 知识库的最佳底座。
但在 NAS 上跑大模型,如果只用 Ollama 跑个 4-bit 量化玩具,遇到稍大并发的流式请求或者带长上下文的 RAG 文档检索时,显存管理僵硬、Token 吞吐骤降的问题暴露无遗。为了压榨这块 24G 显存的极致性能,我将整套推理引擎换成了生产级高并发框架 vLLM,结合 Qdrant 向量数据库,构建了一套开箱即用的 OpenAI 兼容本地推理服务。下面复盘这套架构搭建中的核心配置、避坑实录与压测数据。
一、NAS 底层环境准备:显卡直通与驱动避坑
在 TrueNAS SCALE 这种高度集成的 NAS 系统中玩 GPU 容器化,最怕的是驱动冲突与权限丢失。很多新手容易在这一步卡住好几天。
1. 确认 GPU 驱动与容器工具链
Debian 底层的 SCALE 已经内置了 Nvidia 基础驱动,但要让 Docker 正常调用 GPU,必须确认 nvidia-container-toolkit 处于正常状态。先 SSH 登录 NAS 终端:
# 检查显卡是否正确识别
nvidia-smi
# 确保持久化模式开启,降低唤醒延迟并避免功耗墙策略错乱
sudo nvidia-smi -pm 1
# 验证容器运行时是否包含了 nvidia runtime
docker info | grep -i runtime
# 预期输出应包含:Runtimes: runc nvidia
避坑点:如果你的 NAS 主板开了 IOMMU 且把显卡绑定给了 PCI-Passthrough(直通虚拟机),宿主机的 Docker 就无法直接使用它。玩容器化部署时,务必将 GPU 留给宿主机本身,关闭虚拟化屏蔽。
二、部署与调优:vLLM + Qdrant 最佳实践
这套方案的核心拓扑非常清晰:vLLM 负责加载 Qwen2.5-7B/14B 等开源主力模型并暴露 OpenAI 兼容流式 API;Qdrant 提供毫秒级向量检索支持;上层由自动化 Agent 或 WebUI 串联整个链路。
1. 显存算力与推理引擎核心配置
创建属于这套 AI 服务的专用存储池目录,例如 /mnt/storage/ai-services,并准备 docker-compose.yml:
services:
# 高并发流式推理引擎
vllm:
image: vllm/vllm-openai:v0.6.3.post1
container_name: nas-vllm
runtime: nvidia
restart: unless-stopped
environment:
- NVIDIA_VISIBLE_DEVICES=all
- HUGGING_FACE_HUB_TOKEN=""
ipc: host
ports:
- "8000:8000"
volumes:
- /mnt/storage/ai-models:/root/.cache/huggingface
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
command: >
--model Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4
--served-model-name qwen-local
--gpu-memory-utilization 0.85
--max-model-len 8192
--max-num-seqs 16
--enable-chunked-prefill
--trust-remote-code
# 生产级向量数据库
qdrant:
image: qdrant/qdrant:v1.12.0
container_name: nas-qdrant
restart: unless-stopped
ports:
- "6333:6333"
- "6334:6334"
volumes:
- /mnt/storage/ai-services/qdrant_storage:/qdrant/storage
environment:
- QDRANT__SERVICE__MAX_REQUEST_SIZE_MB=32
2. 关键参数深度解析(老极客避坑)
ipc: host:绝对不能省。如果使用默认的 Docker IPC 空间,多进程 /PagedAttention 在进行显存与系统内存共享时会直接触发Bus error (core dumped)导致容器崩溃。--gpu-memory-utilization 0.85:别贪心设 0.95。因为 NAS 本身可能还在跑 Jellyfin 转码、后台定期脚本,必须留出 15%(约 3.6GB)作为 KV Cache 暴涨的突发安全余量和轻度转码占用。--enable-chunked-prefill:针对 RAG 场景的绝对神器。当知识库将长篇文档作为 Prompt 注入时,Chunked Prefill 可以把庞大的长提示词拆分为小块,让短请求和流式 Token 不会被长文本的 Pre-fill 阶段强行阻塞。
三、性能对比与选型实测:vLLM vs Ollama
我在 NAS 本地执行了一轮标准的基准压测,模型均选用 Qwen2.5-7B-Instruct(Int4 量化),模拟 8 个并发 RAG 查询场景(平均输入 Prompt 包含知识库片段约 2000 tokens,要求输出 300 tokens):
| 指标维度 | Ollama (默认并发) | vLLM (PagedAttention) | 差异体验 |
|---|---|---|---|
| 首字延迟 (TTFT) | 1850 ms | 410 ms | vLLM 流式吐字几乎感知不到停顿 |
| 系统总吞吐 (Tokens/s) | ~38.2 tok/s | 162.7 tok/s | 吞吐提升超过 4 倍,无并发排队瓶颈 |
| 显存利用稳定性 | 频繁碎片化,容易 OOM | 动态分页锁定,极低碎片 | 长时间运行无需重启容器 |
实测数据一目了然:Ollama 适合本地工作站快速试玩单次交互,但要在 NAS 上承载全家各终端或小团队工作流的稳定并发,基于 PagedAttention 的 vLLM 架构才是真正的生产力工具。
四、高并发流式代理与健康排障脚本
NAS 在家庭网络中通常还会面临网络抖动或定时唤醒的问题。为了防止大模型容器因异常掉线而导致前端应用全线报错,我在 NAS 上配置了一个自动化监控并校验流式吐字的 Python 探测脚本:
import requests
import json
import time
API_URL = "http://127.0.0.1:8000/v1/chat/completions"
def health_check_stream():
payload = {
"model": "qwen-local",
"messages": [{"role": "user", "content": "ping"}],
"max_tokens": 5,
"stream": True
}
start_time = time.time()
try:
response = requests.post(API_URL, json=payload, stream=True, timeout=5)
response.raise_for_status()
first_chunk_received = False
for line in response.iter_lines():
if line:
decoded = line.decode('utf-8')
if decoded.startswith("data:") and decoded != "data: [DONE]":
if not first_chunk_received:
ttft = (time.time() - start_time) * 1000
print(f"[OK] vLLM 健康运行 - 首字延迟: {ttft:.2f}ms")
first_chunk_received = True
return True
return False
except Exception as e:
print(f"[ERROR] 推理服务异常: {str(e)}")
return False
if __name__ == "__main__":
health_check_stream()
配合 crontab 定时运行该脚本,若连续 3 次探测失败,自动触发 docker restart nas-vllm,即可保证 NAS 的本地推理服务常年在线可用。
总结与避坑心得
在折腾 NAS 本地大模型体系的过程中,最大的心得就是 不要盲目追求高参数全精度模型。对于个人和小团队的知识库检索、日常写代码辅助场景,一张 24G 显存的消费级显卡搭配 GPTQ/AWQ 4-bit 量化的 7B~14B 模型,在响应速度和准确率之间有着最好的平衡。把显存算力留给上下文长度(KV Cache)和向量检索并行,比死磕一个半速爬行的 70B 模型实用太多。
按照这套方案跑起来后,局域网内的各类工具(如沉浸式翻译、ChatBox、Dify 等)全部无缝切换到 NAS 本地节点,既避免了调用商业 API 的账单焦虑,也彻底打消了隐私文档上传云端的安全顾虑。