제9부 로보틱스
9.6 VPI — 비전 가속
9.6.1 이 장에서 배우는 것 / 선수 지식
8.5(자율주행)에서 VPI(Vision Programming Interface) 가 클래식 비전을 여러 엔진에 가속하는 통일 API라고 봤다. 이 장은 그것을 로보틱스 실습 관점으로 판다 — 로봇 비전의 전처리·클래식 CV(스테레오 깊이·광학 흐름·특징 추적·보정·필터)를 VPI로 가속하는 법, 백엔드 선택, 스트림, interop. DeepStream(9.5)이 비디오 파이프라인을 다뤘다면, VPI는 그 안팎의 비전 프리미티브를 엔진에 매핑한다. SLAM(9.9)·인지의 전단 토대.
핵심 통찰: 로봇 비전도 DNN만이 아니다 — DNN 앞뒤로 클래식 CV(렉티피케이션·스테레오·특징·광학 흐름)가 필요하고, 이를 GPU로만 실행하면 비효율(GPU는 DNN에)이다(8.5). VPI가 이를 PVA·VIC·OFA·GPU·CPU 중 적합한 엔진에 매핑해, 같은 코드로 백엔드를 교체하며 전력 예산 안(9.4)에서 비전을 가속한다.
배우는 것:
- VPI 핵심 — 백엔드(CPU·GPU·PVA·VIC·OFA), 스트림(비동기), 이미지·interop.
- 알고리즘 — remap(보정)·rescale·스테레오 disparity·광학 흐름·특징(Harris/FAST)·KLT·필터.
- 엔진 선택 — 알고리즘마다 적합 백엔드, 로보틱스 전력 효율(8.4·9.4).
- interop — CUDA·OpenCV·DeepStream과 연동, 비전 전처리 → DNN(TensorRT).
- SLAM·인지 전단 — VPI가 cuVSLAM(9.9)·인지의 클래식 CV 토대.
선수 지식: 8.5(VPI 개념·PVA — 자율주행판, 단 그 장은 CPU·GPU·PVA 백엔드만 다룸)·9.4(통합 메모리·엔진 효율)·8.4(DLA/엔진 오프로드)·2.10(스트림). VIC·OFA는 이 장에서 처음 소개하는 Jetson 쪽 전용 엔진(8.2·8.5는 다루지 않음). SLAM은 9.9, Isaac은 9.7. 환경은 Jetson·VPI.
정직: VPI 백엔드·알고리즘 지원은 세대·Jetson 모듈 의존이다(VIC·OFA·PVA 가용성 다양) — 이 장은 백엔드 이식성·알고리즘·엔진 선택의 원리를 가르치고 구체 지원은 "그 모듈 문서로 확인". 코드는 개념 골격이다.
9.6.2 VPI 백엔드 — 엔진을 고른다
VPI의 핵심은 같은 비전 알고리즘을 여러 백엔드(엔진)에 실행하는 것이다(개념은 8.5, 단 Jetson은 VIC·OFA가 추가된 백엔드 목록):
알고리즘마다 적합한 백엔드를 골라 실행한다(같은 API).
- 엔진별 강점: PVA(특징·필터)·VIC(rescale·remap)·OFA(광학 흐름·스테레오)·GPU(유연)·CPU(폴백). 알고리즘이 어느 엔진에 잘 맞나가 다르다.
- 전력 효율(8.4·9.4): 비전을 PVA·VIC·OFA로 오프로드하면 GPU가 DNN(TensorRT)에 자유로워짐 — 엣지 전력 예산 안에서 비전+DNN을 병렬로. 8.5의 분업이 로보틱스에.
- 이식성: 같은 코드에서 백엔드만 바꿔(PVA↔GPU) — 부하·미지원이면 전환, 8.5의 "비전판 CUDA".
핵심: VPI는 "비전 알고리즘을 엔진에 자유롭게 매핑" 한다 — 로봇 비전(보정·스테레오·특징)을 PVA·VIC·OFA로 오프로드해 GPU를 DNN에 남기고, 전력 예산 안에서 병렬로. 같은 코드로 백엔드를 골라 실험·전환(8.5 자율주행판의 로보틱스 실습).
9.6.3 알고리즘 — 비전 프리미티브
VPI가 제공하는 클래식 비전 알고리즘(버전 의존, 로봇 비전의 토대):
- 전처리(remap·rescale): DNN·SLAM 입력 준비 — 왜곡 보정(remap, 캘리브레이션 8.13 적용)·크기 변환. VIC가 효율적.
- 스테레오·광학 흐름: 깊이·모션 — OFA(전용)·PVA·GPU. SLAM(9.9)·인지의 입력.
- 특징·추적(Harris·FAST·KLT): 코너·특징점 검출·추적 — SLAM의 전단(9.9 cuVSLAM이 특징을 추적해 위치 추정). PVA·GPU.
핵심: VPI는 로봇 비전의 클래식 CV 빌딩 블록(보정·스테레오·광학 흐름·특징·필터)을 엔진 가속으로 준다 — 이것이 DNN(TensorRT) 앞뒤의 전처리이자 SLAM(9.9)의 전단(특징·스테레오·광학 흐름). DNN만으론 안 되는 비전을 효율적으로.
9.6.4 스트림·이미지·interop
VPI의 실행·연동(실습 골격):
# VPI 비전 파이프라인(개념 — API·백엔드는 버전 확인)
import vpi
# 1) 스트림(비동기 실행, CUDA 스트림 2.10과 유사)
with vpi.Stream() as stream:
# 2) 백엔드 선택 + 알고리즘
with vpi.Backend.VIC:
rect = input_img.remap(warp_map) # 왜곡 보정(VIC, 8.13 캘리브)
with vpi.Backend.PVA: # 또는 OFA/CUDA
disparity = vpi.stereodisparity(left_rect, right_rect, ...) # 스테레오
with vpi.Backend.CUDA:
features = rect.harriscorners(...) # 특징(또는 PVA)
stream.sync() # 비동기 완료 대기
# 3) interop: VPI ↔ CUDA(GPU)·OpenCV (zero-copy where possible, 9.4)
# disparity를 CUDA로 넘겨 DNN(TensorRT) 입력, 또는 OpenCV로 시각화
- 스트림: VPI 스트림으로 알고리즘을 비동기·파이프라인(2.10 CUDA 스트림 정신) — 엔진들이 병렬로, CPU가 안 막힘.
- 이미지·버퍼: VPI 이미지가 메모리를 감쌈, CUDA·OpenCV와 interop(가능하면 zero-copy, 통합 메모리 9.4) — 복사 없이 공유.
- interop: 비전 전처리(VPI) → DNN(TensorRT, CUDA 버퍼) → 후처리, DeepStream(9.5)·OpenCV와 연동 — 파이프라인의 일부.
견해: VPI는 스트림(비동기)·백엔드 선택·interop로 비전 파이프라인을 짠다 — remap을 VIC로, 스테레오를 OFA/PVA로, 특징을 PVA/GPU로 병렬로 실행하고, 결과를 CUDA(DNN)·OpenCV로 zero-copy 연동(9.4). 엔진 분업(8.5)을 코드로, 전력 예산 안(9.4)에서. SLAM(9.9)·DNN의 전처리.
9.6.5 워크스루 — 스테레오 깊이 파이프라인
로봇의 스테레오 카메라로 깊이를 만드는 VPI 파이프라인(개념).
엔진 분배(8.5·9.4): remap=VIC, 스테레오=OFA(전용·효율), 특징=PVA → GPU는 DNN에 자유로워진다.
견해: 스테레오 깊이는 캘리브레이션(8.13) → remap(VIC) → 스테레오(OFA/PVA) 로, 엔진에 분배해 GPU를 DNN에 남긴다. VPI로 백엔드를 골라(전력 효율 9.4·8.4) 병렬로. 깊이는 SLAM(9.9)·장애물 인지·계획의 입력 — VPI가 그 전단. 캘리브레이션이 틀리면 스테레오가 무너지니(8.13·8.10) 정확도가 안전 직결.
9.6.6 중간 점검 (체크포인트)
- [ ] VPI가 비전 알고리즘을 여러 백엔드(CPU·GPU·PVA·VIC·OFA) 에 실행하는 통일 API임과 백엔드 이식성을 안다(8.5).
- [ ] 알고리즘(remap·rescale·스테레오·광학 흐름·특징·KLT·필터)과 로봇 비전·SLAM 전단에서의 역할을 안다.
- [ ] 엔진 선택(알고리즘별 적합 백엔드)이 GPU를 DNN에 남기는 전력 효율(8.4·9.4)을 줌을 안다.
- [ ] 스트림(비동기)·이미지·interop(CUDA·OpenCV·DeepStream, zero-copy 9.4)을 안다.
- [ ] VPI가 SLAM(9.9)·DNN의 비전 전단 토대임을 안다.
증상→의심: 비전 전처리가 GPU 점유 → PVA/VIC/OFA로 오프로드(8.5·9.4). 스테레오 부정확 → 캘리브레이션·remap(8.13) → 보정 확인. 비전이 직렬로 느림 → 스트림 병렬·엔진 분배. VPI↔CUDA 복사 낭비 → interop·zero-copy(9.4). 알고리즘이 특정 백엔드서 안 됨 → 미지원 → 다른 백엔드(8.5). 엣지 전력 초과 → 비전을 효율 엔진(PVA/VIC)에, DLA로 DNN(8.4·9.4). SLAM 특징 부족 → Harris/FAST 파라미터.
9.6.7 트레이드오프·대안
| 결정 | 트레이드오프 |
|---|---|
| PVA/VIC/OFA vs GPU(비전) | 효율·전용·GPU 자유 vs 유연(8.5·9.4) |
| VPI vs OpenCV | 다엔진 가속·이식 vs 친숙·CPU 중심 |
| 클래식 CV vs DNN(깊이) | 효율·해석 vs 정확·고부하 |
| 백엔드 고정 vs 전환 | 최적 vs 데이터 이동 오버헤드 |
견해: 로봇 비전 전처리·클래식 CV는 VPI로 PVA/VIC/OFA에 오프로드해 GPU를 DNN에 남긴다(8.5·9.4) — 엣지 전력 효율. OpenCV는 친숙하나 CPU 중심·다엔진 가속이 약하니, Jetson 엔진 가속·전력 효율이 필요하면 VPI. 깊이는 클래식(스테레오, 효율)·DNN(정확) 중 선택. interop으로 DNN(TensorRT)·DeepStream(9.5)과 연동. SLAM(9.9)이 그 위에.
비엔비디아 정직: 클래식 비전 가속은 OpenCV(CUDA 모듈)·OpenVX·다른 라이브러리도 있다. VPI의 강점은 PVA·VIC·OFA 전용 엔진·CUDA interop·Jetson/DRIVE 공통·전력 효율이다. OpenCV가 익숙하고 CPU/GPU면 충분할 때도 있으나, Jetson 전용 엔진(PVA/VIC/OFA)·전력 효율이 필요하면 VPI. 백엔드 지원은 세대 의존.
9.6.8 흔한 함정
- 비전 전처리를 GPU로만. GPU는 DNN에 — 클래식 CV는 PVA/VIC/OFA로 오프로드(8.5·9.4) 전력 효율.
- 캘리브레이션 없이 스테레오. remap(보정) 없으면 스테레오가 같은 행 대응을 못 찾아 부정확 → 캘리브레이션(8.13).
- 백엔드 미지원 강행. 알고리즘이 특정 백엔드서 안 되면 다른 백엔드(8.5).
- interop 복사. VPI↔CUDA를 복사하면 이점 상실 → zero-copy(통합 메모리 9.4).
- 직렬 실행. 스트림 없이 직렬이면 엔진 병렬 못 누림 → 스트림(2.10).
- OpenCV로 다엔진 가속 기대. OpenCV는 CPU/GPU 중심 — Jetson 엔진(PVA/VIC/OFA)은 VPI.
- 엣지 전력 무시. 비전+DNN을 GPU로만 → 전력 초과 → 엔진 분업(VPI·DLA, 8.4·9.4).
- 백엔드·알고리즘 버전 불문. VPI 지원이 세대 의존 — 확인.
9.6.9 연습문제
연습 1 (백엔드). VPI가 같은 알고리즘을 여러 백엔드에 실행하는 것이 로봇 비전에서 왜 전력 효율을 주는지 설명하라(8.5·9.4 연결).
정답
로봇 비전은 DNN(TensorRT)뿐 아니라 클래식 CV(보정·스테레오·광학 흐름·특징·필터)가 DNN 앞뒤로 필요하다. 이를 GPU로만 실행하면 GPU가 클래식 CV에도 쓰여 ① DNN(인지)과 경합하고 ② GPU의 범용 오버헤드로 비효율(8.5). VPI가 백엔드 선택을 주면: 클래식 CV를 전용·효율 엔진(PVA·VIC·OFA, 8.5·8.2)에 오프로드 — remap을 VIC, 스테레오/광학 흐름을 OFA, 특징/필터를 PVA에. 그러면 ① GPU가 DNN에 자유로워짐(인지 추론에 집중), ② 클래식 CV가 전용 엔진에서 적은 전력으로(전력 효율, 9.4 엣지 전력 천장), ③ 엔진들이 병렬로(비전+DNN 동시) → 전력 예산 안에서 처리량↑. 같은 코드에서 백엔드만 바꿔(PVA↔GPU) 부하·미지원에 대응하고 최적 엔진을 고름(8.5 "비전판 CUDA"). 9.4(통합 메모리·전력 운영)와 맞물려: 비전을 효율 엔진에, DNN을 GPU+DLA(8.4)에 분배해 전력 천장(8.1) 안에서. 즉 VPI의 백엔드 이식성이 엔진 분업(8.5)을 실용화해, 로봇이 제한된 전력으로 비전+DNN을 모두 실행하게 한다 — GPU로 다 하면 전력 초과·경합. 데이터센터(전력 풍부)는 GPU로 다 해도 되지만 엣지 로봇(9.1·9.4)은 분업이 필수.
연습 2 (스테레오 파이프라인). 로봇 스테레오 카메라로 깊이를 만드는 VPI 파이프라인을 단계로 설계하고 엔진을 매핑하라.
정답
파이프라인: ① 캘리브레이션(8.13) — intrinsic(렌즈 왜곡)·extrinsic(좌우 카메라 상대 위치)을 추정해 warp map 생성(오프라인·자가). ② remap(보정·렉티피케이션) → VIC(또는 PVA) — 좌·우 영상의 왜곡을 보정하고 렉티피케이션(두 영상을 같은 평면·행으로 정렬). 필수: 보정 안 하면 스테레오가 같은 행에서 대응점을 못 찾아 깊이가 틀림. ③ 스테레오 disparity → OFA(전용·효율, 일부 세대)/PVA/GPU — 좌·우 영상을 정합해 disparity(픽셀 시차) → 깊이. ④ (선택) 후처리 → PVA/GPU — 필터·신뢰도 마스크. ⑤ interop — disparity를 CUDA 버퍼로(zero-copy, 9.4) → DNN(장애물 인지)·SLAM(9.9)·계획 입력. 엔진 매핑: remap=VIC, 스테레오=OFA(전용)/PVA, 후처리=PVA → GPU는 DNN에 자유(8.5·9.4 분업). 스트림으로 비동기 병렬(2.10). 검증: 백엔드별 성능·전력(tegrastats 9.4), remap 정확도(캘리브레이션 8.13 — 틀리면 깊이 오류, 안전 8.10). 깊이의 용도: SLAM(9.9)·장애물 회피·매니퓰레이션(9.10)·계획. VPI가 스테레오 전단을 엔진 가속으로, 캘리브레이션(8.13)이 정확도를. 클래식 스테레오(VPI) vs 깊이 DNN(GPU/DLA) 중 정확도·전력으로 선택(또는 융합). 핵심: 캘리브레이션→remap→스테레오를 엔진에 분배, GPU를 DNN에 남김, 깊이를 SLAM·인지에.
연습 3 (SLAM 전단). VPI가 SLAM(9.9)의 전단이라는 말의 의미를, 특징·광학 흐름·스테레오로 설명하라.
정답
SLAM(Simultaneous Localization and Mapping, 9.9)은 로봇이 자기 위치를 추정하며 지도를 만드는 것으로, 그 입력에 클래식 비전이 필요하다 — VPI가 그 전단(front-end) 을 제공: ① 특징 검출·추적(Harris/FAST·KLT) — SLAM(특히 visual SLAM)은 영상에서 특징점(코너) 을 검출하고 프레임 간 추적해, 그 특징의 움직임으로 카메라(로봇) 이동을 추정한다. VPI의 Harris/FAST(검출)·KLT(추적)가 이 특징 전단. ② 광학 흐름 — 프레임 간 픽셀 이동을 계산해 모션 추정·추적 보조. ③ 스테레오 disparity — 스테레오 SLAM은 깊이(스테레오)로 3D 구조·스케일을 얻음. VPI 스테레오가 그 깊이. ④ remap(보정) — 특징·스테레오 전에 왜곡 보정(8.13)으로 정확도. 즉 SLAM은 "특징을 추적해 위치 추정 + 깊이로 지도"인데, 그 특징·광학 흐름·스테레오를 VPI가 엔진 가속으로 제공(PVA·OFA·GPU). SLAM 알고리즘(cuVSLAM 9.9)은 이 전단 위에서 위치·지도를 계산(백엔드는 GPU). VPI가 전단을 효율 엔진에 오프로드하면 GPU·전력을 SLAM 백엔드·DNN에 남김(9.4). 의미: VPI는 SLAM의 "비전 입력(특징·깊이·흐름)"을 만드는 토대 — SLAM이 위에서 그것을 위치·지도로. 로봇 인지(SLAM·장애물·매니퓰레이션)가 모두 이 클래식 CV 전단에 의존. 캘리브레이션(8.13)·VPI(전단)·SLAM(9.9)이 이어지는 로봇 인지 스택.
연습 4 (VPI vs OpenCV). 로봇 비전에 VPI와 OpenCV 중 무엇을 권하고, 각각이 맞는 경우는?
정답
VPI가 맞을 때: ① Jetson 전용 엔진 가속 — PVA·VIC·OFA(8.5·8.2)에 비전을 오프로드해 GPU를 DNN에 남기는 전력 효율(8.4·9.4). 엣지 전력 천장(8.1)에서 비전+DNN을 모두 실행해야 할 때. ② 백엔드 이식성 — 같은 코드로 백엔드를 골라(PVA↔GPU) 최적 엔진·전환. ③ CUDA interop·zero-copy(9.4)로 DNN(TensorRT)·DeepStream(9.5)과 효율 연동. ④ DRIVE·Jetson 공통(8.5). 즉 전력 효율·다엔진·프로덕션 로봇. OpenCV가 맞을 때: ① 친숙·풍부 — 방대한 알고리즘·생태계·문서, 빠른 프로토타입·실험. ② CPU/GPU 중심 — PVA/VIC/OFA 전용 엔진이 필요 없고 CPU 또는 CUDA로 충분하면. ③ 이식성(비-Jetson) — 일반 플랫폼·데스크톱. 단 OpenCV는 Jetson 전용 엔진(PVA/VIC/OFA)을 못 씀(CPU/CUDA 위주)이라 엣지 전력 효율·GPU 자유화가 약함. 판단 기준: Jetson 엣지·전력 효율·GPU를 DNN에 남기기 = VPI, 친숙·프로토타입·CPU/GPU 충분·비-Jetson = OpenCV. 둘을 함께 쓰기도(VPI 가속 + OpenCV interop). VPI는 OpenCV interop을 지원해 시각화·일부 알고리즘은 OpenCV로. 핵심: Jetson 전용 엔진·전력 효율이 필요한 프로덕션 로봇 비전이면 VPI, 빠른 개발·CPU 중심이면 OpenCV. 전력 천장(9.4)이 결정적이면 VPI(PVA/VIC/OFA로 GPU 자유화). 세대별 백엔드 지원은 확인.
연습 5 (엔진 분업). 로봇이 매 프레임 (a) 영상 보정, (b) 스테레오 깊이, (c) 특징 추적, (d) 검출 DNN을 한다. VPI·DLA·GPU로 엔진을 분배하라.
정답
분배(엔진 분업 8.5·9.4·8.4): (a) 영상 보정(remap/rescale) → VPI on VIC(전용 rescale/remap 엔진) — 캘리브레이션(8.13) 적용, 효율. (b) 스테레오 깊이 → VPI on OFA(광학 흐름/스테레오 전용, 일부 세대)/PVA — 전용 엔진으로 효율. (c) 특징 추적(Harris/FAST·KLT) → VPI on PVA(또는 GPU) — 클래식 비전 전용. (d) 검출 DNN → DLA(8.4, 표준 DNN 효율) + GPU(신규·overflow). 결과: 클래식 비전(보정·스테레오·특징)을 VIC·OFA·PVA에, DNN을 DLA(+GPU)에 분배 → GPU가 비교적 자유(융합·계획·신규 DNN에), 모든 엔진이 병렬(VPI 스트림 2.10·매 프레임 동시) → 전력 예산 안(9.4·8.1)에서 다 처리. 데이터는 GPU/통합 메모리에 유지(zero-copy interop 9.4) — VPI↔CUDA(DNN)·DeepStream(9.5) 복사 없이. 이것이 8.5(자율주행 엔진 분업)의 로보틱스판 — ISP/VIC(전처리)·PVA/OFA(클래식 CV)·DLA(DNN)·GPU(유연·융합)·CPU(제어)가 각자 잘하는 것을 병렬로. VPI가 비전을, TensorRT가 DNN을, 엔진 매핑으로 전력 효율. 깊이·특징은 SLAM(9.9)·인지에, 검출은 장애물·계획에. 핵심: 매 프레임 여러 비전·DNN 작업을 적합한 엔진에 분배·병렬해 전력 천장 안에서 — GPU로 다 하면 경합·전력 초과(드론은 특히). tegrastats(9.4)로 각 엔진 활용·전력 모니터해 튜닝.
9.6.10 요약 · 다음 장
- VPI는 클래식 비전(remap·rescale·스테레오·광학 흐름·특징·KLT·필터)을 여러 백엔드(CPU·GPU·PVA·VIC·OFA) 에 실행하는 통일 API(8.5) — 로봇 비전 전처리·SLAM 전단.
- 엔진 선택으로 비전을 PVA/VIC/OFA에 오프로드해 GPU를 DNN에 남기는 전력 효율(8.4·9.4) — 엣지 전력 천장(8.1) 안에서 비전+DNN 병렬. 8.5 분업의 로보틱스판.
- 스트림(비동기)·interop(CUDA·OpenCV·DeepStream, zero-copy 9.4) 으로 파이프라인 — 비전(VPI) → DNN(TensorRT)·SLAM.
- 스테레오 깊이: 캘리브레이션(8.13)→remap(VIC)→스테레오(OFA/PVA) 를 엔진에 분배. 캘리브레이션이 정확도·안전(8.10)을 좌우.
- VPI는 SLAM(9.9)·DNN의 비전 전단 — 특징·광학 흐름·스테레오를 가속 제공. 정직: 백엔드 지원 세대 의존, Jetson 전용 엔진이 필요하면 VPI(OpenCV는 CPU/GPU 중심).
다음 장: 9.7 Isaac ROS I — NITROS·GPU 가속 ROS 2. 비전·추론 가속을 봤으니, 로봇 소프트웨어의 표준 ROS 2를 GPU 가속하는 Isaac ROS — 노드 간 GPU 데이터를 zero-copy로 전달하는 NITROS와 가속 그래프 구조를 본다. ROS 2 위에서 인지·SLAM·매니퓰레이션을 GPU로.