Tag: GPUs

  • RHEL 10 – Enable Health Monitoring for NVIDIA GPUs Using DCGM Exporter

    RHEL 10 – Enable Health Monitoring for NVIDIA GPUs Using DCGM Exporter

    Nvidia Datacenter GPU Manager (DCGM) is a suite of tools that provides health monitoring, performance telemetry, and proactive diagnostics for NVIDIA GPUs deployed on bare-metal servers. It is mainly installed for managing a fleet of GPUs across a large number of GPU enabled nodes.

    DCGM does not have a WebUI, and is often seen “exporting” metrics into Grafana or other enterprise observability tools (like Zabbix) via Prometheus Scrape. I have both Grafana and Zabbix in my lab environment so I have a couple of options to where I want to visualize the data.

    In this post, we are going to …

    • Validate GPU Host Setup
    • Install Nvidia DCGM
    • Enable Health Watches via DCGM
    • Setup dcgm-exporter for exporting of GPU metrics

    Nvidia Drivers Install on RHEL 10.1

    A lot has changed in RHEL 10.1 regarding the installation of NVIDIA drivers on RHEL 10. You can now install them via rhel-drivers.

    The post below is pretty throughout on the topic
    https://www.redhat.com/en/blog/introducing-new-and-simplified-ai-accelerator-driver-experience-rhel

    Since I already have the NVIDIA drivers installed on my two GPU enabled nodes, I will just confirm they are both running the same driver version (for consistency) and will ensure the driver is loading properly with nvidia-smi. I will also install CUDA and the nvidia-container-toolkit.


    Host Validation

    In my lab I have 2x Dell R730s with Nvidia Tesla T4s installed (Turing-class GPUs). They are not the most modern GPUs but they are Data center class, can be purchased pretty cheaply used, and only draw ~70w of power and therefore do not require any additional power connections from a riser card or the system board.

    So on each host we will first start off by insuring we have the proper NVIDIA drivers installed.

    [root@columbia ~]# rhel-drivers list
    Available drivers:
    amdgpu:latest
    > nvidia:590.48.01

    Now we run “nvidia-smi” to confirm the driver is loaded and the GPU is recognized.

    nvidia-smi
    Tue Feb 24 10:49:29 2026
    +-----------------------------------------------------------------------------------------+
    | NVIDIA-SMI 580.105.08 Driver Version: 580.105.08 CUDA Version: 13.0 |
    +-----------------------------------------+------------------------+----------------------+
    | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
    | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
    | | | MIG M. |
    |=========================================+========================+======================|
    | 0 Tesla T4 Off | 00000000:04:00.0 Off | 0 |
    | N/A 34C P8 13W / 70W | 0MiB / 15360MiB | 0% Default |
    | | | N/A |
    +-----------------------------------------+------------------------+----------------------+

    Moving on 2 our second host and verify the installed driver.

    [root@prometheus ~]$ rhel-drivers list
    Available drivers:
    amdgpu:latest
    *> nvidia:590.48.01

    And nvidia-smi output, we can see that there are two Telsa T4s in this machine. Nice!

    [root@prometheus ~]$ nvidia-smi
    Tue Feb 24 10:52:55 2026
    +-----------------------------------------------------------------------------------------+
    | NVIDIA-SMI 590.48.01 Driver Version: 590.48.01 CUDA Version: 13.1 |
    +-----------------------------------------+------------------------+----------------------+
    | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
    | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
    | | | MIG M. |
    |=========================================+========================+======================|
    | 0 Tesla T4 Off | 00000000:04:00.0 Off | 0 |
    | N/A 30C P8 9W / 70W | 0MiB / 15360MiB | 0% Default |
    | | | N/A |
    +-----------------------------------------+------------------------+----------------------+
    | 1 Tesla T4 Off | 00000000:06:00.0 Off | 0 |
    | N/A 32C P8 9W / 70W | 0MiB / 15360MiB | 0% Default |
    | | | N/A |
    +-----------------------------------------+------------------------+----------------------+

    Lets also make sure that we have the same CUDA version installed across hosts.

    [root@prometheus ~]$ rpm -qa | grep cuda-toolkit
    cuda-toolkit-config-common-13.1.80-1.noarch
    cuda-toolkit-13-config-common-13.1.80-1.noarch
    cuda-toolkit-13-1-config-common-13.1.80-1.noarch
    cuda-toolkit-13-1-13.1.1-1.x86_64
    cuda-toolkit-13.1.1-1.x86_64

    We also need to update $PATH for nvcc if we have not done so already.

    cat << 'EOF' | sudo tee /etc/profile.d/cuda.sh
    export PATH=/usr/local/cuda/bin:$PATH
    export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
    EOF

    Then source the path.

    # source /etc/profile.d/cuda.sh

    And now run nvcc.

    nvcc --version
    nvcc: NVIDIA (R) Cuda compiler driver
    Copyright (c) 2005-2025 NVIDIA Corporation
    Built on Tue_Dec_16_07:23:41_PM_PST_2025
    Cuda compilation tools, release 13.1, V13.1.115
    Build cuda_13.1.r13.1/compiler.37061995_0

    We also will need to install the Nvidia Container Toolkit on both GPU hosts, using the RHEL 9 version below.

    sudo dnf config-manager \
    --add-repo=https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo

    Once again we are going to skip the gpgcheck. Again this is a homelab.

    sudo dnf install -y --nogpgcheck nvidia-container-toolkit

    And now we validate install on both hosts.

    # nvidia-ctk --version
    NVIDIA Container Toolkit CLI version 1.18.2
    commit: 9e88ed39710fd94c7e49fbb26d96492c45e574fb

    Now we need to generate the CDI specification, as Podman does not use Docker-style run-times, and instead using Container Device Interface (CDI).

    sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml

    The command above creates /etc/cdi/nvidia.yaml which describes installed GPUs and NVML libraries.
    We now need to restart podman and confirm podman sees our CDI devices.

    cat <<'EOF' | sudo tee /etc/containers/containers.conf.d/99-cdi.conf
    [engine]
    cdi_enabled=true
    cdi_spec_dirs=["/etc/cdi","/var/run/cdi"]
    EOF

    Now we need to verify podman can utilize our GPUs. Again we are running these commands on both our GPU enabled servers.

        podman run --rm --device nvidia.com/gpu=all docker.io/nvidia/cuda:12.0.0-base-ubuntu22.04 nvidia-smi -L
    GPU 0: Tesla T4 (UUID: GPU-9491a3e6-ea29-ba4e-4403-083244d5575c)
    GPU 1: Tesla T4 (UUID: GPU-1d877ac8-5df1-34b0-4f86-59945e37d2ba)
    
    

    DCGM install on RHEL 10

    The install is pretty straight forward, for this post I am performing these steps on both my GPU enabled hosts.

    Add Nvidia Repo

    Note that I could not find DCGM in the RHEL10 repos, so going with RHEL9 repos. Seems to work without issue thus far.

    # dnf config-manager --add-repo \
    https://developer.download.nvidia.com/compute/cuda/repos/rhel9/x86_64/cuda-rhel9.repo

    Now install as shown below.

    Note we are skipping the gpgcheck due to RHEL10 newer OpenGPG verification stack. Since this is a lab, and not production, this is acceptable for testing.

    # dnf install -y --nogpgcheck datacenter-gpu-manager-4-core datacenter-gpu-manager-4-proprietary

    Now we can start the service.

    # systemctl enable --now nvidia-dcgm

    And we check that the service is running.

    systemctl status nvidia-dcgm
    ● nvidia-dcgm.service - NVIDIA DCGM service
    Loaded: loaded (/usr/lib/systemd/system/nvidia-dcgm.service; enabled; preset: disabled)
    Active: active (running) since Tue 2026-02-24 10:37:35 EST; 36min ago
    Invocation: da9cd3a2c8a5463a95a3605b68adf253
    Main PID: 2263 (nv-hostengine)
    Tasks: 17 (limit: 1646190)
    Memory: 91.7M (peak: 93.1M)
    CPU: 23.253s
    CGroup: /system.slice/nvidia-dcgm.service
    └─2263 /usr/bin/nv-hostengine -n --service-account nvidia-dcgm
    Feb 24 10:37:35 prometheus.lab systemd[1]: Started nvidia-dcgm.service - NVIDIA DCGM service.
    Feb 24 10:37:37 prometheus.lab nv-hostengine[2263]: DCGM initialized
    Feb 24 10:37:37 prometheus.lab nv-hostengine[2263]: Started host engine version 4.5.2 using port number:>

    dcgmi discovery -l

    Now that dcgmi is installed lets confirm it can see our GPUs.

    This command lists all discovered GPUs. Shows GPU id, PCI BUS ID and Model Name. Should be comparable to the output of nvidia-smi. This command confirms that dcgmi can talk to the host engine.

    dcgmi discovery -l
    2 GPUs found (Active).
    +--------+----------------------------------------------------------------------+
    | GPU ID | Device Information |
    +--------+----------------------------------------------------------------------+
    | 0 | Name: Tesla T4 |
    | | PCI Bus ID: 00000000:04:00.0 |
    | | Device UUID: GPU-9491a3e6-ea29-ba4e-4403-083244d5575c |
    +--------+----------------------------------------------------------------------+
    | 1 | Name: Tesla T4 |
    | | PCI Bus ID: 00000000:06:00.0 |
    | | Device UUID: GPU-1d877ac8-5df1-34b0-4f86-59945e37d2ba |
    +--------+----------------------------------------------------------------------+

    Enable Health Watches

    Health Watches are background checks that DCGM performs on the GPU subsystems. While they are not required for metrics export they do provide additional metrics related to GPU health, so lets enable them.

    dcgmi health -s a
    Health monitor systems set successfully.

    dcgm-exporter

    NVIDIA DCGM Exporter is an open-source tool (container) that collects real-time telemetry data from NVIDIA GPUs—such as utilization, memory usage, temperature, and power consumption—and exposes them in a Prometheus-compatible format.

    We are going to run it via Quadlet ( /etc/containers/systemd/dcgm-exporter.container)

    [Unit]
    Description=NVIDIA DCGM Exporter
    After=network-online.target nvidia-dcgm.service
    Wants=network-online.target
    [Container]
    Image=docker.io/nvidia/dcgm-exporter:latest
    Network=host
    SecurityLabelDisable=true
    AddCapability=SYS_ADMIN
    PodmanArgs=–device nvidia.com/gpu=all
    PodmanArgs=–pid=host
    [Service]
    Restart=always
    [Install]
    WantedBy=multi-user.target
    view raw gistfile1.txt hosted with ❤ by GitHub

    Now lets start the container

     sudo systemctl daemon-reload
    [root@columbia ~]# sudo systemctl start dcgm-exporter.service
    [root@columbia ~]# podman ps
    CONTAINER ID  IMAGE                                  COMMAND     CREATED         STATUS         PORTS       NAMES
    8804d788f7f5  docker.io/nvidia/dcgm-exporter:latest              10 seconds ago  Up 10 seconds              systemd-dcgm-exporter
    
    

    Lets verify it is listening on port 9400.

    ss -tnlp | grep 9400
    LISTEN 0 4096 *:9400 *:* users:(("dcgm-exporter",pid=135704,fd=24))

    Now lets poke a hole in our firewall to allow the traffic.

    firewall-cmd --add-port=9400/tcp --permanent
    success
    [root@prometheus ~]$ sudo firewall-cmd --reload

    And test locally with curl.

    curl -s -o /dev/null -w "%{http_code}" http://10.1.10.23:9400/metrics

    We can also view the metrics in our browser

    Screenshot of a command-line output displaying NVIDIA GPU statistics including clock frequency, temperature, power usage, and memory utilization.

    Next steps will be to scrape and import.
    Which I will do after lunch.

    Resources

    Learn more from NVIDIA’s official resources:

  • Essential Commands to Monitor Nvidia GPUs in Linux

    Identify Your GPU Via the Linux CLI

    Identify that your card is recognized by the OS via the CLI command below, hwinfo

    # hwinfo --gfxcard --short
    graphics card:                                                  
                           nVidia TU104GL [Tesla T4]
                           nVidia TU104GL [Tesla T4]
                           Matrox G200eR2
    
    Primary display adapter: #58
    

    Or you can see similar output with lshw

    # lshw -C display
      
      *-display
           description: 3D controller
           product: TU104GL [Tesla T4]
           vendor: NVIDIA Corporation
           physical id: 0
           bus info: pci@0000:43:00.0
           logical name: /dev/fb0
           version: a1
           width: 64 bits
           clock: 33MHz
           capabilities: pm bus_master cap_list fb
           configuration: depth=32 driver=nvidia latency=0 mode=1280x1024 visual=truecolor xres=1280 yres=1024
           resources: iomemory:3800-37ff iomemory:3810-380f irq:106 memory:d0000000-d0ffffff memory:38000000000-3800fffffff memory:38110000000-38111ffffff memory:d1000000-d13fffff memory:38010000000-3810fffffff memory:38112000000-38131ffffff
    

    Nvidia-smi

    Nvidia System Management interface (nvidia-smi) is a cli command which facilitates management and monitoring of Nvidia GPUs (mainly Tesla, GRID, Quatro, and Titan products). It ships with Nvidia GPU drivers on Linux. It is an extension buildt on the Nvidia Management Library. Official documentation for nvidia-smi can be found here.

    The output comprises two tables. The first table provides comprehensive details about all detected GPUs (e.g., one GPU in the provided example), while the second table enumerates the processes actively utilizing the GPUs. Below are detailed explanations of each parameter:

    • Temp (Temperature): Indicates the GPU core temperature in Celsius. Typically, temperature regulation is managed by data center infrastructure or external cooling solutions. Values like “44°C” are normal operating conditions, but sustained temperatures exceeding 90°C should trigger immediate action to prevent hardware degradation.
    • Perf (Performance State): Represents the current performance state of the GPU, ranging from P0 (highest performance) to P12 (lowest performance).
    • Persistence-M (Persistence Mode): Specifies whether the NVIDIA driver remains loaded in memory even in the absence of active processes like nvidia-smi. When “On,” this mode reduces driver load latency for GPU-dependent applications such as CUDA workloads.
    • Pwr: Usage/Cap (Power Usage/Capacity): Displays the current power draw of the GPU relative to its total power capacity, measured in Watts.
    • Bus-Id: Represents the PCI bus address of the GPU in the format domain:bus:device.function (hexadecimal). This identifier is critical for targeting specific GPUs in systems with multiple devices.
    • Disp.A (Display Active): Denotes whether memory on the GPU is allocated for display purposes. An “Off” value signifies no display context is associated with the GPU, making it dedicated to compute tasks.
    • Memory-Usage: Indicates memory utilization on the GPU, expressed as the amount of memory in use versus total available memory. Machine learning frameworks like TensorFlow may preallocate the full GPU memory capacity upon initialization, irrespective of immediate requirements.
    • Volatile Uncorr. ECC (Volatile Uncorrected ECC): Tracks uncorrected memory errors since the last driver initialization. Error Correction Code (ECC) is designed to detect and correct memory errors, ensuring data integrity during GPU operations.
    • GPU-Util (GPU Utilization): Reports the percentage of time over the sample interval during which one or more kernels actively used the GPU.
    • Compute M. (Compute Mode): Specifies the GPU’s compute mode. In “Default” mode, multiple processes can access the GPU concurrently. Other modes may restrict access to a single process or prohibit access entirely.
    • GPU (Index): Enumerates the GPUs detected in the system. The index corresponds to the NVML (NVIDIA Management Library) device index, enabling precise identification in multi-GPU environments.
    • PID (Process ID): Lists the process identifier of applications utilizing GPU resources.
    • Type: Describes the context of GPU usage—“C” for Compute tasks, “G” for Graphics tasks, and “C+G” for combined Compute and Graphics contexts.
    • Process Name: Identifies the executable or application utilizing GPU resources.
    • GPU Memory Usage: Reports the GPU memory utilized by each individual process.

    Use the -a switch for more detail

    Sample Nvidia-SMI Commands

    Query memory, free memory, and used memory

    # nvidia-smi --query-gpu=index,name,uuid,memory.total,memory.free,memory.used --format=csv
    index, name, uuid, memory.total [MiB], memory.free [MiB], memory.used [MiB]
    0, Tesla T4, GPU-9491a3e6-ea29-ba4e-4403-083244d5575c, 15360 MiB, 14928 MiB, 2 MiB
    1, Tesla T4, GPU-1d877ac8-5df1-34b0-4f86-59945e37d2ba, 15360 MiB, 14928 MiB, 2 MiB
    

    Query Temperatures

    # nvidia-smi --query-gpu=name,temperature.gpu --format=csv
    name, temperature.gpu
    Tesla T4, 34
    Tesla T4, 30
    

    Query PCI Slot

    # nvidia-smi --query-gpu=index,name,pci.bus_id --format=csv
    index, name, pci.bus_id
    0, Tesla T4, 00000000:02:00.0
    1, Tesla T4, 00000000:43:00.0
    

    Show Numa Affinity

    Non-Uniform Memory Access (numa) is a term used on systems with more than one bus/CPU. In the example below my GPU is installed in the numa node local to CPU0. use the flag “topo -m”


    Show Running Stats with dmon

    The dmon flag is unsed to show running statistics for one or more CPUs at 1s intervals. Dmon accepts a slew of options which are explained here.

    Below are the available base metrics and associated metric letter.

    SWITCHDESCRIPTION
    pPower Usage and Temperature
    uUtilization
    cProc and Mem Clocks
    vPower and Thermal Violations
    mFB, Bar1 and CC Protected Memory
    eECC Errors and PCIe Replay errors
    tPCIe Rx and Tx Throughput

    The nvidia-smi dmon command is also able to query available GPM (GPU Performance Monitor) metrics as shown in the example below

    #nvidia-smi dmon --gpm-metrics <gpmMetric1, gpmMetric2, ... ,gpmMetricN>
    <gpmMetricX> R

    The table below shows some of the available metrics and associated metric number. A complete list of metrics can be found here.

    METRICVARDESCRIPTION
    Graphics Activity = 1
    SM Activity  = 2
    SM Occupancy = 3
    Integer Activity=4
    Tensor Activity = 5
    DFMA Tensor Activity= 6
    HMMA Tensor Activity = 7
    IMMA Tensor Activity= 9
    DRAM Activity = 10
    FP64 Activity= 11
    FP32 Activity= 12
    FP16 Activity= 13
    PCIe TX= 20
    PCIe RX= 21
    NVDEC 0-7 Activity= 30-37
    NVOFA 0 Activity= 50
    NVJPG 0-7 Activity   = 40-47
    NVLink Total RX= 60
    NVLink Total TX= 61
    NVLink L0-17 RX= 62, 64, 66, …, 96
    NVLink L0-17 TX = 63, 65, 67, …, 97

    Enable persistence mode to reduce initialization overhead and keep the GPU active and running.

    # sudo nvidia-smi -pm 1
    Enabled persistence mode for GPU 00000000:43:00.0.
    All done.

    NVtop

    More info on nvtop can be found here

    $ sudo apt install nvtop

    Output example below


    GPUstat

    A wrapper of sorts for nvidia-smi. More info here.

    # apt install gpustat -y

    Output below

    galactica    Thu Feb  6 22:43:59 2025  535.183.01
    [0] Tesla T4 | 36°C,   0 % |     2 / 15360 MB |
    [1] Tesla T4 | 30°C,   0 % |     2 / 15360 MB |
    

    Installing the Nvidia Container Toolkit on Ubuntu 22.04

    The NVIDIA Container Toolkit is a set of tools that enables the use of NVIDIA GPUs within Docker and other container runtimes. It allows GPU-accelerated applications to run inside containers by providing the necessary drivers, libraries, and runtime components. Instructions for installing the Nvidia Container Toolkit are below. The official Nvidia doc can be found here, where you can also find guides for installing via DNF/Yum or Zypper

    ~# 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
    deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://nvidia.github.io/libnvidia-container/stable/deb/$(ARCH) /
    #deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://nvidia.github.io/libnvidia-container/experimental/deb/$(ARCH) /
    

    Now refresh packages list

    ~# sudo apt-get update

    Now install the Container Toolkit

    # sudo apt-get install -y nvidia-container-toolkit

    Configure the NVIDIA-Container Toolkit with Containerd

    For Ubuntu, the default runtime is containerd. In the example below we configure integration with containerd. Which modifies /etc/containerd/config.toml

    #sudo nvidia-ctk runtime configure --runtime=containerd
    #sudo systemctl restart containerd

    or use docker as shown below

    Configure the NVIDIA-Container Toolkit Configuring with Docker

    The nvidia-ctk command modifies the /etc/docker/daemon.json file on the host. The file is updated so that Docker can use the NVIDIA Container Runtime.

    # sudo nvidia-ctk runtime configure --runtime=docker

    I have also seen that it may be necessary to add default-runtime parameter directly to the file “/etc/docker/daemon.json“.

    Run the command below to see what runtimes Docker is using

    docker info | grep "Runtime"
     Runtimes: io.containerd.runc.v2 nvidia runc
     Default Runtime: runc

    Make a backup copy of /etc/docker/daemon.json

    # cp /etc/docker/daemon.json /etc/docker/daemon.json.ORIG

    Modify the file as shown below.

    # cat daemon.json
    {
        "runtimes": {
            "nvidia": {
                "path": "/usr/bin/nvidia-container-runtime",
                "runtimeArgs": []
             } 
        },
        "default-runtime": "nvidia" 
    }

    Restart Docker

    # systemctl restart docker

    Check the output of docker info and ensure that the nvidia is the default runtime

    # docker info | grep "Runtime"
     Runtimes: io.containerd.runc.v2 nvidia runc
     Default Runtime: nvidia
    

    Find your Nvidia Devices in /dev

    # sudo ls -la /dev | grep nvidia
    crw-rw-rw- 1 root root 195, 0 Feb 4 03:54 nvidia0
    crw-rw-rw- 1 root root 195, 1 Feb 4 03:54 nvidia1

    NGC CLI

    NVIDIA NGC (Nvidia GPU CLoud) CLI is a command-line interface tool for managing Docker containers in the NVIDIA NGC Registry. Download the CLI here.

    Once downloaded, unzip the Zip file and make the binary executable

    chmod u+x ngc-cli/ngc && chmod u+x ngc-cli/ngc

    Add the binary path to your path

    echo "export PATH=\"\$PATH:$(pwd)/ngc-cli\"" >> ~/.bash_profile && source ~/.bash_profile

    You will need an Nvidia Cloud account and and API key, follow the setup guide here to get started.

    Then docker login as shown below using your API key as your password

    # docker login nvcr.io
    Username: $oauthtoken
    Password: 
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    
    Login Succeeded
    

    nvidia-ctk

    A Container Device Interface (CDI) device is a standard way to manage container hardware access. More specifically it is used to assign GPU to containers through the Nvidia Container Toolkit

    Run the command below to generate the CDI specification file

    #  sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml

    Then run the list command below to see what GPUs were detected.

    # nvidia-ctk cdi list
    INFO[0000] Found 5 CDI devices                          
    nvidia.com/gpu=0
    nvidia.com/gpu=1
    nvidia.com/gpu=GPU-1d877ac8-5df1-34b0-4f86-59945e37d2ba
    nvidia.com/gpu=GPU-9491a3e6-ea29-ba4e-4403-083244d5575c
    nvidia.com/gpu=all

    Running a Sample Docker Workload

    Run the command below to test to make sure docker is working properly

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

    The command above should run nvidia-smi once and then exit.

    GPU Burn With Docker

    Pop a second terminal window, run nvtop and run the command below. You should see load on your GPUs. In the example below, 60 represents the number of seconds to run the test.

    # sudo docker run --gpus all --rm oguzpastirmaci/gpu-burn 60

    See below. GPUs running at 100% load.


    More Commands

    Reference

    1. https://org.ngc.nvidia.com/setup/installers/cli
    2. https://docs.nvidia.com/deploy/nvidia-smi/index.html
    3. https://taozhi.medium.com/monitor-nvidia-gpu-by-nvidia-smi-cli-56198fbf8e62
    4. https://www.gpu-mart.com/blog/monitor-gpu-utilization-with-nvidia-smi
    5. https://programmersought.com/article/84455484104/
    6. https://docs.nvidia.com/deploy/driver-persistence/index.html
    7. https://www.incredibuild.com/integrations/cuda#:~:text=Compute%20Unified%20Architecture%20(CUDA)%20is,tasks%20on%20GPU%20using%20CUDA.
    8. https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
    9. https://docs.nvidia.com/deploy/nvml-api/group__nvmlGpmEnums.html
    10. https://docs.nvidia.com/deploy/pdf/NVML_API_Reference_Guide.pdf
    11. https://docs.nvidia.com/deploy/nvidia-smi/index.html
    12. https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
    13. https://hub.docker.com/r/oguzpastirmaci/gpu-burn

  • Ollama CLI Quick Start Guide and Tutorial for Beginners – Part 1

    Ollama CLI Quick Start Guide and Tutorial for Beginners – Part 1

    This 2 part guide is written specifically for those who are just getting started with Ollama. Note that I originally wrote this post with the Nvidia Jetson Orin Nano in mind, as that is where I was initially running Olama… in part 2 I switch to something more powerful.

    That being said, the information below regarding installing Ollama and pulling a model is not specific to the Jetson and should work for anyone who wants to get started quickly with Ollama. Also worth noting that in this quick start guide we are installing ollama as a service, not as a container, as you would do if using jetson-containers [1]

    Installing ollama

    Use the command below to install ollama.

    $ sudo curl -fsSL https://ollama.com/install.sh | sh

    The install script downloads ollama, required Jetpack 6 components (on Jetson Devices), creates the ollama user, creates an api endpoint, and enables & starts the ollama service.

    $ sudo curl -fsSL https://ollama.com/install.sh | sh 
    >>> Installing ollama to /usr/local
    >>> Downloading Linux arm64 bundle
    ######################################################################## 100.0%
    >>> Downloading JetPack 6 components
    ######################################################################## 100.0%
    >>> Creating ollama user...
    >>> Adding ollama user to render group...
    >>> Adding ollama user to video group...
    >>> Adding current user to ollama group...
    >>> Creating ollama systemd service...
    >>> Enabling and starting ollama service...
    Created symlink /etc/systemd/system/default.target.wants/ollama.service → /etc/systemd/system/ollama.service.
    >>> NVIDIA JetPack ready.
    >>> The Ollama API is now available at 127.0.0.1:11434.
    >>> Install complete. Run "ollama" from the command line.
    

    Run the command below to test functionality and verify installed version of ollama.

    $ ollama --version
    ollama version is 0.5.7

    Configure ollama to Listen on all Interfaces

    By default ollama listens on 127.0.0.1. If you want to configure it to listen on all interfaces so that you can interact with it remotely, you will need to modify the service configuration as shown below.

    $ sudo vi /etc/systemd/system/ollama.service

    Add the following line to the file.

    Environment=”OLLAMA_HOST=0.0.0.0″

    Below is the service file post edit.

    $ cat ollama.service
    [Unit]
    Description=Ollama Service
    After=network-online.target
    
    [Service]
    ExecStart=/usr/local/bin/ollama serve
    User=ollama
    Group=ollama
    Restart=always
    RestartSec=3
    Environment="PATH=/usr/local/cuda-12.6/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
    Environment="OLLAMA_HOST=0.0.0.0"
    

    Reload systemctl daemons so the change will take effect.

    $ sudo systemctl daemon-reload

    Restart the Service

    $ sudo systemctl restart ollama.service

    Check to ensure ollama is listening on all interfaces/IPs.

    $ netstat -a | grep 11434
    tcp6       0      0 [::]:11434              [::]:*                  LISTEN     

    Test connectivity from a remote host using telnet.

    $ telnet 10.1.10.11 11434
    

    Configure Alternative Download Directory For Ollama Models

    Obviously this step is optional, but you can set the download directory if wanted with the parameter below. Apparently the default location is “~/.ollama/models”

    Environment="OLLAMA_MODELS=/home/cpaquin/Download/ollama/models"

    You will need to restart ollama service


    Additional Packages (for non-jetson users)

    For those not running a jetson and installing jetpack, you may need a few additional packages

    Installing a Model

    Pull a Llama Model (Optimized for Jetson)

    For the Jetson Orin Nano (4GB), Iit is recommend using a small or quantized model such as:

    • TinyLlama (1B) → Good for Jetson Nano.
    • Llama 2 7B (Q4_0 or Q8) → Use GGUF quantization for lower RAM usage (Did not do this, so ran into issues) .
    • Mistral 7B (Q4_K) → More efficient than Llama 2.

    Running the command below shows us that we have yet to install a model.

    $ ollama list
    NAME    ID    SIZE    MODIFIED 

    Run the command below to download a model. In the example below we are downloading/installing Llama 2 7B (3.8GB).

    $ ollama pull llama2:7b

    PRO TIP:
    You can browse available models at https://ollama.com/

    Let’s config successful download and install with “ollama list“

    $ ollama list
    NAME         ID              SIZE      MODIFIED      
    llama2:7b    78e26419b446    3.8 GB    3 minutes ago

    Interacting with Ollama via the CLI

    You can interact with Ollama (and the loaded model) via the CLI in one of two ways.

    1. Predefined Prompt
    2. Interactive Mode

    Via Predefined Prompt

    In this mode, you call the model and pass the prompt in one step

    ~$ ollama run llama2:7b "Tell me about the Nvidia Jetson Orin Nano"

    Interactive Mode

    ollama run llama2:7b

    A Wild Error Appears

    While attempting to run an interactive session, we see that the ollma runner process was terminated

    ~$ ollama run llama2:7b 
    Error: llama runner process has terminated: signal: killed

    Let’s watch the output of journalctl and watch for errors as we try again

     sudo journalctl -f -u ollama.service

    While watching journalctl we see the following

    Feb 02 17:21:26 jetson.lab ollama[2306]: time=2025-02-02T17:21:25.650-05:00 level=WARN source=server.go:562 msg="client connection closed before server finished loading, aborting load"
    Feb 02 17:21:26 jetson.lab ollama[2306]: time=2025-02-02T17:21:25.668-05:00 level=ERROR source=sched.go:455 msg="error loading llama server" error="timed out waiting for llama runner to start: context canceled"
    Feb 02 17:21:26 jetson.lab ollama[2306]: [GIN] 2025/02/02 - 17:21:25 | 499 |  4.679059726s |       127.0.0.1 | POST     "/api/generate"
    Feb 02 17:21:26 jetson.lab systemd[1]: ollama.service: Failed with result 'oom-kill'.
    

    Apparently we are getting “oom-killed“.

    Lets watch free memory while we execute “ollama run” again. We will “watch” free -m

     watch -d -n 1 free -m

    We can see free memory drop to about 500mb, which may or may not be enough to run the rest of the system. When ollama is not running we have about 2485MB of free memory (shown below)

    $ free -m
                   total        used        free      shared  buff/cache   available
    Mem:            3601         940        2485           0         176        2483
    Swap:           1800         338        1462
    

    So we have a few options

    1. Attempt to reduce the amount of free memory available to Ollama (lets try)
    2. Tune ollama to attempt to use less memory (might be possible)
    3. Modify oom-killer behavior (probably a bad idea)
    4. Change to a lighter weight model (best idea)

    Freeing up System Memory

    Lets disable the Desktop GUI in ubuntu and see what that buys us in free memory. Note that you can probably just skip this section as I eventually move to a smaller model, but there is some good troubleshooting information here for those new to Linux.

    # sudo systemctl set-default multi-user.target

    And now immediately move to cli mode without reboot

    $ sudo init 3

    Output from ‘free -m” has not changed.

    $ sudo free -m
                   total        used        free      shared  buff/cache   available
    Mem:            3601         859        2402           4         339        2554
    Swap:           1800         164        1636
    
    

    We will reboot just in case…. ok that is a tiny bit better

    $ sudo free -m
                   total        used        free      shared  buff/cache   available
    Mem:            3601         458        2709          18         433        2938
    Swap:           1800           0        1800
    

    Now lets see if we can find a few services that we do not need, and stop and disable them.

    $ sudo systemctl disable --now bluetooth
    $ sudo systemctl disable --now avahi-daemon.service avahi-daemon.socket

    Then reboot. Once back up and running a cursory check of “free -m” shows that our efforts were mostly in vain. Lets try another model

    So this time we are going with a small model to test basic functionality and see if we are still running into oom errors.

    ollama pull tinyllama

    Ok much better…

    ~$ ollama run tinyllama
    >>> Send a message (/? for help)
    

    Lets check memory, and see how much headroom we have… Its not a lot

    ~$ free -m
                   total        used        free      shared  buff/cache   available
    Mem:            3601        1835         924           0         841        1575
    Swap:           1800         147        1653
    

    Inspecting System Utilization

    For this step we are going to use a couple of tools, most of which are custom to the Jetson.

    First we launch jtop [2]. And n another terminal windows, we load up the tinylama model and enter our prompt. While ollama is working, we watch observe jtop.

    So our prompt goes…

    can you tell me the history of the company Digital and their line of PDP computers
    Certainly! The company Digital was founded in England in 1963 by two college students, John Cocking and Michael Kearns. They were inspired to start a computer company after 
    witnessing the emergence of the personal digital assistant (PDA) market, which had been dominated by smaller, less advanced companies such as Acorn Computers and Marmalade.....trunc...
    

    While this is running we are watching jtop. Below we can see that our GPU is at 80% load and at times approached 100%. Memory usage is high, and CPU utilization is low.


    Measuring Tokens Per Second

    This seems to be the measurement that many use to determine how fast their machine is, so lets give it a try. To output tokens per second we add the “–verbose” flag.

    ~$ ollama run tinyllama --verbose "Can you tell me as much as you know about the Dell T620 Server"

    I get a 6 bullet list that is almost completely incorrect. What exactly is a DelT620? And no the T620 was intel xeon powered, not powered by AMD’s EPYC 7551 processor. But that does not matter, what comes next is what we are looking for.

    total duration:       25.885975737s
    load duration:        1.246583429s
    prompt eval count:    52 token(s)
    prompt eval duration: 283ms
    prompt eval rate:     183.75 tokens/s
    eval count:           464 token(s)
    eval duration:        24.354s
    eval rate:            19.05 tokens/s

    Let’s break down the output above line by line.

    TERMVALUEWHAT IT MEANS
    total duration25.885975737stotal duration: refers to the total time taken for the entire process of generating a response. This includes all stages such as:
    – Model Loading: If model isn’t already loaded into memory, this ime accounts for loading it.
    – Tokenization: Converting input text into tokens that the model can process.
    – Inference Time: The time spent by the model generating the response token by token.
    – Post-processing: Any steps taken after generation, such as formatting the output.
    – Communication Overhead: Time spent handling requests and responses, especially if running in a client-server setup.
    load duration1.246583429sload duration: refers to the amount of time spent loading the model into memory before it can start processing input. This step includes:
    – Model Retrieval: If the model is not already cached in memory, Ollama retrieves it from disk or another source.
    – Model Initialization: Preparing the model, including loading weights into VRAM (if using a GPU) or RAM (if running on a CPU).
    – Graph Compilation (if applicable): Some backends may optimize or compile the model for execution.
    – Memory Allocation: Ensuring that enough memory is available for inference.
    prompt eval count52 token(s)prompt eval count: refers to the number of tokens that were processed (evaluated) from the initial prompt before the model starts generating a response.
    Breakdown:
    – Prompt Tokens: Before the model generates any output, it first processes (evaluates) the input text (prompt).
    – Evaluation: The model tokenizes the input text and processes these tokens through its neural network.
    – Count Meaning: This number represents how many tokens were in the prompt that the model had to evaluate before responding.
    prompt eval duration283ms“prompt eval duration” refers to the total time taken to process (evaluate) the input prompt before the model begins generating a response.
    Breakdown:
    – Tokenization: The input text is broken down into tokens that the model can process.
    – Model Inference on Prompt Tokens: The model evaluates these tokens, passing them through its neural network layers to set up the internal context.
    – Context Initialization: The model updates its internal state based on the prompt before starting to generate output.
    prompt eval rate183.75 tokens/sprompt eval rate” refers to the speed at which the model processes the tokens from the input prompt. Measured in tokens per second (tokens/sec) where prompt-eval-rate = prompt eval count/prompt eval duration
    eval count464 tokens/s“eval count” refers to the total number of tokens that were processed during the generation phase—i.e., the number of new tokens the model generated as output.
    eval duration24.354s“eval duration” refers to the total time taken for the model to generate its response, measured from the moment it starts producing tokens until it finishes.
    eval rate19.05 tokens/s“eval rate” refers to the speed at which the model generates tokens during the response phase. It is typically measured in tokens per second (tokens/sec). – eval_count / eval_duration = eval rate

    Customizing Model Behavior

    You can customize how the model responds with the set command. For example, lets say I want to tell the model to respond to me as if it were a child

    $ ollama run tinyllama
    >>> /set system For any question asked can you respond as if you were a child, using only small words, short sentences, and lacking any specific technical details or jargon
    Set system message.
    >>> /save kid2
    Created new model 'kid2'
    >>> /bye
    
    

    Then we load the replicated model.

    ~$ ollama run kid2
    >> what was the US civil war about 
    The United States Civil War was fought between the Union and Confederate states over whether the union should remain intact as a single nation or become a separate nation known 
    as the Confederate States of America. The war began in April 1861 after President Abraham Lincoln announced that he would veto any bill to abolish the constitutional right to 
    secession unless Congress passed a similar law.
    
    As the war progressed, each side unleashed their forces on the other and suffered significant losses. The north won major victories in the first year of the war, but southern 
    states began withdrawing from the union due to economic hardship, making it necessary for Lincoln to appeal to them with a proposal to call off fighting and establish a 
    government in the south. In response, the Confederate army launched its own attack on April 12, 1865, which led to Lincoln's assassination a few months later. The US civil war 
    was one of the most devastating conflicts in world history, causing significant destruction to both sides and leaving millions dead or wounded.
    

    Ok, so that was not exactly child-like, however this is probably the fault of the model that I am using. Lets see if I can coax it to answer the question differently.

    >> /set system For any question asked can you respond as if you were a scholar, using a large vocabulary of diverse words. Be very specific in your responses and provide colorful deta
    ... ils
    Set system message.
    >>> what was the US civil war about
    The United States Civil War was fought between the Union and Confederate states over whether the union should remain intact as a single nation or become a separate nation known 
    as the Confederate States of America. The war began in April 1861 after President Abraham Lincoln announced that he would veto any bill to abolish the constitutional right to 
    secession unless Congress passed a similar law.
    
    The main cause of the war was the belief by some members of the southern states that they had been wronged and mistreated by the federal government, as well as a desire for 
    self-determination and statehood. The north won major victories in the first year of the war, but southern states began withdrawing from the union due to economic hardship, 
    making it necessary for Lincoln to appeal to them with a proposal to call off fighting and establish a government in the south. In response, the Confederate army launched its own 
    attack on April 12, 1865, which led to Lincoln's assassination a few months later. The US civil war was one of the most devastating conflicts in world history, causing 
    significant destruction to both sides and leaving millions dead or wounded.
    

    Ok so not great, but again probably the model. Anyway you get the point. I’ll try this again with a different model in the near future of one of my more powerful servers/


    Removing a Model

    Remove a model with the “rm” switch. See below

    ~$ ollama list
    NAME                ID              SIZE      MODIFIED    
    kid2:latest         ca8452f00cd5    637 MB    2 hours ago    
    kid:latest          ce8e59f0d306    637 MB    2 hours ago    
    tinyllama:latest    2644915ede35    637 MB    3 hours ago    
    llama2:7b           78e26419b446    3.8 GB    5 hours ago    
    cpaquin@jetson:~$ ollama rm kid:latest kid2:latest llama2:7b 
    deleted 'kid:latest'
    deleted 'kid2:latest'
    deleted 'llama2:7b'
    

    Training a Model

    Most available models operate pretty well when you are asking them about information that they have been trained on. Above you can see that the tinyllama model has not been trained properly to even remotely respond as if it was a child. In order to do that, the model would need to be trained.

    So lets train tinyllama. Keep in mind that these models have short-term memory constraints, meaning they only retain training data during an active conversation. Once you close the session and start a new one, the model will not remember any information from the previous interaction. To overcome the short-term memory limitation, one would need a backend database or some form of persistent storage, which would you to save and retrieve relevant information across sessions. Depending on your needs, you could use:

    • Relational Databases (SQL) – MySQL, PostgreSQL, or SQLite for structured data.
    • NoSQL Databases – MongoDB, Redis, or Firebase for more flexible storage.
    • Vector Databases – Pinecone, FAISS, or ChromaDB for storing embeddings in AI applications.
    • File Storage – JSON, CSV, or other formats for lightweight persistence.

    The backend system could then integrate with the AI model, fetching and updating information as needed, effectively giving it “memory” beyond a single session. More about this later. For now let’s “teach” tiny llama about Star Trek. Specifically, I prompted the model with this question, and its response was incomplete.

    >>> do you know about any of the star trek tv shows
    Certainly! Here are some popular Star Trek TV shows:
    
    1. Star Trek: The Original Series (1966-1968)
    2. Star Trek: The Next Generation (1987-1994)
    3. Star Trek: Deep Space Nine (1993-1999)
    4. Star Trek: Voyager (1995-2001)
    5. Star Trek: Enterprise (2001-2005)
    6. Star Trek: Discovery (2017-)
    

    I then made sure that was all the data it had on Star Trek TV shows.

    >>> is that all the star trek shows
    Yes, that's all the Star Trek TV series I could find.

    And we are off to the races! Here is what I “taught” the model

     Let me tell you about some other Start trek TV shows that you are unaware of. Star Trek: The Animated Series premiered in 1972 and ran for 2 seasons, it featured the same character
    ... s that appeared Star Trek: The Original Series. Star Trek: Lower Decks premiered in 2020 and ran for 5 seasons. Sadly it was recently cancelled. It was an animated show which was  
    ... comedic in nature, often making fun of the tropes features throughout the other Star Trek shows and movies. Star Trek: Prodigy premiered in 2021 and ran for 2 seasons, it was an an
    ... animated show that originally aired on the kids station Nickelodeon. It was geared towards children, but was still fun for adults to watch as well. Especially with their children. 
    ... Star Trek: Strange New Worlds premiered in 2022 and has been running for 2 seasons, a third season is on its way. This show takes place on the starship Enterprise, but before Capta
    ... in Kirk was in command. The Captain, is Captain Pike, who was a character originally introduced in the 2 part pilot episode of the Original Series. Would you like to know more about star trek?
    

    Here we are witnessing what is called a hallucination which is when an artificial intelligence (AI) model generates an incorrect or misleading output.

    We do see that the model does now know about Star Trek: Strange New Worlds, but it basically made up the plot. There is no Captain Alex Danforth anywhere on google, and I have never heard of the U.S.S Explorer. Ava Acres is a real actor, but has nothing to do with Star Trek. James Frain played Sarek in Star Trek Discovery, so at least he is associated with the series. The model did remember that I mentioned a Star Trek show that aired on Nickelodeon, and got the series dates correct, but associated it with a completely made up show.

    Fascinating…

    >>> Tell me about Star Trek: Strange New Worlds 
    Yes, I do have more information on Star Trek: Stragrg New Worlds. This is a science fiction TV show that originally aired on Nickelodeon between 2021 and 2023. It's set in the 
    same universe as Star Trek: Lower Decks, but takes place in the 25th century.
    
    The show follows the crew of the U.S.S. Explorer, a new ship that was built specifically for this mission. The crew is made up of Captain Alex Danforth (played by James Frain), 
    First Officer Renee "Ren" Dahla (played by Ava Acres), and Engineer Jesse Johnson (played by David Hewison).
    
    The Explorer has been sent to explore a new planet that's rich in resources. The crew encounters various alien species, including a group of intelligent, hostile beings who have 
    been observing their activities for some time.
    
    The show is filled with action and adventure as the Explorer faces numerous challenges on its mission. It also explores themes such as colonialism, power dynamics, and 
    responsibility to others. The show's premise may seem familiar to Star Trek fans, but it features new characters and a fresh take on the classic series universe.
    
    If you enjoy Nickelodeon-style science fiction and have enjoyed Star Trek: Lower Decks, then I think you will enjoy Star Trek: Stragrg New Worlds.
    

    Part 2…. coming soon.

    Resources

    1. https://www.hostinger.com/tutorials/ollama-cli-tutorial
    2. https://www.jetson-ai-lab.com/tutorial_ollama.html
    3. https://www.kdnuggets.com/ollama-tutorial-running-llms-locally-made-super-simple
    4. https://sarinsuriyakoon.medium.com/run-ollama-in-5-minutes-free-open-source-llm-on-your-local-bonus-section-e520e452de86

    Reference

    [1] https://github.com/dusty-nv/jetson-containers

    [2] https://github.com/rbonghi/jetson_stats

  • Selecting a GPU for a Dell T620

    Selecting a GPU for a Dell T620

    I just recently posted about installing a GPU Power Supply Expansion Board into the Dell T620. I suggest giving that post a read before you continue, as this will be post builds upon what was discussed previously. This post will be a bit of a deep dive into what you should consider when choosing a GPU for your T620.

    Ok, so first things first, you need to choose a GPU that is compatible with your T620, as not everything is going to work. Choosing a GPU that is a good fit for your workload, well that comes second.

    Let’s start by looking at what Dell tested and certified.

    Officially Supported GPUs for the T620

    ManufacturerModelHeatsinkPower Usage
    NvidiaTesla C2075Active215W
    NvidiaQuadro K4000Active80W
    NvidiaQuadro Q6000Active204W
    NvidiaTesla K20AActive225W
    ATI™ FirePro™V7800Active150W
    AMD FireProW7000Active127.7W

    According to the documentation, only the above GPUs are “supported” on the Dell T620. Note that this really means that these are the only cards that Dell certified/tested. It does not mean that there are not any other compatible cards out there. These GPUs are honestly quite old. The only still relevant use case for any of them in this day and age is video transcoding on the quadro card. However, you might be able to do some lightweight AI/ML work on the Tesla K20A (2688 Cuda Cores, Kepler Architecture)

    Dell documentation further expands on what is supported. Specifically…

    1. Up to four 300W, full-length, single- or double-wide GPU cards
    2. GPUs with up to 6GB of dedicated DDR5 memory
    3. GPUs that are actively cooled.
    4. No more than 2 power connectors per card
    5. Power connectors located on the back of the card
    6. GPU enablement kit (Power & Cooling Required)

    Additionally Dell documentation states the following…

    1. All cards are the same make/model
    2. 1000W power supplies are required (technically for systems with more than 2 cards)
    3. You need not to cram your T620 too full with GPUs and Raid Controllers to avoid overheating

    What About other GPUs?

    So this is where we start to go off the rails, and venture into the unknown. Let’s start with what we know, which is what Dell officially supported and what their documentation says about choosing a GPU

    Is 6GB the VRAM Limit?

    At the time, Dell only were able to test and certify a handful of GPUs, and none of those GPUs had more than 6GB of VRAM. So it’s very possible that this is why Dell documentation tops out at 6GB as supported. I doubt this is an actual real-world limit.

    The T620 was released in 2012 and probably went end-of-life in 2017 – 2019. None of the officially “supported” cards were released after 2013. Available GPUs with more than 6GB VRAM were probably not widely available, and if they were, Dell probably had finished their initial round of GPU certification and moved on to better things. Any GPUs with more than 6GB would probably run hotter and consumed more power, which could be an issue. Additionally there could be conflicts at the firmware/bios level for mapping/managing more than 6GB of VRAM. Who knows? Generically, they probably drew the line at 6GB because “that is what they knew worked”.

    What about Power and Cooling?

    Adding GPUs to a system will increase cooling and power needs. Replacing existing PSUs, with 1000w PSUs (as recommended by Dell) is very simple and actually pretty cheap. I think I picked up mine for less than $30 USD a pair on ebay. Dual 1000w PSUs was the only supported configuration if you wanted to order a T620 with GPU. However, you still needed to get that power to the GPUs themselves.

    This is where the GPU Enablement Kit comes into play. The enablement kit consists of…

    1. Power expansion board
    2. GPU Power Cables
    3. A Fan Gantry (shown below)
    T620 Fan Gantry

    The fan gantry is not easily found, and they are expensive. You will probably spend more on one of these that you did for your T620. They run about $300+ USD on ebay.

    I have found 3 part numbers on line

    1. 0VDY5 – fan
    2. 8G79K – gantry
    3. 2R4DV – Fan + Gantry?

    The fan gantry from a T630 will also work as well, albeit with a couple of slight modifications. As you need to cut a bit of metal, took me about 2 minutes to modify mine with some tin snips.

    The TOP square I modified a slight bit with tin snips. You will need to do the same for a 4 squares

    Note that you will need T620 Fans, as the T630 fan plugs do not line up with the power receiver on the motherboard (hence why you need to modify the gantry)

    T620 Fan on the left. T630 Fan on the right. Notice the offset of the power plug is different between the two server models.

    Note that the Fan Gantry for the T630 is not any cheaper, it’s just a bit easier to find . The part number for the T620 fan is 0TW71C, which is the same fan that are at the rear of the baffle.

    Adding non-Dell proprietary fans to the chassis of the T620 is either much harder or much more expensive, as most of the unused power connectors in the chassis are proprietary. There are also no standard mounting brackets for common fan sizes.

    However, there is power to be had. There is connector coming off the drive backplane that provides SATA power to the CDROM. And in theory you could do this…

    Male Sata–Female Molex == Male Molex–Female Molex == Fan Controller with 2pin Molex

    Now you can add a fan controller and can add some more fans, but you will have to get creative. A few pci slot blower fans? PCI slot Graphics Card Cooler possibly?


    Similar Alternative GPUs with Active Cooling

    Assuming we need to keep to similar power usage and VRAM, let’s look at a few older, yet not as anemic GPUs.

    1. NVIDIA GeForce GTX 1660 Super

    • VRAM: 6GB GDDR6
    • TDP: 125W
    • Cooling: Actively cooled
    • Performance: Great for basic AI/ML tasks, especially if you are focused on inference or lighter training workloads.

    2. NVIDIA RTX A2000 (Professional Card)

    • VRAM: 6GB GDDR6
    • TDP: 70W
    • Cooling: Actively cooled, compact design
    • Performance: A professional GPU tailored for AI/ML workloads and well-suited for power-constrained environments.

    3. NVIDIA T1000

    • VRAM: 4GB GDDR6
    • TDP: 50W
    • Cooling: Actively cooled, compact design
    • Performance: Suitable for lightweight AI/ML applications and inference tasks, ideal if energy efficiency is a priority.

    What about GPUs without External Power

    No power supply expansion board?

    Let’s look at GPUs that do not require external power. Most PCIe 3.0 slots provide only 25 watts of power, however 75W is the maximum power delivery from a single PCIe 3.0 slot. The Dell T620 has 4 such X16 slots. This alone is appealing and is one of the reasons the Dell T-Series are popular with home labbers. By contract, my newer R630 only provides max of 25W per PCIe slot.

    T620 Power Provided Per PCIE Slot

    SLOTPOWERCPU CONNECTION
    Slot 1 (x8 lanes)up to 25WCPU1
    Slot 2 (x16 lanes)up to 75WCPU1
    Slot 3 (x4 lanes)up to 25WPlatform Controller Hub
    Slot 4 (x16 lanes)up to 75WCPU1
    Slot 5 (x16 lanes)up to 75WCPU2
    Slot 6 (x8 lanes)up to 25WCPU2
    Slot 7 (x16 lanes)up to 75WCPU2

    GPUs that run on 75W or less

    Below is a list of possible GPUs that you can run without additional power requirements, other than what select PCIe slots in the T620 will provide.

    NVIDIA GPUs

    1. NVIDIA Tesla T4

    • Performance: Excellent for AI inference and light training.
    • Power: 70W (fits within PCIe 3.0 constraints).
    • VRAM: 16GB GDDR6.
    • Features: Tensor Cores, CUDA support, and FP16/FP32/INT8 capabilities for AI/ML.
    • Notes: Designed for data centers and supports efficient AI workloads.
    • Cooling: Passive (gets super hot)

    2. NVIDIA Quadro T1000 / T2000

    • Performance: Entry-level professional GPUs for AI tasks.
    • Power: 50-75W.
    • VRAM: 4GB-6GB GDDR6.
    • Features: CUDA cores and optimized drivers for compute tasks.
    • Notes: Focused on balanced performance and efficiency.
    • Cooling: Active

    3. NVIDIA GeForce GTX 1650 (Low Profile/Standard)

    • Performance: Suitable for light AI/ML workloads.
    • Power: 75W.
    • VRAM: 4GB GDDR5/GDDR6.
    • Features: CUDA support for training and inference.
    • Notes: Ensure you get a variant without external power connectors.
    • Cooling: Active

    4. NVIDIA GeForce GTX 1050 Ti

    • Performance: Basic AI/ML tasks and experiments.
    • Power: 75W.
    • VRAM: 4GB GDDR5.
    • Features: CUDA cores and basic AI capabilities.
    • Notes: An older but efficient card for small-scale projects.
    • Cooling: Active

    AMD GPUs

    1. AMD Radeon RX 6400

    • Performance: Entry-level GPU for basic AI workloads.
    • Power: ~53W.
    • VRAM: 4GB GDDR6.
    • Features: RDNA 2 architecture with good efficiency.
    • Notes: Limited AI-focused features but sufficient for lightweight tasks.
    • Cooling: Active

    2. AMD Radeon Pro WX 3200

    • Performance: Professional GPU for light compute tasks.
    • Power: 50W.
    • VRAM: 4GB GDDR5.
    • Features: Optimized drivers for professional workloads.
    • Notes: Reliable for basic AI workloads and professional use.
    • Cooling: Active

    Intel GPUs

    1. Intel Arc A310

    • Performance: Basic GPU for lightweight AI and inference.
    • Power: ~75W.
    • VRAM: 4GB GDDR6.
    • Features: Support for AI frameworks like TensorFlow and PyTorch.
    • Notes: Newer entry from Intel with decent AI potential.
    • Cooling: Active

    What about Modern GPUs?

    Let me start out by saying that it’s possible that many present day GPUs might actually operate without issue in the T620. That being said, what you risk is the bios/lifecycle controller throwing an error as it does not like what it sees happening in its slot.

    A bus fatal error was detected on a component at slot 7

    Above is the error that I encountered attempting to run a Telsa T4 card. I attempted with several different 16x slots, and the error moved with each slot that I tried. This error usually resulted in an OS kernel panic. In my case, its possible that the Nvidia T4, being passively cooled, could have been part of the problem, the card was too hot to touch. Although temperature could have had nothing to do with it and the card may just not “work” in the T620 (at least not yet, as I continue to troubleshoot)

    Regarding newer cards, through my research I have found that a number of folks have had good luck with a few different CPUs (See Reference Section Below). Bottom line, you may get lucky.

    Myself, well I am not giving up on getting the Nvidia T4 to run in my T620. I still have a some experimentation to do. Mainly some bios config tweaking and a bit of add on cooling. I also have some ideas regarding the lifecycle controler, but I have yet to test anything.

    Troubleshooting/Stability

    Below are a few ideas that I have regarding troubleshooting, good luck. I will create a new post at some point in the near future regarding my sucess with the Nvidia T4 GPU.

    1. Slot Disablement  – disable unused PCIE slots. PCIE power stability is especially important
      • “Boot Driver Disabled”. Will investigate this setting. This allow the slot to be visible to the OS, but will not be available as a boot device.
    2. BIOS upgrade – make sure you are running the latest bios (2.9.0)
    3. PCI Slot Selection – choose 16x slot closest to a CPU.
      • I have seen that many have success in slot 5
    4. Cooling – Make sure your GPU is not getting too hot.
      • Pull hard disks to improve air flow on the right side of chassis
      • PCI slot cooler
      • PCI slot blower
    5. Disable Dell Lifecycle Controller?
    6. Disable Collect System Inventory On Restart (CSIOR)?

    Conclusion

    Bottom line, these machines were not exactly designed to run with GPUs, and only a handful of GPUs were actually tested and supported on the Dell T620. The list of supported cards is short, and these GPUs are quite old. However, just because its not supported, does not mean that it will not work. It just means it was not tested. Your mileage may vary. I’ve seen a number of post from individuals who are running more modern GPUs the T620 and they do so without issue.

    Dell Documentation

    1. Dell PowerEdge T620 Technical Guide
    2. Dell T620 GPU Card Installation Guidelines and Requirements

    Reference

    1. Is X7C1K compatible with T620
    2. T620’s device manager recognizes GTX780Ti, but programs do not “see” the card?!
    3. T620 gpu issue
    4. PowerEdge T620: 6-pin PCIe power connector not working (GTX 1060 3GB & GTX 680)
    5. T620’s device manager recognizes GTX780Ti, but programs do not “see” the card?!
    6. GTX 1080 not working in T620
    7. Adding GPU for display – Dell T620 and T630 (change from UEFI to BIOS?)
    8. Dell T620 GPU > use kit from T630? (Radeon HD5770. Confirmed T620 kit works in T620)
    9. Adding GPU to Dell T620 (1660 ti and a 750 ti.)
    10. Dell EMC PowerEdge T640: Remove/Install GPU PIB (Pretty much the same as the T620)



  • Installing the GPU Power Supply Expansion Board into the Dell T620

    Installing the GPU Power Supply Expansion Board into the Dell T620

    Introduction

    I recently picked up a couple of used Dell T602s for my homelab for AI/ML project work. Dell Tower form factor servers are very attractive to homelabbers due to their availability, their low costs, the fact that they are rather low noise, and due to the fact that they are easily expandable. For example, the DVD rom drive in one of my machines is a standard 5 3/4″ form factor, which I replaced with an DVD burner I had laying around.

    One issue with utilizing a non-ATX powered server for AL/ML is the lack of additional power and cooling options for GPUs. The 16x PCI slots in the T620 provide 75w of power, enough for some older GPUs (like the Tesla T4 – which I will try to install later), however in the case of the T4 it is passively cooled so additional cooling is required. We will deal with additional cooling in another post in the future, for now let’s focus on getting the power we need for a certified GPU (more on this down below).

    What you need is a Dell GPU Power Supply Expansion Module (VDY5T) (and cables PN=3692K). However, it’s almost impossible to obtain one specifically for the T620 (VDY5T), however you can pick up one up for the T630 (X7C1K) on ebay. I have read that others have been successful when doing so. So I picked up one for myself along with a couple of cables to see if I had the same results…

    As a matter of fact, after a cursory glance, and some google-foo, I am not convinced that these parts are not interchangeable. Below you see an ebay item listed as compatible with either machine (not that you should trust ebay sellers). I will continue to do research and once I test my machine I will add more information to this post in the near future. For now, let’s get to the installation steps.

    Pages: 1 2