SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor

Jellyfin Docker NVIDIA 하드웨어 트랜스코딩 설정 방법

Docker Compose로 Jellyfin 컨테이너에 NVIDIA GPU를 할당하고 NVENC 및 NVDEC를 활성화하는 과정을 설명합니다. nvidia-smi 명령어로 GPU 트랜스코딩 작동 여부를 확인하는 정확한 방법을 안내합니다.

구축할 내용

NVIDIA GPU를 이용한 Jellyfin 하드웨어 트랜스코딩은 정해진 순서에 따라 4단계로 진행되며, 마지막 단계만 Jellyfin 내부에서 수행됩니다. 호스트 드라이버가 로드하지 않은 GPU는 컨테이너가 인식할 수 없습니다. 컨테이너가 인식하지 못하는 GPU는 Jellyfin이 사용할 수 없습니다. 이 순서를 따르면 각 단계에서 발생하는 오류의 원인을 명확하게 파악할 수 있습니다.

  1. 호스트에 NVIDIA 드라이버를 설치한 뒤 nvidia-smi 명령어로 확인합니다.
  2. Docker가 컨테이너에 GPU를 전달할 수 있도록 NVIDIA Container Toolkit을 설치합니다.
  3. docker-compose.yml 파일에서 Jellyfin 서비스를 위해 GPU를 할당하고, 컨테이너가 이를 인식하는지 확인합니다.
  4. Jellyfin의 재생 설정에서 NVENC와 NVDEC를 활성화한 뒤, 실제 재생 시 해당 기능이 사용되는지 확인합니다.

NVENC(NVIDIA 인코더)와 NVDEC(NVIDIA 디코더)는 그래픽 카드 내의 고정 기능 블록입니다. 이는 CUDA(Compute Unified Device Architecture) 작업을 수행하는 셰이더 코어와는 별개의 실리콘 영역입니다. 이러한 분리 구조 덕분에 하드웨어 트랜스코딩을 사용할 가치가 있습니다. 소프트웨어 방식으로 CPU 코어를 여러 개 점유하던 스트림 처리가, 이제는 CPU 코어 일부와 GPU의 전용 하드웨어 블록만으로 처리됩니다.

Direct play가 모든 트랜스코딩보다 효율적이므로 이를 먼저 확인하십시오

이 설정을 구성하기 전에, 단순히 제거할 수 있는 이유로 트랜스코딩을 수행하고 있는지 확인해야 합니다. Jellyfin은 클라이언트가 파일을 그대로 재생할 수 없을 때 트랜스코딩을 수행합니다. 그 이유는 비디오 코덱, 오디오 코덱, 컨테이너 형식, 이미지 기반 자막, 또는 클라이언트가 요청한 비트레이트 제한 중 하나로 항상 정해져 있습니다.

Dashboard를 열고 Playback으로 이동한 뒤, 콘텐츠가 재생되는 동안 활성 세션을 관찰하십시오. Direct playing으로 표시된 세션은 파일을 수정 없이 전송하므로 CPU 자원을 거의 사용하지 않습니다. Transcoding으로 표시된 세션은 Jellyfin이 해당 방식을 선택한 이유를 보여줍니다. 그 이유를 제거하면 GPU를 전혀 가동할 필요가 없습니다.

두 가지 변경 사항만으로 대부분의 트랜스코딩을 제거할 수 있습니다. 첫째, 클라이언트 앱의 화질 설정을 Auto 또는 최댓값으로 설정하십시오. 클라이언트가 4 Mbps를 요청하면 파일의 코덱과 상관없이 20 Mbps 파일을 강제로 재인코딩하기 때문입니다. 둘째, 브라우저 탭 대신 네이티브 클라이언트 앱을 사용하십시오. 브라우저는 가장 제한적인 재생 환경이며, 동일한 TV에서 네이티브 앱을 사용하면 같은 파일을 Direct play로 재생하는 경우가 많습니다.

이미지 기반 자막은 클라이언트 설정으로 해결할 수 없는 예외입니다. Blu-ray 립의 PGS 자막과 DVD 립의 VOBSUB 자막은 이미지 형태이므로 비디오 위에 직접 그려야 하며, 이는 비디오 스트림의 전체 재인코딩을 의미합니다. SRT 형식의 텍스트 자막은 별도의 트랙으로 클라이언트에 전송되므로 비용이 발생하지 않습니다. 가능한 경우 자막 트랙을 텍스트로 변환하는 것이 GPU를 추가하는 것보다 더 가치 있습니다. 서버 측의 나머지 구성은 Jellyfin 미디어 서버를 VPS에서 운영하기 위한 가이드에서 다룹니다.

