Meshy 파이프라인과 포즈 추정을 망가뜨린 로브
생성형 3D는 프롬프트를 런타임 준비가 된 에셋으로 바꾸는 파이프라인만큼만 좋다. RakuAI는 사라지는 벤더 엔드포인트, 유니코드 크래시, 데모가 결코 보여주지 않는 마찰을 견뎌내는 파이프라인을 만들었다.
에셋 파이프라인은 이 엔진에서 지루하면서도 하중을 지탱하는 부분 중 하나다. 디자이너의 아이디어(“타워 디펜스 팩을 위한 적 스무 마리가 필요해”)를 런타임이 로드할 수 있는 텍스처, 리깅, LOD가 완료된 3D 에셋 폴더로 바꿔주는 것이다. 지난 6주 동안 그 작업을 해온 파이프라인은 Meshy.ai였고, 런타임 저장소의 scripts/meshy_asset_pipeline.py에 있는 7단계 스크립트를 통해 연결되어 있다.
이번 토요일 아침, Meshy 파이프라인과 SDK 팩 포맷 사이의 v1 브릿지가 충분히 안정되어서 우리가 배운 것을 적을 수 있게 됐다. 세 가지다. 그 어느 것도 API 문서에는 없다.
일곱 단계가 실제로 하는 일
순서대로, 모든 에셋에 대해.
- 프리뷰 모드의 Text-to-3D 생성.
- PBR 텍스처 맵 생성: albedo, metallic, roughness, normal.
- LOD0 폴링과 다운로드.
- v1 API에 대한 Remesh 작업 생성.
- LOD1 remesh 폴링과 다운로드.
- 디스크상의 에셋 파일 정리.
- 콘텐츠 팩 조립.
이 파이프라인은 에셋 하나를 끝까지 진행시킨 다음 다음 것으로 넘어간다. 배치로 처리하지 않는다. 배치로 처리하지 않는 이유는 아래 세 번째 교훈에서 뼈아프게 드러났다.
교훈 하나: 로브가 포즈 추정을 망가뜨린다
Meshy의 text-to-3D 출력은 다양한 인간형 디자인에 대해 괜찮다. 해골, 병사, 기사, 팔이 드러난 마법사. 파이프라인은 그것들을 리깅하고, 리그는 작동하고, 에셋은 출시된다.
두꺼운 로브를 입은 인간형에는 괜찮지 않다. RPG 콘텐츠 팩이 스프린트 2에서 이것에 부딪혔다. 깔끔하게 리깅되었어야 할 네 개의 에셋이 포즈 추정 중 실루엣 추출에 실패했다. 둘은 예상된 것이었다(슬라임과 wolf_enemy는 인간형이 아니고, 포즈 추정기는 그것들에게서 팔을 찾을 수 없어야 정상이다). 둘은 뜻밖이었다. mage_hero와 blacksmith. 둘 다 인간형이었다. 둘 다 실패했다.
실패 양상은 실루엣이다. Meshy의 포즈 추정기는 팔다리를 찾기 위해 모델의 렌더링된 윤곽선을 본다. 긴 로브를 입은 마법사는 실루엣에서 보이는 다리가 없으므로 골격을 고정할 다리 키포인트가 없다. 앞치마를 두른 대장장이는 가슴과 골반 사이에 보이는 몸통 이음매가 없으므로 척추 관절이 잘못 추측된다. 모델은 괜찮다. 리그가 틀렸다.
파이프라인의 해결책은 실패를 로깅하고, 리깅되지 않은 지오메트리를 저장하고, “이것은 수동 리그 패스가 필요하다”고 말하는 플래그를 에셋 매니페스트에 드러내는 것이다. 프롬프트의 해결책은 자동 리깅이 필요한 인간형이라면 텍스트 프롬프트에 “몸에 딱 맞는 옷, 드러난 팔다리”를 명시하는 것이다. 더 근본적인 해결책은 Meshy 쪽에 있으며 우리가 할 수 있는 것이 아니다.
열세 개의 장르 전체에 걸쳐 실패율은 고르지 않다. 타워 디펜스는 다섯 개 중 하나가 리깅 실패다. 플랫포머는 여섯 개 중 하나다. RPG는 열한 개 중 네 개이고, 그 네 개 중 세 개는 옷 지오메트리 문제다. 이 교훈은 일반화된다. 생성형 모델이 실패할 때, 그 실패는 대개 무작위가 아니며, 그 실패 양상은 그 모델이 어떤 학습 데이터로 만들어졌는지에 대해 뭔가를 알려준다.
교훈 둘: 유니코드는 stdout을 파일로 파이프하는 무엇이든 크래시시킨다
RPG 팩의 Oni 진영은 일본어 캐릭터 이름을 쓴다. 바람을 뜻하는 風, 천둥을 뜻하는 雷, 다이아몬드를 뜻하는 金剛. 이것들은 Meshy 작업 제출에 쓰이는 에셋 이름이다. 파이프라인은 백그라운드에서 실행되며, stdout을 로그 파일로 리디렉션하고, 나중에 어떤 에셋이 성공했는지 그 로그를 파싱한다.
Oni 에셋들이 처음 실행됐을 때, 그 하나하나가 모두 실패했다. 에러는 Python의 stdout에서 나온 UnicodeEncodeError였다. 빌드 머신의 기본 인코딩은 stdout이 TTY가 아닐 때 ASCII다. 일본어 문자는 ASCII가 아니다. print 문은 그 에셋이 Meshy에 제출되기도 전에 크래시한다.
해결책은 런처 스크립트의 한 줄이다. PYTHONIOENCODING=utf-8. 그 환경 변수가 설정되면, print 문이 작동하고 에셋이 생성된다.
이 교훈은 나보다 오래됐다. stdout으로 리디렉션된 파이프라인을 통해 유니코드를 흘려보내는 것은 무엇이든 인코딩을 명시적으로 설정해야 한다. 20년 동안 문서화되어 있던 문제 때문에 이틀을 잃었다. 행동 저널에 기록됐다. 런처에서 고쳐졌다. Meshy에서는 고쳐지지 않았는데, 그것은 Meshy가 고쳐야 할 문제가 아니기 때문이다.
교훈 셋: 벤더 API는 사라진다
스프린트 2의 절반쯤 지났을 때, Meshy v2의 /remesh 엔드포인트가 404를 반환하기 시작했다. 특정 에셋에 대해서가 아니었다. 모든 호출에 대해서였다.
remesh 단계는 LOD0(고폴리곤, 렌더링 비용이 큼)를 LOD1(저폴리곤, 렌더링 비용이 작음)로 바꿔주는 단계다. remesh가 없으면 에셋은 LOD0만 가진 채로 출시된다. 개발자 머신에서는 문제없이 렌더링되지만 AR 글래스 타깃에서는 프레임 레이트를 죽인다.
그 엔드포인트가 폐기된 것인지, 더 높은 등급의 플랜 뒤에 게이트되어 있는 것인지, 리디렉션 없이 옮겨진 것인지, 일시적으로 다운된 것인지 나는 모른다. Meshy 문서는 여전히 그것을 참조하고 있다. 호출하면 404가 난다. 파이프라인은 벤더가 어느 쪽인지 알아낼 때까지 기다릴 수 없다.
해결책은 meshy_asset_pipeline.py의 remesh 단계에 있다. remesh 호출 주위에 try/except를 두는 것이다. 실패하면, 그 에셋을 LOD0 전용으로 로깅하고, 그 사실을 에셋 매니페스트에 기록하고, 파이프라인의 나머지 부분을 계속한다. 모든 에셋은 LOD0를 가진다. 일부는 LOD1도 가진다. 팩은 어느 쪽이든 출시된다.
이 교훈은 벤더 API에 의존하는 모든 프로젝트가 결국 배우게 되는 것이다. 당신이 의존하는 API는 당신 것이 아니며, 그것은 당신 아래에서 바뀔 수 있으며, 유일한 방어책은 우아한 성능 저하다. 이제 우리는 그것을 갖고 있다.
파이프라인은 지금 어디에 있는가
열세 개 중 여덟 개의 장르가 완료됐다. 스페이스 슈터, 퍼즐, 카드 배틀, 러너, 플랫포머, 레이싱, 타워 디펜스, RPG. 다섯 개가 남았다(스포츠, 시뮬레이션, 샌드박스, 파이팅, MMO-lite) 대기열에 있다.
크레딧 예산은 뜻밖의 승리다. 스프린트 2의 추정치는 그 장르의 양 진영을 합쳐 약 510 크레딧이었다. 실제 지출은 일관되게 추정치보다 25에서 35퍼센트 낮았다. 이는 예산에 대한 대화 없이 남은 다섯 개 장르를 밀어붙일 충분한 여유를 이 프로그램에 준다.
이번 달 초에 들어온 v1 브릿지, 스물네 개의 정합성 테스트를 갖춘 scripts/generate_rakupack.py가 바로 이 모든 것을 SDK 쪽에서 다룰 수 있게 만들어주는 것이다. SDK를 쓰는 개발자는 어떤 에셋이 Meshy에서 나왔는지 손으로 모델링된 파이프라인에서 나왔는지 알 필요가 없다. 팩 포맷이 계약이다. Meshy 파이프라인은 팩을 만든다. SDK는 팩을 로드한다.
이것을 적어두는 이유
두 가지다.
첫째, 위의 세 가지 교훈은 벤더 데모에도 마케팅 페이지에도 나타나지 않는 종류의 마찰이다. 로브와 포즈 추정. 유니코드와 stdout. Remesh와 404. 생성형 3D 벤더를 평가하고 있고 이것을 읽으며 “그건 내가 그것에 전념하기 전에 알고 싶었던 종류의 것이다”라고 말한다면, 이 글은 제 값을 한 것이다.
둘째, 파이프라인은 이제 다음 대화가 “Meshy가 우리에게 통하는가”가 아닐 만큼 충분히 안정됐다. 다음 대화는 “우리가 에셋 라이브러리를 무엇으로 만들고 싶은가”이다. 그것은 디자이너의 대화이지, 엔지니어링의 대화가 아니다. 엔지니어링 쪽은 방해가 되지 않음으로써 제 할 일을 했다.
여덟 개 장르 완료. 다섯 개 남음. 파이프라인은 404를 견뎌낸다. 파이프라인은 일본어 문자를 견뎌낸다. 파이프라인은, 아직은, 로브를 견뎌내지 못한다. 잘 보낸 토요일이었다.
당신의 AI가 실제로 실행할 수 있는 세계를 생성하라
RakuAI는 생성형 에셋을 런타임 준비가 된 콘텐츠 팩으로 바꾼다 — 하나의 계약, 어떤 소스든, 벤더 데모가 숨기는 마찰에 맞서 단련되어 있다. 당신의 창작물을 배포하기 위해 만들어진 공간 런타임으로 가져오라.