playreel/known_issue.md
2026-09-02 09:37:58 +09:00

63 lines
3.3 KiB
Markdown

# known_issue.md
이슈는 파이프라인 단계별로 묶는다.
단계: ① detect ② narration_text ③ motion ④ tts ⑤ bgm ⑥ i2v ⑦ render.
어느 단계에도 속하지 않으면 공통에 둔다.
## ① detect
### `recommended_mode` — 죽은 필드
`models/detect.py`의 `Regions.recommended_mode`는 현재 아무 데서도 읽히지 않는다.
`detect.py`가 `title_style == "calligraphy"`이면 `layered`, 아니면 `camera`로 채우기만 한다.
원본 리포에는 렌더 경로가 둘 있었다.
- `layered` — 포스터를 레이어로 분해해 제목 글자는 원본 픽셀 그대로 유지하고 배경만 움직인다.
붓글씨는 획이 조금만 흐트러져도 글자가 아니게 되므로 calligraphy를 이쪽으로 보냈다.
- `camera` — 포스터를 통째로 두고 카메라만 움직인다(팬·줌).
이식한 export에는 둘 다 없다. 레이어 렌더러는 애초에 제외됐고, 실제 렌더는 생성형 i2v이며
그 프롬프트는 오히려 `Locked-off camera: the poster never moves`로 카메라 이동을 금지한다.
판단 유보로 필드는 남겨둔다. 레이어 경로를 되살리지 않기로 하면 지운다.
### `GridBox` 좌표 순서가 강제되지 않는다
`answers/detect_answer.py`의 `GridBox`는 `x0 < x1`, `y0 < y1`을 보장하지 않는다.
프롬프트에도 순서 조건이 없고 스키마에도 밸리데이터가 없다.
VLM이 뒤집어 답하면 `detect.py`의 `tighten_box()`가 `right <= left or bottom <= top`에 걸려
`None`을 돌려주고, 호출부는 VLM 원값을 그대로 쓰는 fallback으로 떨어진다.
그 결과 `x0 > x1`인 `Box`가 그대로 만들어지고, `check_overlay()`의 `draw.rectangle`에서
PIL이 예외를 낸다.
원본 CLI(`detect_regions.py`)에도 같은 구멍이 있다.
막으려면 프롬프트에 순서 조건을 넣거나 `GridBox`에 밸리데이터를 단다.
### focal_points를 VLM이 실제 지점이 아니라 멋대로 잡는다
focal_points 좌표가 포스터를 보고 잰 값이 아니라 그럴듯하게 배치한 값으로 나온다.
관측된 형태는 균등 간격·동일 높이지만, 원인이 같다면 다른 양상으로도 나올 수 있다.
이유는 아마도 둘이다.
- **검증이 없다.** 박스는 VLM이 대충 답해도 `tighten_box()`가 잉크 경계로 다시 잡아준다.
focal_points는 그 후처리가 없어 VLM 값이 곧 최종값이다.
- **틀릴 수 없는 답이다.** 박스와 달리 focal은 정답 경계가 없어서, 모델이 지어내도
스키마도 후처리도 걸러내지 못한다.
프롬프트로 격자를 읽게 못박거나, focal도 박스로 받아 후처리를 태우는 방향이 있다.
후자는 잉크 기반이라 글자에는 듣고 그림에는 덜 듣는다.
## ② narration_text
### `models/narration.py`가 없다
`generate_narration()`이 `answers`의 `NarrationAnswer`를 그대로 반환한다.
detect와 달리 후처리가 없어 LLM 응답이 곧 결과이고, 지금 모델을 만들면 필드를 그대로
베끼는 껍데기가 되기 때문이다.
대신 `answers` 타입이 이 단계의 공개 반환 타입이 되어 LLM 레이어가 위로 새어나간다.
API 레이어가 다른 형태를 요구하면 그때 `models/narration.py`를 만들고 변환을 넣는다.