SAM3 笔记3:基于 Docker + GPU 的部署方案

引言

2025年11月,Meta Research 正式发布了 SAM 3 (Segment Anything Model 3)。作为一个统一了图像分割、视频跟踪和概念检测的端到端基础模型,SAM 3 的强大毋庸置疑。

但对于工程部署来说,SAM 3 带来了一个巨大的挑战:激进的环境依赖。它强制要求 Python 3.12+、PyTorch 2.7 (预览版) 和 CUDA 12.6+。如果在本地 Windows 或 WSL 环境中直接配置,极易引发“依赖地狱”,破坏现有的环境。

本文将分享如何在 Windows WSL 2 环境下,利用 DockerNVIDIA NGC 镜像,构建一个隔离、稳定且高性能的 SAM 3 推理环境。


为什么选择 Docker 方案?

在尝试裸机部署和 Docker 部署后,坚定地选择了 Docker,理由如下:

  1. 版本隔离:SAM 3 需要 PyTorch 2.7 和 CUDA 12.6。而大多数现有项目还停留在 PyTorch 2.4/CUDA 11.8。Docker 让我们可以在不升级宿主机驱动库的情况下运行最新版 CUDA 环境(依靠 NVIDIA 的兼容性层)。
  2. NVIDIA NGC 镜像加持:手动编译 PyTorch 预览版极其痛苦。NVIDIA 官方提供的 nvcr.io/nvidia/pytorch:25.02-py3 镜像已经预装了 PyTorch 2.7 和相关的 CUDA 优化库,开箱即用。
  3. 可复现性:一旦构建好镜像,无论是在本地 RTX 3060 还是云端 H100 上,都能保证环境一致。

核心部署步骤

1. 准备工作

  • 宿主机:Windows 10/11 + WSL 2 (Ubuntu)。
  • 驱动:安装最新的 NVIDIA Game Ready 驱动(支持 CUDA 12.6+)。
  • Docker:安装 Docker Desktop 并开启 WSL 2 Backend。

2. 编写 Dockerfile (最终优化版)

这是经过多次调试后的最终版本,解决了视频解码、OpenCV 依赖和 Ubuntu 24.04 的包名变化问题。

# 使用 NVIDIA 官方提供的 PyTorch 镜像 (包含 CUDA 12.8, PyTorch 2.7预览版)
FROM nvcr.io/nvidia/pytorch:25.02-py3

# 1. 基础环境配置
ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# 优化 PyTorch 显存分配策略,减少 OOM 风险
ENV PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True

# 2. 安装系统级依赖 (修正版)
# 注意:将 libgl1-mesa-glx 替换为了 libgl1
RUN apt-get update && apt-get install -y --no-install-recommends \
    ffmpeg \
    libsm6 \
    libxext6 \
    libgl1 \
    libglib2.0-0 \
    git \
    wget \
    vim \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# 3. 设置工作目录
WORKDIR /app

# 4. 克隆并安装 SAM 3
# 使用 --no-deps 防止 pip 破坏 NGC 镜像里预装的高性能 PyTorch
RUN git clone https://github.com/facebookresearch/sam3.git && \
    cd sam3 && \
    pip install -e . --no-deps && \
    pip install -e ".[notebooks]" --no-deps

# 5. 安装额外的服务化依赖 (FastAPI, Redis等)
RUN pip install fastapi uvicorn[standard] python-multipart jupyterlab

# 6. 设置默认环境变量
ENV SAM3_CHECKPOINT_PATH=/app/checkpoints/sam3.pt

# 7. 暴露端口 (8888用于Jupyter, 8000用于API)
EXPOSE 8888 8000

# 8. 默认命令:启动 bash,方便进入后调试
CMD ["/bin/bash"]

3. 启动容器

关键在于 --shm-size--gpus 参数。

docker run -it -d \
    --name sam3-service \
    --gpus all \
    --shm-size=16g \
    --restart unless-stopped \
    -v $(pwd)/checkpoints:/app/checkpoints \
    -v $(pwd)/src:/app/src \
    sam3-wsl-optimized
注意--shm-size=16g 至关重要。PyTorch DataLoader 依赖共享内存,默认的 64MB 会导致视频处理时直接崩溃 (Bus Error)。

4. 模型权重下载 (Python 脚本版)

