화조당(花鳥堂) — AI 사주 명리 서비스 2026.06.08

프레임 단위의 집착 — 유나 롱폼 영상 제작기

클로즈업 드리프트, 립싱크 밀림, GPU 과열. AI 영상 파이프라인에서 '프레임 단위 품질'을 잡기까지의 사흘.

AI 영상을 만든다는 건, 결국 프레임 단위의 싸움이다. 이번 사흘(6월 4일~7일)은 그걸 온몸으로 체감한 시간이었다. 유나의 롱폼 에피소드 하나를 완성하기까지, 클로즈업 드리프트, 립싱크 밀림, GPU 과열이라는 세 마리 괴물과 싸웠다.

Threads 콘텐츠 2차 정리 — 키워드로는 부족하다

프레임 단위의 집착 — 유나 롱폼 영상 제작기

6월 4일, 먼저 Threads 콘텐츠 2차 정리에 들어갔다. 1차 정리 때 걸러내지 못한 문제들이 눈에 띄었다. 날씨·계절 언급이 곳곳에 남아 있었고, 번역체 특유의 딱딱한 문장들이 자연스러운 한국어 흐름을 깨고 있었다. 전면 제거하고 자연화하는 작업을 진행했다.

여기서 하나 깨달은 게 있다. 키워드 기반 탐지로는 불충분하다. "봄바람이 불어오네요" 같은 직접적 표현은 잡을 수 있지만, "포근한 공기가 감도는 오후" 같은 간접적 계절 묘사는 키워드 필터로 잡기 어렵다. 번역체 판별도 마찬가지다. "그것은 매우 중요한 것입니다" 같은 패턴은 규칙으로 잡을 수 있지만, 미묘하게 어색한 어순이나 조사 사용은 사람이 읽어야 느낄 수 있는 수준이다.

결론은 명확했다. LLM 의미판단이 필수다. 키워드 매칭은 1차 스크리닝 용도로만 쓰고, 최종 판단은 LLM이 문맥을 보고 해야 한다. 이건 단순한 기술적 선택이 아니라, 콘텐츠 품질 파이프라인 전체의 설계 원칙이 되어야 할 문제다.

유튜브 롱폼 제작 착수 — Node v24의 기습

같은 날, 유튜브 26-25 롱폼 에피소드 제작에 들어갔다. 그런데 시작부터 문제가 터졌다. Node v24 환경에서 Windows 크래시가 발생한 것이다.

영상 파이프라인의 상당 부분이 Node 기반 스크립트로 돌아가는데, v24로 올라가면서 특정 구간에서 프로세스가 죽어버렸다. 원인 추적에 시간을 쓰기보다 실용적 해결책을 택했다. resume 래퍼를 만들어서, 크래시가 나면 마지막 완료 지점부터 자동으로 재개하도록 했다. 완벽한 해결은 아니지만, 제작을 멈출 수는 없으니까. 이런 래퍼는 한번 만들어두면 다른 프로젝트에서도 계속 쓸 수 있어서, 투자할 가치가 있다.

클로즈업 모핑 — 드리프트와의 첫 대면

ComfyUI를 이용한 프레임 립싱크 생성 렌더러 파이프라인

6월 6일. 완성본을 처음 통째로 돌려봤을 때, 신 41, 48, 60에서 이상한 현상이 보였다. 전신 샷이 클로즈업으로 서서히 모핑되는 것이다. 유나가 말하기 시작하면 카메라가 점점 얼굴 쪽으로 당겨지듯 구도가 바뀐다. AI가 만든 영상에서 흔히 보이는 드리프트 현상인데, 이번엔 원인이 꽤 명확했다.

두 가지가 겹쳤다:

  1. talk 프롬프트가 클로즈업을 유도하고 있었다. "speaking to camera", "talking" 같은 프롬프트 요소가 모델에게 무의식적으로 클로즈업 구도를 암시했다. 사람이 말할 때 얼굴을 클로즈업하는 건 영상 문법의 관례인데, 모델이 그 패턴을 학습하고 있었던 거다.
  2. 드리프트 검사 도구가 파이프라인에 연결되어 있지 않았다. measureDrift() 함수 자체는 만들어둔 상태였는데, 실제 생성 파이프라인에 게이트로 걸어두지 않았다. 감시 없는 품질관리는 품질관리가 아니다.

대응은 세 갈래로 진행했다:

  • 프롬프트 재작성: 구도를 명시적으로 고정하는 방향으로 수정. "full body shot, fixed camera angle, no zoom" 같은 제약 조건을 넣었다.
  • 네거티브 프롬프트 강화: "close-up", "face zoom", "camera movement" 등을 네거티브에 추가했다.
  • measureDrift() 파이프라인 연결: 생성된 각 프레임의 구도 변화량을 측정하고, 임계값을 넘으면 해당 클립을 재생성하도록 게이트를 걸었다.

립싱크 밀림 — 두 번째 전선

