SSD Nodes Learn 🎉 VPS $5.50/মাস থেকে
নির্দেশিকা Matt Connorদ্বারা Matt Connor

Docker-এ Jellyfin NVIDIA hardware transcoding সেটআপ

Docker Compose ব্যবহার করে Jellyfin কন্টেইনারে NVIDIA GPU যুক্ত করার সঠিক নিয়ম জানুন। NVENC ও NVDEC চালু করুন এবং nvidia-smi কমান্ডের মাধ্যমে GPU ট্রান্সকোডিং নিশ্চিত করুন।

আপনি যা তৈরি করছেন

NVIDIA GPU-তে Jellyfin hardware transcoding সেটআপ করার প্রক্রিয়াটি চারটি নির্দিষ্ট ধাপে সম্পন্ন হয় এবং এর শেষ ধাপটি কেবল Jellyfin-এর ভেতরে ঘটে। হোস্ট ড্রাইভার লোড না করলে কন্টেইনার GPU-কে দেখতে পায় না। আবার কন্টেইনার GPU-কে দেখতে না পেলে Jellyfin তা ব্যবহার করতে পারে না। এই ক্রমানুসারে কাজ করলে প্রতিটি ব্যর্থতার কারণ সহজেই খুঁজে বের করা সম্ভব।

  1. হোস্টে NVIDIA ড্রাইভার ইনস্টল করুন, তারপর nvidia-smi দিয়ে তা নিশ্চিত করুন।
  2. NVIDIA Container Toolkit ইনস্টল করুন যাতে Docker কন্টেইনারের কাছে GPU হস্তান্তর করতে পারে।
  3. docker-compose.yml-এ Jellyfin সার্ভিসের জন্য GPU বরাদ্দ করুন, তারপর নিশ্চিত করুন যে কন্টেইনারটি তা দেখতে পাচ্ছে।
  4. Jellyfin-এর নিজস্ব playback সেটিংস থেকে NVENC এবং NVDEC চালু করুন, তারপর নিশ্চিত করুন যে প্রকৃত playback-এ সেগুলো ব্যবহৃত হচ্ছে।

NVENC (NVIDIA encoder) এবং NVDEC (NVIDIA decoder) হলো কার্ডের নির্দিষ্ট ফাংশন ব্লক। এগুলো CUDA (compute unified device architecture) কাজ সম্পাদনকারী shader core থেকে আলাদা সিলিকন। এই পার্থক্যের কারণেই এটি কার্যকর: যে স্ট্রিমটি সফটওয়্যারে প্রসেস করলে বেশ কয়েকটি CPU কোর খরচ হয়, তা GPU-তে একটি কোরের সামান্য অংশ এবং একটি ডেডিকেটেড হার্ডওয়্যার ব্লক ব্যবহার করেই সম্পন্ন করা যায়।

Direct play যেকোনো transcode-এর চেয়ে ভালো, তাই প্রথমে সেটি পরীক্ষা করুন

এই কনফিগারেশন শুরু করার আগে, জেনে নিন আপনি কোনো এমন কারণে transcoding করছেন কি না যা সহজেই দূর করা সম্ভব। ক্লায়েন্ট যখন ফাইলটি সরাসরি চালাতে পারে না, তখনই Jellyfin transcoding করে। এর কারণগুলো সাধারণত এই তালিকার মধ্যেই থাকে: ভিডিও কোডেক, অডিও কোডেক, কন্টেইনার ফরম্যাট, ইমেজ-ভিত্তিক সাবটাইটেল, অথবা ক্লায়েন্টের অনুরোধ করা কোনো bitrate লিমিট।

Dashboard খুলুন, তারপর Playback-এ যান এবং কোনো কিছু চলার সময় একটি active session পর্যবেক্ষণ করুন। যে সেশনটি Direct playing হিসেবে চিহ্নিত, সেটি ফাইলটিকে কোনো পরিবর্তন ছাড়াই পাঠায় এবং এতে প্রায় কোনো CPU খরচ হয় না। Transcoding হিসেবে চিহ্নিত সেশনে Jellyfin কেন এই পদ্ধতি বেছে নিয়েছে তার কারণ দেখানো হয়। সেই কারণটি দূর করলে GPU-কে আর কোনো কাজই করতে হবে না।