대부분의 VPS 요금제에는 GPU가 없습니다

표준 VPS 요금제에는 GPU가 포함되어 있지 않습니다. 다른 계획을 세우기 전에 서버에서 다음 명령을 실행하십시오.

lspci -nn | grep -Ei "3d|display|vga"

일반적인 KVM VPS에서는 하이퍼바이저의 가상 디스플레이 어댑터가 출력되거나 유용한 정보가 나타나지 않습니다. 해당 장치는 비디오를 인코딩할 수 없습니다. 실제 GPU는 제공업체가 물리적 카드를 인스턴스에 직접 할당(passthrough)하거나 일부를 분할하여 제공할 때만 나타나며, 이러한 요금제는 그에 맞춰 가격이 책정됩니다. GPU VPS 비용을 지불할 가치가 있는 작업 부하에서 GPU가 필요한 대상과 그렇지 않은 대상을 다룹니다.

GPU가 없다면 직접 재생(direct play)을 우선으로 하고 소프트웨어 트랜스코딩은 예외적인 경우로 처리하십시오. 1080p H.264 소프트웨어 트랜스코딩 하나는 부하가 크지만 CPU 코어 몇 개로 감당할 수 있습니다. 톤 매핑이 포함된 4K HDR 소프트웨어 트랜스코딩은 소형 VPS에서 실시간으로 처리할 수 없으며, CPU 점유율이 100%에 고정된 상태에서 스트림이 끊기게 됩니다.

호스트에 NVIDIA 드라이버 설치

Jellyfin 10.11은 Linux에서 최소 520.56.06 버전의 NVIDIA 드라이버를 요구합니다. Ubuntu는 적합한 패키지를 자동으로 선택해 주는 도우미를 제공합니다.

sudo ubuntu-drivers list --gpgpu
sudo ubuntu-drivers install --gpgpu
sudo reboot

--gpgpu는 드라이버의 headless 서버 버전을 선택합니다. 미디어 서버는 데스크톱 환경이 필요 없으므로 이 버전이 적합합니다. 목록 명령어를 실행하면 사용 가능한 브랜치가 출력되며, 예를 들어 sudo ubuntu-drivers install --gpgpu nvidia:570-server과 같이 특정 브랜치를 지정할 수 있습니다. 이 문서에 적힌 예시가 아니라, 실제 목록에 출력된 브랜치를 사용하십시오.

서버 버전은 항상 nvidia-smi를 자동으로 설치하지는 않습니다. 선택한 브랜치에 맞는 유틸리티 패키지를 설치하십시오(예: sudo apt install nvidia-utils-570-server). 설치 후 드라이버를 확인합니다.

nvidia-smi

정상적으로 설치되었다면 드라이버 버전과 CUDA 버전이 포함된 표가 출력되고, 사용 중인 그래픽 카드의 이름과 비어 있는 프로세스 목록이 표시됩니다. 흔히 발생하는 오류는 두 가지입니다. nvidia-smi: command not found은 드라이버가 아닌 유틸리티 패키지가 누락되었음을 의미합니다. NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver은 커널 모듈이 로드되지 않았음을 의미하며, 새로 설치한 경우라면 대부분 재부팅을 하지 않았거나 Secure Boot가 서명되지 않은 모듈의 로드를 거부하는 경우입니다. lsmod | grep nvidia을 사용하여 모듈이 존재하는지 확인하십시오.

NVIDIA Container Toolkit 설치

드라이버는 호스트가 GPU를 사용할 수 있게 합니다. 하지만 컨테이너에는 장치 노드와 드라이버 라이브러리가 없으므로 Docker는 GPU를 컨테이너로 전달하지 못합니다. NVIDIA Container Toolkit은 컨테이너가 시작될 때 이 두 가지를 주입하는 역할을 합니다. 다음은 Debian 및 Ubuntu를 위한 NVIDIA 공식 설치 명령어입니다.

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/stable/deb/nvidia-container-toolkit.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

