在 gVisor 沙箱中运行 Stable Diffusion:基于 NVIDIA GPU 的完整实战指南

发布时间:2026/9/13 23:59:56
在 gVisor 沙箱中运行 Stable Diffusion:基于 NVIDIA GPU 的完整实战指南 在 gVisor 沙箱中运行 Stable Diffusion基于 NVIDIA GPU 的完整实战指南【免费下载链接】gvisorApplication Kernel for Containers项目地址: https://gitcode.com/GitHub_Trending/gv/gvisorgVisor 是面向容器的应用内核Application Kernel for Containers自 2023 年起逐步支持 GPU 工作负载。本文以 Stability AI 的 Stable Diffusion 生成式模型为实例完整演示如何在 gVisor 沙箱内、通过runsc运行时与 NVIDIA T4 GPU运行 Automatic1111 Stable Diffusion Web UI 与底层 PyTorch 代码。读完本文你将掌握 gVisor GPU 支持nvproxy的架构原理、驱动与环境的完整搭建步骤、验证命令序列以及驱动版本兼容性与安全模型的边界。图为沙箱化一块 GPU。这张由 Stable Diffusion v1.5 生成的图片在意识到 GPU 本身就是由沙子硅制成之后寓意会深刻得多。为什么要这么做为 AI 工作负载提供沙箱保护机器学习模型开源项目的爆发式增长带来了大量需要谨慎对待的新软件。与从互联网下载新软件应保持警惕同理运行新开源项目最好放在沙箱中。对 Automatic1111 Stable Diffusion Web UI 这类项目而言这一点尤为重要它会在用户于 Web UI 中启用各种模型、组件和扩展时自动从外部仓库下载大量内容。Pickle 格式模型的安全风险机器学习领域的模型打包与分发工具仍在早期阶段。虽然包括 Stable Diffusion 在内的一部分模型已改用更安全的 safetensors 格式但如今网上分发的绝大多数模型仍使用 Pickle 格式该格式在反序列化时可执行任意 Python 代码。因此即使使用可信的软件加载 Pickle 格式模型依然存在风险2024-04-04 补充这一漏洞向量确实在 Hugging Face 的 Inference API 中被发现过。gVisor 为这一过程提供了一层保护有助于保护宿主机。性能开销极低机器学习应用通常不是 I/O 密集型的因此往往不会经历显著的性能开销。向 GPU 上传代码并不是大量的系统调用且与 GPU 的大部分通信发生在共享内存上——这正是 gVisor 不施加任何开销的领域。因此问题不再是为什么要在 gVisor 中运行 GPU 工作负载而是为什么不呢最后——在 gVisor 里跑 GPU 工作负载本身就很酷。gVisor 的 GPU 支持原理nvproxy在动手搭建之前先理解底层机制。gVisor 在沙箱内部实现了一个名为nvproxy的代理驱动proxy driver它代理应用与宿主机上 NVIDIA 驱动之间的交互为沙箱内的应用提供访问 NVIDIA GPU 专用设备的通道GPU 应用无需修改即可在沙箱内透明地与这些设备交互。从源码结构看nvproxy的实现位于 pkg/sentry/devices/nvproxy其包级说明README.md指出nvproxy 在 gVisor 沙箱内实现了虚拟字符设备模拟真实的 NVIDIA 设备文件/dev/nvidiactl、/dev/nvidia-uvm、/dev/nvidia#。当沙箱内的应用打开并与这些设备交互时nvproxy 拦截ioctl与mmap系统调用经过必要翻译后转发给宿主机上真实的 NVIDIA 驱动。转发过程很直接nvproxy 把 ioctl 的参数结构体从应用地址空间复制到 sentry 地址空间再以 sentry 地址空间中的指针发起宿主机ioctl调用。由于部分 ioctl 结构体中包含指针与文件描述符nvproxy 必须理解 NVIDIA 内核驱动KMD的 ABI即 ioctl 结构体的布局并在 FD 表与地址空间之间做相应翻译。这一设计的完整推演过程可参考 nvidia_driver_proxy.md 提案更详细的用户指南见 gpu.md。注册与启用的源码路径从源码看runsc在沙箱启动时通过nvproxyRegisterDevices完成驱动注册runsc/boot/vfs.go当容器 OCI spec 请求 GPU 支持时调用nvproxy.Register(vfsObj, ...)并携带DriverVersion、DriverCaps驱动能力、AllowUnsupportedDriver等选项。对应的runsc命令行标志定义于 runsc/config/flags.go--nvproxy启用 NVIDIA GPU 支持旧标志若 OCI spec 中出现 NVIDIA 设备会自动启用。--nvproxy-docker注入nvidia-container-runtime-hook作为 prestart hook旧标志。--nvproxy-driver-version指定 NVIDIA 驱动 ABI 版本为空时自动探测宿主机驱动版本。--nvproxy-allow-unsupported-driver允许 nvproxy 以未官方支持的驱动版本初始化。--nvproxy-allowed-driver-capabilities允许容器请求的驱动能力白名单默认utility,compute。免责声明当前支持的边界截至本文2023-06gVisor 的 GPU 支持尚未泛化。只有部分 PyTorch 工作负载在 NVIDIA T4、L4、A100、H100 上经过测试并且要求宿主机使用你的runsc版本所支持的特定驱动版本。用下面的命令查看你所用runsc支持的驱动版本列表# 从克隆的 gVisor 仓库 $ make run TARGETSrunsc ARGSnvproxy list-supported-drivers # 从 runsc 二进制 $ runsc nvproxy list-supported-drivers该子命令的实现位于 runsc/cmd/nvproxy/list_supported_drivers.go。另外需要特别说明尽管 gVisor 会尽力沙箱化工作负载但与 GPU 交互本质上需要在 GPU 硬件上运行代码这部分隔离由 GPU 驱动与硬件本身强制执行而非 gVisor。数月之后gVisor 的 GPU 支持会变得更广、更好用不再局限于本文使用的特定版本组合在那之前本文展示的是当下 gVisor GPU 支持所达成的示例。环境搭建完整步骤本文使用 GCE 上的 Debian 虚拟机。机器需要配备 GPU且内存与磁盘要足以容纳 Stable Diffusion 及其较大的模型文件。下面的命令创建一台 4 vCPU、15GiB 内存、64GB 磁盘、带 NVIDIA T4 GPU、运行 Debian 11bullseye的虚拟机。由于这只是一次实验虚拟机被设置为 6 小时后自毁。$ gcloud compute instances create stable-diffusion-testing \ --zoneus-central1-a \ --machine-typen1-standard-4 \ --max-run-duration6h \ --instance-termination-actionDELETE \ --maintenance-policy TERMINATE \ --acceleratorcount1,typenvidia-tesla-t4 \ --create-diskauto-deleteyes,bootyes,device-namestable-diffusion-testing,imageprojects/debian-cloud/global/images/debian-11-bullseye-v20230509,moderw,size64 $ gcloud compute ssh --zoneus-central1-a stable-diffusion-testing第一步安装与 gVisor 兼容的 NVIDIA 驱动后续所有命令都在 SSH 进入虚拟机后执行。首先需要安装 gVisor 当前兼容的特定 NVIDIA 驱动版本$ sudo apt-get update sudo apt-get -y upgrade $ sudo apt-get install -y build-essential linux-headers-$(uname -r) $ runsc nvproxy list-supported-drivers $ DRIVER_VERSIONsome-driver-version # 从你的 runsc 二进制获取 $ curl -fSsl -O https://us.download.nvidia.com/tesla/$DRIVER_VERSION/NVIDIA-Linux-x86_64-$DRIVER_VERSION.run $ sudo sh NVIDIA-Linux-x86_64-$DRIVER_VERSION.run第二步安装 Docker按 Docker 官方 Debian 安装指南 安装$ sudo apt-get install -y ca-certificates curl gnupg $ sudo install -m 0755 -d /etc/apt/keyrings $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor --batch --yes -o /etc/apt/keyrings/docker.gpg $ sudo chmod ar /etc/apt/keyrings/docker.gpg $ echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release echo $VERSION_CODENAME) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null $ sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli第三步安装 NVIDIA Container Toolkit我们还需要 NVIDIA Container Toolkit它使 Docker 能够使用 GPU。按其安装说明执行$ distribution$(. /etc/os-release;echo $ID$VERSION_ID) curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sed s#deb https://#deb [signed-by/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list $ sudo apt-get update sudo apt-get install -y nvidia-container-toolkit第四步安装 gVisor 并启用 GPU 支持当然还需要安装 gVisor 本身$ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg $ curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg $ echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/gvisor-archive-keyring.gpg] https://storage.googleapis.com/gvisor/releases release main | sudo tee /etc/apt/sources.list.d/gvisor.list /dev/null $ sudo apt-get update sudo apt-get install -y runsc # gVisor 目前默认不启用 GPU 支持需要设置相应标志 $ sudo runsc install -- --nvproxytrue --nvproxy-dockertrue $ sudo systemctl restart docker第五步分层验证整个链路现在通过一组由浅入深的命令逐级验证刚才搭建的每个环节# 检查 NVIDIA 驱动已安装、版本正确、且挂载了受支持的 GPU $ sudo nvidia-smi -L GPU 0: Tesla T4 (UUID: GPU-6a96a2af-2271-5627-34c5-91dcb4f408aa) $ sudo cat /proc/driver/nvidia/version NVRM version: NVIDIA UNIX x86_64 Kernel Module DRIVER_VERSION Wed Nov 30 06:39:21 UTC 2022 # 检查 Docker 可用 $ sudo docker version # [...] Server: Docker Engine - Community Engine: Version: 24.0.2 # [...] # 检查 gVisor 可用 $ sudo docker run --rm --runtimerunsc debian:latest dmesg | head -1 [ 0.000000] Starting gVisor... # 检查 Docker GPU 支持不经 gVisor $ sudo docker run --rm --gpusall nvidia/cuda:11.6.2-base-ubuntu20.04 nvidia-smi -L GPU 0: Tesla T4 (UUID: GPU-6a96a2af-2271-5627-34c5-91dcb4f408aa) # 检查 gVisor 与 GPU 协同工作 $ sudo docker run --rm --runtimerunsc --gpusall nvidia/cuda:11.6.2-base-ubuntu20.04 nvidia-smi -L GPU 0: Tesla T4 (UUID: GPU-6a96a2af-2271-5627-34c5-91dcb4f408aa)全部通过环境就绪注意最后一条命令的关键点同时指定--runtimerunsc与--gpusall说明沙箱内的应用可以访问真实的 T4 GPU。构建 Stable Diffusion 镜像我们使用下面的Dockerfile在启用 GPU 的 Docker 容器中运行 Stable Diffusion 及其 Web UIFROM python:3.10 # 一组使其正常工作所需的依赖 RUN apt-get update apt-get install -y git wget build-essential \ nghttp2 libnghttp2-dev libssl-dev ffmpeg libsm6 libxext6 # 在本次测试使用的修订版本上克隆项目 RUN git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git \ cd /stable-diffusion-webui \ git checkout baf6946e06249c5af9851c60171692c44ef633e0 # 我们不希望构建步骤启动服务器 RUN sed -i /start()/d /stable-diffusion-webui/launch.py # 安装一些 pip 包。 # 注意此命令在 Docker 构建过程中运行不受 gVisor 沙箱保护。 RUN cd /stable-diffusion-webui COMMANDLINE_ARGS--skip-torch-cuda-test python launch.py WORKDIR /stable-diffusion-webui # 这会让 Web UI 使用 Gradio 服务创建公共 URL。 # 若计划让容器长期运行请不要使用此配置。 ENV COMMANDLINE_ARGS--share # 启动 webui 应用 CMD [python, webui.py]构建镜像并创建容器$ cat Dockerfile (... 粘贴上述内容 ...) ^D $ sudo docker build --tagsdui .启动 Web UI 并生成图片最后启动 Stable Diffusion Web UI。注意首次启动会耗时很长因为它需要从互联网下载全部模型。为了保持本文简洁我们没有设置任何持久化数据卷因此每次容器启动都会重新下载$ sudo docker run --runtimerunsc --gpusall --namesdui --detach sdui # 跟踪日志 $ sudo docker logs -f sdui # [...] Calculating sha256 for /stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors: Running on local URL: http://127.0.0.1:7860 Running on public URL: https://4446d982b4129a66d7.gradio.live This share link expires in 72 hours. # [...]大功告成现在可以打开日志中的 Gradio URL开始生成图片了——整个过程都在 gVisor 的安全边界之内。版本兼容性与能力边界结合 gpu.md 文档可以更精确地界定这套方案的适用范围。受支持的 GPU 型号gVisor 目前支持T4Turing 架构、A100 与 A10GAmpere 架构、L4Ada Lovelace 架构、H100Hopper 架构。虽然未正式支持但基于上述相同微架构的其他 NVIDIA GPU如消费级的 RTX 3090、RTX 4090大概率也能工作。驱动版本窗口gVisor 将 NVIDIA 驱动版本分为三档受支持Supported官方认证版本有持续测试开箱即用。不受支持Unsupported源码中已定义但未完整测试的版本默认runsc会拒绝启动但可通过--nvproxy-allow-unsupported-driver放行会记录警告且不受官方支持。未知Unknown源码中完全未定义的版本即使加上--nvproxy-allow-unsupported-driver也必定启动失败。runsc对驱动版本是严格匹配的因为runsc无法假设驱动版本之间存在 ABI 兼容性。nvproxy的版本树定义在 pkg/sentry/devices/nvproxy/version.go这是一棵稀疏版本树并不列出每个 NVIDIA 驱动发布版只包含建模 ABI 演变所需的特定版本其结构模仿 NVIDIA 内核驱动仓库的提交历史含master分支与独立开发分支。运行时nvproxy 读取宿主机驱动版本、在树中找到对应节点、再从根遍历到该节点、沿途应用所有 ABI 变更从而组合出该版本的最终 ABI。正因 KMD 没有任何 ABI 稳定性保证nvproxy必须为每个受支持驱动版本维护内部版本化逻辑。设备文件与 ioctl 集gVisor 只暴露/dev/nvidiactl、/dev/nvidia-uvm和/dev/nvidia#。以下设备文件不支持/dev/nvidia-caps/*MIG 相关、/dev/nvidia-drmDRM 子系统、/dev/nvidia-modeset。为降低跨版本的维护成本受支持的 ioctl 集合是有意受限的由大量 GPU 工作负载实测生成。如果工作负载因未实现的 ioctl 失败调试日志中会出现nvproxy: handler is undefined *前缀的警告对应源码见 pkg/sentry/devices/nvproxy/handlers.go。平台支持nvproxy的全部功能在systrap 与 ptrace平台上受支持KVM 平台上cudaMallocManaged()因虚拟内存布局限制目前不稳定其余功能可用。下载大模型时的宿主配置在 gVisor 内下载大模型时可能因宿主 VMA 耗尽而遭遇应用段错误。可调大/proc/sys/vm/max_map_countecho 1000000 | sudo tee /proc/sys/vm/max_map_count或直接给 runsc 传--host-settingsenforce。安全模型gVisor 能保护什么gVisor 通过多层防御保护宿主机免受沙箱内应用的攻击其中最相关的两层是将应用系统调用重定向到 sentry 处理而非直接传给宿主机内核以及对沙箱施加 seccomp-bpf 过滤器。例如 CVE-2022-0185、CVE-2024-21626 这类漏洞会因应用走的是 gVisor 自己的实现而得到缓解。对 nvproxy 而言gVisor 的 seccomp 过滤器规则被修改为仅允许对受支持的 ioctl 发起ioctl(2)调用白名单规则与各驱动版本对齐见 pkg/sentry/devices/nvproxy/seccomp_filters.go。这使 gVisor 在开放 GPU 访问的同时保留了对宿主机绝大部分的保护。但必须清醒认识到边界gVisor 对 NVIDIA GPU 驱动自身的漏洞缓解能力弱得多——因为它将调用透传给内核模块处理。如果某个驱动的某个 ioctl 存在漏洞且 gVisor 恰好透传了该 ioctlgVisor 同样会受影响如果漏洞位于未实现的功能gVisor 则用 seccomp 过滤器阻断相关调用。此外gVisor 不引入超出 NVIDIA 内核驱动所配置的额外硬件级隔离例如不校验 DMA 缓冲区。因此无论是否使用 gVisor及时更新 NVIDIA 驱动都必须纳入你的安全计划。查看当前 runsc 最新支持的驱动$ runsc nvproxy list-supported-drivers排障与后续若 GPU 工作负载失败第一选择是使用 gVisor 的 ioctl_sniffer 工具源码位于 tools/ioctl_sniffer若失败源于 nvproxy 未实现的 ioctl 命令该工具会列出具体缺失项。必要时也可深入 NVIDIA 驱动本身检出对应版本的 OSS 驱动源码进行调试。gVisor 对ioctl_sniffer与驱动差分工具tools/nvidia_driver_differ的配套使用说明可在 nvproxy README 中查阅。至此你已经完成了从 GCE 虚拟机创建、NVIDIA 驱动与 Docker/gVisor 安装、nvproxy 启用、到 Stable Diffusion Web UI 沙箱内运行的全链路搭建。所有生成过程都发生在 gVisor 的安全沙箱之内——祝你沙箱愉快【免费下载链接】gvisorApplication Kernel for Containers项目地址: https://gitcode.com/GitHub_Trending/gv/gvisor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考