দুটি পরিবর্তন অধিকাংশ transcoding বন্ধ করে দেয়। ক্লায়েন্ট অ্যাপের কোয়ালিটি Auto অথবা সর্বোচ্চ সেটিংসে রাখুন, কারণ একটি ক্লায়েন্ট যদি 4 Mbps-এর অনুরোধ করে, তবে ফাইলটি যে কোডেকই হোক না কেন, সেটি 20 Mbps ফাইলটিকে পুনরায় এনকোড করতে বাধ্য করবে। এছাড়া ব্রাউজার ট্যাবের পরিবর্তে একটি native client অ্যাপ ব্যবহার করুন, কারণ ব্রাউজার আপনার কাছে থাকা সবচেয়ে সীমাবদ্ধ প্লেয়ার এবং একই টিভিতে একটি native অ্যাপ প্রায়শই একই ফাইল সরাসরি (direct play) চালাতে পারে।

ইমেজ-ভিত্তিক সাবটাইটেল হলো ব্যতিক্রম, যা কোনো ক্লায়েন্ট সেটিংস দিয়ে ঠিক করা যায় না। Blu-ray rip থেকে পাওয়া PGS সাবটাইটেল এবং DVD rip থেকে পাওয়া VOBSUB হলো ছবি, তাই এগুলোকে ভিডিওর ওপর বসাতে হয়, যার অর্থ হলো ভিডিও স্ট্রিমটিকে সম্পূর্ণ পুনরায় এনকোড করা। SRT ফরম্যাটের টেক্সট সাবটাইটেলগুলো আলাদা ট্র্যাক হিসেবে ক্লায়েন্টের কাছে পাঠানো হয় এবং এতে কোনো বাড়তি খরচ নেই। যেখানে সম্ভব সাবটাইটেল ট্র্যাকগুলোকে টেক্সটে রূপান্তর করা একটি GPU-এর চেয়েও বেশি কার্যকর। সার্ভার সাইডের বাকি অংশ VPS-এ Jellyfin মিডিয়া সার্ভার চালানোর নির্দেশিকা-তে আলোচনা করা হয়েছে।

অধিকাংশ VPS প্ল্যানে কোনো GPU থাকে না

সাধারণ VPS প্ল্যানে কোনো GPU অন্তর্ভুক্ত থাকে না। অন্য কোনো পরিকল্পনা করার আগে সার্ভারে এটি রান করুন।

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

একটি সাধারণ KVM VPS-এ এটি হাইপারভাইজার থেকে একটি ভার্চুয়াল ডিসপ্লে অ্যাডাপ্টার প্রদর্শন করবে, অথবা কোনো কার্যকর তথ্য দেখাবে না। সেই ডিভাইসটি ভিডিও এনকোড করতে পারে না। একটি প্রকৃত GPU তখনই দেখা যায় যখন প্রোভাইডার আপনার ইনস্ট্যান্সে একটি ফিজিক্যাল কার্ড পাস-থ্রু করে অথবা সেটির একটি অংশ প্রদান করে, এবং সেই প্ল্যানগুলোর মূল্যও সেই অনুযায়ী নির্ধারিত হয়। কোন কাজের জন্য GPU VPS-এর খরচ করা যুক্তিযুক্ত অংশে কাদের এটি প্রয়োজন এবং কাদের প্রয়োজন নেই তা আলোচনা করা হয়েছে।

যদি কোনো GPU না থাকে, তবে সরাসরি প্লে-ব্যাক (direct play) করার লক্ষ্য রাখুন এবং সফটওয়্যার ট্রান্সকোডিংকে বিরল ক্ষেত্র হিসেবে বিবেচনা করুন। একটি 1080পি (1080p) H.264 সফটওয়্যার ট্রান্সকোড বেশ ভারী হলেও কয়েকটি CPU কোরে তা চালানো সম্ভব। 4কে (4K) HDR সফটওয়্যার ট্রান্সকোড এবং টোন ম্যাপিং একটি ছোট VPS-এর পক্ষে রিয়েল-টাইমে সম্পন্ন করা সম্ভব নয়, তাই CPU 100 শতাংশ লোডে আটকে থাকার ফলে স্ট্রিমটি বারবার আটকে যাবে (stutter করবে)।

