Pointcept:Arm64
ARM64 에서 (정확히는 NVIDIA DGX Spark) 에서 Pointcept 를 빌드하고 사용하는 과정에서 발생하는 이슈들에 대하여 정리함.
빌드 방법
DGX Spark (GB10 = sm_121, aarch64) 에서 네이티브로 돌리는 경우입니다. 이 경우 QEMU가 전혀 필요 없고(arch == host_arch면 바로 통과), 그냥 도커만 있으면 됩니다.
시스템 사양
- NVIDIA DGX Spark (GB10 = sm_121, aarch64)
- NVIDIA-SMI 580.173.02
- NVIDIA Driver Version: 580.173.02
- CUDA Version: 13.0
- Ubuntu 24.04.4 LTS (noble)
- Python 3.12
- Torch 2.9.1 (cu130 인덱스의 최소 버전이 2.9.0)
원시코드
- https://github.com/cvprun/Pointcept 를 사용한다. (원본 코드 - https://github.com/pointcept/pointcept - 를 Fork 했다)
한방에 실행하는 간단한 방법
arm64+cu130+torch2.9.1+py3.12+sm_121
./scripts/build_wheels.sh build --arch arm64 --accel cu130 --torch 2.9.1 --python 3.12 --cuda-arch 12.1 --jobs 8 -v
./scripts/verify_wheels.sh wheelhouse/linux-arm64/cu130/torch2.9.1-cp312/
arm64+cu130+torch2.13.0+py3.12+sm_121
./scripts/build_wheels.sh build --arch arm64 --accel cu130 --torch 2.13.0 --python 3.12 --cuda-arch 12.1 --jobs 8 -v
./scripts/verify_wheels.sh wheelhouse/linux-arm64/cu130/torch2.13.0-cp312/
타깃 확정
DGX Spark의 sm_121은 CUDA 12.9 이상에서만 코드 생성이 됩니다. 스크립트의 cuda_supported_arches상 cu128은 12.0까지라 12.1이 검증 단계에서 탈락합니다. 따라서:
| 축 | 값 | 이유 |
| | arm64 | 호스트 아키텍처 (에뮬레이션 없음) |
| | cu130 | sm_121 커버 + PyTorch 인덱스 존재 (cu129도 가능) |
| | 2.9.1 | cu130 인덱스의 최소 버전이 2.9.0 |
| | 3.12 | 기본값 |
| | 12.1 | GB10 전용. 생략하면 8.7 9.0 10.0 11.0 12.0 12.1 6개를 전부 컴파일 |
공통 변수로 묶어두면 편합니다:
cd /path/to/Pointcept
BW=./scripts/build_wheels.sh
T="--arch arm64 --accel cu130 --torch 2.9.1 --python 3.12 --cuda-arch 12.1 --jobs 8 -v"
-
--jobs는 기본값이 nproc(최대 16)인데, DGX Spark는 128GB 통합 메모리를 GPU와 공유합니다. nvcc가 잡당 ~2.5GB를 쓰므로 8~10으로 낮춰 잡는 걸 권합니다. -
-v는 컴파일러 출력을 스트리밍합니다. 몇 시간짜리 빌드를 눈으로 확인하려면 필수입니다.
시작 전 확인 (아무것도 빌드하지 않음):
단계별 빌드
핵심은 --only {패키지} 입니다. 출력 디렉터리와 pip/uv 캐시 볼륨(pointcept-build-cache)이 실행 간에 공유되므로, 나눠 돌려도 결과가 한 곳에 누적됩니다.
manifest.txt에 각 휠을 프리빌트로 받았는지 컴파일했는지가 append로 기록됩니다.
| # | 명령 | 내용 | 체감 비용 | 프로젝트 링크 | 프로젝트 설명 |
| 1 | | 순수 파이썬, PyPI 프리빌트 | 초 단위 | NVIDIA의 Pure C++ Meta: C++ 코드를 파이썬으로 생성하는 메타프로그래밍 도구 | |
| 2 | | aarch64 프리빌트 없음 → 소스 | 무거움 | Concurrent Unified Memory Management: CUDA/CPU 메모리 관리 및 커널 최적화 라이브러리 | |
| 3 | | 소스 | 무거움 | Sparse Convolution: 포인트 클라우드 처리용 희소 3D 합성곱 구현 | |
| 4 | | aarch64 프리빌트 없음 → 소스 | 중간 | PyTorch Scatter: 텐서 scatter/gather 연산의 GPU 최적화 구현 | |
| 5 | | 소스 (이 셋 중 최장) | 무거움 | PyTorch Sparse: 희소 텐서 연산 및 행렬곱을 위한 GPU 최적화 레이어 | |
| 6 | | 소스 | 중간 | PyTorch Cluster: 점군 클러스터링, k-NN 그래프 생성 등 그래프 기반 연산 라이브러리 | |
| 7 | | 둘 다 순수 파이썬 | 초 단위 | PyTorch Geometric: GNN 프레임워크 / OCNN: 옥트리 기반 3D CNN | |
| 8 | | 소스 (CUDA) | 중간 | Swin3D Vision Transformer: 3D 포인트 클라우드 및 영상 처리용 transformer 백본 | |
| 9 | | ⚠️ 아래 참고 | 최장 | FlashAttention: 어텐션 연산의 IO-aware 알고리즘으로 메모리 대역폭 최적화 | |
| 10 | | | 각 수 분 | PointOps: 포인트 클라우드 연산 커널 (Pointcept 및 Point Transformer용) | |
| 11 | | | 각 수 분 | Pointcept: 포인트 클라우드 세분화(segmentation), 인스턴스 그룹핑, 위치 인코딩 커스텀 연산 |
- 의존성은 자동으로 끌어옵니다.
--only spconv만 줘도 pccm → cumm → spconv 순으로 셋 다 빌드하니, 2~3단계를 합치고 싶으면 3번만 실행해도 됩니다.
각 단계는 독립된 컨테이너로 실행되며 매번 "apt 툴체인 설치 + uv venv + torch 설치" 를 처음부터 다시 합니다(약 2~3분 고정 오버헤드). 캐시 볼륨 덕에 두 번째 실행부터는 다운로드가 아니라 캐시 복사입니다.
| INFORMATION |
| 참고로 한번에 전부 실행 시킬 예정이라면 |
sm_121 에서 알아둘 두 가지
cumm/spconv
cumm은 자체 supported_arches 테이블(cumm/common.py)을 가지고 있고 거기에 12.1이 없습니다. 스크립트가 이를 12.0+PTX로 자동 매핑하므로(cumm_arch_for), cubin 대신 PTX가 실려 첫 로드 시 드라이버가 JIT합니다.
빌드 중 이런 로그가 나오면 정상입니다:
flash-attn
flash_attn_arch_for가 아는 값은 80/90/100/120뿐이고 12.1은 매핑이 없어 패키지 자체가 스킵됩니다:
Blackwell은 sm_120 cubin이 sm_121 디바이스에 로드되지 않으므로, 이건 스크립트 버그라기보다 실제 제약입니다. 이 단계는 건너뛰고 진행하시고, flash-attn이 꼭 필요하면 별도로 확인이 필요합니다.
원하시면 12.0+PTX로 넘겨 PTX 경로가 실제로 되는지 스크립트를 손봐드릴 수 있습니다.
완료 후
cat wheelhouse/linux-arm64/cu130/torch2.9.1-cp312/manifest.txt
pip install wheelhouse/linux-arm64/cu130/torch2.9.1-cp312/*.whl
참고로 알아두면 좋은 것
- 빌드는 GPU를 전혀 쓰지 않습니다 (
--gpus플래그 없음, nvcc 크로스 컴파일). 시작 시 뜨는 드라이버/GPU 체크는 "이 휠이 이 머신에서 로드되는가"를 알려줄 뿐 빌드를 막지 않습니다. - 레포는
/src에 읽기 전용으로 마운트되고libs/는 컨테이너 안에서/tmp로 복사된 뒤 빌드되므로, 작업 트리에build/나*.egg-info가 생기지 않습니다. - 실패해도
set +e로 감싸여 있어 해당 패키지 로그 마지막 40줄이 출력됩니다. 전체 로그는 컨테이너 내부/tmp/<패키지>.log인데 컨테이너가--rm이라 사라지므로, 자세히 봐야 하면$BW shell $T로 같은 환경에 들어가서 수동으로 돌리세요. - 한 번에 다 돌려보고 싶어지면
$BW build $T --keep-going— 실패한 패키지를 건너뛰고 끝까지 갑니다.