熱門分類
載入中…
目錄0%

🤖 LLM Ops 實戰:在 Linux 環境使用 Docker 部署 DeepSeek-V3 私有化模型與 API 整合

    🤖 LLM Ops 實戰:在 Linux 環境使用 Docker 部署 DeepSeek-V3 私有化模型與 API 整合

    把大型語言模型(LLM)「搬回內網」的需求,近一年明顯變多:資料不出門、延遲更低、成本更可控、治理更一致。 但真正落地時,挑戰通常不是「跑起來」而已,而是:可維運、可監控、可控權限、可擴展、可回滾

    這篇以 LLM Ops(LLM Operation) 的視角,示範如何在 Linux 上用 Docker 佈署 DeepSeek-V3 推論服務, 透過 vLLM 提供 OpenAI-Compatible API,再用 Nginx 作 API Gateway 做權限、限流與路由, 最後補上 Prometheus/Grafana 監控與 systemd 開機自動啟動,形成一套可上線的私有化推論基座。

    📑 目錄

    一、先談現實:DeepSeek-V3 的部署門檻與策略

    DeepSeek-V3 屬於大型 MoE(Mixture-of-Experts)模型,定位更接近「旗艦級」推論服務。 因此在私有化部署前,建議先做兩個決策:

    1. 目標是「上線供內部多人使用」還是「PoC/開發驗證」?
      PoC 可以用較小模型或 Distill/量化版本先把流程打通;上線才投入更完整的資源與治理。
    2. 要提供哪一種 API 介面?
      企業內部最實用的是 OpenAI-Compatible API,因為既有應用(SDK、框架、RAG)改動最小。

    本文以「介面一致、維運可控」為核心:即使你未必一開始就用最大規模的權重, 也能先把整套 LLM Ops 基座建起來,後續再替換模型版本或擴容 GPU。

    二、目標架構:Docker + vLLM + API Gateway + Observability

    下圖是本文推薦的最小可上線架構(MVP),保留了實務上最常見的治理需求:

    Client / App / RAG
            |
            |  HTTPS + API Key / JWT(建議)
            v
       [ Nginx API Gateway ]
            |
            |  Proxy to internal service
            v
    [ vLLM OpenAI-Compatible Server ]  -- loads -->  DeepSeek-V3 weights (HF/local)
            |
            +--> /metrics  ---> Prometheus ---> Grafana
            |
            +--> Logs (stdout/stderr) ---> Loki/ELK(選配)
    

    這樣拆層的好處是:推論引擎專注推論,安全與流量治理交給 Gateway,監控與稽核可以獨立演進。

    三、部署前準備:GPU、Docker 與模型檔案

    1) 基本檢查清單

    • Linux 主機:建議 Ubuntu 22.04/24.04 或同級伺服器版發行版。
    • NVIDIA Driver:確認 nvidia-smi 可正常顯示 GPU。
    • Docker / Docker Compose:推論服務以容器化方式上線與回滾。
    • GPU Container Runtime:NVIDIA Container Toolkit(讓容器能使用 GPU)。
    • 儲存空間:模型權重通常非常大,請預留足夠容量與 I/O(NVMe 優先)。

    2) 建議目錄規劃

    sudo mkdir -p /opt/llm/models
    sudo mkdir -p /opt/llm/deepseek-v3
    sudo chown -R $USER:$USER /opt/llm
    

    3) 下載模型權重(以 Hugging Face 為例)

    實務上,建議把模型權重固定在一個檔案路徑,並以「版本化資料夾」管理,避免更新時覆蓋造成回滾困難。

    # 安裝 HF CLI(若已安裝可略)
    python3 -m pip install -U "huggingface_hub[cli]"
    
    # 登入(若模型需要授權或你要用加速下載)
    huggingface-cli login
    
    # 下載到本地(範例:DeepSeek-V3)
    # 建議每次下載綁定版本資料夾,例如:/opt/llm/models/deepseek-v3/2025-11-27/
    mkdir -p /opt/llm/models/deepseek-v3/2025-11-27
    huggingface-cli download deepseek-ai/DeepSeek-V3 \
      --local-dir /opt/llm/models/deepseek-v3/2025-11-27 \
      --local-dir-use-symlinks False
    

    四、Docker 部署 vLLM(OpenAI-Compatible Server)

    vLLM 提供 OpenAI-Compatible Server,可直接對外提供 /v1/models/v1/chat/completions 等端點, 讓你把既有應用的呼叫模式「轉向內網」。

    方案 A:docker run(最快驗證)

    # 以 vLLM OpenAI server 為例(映射 8000)
    # 重要:請依 GPU 數量調整 --tensor-parallel-size
    docker run --rm -it \
      --gpus all \
      -p 8000:8000 \
      -v /opt/llm/models:/models \
      vllm/vllm-openai:latest \
      --model /models/deepseek-v3/2025-11-27 \
      --served-model-name deepseek-v3 \
      --tensor-parallel-size 1 \
      --max-model-len 8192 \
      --gpu-memory-utilization 0.90 \
      --trust-remote-code \
      --disable-log-requests
    

    啟動後先做健康檢查:

    curl http://127.0.0.1:8000/v1/models
    

    方案 B:docker compose(上線建議)

    把設定固定在 compose.yml,可重現部署、可追版、也更容易接 systemd。

    cat > /opt/llm/deepseek-v3/compose.yml <<'YAML'
    services:
      deepseek_v3:
        image: vllm/vllm-openai:latest
        container_name: deepseek-v3
        restart: unless-stopped
        ports:
          - "8000:8000"
        volumes:
          - /opt/llm/models:/models:ro
        environment:
          # 若你的流程需要 HF Token,可用環境變數注入(也可改用 docker secret)
          # - HUGGING_FACE_HUB_TOKEN=xxxx
          - TZ=Asia/Taipei
        command:
          - "--model=/models/deepseek-v3/2025-11-27"
          - "--served-model-name=deepseek-v3"
          - "--tensor-parallel-size=1"
          - "--max-model-len=8192"
          - "--gpu-memory-utilization=0.90"
          - "--trust-remote-code"
          - "--disable-log-requests"
        # 需要 Compose v2 + NVIDIA runtime 支援
        deploy:
          resources:
            reservations:
              devices:
                - capabilities: ["gpu"]
    YAML
    
    cd /opt/llm/deepseek-v3
    docker compose up -d
    docker compose logs -f
    

    若你是多張 GPU(例如 2/4/8 張)做張量平行,核心就是把 --tensor-parallel-size 設為對應的 GPU 數, 並確保容器能看見足夠 GPU。資源不足時,請先降低 --max-model-len、或採用更小/量化版本模型。

    五、Nginx API Gateway:TLS、API Key、限流與路由

    不建議把 vLLM 服務(8000)直接暴露在公開網路。實務上應該: vLLM 只聽內網,由 Nginx 作 API Gateway 統一做存取控制與流量治理。

    1) 最小可用:Header API Key + 限流

    以下示範以 X-API-Key 作為簡易授權(內網環境常用),並加上 basic rate limit:

    # /etc/nginx/conf.d/llm-gateway.conf
    # 注意:此為示範,TLS/憑證、WAF、IP allowlist 可依需求擴充
    
    limit_req_zone $binary_remote_addr zone=llm_ratelimit:10m rate=10r/s;
    
    map $http_x_api_key $llm_allowed {
      default 0;
      "REPLACE_WITH_YOUR_KEY" 1;
    }
    
    server {
      listen 443 ssl;
      server_name llm.internal.example.com;
    
      # ssl_certificate / ssl_certificate_key 請自行配置
      # ssl_certificate     /etc/letsencrypt/live/xxx/fullchain.pem;
      # ssl_certificate_key /etc/letsencrypt/live/xxx/privkey.pem;
    
      if ($llm_allowed = 0) { return 401; }
    
      location / {
        limit_req zone=llm_ratelimit burst=20 nodelay;
    
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
    
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    
        # 避免超長回應被切斷(可視情況調整)
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
      }
    
      # 可把 metrics 也收進來,但建議只允許監控網段
      location /metrics {
        allow 10.0.0.0/8;
        deny all;
        proxy_pass http://127.0.0.1:8000/metrics;
      }
    }
    

    建議後續演進方向:API Key 改成 JWT / OAuth2、加上 用戶/部門配額、並將請求記錄導入 SIEM。

    六、API 整合:curl / Python(OpenAI SDK)/ 既有系統改造

    1) curl:快速驗證 Chat Completions

    curl https://llm.internal.example.com/v1/chat/completions \
      -H "Content-Type: application/json" \
      -H "X-API-Key: REPLACE_WITH_YOUR_KEY" \
      -d '{
        "model": "deepseek-v3",
        "messages": [
          {"role": "system", "content": "你是嚴謹的企業 IT 助理。"},
          {"role": "user", "content": "請用條列整理:Docker 化推論服務上線前要檢查哪些項目?"}
        ],
        "temperature": 0.2
      }'
    

    2) Python:使用 OpenAI SDK 指向內網

    python3 -m pip install -U openai
    
    python3 - <<'PY'
    from openai import OpenAI
    
    client = OpenAI(
      base_url="https://llm.internal.example.com/v1",
      api_key="REPLACE_WITH_YOUR_KEY"
    )
    
    resp = client.chat.completions.create(
      model="deepseek-v3",
      messages=[
        {"role":"system","content":"你是嚴謹的企業 IT 助理。"},
        {"role":"user","content":"請給我一份 LLM Ops 上線檢查清單(含監控、日誌、資安)。"}
      ],
      temperature=0.2
    )
    
    print(resp.choices[0].message.content)
    PY
    

    3) 既有系統改造建議(最小變更)

    • 統一設定:以環境變數管理 LLM_BASE_URLLLM_API_KEY,避免散落在程式碼。
    • 模型名稱抽象化:不要把特定模型寫死;用 MODEL_NAME 參數可快速切換版本(回滾更容易)。
    • 超時與重試策略:推論延遲本來就高於一般 API,請設定合理 timeout、並以冪等方式重試。
    • 敏感資料處理:進入 LLM 之前先做遮罩(例如 Token、帳密、個資),並把遮罩規則版本化。

    七、LLM Ops 必備:監控、日誌、容量規劃、版本控管與回滾

    1) 監控:Prometheus / Grafana

    vLLM 通常會提供 /metrics(Prometheus 格式)供抓取。最小設定如下:

    # prometheus.yml(片段)
    scrape_configs:
      - job_name: "vllm-deepseek"
        metrics_path: /metrics
        static_configs:
          - targets: ["llm.internal.example.com:443"]
    

    建議至少做四張圖:

    • 延遲:P50/P95/P99(從 Gateway 與 vLLM 各看一份)
    • 佇列/並發:等待中的請求數、處理中的請求數
    • 吞吐:tokens/s、requests/s
    • 資源:GPU utilization、GPU memory、CPU/RAM、磁碟 I/O

    2) 日誌:可稽核但不洩漏

    • 推論端:建議在隱私敏感場景使用 --disable-log-requests,避免把 prompt/response 打到 logs。
    • Gateway 端:保留 request id、來源、耗時、狀態碼;必要時記錄使用者/部門識別(配額與稽核)。
    • 資料保留:訂定 retention(例如 14/30/90 天),避免無限制成長。

    3) 容量規劃:把「可服務的人數」量化

    LLM 的容量規劃重點通常不是 CPU,而是:GPU 記憶體KV Cache最大上下文長度同時併發數。 實務建議做兩個限制:

    • 限制 max tokens / max model len:先保穩定,再逐步放寬。
    • Gateway 限流:避免尖峰把推論服務打爆(burst + rate)。

    4) 版本控管與回滾:模型也是「發版物」

    • 模型版本化:例如 /opt/llm/models/deepseek-v3/2025-11-27,不要用「latest」資料夾覆蓋。
    • 配置版本化compose.yml、Nginx conf、Prometheus conf 都要進 Git。
    • 回滾策略:出事時先回滾到上一個穩定模型路徑,再排查新版本。

    5) 開機自動啟動:用 systemd 管住 docker compose

    # /etc/systemd/system/deepseek-v3.service
    [Unit]
    Description=DeepSeek-V3 vLLM (Docker Compose)
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=oneshot
    WorkingDirectory=/opt/llm/deepseek-v3
    ExecStart=/usr/bin/docker compose up -d
    ExecStop=/usr/bin/docker compose down
    RemainAfterExit=yes
    TimeoutStartSec=0
    
    [Install]
    WantedBy=multi-user.target
    
    # 啟用
    sudo systemctl daemon-reload
    sudo systemctl enable --now deepseek-v3.service
    sudo systemctl status deepseek-v3.service
    

    八、常見問題與排障清單

    1) 容器看不到 GPU

    nvidia-smi
    docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
    
    • 若第二行失敗:優先檢查 NVIDIA Driver 與 NVIDIA Container Toolkit。

    2) 啟動成功但請求很慢或常超時

    • 先降低 --max-model-len 與每次請求的 max_tokens
    • 檢查 GPU memory 是否爆掉(KV Cache 不足會導致交換/退化)。
    • 把 Gateway 的 proxy_read_timeout 調大,避免回應被切斷。

    3) /metrics 抓不到

    • 先確認:curl http://127.0.0.1:8000/metrics
    • 若走 Nginx:確認 allowlist 與 proxy_pass 路徑。

    4) 模型更新後出現不相容或行為改變

    • 以模型版本資料夾快速回滾。
    • 保留一份「固定測試集」(提示詞 + 期望輸出風格)做 smoke test。

    💬 互動留言

    你目前的部署環境是單機、多 GPU,還是準備走 K8s / Ray 的分散式推論?也歡迎分享你遇到的瓶頸(GPU 記憶體、延遲、併發、權限控管、監控指標)。

    • 想看下一篇:K8s 上線(HPA/自動擴縮/灰度發版)與模型回滾策略
    • 想看實作:RAG(向量庫)+內網 OpenAI-Compatible API 的整合範本
    • 想看治理:部門配額、審計日志、提示詞遮罩與資料防外洩

    最後更新:2026-01-02 · 作者:WWFandy

    🔗 分享這篇 LINE Facebook X

    沒有留言:

    字級