패키지를 설치하는 것만으로는 부족합니다. Docker에게 해당 런타임이 존재함을 알려야 하기 때문입니다.

sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

nvidia-ctk runtime configure/etc/docker/daemon.json 파일에 nvidia 런타임 항목을 작성합니다. 재시작은 사람들이 가장 자주 빠뜨리는 단계이며, 이를 건너뛰면 이 설정 과정에서 가장 흔한 오류가 발생합니다. Jellyfin을 다루기 전에 연결 상태를 먼저 테스트하십시오.

sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

이 명령을 실행하면 호스트에서 출력된 것과 동일한 표가 나타나야 합니다. 만약 gpu 기능을 가진 장치 드라이버를 선택할 수 없다는 오류가 발생한다면, Docker 데몬이 nvidia 런타임을 인식하지 못하는 상태입니다. 이 경우 설정 명령을 다시 실행하고 데몬을 재시작하십시오.

Docker Compose에서 Jellyfin 컨테이너에 GPU 할당하기

이는 Jellyfin이 공식적으로 제공하는 예시와 일치하는 최신 Compose 형식입니다.

services:
  jellyfin:
    image: jellyfin/jellyfin
    container_name: jellyfin
    user: 1000:1000
    network_mode: host
    restart: unless-stopped
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=all
    volumes:
      - /srv/jellyfin/config:/config
      - /srv/jellyfin/cache:/cache
      - /srv/media:/media:ro
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

컨테이너를 실행하고 직접 확인합니다.

docker compose up -d
docker compose exec jellyfin nvidia-smi

컨테이너 내부에서 드라이버 테이블이 출력된다면 GPU가 올바르게 전달된 것이며, 이후 발생하는 모든 문제는 Jellyfin 설정의 영역입니다.

해당 파일의 네 줄에 대해 설명이 필요합니다. capabilities: [gpu]는 Compose 자체에서 요구하는 항목이며, 이를 생략하면 Compose는 GPU 없이 서비스를 시작하는 대신 서비스 실행 자체를 거부합니다. NVIDIA_DRIVER_CAPABILITIES=all은 비디오 기능이 요청될 때만 툴킷이 비디오 라이브러리를 컨테이너에 마운트하기 때문에 중요하며, Jellyfin 문서에서는 공식 이미지 사용 시 이 변수를 필수 항목으로 명시하고 있습니다. 이 설정이 없으면 CUDA는 작동하지만 NVDEC는 작동하지 않으며, 트랜스코딩 로그에는 Cannot load libnvcuvid.so.1가 기록됩니다. network_mode: host는 Jellyfin 공식 예시에서 사용하는 설정인데, UDP 포트 7359를 통한 클라이언트 자동 검색 기능이 브리지 네트워크 환경에서는 정상적으로 동작하지 않기 때문입니다.

user: 1000:1000은 마지막 항목으로, GPU와는 무관합니다. 이 설정은 Jellyfin이 미디어 마운트 경로에서 어떤 파일을 읽을 수 있는지 결정하며, 설정이 일치하지 않으면 권한 오류 대신 라이브러리가 비어 있는 상태로 나타납니다. PUID와 PGID가 컨테이너 사용자를 디스크 파일에 매핑하는 방법에서 번호 체계를 설명하고 있으며, Docker Compose로 Sonarr 및 Radarr 스택을 실행할 때 이미 설정한 번호와 동일합니다.

Why most tutorials still write runtime: nvidia

The older form appears in nearly every guide you will find, and it is not wrong. It is history. The original nvidia-docker2 package registered an OCI runtime named nvidia, so the only way to get a GPU into a container was --runtime=nvidia plus NVIDIA_VISIBLE_DEVICES. Docker 19.03 added the --gpus flag and a proper device-request API. Compose took longer to catch up, and when it did, the device request landed under deploy.resources.reservations.devices, a key that most people had learned to ignore because deploy used to mean Docker Swarm.

The result is that both forms work today, and Jellyfin's published example carries both at once. Keeping runtime: nvidia costs nothing and makes the file work on older Compose versions. If you keep only runtime: nvidia and drop the deploy block, you must keep NVIDIA_VISIBLE_DEVICES=all, because that legacy path reads the environment variable to decide which devices to inject and has no device request to read instead.

