Virtio-nvgpu: Near-native Nvidia GPU access inside a KVM guest
Virtio-nvgpu: KVM 게스트에서 네이티브에 가까운 NVIDIA GPU 사용
virtio-nvgpu는 Linux 게스트에서 NVIDIA의 커널 드라이버 ioctl을 호스트로 전달해 GPU를 공유하는 프로젝트입니다. RTX 3060 실험에서 GPU 부하가 큰 경우 베어메탈 대비 성능 차이는 2% 이내였고, 게스트 4개가 동시에 렌더링하고 인코딩했습니다. 다만 게스트 격리와 보안은 아직 해결되지 않았습니다.
- 주제
AI 요약
virtio-nvgpu는 KVM 게스트에 NVIDIA GPU를 연결하는 가상 장치입니다. Vulkan 같은 그래픽 API 호출을 하나씩 호스트로 보내는 대신, 게스트에서 NVIDIA의 수정되지 않은 사용자 공간 드라이버를 실행하고 커널 드라이버 ioctl을 호스트로 전달합니다. 게스트 드라이버는 요청을 virtqueue에 싣고, 호스트 쪽 장치 코드가 핸들과 포인터를 변환해 실제 NVIDIA 장치 파일에 ioctl을 실행합니다. 렌더링 루프에서는 공유 메모리를 통해 명령을 제출하므로 프레임마다 VM 경계를 넘지 않습니다.
목표 사용 사례는 모니터 없이 실행하는 원격 게임 스트리밍입니다. 게스트 안에서 컴포지터가 화면을 합성하고, GPU에서 NVENC로 인코딩한 뒤 압축된 영상만 외부로 보냅니다. 공유 버퍼와 CUDA 포인터에 게스트가 접근해야 하는 구조라, API 호출을 호스트에서 재생하는 방식으로는 게스트 내부 인코딩을 구현하기 어렵습니다.
성능 측정
RTX 3060과 NVIDIA 드라이버 595.99.02에서 동일한 헤드리스 Vulkan 부하를 베어메탈과 게스트에 걸어 측정했습니다. 호스트가 프레임 하나를 처리하는 데 2ms 이상 걸리는 구간에서 게스트 성능은 베어메탈 대비 2% 이내였습니다. 0.5ms 프레임에서는 7.1%, 0.05ms 프레임에서는 40.8% 느렸습니다. 짧은 프레임일수록 GPU가 깨어나기를 기다리는 약 0.02ms의 비용이 상대적으로 커집니다.
약 100fps로 12초 동안 실행한 CPU 사용량은 베어메탈 0.40초, 게스트 0.37초였습니다. 렌더링 중 ioctl 전달이 발생하지 않기 때문이라고 프로젝트는 설명합니다. 813,691개 프레임을 처리하는 동안 백엔드가 받은 메시지는 13,792개였으며, 대부분 장치 설정 과정에서 발생했습니다.
게스트 4개를 RTX 3060 한 장에 동시에 올린 실험에서는 각각 25.84, 26.49, 25.57, 25.79fps를 기록했습니다. 합계는 103.7fps로 단일 게스트의 102.9fps와 비슷했고, 각 게스트의 프레임 시간도 약 39.16ms로 고르게 나뉘었습니다. 네 게스트가 동시에 렌더링하고 각각 60Hz로 H.264 인코딩하는 데도 성공했습니다. 다만 네 개는 실제로 시험한 수일 뿐 상한은 아니며, 여덟 게스트는 시험하지 않았습니다. 측정에 사용한 GPU와 드라이버 조합은 RTX 3060과 595.99.02 한 가지입니다. RTX A2000과 615.71.09에서는 렌더링을 확인했지만 성능 측정은 하지 않았습니다.
구현과 지원 범위
게스트 커널 모듈은 GPL-2.0, Rust 장치 라이브러리는 Apache-2.0, 양쪽이 공유하는 프로토콜 정의는 BSD-3-Clause 또는 GPL-2.0+로 배포합니다. 장치 라이브러리는 특정 VMM에 의존하지 않으며, VMM이 메모리 매핑과 이벤트 큐 등의 인터페이스를 구현하면 연결할 수 있습니다. 현재 지원 대상으로 Vulkan 렌더링과 게스트 컴포지터 표시, 헤드리스 EGL 기반 OpenGL, CUDA 메모리 할당과 CUDA·Vulkan 상호 운용, NVENC와 NVDEC를 제시합니다. 물리 디스플레이 출력, MIG, SR-IOV, 완전한 통합 메모리 관리는 범위 밖입니다.
NVIDIA 커널 드라이버 ABI는 버전마다 달라질 수 있어 ABI 프로필을 명시적으로 관리합니다. 제공 프로필은 535.129.03, 580.178.04, 595.71.05이며 535.129.03보다 오래된 드라이버는 거부합니다. 프로필 사이의 버전은 낮은 쪽 프로필을 사용하고, 마지막 프로필보다 새로운 버전은 마지막 프로필로 처리합니다. 이 때문에 최신 드라이버에서 문제가 생기면 ABI 가정부터 확인해야 합니다.
보안과 한계
보안 격리는 아직 해결되지 않았습니다. 게스트별로 분리한 비특권 헬퍼 프로세스가 실제 장치 파일 디스크립터를 보유하는 설계는 문서에만 있으며, 현재는 백엔드가 VMM 프로세스 안에서 장치 파일을 직접 다룹니다. 댓글에서도 게스트 ioctl을 폭넓게 호스트로 전달하고 VMM이 장치 접근 권한을 쥐는 점, DMA가 호스트에 미칠 영향, 샌드박싱 부재를 우려했습니다. 프로젝트 작성자도 보안과 일상적인 사용 준비가 부족하다고 답했습니다. 따라서 베어메탈에 가까운 성능 측정이 안전한 다중 테넌트 환경까지 입증하지는 않습니다.
Hacker News 반응
- @mcmatterson — 프로젝트는 놀랍지만 README는 LLM이 쓴 의미 없는 문장처럼 보입니다.
- @WanjohiRyan — 제 모국어가 영어가 아니라서 다듬으려고 최선을 다했습니다. 글이 자연스럽지 않았다면 정말 죄송합니다.
- @mcmatterson — 괜찮습니다. 저도 비슷한 실수를 합니다. 멋진 프로젝트네요. 단일 KVM 패스스루 상황에서도 이점이 있나요?
- @WanjohiRyan — 동시에 실행할 VM 수에 제한이 없다는 점이 이점입니다. 다만 아직 Windows는 지원하지 않습니다. 같은 GPU에서 여러 게임 세션을 실행하는 Nestri도 작업 중입니다.
- @Borealid — 오버헤드를 백분율로만 비교하는 건 적절하지 않습니다. 이 프로젝트와 virtio를 공정하게 비교해야 합니다.
- @WanjohiRyan — 어떤 virtio를 말씀하시나요? NVIDIA GPU를 지원해 직접 비교할 수 있는 것은 Venus뿐입니다. AMD와 Intel GPU의 DRM native context는 약 98%의 베어메탈 성능을 냅니다.
- @Borealid — vfio-pci를 말했습니다.
- @majorchord — Windows 게스트에서도 쓸 수 있나요?
- @WanjohiRyan — 아직은 안 됩니다. 로드맵에 있습니다.
- @markasoftware — gVisor의 nvproxy와 어떻게 다른가요?
- @WanjohiRyan — nvproxy의 아키텍처를 많이 참고했지만 그래픽 작업 부하를 지원하도록 만들었습니다. microVM이나 Cloud Hypervisor, 어쩌면 Firecracker에도 연결할 수 있도록 재사용성을 고려했습니다.
- @hacker_homie — 격리에는 어떤 영향이 있나요?
- @orphereus — 일반적인 GPU 패스스루 대신 이걸 쓸 이유가 무엇인가요?
- @defer — README에는 GPU 하나를 게스트 네 개까지 공유한다고 나옵니다.
- @Tajnymag — 일반 패스스루에서는 호스트가 GPU를 쓰지 못하므로 GPU가 두 장 필요하지 않나요? 이 방식은 GPU 한 장으로 호스트를 계속 쓰면서 게스트에도 헤드리스 접근을 제공하는 것 같습니다.
- @az226 — GeForce GPU는 MIG를 지원하지 않습니다. 워크스테이션과 데이터센터 제품군에서 지원합니다.
- @mjg59 — IOMMU로 제한한 패스스루가 없을 때 GPU가 호스트에 어느 수준까지 접근하는지 설명이 부족합니다.
- @WanjohiRyan — NVIDIA 드라이버는 수정하지 않았습니다. 게스트 드라이버가 호스트 커널 GPU 드라이버와 통신한다고 생각하게 합니다. 보안과 일상 사용 적합성은 아직 갈 길이 멉니다.
- @mjg59 — 그 접근으로 게스트가 호스트 커널을 대상으로 DMA를 실행할 수도 있나요?
- @rwmj — 보안성과 검증 수준이 낮다는 점 외에는 PCI 패스스루와 효과가 어떻게 다른가요?
- @WanjohiRyan — GPU를 여러 KVM 게스트가 공유하거나, 실행할 때마다 호스트에서 GPU를 분리해 VM에 붙이는 절차를 피하려는 상황을 겨냥합니다.
- @refibrillator — VFIO 패스스루는 GPU 전체를 게스트 하나에 맡기고 호스트 커널 드라이버가 관여하지 않아 격리가 가장 강합니다. virtio-gpu는 여러 VM이 GPU를 쓰지만 API 호출을 직렬화하고 호스트에서 재생하므로 오버헤드가 생깁니다. virtio-nvgpu는 여러 게스트가 NVIDIA GPU를 공유하며 성능은 네이티브에 가깝지만, 격리는 가장 약합니다. 게스트 ioctl을 기본적으로 호스트로 전달하고 VMM이 읽기·쓰기 파일 디스크립터를 보유하며 seccomp나 허용 목록도 없습니다.
원문: Hacker News / 번역·요약: Trawling