হোস্টে NVIDIA ড্রাইভার ইনস্টল করা

Jellyfin 10.11-এর ডকুমেন্টেশন অনুযায়ী Linux-এ ন্যূনতম NVIDIA ড্রাইভার সংস্করণ 520.56.06 প্রয়োজন। Ubuntu-তে একটি হেল্পার টুল আছে যা আপনার জন্য উপযুক্ত প্যাকেজটি নির্বাচন করে দেয়।

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

--gpgpu কমান্ডটি ড্রাইভারের headless server সংস্করণ নির্বাচন করে, যা একটি মিডিয়া সার্ভারের জন্য আদর্শ কারণ এতে কোনো ডেস্কটপ এনভায়রনমেন্ট থাকে না। লিস্ট কমান্ডটি আপনার জন্য উপলব্ধ ব্রাঞ্চগুলো দেখাবে, এবং আপনি চাইলে কোনো একটি নির্দিষ্ট ব্রাঞ্চ পিন করতে পারেন, যেমন sudo ubuntu-drivers install --gpgpu nvidia:570-server। এখানে দেওয়া উদাহরণের পরিবর্তে লিস্টে প্রদর্শিত যেকোনো একটি ব্রাঞ্চ ব্যবহার করুন।

সার্ভার সংস্করণের সাথে সবসময় nvidia-smi ইনস্টল নাও হতে পারে। আপনার নির্বাচিত ব্রাঞ্চের জন্য সংশ্লিষ্ট utils প্যাকেজটি ইনস্টল করুন, যেমন sudo apt install nvidia-utils-570-server। এরপর ড্রাইভারটি পরীক্ষা করুন।

nvidia-smi

সফলভাবে ইনস্টল হলে একটি টেবিল প্রদর্শিত হবে যেখানে হেডার অংশে ড্রাইভার সংস্করণ ও CUDA সংস্করণ থাকবে, আপনার কার্ডের নাম দেখা যাবে এবং প্রসেস লিস্টটি খালি থাকবে। এখানে সাধারণত দুটি ত্রুটি দেখা যায়। nvidia-smi: command not found মানে হলো utils প্যাকেজটি অনুপস্থিত, ড্রাইভারের সমস্যা নয়। NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver মানে হলো কার্নেল মডিউলটি লোড হয়নি; নতুন ইনস্টলেশনের ক্ষেত্রে এর অর্থ সাধারণত আপনি এখনো রিবুট করেননি, অথবা Secure Boot স্বাক্ষরবিহীন মডিউল লোড করতে বাধা দিচ্ছে। lsmod | grep nvidia কমান্ড দিয়ে মডিউলটি উপস্থিত আছে কি না তা নিশ্চিত করুন।

NVIDIA Container Toolkit ইনস্টল করা

ড্রাইভার হোস্টকে GPU ব্যবহারের সুযোগ দেয়। কিন্তু Docker নিজে থেকে এটিকে কন্টেইনারের ভেতর পাঠাতে পারে না, কারণ কন্টেইনারে কোনো ডিভাইস নোড বা ড্রাইভার লাইব্রেরি থাকে না। 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 capabilities সহ ডিভাইস ড্রাইভার নির্বাচন করতে না পারার কোনো ত্রুটি দেখায়, তবে বুঝতে হবে Docker daemon nvidia রানটাইম সম্পর্কে জানে না। সেক্ষেত্রে কনফিগার কমান্ডটি পুনরায় চালান এবং daemon রিস্টার্ট করুন।

Jellyfin কন্টেইনারে Docker Compose-এর মাধ্যমে GPU প্রদান করা

এটি আধুনিক Compose ফরম্যাট, যা Jellyfin-এর প্রকাশিত উদাহরণের সাথে সামঞ্জস্যপূর্ণ।

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 সার্ভিসটি চালু না করে প্রত্যাখ্যান করবে। 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 স্ট্যাক এর পাশাপাশি চালান, তবে এই সংখ্যাগুলো একই থাকবে।