Jellyfin에서 NVIDIA 하드웨어 트랜스코딩 활성화하기

지금까지의 설정으로는 Jellyfin이 그래픽 카드를 사용하도록 지시하지 않았습니다. 대시보드(Dashboard)로 이동한 뒤 재생(Playback), 트랜스코딩(Transcoding) 순으로 진입합니다. 하드웨어 가속(Hardware acceleration)을 Nvidia NVENC로 설정합니다. 하드웨어 인코딩 활성화(Enable hardware encoding)를 체크하십시오. 이 설정을 하지 않으면 Jellyfin이 GPU에서 디코딩을 수행한 뒤 CPU에서 인코딩을 하게 되며, GPU는 작동하지만 CPU 점유율은 여전히 높은 혼란스러운 상태가 발생합니다.

향상된 NVDEC 디코더 활성화(Enable enhanced NVDEC decoder)는 현재의 NVDEC 경로와 이전 CUVID 경로 사이를 전환합니다. 이 옵션은 켜두십시오. Dolby Vision을 처리하려면 NVDEC를 사용하기 위해 반드시 이 옵션이 필요합니다.

하드웨어 디코딩 활성화(Enable hardware decoding for) 항목에서는 사용 중인 그래픽 카드가 실제로 디코딩할 수 있는 코덱만 선택하십시오. 사용자들이 가장 많이 실수하는 부분입니다. AV1 디코더가 없는 카드에서 AV1을 체크해도 오류 메시지는 나타나지 않습니다. Jellyfin은 하드웨어 디코딩을 요청하지만 응답을 받지 못하면 소프트웨어 디코딩으로 전환합니다. 결과적으로 CPU 점유율은 높고 GPU는 거의 유휴 상태가 되어, 마치 패스스루(passthrough)가 전혀 작동하지 않는 것처럼 보이게 됩니다.

이 페이지 전체에 적용되는 제약 사항이 하나 더 있습니다. 하드웨어 가속은 번들로 제공되는 jellyfin-ffmpeg 빌드에서만 작동합니다. 만약 FFmpeg 경로를 시스템 FFmpeg으로 지정했다면, 가속이 부분적으로만 작동하거나 아예 작동하지 않을 수 있습니다.

GPU 세대별 디코딩 및 인코딩 지원 코덱

Jellyfin에서 문서화한 NVENC 및 NVDEC의 지원 범위는 다음과 같습니다. 디코딩과 인코딩은 별개의 기능이므로, 그래픽 카드에 따라 한쪽만 지원할 수도 있습니다.

  • H.264 8-bit: NVENC와 NVDEC를 탑재한 모든 NVIDIA GPU에서 디코딩과 인코딩을 지원합니다.
  • HEVC 8-bit: Maxwell 2세대(GM206) 이상부터 디코딩과 인코딩을 지원합니다.
  • HEVC 10-bit: Maxwell 2세대 이상부터 디코딩을 지원하지만, 인코딩은 Pascal 이상부터 지원합니다.
  • AV1: Ampere 이상부터 디코딩을, Ada Lovelace 이상부터 인코딩을 지원합니다.

실무에서 가장 문제가 되는 부분은 HEVC 10-bit 지원 범위입니다. Maxwell 세대 카드는 GPU에서 4K HDR 파일을 디코딩할 수는 있지만 10-bit 출력을 인코딩할 수 없으므로, Jellyfin은 대신 8-bit H.264로 인코딩합니다. 이 방식도 재생은 잘 되며, 대부분의 클라이언트 환경에서는 오히려 올바른 선택입니다. 2026년 현재, 클라이언트 측의 AV1 디코딩 지원은 여전히 부족하며 트랜스코딩은 이미 재생에 어려움을 겪는 클라이언트를 위해 수행하는 작업이므로, 어떤 카드를 사용하든 AV1 인코딩은 권장하지 않습니다.

톤 매핑이 GPU를 조용히 과부하 상태로 만드는 이유

