Post

[리뷰] 단 한 장의 사진이 실시간 렌더링을 만나기까지: Deep-Live-Cam 아키텍처 해부와 실무 적용기

[리뷰] 단 한 장의 사진이 실시간 렌더링을 만나기까지: Deep-Live-Cam 아키텍처 해부와 실무 적용기

현업에서 10년 넘게 코드를 만지며 수많은 오픈소스를 뜯어봤지만, 최근처럼 ‘비전 AI’ 생태계가 실시간(Real-time) 영역으로 무섭게 침투하는 걸 보면 경외감과 피로감이 동시에 몰려옵니다. 프로젝트를 진행하며 최신 트렌드를 따라잡는 것도 벅찬데, 하루가 다르게 쏟아지는 새로운 툴들은 우리를 끊임없이 시험에 들게 하죠.

과거 영상 딥페이크 기술, 특히 DeepFaceLab이나 DeepFaceLive 같은 초창기 툴을 실무에 도입해보려다 좌절했던 경험, 다들 한 번쯤 있으실 겁니다. 수천 장의 프레임 추출, 얼굴 정렬, 그리고 RTX 3090을 갈아 넣으며 48시간 동안 Loss 값이 떨어지기만을 기도하던 그 지루한 파이프라인 말입니다. ‘이걸 현업에서 라이브 서비스에 태울 수 있을까?’라는 질문에 당시의 저는 회의적이었습니다. 하지만 시대가 변했습니다. 단 한 장의 사진, 그리고 웹캠. 이 두 가지만 있으면 실시간으로 얼굴이 바뀌는 시대가 온 거죠.

오늘 우리가 커피 한 잔을 곁들여 뜯어볼 프로젝트는 최근 GitHub 생태계를 뜨겁게 달군 Deep-Live-Cam입니다. 단순한 ‘신기한 장난감’을 넘어, 이 툴이 어떻게 실시간 렌더링의 병목을 뚫어냈는지, 그리고 그 이면에 숨겨진 엔지니어링적 타협점은 무엇인지 개발자의 시선에서 집요하게 파헤쳐보겠습니다.

TL;DR: Deep-Live-Cam은 무거운 모델 학습 과정을 완전히 제거한 단일 이미지 기반 Zero-shot 페이스 스왑 파이프라인으로, ONNX Runtime의 이기종(Heterogeneous) 하드웨어 가속을 영리하게 활용하여 컨슈머급 PC에서도 실시간 웹캠 추론을 가능하게 만든 파이프라인 엔지니어링의 훌륭한 레퍼런스입니다.


Deep Dive: Under the Hood (내부 아키텍처 해부)

단순히 python run.py를 실행해서 얼굴이 바뀌는 것에 만족한다면 우리는 기획자나 일반 유저와 다를 바 없습니다. 개발자라면 이 코드가 GPU 메모리 위에서 어떻게 춤을 추고 있는지 그 파이프라인의 코어 로직을 이해해야 합니다. 이 프로젝트의 핵심은 새로운 AI 모델을 바닥부터 학습시킨 것이 아니라, 기존에 존재하던 강력한 모델들(InsightFace, inswapper, GFPGAN)을 실시간(Real-time)이라는 제약 조건 아래에서 어떻게 최적화하여 엮어냈는가에 있습니다.

이 파이프라인은 크게 5단계의 생명 주기를 거칩니다.

1. Frame Acquisition & Queueing (프레임 획득과 큐잉) 실시간 웹캠 스트림은 cv2.VideoCapture를 통해 들어옵니다. 여기서 흥미로운 점은 I/O 바운드 작업인 프레임 캡처와 연산 집약적인(Compute-bound) AI 추론을 분리하기 위해 Producer-Consumer 패턴의 큐(Queue) 아키텍처를 활용한다는 것입니다. 메인 스레드가 블로킹되는 순간 라이브 캠의 FPS는 나락으로 떨어지기 때문에, 프레임 버퍼링을 적절히 관리하는 것이 첫 번째 핵심입니다.

