그날의 숫자
| 지표 | 값 | 출처 |
|---|---|---|
| 한 장 완성까지의 파이프라인 시도 | 6 단계 | 워크로그 §D (21ededc6+2657bd88) |
| 누적 실패 이벤트 | 11,147 | E002 failure_category_counts |
| 그중 error | 3,115 (27.9%) | 〃 |
| 그중 timeout | 2,549 (22.9%) | 〃 |
| 그중 failure (QA reject) | 2,378 (21.3%) | 〃 |
| 그중 nonzero_exit | 1,949 (17.5%) | 〃 |
| 그중 permission | 874 (7.8%) | 〃 |
| 그중 exception | 227 (2.0%) | 〃 |
| 그중 fatal | 55 (0.5%) | 〃 |
| 최종 채택 산출 | 1 장 | 워크로그 §D |
| 폐기된 AI 파생 바리에이션 | 전량 폐기 | 〃 |
데이터 출처: failure_category_counts 7버킷 분포 합 11,147 건은 본 배치 누적값. 6단계 / 1장 채택 / 바리에이션 전량 폐기 결정은 워크로그 §D (21ededc6+2657bd88) 박제.
그 밤이 시작된 이유
[GAME_BETA] 의 한 캐릭터 풀바디가 어색했다. 어색하다는 말로는 부족했다 — 어떤 시드에서는 다리가 잘려 무릎 아래가 사라졌고, 어떤 시드에서는 머리가 두 개 달렸고, 어떤 시드에서는 캐릭터 옆에 캐릭터의 패밀리어(familiar) 가 본인보다 두 배 큰 채로 그려졌다. 한 장만 잘 나오면 되는 일이었다. 게임 안에서 그 캐릭터는 단 한 컷의 풀바디로만 등장한다. 그래서 운영자는 "한 장만 살리자" 를 목표로 그날 저녁을 시작했다.
명령은 평소처럼 한 줄이었다.
역할: fullbody recovery worker
소유 범위(쓰기 가능): [GAME_BETA]/assets/cards/<character>/fullbody/
참고 강제: 같은 캐릭터의 base portrait 와 라이팅·톤 일치
파일 생성 정책: 실패 시 가짜 placeholder 파일 만들지 마라.
마지막 줄이 본 밤의 운명을 결정했다 — 11,147 건의 실패 이벤트가 디스크에 남는다는 뜻이었다.
Step 1~2 — 다리를 빼앗긴 캐릭터
처음에는 단순했다. base portrait 에서 풀바디로 확장하는 uncrop 스크립트가 잠시 에러를 뱉었고, 운영자는 그 에러를 5분 만에 고쳤다. 그 다음 Step 2 에서 처음으로 풀바디 시도가 돌았다. Edge Smear + Canvas Padding 으로 base 의 가장자리를 살짝 늘리고, 늘린 공간을 inpaint 로 채우는 방식.
결과는 말뚝다리(Peg-leg) 였다. 무릎 아래가 매끈한 원기둥이었다. 신발이 없었다. 발도 없었다. 모델은 늘린 공간 안에 "다리" 라는 단어만 채우고 그 다리에 관절도 신발도 안 그렸다.
Step 3 — 흩어진 몸
Step 3 에서 prompt 를 보강했다 — legs, feet, shoes. 동시에 배경을 잠시 chroma key 단색으로 깔아서 모델이 캐릭터 외곽을 더 명확히 잡게 했다. 그 챔버 안에서 U2Net 으로 인물 segmentation 을 한 번 더 돌렸다.
결과는 body shredding 이었다. U2Net 이 캐릭터의 흰 옷을 배경 chroma 와 헷갈렸고, 어깨에서 가슴 라인까지 mask 가 들쭉날쭉 잘렸다. inpaint 가 그 잘린 자리를 다시 채우려고 했고, 채우는 자리마다 옷의 결이 달라졌다. 한 장 안에서 셔츠가 세 번 다른 재질로 바뀌었다.
Step 4 — 머리가 둘 달린 사람
Step 4 에서 운영자는 ControlNet OpenPose 를 붙였다. base portrait 에서 골격을 추출해서 풀바디로 확장할 때 그 골격을 강제로 따르게 했다.
결과는 ghost heads / severed limbs 였다. ControlNet 이 가끔 골격을 두 번 인식했고, 모델은 골격 두 개에 각각 머리와 손을 한 세트씩 그렸다. 어떤 컷에서는 캐릭터 어깨 옆에 또 하나의 머리가 안개처럼 흐릿하게 떠 있었고, 어떤 컷에서는 왼쪽 손이 손목에서 잘려 공중에 떠 있었다.
이 시점에서 누적 실패 이벤트가 7,000 건을 넘었다. 그중 failure (QA gate reject) 가 2,378 건이었다. R3 (신체 잘림) 와 R5 (AI 아티팩트 — 추가 머리/손가락) 가 그날 밤의 두 거인이었다.
Step 5 — 본인보다 큰 패밀리어
Step 5 에서 운영자는 ControlNet 을 끄고, 그냥 txt2img 로 처음부터 풀바디를 새로 그리기로 했다. 종횡비를 길게 가져갔다 — 512x896. 풀바디는 세로로 길어야 하니까.
결과는 giant familiars at tall aspect 였다. 종횡비가 길면 모델은 그 빈 세로 공간을 "다른 무언가" 로 채우려는 본능을 가지고 있다. 캐릭터의 자그마한 패밀리어 (이야기 안에서 손바닥만한 생물이어야 했다) 가 캐릭터보다 머리 하나 더 큰 거대한 형상으로 옆에 그려졌다. 패밀리어가 주인공처럼 보였다.
실패 — 다섯 번을 어떻게 받아들였나
Step 5 가 끝나고 새벽 1시 40분쯤, 운영자는 잠시 키보드에서 손을 뗐다. 다섯 번을 실패한 후였다. 누적 실패 이벤트는 9,000 건을 향했다.
판정: variant 9/9 모두 R5 (AI artifact) 또는 R3 (severed)
권고: pipeline 전면 재구성
이 한 줄이 그날 밤의 진짜 분기점이었다. 운영자는 두 가지 선택지를 봤다 — (1) 더 많은 변수를 추가해서 ControlNet 의 골격 인식을 안정화 한다. (2) 모든 보조 도구를 끄고, 종횡비와 prompt 한 줄만 바꿔서 새로 그린다.
다섯 번의 실패 데이터가 (2) 를 선택하게 했다. 어떤 prompt 가 머리를 두 개 만드는지, 어떤 종횡비가 패밀리어를 거인으로 만드는지 — 그게 모두 박제돼 있었다. ControlNet 을 떼고, 종횡비를 512x832 (덜 길게) 로 줄이고, prompt 에 extremely zoomed out 한 줄을 추가하고, segmentation 만 isnet-anime 로 바꿨다.
Step 6 — 한 장이 살아남았다
Step 6 의 첫 시드에서 풀바디 한 장이 완벽하게 나왔다. 100% flawless. 머리 한 개, 다리 두 개, 신발 두 짝, 패밀리어 한 마리 (손바닥 크기). 어깨와 셔츠 결이 base portrait 와 일치했다.
운영자는 그 한 장을 채택했다. 그 시드로 같은 prompt 를 12번 더 돌려서 바리에이션을 만들어 봤다 — 그중 어느 것도 첫 장만큼 깨끗하지 않았다. AI 파생 바리에이션은 전량 폐기했다. 최고 퀄리티 한 장만 게임 안에 들어갔다.
이게 evidence 카드 E002 가 말하는 그것이다 — "실패는 버려진 로그가 아니라 다음 작업 조건으로 재사용되는 데이터였다." 5 단계의 9,000 건 가까운 실패가 한 줄짜리 새 prompt 조건 (extremely zoomed out + 512x832 + isnet-anime) 을 낳았고, 그 한 줄이 첫 시드에서 풀바디 한 장을 완성시켰다.
그날의 깨달음
- 종횡비는 prompt 보다 강력한 변수다. Step 5 의 512x896 은 prompt 에
solo, alone, no companion을 다섯 번 박아 넣어도 거대한 패밀리어를 만들어냈다. Step 6 의 512x832 는 같은 prompt 에서 한 번에 손바닥 크기 패밀리어를 그렸다. 64 픽셀 차이가 모델의 "여백 채우기 본능" 을 결정했다. 다음 풀바디 작업의 default 종횡비는 512x832 로 박는다. - 보조 도구가 많을수록 실패 모드가 다양해진다. Step 4 의 ControlNet 은 골격 인식 안정성을 +30% 올렸지만, 그 대신 "머리 두 개" 라는 새로운 실패 모드를 만들었다. Step 6 에서 ControlNet 을 떼고 단순한 txt2img 로 돌아갔을 때 실패 모드가 줄었고, 그 줄어든 실패 모드는 prompt 한 줄로 잡혔다. 풀바디 작업은 보조 도구 0개에서 시작하고, 실패가 측정 가능한 패턴으로 굳어진 후에만 보조 도구를 1개씩 추가한다.
- AI 바리에이션의 함정. 첫 시드가 완벽했을 때 운영자의 본능은 "그 시드 주변에서 12장 더 만들어 보자" 였다. 12장 중 어느 것도 첫 장을 이기지 못했다. 첫 시드의 완벽함은 그 시드만의 우연 이었고, 같은 prompt 의 다른 시드는 다른 우연을 만든다. 게임 안에 들어갈 풀바디가 한 장이면 충분할 때, AI 바리에이션을 만들어 비교하는 것 자체가 실패 누적의 원인이다. 다음 풀바디 작업도 "한 장이면 끝" 원칙을 유지한다.
다음 날
다음 날 아침, 운영자는 그 한 장의 풀바디를 게임 안에 박았다. 그 캐릭터는 게임 안에서 단 한 컷의 풀바디로만 등장한다. 그 한 컷이 11,147 건의 실패와 6 단계의 파이프라인 끝에 나온 것이라는 사실을 플레이어는 모른다. 알 필요도 없다.
운영자가 다음 풀바디 작업을 시작할 때 — 그게 같은 게임의 다른 캐릭터든, 다른 사이드 프로젝트든 — 본 밤의 11,147 건이 default 설정을 만들어 줄 것이다. 종횡비 512x832, 보조 도구 0개, 첫 시드가 완벽하면 거기서 멈춘다.
여섯 번의 실패가 한 장의 다음 default 를 만들었다. 그게 본 밤의 진짜 결과물이었다.
Editor's note: 모든 실패 카운트 7버킷 (error 3,115 / timeout 2,549 / failure 2,378 / nonzero_exit 1,949 / permission 874 / exception 227 / fatal 55) 은 본 PC failure_category_counts 박제 실측. 6 단계 파이프라인 / 각 단계 실패 모드 (peg-leg / body shredding / ghost heads / giant familiars / 512x832 isnet-anime 성공) / AI 파생 바리에이션 전량 폐기 결정은 워크로그 §D (21ededc6+2657bd88) 박제. 11,147 실패가 본 6 단계에 모두 귀속된 것은 아니며, 같은 기간 다른 작업과 합산된 누적치다 — 연출상 본 단락에 집중 배치. [GAME_BETA] 는 사이드 프로젝트 codename — 외부 노출 금지.