HDR(high dynamic range)을 SDR(standard dynamic range)로 변환하는 톤 매핑은 GPU 자원을 가장 많이 소모하는 설정이며, 그 이유는 아키텍처 구조에 있습니다. 디코딩은 NVDEC에서 수행되고, 인코딩은 NVENC에서 수행됩니다. 하지만 톤 매핑은 이 두 곳 어디에서도 처리되지 않습니다. 톤 매핑은 셰이더 코어에서 실행되는 CUDA 필터이며, 이는 연산 작업을 수행하는 GPU의 범용 영역입니다. 따라서 톤 매핑이 필요한 4K HDR 스트림은 디코더와 인코더를 사용하는 동시에 셰이더까지 추가로 점유하게 됩니다.

Jellyfin은 HEVC 10-bit 디코딩이 가능한 모든 NVIDIA GPU에서 CUDA 톤 매핑을 사용할 수 있다고 명시합니다. 즉, 4K 해상도에서 성능을 유지할 수 없는 카드에서도 해당 체크박스가 나타나고 기능이 활성화됩니다. 이 경우 스트림이 시작된 후 버퍼링이 반복되며 정상적으로 재생되지 않는데, 이때 nvidia-smi를 확인해 보면 인코더는 거의 작동하지 않는 상태로 나타납니다.

이것이 바로 셰이더 부하를 별도로 모니터링해야 하는 이유입니다.

nvidia-smi dmon -s u

이 명령은 sm, enc, dec 열을 포함하여 초당 한 줄씩 상태를 출력합니다. enc와 dec 수치는 낮은데 sm 수치가 높다면, 고정 기능 블록은 여유가 있지만 셰이더가 병목 현상을 일으키고 있다는 뜻입니다. 즉, 톤 매핑, 스케일링 또는 자막 굽기(subtitle burn-in) 작업이 자원을 소모하고 있는 것입니다. CUDA 경로는 Dolby Vision profile 5를 제로 카피(zero copy) 방식으로 처리하기도 합니다. 제로 카피를 사용하지 않으면 필터 단계마다 프레임이 시스템 메모리로 이동했다가 다시 돌아와야 하며, 이 왕복 과정에서 모든 프레임마다 대역폭 비용이 발생하기 때문에 제로 카피 지원 여부는 매우 중요합니다.

소비자용 NVENC 세션 제한이 실제로 의미하는 것

ChartNVENC engines and concurrent encode session cap, NVIDIA published support matrix, August 2026
The data behind this chart
[
  {
    "label": "GeForce RTX 5090",
    "nvenc_engines": 3,
    "max_encode_sessions": 12
  },
  {
    "label": "GeForce RTX 4090",
    "nvenc_engines": 2,
    "max_encode_sessions": 12
  },
  {
    "label": "GeForce RTX 4060",
    "nvenc_engines": 1,
    "max_encode_sessions": 12
  }
]

이 수치는 2026년 8월 기준으로 NVIDIA가 공개한 매트릭스이며, 본 문서에서 직접 측정한 값이 아닙니다. GeForce 카드는 모델과 관계없이 12개의 동시 인코딩 세션으로 제한됩니다. 이 제한은 하드웨어가 아닌 드라이버 수준에서 적용되며, NVIDIA는 수년간 이를 여러 차례 상향 조정했으므로 오래된 포럼 게시글 대신 최신 매트릭스를 확인해야 합니다. 카드마다 실제로 차이가 나는 부분은 엔진 개수입니다. GeForce RTX 5090 모델은 3개의 NVENC 엔진을 탑재하고 있으며, GeForce RTX 4060 모델은 1개를 탑재합니다. 엔진이 많을수록 병렬 인코딩 처리량은 증가하지만, 세션 제한 수치가 높아지는 것은 아닙니다.

이 제한은 인코딩 세션 수를 기준으로 하므로 트랜스코딩 스트림에만 적용됩니다. 다이렉트 플레이(Direct play)나 리먹싱(Remuxing)은 인코딩 세션을 생성하지 않습니다. L4와 같은 데이터 센터용 카드는 동일한 매트릭스에서 제한 없음으로 표시되며, GPU VPS 플랜은 보통 이러한 데이터 센터용 카드를 제공하므로 이 제한은 주로 홈 서버 운영 시 고려할 사항입니다.

제한에 도달하면 트랜스코딩이 실패하고 FFmpeg 로그에 OpenEncodeSessionEx failed: out of memory (10)이 기록됩니다. 해당 메시지는 메모리 관련 오류를 언급하지만, 세션 제한으로 인한 거부 시에도 동일한 코드가 출력됩니다. 따라서 VRAM 누수를 조사하기 전에 동시 스트림 개수부터 확인하십시오. 실제 환경에서는 대부분의 사용자가 세션 12개에 도달하기 전에 톤 매핑(tone-mapping) 한계나 업로드 대역폭 문제에 먼저 직면하게 됩니다.

