# nbd-vram - Linux에서 NVIDIA GPU VRAM을 스왑 공간으로 사용하는 도구

> Clean Markdown view of GeekNews topic #30148. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=30148](https://news.hada.io/topic?id=30148)
- GeekNews Markdown: [https://news.hada.io/topic/30148.md](https://news.hada.io/topic/30148.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-06-04T00:34:26+09:00
- Updated: 2026-06-04T00:34:26+09:00
- Original source: [github.com/c0dejedi](https://github.com/c0dejedi/nbd-vram)
- Points: 1
- Comments: 1

## Topic Body

- **nbd-vram**은 Linux에서 NVIDIA GPU의 유휴 VRAM을 높은 우선순위의 스왑 공간으로 쓰게 해주는 작은 데몬임
- 납땜 메모리라 업그레이드가 어렵고 내장 AMD/ATI GPU가 화면 출력을 맡는 **하이브리드 그래픽 노트북**에서, 놀고 있는 NVIDIA VRAM을 메모리 압박 완화에 활용함
- 테스트 환경은 AMD/ATI + RTX 3070 Laptop, RAM 16GB, VRAM 8GB, NVIDIA driver 580.159.03, kernel 6.17, Pop!_OS이며, VRAM 7GB를 스왑으로 할당해 zram·SSD 스왑까지 합쳐 약 46GB의 주소 지정 가능한 메모리를 구성함
- 동작 순서는 RAM이 먼저 차고, 그다음 **VRAM**이 PCIe를 통해 넘친 페이지를 흡수하며, 이후 zram이 CPU로 압축하고, 마지막에 SSD를 사용하는 구조임
- 데몬은 CUDA driver API로 VRAM을 할당하고, Unix socket 위의 **NBD(Network Block Device)** 프로토콜로 블록 장치를 제공하며, 커널의 내장 `nbd` 드라이버가 `/dev/nbdX`로 노출해 일반 스왑 장치처럼 사용함
- 데이터 경로는 kernel swap subsystem → `/dev/nbdX` → nbd kernel driver → Unix socket → nbd-vram daemon → `cuMemcpyHtoD/DtoH` → GPU VRAM으로 이어짐
- 별도 커널 모듈이나 NVIDIA 커널 심볼이 필요 없어서, 커널·드라이버 업데이트 뒤에도 재빌드 없이 유지될 수 있음
- NVIDIA P2P API 방식은 consumer GeForce GPU에서 `nvidia_p2p_get_pages_persistent`가 `EINVAL`을 반환하고, BAR1 직접 `ioremap_wc` 방식도 약 16MiB의 디스플레이 프레임버퍼 외 영역 읽기가 0을 반환해 실패함
- **CUDA 복사 경로**인 `cuMemcpyHtoD`와 `cuMemcpyDtoH`는 특별한 권한 없이 CUDA GPU에서 동작하므로, NBD 접근이 P2P·BAR1 제약을 우회함
- 요구사항은 CUDA 지원 NVIDIA GPU, `libcuda.so.1`이 있는 NVIDIA 드라이버, Linux kernel 3.0+의 nbd 모듈, `nbd-client`, `gcc`, `make`이며 CUDA toolkit은 필요 없음
- 설치 후 `vram-swap-nbd` systemd 서비스가 부팅 시 자동 실행되며, `/etc/systemd/system/vram-swap-nbd.service`의 `VRAM_SETUP_SIZE_MB`와 `VRAM_SWAP_PRIORITY`로 사용할 VRAM 상한과 스왑 우선순위를 조정함
- 데몬은 요청한 VRAM 크기를 먼저 시도하고 GPU 메모리가 부족하면 512MiB 단위로 줄여 할당하므로, `VRAM_SETUP_SIZE_MB`는 필수 크기가 아니라 상한으로 동작함
- 전원 인식 관리를 켜면 AC 전원 해제나 배터리 임계값 이하에서 서비스가 자동 중지되고, 전원이 복구되면 다시 시작되며, 수동 `systemctl stop`은 덮어쓰지 않음
- RTX 3070 Laptop 벤치마크에서 순차 처리량과 지속 랜덤 I/O는 NVMe가 더 빠르지만, 4K 읽기 1 request/sec 지연 시간은 VRAM이 평균 335us로 NVMe 9.05ms보다 27배 빠름
- **MIT 라이선스**로 제공되며, 저장소는 스모크 테스트용 `test-nbd.sh`, 전체 파티션 검사용 `test-fill.sh`, 처리량·IOPS·지연 시간 벤치마크 스크립트를 함께 제공함

## Comments



### Comment 58879

- Author: neo
- Created: 2026-06-04T00:34:27+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=48377404) 
- CUDA를 통해 파일 저장소나 마운트처럼 다루면 오버헤드가 크니, **BAR**를 쓰면 처리량이나 IOPS를 확실히 개선할 수 있을 것 같음

- 납땜 메모리라 업그레이드 경로가 없는 노트북용이라는 설명이라면, 비싼 RAM에서 더 비싼 RAM으로 왜 스왑하나 했던 즉각적인 의문에는 답이 됨  
  용도는 좁아 보이지만, **SSD로 스왑되는 상황**에서 놀고 있는 8GB VRAM을 쓰는 건 필요할 때 좋은 아이디어임
  - 또 다른 이유로, VRAM이 있지만 항상 쓰지는 않는 경우가 있음  
    예를 들어 게임하려고 GPU를 샀다면, 게임하지 않을 때는 데스크톱 렌더링에 **16GB VRAM**이 필요하지 않으니 다른 용도로 써도 되지 않나 싶음  
    다만 게임을 시작할 때 스왑으로 쓰던 VRAM을 시스템이 해제할 수 있다는 전제가 필요한데, 실제로 가능한지는 궁금함
  - VRAM을 일반 RAM처럼 실제로 쓸 수 있나? 예를 들어 16GB RAM 모듈이 있고 GPU에 **16GB VRAM**이 있으면, 시스템이 32GB RAM으로 표시되게 만들 수 있는지, 그 영향은 무엇인지 궁금함
  - 옛날에는 이런 걸 **RAM 디스크**라고 불렀고, Atari ST가 엄청 빨라졌음  
    80년대 중반부터 90년대 중반까지 영국에 흔했던 Amstrad PCW에서는 최대 512kB RAM을 쓸 수 있었고, 그중 꽤 큰 부분을 RAM 디스크로 만들 수 있었음  
    Turbo Pascal로 컴파일할 때도 아주 빨라졌음 :-)