কেন বেশিরভাগ টিউটোরিয়ালে এখনও runtime: nvidia লেখা থাকে

পুরানো এই ফরম্যাটটি আপনি প্রায় প্রতিটি গাইডেই দেখতে পাবেন এবং এটি ভুল নয়। এটি মূলত ইতিহাসের অংশ। মূল nvidia-docker2 প্যাকেজটি nvidia নামে একটি OCI runtime রেজিস্টার করত, তাই কন্টেইনারে GPU ব্যবহারের একমাত্র উপায় ছিল --runtime=nvidia এবং তার সাথে NVIDIA_VISIBLE_DEVICES ব্যবহার করা। Docker 19.03 সংস্করণে --gpus ফ্ল্যাগ এবং একটি যথাযথ device-request API যুক্ত করা হয়। Compose-এর ক্ষেত্রে এটি আপডেট হতে কিছুটা সময় লেগেছে, এবং যখন এটি যুক্ত হলো, তখন device request-টি deploy.resources.reservations.devices-এর অধীনে রাখা হয়। এটি এমন একটি কী (key) যা বেশিরভাগ মানুষ উপেক্ষা করতে শিখেছিলেন, কারণ deploy বলতে সাধারণত Docker Swarm বোঝাত।

এর ফলাফল হলো, বর্তমানে উভয় পদ্ধতিই কাজ করে এবং Jellyfin-এর প্রকাশিত উদাহরণে উভয়ই একসাথে রাখা হয়েছে। runtime: nvidia রাখাটা কোনো বাড়তি ঝামেলা নয় এবং এটি ফাইলটিকে পুরানো Compose ভার্সনেও কাজ করতে সাহায্য করে। আপনি যদি শুধুমাত্র runtime: nvidia রাখেন এবং deploy ব্লকটি বাদ দেন, তবে আপনাকে অবশ্যই NVIDIA_VISIBLE_DEVICES=all রাখতে হবে। কারণ সেই লিগ্যাসি পাথটি এনভায়রনমেন্ট ভেরিয়েবল পড়ে সিদ্ধান্ত নেয় কোন ডিভাইসগুলো ইনজেক্ট করতে হবে এবং সেখানে পড়ার মতো কোনো device request থাকে না।

Jellyfin-এ NVIDIA হার্ডওয়্যার ট্রান্সকোডিং চালু করা

এখন পর্যন্ত Jellyfin-কে কার্ডটি ব্যবহার করার কোনো নির্দেশ দেওয়া হয়নি। Dashboard-এ যান, তারপর Playback এবং এরপর Transcoding-এ ক্লিক করুন। Hardware acceleration-কে Nvidia NVENC হিসেবে সেট করুন। Enable hardware encoding বক্সে টিক দিন, অন্যথায় Jellyfin GPU-তে ডিকোড করবে কিন্তু CPU-তে এনকোড করবে; এটি একটি বিভ্রান্তিকর মধ্যবর্তী অবস্থা যেখানে GPU-তে কাজ দেখালেও CPU-এর ওপর চাপ বজায় থাকে।

Enable enhanced NVDEC decoder অপশনটি বর্তমান NVDEC পাথ এবং পুরোনো CUVID পাথের মধ্যে পরিবর্তন করে। এটি চালু রাখুন। Dolby Vision হ্যান্ডেল করার জন্য NVDEC ব্যবহার করতে হলে এটি চালু থাকা আবশ্যক।

Enable hardware decoding for সেকশনের অধীনে শুধুমাত্র সেই কোডেকগুলোতে টিক দিন যা আপনার কার্ড প্রকৃতপক্ষে ডিকোড করতে পারে। এটি এমন একটি সেটিংস যা মানুষ ভুল করে থাকে। যে কার্ডে AV1 ডিকোডার নেই তাতে AV1-এ টিক দিলে কোনো এরর মেসেজ দেখাবে না। Jellyfin হার্ডওয়্যার ডিকোডের অনুরোধ করবে, কিন্তু তা না পেয়ে সফটওয়্যার ডিকোডিংয়ে ফিরে যাবে। ফলে আপনার CPU-এর ব্যবহার বেড়ে যাবে এবং GPU প্রায় অলস অবস্থায় থাকবে, যা দেখে মনে হবে যেন পাসথ্রু কখনোই কাজ করেনি।