GPU 트랜스코딩 확인하기 (설정값 신뢰 금지)

설정값이 저장되었다고 해서 실제 작동을 보장하지는 않습니다. 트랜스코딩이 강제되는 파일을 재생한 뒤 다음 세 가지 항목을 확인하십시오.

  1. 대시보드에서 재생(Playback) 항목을 엽니다. 활성 세션에 'Transcoding'이라고 표시되어야 하며, 그 이유가 명시되어야 합니다. 만약 'Direct playing'이라고 표시된다면 트랜스코딩이 이루어지지 않는 것이므로, 테스트 중인 파일이 잘못되었습니다.
  2. 대시보드에서 로그(Logs)를 열고 가장 최신인 FFmpeg.Transcode 로그를 확인합니다. 하드웨어 트랜스코딩이 작동 중이라면 명령줄에 -hwaccel cuda-hwaccel_output_format cuda이 나타나며, 인코더로 h264_nvenc 또는 hevc_nvenc가 표시됩니다. 설정 페이지의 내용과 관계없이 이곳에 libx264이 보인다면 소프트웨어 트랜스코딩이 수행되고 있는 것입니다.
  3. 재생이 진행되는 동안 호스트에서 nvidia-smi을 실행합니다. /usr/lib/jellyfin-ffmpeg/ffmpeg 프로세스가 나타나고 GPU 메모리가 할당되어 있어야 하며, nvidia-smi dmon -s u의 enc 및 dec 열에 0이 아닌 값이 표시되어야 합니다.

세 번째 확인 작업은 컨테이너 내부가 아닌 호스트에서 실행하십시오. 컨테이너 내부에서 nvidia-smi을 실행하면 자신의 네임스페이스 외부 프로세스 ID를 볼 수 없어 프로세스 목록이 비어 있는 경우가 많지만, 사용률 수치는 정상적으로 표시됩니다. 컨테이너 내부의 프로세스 목록이 비어 있는 것은 오류가 아닙니다.

알림 없이 소프트웨어 인코딩으로 전환되는 경우

Jellyfin은 재생을 유지하는 것을 우선합니다. 하드웨어 경로를 사용할 수 없게 되면 스트림을 중단하는 대신 소프트웨어 인코딩으로 전환하므로, 오류 배너가 아닌 CPU 부하와 FFmpeg 로그를 통해 상태를 확인해야 합니다.

트랜스코딩 로그에 나타나는 Cannot load libnvcuvid.so.1은 디코더 라이브러리가 컨테이너에 마운트되지 않았음을 의미합니다. NVIDIA_DRIVER_CAPABILITIES=all를 설정하고 컨테이너를 다시 생성하십시오. 환경 변경 사항을 적용하려면 docker compose up -d을 사용하여 컨테이너를 다시 빌드해야 하며, 단순 재시작으로는 이전 설정이 유지되기 때문입니다.

h264_nvenc에서 발생하는 No capable devices found는 FFmpeg가 인코더 라이브러리에 도달했으나 사용 가능한 카드를 찾지 못했음을 의미합니다. 장치 예약이 해제되었거나 오래된 파일로부터 컨테이너가 다시 생성되었을 가능성이 높으므로 docker compose exec jellyfin nvidia-smi을 다시 확인하십시오.

GPU는 조용한데 CPU 사용량이 높다면 디코딩 단계에서 오류가 조용히 발생하고 있는 것입니다. 현재 세대에서 디코딩할 수 없는 코덱의 체크를 해제한 뒤, 동일한 파일을 다시 재생하고 FFmpeg 로그에서 -hwaccel cuda이 나타나는지 확인하십시오.

1080p는 정상인데 4K HDR 트랜스코딩만 시작 후 멈춘다면, 이는 설치 오류가 아니라 톤 매핑(tone-mapping) 성능 한계에 도달한 것입니다. nvidia-smi dmon -s u의 sm 열을 통해 이를 확인하고, 클라이언트가 요청하는 해상도를 낮추거나 4K HDR 파일을 직접 재생(direct play)할 수 있는 클라이언트에서 재생하십시오.

