> 本文摘要: > 1. `shm_size` 是使用 RAM 的暫存空間。 > 2. 使用 `ipc: host` 時,`shm_size` 將失去作用,並會分配主機資源的 50% 供使用。 > 3. 許多 AI 模型範例設定常同時配置 `ipc: host` 和 `shm_size`,但實際上只設定其中一項會提高可讀性。 > 4. 對於 AI 工作負載,建議至少設定 **8G~16G** 以上,請根據您的環境選擇合適的配置。 ## 🐳 AI/數據工作負載的必備設定:徹底理解 Docker 共享記憶體 (shm_size 與 ipc) {#sec-2161daf65756} 在 AI 及大數據處理工作負載中,若您曾遇到類似 `OSError: No space left on device` 的不明錯誤,這通常是因 **[[Docker]] 容器的共享記憶體 (`shm_size`) 設定不足**所致。本文將清楚說明在容器環境中共享記憶體的重要性,以及如何正確設定 `shm_size` 和 `ipc: host` 選項。 ![shm_size 與 ipc 方式的比較圖](/media/whitedec/blog_img/5c8cd9fb5f93404fb70bc6019e296acf.webp) --- ## 1. shm_size 的作用與重要性 {#sec-21161777e576} ### 作用:決定容器的共享記憶體大小 {#sec-5e3ff7cb88f8} **`shm_size`** 是設定容器內部 **/dev/shm (POSIX shared memory)** 檔案系統**最大大小**的選項。 * [[Docker]] 預設值為 **64MB**,非常小。 * **注意**:`/dev/shm` 是使用**主機 RAM** 的 **`tmpfs`**(暫存檔案系統),與 **VRAM (GPU 記憶體)** 無關。 ### 為何重要? {#sec-8127b7b9aeb4} AI/數據處理任務在不同程序之間交換大量數據時,會核心地利用這種**共享記憶體**。 * **PyTorch DataLoader**:當設定 `num_workers > 0` 時,會在工作程序之間透過**共享記憶體傳遞張量/批次**。如果此空間不足,就會發生 `OSError: No space left on device` 錯誤。 * **TensorRT 引擎建構/服務**:會大量使用共享記憶體作為大容量中間產物或 IPC 緩衝區,若空間不足可能導致引擎建構失敗或分段錯誤。 * **多程序處理及 IPC 通訊**:在 NCCL、OpenCV、NumPy 等應用中,對於程序間共享大容量陣列/緩衝區至關重要。 --- ## 2. ipc 設定:共享記憶體的隔離範圍 {#sec-6d4d31fe3ee4} **IPC (Inter-Process Communication) namespace** 是 Docker 選項,用於定義容器中程序間通訊空間(共享記憶體、信號量等)的隔離範圍。 | **ipc 設定** | **運作方式** | **/dev/shm 大小決定** | | --- | --- | --- | | **預設 (省略)** | 使用容器**自身的 IPC 命名空間** (隔離) | 由 `shm_size` 指定的大小 (預設值 **64MB**) | | **`ipc: host`** | 容器**共享主機的 IPC 命名空間** | **主機 `/dev/shm` 的大小** (通常是 RAM 的一半) | | **`ipc: container:`** | 與指定的其他容器共享 IPC | 遵循共享目標容器的設定 | --- ## 3. shm_size 與 ipc: host 同時使用時的運作原理 (範例分析) {#sec-77e6ca4c4b62} 在 AI/LLM 任務中,常見同時設定 `shm_size: "16g"` 和 `ipc: host`。本文將透過實際範例來探討此時哪種設定會生效。 ### 測試:使用 `ipc: host` 時的驗證結果 {#sec-f473e8607f63} 我們像下面這樣同時設定了 `shm_size` 和 `ipc: host`。 ```yaml shm_size: "16g" ipc: host ``` 然後進入容器內部檢查 /dev/shm 的大小。 ```bash ~$df -h /dev/shm Filesystem Size Used Avail Use% Mounted on tmpfs 60G 8.3M 60G 1% /dev/shm ``` **觀察結果**:顯示的是主機 /dev/shm 的大小 60GB,而非 `shm_size` 中設定的 16GB。 > **結論:`ipc: host` 會忽略 `shm_size`。** **為何會出現這種結果?** 1. **當 `ipc: host` 生效時**:容器會直接使用**主機的 IPC 命名空間**。 2. **`shm_size: "16g"` 將被忽略**:此選項僅在容器使用**自身 IPC 命名空間**時才具意義。 3. **60G 的來源**:主機 Linux 系統通常預設將 `/dev/shm` 設定為**總 RAM 的一半**左右。因此,在上述範例中,容器看到的是主機 120G RAM 的一半,即 60G。 **再次強調** > **當設定 `ipc: host` 時,容器將直接使用主機的共享記憶體空間,因此 `shm_size` 的設定實際上不會生效。** --- ## 4. 根據您的環境與目的選擇記憶體管理方式 {#sec-d62a63904765} ### 追求穩定性 vs 容器獨立隔離 {#sec-870976b9ffe1} #### 1. 穩定性優先:維持 `ipc: host` 這是最省心的方法。它直接利用主機充裕的 RAM 資源。適用於單一使用者/單一專案環境,即使多個容器共享資源也不會產生問題。**主機 50% 的使用率僅為最大值,實際只佔用實際使用的 RAM 量**,因此如果沒有記憶體壓力,維持此設定會更方便。 * **設定**:僅保留 `ipc: host` (雖然許多範例會同時看到 `shm_size`,但它沒有意義,請大膽刪除 `shm_size`)。 * **結果**:使用主機充裕的 `/dev/shm` 大小 (例如:60G)。 #### 2. 強制設定容器上限:移除 `ipc: host` 適用於多租戶環境,或需要防止特定容器佔用過多 RAM 的情況。 * **設定**:**移除** `ipc: host` + 明確指定 `shm_size: "8g"` 或 `"16g"`。 * **結果**:會為容器建立專用的 16GB `/dev/shm`。 * **優點**:當運行多個容器時,可以明確限制**每個容器的共享記憶體使用上限**,從而保護主機 RAM 並實現隔離。 ### 參考:主機共享記憶體大小調整方法 (使用 ipc:host 時) {#sec-5e365d4f36e8} 若您在使用 `ipc: host` 的同時,希望變更主機 `/dev/shm` 本身的大小,則需要修改 `tmpfs` 的設定。 1. **暫時性變更大小 (重啟後恢復預設):** ``` sudo mount -o remount,size=16G /dev/shm ``` 此設定會立即應用於所有程序/容器。 2. **永久性變更大小 (修改 `/etc/fstab`):** ``` # 在 /etc/fstab 檔案中新增/修改以下行 tmpfs /dev/shm tmpfs defaults,size=16G 0 0 ``` 儲存後重啟系統,或使用上述 `remount` 命令立即生效。