먼저 짚을 점
유스케이스 순서는 공개 자료(벤더 백서, 업계 사례)와 일반적인 도입 패턴을 바탕으로 한 저의 판단입니다. 업계 공인 통계는 아닙니다. 클러스터 배치는 그 위에 제가 설계한 안입니다.
전체 구조와 역할
| 클러스터 | 구성 요소 |
|---|
| Storage | MinIO AIStor (Iceberg 데이터/메타 파일, 원본 FDC·STDF·이미지), Polaris(+Postgres) |
| Compute-Batch | Spark, Airflow 워커 |
| Compute-Interactive | Trino, StarRocks, Superset, JupyterLab |
| GPU | 학습/추론, Spark RAPIDS, GPU 노트북 |
- Compute를 배치와 인터랙티브로 나누면, Spark 폭주가 대시보드 지연으로 번지지 않습니다.
- 카탈로그 주의: AIStor는 Iceberg REST 카탈로그를 자체 내장하고 있어 Polaris와 기능이 겹칩니다. 카탈로그 권한자는 하나만 두세요. Polaris를 쓴다면 AIStor는 S3 저장소로만 쓰는 것이 단순합니다. Polaris는 Spark, Flink, Trino, StarRocks가 하나의 Iceberg 데이터를 동시에 질의하게 해줍니다.
유스케이스 (실제 빈도 순)
① 수율 분석 / 근본 원인 분석(RCA)
챔버 압력, RF 파워, 가스비 같은 설비 파라미터를 수천 웨이퍼의 결함 시그니처와 상관 분석하는 것이 대표적입니다.
- 배치: Spark(조인/피처 생성) → Iceberg → StarRocks/Trino → Superset/Jupyter
- 멀티클러스터: 무거운 조인은 Batch, 반복 조회는 Interactive로 분리. 스토리지는 한 곳에서 공유하므로 데이터 복사가 없습니다.
② 설비 센서(FDC) 트레이스 수집·분석
FDC 트레이스는 웨이퍼 가공 중 챔버/설비 거동을 담은 시계열이며 수율, E-test와 상관이 큽니다.
- 배치: 수집/정제는 Batch(Spark), 조회는 Interactive. 원본 파일은 AIStor.
- 멀티클러스터: 쓰기 폭주(Batch→AIStor)와 읽기(Interactive→AIStor)의 경로를 분리해 격리. 파티션/컴팩션 잡은 Batch에서 야간 실행.
③ BI 대시보드 / SPC·OEE 모니터링
- 배치: StarRocks + Superset (Interactive)
- 멀티클러스터: StarRocks는 Iceberg 카탈로그 기반 머티리얼라이즈드 뷰를 지원하고 파티션 단위 증분 갱신을 감지하므로, 자주 쓰는 집계를 MV로 만들어 스토리지 왕복을 줄입니다. 로컬 캐시가 적중하면 컴퓨트-스토리지 분리 구조도 일체형과 같은 성능이므로 CN 노드의 NVMe 캐시를 크게 잡으세요.
④ Lot/Wafer 이력·계보(Genealogy) 조회
웨이퍼 추적성과 공정 단계 전체의 계보 관리가 대표 사례입니다.
- 배치: Trino/StarRocks 포인트 조회. 카탈로그는 Polaris.
- 멀티클러스터: Iceberg 타임트래블로 감사 이력 확보. 사이트 간 이력 조회는 아래 "페더레이션" 참고.
⑤ ETL/ELT 파이프라인 + 데이터 품질
설비 식별자가 시스템마다 일치하지 않는 것이 현실이라, 공통 데이터 모델과 정규화가 선행됩니다.
- 배치: Airflow(Batch 또는 관리용) → Spark. 품질 검증, 컴팩션, 스냅샷 정리.
- 멀티클러스터: Airflow가 클러스터별 연결(kubeconfig)로 Batch/GPU에 잡을 제출. YuniKorn은 Spark on K8s의 배치 스케줄링을 개선하고, 갱 스케줄링으로 자원 분절을 줄입니다.
⑥ 테스트 데이터(E-test, CP/FT, STDF) 분석
- 배치: 파서/적재는 Spark, 분석은 StarRocks. 결과를 ①의 FDC/결함 데이터와 조인.
- 멀티클러스터: 원본 대용량 파일은 AIStor에, 파싱 결과만 Iceberg로.
⑦ 엔지니어 Ad-hoc 탐색
- 배치: JupyterLab(Interactive) → Trino/Spark Connect
- 멀티클러스터: 무거운 쿼리는 Spark Connect로 Batch에 위임. GPU가 필요하면 GPU 클러스터의 노트북 이미지로 분리.
⑧ 웨이퍼 맵 패턴 분류 / 공간 시그니처
시스템적 웨이퍼 맵 패턴을 ML로 자동 검출·분류하고 공간 상관을 분석합니다.
- 배치: 데이터 준비는 Batch, 학습/추론은 GPU.
- 멀티클러스터: GPU가 AIStor에서 직접 읽도록 하고 결과 라벨은 Iceberg로 되돌려 쓰기. 학습 잡은 Kueue(사이트 간은 MultiKueue)로 관리.
⑨ 결함 이미지(SEM/광학 검사) 학습·추론
이미지 기반 유스케이스는 팹의 변화로 데이터 드리프트가 생겨 재학습이 필요합니다.
- 배치: 이미지는 AIStor 객체, 메타데이터는 Iceberg. GPU에서 학습/배치 추론.
- 멀티클러스터: 재학습 파이프라인(Airflow → GPU 잡)을 자동화하고, GPU↔AIStor 대역폭을 Cilium BGP/ECMP로 확보.
⑩ 가상 계측(VM) / 디지털 트윈 / 예측 모델
- 배치: 피처는 Spark, 학습은 GPU 또는 Batch, 서빙은 용도에 따라 선택.
- 멀티클러스터: 피처와 모델을 같은 Iceberg/AIStor 기준으로 버전 관리.
⑪ 예지보전(PdM)
- 배치: 스트리밍 피처(Batch) + 모델 추론.
- 멀티클러스터: 알람 지연이 중요하므로 사이트 내에서만 처리.
⑫ 설비/챔버 commonality 분석
Lot/Wafer 이력 데이터로 수율을 제약하는 설비·챔버를 식별합니다. ①과 같은 구조이며 MV로 가속합니다.
⑬ 공급망·자재·재고 분석: Trino로 외부 DB와 Iceberg를 페더레이션 조회. Interactive 클러스터에서 처리.
⑭ Fab→Package→Final test 통합 분석
2026년 이후 트렌드는 팹, 테스트, 어셈블리 데이터를 통합해 웨이퍼부터 패키지까지 상관 분석하는 것입니다. 사이트가 다르면 사이트 간 페더레이션이 필요합니다.
⑮ 외부(장비사·고객) 데이터 공유
장비 공급사가 수율 문제 디버깅에 공정 데이터를 필요로 하지만, 고객 할당 데이터는 민감합니다. Polaris RBAC과 별도 뷰로 제한하고, AIStor의 Delta Sharing 기반 테이블 공유도 후보입니다.
⑯ 공정 문서/로그 LLM·RAG: GPU 클러스터에서 추론, 벡터 인덱스는 별도. 신규 영역이라 우선순위는 낮습니다.
멀티클러스터를 잘 쓰는 공통 패턴
- 데이터 중력: 모든 대용량 읽기는 Storage 클러스터로 갑니다. Cilium native + BGP이므로 Pod IP가 그대로 라우팅되어 오버레이 오버헤드가 없습니다. AIStor 엔드포인트는 BGP로 광고하는 LB IP로 노출하고 ECMP로 분산하세요.
- 네트워크 정책 분리: Compute/GPU → AIStor(S3 포트), Polaris(REST 포트)만 허용하는 CiliumNetworkPolicy를 클러스터 간에 적용하세요.
- Polaris는 글로벌 서비스로 노출하되 로컬 우선 어피니티를 쓰세요. 엔진별로 자격증명을 분리하고, StarRocks는 OAuth2와 vended credentials 설정을 지원합니다. MinIO와의 vended credentials 동작은 PoC에서 확인하세요(일반 권고).
- 스케줄링 이원화: Spark는 Batch 안에서 YuniKorn, GPU는 Kueue(+MultiKueue). 오케스트레이션은 Airflow가 담당합니다.
- StarRocks CN은 상태가 없으므로 K8s 오퍼레이터로 배포해 독립적으로 스케일하세요.
사이트 간 데이터 페더레이션 (일반 설계 지식)
- Iceberg 메타데이터에는 절대 경로가 들어 있어, 버킷만 복제하면 카탈로그가 깨질 수 있습니다. 복제 시 경로 재작성(Spark
rewrite_table_path 프로시저 등)이 필요한지 버전 문서로 확인하세요.
- 현실적인 전략은 원본/상세는 사이트 로컬 유지(데이터 중력, 수출통제·데이터 레지던시 이슈 CHIPS Act 데이터 거주 요건, EAR/ITAR)하고, 요약/골드 테이블만 사이트 간 비동기 복제하는 것입니다.
- 사이트 간 조회가 필요하면 상대 사이트의 Polaris를 Trino 카탈로그로 추가해 집계 결과만 가져오는 방식이 대역폭을 아낍니다.
도입 순서
- Storage + Polaris + Compute-Interactive(StarRocks/Trino)로 ①③ 먼저
- Batch + Airflow로 ②⑤⑥
- GPU + Kueue로 ⑧⑨⑩
- 사이트 간 요약 테이블 복제
이 내용을 정리된 문서(Word/Markdown)로 만들어 드릴까요?
===
결론: GPU가 필요한 "단계"만 원격 GPU로 보냅니다
워크플로(Airflow DAG, 노트북, Spark 파이프라인)는 compute 클러스터에 두고, GPU가 이득인 특정 태스크만 GPU 클러스터로 보내는 구조입니다. 데이터는 이동하지 않고 GPU 파드가 AIStor에서 직접 읽습니다. 아래 표는 앞서 정리한 유스케이스에 대한 저의 설계 판단입니다.
| 유스케이스 | compute에 남는 부분 | GPU로 burst하는 부분 | 방식 |
|---|
| ⑨ 결함 이미지 ML | 데이터셋 구성, 라벨 관리 | 학습, 배치 추론 | A 또는 B |
| ⑧ 웨이퍼 맵 패턴 분류 | 전처리/피처 | 학습, 추론 | A 또는 B |
| ⑩ 가상계측/예측 모델 | 피처 생성 | 딥러닝 학습, 대규모 하이퍼파라미터 탐색 (소규모는 CPU로 충분) | A |
| ⑪ 예지보전 | 스트리밍 피처 | 재학습 (추론은 CPU) | A |
| ⑯ LLM/RAG | 문서 수집/정제 | 임베딩 배치 생성, 추론 | A/B + C |
| ②⑥ FDC·테스트 데이터 대용량 재처리(backfill) | 평소 증분 처리(CPU) | 수 PB급 재처리 시 Spark RAPIDS | B |
| ① 수율 RCA 대규모 조인/ML | 평소 SQL 분석 | 무거운 피처 중요도/모델링 | B |
| ⑦ Ad-hoc 노트북 | 노트북, 데이터 탐색 | GPU 커널이 필요한 셀 | D |
burst가 불필요한 것: ③ 대시보드, ④ 이력 조회, ⑫ commonality(SQL 중심), ⑬ 공급망, ⑮ 외부 공유. StarRocks/Trino는 CPU 엔진이라 compute에서 끝냅니다.
실행 방식 4가지
A. MultiKueue 디스패치 (큐/쿼터 통합 필요 시)
compute 클러스터를 매니저로 두고 GPU 클러스터를 워커로 등록합니다. 사용자는 매니저에 잡을 제출하기만 하면 됩니다.
- 매니저의 워크로드가 쿼터를 얻으면 모든 워커에 복사본이 생기고, 한 워커가 승인하면 매니저가 그곳에 잡 사본을 만들어 상태를 동기화하며, 완료되면 워커의 객체를 삭제합니다.
- 지원 유형은 Job, JobSet, Kubeflow 잡(TrainJob 포함), RayJob/RayCluster, Pod, AppWrapper입니다. SparkApplication은 지원 목록에 없습니다. (Kueue 개요 문서의 MultiKueue 지원 표 기준)
B. 오케스트레이터가 GPU 클러스터에 직접 제출
Airflow가 GPU 클러스터의 kubeconfig 연결로 KubernetesPodOperator, SparkKubernetesOperator, RayJob을 직접 생성합니다(일반적인 Airflow 사용법). MultiKueue보다 단순하고, GPU 클러스터의 로컬 Kueue가 큐를 관리합니다. 고정 라우팅이면 가장 실용적입니다. Spark RAPIDS처럼 MultiKueue가 못 다루는 잡은 이쪽을 쓰세요.
C. 서비스 호출 (상주 추론)
모델 서버(Triton, vLLM, KServe 등)를 GPU 클러스터에 상주시키고, compute의 Spark/Airflow가 Cluster Mesh 글로벌 서비스로 호출합니다. 실시간 결함 분류처럼 GPU를 항상 켜둘 때 적합합니다.
D. 인터랙티브 원격 실행
JupyterLab에서 Ray 클러스터(GPU 쪽)나 Spark Connect 엔드포인트에 붙거나, GPU가 필요한 사용자만 GPU 클러스터의 노트북 이미지를 쓰게 합니다(일반 설계).
예시
A: MultiKueue로 학습 잡 제출 (매니저 클러스터에서)
apiVersion: batch/v1
kind: Job
metadata:
name: defect-train
namespace: ml
labels:
kueue.x-k8s.io/queue-name: multikueue-queue
spec:
suspend: true
template:
spec:
containers:
- name: train
image: registry/defect-train:1.0
args: ["--table=polaris.fab.defect_img", "--snapshot-id=123456"]
resources:
limits: {nvidia.com/gpu: 4}
restartPolicy: Never
--snapshot-id로 Iceberg 스냅샷을 고정하면 재현 가능한 학습이 됩니다.
B: Airflow (compute 클러스터)
태스크 prepare_features(Spark, compute) → train_model(KubernetesPodOperator, GPU 클러스터 연결 지정) → write_predictions(Spark, compute) 순서로 DAG를 구성합니다.
Spark RAPIDS를 쓸 때
- Iceberg 읽기/쓰기의 GPU 가속은 기본 활성화이고, Parquet 형식을 지원합니다. 다만 스냅샷, 이력 같은 메타데이터 읽기는 GPU 가속 대상이 아닙니다. 지원 카탈로그에 Polaris(REST)가 포함되는지는 사용 버전 문서에서 확인하세요.
- NVIDIA 가이드에는 CPU 워크로드가 GPU 가속에 적합한지 평가하는 Qualification 도구가 있습니다. 모든 Spark 잡을 옮기지 말고, 이 도구로 이득이 큰 잡만 선별하세요.
- 이 잡은 MultiKueue 대상이 아니므로 방식 B로 GPU 클러스터에 Spark Operator를 두고 Airflow가 제출합니다. 드라이버와 익스큐터는 같은 클러스터에 두는 것이 안전합니다.
설계 포인트
- 데이터는 참조만 전달: 잡 파라미터에 테이블명/스냅샷 ID만 넘기고, GPU 파드가 Polaris와 AIStor에 직접 접근합니다. GPU 클러스터 → AIStor 경로 대역폭이 성능을 좌우하므로 BGP/ECMP 경로를 확인하세요.
- 자격증명 최소화: 잡 단위로 범위가 제한된 서비스 프린시펄을 쓰세요. 결과는 Polaris 경유로 Iceberg에 쓰거나, 모델은 AIStor 버킷(MLflow 등)에 저장합니다.
- MultiKueue 구성 요건: 워커에 같은 네임스페이스와 LocalQueue가 있어야 하고, 매니저의 쿼터는 모든 워커 쿼터 합과 같게 두는 것이 이상적입니다. 또 매니저 클러스터는 자기 자신의 워커가 될 수 없습니다. 매니저 → 워커 kube-apiserver 접근 경로(LB IP + 방화벽/정책)도 열어야 합니다.
- 사이트 간 GPU 사용: 기본은 같은 사이트 GPU만 쓰고, 원격 사이트 GPU는 데이터가 복제된 경우에만 허용하세요. 큰 데이터를 WAN으로 읽게 되면 burst 이점이 사라집니다.
- 성숙도: MultiKueue는 아직 개선이 활발한 기능이라 PoC 검증이 필요합니다.
추천 시작점
- 먼저 방식 B(Airflow → GPU 클러스터)로 ⑧⑨ 학습/추론을 연결해 흐름을 검증
- GPU 팀 쿼터와 공유가 필요해지면 MultiKueue(A) 도입
- 상주 추론이 필요하면 C 추가
- 대용량 재처리 비용이 커지면 Spark RAPIDS를 Qualification 도구로 선별해 적용
GPU 워크로드의 대부분이 학습인지 추론인지, 그리고 GPU 클러스터가 compute와 같은 사이트에 있는지 알려주시면 A/B 중 하나로 좁혀서 구체적인 DAG와 큐 설계를 드리겠습니다.
===
결론
방향이 맞습니다. 추론(서빙)과 학습은 GPU 클러스터로 분리하고, compute는 "URL 호출"과 "잡 제출" 두 가지 인터페이스로만 GPU 클러스터를 씁니다. 학습 수요가 늘면 인터페이스는 그대로 두고 GPU 클러스터만 늘리는 방식으로 확장할 수 있습니다.
compute 안에 GPU 노드를 넣지 않는 것이 좋은 이유는 다음과 같습니다(일반 설계 관점).
- 학습은 노드 간 고속망(RDMA/RoCE)과 토폴로지 인식 스케줄링을 요구하고, 추론은 저지연과 오토스케일을 요구해서 운영 성격이 다릅니다.
- 학습이 Spark/Trino/StarRocks의 노이지 네이버가 되는 것을 막을 수 있습니다.
1. 추론: "Pod 주소" 대신 "게이트웨이 URL"
Pod IP는 재시작과 스케일링 때마다 바뀌므로 직접 지정하지 마세요. 추천은 GPU 클러스터에 추론 게이트웨이를 두고, 안정적인 VIP/DNS 하나로 노출하는 구조입니다.
- Gateway API Inference Extension(GIE): ext-proc를 지원하는 게이트웨이(Envoy Gateway, kgateway 등)를 추론 게이트웨이로 확장하며, KV 캐시와 요청 비용을 고려하는 스케줄링으로 LLM 요청의 꼬리 지연과 처리량을 개선합니다. Endpoint Picker가 vLLM 파드마다 큐 깊이, KV 캐시 사용률, 프리픽스 캐시 적중률을 평가해 라우팅합니다. 일반 L4 라운드로빈보다 vLLM에 훨씬 유리합니다.
- llm-d: vLLM과 협력해 IGW 위에서 분리형(disaggregated) 서빙을 제공합니다. 규모가 커질 때 검토하세요.
- 주의: GIE는 아직 GA를 향해 가는 단계입니다. 초기에는 일반 게이트웨이 + vLLM으로 시작하고 PoC 후 전환하는 것도 방법입니다.
- 노출 방식: 게이트웨이 Service를 LoadBalancer로 만들고 BGP로 광고(ECMP), 내부 DNS(예:
llm.ai.internal)를 붙이세요. compute의 Spark/Airflow/Jupyter는 이 OpenAI 호환 URL만 쓰면 됩니다. Cluster Mesh 글로벌 서비스로 이름을 맞추면 compute에서 클러스터 로컬 서비스처럼 부를 수도 있습니다.
- 인증/과금: 이미 Keycloak이 있으니 게이트웨이에서 OIDC/JWT 검증과 팀별 rate limit을 적용하세요.
| 추론 유형 | 방식 |
|---|
| 온라인(챗, RAG, 결함 분류 API) | 게이트웨이 URL 호출 |
| 소규모 배치(수천~수만 건) | Spark/Airflow에서 게이트웨이를 동시성 제한을 두고 호출 |
| 대규모 오프라인(수억 행 임베딩 등) | GPU 클러스터에서 배치 잡(vLLM offline, RayJob)으로 AIStor를 직접 읽고 쓰기. 온라인 엔드포인트를 압박하지 않기 위함 |
2. 학습: 지금은 단순하게, 늘면 MultiKueue
1단계 (지금)
- GPU 클러스터 안에서 Kueue로 서빙과 학습을 함께 관리합니다. Kueue는 배치 워크로드와 서빙 워크로드(Deployment/StatefulSet)의 동시 관리를 지원합니다.
- 서빙은 높은 우선순위로 선점 불가, 학습은 낮은 우선순위로 선점 가능하게 하고, cohort와 선점 정책으로 팀 간 유휴 용량을 빌려 쓰게 하세요. 노드풀은 taint로 서빙용/학습용을 나눕니다.
- compute의 Airflow가 GPU 클러스터에 학습 잡을 직접 제출(방식 B)합니다.
2단계 (학습 수요 증가)
- 학습 전용 GPU 클러스터를 추가하고 MultiKueue로 연결합니다(서빙 클러스터는 그대로).
- Kueue는 물리 네트워크 토폴로지를 반영한 대규모 분산 학습 배치도 지원하므로 학습 클러스터의 RDMA 구성에 유리합니다.
- 제약: 매니저 클러스터는 자기 자신의 워커가 될 수 없고, 매니저 쿼터는 워커 쿼터 합과 같게 두는 것이 이상적입니다. 또 MultiKueue 지원 목록은 Job, JobSet, Kubeflow 잡, RayJob/RayCluster, Pod, AppWrapper이고, 표상 Deployment 같은 서빙 리소스는 포함되지 않았습니다. 서빙은 Argo CD로 GPU 서빙 클러스터에 직접 배포하세요(제 해석이므로 버전 문서 확인 필요).
핵심은 "자연스러운 전환"입니다. 아래 계약을 처음부터 고정해 두면 클러스터 분리/증설이 사용자에게 투명합니다.
1. 서빙 URL: 게이트웨이 DNS
2. 학습 제출: Kueue 큐 이름과 네임스페이스 규약
3. 데이터: Polaris 테이블/스냅샷 ID + AIStor 경로
4. 산출물: 모델은 AIStor 버킷(또는 MLflow 등)에 저장
3. 학습 → 서빙 순환 (MLOps 루프)
- 학습 잡이 Iceberg 스냅샷을 고정해 학습 → 모델을 AIStor 버킷에 저장
- Git의 서빙 매니페스트에서 모델 경로/버전 변경 → Argo CD가 서빙 클러스터에 롤아웃
- vLLM 파드는 AIStor에서 가중치를 로드합니다. 대형 모델은 기동이 느리므로 노드 로컬 NVMe 캐시나 사전 풀링을 고려하세요.
- 평가용 소규모 트래픽(카나리) → 전환
4. 네트워크/스토리지 포인트 (native + BGP)
- GPU(학습/서빙) → AIStor 경로 대역폭이 핵심입니다. AIStor LB IP를 BGP/ECMP로 광고하고, GPU 클러스터 노드가 가장 짧은 경로로 붙게 설계하세요.
- 클러스터 간 허용 흐름은 CiliumNetworkPolicy로 최소화합니다: compute → 게이트웨이(443), GPU → AIStor(S3)/Polaris(REST), 매니저 → 워커 API 서버(MultiKueue).
- 클러스터 내부의 학습 노드 간 통신(NCCL)은 별도 고속망이 있다면 Cilium이 아닌 보조 NIC 경로를 쓰는 구성이 일반적입니다. 인프라 팀과 확인하세요.
5. DR 관점 (미정이므로 가볍게)
추론 서빙은 무상태 + Git 매니페스트 + 모델 버킷으로 구성되므로 DR이 가장 쉬운 축입니다. 모델/가중치 버킷만 다른 사이트로 복제해 두면, 필수 서비스에 한해 warm standby 서빙 클러스터를 다른 사이트에 둘 수 있습니다. 학습은 DR 대상에서 제외하는 것이 일반적입니다.
추천 순서
- GPU 클러스터에 vLLM + 게이트웨이(VIP/DNS) + Keycloak 인증, compute에서 URL 호출
- GPU 클러스터에 Kueue 도입(서빙 고우선/학습 선점 가능)
- Airflow → GPU 클러스터 학습 잡 제출, 모델은 AIStor에 저장하고 Argo CD로 서빙 배포
- 학습 수요가 한계에 오면 학습 클러스터 분리 + MultiKueue
GPU 서버가 사이트 내 몇 대 정도이고, 서빙할 모델 규모(수 B ~ 수십 B 이상)와 동시 사용자 수를 알려주시면 서빙 클러스터와 학습 클러스터를 처음부터 나눌지, 한 클러스터로 시작할지 규모 기준으로 더 구체적으로 판단해드리겠습니다.
===
짧은 답
- BGP 광고는 public 여부와 무관합니다. private 망에서도 Service(LoadBalancer) VIP를 광고할 수 있습니다.
- GPU↔AIStor는 용도별로 경로를 나누는 게 좋습니다. 제어/일반 S3는 private 본딩(Cilium), 대용량 학습 데이터와 체크포인트는 400G IB 패브릭으로 보냅니다. 단, IB 경로를 Kubernetes에서 쓰는 방식은 AIStor 공식 문서끼리 상충하는 부분이 있어 먼저 확인이 필요합니다.
1. private 망에서 서비스를 BGP로 광고해도 되나
네, 됩니다. "private 쪽으로는 Pod CIDR만 광고"하는 것은 기본 구성일 뿐 제약이 아닙니다. BGP는 "어느 IP를 어느 피어에게 알릴지"의 문제이고, public/private은 그 피어가 속한 망일 뿐입니다. Cilium BGP Control Plane은 Pod CIDR 외에 LoadBalancer IP(LB IPAM 풀)도 광고할 수 있습니다(일반 지식, 버전별 필드 확인).
GPU 클러스터에는 이렇게 하면 됩니다.
- 사설 대역(RFC1918)으로 LB IP 풀을 만들고, private ToR과만 피어링해 그 IP를 광고합니다.
- vLLM 게이트웨이 VIP는 compute가 같은 private 망으로 접근하므로 public이 필요 없습니다.
externalTrafficPolicy: Local을 쓰면 해당 파드가 있는 노드만 광고되어 불필요한 홉이 줄어듭니다.
- 외부 사용자 접근이 필요하면 GPU가 아니라 public이 있는 compute 클러스터의 ingress가 프록시하는 편이 안전합니다.
앞서 "GPU 클러스터 노드가 가장 짧은 경로로 붙게"라고 한 것은 정정이 필요합니다. 실제로는 AIStor VIP를 내부용(private 광고)과 외부용(public 광고)으로 분리하고, GPU와 compute는 내부용만 쓰게 하세요.
2. GPU → AIStor 연결 권장안
| 용도 | 경로 | 이유 |
|---|
| Polaris REST, 메타/소량 읽기, 노트북 | private 본딩 + Cilium | 정책/관측(Hubble) 적용, 설정 단순 |
| 학습 데이터 로딩, 체크포인트, 대형 모델 가중치 | IB 패브릭 | 대역폭 (400G×2) |
| 위 중 클라이언트를 직접 통제할 수 있는 경로 | S3 over RDMA | CPU 복사 제거 |
S3 over RDMA 요점
- 서버에서 클라이언트 GPU/호스트 메모리로 데이터가 직접 흐르며 복사가 한 번 줄어듭니다. GetObject, PutObject, UploadPart에 RDMA 경로가 있고, Go/C++/Rust/Python SDK가 NVIDIA cuObjClient로 지원합니다.
- 필요 조건은 RDMA 빌드 서버(표준 바이너리에서는 RDMA 설정이 컴파일에서 빠져 TCP로만 동작)와 InfiniBand(HDR/NDR) 또는 RoCEv2 패브릭, GPUDirect RDMA를 지원하는 GPU, NVIDIA 드라이버 470 이상입니다.
- 서버가 거절하면 501을 반환하고 재시도는 클라이언트 몫이므로, TCP 폴백 로직이 필요합니다.
- 현실적 한계: PyTorch DataLoader, vLLM의 기본 로더 같은 표준 도구는 일반 S3(TCP)로 읽습니다. RDMA를 쓰려면 SDK 기반의 커스텀 로더 통합이 필요합니다(일반 판단). 따라서 처음부터 모든 경로를 RDMA로 바꾸기보다 학습 로더, 체크포인트 같은 핫패스부터 적용하세요.
표준 S3 클라이언트를 IB로 태우는 방법 (IPoIB)
IPoIB는 RDMA가 아닌 IP over IB(TCP)라서 라인 레이트에 못 미치고 튜닝(멀티 스트림 등)이 필요합니다(일반 지식). 사용하려면 파드에 보조 인터페이스가 필요합니다. NVIDIA Network Operator가 Multus, IPoIB CNI, RDMA shared device plugin, SR-IOV device plugin을 제공합니다. 다만 이 경로의 트래픽은 Cilium 정책/Hubble이 보지 못합니다. 인증은 AIStor IAM/정책과 IB 파티션(pkey)으로 보완해야 합니다(일반 설계 판단).
3. 꼭 확인할 점: Kubernetes에서의 RDMA 지원 상충
AIStor 문서가 서로 다르게 말합니다.
- 설치 가이드: Operator에서 RDMA를 켜려면 aistor-operator Helm 차트 6.0.0 이상이 필요하고, RDMA 파드는 호스트 네트워크에서 동작하며 privileged PodSecurity가 필요합니다.
- RDMA 개요 페이지: 이 릴리스에서 Operator는 RDMA를 지원하지 않으며 Kubernetes에 RDMA를 배포하지 말라고 안내합니다.
어느 쪽이 현재 버전에 맞는지는 제가 확인하지 못했습니다. 사용 중인 Operator/서버 버전을 기준으로 MinIO 지원 팀에 확인하세요. 호스트 네트워크 파드는 CiliumNetworkPolicy 적용 대상이 아니라는 점도 보안 설계에 반영해야 합니다.
또 하나, 서버 간(erasure shard) RDMA는 GPU 없이도 RDMA 패브릭만 있으면 되며 별도로 켭니다. 스토리지 노드끼리도 IB로 연결되어 있다면 쓰기/복구 성능에 이득이 있을 수 있습니다.
추천 순서
- 먼저 베이스라인: private 본딩(200G) + Cilium으로 GPU → AIStor 실제 처리량을 측정합니다(멀티 스트림 기준). 이것으로 충분한 워크로드가 많습니다.
- 부족한 핫패스(학습 로더, 체크포인트, 가중치 로딩)만 IB로 전환합니다. 지원 가능하면 S3 over RDMA, 어렵다면 IPoIB.
- AIStor RDMA 빌드와 Operator 지원 여부를 먼저 PoC로 검증한 뒤 운영에 반영합니다.
- 정책 우회 경로(IB, 호스트 네트워크)는 AIStor IAM, 버킷 분리, 패브릭 파티션으로 보완합니다.
GPU 노드의 400G IB NIC이 스토리지 전용인지, 노드 간 NCCL 학습 통신도 함께 쓰는지 알려주시면 대역폭 충돌 여부와 구성(NIC 분리, 서비스 레벨 설정)을 더 구체적으로 짚어드리겠습니다.
===
결론
NIC를 공유하면 학습 중 스토리지 트래픽이 NCCL을 늦출 수 있으므로, 학습 노드는 IB를 NCCL 전용으로 두고 스토리지 접근은 private 본딩으로 분리하는 것을 기본으로 권합니다. 앞서 "학습 데이터/체크포인트를 IB로"라고 한 권고는 이 새 정보에 맞춰 수정합니다.
왜 문제가 되나
NCCL의 all-reduce는 모든 랭크가 동기화되는 집합 통신이라 한 노드의 NIC 경합이 전체 스텝 시간을 끌어내립니다. 체크포인트 쓰기나 데이터 로딩의 순간적 폭주가 학습 전체 지연으로 번질 수 있습니다(일반 지식). NVIDIA/파트너 참조 아키텍처도 이 때문에 구성이 다릅니다. 예를 들어 NetApp AIPod의 DGX H100 구성은 컴퓨트 인터커넥트와 스토리지 접근에 별도 패브릭을 쓰고, DGX SuperPOD도 스토리지 네트워크와 컴퓨트 네트워크를 물리적으로 분리합니다.
권장 구성 (우선순위 순)
1. 학습 노드: IB = NCCL 전용, 스토리지 = private 본딩(200G)
- 체크포인트는 노드 로컬 NVMe에 먼저 저장하고 AIStor로 비동기/샤딩 업로드하세요. 데이터 로더도 로컬 NVMe 캐시와 프리패치를 쓰면 공유 스토리지 부하가 줄어듭니다. 참조 아키텍처에서도 노드 로컬 NVMe를 캐시/임시 저장소로 두어 공유 스토리지 접근 압력을 낮춥니다.
- 200G 본딩은 이론상 약 25GB/s이므로 비동기 체크포인트에는 충분한 경우가 많습니다(실측 필요).
- 이 방식은 AIStor RDMA를 Kubernetes에 올릴지 불확실한 문제(문서 상충)도 피할 수 있다는 장점이 있습니다.
2. 서빙(추론) 노드: IB를 스토리지용으로 사용
추론은 단일 노드 안에서 NVLink로 처리하는 경우가 많아 노드 간 NCCL이 거의 없을 수 있습니다(모델 크기에 따라 다름). 이런 노드는 IB를 모델 가중치 로딩에 써도 경합이 적습니다. S3 over RDMA나 IPoIB 검토는 이쪽에 먼저 적용하세요.
3. 어쩔 수 없이 학습 노드에서 IB로 스토리지도 써야 한다면: QoS로 격리
- InfiniBand는 서비스 레벨(SL)을 가상 레인(VL)에 매핑해 트래픽 분리와 우선순위 구분을 할 수 있습니다. Subnet Manager(OpenSM/UFM)에서 QoS를 설정하고 NCCL을 높은 우선순위로 두세요.
- 양쪽의 SL을 다르게 지정합니다. NCCL은
NCCL_IB_SL/NCCL_IB_TC 환경변수(일반 지식)로, AIStor는 MINIO_RDMA_SERVICE_LEVEL로 InfiniBand 서비스 레벨을 지정할 수 있습니다.
- AIStor의 서버 대역폭 제한(bandwidth cap)은 S3 over RDMA 클라이언트 전송에도 적용되므로 스토리지 쪽 상한을 걸어 NCCL 여유를 확보할 수 있습니다.
- 체크포인트 시점을 랭크별로 엇갈리게 하는 등 앱 레벨 스로틀링도 병행하세요.
클러스터 구성에 미치는 영향
- 학습과 서빙이 같은 IB 리프를 공유하면 서로 영향을 줍니다. 앞서 제안한 학습/서빙 클러스터(또는 최소한 노드풀과 리프 단위) 분리의 근거가 더 강해졌습니다.
- 학습 잡은 Kueue의 토폴로지 인식 스케줄링으로 가까운 리프/랙에 몰아서 배치하세요. Kueue는 물리 네트워크 토폴로지를 반영한 대규모 분산 학습 배치를 지원합니다. 스파인 경유 트래픽이 줄어듭니다.
반드시 측정할 것
nccl-tests(all_reduce_perf)로 단독 기준선을 측정합니다.
- 같은 시간에 스토리지 부하(체크포인트 모사, MinIO warp 등)를 걸고 다시 측정해 감소율을 확인합니다.
- 포트 혼잡 카운터(UFM, ibdiagnet 등)를 모니터링합니다.
- 감소율이 허용 범위(예: 몇 % 이내)면 공유를 유지하고, 아니면 1번 구성(스토리지는 본딩 경로)을 고정하세요.
정리
| 노드 | IB | 스토리지 경로 |
|---|
| 학습 | NCCL 전용 | private 본딩 + 로컬 NVMe 스테이징 |
| 서빙 | 스토리지(가중치 로딩) 가능 | IB(RDMA 가능 여부 PoC 후) 또는 본딩 |
| 혼용 불가피 | SL/VL QoS + 대역폭 상한 | 측정 후 결정 |
학습 노드는 GPU가 노드당 몇 장이고 몇 대 규모로 계획하시나요? 규모와 NIC 수(GPU:NIC 비율)에 따라 NCCL이 IB 대역폭을 얼마나 점유하는지가 달라지므로, 공유를 허용할 수 있는지 더 구체적으로 판단해드리겠습니다.