前言
Immich 在 TrueNAS 上已经用了有一段时间,之前一直没单独写它。应用商店里就能安装,真正折腾的是模型:网络不通时下载不了,手动复制进去以后,升级又可能需要重新放一遍。每次更新都要处理这些文件,也就很难放心地自动升级。
最近把 Immich 升级到 v3.3.6,顺便整理了模型目录。这篇记录部署和离线模型的配置,方便以后更新时继续使用已有模型。
一、部署 Immich
上一篇 NAS 折腾日记(9)TrueNAS 部署与存储配置 已经介绍了这台异地 NAS 的安装、数据集和 Apps 配置。Immich 直接安装在 TrueNAS Apps,照片、数据库和模型都保存在这台 NAS 上。机器是 Intel N100,32 GB 内存,带 Intel 核显;系统为 TrueNAS 25.10.8。下面使用的应用版本是 1.14.62,对应 Immich v3.3.6。
1.1 数据集配置
在 TrueNAS 的 Datasets 中创建 apps/immich,下面分别创建 data、pgData 和 mlcache。以下统一用 /mnt/pool 作为存储池示例路径,使用时替换为自己的路径。
| 用途 | 宿主机示例路径 | 容器内路径 |
|---|---|---|
| 上传照片与派生文件 | /mnt/pool/apps/immich/data |
服务端 /data |
| PostgreSQL 数据 | /mnt/pool/apps/immich/pgData |
数据库 /var/lib/postgresql |
| 机器学习模型 | /mnt/pool/apps/immich/mlcache |
模型服务 /mlcache |
新建的照片数据集可以使用 Apps 预设,让应用用户拥有修改权限。数据库目录按应用要求设置 UID 999;模型目录需要允许机器学习容器的运行用户读写,后面生成的编译缓存也会写在这里。已有目录先检查用户和 ACL,避免递归修改权限影响原来的文件访问。
如果照片已经整理在其它目录,可以另外添加外部图库。例如将 /mnt/pool/photos 只读挂载到服务端的 /photos。/data 仍然保留,用于 Immich 上传的照片及生成的缩略图等文件。
1.2 应用安装
进入 Apps → Discover Apps,搜索 Immich 并安装,界面可以参考 TrueNAS 安装说明。
启用 Machine Learning。这里使用 N100 的核显,所以 Machine Learning Image Type 选择 openvino,GPU 配置中分配 Intel GPU。数据库和 Redis 分别设置密码。
Storage Configuration 中,数据、数据库和机器学习缓存都选择 Host Path,填入上面的三个目录。Host Path 就是把指定的宿主机目录挂进容器,容器重建后仍能使用这些文件。自动权限处理也要核对目标目录和运行用户后再启用。
Web 端口沿用 TrueNAS 应用模板的默认值 30041,也可以在安装表单中修改。部署完成后访问 http://YOUR_TRUENAS_IP:30041,按页面引导创建管理员账号。使用外部图库时,在管理界面添加前面挂载的 /photos 并扫描;手机照片则通过客户端选择备份相册上传。
二、模型缓存目录
以前每次更新 Immich,我都要把下载好的模型重新复制到机器学习容器的缓存目录。网络环境没有变,自动下载依然不通,更新完就得再手动处理一次。
当时应用模板把机器学习缓存设成了匿名卷。后来 TrueNAS 的 Immich 应用增加了独立的 Machine Learning Cache 存储选项,可以给机器学习容器指定 Host Path,我才把模型搬到 NAS 上的固定目录。
现在在应用的 Storage Configuration 中,将 Machine Learning Cache 设为 Host Path,选择 /mnt/pool/apps/immich/mlcache。它会挂到机器学习容器的 /mlcache,以后直接把模型放进这个宿主机目录即可。
这项设置要选在 Machine Learning Cache 下,让模型服务读到文件。机器学习容器的环境变量也指向同一个位置:
text123MACHINE_LEARNING_CACHE_FOLDER=/mlcache HF_HOME=/mlcache TRANSFORMERS_CACHE=/mlcache
Immich 用 MACHINE_LEARNING_CACHE_FOLDER 确定模型根目录,另外两个是相关库的缓存设置。检查时把变量和挂载一起看,尤其留意教程中的 /cache 与自己环境里的 /mlcache 是否一致。
在 TrueNAS Shell 中,用有 Docker 权限的用户执行以下命令。先看 docker ps,如果容器名不同,替换后再执行后两条:
bash123456docker ps --format '{{.Names}} {{.Status}}' docker inspect ix-immich-machine-learning-1 \ --format '{{range .Mounts}}{{println .Type .Source "->" .Destination}}{{end}}' docker inspect ix-immich-machine-learning-1 \ --format '{{range .Config.Env}}{{println .}}{{end}}' \ | grep -E '^(MACHINE_LEARNING_CACHE_FOLDER|HF_HOME|TRANSFORMERS_CACHE)='
输出中应当能找到 /mnt/pool/apps/immich/mlcache 到 /mlcache 的映射,环境变量也指向 /mlcache。应用已经生成的变量不用重复添加,修改现有值即可。
三、离线模型配置
3.1 搜索与人脸模型
中文搜索使用 XLM-Roberta-Large-Vit-B-16Plus,人脸识别使用 buffalo_l。它们分别来自 Immich 维护的 搜索模型仓库和人脸模型仓库。
模型按功能和名称分目录保存,主要文件如下。运行时模型 revision 保持默认 main:
text12345678910111213141516mlcache/ ├── clip/ │ └── XLM-Roberta-Large-Vit-B-16Plus/ │ ├── textual/ │ │ ├── model.onnx │ │ └── 分词器、配置及外部权重文件 │ └── visual/ │ └── model.onnx ├── facial-recognition/ │ └── buffalo_l/ │ ├── detection/model.onnx │ └── recognition/model.onnx └── ocr/ └── PP-OCRv6_tiny/ ├── detection/model.onnx └── recognition/model.onnx
搜索模型分成 textual 和 visual 两部分。下载时保留完整目录,包括 ONNX 文件、外部权重、分词器和配置文件,单独复制 model.onnx 会缺少依赖。如果通过 Git 下载,也要把 Git LFS 管理的权重一并拉下来。
在能访问 Hugging Face 的电脑上,用独立 Python 环境下载:
bash1234567891011python3 -m venv .venv-immich-models . .venv-immich-models/bin/activate python -m pip install huggingface_hub mkdir -p immich-models/clip immich-models/facial-recognition hf download immich-app/XLM-Roberta-Large-Vit-B-16Plus \ --revision 02aad7af091ed078517e344982725f854f6ee2cd \ --local-dir immich-models/clip/XLM-Roberta-Large-Vit-B-16Plus hf download immich-app/buffalo_l \ --revision f833e51b56d96744b95c40af840411bfbcfd5995 \ --local-dir immich-models/facial-recognition/buffalo_l
上面的 --revision 固定下载版本,避免重新下载时文件发生变化。Immich 的运行时 revision 保留默认 main,这里不需要填下载命令中的提交号。
更新模型时整套替换,避免混用不同版本的 ONNX 和外部权重文件。
3.2 上传模型文件
在下载电脑上生成校验清单并打包:
bash123456cd immich-models find clip facial-recognition -type f ! -path '*/.cache/*' -print0 \ | sort -z | xargs -0 sha256sum > SHA256SUMS tar -czf ../immich-models.tar.gz clip facial-recognition SHA256SUMS cd ..
把压缩包上传到 TrueNAS 的 /tmp/immich-models.tar.gz,先解压到暂存目录,检查传输后的文件。下面的复制命令用于新部署,目标下已有同名模型时会停止;已有模型要先备份再处理。
bash123456789mkdir -p /tmp/immich-model-stage tar -xzf /tmp/immich-models.tar.gz -C /tmp/immich-model-stage cd /tmp/immich-model-stage sha256sum -c SHA256SUMS # 仅用于目标尚无这两个模型目录的新部署。 test ! -e /mnt/pool/apps/immich/mlcache/clip/XLM-Roberta-Large-Vit-B-16Plus && \ test ! -e /mnt/pool/apps/immich/mlcache/facial-recognition/buffalo_l && \ cp -a clip facial-recognition /mnt/pool/apps/immich/mlcache/
复制后检查应用用户是否有读取和写入权限。容器里最终应当能找到 /mlcache/clip/模型名/textual/model.onnx,不要在中间多套一层 immich-models。
3.3 OCR 模型
OCR 需要另外下载模型。v3.3.6 默认使用 PP-OCRv5_mobile,这里选择 PP-OCRv6_tiny,两者的测试结果放在下一节。
OCR 通过 RapidOCR 加载,模型从 ModelScope 下载,检测和识别各有一个文件。下面的地址及校验值取自镜像附带的 RapidOCR 配置,在联网电脑执行:
bash1234567891011121314mkdir -p immich-ocr/ocr/PP-OCRv6_tiny/{detection,recognition} cd immich-ocr base='https://www.modelscope.cn/models/RapidAI/RapidOCR/resolve/v3.9.2/onnx/PP-OCRv6' curl -fL --retry 3 "$base/det/PP-OCRv6_det_tiny.onnx" \ -o ocr/PP-OCRv6_tiny/detection/model.onnx curl -fL --retry 3 "$base/rec/PP-OCRv6_rec_tiny.onnx" \ -o ocr/PP-OCRv6_tiny/recognition/model.onnx cat > SHA256SUMS <<'SUMS' f42c0fbd294d95eac1a550e131b277dac97462c8025fa4b6c3cec1b7894bd3d5 ocr/PP-OCRv6_tiny/detection/model.onnx e16e242de5937ad92609223f19bc2aff3727ee40b095f996907c24749bad251b ocr/PP-OCRv6_tiny/recognition/model.onnx SUMS sha256sum -c SHA256SUMS tar -czf ../immich-ocr.tar.gz ocr SHA256SUMS
两个文件分别约 1.83 MB 和 4.49 MB。校验通过后,与前面一样上传、解压到暂存目录,再把 ocr/PP-OCRv6_tiny 复制到 NAS 的模型缓存目录。目录里已有同名模型时先备份。源站的文件名不同,放入缓存时都要改成各自子目录中的 model.onnx。
3.4 模型选择
文件放好后,在 Immich 管理设置的机器学习部分选择对应模型:搜索使用 XLM-Roberta-Large-Vit-B-16Plus,人脸识别使用 buffalo_l;启用 OCR,将模型名设为 PP-OCRv6_tiny 并保存。OCR 对应的配置键是 machineLearning.ocr.modelName。
配置中的模型名要与缓存目录对应,服务端会按这个名称调用模型。已有图库更换搜索模型后,需要重新生成全库搜索索引。
四、模型加载与测试
模型准备好以后,先看容器和日志。在 TrueNAS Shell 中执行:
bash123docker ps --filter name=ix-immich --format '{{.Names}} {{.Status}}' docker logs --since 10m ix-immich-machine-learning-1 docker exec ix-immich-machine-learning-1 ls -l /dev/dri
如果日志仍然尝试下载,先看它缺的是哪个模型,再检查对应的目录和文件。容器反复退出时,还要留意内存。
这次就遇到了内存不足:旧配置将容器限制在 4 GiB,中文搜索模型加载时被系统杀掉,日志和 cgroup 记录都确认了 OOM。改成 8 GiB 后才正常,升级后几种模型一起测试的峰值约 5.48 GiB。TrueNAS 的这项设置会作用于应用的多个容器,调整前要给其它服务留出内存;实际需要多少内存,取决于选择的模型和推理后端。
N100 核显在新版容器中可见,日志选择了 OpenVINO,模型目录下也生成了对应的 openvino/ 编译缓存。这些新文件可以保留。官方说明提到 OpenVINO 的内存占用可能高于 CPU 后端,启用核显后仍要留意容器的内存限制。
OCR 使用一张写有“家庭相册 中文识别测试”和“IMMICH 2026”的图片测试。预热后交替调用两套模型各五次,v5 mobile 的中位耗时为 95.4 ms,v6 tiny 为 70.0 ms,两者都识别出了文字,中文空格处理稍有不同。这张测试图上 v6 tiny 更快,所以先用它。模型的语言支持和规格见 PP-OCRv6 说明。
配置完成后,上传一张带文字的图片,等 OCR 任务完成,再搜索其中的文字。搜索照片内容和人脸识别也分别试一下。先用少量图片确认识别和搜索结果,再给已有图库重跑 OCR。
五、版本升级
改成 Host Path 后,这次升级到 v3.3.6,原来的搜索和人脸模型直接就能使用,不用再往容器里复制。新增加的 OCR 模型按前面的目录结构补进去,再到 Immich 中选择对应模型。
以后更新时,保留 Machine Learning Cache 的 Host Path 设置和原目录。模型名没有变,就继续用已有文件;切换模型时,再下载对应目录中的文件。更新后看一下机器学习服务的日志,确认加载的是所选模型。
跨大版本时还要看 升级说明,尤其是数据库和存储路径的变化。我这次遇到了 PostgreSQL 15 到 18 自动迁移失败,最后通过数据库导出、恢复完成升级。这样的更新先备份数据库和应用配置,旧数据保留到新版正常运行后再处理。
系列阅读
参考
支付宝
微信