Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
92d657e
docs(concepts): replace Introduction with a Concepts category
togettoyou Oct 15, 2026
5361ae1
docs(concepts): add device plugin and DRA background page
togettoyou Oct 15, 2026
e40c94a
docs(concepts): rewrite Architecture around the path of a Pod
togettoyou Oct 15, 2026
740cab8
docs(concepts): explain the device sharing resource model
togettoyou Oct 16, 2026
8e1ddab
docs(concepts): explain how HAMi-Core isolates memory and compute
togettoyou Oct 16, 2026
04ee462
docs(concepts): add a Scheduling concept page
togettoyou Oct 16, 2026
8da704f
docs(concepts): add an Observability concept page
togettoyou Oct 16, 2026
d509dfd
docs(concepts): redraw the ecosystem integrations diagram as SVG
togettoyou Oct 17, 2026
4ad0b80
docs(concepts): redraw the GPU software stack diagrams as SVG
togettoyou Oct 17, 2026
b532eb9
docs(concepts): redraw the GPU drivers diagram and fix the module notes
togettoyou Oct 17, 2026
e73db0c
docs(concepts): add the problem, a diagram and how it works to What i…
togettoyou Oct 17, 2026
66656a3
docs(concepts): move What is HAMi to the top of the sidebar
togettoyou Oct 17, 2026
8cf0abe
docs(concepts): sync the Concepts section to v2.10.0
togettoyou Oct 17, 2026
e186a27
docs(concepts): fix arrow and label overlaps in three diagrams
togettoyou Oct 17, 2026
9b244e8
docs(concepts): address review comments and replace the animated diag…
togettoyou Oct 17, 2026
aaf34c4
docs(concepts): clarify what the device plugin reports to kubelet
togettoyou Oct 17, 2026
5ddcb72
docs(concepts): keep the Concepts section in next only
togettoyou Oct 31, 2026
07e389f
docs(concepts): address review comments on facts and diagram readability
togettoyou Oct 31, 2026
fb2bbbd
docs(concepts): redo the diagrams in draw.io with brand colors and da…
togettoyou Nov 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 18 additions & 16 deletions docs/core-concepts/architecture.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
---
title: Architecture
description: The four HAMi components and the path a Pod takes through them.
---

The overall architecture of HAMi is shown as below:

![Architecture](/img/docs/common/core-concepts/architect.jpg)
![HAMi components and the path of a Pod](/img/docs/en/core-concepts/hami-architecture-flow.svg#light-only) ![HAMi components and the path of a Pod](/img/docs/en/core-concepts/hami-architecture-flow-dark.svg#dark-only)

HAMi consists of the following components:

- HAMi MutatingWebhook
- HAMi scheduler-extender
- Device-plugin (HAMi-device-plugin)
- In-container resource control (HAMi-Core)
| Component | Runs as | What it does |
| --- | --- | --- |
| MutatingWebhook | Part of the `hami-scheduler` Deployment | Checks each new Pod. If the Pod asks for HAMi resources and names no other scheduler, sets `schedulerName` to `hami-scheduler`. Other Pods pass through unchanged. |
| HAMi scheduler | `hami-scheduler` Deployment, next to `kube-scheduler` as a scheduler extender | Keeps a view of every GPU in the cluster. Filters nodes, picks a card, and writes the choice to the Pod's annotations. |
| HAMi device plugin | DaemonSet on each GPU node | Reports the node's cards to kubelet and to the scheduler. When a Pod starts, mounts the chosen card and HAMi-Core into the container and passes the limits as environment variables. |
| HAMi-Core (`libvgpu.so`) | Library loaded inside the container | Intercepts CUDA and NVML calls. Rejects memory allocations past the limit and can throttle kernel launches to the compute share. |

## HAMi MutatingWebhook {#hami-mutatingwebhook}
## The path of a Pod

HAMi MutatingWebhook checks if this task can be handled by HAMi. It scans the resource field of each pod submitted. If each resource the pod requires is either 'CPU', 'Memory' or a HAMi-resource, then it will set the schedulerName field of this pod to 'hami-scheduler'.
Take a Pod that asks for `nvidia.com/gpumem: 3000`:

## HAMi Scheduler {#hami-scheduler}
1. **Admission.** The webhook sees a HAMi resource and routes the Pod to `hami-scheduler`.
2. **Scheduling.** The HAMi scheduler reads each card's memory and compute from node annotations. It keeps the nodes with a card that has 3000 MiB free, picks one card by policy, and records the card's UUID and the Pod's share in Pod annotations.
3. **Start.** kubelet on the chosen node starts the Pod and calls the device plugin's `Allocate`.
4. **Injection.** The device plugin reads the annotations, mounts the card, `libvgpu.so`, and `/etc/ld.so.preload` into the container, and sets `CUDA_DEVICE_MEMORY_LIMIT_0=3000m`.
5. **Enforcement.** When any process in the container starts, the dynamic linker loads HAMi-Core first. From then on, HAMi-Core checks memory allocations and kernel launches against the limits. See [Device resource isolation](../key-features/device-resource-isolation.md).

The HAMi scheduler is responsible for assigning tasks to the appropriate nodes and devices. At the same time, the scheduler needs to maintain a global view of heterogeneous computing devices for monitoring.
## Learn more

## Device Plugin {#device-plugin}

The device-plugin layer obtains the scheduling result from the annotations field of the task and maps the corresponding device to the container.

## HAMi-Core {#hami-core}

The in-container resource control is responsible for monitoring the resource usage within the container and providing hard isolation capabilities.
- [GPU virtualization principles](./gpu-virtualization.md): a detailed walk through registration, scheduling, and injection
- [Protocol design](../developers/protocol.md): the annotations the scheduler and device plugin exchange
51 changes: 51 additions & 0 deletions docs/core-concepts/device-plugin-and-dra.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: Device Plugin and DRA
description: The two ways Kubernetes hands devices to Pods, and how classic HAMi and HAMi-DRA use them.
sidebar_label: Device plugin and DRA
---

Kubernetes has two ways to hand a device to a Pod: the device plugin API and Dynamic Resource Allocation (DRA). Classic HAMi uses a device plugin. [HAMi-DRA](https://github.com/Project-HAMi/HAMi-DRA) uses DRA.

![Device information flow with a device plugin and with DRA](/img/docs/en/core-concepts/device-plugin-vs-dra.svg#light-only) ![Device information flow with a device plugin and with DRA](/img/docs/en/core-concepts/device-plugin-vs-dra-dark.svg#dark-only)

## Device plugin

A device plugin runs as a DaemonSet on each GPU node. It does three things:

1. **Register** with kubelet under a resource name such as `nvidia.com/gpu`.
2. **Report** its devices, each with an ID and a health state. kubelet publishes the count in the node's capacity.
3. **Allocate** a device when a Pod starts on the node. kubelet calls the plugin, and the plugin returns the device files, mounts, and environment variables for the container.

The scheduler sees only that count. It learns that a node has 4 GPUs, and nothing about their memory or model. For a whole-card request that is enough. To place a 3000 MiB slice, the scheduler needs more.

HAMi fills the gap in two ways:

- The HAMi device plugin reports each card `deviceSplitCount` times (10 by default), so up to 10 Pods can hold a share of one card. A node with one GPU shows `nvidia.com/gpu: 10`.
- It writes each card's details to the node annotation `hami.io/node-nvidia-register`: UUID, memory, compute, model, NUMA node, and health. The HAMi scheduler reads this annotation to pick a card.

See [Protocol design](../developers/protocol.md) for how the scheduler and device plugin pass decisions through annotations.

## Dynamic Resource Allocation

DRA reached general availability in Kubernetes v1.34. It describes devices and requests with these API objects:

| Object | Role |
| --- | --- |
| `ResourceSlice` | Published by the DRA driver. Lists each device with its attributes. |
| `DeviceClass` | A named set of devices, selected by attributes. |
| `ResourceClaim` | A Pod's request for devices, similar to a PersistentVolumeClaim. |
| `ResourceClaimTemplate` | A template the Pod references. Kubernetes creates a `ResourceClaim` from it for each Pod. |

The scheduler reads device attributes from `ResourceSlice` objects directly, so no annotation is needed.

HAMi-DRA keeps the HAMi Pod spec. Its webhook converts `nvidia.com/gpu`, `nvidia.com/gpumem`, and `nvidia.com/gpucores` into a `ResourceClaim`. HAMi-Core still enforces the limits inside the container, so isolation works the same way in both modes.

## Which one to use

HAMi-DRA needs Kubernetes v1.34 or later with the DRA Consumable Capacity feature gate, plus CDI in the container runtime. On any other cluster, use classic HAMi. [Choose your setup](../get-started/choose-your-setup.md) has the full comparison.

## Learn more

- [Kubernetes device plugins](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)
- [Kubernetes Dynamic Resource Allocation](https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/)
- [HAMi DRA for Kubernetes](../installation/how-to-use-hami-dra.md)
41 changes: 5 additions & 36 deletions docs/core-concepts/ecosystem-integrations.md
Comment thread
togettoyou marked this conversation as resolved.
Resolved
Comment thread
togettoyou marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
@@ -1,45 +1,14 @@
---
title: Ecosystem Integrations
description: How HAMi works with Volcano, Kueue, Koordinator, and KAI Scheduler.
sidebar_label: Integrations
---

HAMi doesn't replace your Kubernetes scheduler. It extends it. HAMi handles GPU virtualization, sharing, and runtime isolation, and it slots into the wider Kubernetes scheduling world so you can pair **GPU sharing** with **batch scheduling, job queuing, and colocation**.

This page shows how HAMi works alongside the default scheduler and four ecosystem partners: **Volcano**, **Kueue**, **Koordinator**, and NVIDIA's **KAI Scheduler**.

```mermaid
%% title: HAMi Ecosystem Integrations
flowchart TB
WL["AI Workloads<br/>(inference · training · batch)"]

subgraph Schedulers["Scheduling & Queueing Ecosystem"]
direction LR
KS["kube-scheduler<br/>(native)"]
VOL["Volcano<br/>gang & batch"]
KUE["Kueue<br/>queueing & fairness"]
KOO["Koordinator<br/>device scheduling"]
KAI["KAI Scheduler<br/>(NVIDIA) AI batch"]
end

subgraph HAMi["HAMi"]
direction TB
HSCHED["hami-scheduler<br/>vGPU allocation · kube-scheduler extender"]
HDP["hami-device-plugin<br/>vGPU resources"]
CORE["HAMi-core<br/>runtime GPU isolation"]
end

HW["Heterogeneous Accelerators<br/>NVIDIA · AMD · Huawei Ascend · Cambricon · Hygon · Mthreads · Iluvatar · …"]

WL --> Schedulers
KS -->|"GPU filter / score"| HSCHED
HSCHED --> KS
KS --> HDP
HDP --> CORE
VOL -.->|"volcano-vgpu-device-plugin"| CORE
KOO -.->|"HAMi-core isolation"| CORE
KAI -.->|"kai-resource-isolator (HAMi-core)"| CORE
KUE -.->|"queues workloads over<br/>vGPU ResourceFlavors"| KS
CORE --> HW
```
![HAMi Ecosystem Integrations](/img/docs/en/core-concepts/ecosystem-integrations.svg#light-only) ![HAMi Ecosystem Integrations](/img/docs/en/core-concepts/ecosystem-integrations-dark.svg#dark-only)

## How HAMi integrates

Expand All @@ -66,7 +35,7 @@ Out of the box, `kube-scheduler` delegates GPU filtering and scoring to `hami-sc

### Kueue for job queuing and fairness

[Kueue](https://kueue.sigs.k8s.io/) sits above the default scheduler and manages job admission, fairness, and quotas through `ResourceFlavor` and `ClusterQueue`. HAMi's vGPU resources show up as schedulable flavors that Kueue can queue and admit. That gives you **cohort fairness and quota enforcement** on top of GPU sharing, all without replacing `kube-scheduler`.
[Kueue](https://kueue.sigs.k8s.io/) sits above the default scheduler and manages job admission, fairness, and quotas through `ResourceFlavor` and `ClusterQueue`. Kueue's `ResourceTransformation` multiplies `nvidia.com/gpumem` and `nvidia.com/gpucores` by the `nvidia.com/gpu` count, and the `ClusterQueue` sets quotas on the totals. That gives you **cohort fairness and quota enforcement** on top of GPU sharing, all without replacing `kube-scheduler`.

- Guide: [Using HAMi with Kueue](../userguide/kueue/how-to-use-kueue.md)
- Upstream integration doc: [Running HAMi workloads in Kueue](https://kueue.sigs.k8s.io/docs/tasks/run/using_hami/)
Expand All @@ -81,7 +50,7 @@ Out of the box, `kube-scheduler` delegates GPU filtering and scoring to `hami-sc

[KAI Scheduler](https://github.com/kai-scheduler/KAI-Scheduler) is NVIDIA's open-source, Kubernetes-native scheduler for AI workloads. It grew out of Run:ai, ships under Apache 2.0, and is a CNCF Sandbox project. It brings **PodGroup gang scheduling**, **hierarchical fair queues**, **fractional GPU sharing**, **topology-aware placement**, and **elastic workloads**. These are the things AI training needs that the default scheduler doesn't offer.

Here's the catch, though. KAI's fractional GPU sharing is _cooperative_: the scheduler keeps the sum of requests within a card, but it doesn't physically stop a Pod from using more memory than it asked for. A container that requests 2 GiB can still see the whole GPU through `nvidia-smi`. In a multi-tenant production cluster, that's the gap that bites you.
Here's the catch, though. KAI's default GPU sharing mode, `NonMemoryEnforced`, doesn't enforce memory at runtime: the scheduler keeps the sum of requests within a card, but it doesn't physically stop a Pod from using more memory than it asked for. A container that requests 2 GiB can still see the whole GPU through `nvidia-smi`. In a multi-tenant production cluster, that's the gap that bites you.

HAMi-core fills it. **KAI Scheduler does the scheduling, HAMi-core does the isolation.** The integration uses HAMi-core directly rather than the full HAMi platform, so KAI keeps its own scheduler. Turn on the `hamicore` plugin in KAI Scheduler to inject `CUDA_DEVICE_MEMORY_LIMIT`, then deploy [`kai-resource-isolator`](https://github.com/Project-HAMi/KAI-resource-isolator). It's a HAMi project component that ships HAMi-core to each node through a DaemonSet and uses a MutatingWebhook to inject the library and `ld.so.preload`. At runtime `libvgpu.so` enforces the memory cap, so `nvidia-smi` shows only the slice you allocated.

Expand Down
44 changes: 9 additions & 35 deletions docs/core-concepts/gpu-driver.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
---
title: "Understanding GPU Drivers"
description: How to check the NVIDIA driver and what each kernel module does.
sidebar_label: GPU drivers
---

Before using a GPU, you first need to verify that the GPU driver is properly loaded into the kernel. This document explains how to check GPU driver status and understand the architecture of NVIDIA kernel modules.

The driver is layer 2 of the [GPU software stack](./gpu-stack.md).

## Checking GPU Driver Status

Use the following command to check whether the NVIDIA kernel module is loaded:
Expand All @@ -28,52 +32,22 @@ Each line represents a loaded kernel module. The columns are: module name, memor

The NVIDIA driver consists of multiple kernel modules with dependencies between them:

```mermaid
%% title: NVIDIA Kernel Module Hierarchy
flowchart TB
subgraph LinuxKernel["Linux Kernel"]
NVIDIA["nvidia - Core GPU Driver"]
UVM["nvidia_uvm - Unified Virtual Memory"]
MODESET["nvidia_modeset - Display Mode Management"]
ECC["ecc - ECC Error Handling"]
MODESET --> NVIDIA
UVM --> NVIDIA
ECC --> NVIDIA
end
NVIDIA --> GPU["NVIDIA GPU"]
```
![NVIDIA driver modules and the path from user space to the GPU](/img/docs/en/core-concepts/gpu-driver.svg#light-only) ![NVIDIA driver modules and the path from user space to the GPU](/img/docs/en/core-concepts/gpu-driver-dark.svg#dark-only)

### Module Descriptions

| Module | File | Description |
| --- | --- | --- |
| **nvidia** | `nvidia.ko` | The core GPU driver module, responsible for GPU hardware initialization, video memory management, command queue scheduling, and other fundamental functions. All other NVIDIA modules depend on it. |
| **nvidia_uvm** | `nvidia_uvm.ko` | Unified Virtual Memory, enabling CPU and GPU to share the same address space. CUDA programs using `cudaMallocManaged` depend on this module, which automatically migrates data between CPU and GPU. |
| **nvidia_modeset** | `nvidia_modeset.ko` | Display mode setting module, responsible for managing display output (resolution, refresh rate, etc.). Depends on `nvidia_drm` (DRM subsystem interface) to function. |
| **ecc** | `ecc.ko` | ECC (Error-Correcting Code) error handling module, used for memory error detection and correction on data center GPUs (such as A100, H100). Consumer-grade GPUs typically do not load this module. |
| **nvidia_uvm** | `nvidia-uvm.ko` | Unified Virtual Memory, enabling CPU and GPU to share the same address space. CUDA programs using `cudaMallocManaged` depend on this module, which automatically migrates data between CPU and GPU. |
| **nvidia_modeset** | `nvidia-modeset.ko` | Display mode setting module, responsible for managing display output (resolution, refresh rate, etc.). `nvidia_drm` depends on it. |
| **nvidia_drm** | `nvidia-drm.ko` | DRM subsystem interface, connecting the driver to the Linux Direct Rendering Manager. |
| **ecc** | `ecc.ko` | A general Linux kernel module. It is not part of the NVIDIA driver. |

## Linux Driver Architecture

GPU drivers follow the standard Linux layered architecture: user space communicates with kernel space modules through libraries, which ultimately operate the hardware.

```mermaid
%% title: Linux GPU Driver Architecture
flowchart TB
subgraph User["User Space"]
CLI["CLI Tools (nvidia-smi)"]
Lib["User-Space Library (libnvidia-ml.so)"]
end
subgraph Kernel["Kernel Space"]
Module["Kernel Module (nvidia.ko)"]
end
subgraph Hardware["Hardware"]
HW["GPU Device"]
end
CLI --> Lib
Lib --> Module
Module --> HW
```

Call chain:

1. User runs a CLI tool such as `nvidia-smi`
Expand Down
Loading
Loading