পুরো পেজটির জন্য আরও একটি সীমাবদ্ধতা প্রযোজ্য: হার্ডওয়্যার এক্সিলারেশন শুধুমাত্র বান্ডেল করা jellyfin-ffmpeg বিল্ডের সাথেই কাজ করে। আপনি যদি FFmpeg পাথ হিসেবে সিস্টেমের কোনো FFmpeg-কে নির্দেশ করে থাকেন, তবে আপনি আংশিক বা কোনো এক্সিলারেশনই পাবেন না।

আপনার GPU জেনারেশন কোন কোডেকগুলো ডিকোড এবং এনকোড করতে পারে

NVENC এবং NVDEC-এর জন্য Jellyfin যে সীমাবদ্ধতাগুলো নথিবদ্ধ করেছে তা নিচে দেওয়া হলো। ডিকোড এবং এনকোড আলাদা সক্ষমতা, তাই একটি কার্ডে একটি থাকলেও অন্যটি নাও থাকতে পারে।

  • H.264 8-bit: NVENC এবং NVDEC যুক্ত প্রতিটি NVIDIA GPU এটি ডিকোড এবং এনকোড করতে পারে।
  • HEVC 8-bit: Maxwell second generation (GM206) এবং তার পরবর্তী কার্ডগুলো এটি ডিকোড ও এনকোড করতে পারে।
  • HEVC 10-bit: Maxwell second generation এবং তার পরবর্তী কার্ডগুলো এটি ডিকোড করতে পারে, কিন্তু 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-এর সক্ষমতাকে ছাড়িয়ে যায়, এবং এর কারণটি স্থাপত্যগত। ডিকোড (Decode) চলে NVDEC-এ। এনকোড (Encode) চলে NVENC-এ। টোন ম্যাপিং এর কোনোটিতেই চলে না: এটি একটি CUDA ফিল্টার যা shader core-এ কার্যকর হয়, অর্থাৎ GPU-এর সেই সাধারণ-উদ্দেশ্যমূলক অংশে যা কম্পিউট সংক্রান্ত কাজগুলো সম্পন্ন করে। তাই একটি 4K HDR স্ট্রিম যার টোন ম্যাপিং প্রয়োজন, সেটি ডিকোডার এবং এনকোডার উভয়কেই ব্যবহার করে এবং তার ওপর shader-এর ওপর বাড়তি চাপ সৃষ্টি করে।

Jellyfin-এর ডকুমেন্টেশন অনুযায়ী, প্রতিটি NVIDIA GPU যা HEVC 10-bit ডিকোড করতে পারে, সেটিতেই CUDA টোন ম্যাপিং উপলব্ধ। এর মানে হলো, এমন কার্ডগুলোতেও চেকবক্সটি দেখা যায় এবং কাজ করে যা 4K রেজোলিউশনে এটি ধরে রাখতে পারে না। এর লক্ষণ হলো এমন একটি স্ট্রিম যা শুরু হয়, বাফার করে এবং কখনোই স্থিতিশীল হয় না, অথচ nvidia-smi রিপোর্ট করে যে এনকোডারটি প্রায় অলস অবস্থায় আছে।

এ কারণেই shader-এর ওপর চাপের বিষয়টি আলাদাভাবে পর্যবেক্ষণ করা জরুরি।

nvidia-smi dmon -s u

