콘텐츠로 이동

디바이스 할당

목표: Pod 하나가 NPU와 RoCE NIC을 같은 NUMA 노드에서 함께 할당받도록 구성합니다. 레퍼런스 구성은 Pod당 NPU 4개와 NIC 2개를 사용합니다. Dynamic Resource Allocation(DRA) 모드에서는 적용한 ResourceClaimTemplate(이하 RCT)가 NPU 수와 NIC 수를 정합니다.

RCT는 네임스페이스 범위 리소스이므로 스택이 사용할 네임스페이스를 먼저 생성하세요. 클러스터 기반 구성의 Secret과 모델 저장소도 같은 네임스페이스에 생성합니다.

kubectl create namespace <ns>

레퍼런스 구성은 DRA로 NPU와 RoCE NIC을 할당합니다. DRA에서는 RCT로 NPU와 NIC을 같은 NUMA 노드에서 함께 할당하도록 요구할 수 있기 때문입니다. 디바이스 플러그인과의 비교는 Rebel100™ 기반 Coding Assistant › 설계 대안을 참고하세요.

DRA의 일반적인 개념과 API는 Kubernetes Dynamic Resource Allocation 문서를 참고하세요. 이 문서에서는 이 스택이 사용하는 DRA 관련 Kubernetes 리소스와 각 리소스를 만드는 주체만 다룹니다.

스케줄러는 다음 리소스를 보고 Pod에 디바이스를 할당합니다. DeviceClass, ResourceSlice, RCT 중 하나라도 없으면 Pod는 Pending 상태로 남습니다. Pod의 spec.resourceClaims는 차트가 설치할 때 작성합니다. Kubernetes는 RCT로 Pod마다 ResourceClaim을 만들고, 스케줄러는 할당한 디바이스를 그 ResourceClaim에 기록합니다.

계층 리소스 만드는 주체 시점
1 DeviceClass(npu.rebellions.ai, dranet) RBLN NPU Operator, dranet 노드 준비
2 ResourceSlice(노드별 디바이스 목록) RBLN NPU Operator, dranet 노드 준비
3 ResourceClaimTemplate npu-rdma(워크로드의 요청) 사용자 설치 전
4 Pod의 spec.resourceClaims(Pod가 RCT를 참조하는 항목) 차트(helm install) 설치

레퍼런스 구성은 같은 NUMA 노드에 속한 NPU와 RoCE NIC을 Pod에 할당합니다. KV 전송이 다른 NUMA 노드를 거치지 않게 하기 위해서입니다. numa-aligned RCT의 matchAttribute: resource.kubernetes.io/numaNode 제약 조건이 같은 NUMA 노드 할당을 구현합니다. 레퍼런스 아키텍처의 서버 노드에는 NUMA 노드가 2개 있고, NUMA 노드마다 NPU가 4개 있습니다. 따라서 NPU 4개를 쓰는 Pod는 서버 노드 하나에 최대 2개까지 배치됩니다.

npu-rdma용 ResourceClaimTemplate

이 리소스는 사용자가 생성합니다. 차트는 RCT를 만들지 않고 이름(devices.claimTemplateName)으로만 참조합니다.

레퍼런스 구성은 차트의 examples/manifests/rct/numa-aligned.yaml을 사용합니다. numa-aligned.yaml은 Pod마다 같은 NUMA 노드의 NPU 4개와 NIC 2개를 요청합니다. numa-aligned.yaml은 두 NIC이 서로 다른 물리 NIC에 속하도록, 즉 resource.kubernetes.io/pcieRoot 값이 서로 다르도록 요구합니다. RBLN NPU DRA 드라이버와 dranet(v1.5.0 이상)이 모두 resource.kubernetes.io/numaNode를 게시해야 합니다. dranet은 resource.kubernetes.io/pcieRoot도 게시해야 합니다. Kubernetes 1.34와 1.35에서는 kube-apiserver, kube-scheduler, kubelet에서 DRAConsumableCapacity feature gate를 활성화하세요.

kubectl -n <ns> apply -f examples/manifests/rct/numa-aligned.yaml

레퍼런스 구성과 다른 클러스터에서는 다음과 같이 RCT를 적용하거나 수정하세요.

  • 드라이버가 resource.kubernetes.io/numaNode를 게시하지 않거나 dranet이 resource.kubernetes.io/pcieRoot를 게시하지 않는 경우: examples/manifests/rct/numa-unaligned.yaml
  • NIC 없이 AGG로 설치하는 경우: examples/manifests/rct/npu-only.yaml. devices.rdma.enabled=false와 devices.claimTemplateName=npu-only도 함께 설정하세요.
  • 차트에 레시피가 있는 모델: 그 레시피의 examples/models/<model>/rct-*.yaml
  • 레퍼런스 노드의 Broadcom NIC과 다른 backend NIC을 쓰는 경우: RCT의 NIC 셀렉터에서 pciSubsystem == "9140" 조건을 그 NIC에 맞게 수정하거나 삭제

디바이스 할당 확인

스케줄러가 RCT가 요청하는 디바이스를 할당할 수 있는지 확인하세요. 항목(5)는 설치 전에 확인하세요(항목(5) 속성 비교 참고).