FAQ

NVENC를 활성화했는데도 왜 Jellyfin이 여전히 CPU를 사용합니까?

대시보드(Dashboard)의 로그(Logs)에서 가장 최근의 FFmpeg.Transcode 로그를 확인하십시오. 만약 libx264이 표시된다면 하드웨어 경로가 전혀 사용되지 않은 것입니다. 이는 보통 컨테이너가 GPU를 인식하지 못하는 상황이므로 docker compose exec jellyfin nvidia-smi을 실행하여 확인하십시오. 만약 h264_nvenc가 표시되는데도 CPU 점유율이 높다면 디코딩 과정이 소프트웨어로 실행되고 있는 것입니다. 이는 그래픽 카드가 지원하지 않는 코덱을 선택했거나, 하드웨어 인코딩 활성화(Enable hardware encoding) 옵션을 켜지 않아 파이프라인의 절반만 GPU로 넘어갔을 때 발생합니다.

Docker Compose에 여전히 runtime: nvidia 줄이 필요합니까?

deploy.resources.reservations.devices 블록이 있고 최신 버전의 Docker Compose를 사용 중이라면 필요하지 않습니다. 해당 블록은 최신 방식의 장치 요청(device-request) 형식이므로 동일한 역할을 수행합니다. runtime: nvidianvidia-docker2 시절의 구형 방식이지만 여전히 작동하며, Jellyfin 공식 예제에서도 두 가지를 모두 포함하고 있습니다. 둘 다 유지해도 문제는 없습니다. runtime: nvidia만 유지하려면 NVIDIA_VISIBLE_DEVICES=all도 반드시 함께 유지해야 합니다. 해당 방식은 장치 요청을 읽어오는 기능이 없어 환경 변수에서 장치 목록을 가져와야 하기 때문입니다.

NVIDIA GPU 하나로 동시에 몇 개의 스트림을 트랜스코딩할 수 있습니까?

2026년 8월 기준, NVIDIA 공식 매트릭스에 따르면 GeForce 카드는 최대 12개의 동시 인코딩 세션을 지원하며 데이터 센터용 카드는 제한이 없습니다. 하지만 실제로는 이 제한보다 다른 요소가 먼저 병목을 일으킵니다. HDR을 SDR로 변환하는 톤 매핑(tone mapping)은 NVENC가 아닌 셰이더 코어에서 실행됩니다. 따라서 4K HDR 스트림 몇 개만으로도 세션 수 제한에 도달하기 훨씬 전에 셰이더 자원이 고갈됩니다. nvidia-smi dmon -s u을 사용하여 직접 측정해 보십시오. 이때 세션 수가 아닌 sm 열의 수치를 확인해야 합니다.

GPU가 없는 VPS에서 하드웨어 트랜스코딩을 사용할 수 있습니까?

아니요. 인코딩에는 물리적인 NVENC 블록이 필요합니다. 일반적인 VPS에서 lspci -nn | grep -Ei "3d|display|vga"를 실행하면 하이퍼바이저가 제공하는 가상 디스플레이 어댑터만 보일 뿐입니다. GPU가 없는 환경에서 현실적인 해결책은 트랜스코딩을 피하는 것입니다. 클라이언트의 화질 설정을 자동(Auto)으로 높이고, 브라우저 대신 네이티브 클라이언트 앱을 사용하며, 이미지 기반 자막 트랙을 텍스트 형식으로 변환하여 비디오 재인코딩이 강제되지 않도록 하십시오.

1080p는 잘 트랜스코딩되는데 왜 4K HDR은 끊깁니까?

두 작업은 그래픽 카드의 서로 다른 부분을 사용합니다. 1080p SDR 트랜스코딩은 고정 기능 하드웨어에서 수행되는 디코드와 인코드 작업만 필요합니다. 반면 4K HDR 스트림은 셰이더 코어에서 실행되는 CUDA 필터인 톤 매핑과 더 큰 프레임 스케일링 작업을 추가로 요구합니다. nvidia-smi dmon -s u에서 enc와 dec 수치는 낮은데 sm 수치가 높게 나온다면, 고정 기능 블록은 유휴 상태이고 범용 코어가 한계에 도달했음을 의미합니다.