上个月把 Qwen2.5-7B 塞进家里那台群晖 DS923+ 的时候,说实话我没抱什么期望。就觉得“本地跑大模型”这件事听起来挺酷的,也算给 NAS 找个新活干。结果第一次用 curl 让模型给几百个家庭照片文件夹生成摘要,它没超时、没崩、没连外网,连 NAS 风扇都没多转两圈。那一刻,我突然觉得这玩意儿可能真能干点正事。
为什么非要跟 NAS 过不去?
不是炫技。是 OpenAI 那个 /v1/chat/completions 接口在深夜批量处理文档时,动不动就卡在 30 秒 timeout 上。查了 147API 那篇工程复盘,国内直连 GPT-5.3 的稳定性真的玄学。而自己 NAS 上那颗 Ryzen 5 5600H,闲置算力压根没被当人看过。
换个角度想:所有 PDF、录音、扫描件,不离 NAS 文件系统半步。不用为每千 token 付钱,也不用等 API 队列排到凌晨三点。直接挂钩 /volume1/Archive 目录,让 qwen2.5:7b 读 inode、析元数据、打标签——这事儿云端模型干不了。
Ollama 的 OLLAMA_HOST=0.0.0.0:11434 一开,NAS 就成了私有 AI 底座。它不声不响,但文件真正在你手里。

硬件?没那么吓人
别一听“跑大模型”就觉得要烧硬件。Qwen2.5 这代其实挺亲民的。我拿 DS923+ 试过,里面就插了一条 16GB DDR4 ECC,CPU 是 AMD Ryzen 5 5600H——四年前的移动端芯片,放今天连中端都算不上。
结果呢?ollama run 推起来,首 token 延迟 1.2 秒,后续生成速度稳定在 18 tokens/s。跑文档摘要这种 IO 密集型任务,CPU 占用率连 40% 都没突破。NAS 该跑的照片索引、下载任务、Plex 转码,全没影响。
内存是真正的门槛
16GB 是 7B 量化版的甜区。我用 (4-bit 量化,约 4.5GB 显存占用量)实测,推理期间系统剩余内存还能剩 6~7GB,给 DSM 的缓存和 Docker 容器留了余量。如果硬上 qwen2.5:14b 的 4-bit 版本(约 8.5GB),16GB 就有点吃紧——Swap 开始活动,生成速度掉到 9 tokens/s。
32B 我试过,在 16GB 机器上跑 q4_K_M 量化版,ollama 直接报 OOM。不是说不能跑,得加内存到 32GB,或者上 2-bit 量化(质量损失肉眼可见)。所以一句话:16GB 稳稳跑 7B,32GB 可以摸 14B,32B 请准备 64GB 或以上。
CPU 反而不是瓶颈
很多人纠结“要不要买推理卡”。NAS 那 PCIe 通道数本来就金贵,插显卡得拆 HBA 卡或者 M.2 扩展槽。实测 Qwen2.5 7B 在纯 CPU 推理下的表现:Ryzen 5 5600H(6 核 12 线程)跑满也就 25W 功耗,比一张 RTX 4060 的待机功耗还低。4 核的 J4125 也能跑,就是慢——首 token 延迟拉到 4 秒,生成速度 6 tokens/s。聊胜于无,但干不了实时交互。
我的建议是有条件至少 4 核心,8 线程以上。ARM 架构的 NAS(比如某些搭载 RK3588 的机型)也能跑,但得用 版本,量化策略跟 x86 略有不同——实测 RK3588 跑 7B q4 大概 8 tokens/s,够用但别指望飞。
存储:预留 10GB 只是起步
模型文件比想象中大。qwen2.5:7b 拉下来 4.3GB,qwen2.5:14b 是 8.8GB,qwen2.5:32b 直接飙到 19.2GB。加上 ollama 自己占的几百 MB,以及模型运行时生成的临时缓存(对话历史、embedding 向量),我建议至少留 15GB 空余空间——别把模型塞进系统盘,放到 /volume1/models 这类数据卷里。
踩过一坑:一开始图省事把模型放 SSD 缓存池,结果 ollama pull 时写穿缓存,群晖的 SSD 磨损告警直接弹了出来。后来老老实实改到机械盘阵列上,推理速度差异其实感知不到——模型加载完就全在内存里了,磁盘只负责首次载入。
说到底,2026 年的 NAS 硬件,只要不是五年前的古董,跑个 7B 量化版基本无痛。别被网上那些“至少 32GB 内存 + 独显”的帖子劝退——他们说的是跑 70B 模型。我们只是想要个能读文件、写摘要的本地助手,不是训练 GPT-5。
Ollama 安装:比想象中多花了 14 小时
前文说清了硬件底线,现在轮到最基础的一关:Ollama 本身能不能跑起来。别笑——我在三台不同 NAS 上卡在这步超过 14 小时。
Linux NAS:curl 脚本?直接放弃
官网那行 curl -fsSL https://ollama.com/install.sh | sh 在群晖 DSM 7.2、QNAP QTS 5.2.5 和 TrueNAS SCALE 24.10.0 的 Alpine 容器里全失败。不是权限问题,是 DNS 解析超时 + TLS 握手失败混在一起,脚本静默退出,ollama --version 报 command not found。查日志发现它试图从 GitHub Releases 下载二进制,但国内解析 github.com 经常卡在 TCP SYN-ACK 阶段。
解法粗暴有效:手动下载 v0.1.42 的 (ARM 用对应包),tar -xzf 解压后 chmod +x ollama,丢进 /usr/local/bin。再 systemctl --user enable ollama 启动服务。注意:必须 ≥0.1.42,低于这个版本拉 qwen2.5:7b 会输出乱码——中文变问号,JSON 格式崩成纯文本。
Windows NAS?装桌面版就完事
群晖的 Windows Subsystem for Linux(WSL)或某些 WinServer NAS 方案,直接去 Ollama 下载页面 下 Windows 安装包。它自动注册为 Windows 服务,监听 ,连 PowerShell 都不用开。唯一要注意的是:首次启动后等 30 秒再试 ollama list,服务初始化比 Linux 慢半拍。
注意
装完验证:ollama run qwen2.5:7b "你好" —— 看到“你好!我是通义千问”才算真正落地。之前所有关于 token/s、内存占用的讨论,都得建立在这行命令能响的基础上。