2. Face Detection & Alignment (얼굴 탐지와 정렬) 웹캠 프레임이 들어오면 RetinaFace 또는 YOLOv8-face 모델이 얼굴의 Bounding Box와 5개의 핵심 랜드마크(눈, 코, 입꼬리)를 찾습니다. 여기서 끝이 아닙니다. 다음 단계의 스와퍼(Swapper) 모델은 정확히 정면을 바라보고 있는 128x128 픽셀 크기의 얼굴을 기대합니다. 따라서 랜드마크를 기반으로 얼굴을 회전하고 잘라내는 어파인 변환(Affine Transformation)이 매우 정교하게 일어납니다. 수학적인 행렬 곱셈이 GPU 위에서 쉴 새 없이 돌아가는 순간이죠.

3. Identity Injection (특징 추출 및 주입) 여기가 마법이 일어나는 구간입니다. 사전에 ArcFace 모델을 통해 타겟 사진(바꾸고 싶은 얼굴)에서 512차원의 임베딩 벡터(Identity)를 추출해 둡니다. 그리고 웹캠에서 잘라낸 내 얼굴 이미지와 이 임베딩 벡터를 inswapper_128.onnx 모델에 동시에 밀어 넣습니다. 이 모델은 내 얼굴의 표정, 포즈, 조명은 유지한 채, 픽셀의 질감과 이목구비의 형태만 타겟 사진의 임베딩으로 교체하여 디코딩합니다.

4. Face Enhancement (업스케일링 및 디테일 복원) 가장 VRAM을 많이 파먹는 주범이자 딜레마의 구간입니다. inswapper 모델의 태생적 한계 때문에 결과물이 128x128 해상도로 나옵니다. 요즘 같은 4K 시대에 128픽셀짜리 얼굴을 1080p 웹캠 화면에 그대로 붙이면 모자이크처럼 보일 수밖에 없죠. 이를 해결하기 위해 GFPGAN이나 CodeFormer 같은 복원 모델을 태워 해상도를 뻥튀기합니다. 하지만 프레임당 이 복원 모델을 태우는 순간 FPS가 반토막 나는 트레이드오프가 발생합니다.

5. Seamless Blending (자연스러운 합성) 마지막으로 업스케일링된 얼굴을 원래 웹캠 프레임의 위치로 역변환(Inverse Affine Transform)하고, 가장자리가 어색하지 않게 마스크를 씌워 알파 블렌딩(Alpha Blending)을 수행합니다.

이를 가능하게 하는 기반 기술은 단연코 ONNX Runtime입니다. 파이토치(PyTorch) 네이티브로 돌리지 않고 ONNX로 변환된 모델을 사용하는 이유는 완벽한 크로스 플랫폼 및 이기종 하드웨어 대응 때문입니다.

Execution Provider (EP)타겟 하드웨어특징 및 현업 평가
CUDAExecutionProviderNVIDIA GPU가장 안정적이고 빠릅니다. cuDNN과의 시너지가 좋으나 VRAM 누수 관리가 필요합니다.
CoreMLExecutionProviderApple Silicon (M1/M2/M3)Mac 환경에서 CPU 렌더링을 피하게 해주는 구원투수입니다. ANE(Apple Neural Engine)를 적극 활용합니다.
DmlExecutionProviderAMD / Intel GPUDirectML 기반. 윈도우 환경에서 엔비디아가 아닌 유저들을 위한 범용적인 대안이지만 초기 로딩이 깁니다.

Hands-on / Pragmatic Use Cases (실무에서는 어떻게 쓸까?)

“그래, 기술 좋은 건 알겠는데 이걸 당장 현업 프로젝트에 어떻게 쓰지?”

제가 동료들과 이 레포지토리를 테스트하며 논의했던 실무 적용 가능한 창의적 시나리오는 다음과 같습니다.

첫째, 프라이버시가 보장되는 원격 회의 시스템 (Virtual Avatar 2.0)입니다. 재택근무 시 카메라를 켜는 것에 부담을 느끼는 팀원들이 많습니다. 기존의 3D 아바타(VTuber 스타일)는 프로페셔널한 비즈니스 미팅에서 불쾌한 골짜기를 유발하거나 분위기를 해치는 경우가 있죠. Deep-Live-Cam을 활용해 ‘가장 단정하게 차려입은 내 사진’ 한 장을 베이스로 적용하면, 잠옷 바람으로 회의에 참석하더라도 화면 속의 나는 완벽한 비즈니스 룩과 자연스러운 표정으로 회의를 진행할 수 있습니다. 엔터프라이즈 화상 솔루션의 프리미엄 기능으로 기획해볼 만한 가치가 있습니다.

