콘텐츠로 이동

RBLN NPU DRA 드라이버

개요

RBLN NPU DRA 드라이버는 Kubernetes의 Dynamic Resource Allocation(DRA) 프레임워크를 통해 RBLN NPU를 사용할 수 있도록 합니다.

Kubernetes Device Plugin이 디바이스를 노드의 고정된 리소스로 노출하는 방식과 달리, DRA는 워크로드가 제품 타입, NUMA 위치, PCIe 토폴로지 등의 조건에 따라 디바이스를 동적으로 요청할 수 있도록 합니다.

이는 Kubernetes Resource API (resource.k8s.io) 오브젝트를 통해 디바이스 인벤토리와 선택 조건을 표현함으로써 이루어집니다.

그 결과, 복잡한 환경에서도 NPU를 보다 유연하고 정밀하게 스케줄링할 수 있습니다.

주요 기능

  • ResourceSlice를 통해 노드 단위 NPU 디바이스 인벤토리 노출
  • DeviceClass를 사용하여 디바이스 타입 및 선택 조건 정의
  • ResourceClaim (Template)로 파드가 요청하는 디바이스 개수와 조건을 선언
  • CEL 표현식(selectors.cel.expression)을 사용하여 제품명, NUMA, PCIe 토폴로지, UUID 등의 속성 기반 디바이스 선택 지원

권장: DRA 드라이버를 사용한다면 쿠버네티스 디바이스 플러그인(Device Plugin)비활성화하는 것을 권장합니다. (중복 노출 및 디버깅 혼란 방지)


배포

NPU DRA 드라이버는 보통 RBLN NPU Operator를 통해 배포하는 것을 권장합니다.

Operator가 이미 설치되어 있고 (버전 v0.3.0 이상), Helm values에서 DRA 모드를 활성화할 수 있습니다.

1단계. 사전 준비

  • Kubernetes v1.34.0 이상
  • RBLN NPU Operator 버전 v0.3.0 이상
  • RBLN Container Toolkit 활성화 (CDI 기반 장치 주입 준비)

2단계. DRA 모드 활성화

아래 예시처럼 draKubeletPlugin.enabled=true로 설정하고, 기존 Device Plugin은 비활성화합니다.

NPU DRA 드라이버와 Kubernetes Device Plugin은 동시에 사용할 수 없습니다. 이 경우 디바이스가 중복으로 노출되어 예측할 수 없는 동작이 발생할 수 있습니다.

기존에 Device Plugin을 사용 중이라면, NPU DRA 드라이버를 활성화하기 전에 먼저 비활성화해야 합니다.

1
2
3
4
5
6
# values-dra.yaml
draKubeletPlugin:
  enabled: true

devicePlugin:
  enabled: false

3단계. Operator 업그레이드

1
2
3
helm upgrade <release-name> rebellions/rbln-npu-operator \
  -n <namespace> \
  -f values-dra.yaml

설치 확인

DRA 모드가 정상적으로 활성화 되었다면, 클러스터에 다음 오브젝트들이 생성/갱신됩니다.

  • DeviceClass (예: npu.rebellions.ai)
  • ResourceSlice (노드별 NPU 인벤토리)
  • 워크로드가 요청하면 ResourceClaim (또는 Template 기반 Claim)

ResourceSlice 확인

kubectl get resourceslices -A

특정 ResourceSlice를 자세히 보기 위해서는 다음 명령어를 사용합니다.

kubectl describe resourceslice <name> -n <namespace>

팁: selector (CEL)를 작성할 때는 kubectl describe resourceslice ... 출력에서 device.attributes["npu.rebellions.ai"].... 형태의 키/구조를 먼저 확인하는 것이 가장 안전합니다.


핵심 리소스 모델

DRA 기반 워크로드는 보통 아래 흐름으로 구성됩니다.

  1. DeviceClass: 어떤 디바이스를 사용할 것인지를 정의 (기본: npu.rebellions.ai)
  2. ResourceSlice: 노드가 가진 디바이스 목록과 속성(attributes)을 노출합니다.
  3. ResourceClaim: 파드가 요청하는 디바이스를 선언합니다.
  4. Pod: resources.claimsResourceClaim을 소비합니다.

