SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

Immich 中文搜尋:換 CLIP 模型、開 OCR,算好 VPS 記憶體

Immich 搜「海邊」「貓」找不到照片?問題多半在預設的 ViT-B-32__openai 模型。依官方中文基準比較多語模型的記憶體與準確率,說明在 VPS 上換模型、重建索引,再用 OCR 搜尋照片裡的繁體中文字。

Immich 中文搜尋找不到照片,通常是模型的問題

Immich 中文搜尋輸入「海邊」或「貓」卻沒有結果,最常見的原因是 Smart Search 還在用預設的 CLIP 模型 ViT-B-32__openai。官方文件為多語搜尋另外列出 nllb、xlm 與 siglip2 幾個模型系列。換成其中一個,再對全部照片重跑 Smart Search 工作,中文查詢才有合適的模型處理。代價是記憶體:官方中文基準表裡最省記憶體的多語模型,估計峰值也要 2830 MiB。

照片裡的招牌、菜單、發票文字是另一件事,要靠 OCR(optical character recognition,光學字元辨識)。Immich 的 OCR 預設開啟,官方說它正式支援繁體中文。不過舊照片要手動跑一次 OCR 工作,才搜得到裡面的字。

本文的介面標籤與設定名稱都對照 Immich v3.3.1,這是 2026 年 10 月 8 日發布、撰寫當天的最新版。文件數據於 2026 年 10 月 14 日讀取。還沒架好 Immich 的話,先看 在 VPS 上自架 Immich 取代 Google 相簿,再回來調整搜尋。

先確認你現在用的是哪個 CLIP 模型

CLIP 是一種同時理解圖片與文字的模型。Immich 先用它把每張照片轉成一串數字,也就是向量(embedding)。你搜尋時,Immich 再用同一個模型把查詢文字轉成向量,找出最接近的照片。所以照片和查詢必須由同一個模型處理。模型讀不懂你的語言,向量就對不上,結果就不準。

用管理員帳號登入網頁版,進入 Administration(管理)的設定頁,打開 Machine Learning Settings,在 Smart Search 區塊找到 CLIP model 欄位。這裡用的是 v3.3.1 英文介面的標籤。中文介面會顯示翻譯後的名稱,位置一樣。

欄位顯示 ViT-B-32__openai 的話,就是預設值。v3.3.1 原始碼 server/src/dtos/config.dto.ts 裡寫的就是這個名稱。官方搜尋文件對它只說了一句:預設模型速度快,另有其他選項能提供更好的搜尋結果。文件的中文基準表裡沒有這個模型,所以官方沒有它的中文分數。我們不知道它在中文上差多少,只知道官方沒有公布測試結果。

nllb、xlm 與 siglip2:官方的多語模型怎麼選

