콘텐츠로 이동
Search

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)

원시코드

한방에 실행하는 간단한 방법

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이 검증 단계에서 탈락합니다. 따라서:

축

값

이유

--arch

arm64

호스트 아키텍처 (에뮬레이션 없음)

--accel

cu130

sm_121 커버 + PyTorch 인덱스 존재 (cu129도 가능)

--torch

2.9.1

cu130 인덱스의 최소 버전이 2.9.0

--python

3.12

기본값

--cuda-arch

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는 컴파일러 출력을 스트리밍합니다. 몇 시간짜리 빌드를 눈으로 확인하려면 필수입니다.

시작 전 확인 (아무것도 빌드하지 않음):

## 조합·패키지 목록 출력:
$BW matrix $T

## 실제 실행될 docker 커맨드 출력:
$BW build $T --dry-run

단계별 빌드

핵심은 --only {패키지} 입니다. 출력 디렉터리와 pip/uv 캐시 볼륨(pointcept-build-cache)이 실행 간에 공유되므로, 나눠 돌려도 결과가 한 곳에 누적됩니다.

wheelhouse/linux-arm64/cu130/torch2.9.1-cp312/

manifest.txt에 각 휠을 프리빌트로 받았는지 컴파일했는지가 append로 기록됩니다.

#

명령

내용

체감 비용

프로젝트 링크

프로젝트 설명

1

$BW build $T --only pccm

순수 파이썬, PyPI 프리빌트

초 단위

PCCM

NVIDIA의 Pure C++ Meta: C++ 코드를 파이썬으로 생성하는 메타프로그래밍 도구

2

$BW build $T --only cumm

aarch64 프리빌트 없음 → 소스

무거움

CUMM

Concurrent Unified Memory Management: CUDA/CPU 메모리 관리 및 커널 최적화 라이브러리

3

$BW build $T --only spconv

소스

무거움

spconv

Sparse Convolution: 포인트 클라우드 처리용 희소 3D 합성곱 구현

4

$BW build $T --only torch-scatter

aarch64 프리빌트 없음 → 소스

중간

pytorch_scatter

PyTorch Scatter: 텐서 scatter/gather 연산의 GPU 최적화 구현

5

$BW build $T --only torch-sparse

소스 (이 셋 중 최장)

무거움

pytorch_sparse

PyTorch Sparse: 희소 텐서 연산 및 행렬곱을 위한 GPU 최적화 레이어

6

$BW build $T --only torch-cluster

소스

중간

pytorch_cluster

PyTorch Cluster: 점군 클러스터링, k-NN 그래프 생성 등 그래프 기반 연산 라이브러리

7

$BW build $T --only torch-geometric,ocnn

둘 다 순수 파이썬

초 단위

PyG, OCNN

PyTorch Geometric: GNN 프레임워크 / OCNN: 옥트리 기반 3D CNN

8

$BW build $T --only swin3d

소스 (CUDA)

중간

Swin3D

Swin3D Vision Transformer: 3D 포인트 클라우드 및 영상 처리용 transformer 백본

9

$BW build $T --only flash-attn

⚠️ 아래 참고

최장

FlashAttention

FlashAttention: 어텐션 연산의 IO-aware 알고리즘으로 메모리 대역폭 최적화

10

$BW build $T --only pointops,pointops2

libs/ 로 확장

각 수 분

PointOps

PointOps: 포인트 클라우드 연산 커널 (Pointcept 및 Point Transformer용)

11

$BW build $T --only pointgroup_ops,pointseg,pointrope

libs/ 로 확장

각 수 분

Pointcept

Pointcept: 포인트 클라우드 세분화(segmentation), 인스턴스 그룹핑, 위치 인코딩 커스텀 연산

  • 의존성은 자동으로 끌어옵니다. --only spconv만 줘도 pccm → cumm → spconv 순으로 셋 다 빌드하니, 2~3단계를 합치고 싶으면 3번만 실행해도 됩니다.

각 단계는 독립된 컨테이너로 실행되며 매번 "apt 툴체인 설치 + uv venv + torch 설치" 를 처음부터 다시 합니다(약 2~3분 고정 오버헤드). 캐시 볼륨 덕에 두 번째 실행부터는 다운로드가 아니라 캐시 복사입니다.

INFORMATION

참고로 한번에 전부 실행 시킬 예정이라면 --only ... 플래그를 빼고 실행하면 된다. 즉, $BW build $T 으로 실행

sm_121 에서 알아둘 두 가지

cumm/spconv