NPU 속성 (ResourceSlice attributes)

RBLN NPU의 ResourceSlice는 각 노드별로 배포되며, 하나의 디바이스는 다음과 같은 속성(attributes)를 제공합니다.

이러한 속성은 selector 표현식(selectors.cel.expression)에서 사용되어, 워크로드에 할당될 디바이스를 선택하고 결정하는 데 활용됩니다.

이름 타입 예시 값 설명
driverVersion string 3.0.0 설치된 NPU 드라이버 버전
firmwareVersion string 3.0.0 디바이스 펌웨어 버전
pciDeviceID string 0x1250 PCI Device ID
pciLinkSpeed string 32.0GT/s PCIe 링크 속도
pciLinkWidth string 16 PCIe 링크 레인 수
productName string RBLN-CA25 NPU 제품명
sid string 0000000022527010 카드/보드 식별자
type string npu 디바이스 유형
uuid string 55668c63-d739-4193-8212-ad7ba933520c 디바이스 고유 식별자
resource.kubernetes.io/numaNode int 0 디바이스가 연결된 NUMA 노드
resource.kubernetes.io/pciBusID string 0000:46:00.0 PCI Bus 주소
resource.kubernetes.io/pcieRoot string 0000:00:00.0 PCIe Root 주소

빠른 시작

아래 예시는 ResourceClaimTemplate + Pod 패턴으로 NPU를 할당하는 가장 단순한 형태입니다.

1) 2개의 RBLN NPU를 할당하는 Pod 배포

다수의 리소스를 요청하기 위해서는 exactly.count를 사용합니다.

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: double-npu
spec:
  spec:
    devices:
      requests:
      - name: npus
        exactly:
          deviceClassName: npu.rebellions.ai
          count: 2
---
apiVersion: v1
kind: Pod
metadata:
  name: pod0
spec:
  containers:
  - name: ctr0
    image: ubuntu:22.04
    command: ["bash", "-c"]
    args: ["trap 'exit 0' TERM; sleep 9999 & wait"]
    resources:
      claims:
      - name: npus
  resourceClaims:
  - name: npus
    resourceClaimTemplateName: double-npu

적용:

1
2
3
kubectl apply -f double-npu.yaml
kubectl get pod pod0
kubectl describe pod pod0

2) RBLN-CA25 NPU를 1개 할당하는 Pod 배포

ResourceSlice의 속성을 기반으로 리소스를 선택하기 위해서는 selectors(CEL)를 사용합니다.

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: single-npu
spec:
  spec:
    devices:
      requests:
      - name: npus
        exactly:
          deviceClassName: npu.rebellions.ai
          count: 1
          selectors:
          - cel:
              expression: device.attributes["npu.rebellions.ai"].productName == "RBLN-CA25"
---
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: ctr0
    image: ubuntu:22.04
    command: ["bash", "-c"]
    args: ["trap 'exit 0' TERM; sleep 9999 & wait"]
    resources:
      claims:
      - name: npus
  resourceClaims:
  - name: npus
    resourceClaimTemplateName: single-npu

적용:

1
2
3
kubectl apply -f single-npu.yaml
kubectl get pod pod1
kubectl describe pod pod1

예제: 자주 쓰는 selector/constraints 패턴

PCI Bus ID로 같은 카드에서 선택

RBLN-CA25는 카드당 4개의 NPU 칩을 포함합니다. 서로 다른 카드에 걸쳐 NPU를 할당할 경우 성능 저하가 발생할 수 있으므로, 최적의 성능을 위해 가능한 한 동일한 카드의 NPU를 할당해야 합니다.

1
2
3
constraints:
- requests: ["npus"]
  matchAttribute: resource.kubernetes.io/pcieRoot

UUID로 단일 디바이스 고정

1
2
3
selectors:
- cel:
    expression: device.attributes["npu.rebellions.ai"].uuid == "55668c63-d739-4193-8212-ad7ba933520c"