클로즈업 드리프트를 잡았더니 다음 문제가 드러났다. 립싱크 밀림이다. 유나의 입 움직임과 음성이 미묘하게 어긋나는 구간들이 있었다. 몇 프레임 차이인데, 보는 사람 입장에서는 꽤 거슬린다.

이건 드리프트 수정 과정에서 프롬프트 밸런스가 깨지면서 생긴 2차 문제였다. 구도를 고정하려고 프롬프트를 강하게 제약했더니, 모델이 입 움직임 생성에 할당하는 "주의력"이 줄어든 것으로 보였다. AI 모델에서 프롬프트는 제로섬에 가깝다. 한쪽을 강하게 제약하면 다른 쪽이 약해진다.

프롬프트 재균형을 했다. 구도 고정 조건은 유지하되, 립싱크 관련 힌트의 가중치를 올렸다. 그리고 측정 게이트를 추가했다. 드리프트 측정과 함께 립싱크 정합도도 자동으로 체크해서, 두 기준을 모두 통과한 클립만 최종 파이프라인에 남기도록 했다.

여기에 하나 더. ComfyUI에서 여러 job을 동시에 큐에 넣으면 poll timeout이 발생하는 문제가 있었다. GPU 리소스를 두고 job들이 경합하면서 타임아웃이 나는 거다. 해결은 단순하게 갔다. 단일 job 순차 실행. 병렬 처리의 유혹을 버리고, 한 번에 하나씩 확실하게 처리하는 방식으로 전환했다. 느려 보이지만, 실패와 재시도로 낭비되는 시간을 감안하면 오히려 빠르다.

신 41 — base1blur의 발견

6월 7일. 신 41은 다른 접근이 필요했다. 여러 번 재생성해도 드리프트가 완전히 잡히지 않았다. 그래서 base1blur로 전환했다. 베이스 이미지 자체에 약간의 블러를 걸어서, 모델이 디테일을 과도하게 추적하지 않도록 유도하는 방식이다. 이게 먹혔다. 구도가 안정적으로 유지되면서도 전체적인 영상 품질은 수용 가능한 수준이었다.

이건 직관에 반하는 해결책이다. 보통은 입력 이미지의 품질을 높여야 출력이 좋아진다고 생각하는데, 때로는 적절한 불확실성을 주는 게 모델의 과적합을 방지한다. 사진을 너무 선명하게 주면, 모델이 각 프레임에서 그 선명한 디테일을 재현하려다가 오히려 구도를 흔들어버리는 거다.

GPU 과열 — 시간과의 싸움

ComfyUI를 4시간 이상 연속 가동하니 성능 저하가 눈에 보였다. 처음에 클립당 7~8분이던 처리 시간이 15분으로 늘어나더니, 결국 33분 이상까지 올라갔다. GPU 메모리 누수인지 열 쓰로틀링인지 정확한 원인은 모르겠지만, 해결책은 명확했다. 재시작. ComfyUI를 내렸다 올리면 다시 7~8분으로 돌아온다.

이걸 경험으로 알게 됐으니, 앞으로는 일정 시간마다 자동으로 재시작하는 스크립트를 짜둬야겠다. 4시간 연속 가동의 비효율보다, 2시간마다 재시작하고 깨끗한 상태에서 돌리는 게 총 처리 시간이 짧다.

신 48·60과 최종 완성

신 48과 60은 base2.png로 재생성하는 방식으로 해결했다. base1 계열이 아닌 다른 베이스 이미지를 쓰면서, 해당 신들의 구도와 톤을 새로 잡았다. 모든 신이 같은 베이스에서 출발할 필요는 없다. 각 신의 특성에 맞는 베이스를 선택하는 것도 파이프라인 운영의 일부다.

최종 결과물: 26-25-bigyo.mp4, 391초. 6분 30초짜리 롱폼 에피소드가 완성됐다. 마지막으로 MYBOX와 로컬 저장소 대청소를 해서 1.5G에서 1.2G로 용량을 정리했다. 중간 생성물과 실패한 클립들이 쌓이면 금방 디스크를 잡아먹는다.

사흘의 교훈

이번 작업에서 얻은 것들을 정리하면:

  • 프롬프트는 제로섬이다. 한쪽을 강하게 제약하면 다른 쪽이 약해진다. 밸런스를 잡는 게 핵심이다.
  • 측정 없는 품질관리는 품질관리가 아니다. 도구를 만들어놓고 파이프라인에 연결하지 않으면 소용없다.
  • 때로는 입력의 품질을 의도적으로 낮추는 게 답이다. base1blur의 교훈.
  • 병렬보다 순차가 빠를 때가 있다. 실패와 재시도 비용을 감안해야 한다.
  • 장시간 연속 가동은 독이다. 주기적 재시작이 총 효율을 높인다.

AI 영상 제작은 아직 "버튼 하나로 뚝딱" 만드는 세계가 아니다. 프레임 단위로 들여다보고, 문제를 진단하고, 파이프라인을 고치는 엔지니어링의 영역이다. 그래서 힘들지만, 그래서 재밌다.

화조당(花鳥堂) — AI 사주 명리 서비스 프로젝트로