cumm은 자체 supported_arches 테이블(cumm/common.py)을 가지고 있고 거기에 12.1이 없습니다. 스크립트가 이를 12.0+PTX로 자동 매핑하므로(cumm_arch_for), cubin 대신 PTX가 실려 첫 로드 시 드라이버가 JIT합니다.

빌드 중 이런 로그가 나오면 정상입니다:

-> cumm arch set: 12.0+PTX (from 12.1)

flash-attn

flash_attn_arch_for가 아는 값은 80/90/100/120뿐이고 12.1은 매핑이 없어 패키지 자체가 스킵됩니다:

!! flash-attn skipped: no target in '12.1' has flash-attn 2.x kernels

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 — 실패한 패키지를 건너뛰고 끝까지 갑니다.

Troubleshooting

Pointcept (PTv3) 학습 크래시 : cudaErrorIllegalAddress

DGX Spark 노드에서 PTv3 학습이 cudaErrorIllegalAddress 로 죽었다. 에러는 매번 spconv 의 pair 생성에서 보고됐지만, 죽는 iteration 과 씬 형상은 런마다 달랐다.

여러 가설을 차례로 배제하는 과정에서, 한 번은 torch 2.13.0 을 원인으로 잘못 확정했다. torch 를 2.9.1 로 내린 운영 런도 똑같이 죽어서 그 결론은 철회했다.

마지막으로 implicit gemm 경로를 통째로 빼는 spconv_native: true 로 운영 런을 돌렸고, 100 epoch(2,500 iter)를 끝까지 돌았다. 이 스위치를 기본값으로 켰다.

증상