এটি প্রতি সেকেন্ডে একটি লাইন প্রিন্ট করে যেখানে sm, enc এবং dec-এর জন্য আলাদা কলাম থাকে। একটি উচ্চ sm সংখ্যার পাশাপাশি কম enc এবং dec থাকা মানে হলো fixed-function ব্লকগুলো অলস বসে আছে এবং shader-ই হলো বাধা (bottleneck), তাই টোন ম্যাপিং, স্কেলিং বা সাবটাইটেল বার্ন-ইন আপনার সিস্টেমের ওপর বাড়তি চাপ সৃষ্টি করছে। CUDA পাথটি Dolby Vision profile 5-কে zero copy-র মাধ্যমেও পরিচালনা করে, যা গুরুত্বপূর্ণ কারণ 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 সালের আগস্ট পর্যন্ত NVIDIA-এর প্রকাশিত ম্যাট্রিক্সের পরিসংখ্যান, এখানে পরিমাপ করা কোনো তথ্য নয়। মডেল যাই হোক না কেন, একটি GeForce কার্ডে সর্বোচ্চ 12 টি কনকারেন্ট এনকোড সেশন সীমাবদ্ধ থাকে। এই সীমাবদ্ধতা সিলিকনের পরিবর্তে ড্রাইভারের মধ্যে থাকে এবং NVIDIA বছরের পর বছর ধরে এটি একাধিকবার বাড়িয়েছে, তাই পুরনো ফোরাম থ্রেড না পড়ে বর্তমান ম্যাট্রিক্সটি দেখুন। ইঞ্জিনের সংখ্যা হলো সেই অংশ যা কার্ডভেদে পরিবর্তিত হয়: GeForce RTX 5090 মডেলে 3 টি NVENC ইঞ্জিন থাকে, যেখানে GeForce RTX 4060 মডেলে 1 টি ইঞ্জিন থাকে। বেশি ইঞ্জিনের অর্থ হলো সমান্তরাল এনকোড থ্রুপুট বেশি, সেশনের উচ্চতর সীমা নয়।

এই ক্যাপটি শুধুমাত্র এনকোড সেশন গণনা করে, তাই এটি কেবল ট্রান্সকোডিং স্ট্রিমের ক্ষেত্রে প্রযোজ্য। ডিরেক্ট প্লে এবং রিমাক্সিংয়ের ক্ষেত্রে কোনো এনকোড সেশন ওপেন হয় না। একই ম্যাট্রিক্সে L4-এর মতো ডেটা সেন্টার কার্ডগুলোকে আনরেস্ট্রিক্টেড হিসেবে তালিকাভুক্ত করা হয়েছে এবং GPU VPS প্ল্যানে সাধারণত এই ধরনের ডেটা সেন্টার কার্ডই দেওয়া হয়, তাই এই ক্যাপটি মূলত হোম-সার্ভার ব্যবহারকারীদের জন্য একটি উদ্বেগের বিষয়।

যখন আপনি এই সীমাতে পৌঁছান, তখন ট্রান্সকোড ব্যর্থ হয় এবং FFmpeg লগে OpenEncodeSessionEx failed: out of memory (10) দেখা যায়। মেসেজটিতে মেমরির কথা উল্লেখ থাকলেও, সেশন-লিমিট প্রত্যাখ্যানের ক্ষেত্রেও একই কোড রিপোর্ট করা হয়, তাই VRAM লিক খোঁজার আগে আপনার কনকারেন্ট স্ট্রিমের সংখ্যা পরীক্ষা করে দেখুন। বাস্তবে, বেশিরভাগ মানুষ বারোটি সেশনে পৌঁছানোর আগেই টোন-ম্যাপিংয়ের সীমাবদ্ধতা বা তাদের আপলোড ব্যান্ডউইথের সংকটে পড়েন।

GPU ট্রান্সকোডিং করছে কি না তা যাচাই করুন, কনফিগারেশনের ওপর নির্ভর করবেন না

একটি সেভ করা সেটিংস মানেই প্রমাণ নয়। এমন একটি ফাইল প্লে করুন যা ট্রান্সকোড করতে বাধ্য করে, তারপর তিনটি পরীক্ষা চালান।

  1. Dashboard খুলুন, তারপর Playback-এ যান। সক্রিয় সেশনে Transcoding লেখা থাকা উচিত এবং সেখানে কারণটিও উল্লেখ থাকবে। যদি Direct playing লেখা থাকে, তবে কোনো কিছু ট্রান্সকোড হচ্ছে না এবং আপনি ভুল ফাইল পরীক্ষা করছেন।
  2. Dashboard খুলুন, তারপর 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 কলামে শূন্য ছাড়া অন্য মান থাকা উচিত।

