콘텐츠로 이동

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 등의 속성 기반 디바이스 선택 지원

Tip

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>

Tip

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 패턴

PCIe Root 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"

로깅

kubelet 플러그인과 웹훅은 각각 구조화된 로그를 stdout에 출력합니다. 다음 환경 변수로 로그 레벨과 출력 형식을 설정합니다.

변수 설명 기본값
RBLN_DRA_DRIVER_LOG_LEVEL 로그 상세도: error, warning(또는 warn), info, debug, trace. info
RBLN_DRA_DRIVER_LOG_FORMAT 출력 형식: json 또는 text. json

같은 로그 레벨이 Kubernetes 라이브러리 로그에도 적용됩니다. trace는 gRPC와 admission 페이로드까지 덤프하므로 운영 환경에서는 사용하지 마세요. 잘못된 값을 지정하면 기본값으로 되돌아가면서 경고를 남깁니다.

NPU 유저스페이스 라이브러리는 자체 텍스트 형식 레코드 일부를 stderr에 출력합니다. 이 레코드는 위 변수의 영향을 받지 않으므로 json을 설정해도 텍스트 형식으로 출력됩니다.

RBLN NPU Operator로 배포한 경우 차트의 draKubeletPlugin.logging 값으로 설정하세요. 컴포넌트 로깅을 참고하세요.