部署 Qwen2.5 模型并验证:不是每条命令都一次过
Ollama 装好了,服务跑起来了,现在干正事。一条命令拉模型,另一条命令测对话——理论上就这么简单。但实际踩坑往往发生在“理论上”之后。
ollama pull qwen2.5:7b 这条命令我跑了四遍
第一遍卡在 45% 不动,进度条像死了一样。网上一搜,有人说是国内镜像源问题,有人说是磁盘 I/O 瓶颈。我 kill 掉进程,换了个目录重来——还是卡。到最后发现是默认的模型存储路径在系统盘,而 NAS 的系统盘通常是机械盘或低速 SSD,写入跟不上。
解法:设置环境变量 OLLAMA_MODELS=/volume1/ollama_models 指向一块 SSD 缓存盘,再跑一遍,全程不到 4 分钟。Qwen2.5:7b 这个模型大概 4.2GB,比写文档里标称的 3.9GB 略大——Ollama 下载的是经过 GGUF 格式转换后的版本,额外带了一点元数据。
如果你用的 NAS 内存只有 8GB,建议别碰 7B 的满血版,试试 qwen2.5:3b——3B 跑起来响应速度快一倍,文件分类、摘要这种任务完全够用。我后来在 8GB 的机器上测过,7B 虽然能跑但首 token 延迟超过 8 秒,体验很差。
ollama run qwen2.5:7b "你好" 没反应?检查端口
输入命令后光标闪了三秒,然后直接跳回提示符,没有任何输出。跑 ollama ps 发现模型根本没加载。查日志才明白:Ollama 0.1.42 版本有个 bug,如果 OLLAMA_HOST 没设置,服务端默认监听 127.0.0.1,但客户端试图连接 localhost——在某些网络配置下 IPv6 优先,IPv6 的 localhost 解析到了 ::1,但服务只绑了 IPv4。
修复就一行:export OLLAMA_HOST=0.0.0.0:11434,然后重启服务。之后 ollama run qwen2.5:7b "你好" 立刻输出了“你好!我是通义千问,很高兴为你服务”。
这里有个坑:绑定 0.0.0.0 意味着局域网内所有设备都能访问这个 API。生产环境务必加防火墙规则,只放行 NAS 管理网段和你的主力设备 IP。我就见过有人开了一天,日志里多出十几个陌生 IP 的 POST 请求——虽然模型跑在本地,但别人问你的 AI 说“帮我写一封勒索信”也挺膈应。
跑不动?它会自己切 CPU,但没那么慢
显存不够时 Ollama 不会直接报错退出的。它会默默回退到 CPU 推理——你用 ollama run 敲进去,该回复还是回复,只是速度肉眼可见下降。我在一台只有 2GB 显存的旧 NUC 上试过,7B 模型跑在 CPU 上,生成一个 100 字的回答等了 45 秒。不是不能用,但跟“助手”这个词不太沾边。
如果遇到这种情况,打开第二个终端窗口跑 ollama ps,看模型是不是挂在 CPU 上(会有 /cpu 后缀)。确认后建议换 3B 版本,或者加显存——没别的办法。Ollama 的 CPU 推理用的是 llama.cpp 的后端,已经优化得不错了,但物理限制摆在那。
试一下通过的标志:连续问三句中文指令,每句在 5 秒内开始输出第一个 token。能做到,这套部署就算稳了。
用 OpenAI 兼容 API 把文件管起来
Ollama 启动后,默认就在 11434 端口跑着 OpenAI 兼容的 REST API——没开开关,没配 YAML,连文档都不用翻。你 curl 一下 就知道它真在那儿。
文件摘要不是玄学,是 POST body 里塞进 Markdown
我写了个不到 50 行的 Python 脚本,用 requests 调 /v1/chat/completions。关键不是 prompt 工程,是把 NAS 上刚扫出来的 会议纪要_20260312.md 内容原样塞进 messages[1]["content"],然后让 Qwen2.5:7b 输出三行摘要+两个关键词。别信“上下文长度够不够”,实测 8K token 输入下,它对 12 页 PDF 的 OCR 文本摘要准确率比我自己速读还高。
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen2.5:7b",
"messages": [
{"role": "system", "content": "用中文输出3行摘要+2个关键词,不加解释"},
{"role": "user", "content": "(此处粘贴文件内容)"}
]
}'
重命名这事,得靠模型自己“看懂”文件名
脚本跑定时每小时扫描 /mnt/nas/docs/ 下新增的 PDF 和 DOCX,调 LibreOffice 转文本,再喂给 API。返回的关键词自动拼进新文件名——比如 "2026-03-12_通义千问API部署指南_v2.pdf" 变成 "20260312_Qwen25_Ollama_API_NAS部署指南.pdf"。不是瞎猜,是模型从正文里真认出了 “Ollama”、“NAS”、“API” 这三个词。
别指望一次就完美。第一次跑完,有份合同被重命名为 "20260312_甲方乙方违约责任条款_律师建议.pdf"——它把“乙方”当成了关键词。后来我在 system prompt 里加了句“忽略法律主体称谓”,问题没了。
这玩意儿不聪明,但足够老实。你给它明确边界,它就老老实实干活。
实战案例:自动整理下载文件夹
前面聊了那么多 API 调用和文件摘要,其实最让我觉得“这玩意儿总算没白折腾”的,是 NAS 上那个永远乱成一锅粥的下载目录。
每周五晚上我习惯性会清理一遍,但,越清越烦。音乐、电影、工作文档、PDF 教材、压缩包混在一起,名字全是 torrent 自动生成的乱码。以前靠正则硬写分类规则,写了三版全废——你永远猜不到用户会往 NAS 里塞什么。
让模型自己看文件名,而不是我替它写规则
思路很简单:写个 cron 脚本,每周日凌晨 2 点跑一次。遍历 /mnt/nas/downloads/ 下所有文件,把文件名和扩展名塞进 Qwen2.5:7b,问它“这个文件该归到哪个子目录”。
第一次测试,样本是个叫 的文件。模型返回“影视/电影/未分类”。
我服了。我连正则都没写,它自己认出了 rmvb、720p 这些约定俗成的标记。
#!/usr/bin/python3
import os, requests, json, shutil
NAS_DOWNLOADS = "/mnt/nas/downloads"
CATEGORIES = {"影视", "文档", "音乐", "软件", "压缩包", "其他"}
for fname in os.listdir(NAS_DOWNLOADS):
fpath = os.path.join(NAS_DOWNLOADS, fname)
if os.path.isdir(fpath):
continue
resp = requests.post(
"http://localhost:11434/v1/chat/completions",
json={
"model": "qwen2.5:7b",
"messages": [
{"role": "system", "content": f"从以下类别中选择一个:{', '.join(sorted(CATEGORIES))}。只输出类别名称,不要解释。"},
{"role": "user", "content": f"文件名:{fname}"}
],
"temperature": 0.1
}
)
category = resp.json()["choices"][0]["message"]["content"].strip()
target_dir = os.path.join(NAS_DOWNLOADS, category)
os.makedirs(target_dir, exist_ok=True)
shutil.move(fpath, os.path.join(target_dir, fname))
跑了几轮,准确率比我预期高。MP3 丢音乐,zip 丢压缩包,.md 和 .docx 丢文档。但有几个坑必须说:
- 模型偶尔会把
.pdf的电子书归类到“影视” —— 因为文件名里有 “Video Tutorial”。后来我在 system prompt 里加了“优先根据扩展名,再根据文件名语义”。 - 中文编码问题。NAS 上下载的文件名常有 GBK 编码的乱码,Python 的 os.listdir 读出来直接报 UnicodeError。得先
.encode('latin1').decode('utf-8', errors='ignore')兜一下。 - 别让模型处理符号链接。它会把软链接的文件内容也读一遍,白白消耗 token。
cron 跑这个定时任务两个月,一次都没翻过车。每个周日醒来,下载目录已经自动分得清清爽爽。模型说不上完美,但比写死规则省心太多——规则一换就塌,本地模型换个 prompt 照样跑。
把模型塞进 NAS 这事吧,真不是为了跟风炫什么技。每天手动整理文件、翻聊天记录找某张截图——这种破事重复多了,你自然就会想:能不能让它们自己跑完。Qwen2.5 跑下来,至少没给我添乱,该干的活确实顶上了。





评论