তৃতীয় পরীক্ষাটি কন্টেইনারের ভেতরে নয়, বরং হোস্ট মেশিনে চালান। কন্টেইনারের ভেতরে nvidia-smi চালালে সাধারণত একটি খালি প্রসেস লিস্ট দেখায়, কারণ এটি তার নিজস্ব নেমস্পেসের বাইরের প্রসেস আইডি দেখতে পায় না, যদিও ইউটিলাইজেশন নম্বরগুলো সঠিকভাবে দেখায়। কন্টেইনারের ভেতরে প্রসেস লিস্ট খালি থাকা কোনো ত্রুটি নয়।

যখন এটি আপনাকে না জানিয়েই সফটওয়্যার মোডে ফিরে যায়

Jellyfin সাধারণত ভিডিও চালানো চালিয়ে যেতে পছন্দ করে। যখন কোনো হার্ডওয়্যার পাথ (hardware path) পাওয়া যায় না, তখন এটি স্ট্রিম বন্ধ না করে সফটওয়্যার মোডে চলে যায়। তাই এক্ষেত্রে সঠিক সংকেত হলো 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 দেখা যায় কি না।

যদি কোনো ট্রান্সকোড শুরু হওয়ার পর 4K HDR-এর ক্ষেত্রে আটকে যায় কিন্তু 1080p-তে ঠিকঠাক চলে, তবে বুঝতে হবে এটি টোন-ম্যাপিংয়ের সীমাবদ্ধতা, কোনো ব্রোকেন ইন্সটলেশন নয়। nvidia-smi dmon -s u-এ sm কলামটি দেখে এটি নিশ্চিত করুন। এরপর হয় ক্লায়েন্টের অনুরোধ করা রেজোলিউশন কমিয়ে দিন, অথবা 4K HDR ফাইলগুলো এমন ক্লায়েন্টে চালান যারা সেগুলো সরাসরি প্লে (direct play) করতে সক্ষম।

FAQ

Why does Jellyfin still use the CPU after I enabled NVENC?

Check the newest FFmpeg.Transcode log under Dashboard, then Logs. If it shows libx264, no hardware path was used at all, which usually means the container cannot see the GPU, so run docker compose exec jellyfin nvidia-smi to confirm. If it shows h264_nvenc but the CPU is still busy, the decode side is running in software, which happens when you ticked a codec your card cannot decode or when Enable hardware encoding was left off so only half the pipeline moved to the GPU.

Do I still need the runtime: nvidia line in Docker Compose?

Not if you have the deploy.resources.reservations.devices block and a current Docker Compose. The block is the modern device-request form and does the same job. runtime: nvidia is the older path from the nvidia-docker2 era, it still works, and Jellyfin's own published example keeps both. Keeping both is harmless. Keeping only runtime: nvidia means you must also keep NVIDIA_VISIBLE_DEVICES=all, because that path has no device request to read and takes the device list from the environment.

How many streams can one NVIDIA GPU transcode at once?

NVIDIA's published matrix caps GeForce cards at twelve concurrent encode sessions as of August 2026, and data center cards are listed as unrestricted. That ceiling is rarely what stops you. HDR to SDR tone mapping runs on the shader cores rather than on NVENC, so a handful of 4K HDR streams will exhaust the shaders long before the session counter matters. Measure your own case with nvidia-smi dmon -s u and watch the sm column, not the session count.

Can I use hardware transcoding on a VPS with no GPU?

No. Encoding needs the physical NVENC block, and lspci -nn | grep -Ei "3d|display|vga" on a standard VPS shows only a virtual display adapter from the hypervisor. The realistic answer on a GPU-free plan is to remove the transcodes instead: raise the client's quality setting to Auto, use a native client app rather than a browser, and convert image-based subtitle tracks to text so they do not force a video re-encode.

Why does 4K HDR stutter when 1080p transcodes fine?

The two workloads use different parts of the card. A 1080p SDR transcode is decode and encode only, both on fixed-function hardware. A 4K HDR stream adds tone mapping, which is a CUDA filter running on the shader cores, plus a much larger frame to scale. nvidia-smi dmon -s u showing low enc and dec next to high sm confirms it, because that pattern means the fixed-function blocks are idle and the general-purpose cores are the limit.