由于 Hugging Face 的 CLI 工具在某些网络环境下不稳定,推荐使用以下 Python 脚本强制下载

前提:设置好 HF_ENDPOINT 为镜像站(国内用户),并准备好 Hugging Face Token。

import os
from huggingface_hub import hf_hub_download

os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
MY_HF_TOKEN = "your_token_here"

print(">>> 开始下载 SAM 3 权重...")
# 强制下载实体文件,禁用软链接,覆盖旧文件
path = hf_hub_download(
    repo_id="facebook/sam3",
    ignore_patterns=["*.safetensors"],
    local_dir="/app/checkpoints",
    token=MY_HF_TOKEN,
    local_dir_use_symlinks=False, 
    force_download=True
)
print(f"下载完成: {path}")

5. 推理代码 (AMP 混合精度版)

为了在 RTX 3060 (12GB) 上流畅运行,且避免类型不匹配错误,必须使用 torch.autocast

import torch
from PIL import Image
from sam3.model_builder import build_sam3_image_model
from sam3.model.sam3_image_processor import Sam3Processor
import requests
from io import BytesIO

def run_inference():
    device = "cuda"
    checkpoint = "/app/checkpoints/sam3.pt"
    
    # 1. 加载模型 (保持权重为 Float32,不要手动转 dtype)
    print("Loading model...")
    model = build_sam3_image_model(checkpoint_path=checkpoint)
    model.to(device)
    processor = Sam3Processor(model)
    
    # 2. 准备图片
    url = "https://raw.githubusercontent.com/facebookresearch/segment-anything/main/notebooks/images/truck.jpg"
    image = Image.open(BytesIO(requests.get(url).content)).convert("RGB")
    
    # 3. 推理 (关键:使用 Autocast 上下文)
    print("Running inference...")
    with torch.autocast(device_type="cuda", dtype=torch.bfloat16):
        inference_state = processor.set_image(image)
        output = processor.set_text_prompt(state=inference_state, prompt="truck")
    
    print(f"Detected {len(output['masks'])} objects!")

if __name__ == "__main__":
    run_inference()

踩坑实录 (Troubleshooting)

在部署过程中,我们遇到并解决了以下几个典型问题:

坑 1:libgl1-mesa-glx 安装失败

  • 现象:构建 Docker 镜像时报错 Package 'libgl1-mesa-glx' has no installation candidate
  • 原因:基础镜像基于 Ubuntu 24.04 (Noble),该版本已废弃旧版 OpenGL 包。
  • 解决:将 Dockerfile 中的依赖包名称替换为 libgl1

坑 2:模型加载报错 filename 'storages' not found

  • 现象torch.load() 报错,提示找不到 storages。
  • 原因:Hugging Face 默认下载了 model.safetensors 或者下载了一个只有几 KB 的 LFS 指针文件。SAM 3 官方代码硬编码使用 torch.load 读取 Zip 格式的 .pt 文件,无法识别 .safetensors
  • 解决:删除 checkpoints 目录下所有文件,使用 hf_hub_download 显式指定 filename="sam3.pt" 且设置 local_dir_use_symlinks=False

坑 3:类型不匹配 Float and BFloat16

  • 现象:推理时报错 RuntimeError: mat1 and mat2 must have the same dtype
  • 原因:手动执行了 model.to(dtype=torch.bfloat16) 将权重转为了 BF16,但输入数据(Processor 处理后)默认为 FP32。
  • 解决不要手动转换模型权重。保持权重为 FP32,仅在推理代码块外部包裹 with torch.autocast(device_type="cuda", dtype=torch.bfloat16):,让 PyTorch 自动处理混合精度。

坑 4:依赖缺失

  • 现象:运行脚本提示 ModuleNotFoundError: No module named 'iopath'decord
  • 原因:为了保护 NGC 镜像环境使用了 --no-deps 安装 SAM 3,导致子依赖未安装。
  • 解决:手动补齐安装:pip install iopath ftfy timm decord scikit-image

结语

通过 Docker 容器化部署,我们成功避开了底层驱动的版本冲突,在 WSL 环境下构建了稳定的 SAM 3 服务。这套方案不仅适用于本地开发,也完全可以直接推送到生产环境的 Kubernetes 集群中运行。