# 확인 항목 기대 결과
1 두 DeviceClass 존재 여부 npu.rebellions.ai와 dranet이 목록에 표시됩니다
2 NPU 노드별, 드라이버별 ResourceSlice 게시 여부 모든 NPU 노드에 드라이버가 npu.rebellions.ai인 ResourceSlice(NPU 디바이스)와 dra.net인 ResourceSlice(NIC 디바이스)가 있습니다
3 스택 네임스페이스의 RCT npu-rdma 존재 여부 npu-rdma가 목록에 표시됩니다
4 prefill Pod와 decode Pod의 ResourceClaim 할당 여부(스택 설치 후) 각 ResourceClaim의 STATE에 allocated가 표시됩니다
5 RCT가 요구하는 속성의 실제 게시 여부 필요한 모든 키가 게시된 목록에 있습니다
# (1) 두 DeviceClass를 확인합니다.
kubectl get deviceclasses

# (2) 노드마다 드라이버별 ResourceSlice(NPU, NIC)를 확인합니다.
kubectl get resourceslices
kubectl get resourceslices -o wide | head

# (3) RCT가 있는지 확인합니다.
kubectl -n <ns> get resourceclaimtemplate npu-rdma

# (4) 스택 설치 후 실제 할당을 확인합니다.
kubectl -n <ns> get resourceclaims

레퍼런스 구성의 RCT(numa-aligned.yaml)는 RDMA를 쓸 수 있는 NIC(dra.net/rdma가 true인 NIC)만 요청합니다. dranet은 NIC 벤더의 RDMA 드라이버가 로드되어 있을 때 dra.net/rdma를 true로 게시합니다. 레퍼런스 노드의 Broadcom NIC은 RDMA 드라이버로 bnxt_re를 사용합니다. 각 노드에서 RDMA 드라이버가 NIC을 인식했는지 확인하세요.

ls /sys/class/infiniband/    # RDMA를 쓸 NIC마다 항목이 보여야 합니다. 레퍼런스 노드에서는 bnxt_re0, bnxt_re1처럼 표시됩니다.

같은 ls /sys/class/infiniband/ 확인을 modelserver 컨테이너 안에서도 실행하세요. Pod 안의 /sys/class/infiniband/에는 해당 Pod에 할당된 NIC만 표시됩니다.

kubectl -n <ns> exec <modelserver-pod> -c modelserver -- sh -c 'ls /sys/class/infiniband/'

항목(5) 속성 비교

RCT가 요구하는 속성을 클러스터가 모두 게시하는지 비교하세요. 속성이 하나라도 없으면 Pod는 cannot allocate all claims 이벤트와 함께 Pending 상태로 남습니다. cannot allocate all claims 이벤트는 어떤 속성이 빠졌는지 알려 주지 않습니다.

1
2
3
4
5
6
7
# (a) RCT가 요구하는 속성: selectors의 CEL 표현식과 constraints의 matchAttribute 및 distinctAttribute
kubectl -n <ns> get resourceclaimtemplate npu-rdma -o yaml \
  | grep -nE 'device\.attributes|matchAttribute|distinctAttribute'

# (b) 클러스터가 드라이버별로 게시하는 속성
kubectl get resourceslices -o json | jq '.items[]
  | {driver: .spec.driver, attrs: (.spec.devices[0].attributes | keys)}'

(a)의 모든 키가 (b)의 해당 드라이버 목록에 있어야 합니다. resource.kubernetes.io/numaNode나 resource.kubernetes.io/pcieRoot가 없으면 npu-rdma RCT를 삭제한 뒤 numa-unaligned.yaml을 적용하세요. Kubernetes는 기존 RCT의 spec을 바꾸는 apply를 거부합니다. NIC 셀렉터의 dra.net 속성이 없으면 NIC 셀렉터를 수정하세요. numa-unaligned.yaml의 NIC 셀렉터는 numa-aligned.yaml과 같습니다.

주요 디바이스 설정

다음 차트 values를 RCT에 맞춰 설정하세요.

키 설명 기본값
devices.npu.count 차트가 선언하는 Pod당 NPU 수. 차트는 렌더링할 때 devices.npu.count를 data parallel, tensor parallel, pipeline parallel 크기의 곱과 비교합니다. devices.npu.count를 RCT의 NPU count와 같은 값으로 설정하세요 4
devices.claimTemplateName Pod가 참조하는 RCT 이름 npu-rdma

RDS 노드 레이블은 노드 준비 › RDS 설정을 참고하세요.

디바이스 플러그인 모드

DRA를 쓸 수 없는 클러스터에서는 다음 values로 차트를 디바이스 플러그인 모드로 설치하세요. 디바이스 플러그인 모드는 RCT를 쓰지 않고 NUMA 정렬을 보장하지 않습니다. 디바이스 플러그인 모드는 Unverified입니다.

1
2
3
4
5
6
7
8
devices:
  npu:
    mode: devicePlugin
    count: 4
  rdma:
    mode: devicePlugin
    resourceName: <rdma-resource-name>  # 클러스터의 RDMA extended resource 이름(예: rdma/hca)
    count: 2