Google Photos 的免費空間在 2021 年就沒了,2026 年 Google One 又一次調整方案,2TB 分層被拆得更零碎,同一時間 Gemini 相簿記憶功能開始把使用者的照片當成訓練資料的一部分。從 2022 年就一直在寫「今年可能是自架相簿真的能用」的社群,這一次終於等到證據——Immich 在 2026 年初推進到 3.0,把撐了兩年的 pgvecto.rs 換成 VectorChord,同一支 Docker Compose 就能跑起 CLIP 語意搜尋、buffalo_l 人臉聚類、硬體轉檔、iOS/Android 背景同步,功能對到 Google Photos 大概八成,而且 GitHub 星星突破 9 萬顆的曲線比 Home Assistant 當年還陡。
自架相簿這件事會走到今天這個節點,關鍵不在 Docker 好不好裝,而在向量索引這一層終於穩了。過去五年只要有人架 Immich,遲早會撞到 pgvecto.rs 的記憶體爆走、reindex 卡住、或是升版被迫 dump/restore。3.0 把這條路封掉,統一收在 VectorChord 上,代價是每個舊使用者都得走一次遷移。這個決定本身就是這個版本的重點。
Google Photos 的鎖定其實不在儲存空間
免費 15GB 的用量早就被 Gmail 附件跟 Google Drive 吃光,真正的問題是把相簿搬走這件事幾乎沒被設計成可行選項。Google Takeout 匯出的檔案是把每張照片的中繼資料拆到獨立的 JSON 檔,一份 500GB 的相簿匯出下來會變成幾十萬個小檔案,序列匯入到任何其他相簿服務都得寫腳本重組時間戳跟 GPS 座標。這是刻意的——只要匯出成本夠高,多數使用者就不會真的離開。
2025 年下半年開始,Gemini 的相簿記憶功能把「相片就是訓練資料」這件事推到檯面上。條款上這一直允許,只是過去沒有被明講。對家庭照片、工作素材、私人紀錄有一點點警覺的使用者,這一年裡的搜尋量突然轉向「self-hosted photos」,Immich 就是這波流量的最大受益者。
自架的算式其實不難算。一顆 4 核心、8GB RAM、1TB NVMe 的臺灣本地 VPS,一個月大概新臺幣 700 到 900 元,容量足以裝十年份的手機相簿加上 4K 影片,換算到 Google One 的 2TB 方案已經沒有價差。真正貴的從來不是空間,是離開的門檻。
四個容器就是全部,Node、Python、Postgres、Redis 各一份
Immich 的架構刻意保持簡單:一支 Node.js 寫的 API server 負責認證、上傳、資料庫存取;一支獨立的 Python FastAPI 服務跑機器學習模型;一份 PostgreSQL 存中繼資料跟向量嵌入;一份 Redis 管佇列跟快取。React 寫的網頁前端跟 Flutter 寫的手機 App 都直接打 API server,不再多分一層 gateway。
分離 ML 服務這個設計常被誤解成「為了 GPU」,實際理由更務實——Python 是 CLIP 跟 InsightFace 的原生語言,硬要把這些模型用 ONNX 塞回 TypeScript 進程效能會掉、GPU 加速也難接。把 Python 隔在另一個容器裡,還意味著 ML 可以獨立擴充:家裡有一臺閒置的 RTX 3060 就可以只把 machine-learning 這支容器丟到 GPU 主機上,其他三支還留在 VPS,中間靠內網通訊。
Postgres 這一層在 3.0 之後變得比較挑。Immich 官方倉庫預設走的是自家打包的 tensorchord/vchord-postgres 映像檔,用外接的 Postgres 得手動裝 VectorChord、vchord_bm25、pgvector 三個擴充套件,版本要對齊 17 或 18,這幾點在 upgrade 指南裡都寫得很細。想省事的話就用官方映像檔,不要跟現有的 Postgres 共用;共用會踩到擴充套件版本的地雷。
從 pgvecto.rs 換到 VectorChord 為什麼是重點
CLIP 產出的是 512 維或 768 維的浮點向量,每張照片一組、每張臉一組。50 萬張照片就是 50 萬條向量,用暴力比對做「跟這張最像的前 20 名」會慢到不能用,所以必須靠索引結構——這正是 pgvector 系列擴充套件在做的事。
pgvecto.rs 是 2023 年 tensorchord 團隊用 Rust 寫的一支 Postgres 擴充,走 IVF 系列演算法,過去兩年是 Immich 的預設。它的問題不在演算法,在生命週期——維護節奏慢、記憶體回收有洩漏、大型索引 rebuild 時有機率卡死。社群有人架超過 30 萬張照片的實例,光重建一次索引就要停機半天。
VectorChord 是同一群工程師的下一代作品,走 RaBitQ 量化 + IVF 的組合,記憶體用量降到 pgvecto.rs 的三分之一左右,索引建置速度提升好幾倍,並且從一開始就設計成可以熱切換。這也是為什麼 Immich 在 v1.133 就開始建議遷移、v3.0 直接把 pgvecto.rs 移除——留舊擴充在裡面等於留一個隨時會爆的角落。
實際遷移的步驟其實只有三步:跑一次 EXTENSION_LIST=vectorchord,vchord_bm25,pgvector 的初始化、把 Docker Compose 裡的映像檔換成 vchord-postgres、啟動時等 Reindexing clip_index 跟 Reindexing face_index 跑完。這段時間服務會停,10 萬張照片大約 5 到 15 分鐘,超過 50 萬張建議先關掉自動備份再做,避免手機端超時重試把佇列灌爆。
CLIP 語意搜尋跟 buffalo_l 人臉聚類真的能用嗎
CLIP 是 OpenAI 2021 年放出來的多模態模型,訓練時把「文字描述」跟「對應的圖片」映射到同一個嵌入空間。使用者搜尋「海邊夕陽」的時候,Immich 把這串文字打進 CLIP,拿到一組向量,然後在 Postgres 裡用 cosine similarity 找出向量最接近的照片。整個流程不需要事前打標籤、不需要 EXIF,也不理解「這是一張夕陽」——它只是在把兩組空間位置比近距離。
實務上這招對通用場景很準,對長尾場景會失手。搜「壽司」、「山」、「腳踏車」幾乎一次到位;搜「阿嬤生日」就沒辦法,因為 CLIP 不知道誰是阿嬤,也不知道那個蛋糕是為誰而做。這是模型的先天限制,不是 Immich 的實作問題。
人臉那條線走的是另一套模型——InsightFace 的 buffalo_l。每張偵測到的臉會被抽成一組嵌入向量,然後拿 DBSCAN 演算法做聚類。DBSCAN 的邏輯是「一個點如果周圍在半徑 R 內有超過 N 個鄰居,就是核心點」,Immich 的「最少辨識臉數」設定就是在調這個 N。這也解釋了為什麼一個人的臉一開始會被拆成兩三群——初次匯入時候的照片密度不夠,等到累積到某個閾值再手動合併一次就穩了。
DBSCAN 本身沒有「新資料進來就更新聚類」的能力,Immich 只好在上面套一層增量處理:新臉進來時先找最近鄰、判斷是否落在既有群體的核心點半徑內,落內就掛過去、落外就先擱著等下一輪重跑。這個設計換來效能,代價是初期幾週的辨識準度會比較跳。
硬體要抓多少才夠
官方文件的最低配是 4 核心 CPU、4GB RAM,實務上這個規格只夠跑得起來,不夠跑得順。CLIP 嵌入計算在初次匯入時會把 CPU 打到滿載,一張 12MB 的 iPhone 相片大約要 200 到 400 毫秒,10 萬張照片跑完索引是好幾天的事情。Raspberry Pi 4 這一級的硬體會直接被 ML 服務拖到動不了,Pi 5 勉強可行但要有耐心。
實際建議:初次匯入階段給到 8 核心、8GB RAM,之後日常運作可以縮回 4 核心、6GB。硬體轉檔如果打算開,就要看主機平臺——Intel N100 或以上的 CPU 內建 Quick Sync 幾乎是最划算的選擇,一顆 6000 元的迷你主機就能加速 H.264、H.265、AV1;NVIDIA 走 NVENC 效能最好但成本高;AMD 的 VAAPI 在 Linux 上支援度落後一截。ML 那條線也可以吃 GPU,CUDA 或 OpenVINO 都行,但除非要跑幾十萬張照片的初次索引,不然單靠 CPU 就夠。
儲存這一層 NVMe 是強烈建議、SATA SSD 可接受、HDD 不建議。Postgres 的 VectorChord 索引在讀取時對隨機 IO 很敏感,機械硬碟會讓語意搜尋從 200 毫秒惡化到好幾秒。真的要用 HDD 就把 Postgres 那份卷分到 SSD、原始照片留在 HDD 上。
一個 Docker Compose 起手就結束了
Immich 官方唯一支援的部署方式就是 Docker Compose,這個立場從專案第一天就沒變過。手動裝、跑裸機、拆 Kubernetes 都可以做,但出問題不會有社群支援。這對想跑生產等級的人來說反而是好事——版本控制清楚、升級路徑收斂、backup 策略也單純。
上線之後的重點是備份。Immich 自己不做原始檔案的備份,它假設檔案系統這一層有 snapshot 或 rsync。真正需要備份的是三份東西:UPLOAD_LOCATION 底下的原始照片、Postgres 的邏輯備份(pg_dumpall)、還有 .env 檔本身。前面文章介紹過的 Restic 加上臺灣本地 VPS 之間的內網傳輸,就能做到每天全量 + 每小時增量。硬要跨地備份的話,選一個支援 S3 API 的物件儲存丟過去就好。
結論:這一次真的可以離開 Google Photos 了
自架相片這條路過去五年一直卡在「可以裝」跟「敢正式用」之間的模糊地帶,Immich 3.0 把最後一個結構性的隱患——搖擺的向量擴充套件——換掉之後,這條線變乾淨了。CLIP 語意搜尋準到能用、buffalo_l 人臉聚類穩到能用、硬體轉檔選擇多、App 完成度高,整個技術棧的每一塊都不再是實驗品。
NCSE Network 提供以臺灣是方電訊機房為據點的 VPS,Intel Gold CPU 加上 NVMe SSD 的組合對 Immich 這種吃隨機 IO 的工作負載特別友善,臺灣本地路由讓 iOS 跟 Android 端上傳延遲穩定在毫秒級。想把手機相簿從 Google Photos 搬回自家控制的伺服器,可以參考 NCSE VPS 方案。