nbd-vram:在Linux上使用NVIDIA GPU的显存作为交换空间
摘要
nbd-vram是一个Linux工具,通过NBD协议和CUDA使用NVIDIA GPU显存作为交换空间,为搭载焊接式内存且无法升级的系统提供额外内存。
查看缓存全文
缓存时间: 2026/06/01 20:35
c0dejedi/nbd-vram
Source: https://github.com/c0dejedi/nbd-vram
nbd-vram
在 Linux 上使用 NVIDIA GPU 的显存作为交换空间。
专为内存焊接在主板、无法升级的笔记本电脑而设计。如果你有一张 RTX 显卡,空着 8GB 显存,而系统正在将数据交换到 SSD,这个工具就能让显存派上用场。
测试环境:RTX 3070 笔记本(GA104M,物理内存 16 GB,显存 8 GB),驱动版本 580.159.03,内核 6.17,Pop!_OS。分配了 7 GB 作为交换空间。最终结果包括 zram 和 SSD 交换共约 46 GB,可寻址内存翻了三倍。溢出顺序:RAM 填满 → VRAM 吸收溢出(快,PCIe)→ zram 压缩剩余部分(CPU)→ 仅在以上全部耗尽时才使用 SSD。
演示
工作原理
一个小型守护进程通过 CUDA 驱动 API 分配显存,然后通过 NBD(网络块设备)协议在 Unix 套接字上将其作为块设备提供服务。内核内置的 nbd 驱动连接到该守护进程,并暴露出 /dev/nbdX。随后它就是一个普通的交换设备。
数据路径:内核交换子系统 → /dev/nbdX → nbd 内核驱动 → Unix 套接字 → nbd-vram 守护进程 → cuMemcpyHtoD/DtoH → GPU 显存。
无需编写或维护内核模块,无需 NVIDIA 内核符号,在升级内核或驱动后无需重新编译任何东西。
为什么不使用 NVIDIA P2P API?
“显而易见”的方法是 nvidia_p2p_get_pages_persistent,它会在 BAR1 中固定显存页,使得 CPU 可以通过 ioremap_wc 直接访问。每一个尝试这条路的现有项目都遇到了同样的障碍:NVIDIA 驱动在消费级 GeForce GPU 上返回 EINVAL。无论持久化还是非持久化变体,无论标志值如何,该 API 都在 RM 层面被限制为 Quadro/数据中心 SKU 专用,与驱动版本无关。
另一种方法——不通过 P2P API 直接对 BAR1 物理地址进行 ioremap_wc——同样无效。GPU 的内部页表仅映射了约 16 MiB 的 BAR1(仅用于显示帧缓冲区)。从其余地址读取返回零。mkswap 看似成功,但随后 swapon 会因为交换头部实际不存在而失败。
NBD 方法绕过了所有这些限制。cuMemcpyHtoD 和 cuMemcpyDtoH 在任何 CUDA GPU 上都能工作,无需任何特殊权限。
要求
- 支持 CUDA 的 NVIDIA GPU(任意消费级 RTX/GTX 显卡)
- 带有
libcuda.so.1的 NVIDIA 驱动(无需 CUDA 工具包) - Linux 内核 3.0+(nbd 模块,大多数发行版已内置)
nbd-client软件包gcc、make
安装
git clone https://github.com/c0dejedi/nbd-vram
cd nbd-vram
sudo ./install.sh
sudo systemctl start vram-swap-nbd
验证:
swapon --show
# NAME TYPE SIZE USED PRIO
# /dev/nbd0 partition 7G 0B 1500
该服务在安装时即被启用,因此每次启动时都会自动运行。
配置
编辑 /etc/systemd/system/vram-swap-nbd.service:
Environment=VRAM_SETUP_SIZE_MB=7168 # 要使用的显存量(MB)
Environment=VRAM_SWAP_PRIORITY=1500 # 交换优先级(数值越高,越优先使用)
守护进程首先尝试请求的大小,如果 GPU 内存不足,则以 512 MiB 为步长逐步回退——因此即使显示合成器已占用了部分显存,它也会尽可能多获取。VRAM_SETUP_SIZE_MB 是上限,而非硬性要求。
修改后,运行 sudo systemctl daemon-reload && sudo systemctl restart vram-swap-nbd。
快速测试(无需安装)
sudo bash test-nbd.sh
该脚本会分配显存、连接 NBD 设备、执行 1 MiB 写入/回读检查、激活交换,然后打印清理指令。如果已有测试实例在运行,install.sh 会自动执行清理。
快速测试通过后,要对整个分区进行压力测试:
sudo bash test-fill.sh
该脚本会用零填充整个显存分区,验证样本回读,然后在退出时自动恢复交换。
性能
在 RTX 3070 笔记本上通过 test-fill.sh 测量(7 GiB 顺序写入,4M 块):
- 顺序吞吐量:约 1.3 GB/s
- 延迟低于 NVMe,因为数据路径通过 PCIe 直达 GPU,而非经过存储设备
对于已使用 zram 的笔记本电脑,将 VRAM 交换设置为更高优先级,使其在溢出时优先于 SSD 吸收数据。
卸载
sudo systemctl disable --now vram-swap-nbd
sudo rm /usr/local/bin/nbd-vram
sudo rm /usr/local/bin/nbd-vram-connect.sh
sudo rm /usr/local/bin/nbd-vram-disconnect.sh
sudo rm /etc/systemd/system/vram-swap-nbd.service
sudo systemctl daemon-reload
许可证
MIT - Sean Lobjoit (c0dejedi)
相似文章
@leftcurvedev_: 任何拥有8GB或12GB显存配置的用户都需要明白,“-ncmoe”是在llama.cpp上提升性能的关键标志…
解释了llama.cpp中的-ncmoe标志如何通过将部分专家层卸载到CPU+内存,在有限显存(8-12GB)上提升MoE模型(如Qwen3.6 35B A3B)的性能,基准测试显示在RTX 3070Ti上可实现高达5倍的加速。
交换表、闪存友好的交换、swap_ops 等
本文介绍了 Linux 内核交换子系统的最新改进和未来计划,包括减少每页开销、基于 folio 的辅助函数,以及使交换更适配固态存储的努力。相关内容在 2026 年 Linux 存储、文件系统、内存管理与 BPF 峰会上进行了讨论。
高显存本地编码模型——依然首选 Qwen 3.6 27B 吗?
用户分享了使用 Qwen 3.6 27B 进行本地编码任务的经验,并寻求适合拥有 224GB 显存系统的更大模型(100B 以上)的推荐。
RDNA3上llama.cpp的Flash Attention:比Vulkan f16 K减少47% KV VRAM,在F16 K / q4_0 V上KLD几乎无损。第一部分。
一种针对RDNA3 GPU上llama.cpp的新packed16 K技术,相比Vulkan fp16将KV缓存VRAM减少47%,使用int8打包和原生dot4指令,以最小的KLD损失保持fp16质量的K值。
给机子加了一张旧2070 Super后,我回不去了……更糟糕的是,我现在需要更多
一位用户分享了将旧款 NVIDIA 2070 Super GPU 添加到机子中以获得额外 VRAM 的经验,使其能够以高量化和上下文大小运行像 Qwen3.6-27B 这样的更大模型,且性能良好,现在正考虑升级到 3090 以获得更多 VRAM。