- 아이디어는 좋은데 여기서는 뭔가 크게 잘못된 듯함  
  RTX 3070 Laptop에서 순차 처리량이 약 **1.3 GB/s**라는데, 이 RTX 3070 칩은 PCIe 4.0 x16이라 64GB/s가 나와야 하고, 8GB GDDR6 자체는 448GB/s임  
  NVMe 드라이브로 스왑하는 게 두 배는 빠르겠지만 지연 시간은 더 높을 것임
  - PCIe 4.0 x16은 방향당 **32 GB/s**이고, 여기 구현 방식은 고성능을 원할 때 택할 방식이 아님  
    벤치마크도 ZRAM을 써서 돌렸는데, ZRAM은 스왑에 쓰기 전에 페이지를 압축함. 그 성능 오버헤드가 정확히 얼마인지는 모르지만 꽤 클 가능성이 있음  
    우선 사용자 공간 프로그램이 느리기로 알려진 nbd 드라이버에 걸려 있고, GPU로 전송하기 전에 사용자 공간의 바운스 버퍼도 사용함. 커널이 페이지를 스왑해야 하면 먼저 사용자 공간에 노출된 버퍼로 복사하고, 사용자 공간 프로그램이 다시 깨어나 CUDA 연산을 발행해 그 페이지를 장치 메모리로 복사해야 함  
    nbd는 높은 큐 깊이나 인접 접근 병합도 잘 지원하지 않음. 커널이 병합 없이 4K 페이지 스왑을 많이 발행하면, 4 GB/s만 처리해도 초당 최소 백만 번의 커널/사용자 공간 문맥 전환이 필요해짐. 64 GB/s는 말할 것도 없음. 이건 NBD 부분만 본 것이고 NVIDIA 드라이버의 복잡함은 제외한 것임  
    PCIe는 데이터를 많이 옮길 수 있지만, 전체 대역폭에 가까이 가려면 긴 페이지 목록을 가진 **DMA 엔진**을 써야 함. PCIe에서 4K 페이지마다 전송을 설정하면 버스를 완전히 포화시킬 수 없음  
    NVMe로 스왑하는 경로는 매우 최적화되어 있음. 스와퍼가 페이지 목록을 NVMe 드라이버에 직접 제출할 수 있고, 컨트롤러가 RAM에서 직접 DMA로 가져가므로 CPU 쪽 복사나 문맥 전환이 전혀 없음  
    ublk 드라이버로 옮기면 사용자 공간 바운스 버퍼를 피할 수 있을지도 모르고, 여러 쓰기 큐로 CUDA 복사를 병렬 설정할 수도 있어 개선 가능성이 있음
  - NVMe로 스왑하면 NAND의 **PE 사이클**도 소모해서 시간이 지나며 마모됨  
    RAM이나 VRAM은 사용한다고 열화되지 않음

- 개발 머신에 **32GB RAM**과 AI 모델을 돌리지 않을 때 대부분 놀고 있는 **32GB VRAM**이 있어서, 이 아이디어가 그렇게 나쁘지는 않음
  - 이건 pcmasterrace식으로 상체만 크고 다리는 비쩍 마른 몸 같은 느낌임