官方搜尋文件(https://docs.immich.app/features/searching)依語言列出可用的模型。模型名稱的開頭,決定它怎麼處理你的查詢語言:

  • nllb 系列:文件說它「expect the search query to be in the language specified in the user settings」。查詢文字必須和使用者設定的語言一致。
  • xlm 與 siglip2 系列:文件說它們「understand search text regardless of the current language setting」。不管語言設定是什麼,它們都能理解查詢文字。

文件的建議大致是:主要只用一種非英文語言,選 nllb;會混用多種語言,選 xlm 或 siglip2。台灣和香港的使用者很常中英混打,例如「101 夜景」「iPhone 截圖」「貓 sofa」。這種查詢正是 xlm 與 siglip2 的適用情況。下一節還有一個更具體的理由,讓繁體中文使用者避開 nllb。

用繁體中文介面時,nllb 收到的是哪個語言?

這一節是讀 Immich v3.3.1 原始碼得出的推論,不是官方文件的說法。你可以用本節最後的指令在自己的主機上驗證。

網頁版送出 Smart Search 請求時,會附上一個語言代碼。這個代碼來自網頁版的語言設定(Language),它存在瀏覽器裡,第一次使用時取自瀏覽器偏好的語系。所以它是每個瀏覽器各自的設定,不是伺服器上的帳號欄位。手機 App 怎麼處理,我們沒有查證。

v3.3.1 的繁體中文語系檔叫 zh_Hant.json。網頁版用 convertBCP47 函式把底線換成連字號,所以送出的代碼是 zh-Hant。瀏覽器語系是 zh-TW、zh-HK 或 zh-MO 時,網頁版也會把它們對應成 zh-Hant。

機器學習服務只在模型名稱以 nllb 開頭時使用這個代碼。它先在 WEBLATE_TO_FLORES200 對照表裡找完整代碼。找不到,就取連字號前面那一段再找一次。v3.3.1 的對照表裡,中文只有三個鍵:zh-CN 和 zh-Hans 對到 zho_Hans,zh-TW 對到 zho_Hant。表裡沒有 zh-Hant,也沒有單獨的 zh。兩次都找不到時,程式記錄一則警告,然後改用英文代碼 eng_Latn。

結果就是:照原始碼來看,繁體中文介面加上 nllb 模型,你的中文查詢會被標成英文再送進模型。nllb 期待查詢語言和標記一致,所以這個組合的結果可能比表上的分數差。xlm 與 siglip2 不加語言標記,因此不受影響。

要在自己的主機上確認,先把模型換成 nllb 系列,用繁體中文介面搜尋一次。接著在放 docker-compose.yml 的目錄執行:

docker compose logs immich-machine-learning | grep "not found, defaulting"

輸出裡出現下面這段文字,就代表語言代碼沒有對上,查詢被當成英文處理:

Language 'zh-Hant' not found, defaulting to 'en'

沒有任何輸出,代表這次搜尋沒有走到這段程式。最常見的原因是目前的模型不是 nllb 系列。

官方中文基準:記憶體與準確率

先講清楚這張表的範圍。文件的中文表標題是 Chinese (Simplified),也就是簡體中文。整份文件沒有繁體中文或粵語的表。所以下面的召回率(recall,測試中找回正確圖片的比例)都是簡體中文的測試結果,不能直接當成繁體中文的分數。中文表共列出 19 個模型,這裡挑出 6 個最值得比較的。

Memory 欄是文件說的 peak RSS:機器學習程序跑完計時測試之後,最高的常駐記憶體用量。它不包含圖片解碼、同時處理多張照片,也不包含網頁伺服器。文件自己說這些是估計值,主要用來比較模型之間的差距。因為少算了這些工作,你主機上的實際用量會高於表上的數字。

圖表官方中文(簡體)表:機器學習程序峰值記憶體(MiB),2026-10-14 讀取
此圖表背後的資料
[
  {
    "label": "ViT-L-16-SigLIP2-256__webli",
    "memory_mib": 2830
  },
  {
    "label": "ViT-B-16-SigLIP-i18n-256__webli",
    "memory_mib": 3029
  },
  {
    "label": "XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k",
    "memory_mib": 3030
  },
  {
    "label": "ViT-B-16-SigLIP2__webli",
    "memory_mib": 3038
  },
  {
    "label": "ViT-B-32-SigLIP2-256__webli",
    "memory_mib": 3061
  },
  {
    "label": "nllb-clip-large-siglip__v1",
    "memory_mib": 4226
  }
]
圖表官方中文(簡體)表:召回率(%)與執行時間(ms),2026-10-14 讀取
此圖表背後的資料
[
  {
    "label": "ViT-L-16-SigLIP2-256__webli",
    "recall_pct": 70.51,
    "exec_ms": 23.77
  },
  {
    "label": "ViT-B-16-SigLIP-i18n-256__webli",
    "recall_pct": 67.48,
    "exec_ms": 6.87
  },
  {
    "label": "XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k",
    "recall_pct": 65.7,
    "exec_ms": 3.2
  },
  {
    "label": "ViT-B-16-SigLIP2__webli",
    "recall_pct": 66.84,
    "exec_ms": 5.81
  },
  {
    "label": "ViT-B-32-SigLIP2-256__webli",
    "recall_pct": 63.38,
    "exec_ms": 3.31
  },
  {
    "label": "nllb-clip-large-siglip__v1",
    "recall_pct": 79.7,
    "exec_ms": 75.05
  }
]

召回率最高的是 nllb-clip-large-siglip__v1,有 79.7%,也是整張中文表的第一名。但它的記憶體是 4226 MiB,執行時間 75.05 ms,是這幾個裡最慢的。它又是 nllb 系列,會遇到上一節的語言代碼問題。

最省記憶體的是 ViT-L-16-SigLIP2-256__webli,2830 MiB,召回率 70.51%,執行時間 23.77 ms。要注意,記憶體最少的並不是名稱裡帶 B 的小型號,而是這個 L 型號。這幾個裡最快的是 XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k,3.2 ms,召回率 65.7%,記憶體 3030 MiB。

表上最大的 SigLIP2 gopt 型號超過 6 GB。對一般 VPS 來說,它們不在選項裡。

VPS 要多少記憶體才跑得動 Immich 中文搜尋

Immich 官方安裝需求寫的是:記憶體最少 6 GB,建議 8 GB;CPU 最少 2 核,建議 4 核。只有 4 GB 記憶體時,文件說可以在關閉機器學習功能的情況下執行 Immich。機器學習關掉,Smart Search 和 OCR 都不會運作。

現在把這個數字和上面的表放在一起。最省記憶體的多語模型估計峰值是 2830 MiB,而且這只算機器學習程序本身。同一台主機上還要跑 Immich 伺服器、PostgreSQL 資料庫和快取服務。4 GB 的主機放不下這個組合。詳細的容量規劃,請看 Immich 的記憶體與儲存空間需求。

另一個常見的限制是 compose 檔裡的記憶體上限。有些精簡設定會用 mem_limit 或 deploy.resources.limits.memory 把機器學習容器限制在 1024M 之類的數值。1024 MiB 比表上每一列都小,所以這個上限下不要期待多語模型能正常運作。用下面的指令看每個容器目前的用量與上限:

docker stats --no-stream

找到機器學習容器那一行,看 MEM USAGE / LIMIT 欄。LIMIT 等於主機總記憶體,代表沒有另外設上限。LIMIT 是 1GiB 左右,代表 compose 檔裡有上限要處理。重建索引時再執行幾次,觀察實際用量。官方文件沒有給出多語模型在 VPS 上的實際用量,所以你主機上的數字才是準的。

記憶體不夠時的四個選擇

  1. 換一台更大的主機。 官方建議 8 GB。這是最單純的做法,所有服務留在同一台,設定不用拆開。
  2. 選最省記憶體的多語模型。 依官方表,ViT-L-16-SigLIP2-256__webli 的估計峰值最低。主機剛好在 6 GB 上下時,這是最值得先試的模型。
  3. 把機器學習搬到另一台機器。 照片和資料庫留在 VPS,模型跑在一台記憶體比較多的電腦上。下一節說明做法。
  4. 暫時不換模型。 先用檔名、資料夾路徑或 OCR 搜尋,或自己試試同一批照片用英文關鍵字搜尋的結果。這不能解決中文搜尋,但不增加任何記憶體。

把機器學習搬到另一台機器

官方有一份遠端機器學習指南(https://docs.immich.app/guides/remote-machine-learning),說明怎麼在另一台機器上只跑機器學習容器。照指南把容器跑起來後,回到 Immich 的 Machine Learning Settings,按 Add URL,填入遠端容器的位址,格式是 http://ip:port。

文件建議「新增」網址,不要「取代」預設的 http://immich-machine-learning:3003。原因是 Immich 會依序嘗試這些網址,遠端那台關機時,就會退回本機的容器。所以遠端網址要排在前面。

搬過去之前,先知道這幾件事:

  • 不是每個功能都會用遠端。 文件說 Smart Search 和 Face Detection(人臉偵測)會用遠端伺服器,Facial Recognition(人臉辨識)不會。這份指南沒有提到 OCR,所以不要假設 OCR 也會搬走。跑 OCR 工作時,在兩台機器上都執行 docker stats --no-stream,看是哪一台的機器學習容器在吃 CPU 和記憶體。
  • 版本要一致。 文件要求兩邊的 Immich 版本相同。升級 VPS 上的 Immich 時,遠端那台也要一起升。
  • 容器本身沒有任何保護。 文件明白寫著這個容器「has no security measures whatsoever」。不要把它的連接埠開到公開網路上。兩台機器之間要走私人網路或 VPN。
  • 舊電腦要先確認 CPU。 從 v3 開始,amd64 上的機器學習容器需要 x86-64-v2 或更新的 CPU。

如果遠端那台有顯示卡或 Intel 內顯,可以考慮硬體加速。文件提醒,OpenVINO 的記憶體用量比純 CPU 運算更高,所以記憶體要留得比上面的表更寬。

換模型本身只要幾秒鐘,花時間的是之後的重建索引。在開始一個要處理整個相簿的工作之前,先確認你知道 Immich 的 Docker 把照片存在哪裡,而且資料庫和照片都有備份。

  1. 進入 Administration 的設定頁,打開 Machine Learning Settings。
  2. 在 Smart Search 區塊的 CLIP model 欄位,貼上完整的模型名稱,例如 ViT-L-16-SigLIP2-256__webli 或 XLM-Roberta-Base-ViT-B-32__laion5b_s13b_b90k。名稱要和文件表上完全一樣,包含兩個底線後面的部分。
  3. 儲存設定。
  4. 打開 Administration 底下的 Jobs 頁面,在 Smart Search 那一列按 All。

第 4 步不能省。官方系統設定文件寫的是:「When changing the CLIP model it is mandatory to re-run the Smart Search job on all images to fully apply the change.」換了模型,舊照片的向量還是舊模型算出來的。新模型算出的查詢向量和它們對不上,所以必須對全部照片重跑,而不是只處理缺少資料的照片。

相簿很大時,這等於整個 Smart Search 索引從頭再做一次。官方沒有給出需要多久,時間取決於照片數量、CPU 和模型大小。在 Jobs 頁面看 Smart Search 的佇列數字慢慢歸零,同時用 docker stats --no-stream 看機器學習容器的記憶體。

佇列跑完後驗證一次。在網頁版搜尋列打開搜尋選項,搜尋類型選 Search by context(依內容搜尋),輸入「海邊」或「貓」。結果裡應該出現對應的照片。如果還是空的,先回 Jobs 頁面確認 Smart Search 真的跑完了。

用 OCR 搜尋照片裡的繁體中文字

Smart Search 找的是照片「拍了什麼」。OCR 找的是照片「上面寫了什麼」,例如菜單上的「牛肉麵」、發票上的店名、路牌、手機截圖裡的對話。這兩種搜尋互相補足,對中文使用者來說,OCR 常常更實用。

OCR 在 v2.2.0 加入,該版本於 2025 年 10 月 30 日發布。它的發布說明寫著:「OCR currently has official support for English, Chinese (Simplified), Chinese (Traditional) and Japanese text.」繁體中文在官方支援清單裡。

在 v3.3.1 原始碼的預設設定裡,OCR 是開啟的,預設模型是 PP-OCRv5_mobile。Machine Learning Settings 的 OCR 區塊有這些欄位:

  • Enable OCR:開關。預設開啟。
  • OCR model:使用的模型。預設 PP-OCRv5_mobile。
  • Maximum resolution:辨識時使用的最大解析度。預設 736。
  • Minimum detection score:偵測到文字區塊的最低分數。預設 0.5。
  • Minimum recognition score:辨識結果的最低分數。預設 0.8。

OCR model 欄位的說明寫著:server 模型比 mobile 模型準確,但處理時間比較長,也用更多記憶體。v3.3.1 的機器學習服務在程式裡接受的名稱包含 PP-OCRv5_server、CH__PP-OCRv5_server 和 CH__PP-OCRv5_mobile 等。下拉選單實際提供哪些,請以你自己的介面為準。在記憶體吃緊的 VPS 上,先維持預設的 mobile 模型。

新上傳的照片會在機器學習流程中自動跑 OCR。升級到 v2.2.0 以後才有 OCR,所以在那之前上傳的照片不會自動處理。v2.2.0 的發布說明要你到 Administration 的工作頁面,在 OCR 那一列按 All。v3.3.1 介面上這個頁面叫 Jobs。

跑完後,在搜尋選項裡把搜尋類型改成 Search by OCR,再輸入照片上的字。介面上的說明是:搜尋類型決定 Immich 怎麼理解你的查詢,依畫面內容、檔案資訊,或照片裡的文字。如果你換了 OCR 模型,官方文件沒有說舊照片要不要重跑。想讓舊照片也用新模型的結果,就再對 OCR 按一次 All。

搜尋結果還是不對時,先檢查這些

換了模型,中文還是找不到。 最常見的原因是 Smart Search 工作還沒跑完,或按的不是 All。打開 Jobs 頁面,看 Smart Search 的佇列是否還有數字。佇列沒歸零前,部分照片的向量還是舊模型的。

用的是 nllb,結果比預期差。 照前面的原始碼分析,繁體中文介面送出的 zh-Hant 不在對照表裡,查詢會被標成英文。執行 docker compose logs immich-machine-learning | grep "not found, defaulting",看到 Language 'zh-Hant' not found 就是這個原因。改用 xlm 或 siglip2 系列,再重跑 Smart Search。

機器學習容器一直重新啟動。 執行 docker compose ps,機器學習容器的狀態欄出現 Restarting,再看 docker stats --no-stream 的 MEM USAGE / LIMIT。用量貼著上限,就是記憶體不夠。回到前面的四個選擇。

OCR 搜不到照片上的字。 先確認搜尋類型選的是 Search by OCR,不是 Search by context。再確認舊照片有跑過 OCR 工作。字很小或很模糊時,可以試試 server 模型,代價是更慢、更吃記憶體。

設了遠端機器學習,卻沒有在用。 確認遠端網址排在預設網址前面,兩台的 Immich 版本相同,而且 VPS 連得到遠端那台的連接埠。連不到時,Immich 會安靜地退回本機容器,所以搜尋還能用,只是跑在 VPS 上。

FAQ

為什麼 Immich 用中文搜尋找不到照片?

多半是因為 Smart Search 還在用預設的 CLIP 模型 ViT-B-32__openai。官方的中文基準表裡沒有這個模型,文件另外列出 nllb、xlm 與 siglip2 等多語模型。在 Machine Learning Settings 的 CLIP model 欄位換成多語模型,再到 Jobs 頁面對 Smart Search 按 All,中文查詢才會由多語模型處理。

換了 CLIP 模型之後,一定要重跑 Smart Search 嗎?

一定要。Immich 官方系統設定文件說,換 CLIP 模型後「mandatory」要對全部照片重跑 Smart Search 工作。舊照片的向量是舊模型算的,和新模型算出的查詢向量對不上。相簿很大時,這等於整個索引重做一次,官方沒有提供需要多久的數字。

4 GB 記憶體的 VPS 能跑 Immich 的中文搜尋嗎?

不實際。官方需求是最少 6 GB、建議 8 GB,只有 4 GB 時文件說要關閉機器學習功能。官方中文表裡最省記憶體的多語模型 ViT-L-16-SigLIP2-256__webli,估計峰值就要 2830 MiB,而且這只算機器學習程序本身。可行的做法是換 8 GB 的主機,或把機器學習容器搬到另一台記憶體比較多的機器。

Immich 的 OCR 能辨識繁體中文嗎?

可以。OCR 在 v2.2.0 加入,發布說明寫明官方支援英文、簡體中文、繁體中文和日文。v3.3.1 預設開啟 OCR,模型是 PP-OCRv5_mobile。新照片會自動處理,舊照片要到 Administration 的 Jobs 頁面,對 OCR 按 All,然後在搜尋類型選 Search by OCR。

台灣和香港的使用者該選 nllb,還是 xlm 或 siglip2?

建議選 xlm 或 siglip2。官方文件說這兩個系列不管語言設定都能理解查詢文字,適合中英混打的查詢。nllb 要求查詢語言和設定一致,而從 v3.3.1 原始碼來看,繁體中文介面送出的 zh-Hant 不在 nllb 的語言對照表裡,查詢會被當成英文處理。注意官方中文分數只測了簡體中文,繁體中文沒有公布的分數。

#immich#smart-search#ocr#machine-learning#self-hosting#chinese