[Exception|implicit_gemm_pair]indices=torch.Size([49093, 4]),bs=1,ss=[757, 621, 546],
  algo=ConvAlgo.MaskImplicitGemm,ksize=[3, 3, 3],...,subm=True,transpose=False
  File ".../spconv/pytorch/ops.py", line 550, in get_indice_pairs_implicit_gemm
    SpconvOps.sort_1d_by_key_allocator(pair_mask_tv[j],
RuntimeError: merge_sort: failed to synchronize: cudaErrorIllegalAddress:
  an illegal memory access was encountered
  • merge_sort: failed to synchronize 는 thrust 가 앞서 실행된 다른 커널의 잘못된 메모리 접근을 늦게 알아챈 것이다. 그래서 트레이스백은 결함이 난 곳이 아니라 그 뒤의 첫 동기화 지점을 가리킨다.
  • 운영 런에서 사망한 지점:

런

torch

조건

사망 지점

1차

2.13.0

기본 (amp 켬)

학습 25 iter 뒤 첫 평가 샘플

2차

2.13.0

enable_amp=false

epoch 2 의 17번째 iter (누적 42 iter)

3차

2.9.1

클래스에서 -1 제거

epoch 3 의 17번째 iter (누적 67 iter)

4차

2.9.1

spconv_native: true

사망 없음 — 100 epoch 완주

조사 경과

#

가설

검증 방법

결과

1

평가만 fp32 로 돈다 (학습은 autocast fp16)

enable_amp=false 로 재제출

기각 — 평가는 통과하고 학습 중에 죽음

2

평가를 autocast 로 감싸면 우회된다

로컬 amd64 에서 실제 엔트리포인트 구동

막다른 길 — amd64 에서도 can't find suitable algorithm for 0. 평가(is_train=False)에는 fp16 커널 후보가 없다. 되돌림

3

데이터 오염 (NaN, 이상치)

62개 PLY 전수 검사

기각 — 비유한 좌표 0건

4

특정 씬 형상이 방아쇠

로그의 ss 를 역산해 크래시 씬 특정 (24_final.ply)

기각 — 같은 씬이 로컬에서 멀쩡하고, 사망 때마다 형상이 다름

5

sm_121 에서 PTX JIT 된 spconv 커널

DGX Spark 에서 torch 2.9.1 휠하우스로 한 번 실행

기각했으나 잘못된 기각 — 통과 한 번뿐이었음 (가설 8 에서 복원)

6

검증 런이 너무 짧고 작다

47.7k voxel × 60 iter 로 재실행

2.9.1 통과. 이것도 한 번뿐

7

torch 2.13.0 휠 세트

같은 조건으로 torch 2.13.0 휠하우스 실행

epoch 5 에서 사망 → 원인으로 확정했으나 틀림

7'

(정정)

torch 2.9.1 로 재게시한 운영 이미지

같은 에러로 재발 → 가설 7 철회

8

spconv implicit gemm 경로

운영에 spconv_native: true (implicit gemm 을 통째로 뺌)

확인 — 수십 iter 안에 죽던 조건에서 2,500 iter 완주

틀린 결론에서 배운 것

가설 5·6·7 은 모두 설정마다 한 번씩만 돌린 결과로 판정했다. 매번 다른 자리에서 터지는 결함이라면 한 번 통과한 것은 운일 수 있다. 실제로 2.9.1 쪽의 통과는 운이었다. 판별력이 있었던 실험은 결함 경로를 통째로 빼는 것(가설 8)이었다.

traceback 의 줄 번호로 운영 이미지의 torch 버전을 확인했다. module.py 의 _wrapped_call_impl 줄이 2.9.1 은 1775, 2.13.0 은 1778 이다.

주요 사실

  • cumm 0.8.2 는 12.1 을 받지 않는다. cumm/common.py 의 supported_arches 가 "12.0" 에서 끝난다. 그래서 sm_121 용 spconv 는 12.0+PTX 로 빌드되고 드라이버가 JIT 한다. torch 자신도 compute_120 PTX 로 같은 방식으로 돈다.
  • spconv 는 모든 weight 를 알고리즘과 무관하게 KRSC 로 저장한다(ALL_WEIGHT_IS_KRSC=True). 그래서 모델을 만든 뒤 ConvAlgo.Native 로 바꿔도 안전하다. 훅은 이 전제를 assert 로 확인한다.
  • Native 의 비용은 sm_120 노트북에서 약 4% 였다.

조치

저장소

커밋

내용

mlops

2dd58d0

scripts/pointcept/spconv_probe.py — spconv 를 dtype × mode × algo 조합으로 판별. 조합마다 별도 프로세스로 실행

mlops

a438690

하이퍼파라미터 spconv_native 추가. 켜면 GeoSpconvAlgo 훅이 spconv 레이어 23개를 ConvAlgo.Native 로 고정

mlops

7880d6a

Dockerfile.pointcept 의 torch 를 2.13.0 → 2.9.1 로 고정. 원인은 아니었지만 해가 없어 유지

mlops

409c759

spconv_native 기본값을 켬. 트레이너·훅·편집 템플릿 모두. 이 커밋이 7880d6a 의 원인 판단을 바로잡는다

Pointcept

d10d7ea

scripts/verify_mlops.sh — 휠하우스 위에서 mlops 의 학습·추론 엔트리포인트를 그대로 실행

Pointcept

f81ef2b

mlops 체크아웃이 없는 노드용으로 엔트리포인트 3개를 scripts/mlops_runtime/ 에 번들. 원본과 달라지면 경고하고 --update-bundle 로 갱신

PointGroup 인스턴스 분할 학습 트러블슈팅

작성 2026-09-23. 대상은 instance_segmentation / pointcept / pg-ptv3 (PointGroup PG-v1m2 + PTv3 백본), GB10 (sm_121) 단일 GPU, 사용자 PLY 62개 (학습 50 / 검증 12), 단일 클래스.

플랜 문서는 docs/plans/50_pointgroup_instance_segmentation_plan.md 의 Phase 6 진행 메모이고, 이 파일은 그중 실행에서 만난 문제만 따로 모은 것이다.

1. 한눈에

회차

증상

원인

조치

커밋

1차

AttributeError: module 'numpy' has no attribute 'in1d'

NumPy 2 가 np.in1d 를 제거, Pointcept 의 인스턴스 경로만 그것을 씀

patch_numpy_compat() 가 np.isin 으로 되살림

0aeb054

2차

역전파에서 CUDA device-side assert (scatter/gather 범위 초과)

미확정, 3차에서 재현되지 않음

cuda_launch_blocking 하이퍼파라미터 + describe_scene() 범위 검사 계측

5cdb0c9

3차

완주했으나 mAP/AP50/AP25 가 전부 0, bias_l1_loss 가 150~225 에서 고정

좌표 규모가 PointGroup 기본값의 약 100배

스테이징이 좌표에 배율을 걸어 grid_size 를 TARGET_VOXEL(0.02)로 옮김

1e09229

3차에서 확인된 가장 중요한 사실 하나: pointgroup_ops 의 bfs_cluster 가 sm_121 에서 실제로 돈다. 플랜의 최대 리스크였고 CPU 폴백을 준비할 필요가 없어졌다.

2. 1차: np.in1d 없음

mask = ~np.in1d(segment, self.segment_ignore_index)
AttributeError: module 'numpy' has no attribute 'in1d'

NumPy 2.0 에서 np.in1d 가 사라졌다. 이미지의 numpy 는 2.5.2 다. Pointcept 포크에서 이 함수를 쓰는 자리는 세 곳뿐이고 전부 인스턴스 경로다 (InstanceParser, InsSegEvaluator, tester). 그래서 시맨틱 분할은 같은 이미지로 100 epoch 를 완주하면서도 이 오류를 한 번도 만나지 않았다.

조치는 pointcept_semseg.patch_numpy_compat() 다. np.in1d 를 np.isin 으로 되살린다. 세 자리 모두 1-D 라벨 배열이라 동치다. 디스패처가 트레이너를 고르기 전에 부르고, pointcept_insseg.main() 도 시작에서 한 번 부른다. 포크에 다른 NumPy 2 제거 별칭은 없다 (전수 확인).

곁가지로 이 수정의 테스트가 patch.dict(sys.modules, ...) 를 쓰고 있었는데, 이 패치는 빠져나올 때 사전을 통째로 되돌려서 블록 안에서 처음 import 된 모듈을 지운다. 그 뒤 numpy 가 두 벌이 되어 엉뚱한 테스트가 _NoValueType 으로 죽었다. 키 하나만 바꾸고 되돌리는 _stub_module 로 교체했다.

3. 2차: 역전파에서 CUDA device-side assert

ScatterGatherKernel.cu:163 ... scatter gather kernel index out of bounds   (수백 줄)
spconv indice_conv_backward ... dev2host ... error 710

데이터 준비와 첫 forward 는 통과했다. CUDA 오류는 비동기라 터진 자리(spconv 역전파)와 원인 커널이 다르다. Pointcept 과 PointGroup 코드에서 ATen gather/scatter 를 직접 부르는 자리는 없고 (comm.gather 와 torch_scatter.segment_csr 뿐), 백본과 spconv 와 데이터는 같은 조합으로 시맨틱 분할 100 epoch 를 완주한 적이 있다. 코드 읽기로는 더 좁힐 수 없어서 계측을 넣었다.

  • 하이퍼파라미터 cuda_launch_blocking (기본 꺼짐). 켜면 트레이너가 torch import 전에 CUDA_LAUNCH_BLOCKING=1 을 놓아 트레이스백이 진짜 커널을 가리킨다. 대신 느려진다.
  • describe_scene() 이 씬마다 segment 와 instance 범위를 검사한다. 클래스 인덱스가 모델의 클래스 수를 넘거나, "클래스는 있는데 인스턴스가 없는 점" 이 있으면 학습 시작 전에 실패한다. 앞 세 씬의 통계와, 인스턴스가 하나도 없는 씬 목록을 로그에 남긴다.

3차(blocking 켜고 실행)에서 재현되지 않았다. 비동기 경로의 일시적 현상으로 보고 계측만 남겼다. 다시 나오면 순서는 이렇다. cuda_launch_blocking: True 로 트레이스백 확보 → batch_size: 1 (씬 경계 문제 배제) → enable_amp: False.

4. 3차: 완주했는데 AP 가 전부 0

seg_loss: 0.0000   bias_l1_loss: 150 ~ 225
Val result: mAP/AP50/AP25 0.0000/0.0000/0.0000
Best validation AP50 updated to: 0.0000

seg_loss: 0.0000 은 정상이다. 클래스가 1개라 시맨틱 손실이 상수이고 seg_head 는 배울 것이 없다. 추론 때 pred_classes 는 항상 0 이다.

문제는 bias_l1_loss 다. 사용자 PLY 12개를 다시 재 본 값이다.

이 데이터

ScanNet (기본값이 맞춰진 기준)

씬 크기

749 × 594 × 494 단위

5~10 m

점에서 제 인스턴스 중심까지 평균 절대 오프셋

172.4

1~2

로그의 150~225 가 바로 이 172 다. 즉 오프셋 헤드가 아무것도 배우지 못한 상태의 손실에 그대로 앉아 있었다는 뜻이다. PointGroup 의 오프셋 헤드는 점마다 "내 인스턴스 중심까지의 변위" 를 회귀하고, 그 변위로 점들을 끌어모은 뒤 BFS 로 군집해 제안을 만든다. 오프셋이 안 모이면 제안이 없고, 제안이 없으면 AP 는 0 이다.

원인은 좌표 규모다. PointGroup 의 군집 반경(cluster_thresh)과 Pointcept 의 증강값 (RandomJitter sigma=0.005 clip=0.02)은 미터 단위 실내 씬(복셀 0.02 m)에 맞춰진 숫자다. 우리는 그 100배 규모를 그대로 넣고 있었다. 749 단위 씬에서 지터 0.005 는 아무 일도 하지 않는다. 여기에 2 epoch 만 돈 것이 겹쳤다.

조치

스테이징이 좌표에 배율만 건다. 사용자가 고른 grid_size(데이터 단위, 기본 0.6)가 TARGET_VOXEL = 0.02 가 되도록 스케일해서 저장하고, 생성되는 설정의 grid_size 와 voxel_size 는 그 값을 쓴다.

  • 복셀 격자는 그대로다. 같은 점이 같은 복셀에 묶인다. cluster_thresh 가 덮는 실제 거리도 데이터 0.9 단위 그대로다. 바뀐 것은 회귀 목표 크기(172 에서 5.7)와 증강 크기뿐이다.
  • 배율은 model_config["coord_scale"] 로 모델에 실린다. 서빙 pyfunc 이 같은 배율을 걸어 학습과 같은 규모로 본다. 결과는 점별 ID 라 좌표 규모의 영향을 받지 않는다.
  • 스테이징이 mean |offset| to the instance centre 를 로그에 찍는다.

5. 정상 로그 읽는 법

스테이징 구간에서 볼 것.

-> scene 10_final: {'points': 45470, 'instances': 3, 'labelled': 45470, 'classes': [0]}
-> coordinates scaled by 0.0333333 so the voxel is 0.02 ...
-> mean |offset| to the instance centre: 5.7 (PointGroup's bias_l1_loss starts near this; ScanNet sits at 1-2)
-> prepared 50 train / 12 val scene(s), 249 instance(s)
  • instances 가 0인 씬이 많으면 그만큼 오프셋 손실을 못 배운다. 별도 줄로 알려 준다.
  • labelled 가 points 보다 한참 작으면 미할당 인스턴스가 많다는 뜻이다. 데이터셋 화면의 할당표나 CSV 로 채운다.
  • mean |offset| 이 한 자리 수면 규모가 맞다. 세 자리 수면 이 문서 4장 상황이다.

학습 구간에서 볼 것.

  • bias_l1_loss 가 위 mean |offset| 근처에서 시작해서 내려가야 한다. 고정이면 학습이 안 되는 것이다.
  • seg_loss: 0.0000 은 단일 클래스에서 정상이다.
  • best 체크포인트는 평가기가 AP50 으로 고른다. mAP 가 아니다.
  • MLflow 지표 이름은 metrics/mAP, metrics/AP50, metrics/AP25 다.

6. AP 가 여전히 낮을 때 만질 순서

  1. 에폭. 2 epoch 로는 아무것도 나오지 않는다. 50~100 부터 본다.
  2. cluster_thresh (기본 1.5, 복셀 단위). 제안이 하나도 없으면 올리고, 물체가 전부 하나로 붙으면 내린다.
  3. cluster_min_points (기본 50), cluster_propose_points (기본 100). 작은 물체가 통째로 버려지면 내린다.
  4. batch_size: 1, enable_amp: False. 불안정한 실행을 좁힐 때만.

인스턴스가 2~5개인 파일 62개는 작은 데이터셋이다. ScanNet 사전학습 백본을 쓰지만 과적합 여지가 크고, 검증이 12개뿐이라 AP 의 분산도 크다. 한 번의 숫자로 결론 내지 않는 편이 좋다.

7. 재게시가 필요한 변경

트레이너와 pyfunc 은 학습 런타임 이미지 안에 들어간다. 즉 코드를 고치면 런타임을 다시 게시해야 실행에 반영된다. 지금까지 재게시가 필요했던 변경은 이렇다.

  • pointgroup_ops 휠 추가 (Phase 0)
  • np.in1d 복원 (1차 조치)
  • cuda_launch_blocking 과 씬 검사 계측 (2차 조치)
  • 좌표 배율 (3차 조치)

서빙 이미지는 학습 이미지를 FROM 으로 하므로, 학습 이미지를 새로 게시한 뒤에 만든 모델부터 새 pyfunc 으로 서빙된다. 이미 등록된 시맨틱 분할 모델의 서빙에는 영향이 없다. pyfunc 이 geo_task 로 분기하고 기본이 시맨틱 분할이다.

8. 파일 위치

무엇

경로

트레이너 디스패처

src/geo_mlops/resources/training_runtime/pointcept_train.py

인스턴스 분할 트레이너

src/geo_mlops/resources/training_runtime/pointcept_insseg.py

공용 헬퍼와 NumPy 호환

src/geo_mlops/resources/training_runtime/pointcept_semseg.py

서빙 pyfunc

src/geo_mlops/resources/training_runtime/pointcept_pyfunc.py

하이퍼파라미터 화이트리스트

src/geo_mlops/training/hyperparams.py

테스트

tester/training/test_pointcept_insseg.py

플랜과 진행 메모

docs/plans/50_pointgroup_instance_segmentation_plan.md

See also

Favorite site

lastmod 2026-09-23created 2026-09-23author Zer0 sitemap