콘텐츠로 이동

DRA로 NPU 할당 조건 지정하기

DRA의 요청 수량, CEL 셀렉터, PCIe 토폴로지 제약으로 할당할 NPU를 선택합니다. 기본 요청과 확인 절차는 DRA로 NPU 요청하기에서 확인할 수 있습니다.

이 튜토리얼은 DRA 구성을 기준으로 합니다. Operator가 아직 설치되어 있지 않다면 먼저 NPU Operator 설치 절차를 진행합니다.

1. 장치 속성 확인하기

제품명·PCIe 루트·UUID는 노드마다 다릅니다. 먼저 실제 디바이스 속성과 값을 확인합니다. 속성별 설명은 NPU 속성에서 확인할 수 있습니다.

kubectl get resourceslices
kubectl describe resourceslice <NAME>

2. 요청 조건 지정하기

원하는 예제를 실행합니다.

NPU 2개 요청하기

exactly.count를 2로 설정합니다. 같은 노드에 할당 가능한 NPU가 2개 이상 있어야 합니다.

export DRA_POD=dra-two-npus
kubectl create namespace npu-tutorial --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f - <<'EOF'
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: dra-two-npus
  namespace: npu-tutorial
spec:
  spec:
    devices:
      requests:
      - name: npu
        exactly:
          deviceClassName: npu.rebellions.ai
          count: 2
---
apiVersion: v1
kind: Pod
metadata:
  name: dra-two-npus
  namespace: npu-tutorial
spec:
  containers:
  - name: ubuntu
    image: ubuntu:22.04
    command: ["sleep", "infinity"]
    resources:
      claims:
      - name: npu
  resourceClaims:
  - name: npu
    resourceClaimTemplateName: dra-two-npus
EOF

제품명으로 NPU 선택하기

exactly.selectors에 제품명을 지정해 NPU 1개를 요청합니다.

export DRA_POD=dra-rebel100
kubectl create namespace npu-tutorial --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f - <<'EOF'
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: dra-rebel100
  namespace: npu-tutorial
spec:
  spec:
    devices:
      requests:
      - name: npu
        exactly:
          deviceClassName: npu.rebellions.ai
          count: 1
          selectors:
          - cel:
              expression: device.attributes["npu.rebellions.ai"].productName == "RBLN-CR13"
---
apiVersion: v1
kind: Pod
metadata:
  name: dra-rebel100
  namespace: npu-tutorial
spec:
  containers:
  - name: ubuntu
    image: ubuntu:22.04
    command: ["sleep", "infinity"]
    resources:
      claims:
      - name: npu
  resourceClaims:
  - name: npu
    resourceClaimTemplateName: dra-rebel100
EOF
export DRA_POD=dra-atom
kubectl create namespace npu-tutorial --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f - <<'EOF'
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: dra-atom
  namespace: npu-tutorial
spec:
  spec:
    devices:
      requests:
      - name: npu
        exactly:
          deviceClassName: npu.rebellions.ai
          count: 1
          selectors:
          - cel:
              expression: device.attributes["npu.rebellions.ai"].productName == "RBLN-CA25"
---
apiVersion: v1
kind: Pod
metadata:
  name: dra-atom
  namespace: npu-tutorial
spec:
  containers:
  - name: ubuntu
    image: ubuntu:22.04
    command: ["sleep", "infinity"]
    resources:
      claims:
      - name: npu
  resourceClaims:
  - name: npu
    resourceClaimTemplateName: dra-atom
EOF

같은 PCIe 루트의 NPU 요청하기

devices.constraints의 matchAttribute로 같은 PCIe 루트 컴플렉스에 연결된 NPU 2개를 요청합니다.

RBLN-CA25는 카드당 NPU 칩 4개를 포함합니다. 루트 컴플렉스 하나에 여러 카드가 연결될 수 있으므로 같은 PCIe 루트라는 조건이 같은 카드를 보장하지는 않습니다.

export DRA_POD=dra-pcie-root
kubectl create namespace npu-tutorial --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f - <<'EOF'
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: dra-pcie-root
  namespace: npu-tutorial
spec:
  spec:
    devices:
      requests:
      - name: npu
        exactly:
          deviceClassName: npu.rebellions.ai
          count: 2
      constraints:
      - requests: ["npu"]
        matchAttribute: resource.kubernetes.io/pcieRoot
---
apiVersion: v1
kind: Pod
metadata:
  name: dra-pcie-root
  namespace: npu-tutorial
spec:
  containers:
  - name: ubuntu
    image: ubuntu:22.04
    command: ["sleep", "infinity"]
    resources:
      claims:
      - name: npu
  resourceClaims:
  - name: npu
    resourceClaimTemplateName: dra-pcie-root
EOF

UUID로 NPU 선택하기

특정 NPU를 요청하려면 uuid 속성을 사용합니다. 예제 UUID를 실제 ResourceSlice의 값으로 바꿉니다. rbln-smi -L 출력에서 가져온 UUID라면 NPU- 접두사를 제외합니다.

export DRA_POD=dra-uuid
kubectl create namespace npu-tutorial --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f - <<'EOF'
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: dra-uuid
  namespace: npu-tutorial
spec:
  spec:
    devices:
      requests:
      - name: npu
        exactly:
          deviceClassName: npu.rebellions.ai
          count: 1
          selectors:
          - cel:
              expression: device.attributes["npu.rebellions.ai"].uuid == "34428712-d887-840b-a7b9-1c9e05807fc3"
---
apiVersion: v1
kind: Pod
metadata:
  name: dra-uuid
  namespace: npu-tutorial
spec:
  containers:
  - name: ubuntu
    image: ubuntu:22.04
    command: ["sleep", "infinity"]
    resources:
      claims:
      - name: npu
  resourceClaims:
  - name: npu
    resourceClaimTemplateName: dra-uuid
EOF

3. 할당 결과 확인하기

선택한 예제의 Pod($DRA_POD)가 Ready 상태가 될 때까지 기다립니다.

kubectl wait -n npu-tutorial --for=condition=Ready "pod/$DRA_POD" --timeout=180s

Claim 할당 결과와 컨테이너 안의 NPU를 확인합니다.

1
2
3
4
5
CLAIM=$(kubectl get pod -n npu-tutorial "$DRA_POD" -o jsonpath='{.status.resourceClaimStatuses[0].resourceClaimName}')
kubectl get resourceclaim -n npu-tutorial "$CLAIM" \
  -o json | \
  jq '.status.allocation.devices.results | map({driver, pool, device})'
kubectl exec -n npu-tutorial "$DRA_POD" -- rbln-smi -L

선택한 예제에 따라 다음 조건을 확인합니다.

예제 확인할 결과
NPU 2개 요청 Claim 할당 결과와 rbln-smi -L에 장치가 각각 2개 표시됨
제품명 선택 NPU 1개가 할당되고 rbln-smi -L의 제품명이 지정한 값과 일치함
같은 PCIe 루트 NPU 2개가 할당되고 해당 장치들의 ResourceSlice에서 resource.kubernetes.io/pcieRoot 값이 같음
UUID 선택 NPU 1개가 할당되고 rbln-smi -L의 UUID에서 NPU- 접두사를 제외한 값이 지정한 UUID와 일치함

정리

선택한 예제의 Pod와 ResourceClaimTemplate을 삭제합니다. 생성된 Claim도 자동으로 삭제됩니다. 다른 예제를 실행하기 전에 사용한 NPU를 반환해야 합니다.

kubectl delete pod -n npu-tutorial "$DRA_POD"
kubectl delete resourceclaimtemplate -n npu-tutorial "$DRA_POD"