- **역압**은 어떻게 처리하는지 궁금함. VRAM이 스왑 공간으로 쓰이는 동안 VRAM 할당 요구가 들어오면 어떻게 되나?  
  X11에서는 버퍼가 미리 할당돼서 그렇게 나쁘지 않지만, Wayland에서는 할당이 훨씬 동적이라 VRAM이 부족해지면 데스크톱 전체가 쉽게 죽을 수 있음  
  Hyprland+llama-server+KVM으로 컴퓨터를 전환하다가 VRAM을 해제하지 못해서 이런 충돌을 몇 번 겪었음

- 사용자 수준에서 **스왑 장치**를 만드는 건 예전부터 고전적인 해결 불가능 문제 중 하나였음  
  데몬이 페이지를 스왑인하려고 하는데, 그 페이지를 스왑인하려면 데몬 자체의 페이지를 먼저 스왑인해야 한다면 어떻게 하나?  
  적어도 마이크로커널이 절대 작동하지 않을 이유로 이런 논의가 있었음. 여기서는 해법이 뭔지 잘 모르겠음
  - 데몬이 자기 페이지가 무엇인지 알 만큼 똑똑하고, 그 페이지가 스왑아웃되지 않게 막으면 됨  
    Linux 커널도 자기 텍스트 페이지가 스왑아웃되지 않게 막으니, 해법은 이미 있고 마이크로커널 설계에도 적용되지 않을 이유를 모르겠음
  - 일반 원칙은 **페이징에 관여하는 것 자체는 페이징되지 않아야 한다**는 것임  
    그 데몬 전체의 메모리를 고정해 두면 이 문제는 사소하게 해결됨

- 예전에 Linux의 MTD/phram 드라이버로 비슷한 걸 했던 기억이 있음: [https://wiki.archlinux.org/title/Swap_on_video_RAM](<https://wiki.archlinux.org/title/Swap_on_video_RAM>)  
  다만 지금도 관련이 있는지는 모르겠음. DRM과 어떻게 상호작용하는지, VRAM 일부를 예약하는 처리를 어떻게 하는지 모르기 때문임. xorg.conf로 제한을 제안하는 방식은 지금은 꽤 구식일 가능성이 큼  
  그 페이지에는 OpenCL 위에서 구현한 FUSE 파일시스템도 있음: [https://github.com/Overv/vramfs](<https://github.com/Overv/vramfs>)  
  이쪽이 더 호환성이 좋을 수도 있음
  - 예전에 mtd를 통해 **8MB 비디오 메모리**를 매핑해서 쓰곤 했고, 그 덕분에 그... X11 드라이버들을 빌드하는 데 도움이 됐음  
    추억이 떠오름

- Windows에서도 몇 년 전에 비슷한 걸 본 적 있음  
  NVIDIA 카드의 VRAM으로 RAM 드라이브를 만들 수 있게 해 주는 실험적 개념 증명 드라이버였고, 순차 접근은 예상대로 빠르지만 무작위 접근은 개선 여지가 많았음  
  GpuRamDrive는 GPU RAM으로 뒷받침되는 가상 드라이브를 만듦: [https://github.com/prsyahmi/GpuRamDrive](<https://github.com/prsyahmi/GpuRamDrive>)  
  AMD 지원 포크: [https://github.com/brzz/GpuRamDrive/](<https://github.com/brzz/GpuRamDrive/>)

- 비슷하지만 **OpenCL API**를 써서 AMD에서도 동작함  
  다만 AMD 드라이버가 꽤 버그가 많아서 “동작”의 정의가 필요함: [https://libguestfs.org/nbdkit-vram-plugin.1.html](<https://libguestfs.org/nbdkit-vram-plugin.1.html>)

- 32GB RAM이 달린 Apple Silicon Mac이 20GB가 아직 미사용/“free”인데도 왜 스왑 파일을 쓰거나 심지어 만드는지 모르겠음  
  Linux의 `swapoff -a`처럼 간단한 명령으로 **스왑 파일을 완전히 비활성화**할 수는 왜 없나?  
  SSD 수명을 일부러 줄이는 게 목적이 아니라면 좀 어리석어 보임  
  GUI에서 스왑 파일을 끄는 시스템 설정이 있으면 좋겠고, Apple이 지금의 시스템 설정/레이아웃 “단계”를 드디어 버려도 좋겠음. 수십 년간의 환경설정 패널에 비하면 아직도 단어 샐러드 같음  
  #Apple #Feedback #swapfile
  - 페이징 시스템의 원칙은 **주 메모리가 보조 기억장치의 캐시**라는 것임  
    “사용 가능한 메모리”라는 개념도 이상적으로는 “다른 목적을 위해 빠르게 회수할 수 있는 메모리”에 가까움  
    어떤 시점에는 익명 메모리를 주 메모리에 계속 두는 것보다, 캐시된 파일 내용이 그 자리를 차지하게 하는 편이 더 나을 때가 있음