둘째, 미디어 및 게임 제작 파이프라인에서의 Rapid Prototyping입니다. 영상 프로덕션에서 특정 배우의 스케줄이 맞지 않을 때 대역 배우가 연기를 하고, 감독은 모니터링 화면을 통해 타겟 배우의 얼굴이 실시간으로 합성된 프리비즈(Pre-vis) 영상을 보며 디렉팅을 할 수 있습니다. 후반 작업(Post-production)에 들어가기 전 씬의 느낌을 확인하는 용도로는 이만한 가성비가 없습니다.


Honest Review (환상 너머의 진짜 장단점)

자, 이제 칭찬은 멈추고 냉정하게 칼을 들이대 봅시다. 솔직히 까놓고 말해서, 이 툴을 로컬 환경에 완벽하게 세팅하고 60 FPS 방어까지 해내는 과정은 결코 순탄치 않습니다.

가장 먼저 우리를 괴롭히는 건 끔찍한 의존성(Dependency) 지옥입니다. 파이썬 환경에서 insightface를 설치해 본 윈도우 개발자라면 깊이 공감하실 겁니다. 터미널을 붉게 물들이는 Microsoft Visual C++ 14.0 or greater is required 에러 메시지. C++ 빌드 툴을 깔고 환경 변수를 잡아주는 과정은 주니어 개발자들의 멘탈을 흔들기에 충분합니다. 패키지 버전 충돌(특히 ONNX Runtime과 CUDA 툴킷 버전의 호환성)은 아직 이 프로젝트가 프로덕션 레벨보다는 실험실 수준에 머물러 있음을 보여줍니다.

기술적인 한계점도 명확합니다. 가장 큰 치명타는 측면 얼굴(Side-profile) 인식의 한계입니다. 고개를 좌우로 45도 이상 돌리거나 위아래로 크게 끄덕일 때, YOLO나 RetinaFace가 랜드마크를 놓치는 순간 얼굴 마스크가 기괴하게 튀어 오르는(Flickering) 현상이 발생합니다. 2D 이미지 기반 어파인 변환의 태생적 한계죠.

또한 앞서 언급한 128x128 해상도의 병목도 문제입니다. 실시간성을 확보하기 위해 GFPGAN 업스케일러를 끄는 순간, 얼굴은 2000년대 초반 하두리 캠 시절로 돌아갑니다. 반대로 업스케일러를 켜면 RTX 4090이 아닌 이상 웹캠의 프레임이 10~15 FPS로 뚝 떨어지며 엄청난 입력 지연(Latency overhead)이 발생합니다. 내가 입을 벌리고 나서 0.5초 뒤에 화면 속 얼굴이 입을 벌리는 현상은 아직 실시간 라이브 커머스 등에 바로 적용하기엔 무리가 있다는 뜻입니다.


Closing Thoughts (마치며)

Deep-Live-Cam은 무거운 학습 모델을 버리고, 가벼운 추론 파이프라인의 조합으로 ‘실시간 렌더링’이라는 시대적 요구를 훌륭하게 만족시킨 프로젝트입니다. 완벽하지는 않지만, 우리가 앞으로 마주할 생성형 AI의 경량화 및 엣지 컴퓨팅(Edge Computing) 트렌드를 가장 적나라하게 보여주는 예시이기도 하죠.

하지만 개발자로서 기술적 희열만 느끼고 끝내서는 안 됩니다. 단 한 장의 사진만으로 누군가의 정체성(Identity)을 실시간으로 도용할 수 있다는 사실은, 이 기술이 언제든 악용될 수 있는 윤리적 지뢰밭임을 의미합니다. 워터마크 강제 삽입, 합성 여부 탐지 메타데이터(C2PA) 표준 적용 등, 기술의 발전 속도에 발맞춰 시스템의 방어 로직을 함께 고민하는 것이 다음 세대 비전 AI를 다루는 우리 엔지니어들의 가장 중요한 숙제가 아닐까 싶습니다.

References

  • https://github.com/hacksider/Deep-Live-Cam
  • https://onnxruntime.ai/docs/execution-providers/
This post is licensed under CC BY 4.0 by the author.