M09.05|容器化與雲端部署:讓模型在任何地方都能跑
『在我的電腦上可以跑』已經不夠了 — 容器化讓環境一致,雲端讓規模彈性
本講學習重點
Docker = 把應用程式和環境一起打包的技術,解決「環境不一致」問題
K8s = 自動管理大量 Docker 容器的系統(擴展、自癒、負載均衡)
SageMaker 整合 AWS 生態、Vertex AI 整合 GCP BigQuery、Azure ML 整合 Office 365
邊緣部署:網路不穩定、延遲要求極低(<10ms)、資料隱私敏感的場景
ML 容器要注意:GPU 驅動版本、模型大檔案分層策略、敏感資料不進映像檔
Helm Chart 讓 K8s 的 ML 服務部署可重現、可版本控制
托管 vs 自建:托管省運維心力但貴、自建靈活但維護複雜
🎙️ Podcast(中文)
一句話搞懂
容器化就是把模型程式和它需要的一切(Python 版本、套件、設定檔)打包進一個標準化的「貨櫃」,這個貨櫃在開發者的筆電、測試伺服器、雲端平台上都能一模一樣地跑;而 Kubernetes 則是管理這些貨櫃的「港口調度系統」,負責在需求增加時自動開更多貨櫃、某個貨櫃壞掉時自動換新的、確保整個系統不間斷地對外服務。
白話解說
「在我電腦上可以跑」:環境不一致的魔咒
每個 ML 工程師都經歷過這個場景:你在本機訓練好的模型,在同事的電腦上一跑就報錯;好不容易統一了,部署到測試伺服器又壞了;測試通過了,推到生產環境又是另一個問題。
原因通常是環境不一致:Python 版本不同(3.9 vs 3.11)、套件版本不同(scikit-learn 1.1 vs 1.3)、CUDA 版本不同、系統底層函式庫不同。每個人的環境都微妙地不一樣,讓「環境問題」成為 ML 部署中最浪費時間的障礙之一。
Docker 的出現,從根本上解決了這個問題。
Docker:打包環境的魔法貨櫃
Docker 的核心概念是容器(Container):把應用程式和它所依賴的一切(作業系統函式庫、Python 版本、所有 pip 套件),全部打包成一個獨立的、可攜帶的單位。這個「貨櫃」可以在任何安裝了 Docker 的機器上完全一致地執行。
一個典型的 ML 服務 Dockerfile 長這樣:
# 選擇基礎映像(包含 Python 3.11 和 CUDA 12.0)
FROM python:3.11-slim
# 設定工作目錄
WORKDIR /app
# 先複製套件清單並安裝(利用 Docker 快取層)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 複製應用程式程式碼
COPY src/ ./src/
COPY models/ ./models/
# 設定環境變數
ENV MODEL_VERSION=v2.1.3
# 啟動服務
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8080"]
這個 Dockerfile 就像一份食譜。任何人根據這份食譜,都能建出完全一樣的環境。一旦建成 Docker 映像(Image),就可以推送到 Container Registry(像 Docker Hub 或 AWS ECR),任何人從那裡拉取(pull)這個映像,跑起來的環境都完全一致。
Docker 用於 ML 的特別考量
ML 容器有幾個和一般 Web 應用不一樣的特點,需要特別處理:
模型檔案的大小問題:模型檔案可能幾百 MB 到幾十 GB。如果直接把模型打包進容器映像,映像會非常龐大,推送和拉取都很慢。更好的做法是:容器啟動時,從物件儲存(S3、GCS)動態下載模型,或使用 Kubernetes 的 Init Container 在主容器啟動前先把模型準備好。
GPU 驅動版本相依:如果模型需要 GPU 推論,容器內的 CUDA 版本必須和主機的 GPU 驅動版本相容。用 nvidia/cuda 系列的基礎映像,並確認 CUDA 版本和宿主機驅動的相容矩陣。
敏感資訊保護:不要把 API Token、資料庫密碼、模型的加密金鑰放進 Dockerfile 或映像裡。使用環境變數(在執行時注入)或 Kubernetes Secrets,避免機密資訊外洩。
映像層次優化:Dockerfile 的每一條指令都會產生一個「層」,Docker 會快取每一層。把不常變動的步驟(安裝套件)放在前面,常變動的(複製程式碼)放在後面,能大幅加速 CI/CD 的建構速度。
Kubernetes:容器的管理大腦
當你的服務只有一個容器時,手動用 Docker 管理就夠了。但當你要同時管理幾十個、幾百個容器,並且要確保它們持續正常運作,就需要容器編排(Container Orchestration)系統。
Kubernetes(K8s) 是目前最主流的容器編排系統,由 Google 開源。它解決了幾個核心問題:
自動擴展(Auto-scaling):當請求量增加(例如促銷活動),K8s 能自動增加更多容器副本來分擔負載;請求量下降後,自動縮減容器數量節省成本。這種「彈性擴縮」是雲端的核心優勢。
自我修復(Self-healing):某個容器崩潰了,K8s 自動偵測並重啟一個新的,對外服務不中斷。這讓你的系統天然具備高可用性,而不需要人工值班盯著每台機器。
負載均衡(Load Balancing):把流量均勻分配到多個容器副本,防止某一個副本過載而其他副本閒置。
滾動更新(Rolling Update):更新模型時,K8s 逐個替換舊容器,而不是一次性全換,確保服務持續可用,沒有停機時間。
一個 ML 服務的 K8s 部署設定(deployment.yaml)大概長這樣:
apiVersion: apps/v1
kind: Deployment
metadata:
name: sentiment-model-service
spec:
replicas: 3 # 同時跑 3 個容器副本
template:
spec:
containers:
- name: model-server
image: your-registry/sentiment-model:v2.1.3
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
env:
- name: MODEL_VERSION
value: "v2.1.3"
三大雲端 ML 平台:托管式的一站式解決方案
自己搭 Docker + K8s 的環境需要相當的基礎設施知識和維護成本。三大雲端平台都提供了更高層次的 ML 服務,讓你專注在模型本身:
AWS SageMaker: AWS 生態系中最完整的 ML 托管服務。從資料標注(SageMaker Ground Truth)、訓練(托管的訓練叢集)、模型登錄、一鍵部署,到監控(SageMaker Model Monitor)都有覆蓋。特別強的是和 AWS 其他服務的整合:S3 存資料、Lambda 做事件觸發、CodePipeline 做 CI/CD。適合已經深度使用 AWS 的企業。
Google Cloud Vertex AI: Google 將原來分散的 AI Platform、AutoML、Explainability AI 統一在 Vertex AI 底下。最大的優勢是和 BigQuery 的深度整合——可以直接在 BigQuery 的資料上訓練模型(BigQuery ML),也可以把特徵工程結果存在 Vertex Feature Store,供多個模型共享。適合資料主要在 BigQuery 的企業。
Azure Machine Learning: 微軟的 ML 平台,最大的賣點是和企業既有 IT 生態的整合:Active Directory 做身份認證、DevOps 做 CI/CD、Power BI 做結果視覺化。對於已經使用 Microsoft 365 的企業而言,這套生態是最自然的選擇。
選擇準則:如果你的公司已經 all-in 在某個雲端,就用那個雲的 ML 平台,能最大化和現有基礎設施的整合。如果是從零開始,GCP 的 Vertex AI 在 ML 工具的整合度上稍有優勢,但三者的核心功能差異不大。
邊緣部署:當模型不能上雲
有些場景必須把模型部署在「邊緣」(網路末端的設備),而不是雲端:
工廠設備預測維護:感測器資料傳到雲端再回來,往返延遲可能有幾百毫秒,對需要即時反應的製造設備來說太慢。在設備旁邊放一台邊緣伺服器(如 NVIDIA Jetson),模型就在本地運算,延遲控制在 10ms 以內。
醫療設備:病患的生命徵象資料因隱私法規不能傳到雲端,心電圖異常偵測模型必須在設備本地運行。
零售收銀系統:超市需要在沒有網路的環境下繼續運作,促銷推薦模型要能在本地執行。
邊緣部署的挑戰:邊緣設備的運算資源和記憶體遠不如伺服器,模型必須大幅壓縮(量化、剪枝、蒸餾)。模型更新也更複雜——你需要管理分佈在數百台設備上的模型版本,而不是只更新一個雲端服務。
應用場景
| 場景 | 部署方式 | 工具選擇 | 主要考量 |
|---|---|---|---|
| 新創公司第一個 ML 服務 | Docker + 單台雲端 VM | Docker + FastAPI | 快速上線,成本低 |
| 中型企業推薦系統(高流量) | Kubernetes 叢集 | K8s + Helm + HPA | 彈性擴縮、高可用 |
| 深度整合 AWS 的電商平台 | AWS SageMaker | SageMaker Endpoint | 和 S3、Lambda 整合 |
| 資料在 BigQuery 的企業 | GCP Vertex AI | Vertex AI Endpoints | BigQuery 特徵工程直通 |
| 工廠設備即時異常偵測 | 邊緣部署 | NVIDIA Jetson + TensorRT | 極低延遲、離線運作 |
| 手機 App 的 AI 功能 | 設備端部署 | TFLite / Core ML | 隱私保護、離線使用 |
| 跨雲端、混合雲場景 | K8s + Kubeflow | Kubeflow Pipelines | 避免雲端鎖定 |
常見誤區
誤區 1:「容器化就是把所有東西全塞進一個容器」
初學者很容易把容器化理解成「把所有東西放進一個容器」,包括資料庫、快取、API 服務、模型服務通通放在一起。這和容器化的精神完全相反。
容器化的核心原則是單一責任:每個容器只做一件事。模型推論服務一個容器、快取(Redis)一個容器、API 閘道一個容器、監控 Agent 一個容器。這樣的架構讓每個元件可以獨立擴展、獨立更新、獨立故障不影響其他元件。
把所有東西塞在一個容器的問題:你沒辦法只擴展需要更多資源的那個元件(例如模型推論);某一個元件崩潰了,整個容器都掛掉;更新任何元件都要重新部署整個大容器。
在 Docker Compose 或 Kubernetes 中,每個服務對應一個容器,透過定義好的網路接口互相溝通,才是正確的微服務架構。
誤區 2:「用了 Kubernetes 就自動解決所有問題」
Kubernetes 是強大的工具,但它本身的學習曲線很陡,而且帶來了新的複雜性。很多小團隊在根本沒有需要的情況下就引入 K8s,反而增加了大量維護負擔。
K8s 真正適合的場景:需要管理很多個容器副本(通常 10 個以上)、需要跨多台機器的排程、需要複雜的滾動更新策略。
如果你只有一個模型服務,只需要跑幾個副本,考慮更輕量的替代方案:
- Docker Compose:本機和小規模部署夠用,幾行 YAML 定義多個服務
- AWS ECS / Fargate:托管的容器服務,不用管 K8s 的複雜性
- Fly.io / Render:現代化的容器托管平台,上手門檻低很多
先從簡單的開始,等到遇到 K8s 真正解決的問題(規模、複雜性、跨雲需求)再引入。
誤區 3:「雲端 ML 平台貴,自己搭比較省」
這個判斷需要把隱藏成本也算進去。自建 ML 基礎設施的直接成本(機器費用)確實可能比托管服務便宜,但要加上:
工程師時間成本:自建 K8s 叢集、維護 GPU 驅動、處理節點故障、設定監控告警,這些工作需要有人做,而且是持續的,不是一次性的投入。如果你的 ML 工程師花 40% 的時間在維護基礎設施,這才是最大的成本。
機會成本:花在基礎設施的時間,就是沒花在改善模型和創造業務價值的時間。對大多數非基礎設施公司來說,這個取捨很清晰。
規模經濟:AWS、GCP、Azure 的規模讓它們在硬體採購上有極大的成本優勢,加上彈性計費(用多少付多少),對於流量波動大的場景,雲端托管的實際費用往往不比自建高。
真正值得自建的場景:有大量固定的 GPU 需求(幾十張以上 24x7 跑滿)、有資料主權合規要求(某些政府機關、醫療機構)、有足夠的基礎設施工程師。
小練習
練習 1:撰寫 Dockerfile
你有一個用 Python 3.11 和 scikit-learn 1.3.0 訓練的分類模型,儲存為 model.pkl。服務程式碼在 app.py,使用 FastAPI 提供 REST API,監聽 port 8080。請撰寫這個服務的 Dockerfile,需要注意:
- 使用輕量基礎映像
- 利用 Docker 層快取優化建構速度
- 不在映像中硬寫任何密碼或 Token
練習 2:雲端 ML 平台選擇
以下三個公司,請為每個公司推薦最適合的 ML 部署方案,並說明理由:
A. 一家台灣的電商平台,現有 IT 基礎設施主要在 AWS(RDS、S3、EC2),有 3 位 ML 工程師,要部署推薦系統和評論分析兩個模型
B. 一家醫療新創,開發 AI 醫療影像診斷輔助,資料不能出院內,只有 1 位 ML 工程師
C. 一家跨國零售企業,在台灣、美國、德國都有 IT 中心,使用 Microsoft 365,要統一管理全球的 ML 模型