<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>LXC on Charlie Chiang's blog</title><link>https://charlie0129.github.io/blog/categories/lxc/</link><description>Recent content in LXC on Charlie Chiang's blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Mon, 04 Nov 2024 12:57:00 +0800</lastBuildDate><atom:link href="https://charlie0129.github.io/blog/categories/lxc/index.xml" rel="self" type="application/rss+xml"/><item><title>Share NVIDIA GPU between CTs in Proxmox VE</title><link>https://charlie0129.github.io/blog/p/pve-ct-share-nvidia-gpu/</link><pubDate>Mon, 04 Nov 2024 12:57:00 +0800</pubDate><guid>https://charlie0129.github.io/blog/p/pve-ct-share-nvidia-gpu/</guid><description>&lt;h2 id="background">Background
&lt;/h2>&lt;p>Consider a small lab, students need to use GPU for their projects. We have a NVIDIA GPU in our Proxmox VE server, and we want to share the GPU between multiple containers so that multiple students can use the GPU at the same time.&lt;/p>
&lt;p>Why not use a VM? Because a GPU can only be passed through to one VM at a time (only one student can use the GPU at a time). And resources are not flexible in VMs.&lt;/p>
&lt;p>Why not create multiple users in the host and let them run their programs in the host? Because we want to isolate the students from the host, so that they can&amp;rsquo;t access the host and other students&amp;rsquo; data.&lt;/p>
&lt;p>Why not use Docker? Because Docker containers doesn&amp;rsquo;t have a full init system, and it&amp;rsquo;s hard to run some applications.&lt;/p>
&lt;p>Since we use PVE and it has LXC containers built-in (called CT), it is a perfect choice.&lt;/p>
&lt;h2 id="install-drivers-on-the-host">Install Drivers on the Host
&lt;/h2>&lt;p>Make sure the GPU is detected by the host. Note the NVIDIA GPUs &lt;code>3b:00.0&lt;/code> (Your address may differ).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> lspci &lt;span class="p">|&lt;/span> grep -i nvidia
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">3b:00.0 VGA compatible controller: NVIDIA Corporation TU104GL [Quadro RTX 5000] (rev a1)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">3b:00.1 Audio device: NVIDIA Corporation TU104 HD Audio Controller (rev a1)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">3b:00.2 USB controller: NVIDIA Corporation TU104 USB 3.1 Host Controller (rev a1)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">3b:00.3 Serial bus controller [0c80]: NVIDIA Corporation TU104 USB Type-C UCSI Controller (rev a1)
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;blockquote>
&lt;p>You may ask: does your entire lab only own one RTX 5000? What kind of lab is this? Are you cave people?&lt;/p>
&lt;p>Yes, although we have multiple projects worth over millions of Chinese Yuan, most of the money is gone to the some other places (which I cannot publicly speak on the Internet 🤫 ). And the professors have no emphasis on students&amp;rsquo; growth.
As a result, we are actually poor as hell.&lt;/p>
&lt;p>Since almost no one knows how to properly configure a Linux server, I want to help my classmates to learn more and let them use the only GPU. But to be honest, I won&amp;rsquo;t benefit from doing this. It&amp;rsquo;s just voluntary work.&lt;/p>&lt;/blockquote>
&lt;p>Install prerequisites. Note that I am using &lt;code>pve-headers-$(uname -r)&lt;/code> to install the headers for the current kernel. If you are using a different kernel, you may need to install the headers for that kernel. Also, you may want to use &lt;code>linux-headers-$(uname -r)&lt;/code> instead of &lt;code>pve-headers-$(uname -r)&lt;/code> if you are not using Proxmox VE.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> apt install -y gcc make pve-headers-&lt;span class="k">$(&lt;/span>uname -r&lt;span class="k">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Download CUDA toolkit from &lt;a class="link" href="https://developer.nvidia.com/cuda-downloads" target="_blank" rel="noopener"
>here&lt;/a> and install it. Drivers are included in the CUDA toolkit so you don&amp;rsquo;t need to install drivers separately.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> wget &amp;lt;cuda-runfile-download-url&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> ./cuda_12.2.2_535.104.05_linux.run --silent
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>The default installation options will work fine. If anything fails, you can check the log file at &lt;code>/var/log/cuda-installer.log&lt;/code> for CUDA logs and &lt;code>/var/log/nvidia-installer.log&lt;/code> for NVIDIA driver logs.&lt;/p>
&lt;p>PS: You need to blacklist &lt;code>nouveau&lt;/code> driver. This is automatically done by PVE. If not, you can do this by creating a file &lt;code>/etc/modprobe.d/blacklist-nouveau.conf&lt;/code> with the following content: &lt;code>blacklist nouveau&lt;/code>. Then run &lt;code>update-initramfs -u&lt;/code> to update the initramfs.&lt;/p>
&lt;p>PPS: If you used to passthrough this GPU to a VM, be sure to remove the GPU from the VM&amp;rsquo;s hardware configuration in PVE otherwise PVE will bound the GPU to &lt;code>vfio-pci&lt;/code> (see &lt;code>Kernel driver in use&lt;/code> row in &lt;code>lspci -k&lt;/code>) and cannot be used by the host.&lt;/p>
&lt;p>PPPS: Some kernel versions are known to have problems with NVIDIA drivers. If you encounter problems, you may need to downgrade/upgrade the kernel. For example, kernel version 5.10.0 is known to have &lt;code> make[3]: *** No rule to make target 'scripts/module.lds', needed by '/tmp/selfgz38416/NVIDIA-Linux-x86_64-560.35.03/kernel-open/nvidia.ko'&lt;/code> error.&lt;/p>
&lt;p>After installation finished, check if the driver is loaded.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> nvidia-smi
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">Tue Nov 5 09:56:44 2024
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">+---------------------------------------------------------------------------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| NVIDIA-SMI 535.104.05 Driver Version: 535.104.05 CUDA Version: 12.2 |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">|-----------------------------------------+----------------------+----------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| | | MIG M. |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">|=========================================+======================+======================|
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| 0 Quadro RTX 5000 Off | 00000000:3B:00.0 Off | Off |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| 33% 44C P0 28W / 230W | 0MiB / 16384MiB | 6% Default |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| | | N/A |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">+-----------------------------------------+----------------------+----------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">+---------------------------------------------------------------------------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| Processes: |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| GPU GI CI PID Type Process name GPU Memory |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| ID ID Usage |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">|=======================================================================================|
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| No running processes found |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">+---------------------------------------------------------------------------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="allow-nvidia-device-passthrough-in-ct">Allow NVIDIA Device Passthrough in CT
&lt;/h2>&lt;p>Now we need to allow the CT to access the GPU. I am using an unprivileged container here. Edit the CT&amp;rsquo;s configuration file (&lt;code>/etc/pve/local/lxc/&amp;lt;id&amp;gt;.conf&lt;/code>). Add the following lines to the end of the file.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-diff" data-lang="diff">&lt;span class="line">&lt;span class="cl"> arch: amd64
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> cores: 4
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> features: nesting=1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> hostname: ct-gpu-tmpl-deb127-cu122
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> memory: 4096
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> net0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=AA:AB:F0:07:42:D0,ip=dhcp,type=veth
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ostype: debian
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> rootfs: local-zfs:basevol-8001-disk-0,size=16G
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> swap: 0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> unprivileged: 1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># These lines allow the container to access specific character devices (c) with rwm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># permissions (read, write, modify). These are needed for NVIDIA GPU access.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.cgroup.devices.allow: c 195:* rwm
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.cgroup.devices.allow: c 509:* rwm
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.cgroup.devices.allow: c 235:* rwm
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">&lt;/span># These lines mount various GPU-related devices from the host into the container.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gi">+ lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>PS: If you cannot use &lt;code>nvidia-smi&lt;/code> (it says &lt;code>Failed to initialize NVML: Unknown Error&lt;/code>), there is a possibility that you are using &lt;code>cgroup2&lt;/code>. Change all the &lt;code>lxc.cgroup.devices.allow&lt;/code> lines to &lt;code>lxc.cgroup2.devices.allow&lt;/code>.&lt;/p>
&lt;p>&lt;strong>Explanation:&lt;/strong>&lt;/p>
&lt;p>Allows container access to NVIDIA device nodes:&lt;/p>
&lt;ul>
&lt;li>&lt;code>c 195:*&lt;/code> - NVIDIA character devices&lt;/li>
&lt;li>&lt;code>c 509:*&lt;/code> - NVIDIA UVM devices&lt;/li>
&lt;li>&lt;code>c 235:*&lt;/code> - NVIDIA CTL devices&lt;/li>
&lt;/ul>
&lt;p>Maps the following host GPU devices into container:&lt;/p>
&lt;ul>
&lt;li>&lt;code>/dev/nvidia0&lt;/code> - Main GPU device&lt;/li>
&lt;li>&lt;code>/dev/nvidiactl&lt;/code> - NVIDIA control device&lt;/li>
&lt;li>&lt;code>/dev/nvidia-modeset&lt;/code> - Display mode setting&lt;/li>
&lt;li>&lt;code>/dev/nvidia-uvm&lt;/code> - Unified memory management&lt;/li>
&lt;li>&lt;code>/dev/nvidia-uvm-tools&lt;/code> - UVM diagnostic tools&lt;/li>
&lt;li>&lt;code>/dev/dri&lt;/code> - Direct Rendering Infrastructure&lt;/li>
&lt;li>&lt;code>/dev/fb0&lt;/code> - Framebuffer device&lt;/li>
&lt;/ul>
&lt;p>Mount options:&lt;/p>
&lt;ul>
&lt;li>&lt;code>bind&lt;/code>: Mount as a bind mount&lt;/li>
&lt;li>&lt;code>optional&lt;/code>: Don&amp;rsquo;t fail if device doesn&amp;rsquo;t exist&lt;/li>
&lt;li>&lt;code>create=file/dir&lt;/code>: Create the mount point if it doesn&amp;rsquo;t exist&lt;/li>
&lt;/ul>
&lt;p>Note that if you are using a different GPU, you may need to change the device numbers. For example, &lt;code>/dev/nvidia1&lt;/code> instead of &lt;code>/dev/nvidia0&lt;/code>. You can find the device numbers in &lt;code>nvidia-smi&lt;/code> output.&lt;/p>
&lt;h2 id="install-drivers-in-ct">Install Drivers in CT
&lt;/h2>&lt;p>Log into the CT. All the following commands are run in the CT.&lt;/p>
&lt;p>You should be able to see NVIDIA devices inside the CT:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> ls -l /dev/nvidia*
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">---------- 1 root root 0 Nov 5 02:31 /dev/nvidia-modeset
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">crw-rw-rw- 1 nobody nogroup 507, 0 Nov 5 01:56 /dev/nvidia-uvm
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">crw-rw-rw- 1 nobody nogroup 507, 1 Nov 5 01:56 /dev/nvidia-uvm-tools
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">crw-rw-rw- 1 nobody nogroup 195, 0 Nov 5 01:56 /dev/nvidia0
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">crw-rw-rw- 1 nobody nogroup 195, 255 Nov 5 01:56 /dev/nvidiactl
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Install CUDA and drivers, just like you would on a physical machine, except that you don&amp;rsquo;t need to install the kernel modules. I will install CUDA 12.2 (drivers are included in the CUDA installer).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> wget &amp;lt;cuda-runfile-download-url&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> apt install -y gcc
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> ./cuda_12.2.2_535.104.05_linux.run --extract&lt;span class="o">=&lt;/span>&lt;span class="k">$(&lt;/span>&lt;span class="nb">pwd&lt;/span>&lt;span class="k">)&lt;/span>/cu122
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Note that I extracted the installer to manually install it because we want to skip kernel module installation and such options are not exposed in the installer.&lt;/p>
&lt;p>Install the bundled drivers:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="go">cd cu122
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">./NVIDIA-Linux-x86_64-535.104.05.run --no-nouveau-check --no-kernel-modules --silent
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Run &lt;code>nvidia-smi&lt;/code> to check if the driver is loaded.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> nvidia-smi
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">Tue Nov 5 05:49:02 2024
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">+---------------------------------------------------------------------------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| NVIDIA-SMI 535.104.05 Driver Version: 535.104.05 CUDA Version: 12.2 |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">|-----------------------------------------+----------------------+----------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| | | MIG M. |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">|=========================================+======================+======================|
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| 0 Quadro RTX 5000 Off | 00000000:3B:00.0 Off | Off |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| 33% 38C P0 23W / 230W | 0MiB / 16384MiB | 0% Default |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| | | N/A |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">+-----------------------------------------+----------------------+----------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">+---------------------------------------------------------------------------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| Processes: |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| GPU GI CI PID Type Process name GPU Memory |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| ID ID Usage |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">|=======================================================================================|
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">| No running processes found |
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">+---------------------------------------------------------------------------------------+
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>We can now see that the GPU is accessible in the CT.&lt;/p>
&lt;p>Let&amp;rsquo;s continue with the CUDA installation. Remember to uncheck the driver installation option because we have already installed the drivers above.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="go">./cuda-linux.12.2.2-535.104.05.run
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>After a successful installation, you should add cuda binaries to PATH. Instructions should be printed at the end of the installation. Then you can run &lt;code>nvcc&lt;/code> to see if CUDA is installed correctly.&lt;/p>
&lt;p>Everything should be working by this point.&lt;/p>
&lt;h2 id="missing-nvidia-uvm-and-high-idle-power-draw">Missing &lt;code>nvidia-uvm&lt;/code> and High Idle Power Draw
&lt;/h2>&lt;p>One problem I encountered is that when the host reboots, the GPU is not accessible in the CT. This is because &lt;code>nvidia-uvm&lt;/code> device isn&amp;rsquo;t created until an application attempts to interact with the graphics card. This is a problem because no application will interact with the GPU at boot, so no &lt;code>nvidia-uvm&lt;/code> device is created. But the CT needs the &lt;code>nvidia-uvm&lt;/code> device bind-mounted at CT-startup in order to access the GPU.&lt;/p>
&lt;p>Also, the graphics card have insanely high power draw at idle (over 100 Watts). The GPU is in P0 and never leaves it. We can use &lt;code>nvidia-persistenced&lt;/code> to let the GPU enter a low-power state (P8) when not in use.&lt;/p>
&lt;p>To solve this, we can run &lt;code>nvidia-smi -pm 1&lt;/code> (which enables &lt;code>nvidia-persistenced&lt;/code> and keeps nvidia character device and handles frequency scaling) at boot. Add the following line to the host&amp;rsquo;s crontab to run &lt;code>nvidia-smi -pm 1&lt;/code> at boot.&lt;/p>
&lt;p>PS: This only works if the host is a headless server (no monitor attached). If you have a monitor attached, you may need to run &lt;code>nvidia-smi&lt;/code> below instead.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="gp">#&lt;/span> crontab -e
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">@reboot /usr/bin/nvidia-smi -pm 1
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="downsides">Downsides
&lt;/h2>&lt;p>Despite the fact that this method works best for us, there are some downsides:&lt;/p>
&lt;ul>
&lt;li>The CT will have full access to the GPU. If one CT uses all the GPU memory, other CTs will be starving. So you must trust the users of the CTs. This is not a problem for us because we know each other.&lt;/li>
&lt;li>Driver updates are a bit more complicated. You need to update the drivers on the host and in all of the CTs. It&amp;rsquo;s best to not update the drivers too often.&lt;/li>
&lt;li>The CTs share the same kernel with the host. To avoid potential compatibility issues, we don&amp;rsquo;t update the kernel unless necessary.&lt;/li>
&lt;/ul></description></item></channel></rss>