--- title: ROEM-AI emoji: ๐Ÿ“ธ colorFrom: blue colorTo: indigo sdk: docker app_port: 7860 pinned: false short_description: AI fashion model cut generator --- # AI ModelCut Studio ## Hugging Face Dataset Save Generated images are saved to a Hugging Face Dataset when these Space secrets are set: ```text HF_DATASET_REPO=sunyoung00/ROEM_TEST HF_TOKEN=hf_... ``` `HF_TOKEN` must have write permission for the dataset repo. If `HF_DATASET_REPO` is not set, the app defaults to `sunyoung00/ROEM_TEST`. Upload failures are logged but do not block image generation. Saved files are uploaded under: ```text generated/YYYYMMDDTHHMMSSZ_requestid/ 01_label.png metadata.json ``` ์ œํ’ˆ ์ด๋ฏธ์ง€, AI ๋ชจ๋ธ ์–ผ๊ตด, ์ฒดํ˜• ๋ ˆํผ๋Ÿฐ์Šค, ์ œํ’ˆ ๊ธฐ์žฅ, ์ƒท๋ณ„ ํฌ์ฆˆ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์กฐํ•ฉํ•ด ์‡ผํ•‘๋ชฐ์šฉ AI ๋ชจ๋ธ์ปท์„ ์ƒ์„ฑํ•˜๋Š” Hugging Face Spaces์šฉ ์•ฑ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. (์–ผ๊ตด/์ฒดํ˜•/ํฌ์ฆˆ ๋ ˆํผ๋Ÿฐ์Šค ๋ฐฐ์น˜๋Š” `assets/README.md` ์ฐธ๊ณ ) ## Hugging Face Spaces ์‹คํ–‰ ๊ตฌ์กฐ ์ด ์ €์žฅ์†Œ๋Š” Docker Space๋กœ ๋ฐ”๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์ˆ˜ ํŒŒ์ผ: - `Dockerfile`: Hugging Face Spaces Docker SDK๊ฐ€ ๋นŒ๋“œํ•˜๋Š” ์ปจํ…Œ์ด๋„ˆ ์ •์˜ - `app.py`: FastAPI ๊ธฐ๋ฐ˜ ์›น ์„œ๋ฒ„์™€ ์ƒ์„ฑ API - `requirements.txt`: Python ๋Ÿฐํƒ€์ž„ ์˜์กด์„ฑ - `index.html`, `styles.css`, `script.js`: ๋ณ„๋„ ํ”„๋ก ํŠธ์—”๋“œ ์‹œ์•ˆ Hugging Face์—์„œ ์ƒˆ Space๋ฅผ ๋งŒ๋“ค ๋•Œ SDK๋Š” `Docker`๋กœ ์„ ํƒํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ```text Space SDK: Docker Port: 7860 Start command: Dockerfile CMD ์‚ฌ์šฉ ``` ํ˜„์žฌ `app.py`๋Š” OpenAI/Gemini ์ด๋ฏธ์ง€ ์ƒ์„ฑ API๋ฅผ ์šฐ์„  ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. API ํ‚ค๊ฐ€ ์—†๊ฑฐ๋‚˜ `DEMO_FALLBACK=true`๋กœ ์„ค์ •ํ•œ ๊ฒฝ์šฐ์—๋Š” ์—…๋กœ๋“œํ•œ ์ œํ’ˆ ์ด๋ฏธ์ง€๋ฅผ ํ•ฉ์„ฑํ•˜๋Š” ๋ฐ๋ชจ worker๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ์‹ค์ œ ์ด๋ฏธ์ง€ ์ƒ์„ฑ API ํ˜„์žฌ ์•ฑ์€ Docker ์ปจํ…Œ์ด๋„ˆ์—์„œ OpenAI ๋˜๋Š” Gemini ์ด๋ฏธ์ง€ ์ƒ์„ฑ API๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ๋ณ€์ˆ˜: ```text OPENAI_API_KEY=... GEMINI_API_KEY=... OPENAI_IMAGE_MODEL=gpt-image-2 GEMINI_IMAGE_MODEL=gemini-3.1-flash-image-preview DEMO_FALLBACK=false # ๋ฐ์ดํ„ฐ์…‹ ์ €์žฅ HF_DATASET_REPO=sunyoung00/ROEM_TEST HF_TOKEN=hf_... # ์ƒ์„ฑ ๋™์ž‘ ํŠœ๋‹ (์„ ํƒ) GEN_MAX_WORKERS=4 # ์ผ๊ด„ ์ƒท / Gemini ํ›„๋ณด ๋™์‹œ ์ƒ์„ฑ ์ˆ˜ API_INPUT_MAX_SIDE=2048 # ๋ ˆํผ๋Ÿฐ์Šค ์ด๋ฏธ์ง€ ์ „์†ก ์‹œ ๊ธด ๋ณ€ ์ƒํ•œ MATCH_REFERENCE_FRAMING=true # ์ƒท ๋ ˆํผ๋Ÿฐ์Šค ํ”„๋ ˆ์ด๋ฐ์— ๋งž์ถฐ ์ž๋™ ํฌ๋กญ SUBJECT_BG_TOLERANCE=32 # ๋ฐฐ๊ฒฝ ๋Œ€๋น„ ํ”ผ์‚ฌ์ฒด ๊ฒ€์ถœ ๋ฏผ๊ฐ๋„(ํฌ๋กญ์šฉ) IDEALIZE_PROPORTIONS=false # ์ฒดํ˜• ๋ ˆํผ๋Ÿฐ์Šค ์—†์„ ๋•Œ 8.2~8.5๋“ฑ์‹  ๊ฐ•์ œ ์—ฌ๋ถ€ FRAMING_TOP_MARGIN= # (์„ ํƒ) ์ˆ˜๋™ ํฌ๋กญ ์ƒ๋‹จ ์—ฌ๋ฐฑ ๋น„์œจ, ์˜ˆ: 0.10 FRAMING_BOTTOM_MARGIN= # (์„ ํƒ) ์ˆ˜๋™ ํฌ๋กญ ํ•˜๋‹จ ์—ฌ๋ฐฑ ๋น„์œจ, ์˜ˆ: 0.08 ``` ํ™”๋ฉด์˜ `์ด๋ฏธ์ง€ ์ƒ์„ฑ ๋ชจ๋ธ`์—์„œ ์•„๋ž˜ provider๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. - `openai:gpt-image-2` - `openai:gpt-image-1.5` - `openai:gpt-image-1` - `gemini:gemini-3.1-flash-image-preview` - `gemini:gemini-3-pro-image-preview` - `gemini:gemini-2.5-flash-image` `1K`๋Š” 1024px๊ธ‰ ์„ธ๋กœ ๊ฒฐ๊ณผ, `2K`๋Š” 2048px๊ธ‰ ์„ธ๋กœ ๊ฒฐ๊ณผ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. GPT Image 2์™€ Gemini 3.1/3 Pro ์ด๋ฏธ์ง€ ๋ชจ๋ธ์ฒ˜๋Ÿผ 2K ์š”์ฒญ์„ ์ง€์›ํ•˜๋Š” ๋ชจ๋ธ์€ API ์š”์ฒญ ๋‹จ๊ณ„์—์„œ 2K๋ฅผ ์ง€์ •ํ•˜๊ณ , ๋ฐ˜ํ™˜ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๊ฐ€ ๋‹ค๋ฅด๋ฉด ์ตœ์ข… ์บ”๋ฒ„์Šค์— ๋งž์ถฐ ์ •๊ทœํ™”ํ•ฉ๋‹ˆ๋‹ค. API ํ‚ค๊ฐ€ ์—†๊ฑฐ๋‚˜ ๋ชจ๋ธ๋ช…์ด ํ•ด๋‹น ๊ณ„์ •์—์„œ ์ง€์›๋˜์ง€ ์•Š์œผ๋ฉด ํ™”๋ฉด์— ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. `DEMO_FALLBACK=true`๋ฅผ ์„ค์ •ํ•œ ๊ฒฝ์šฐ์—๋งŒ ๊ธฐ์กด ๋ฐ๋ชจ ๋ Œ๋”๋Ÿฌ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค. ## ๋ชจ๋ธ ์–ผ๊ตด ํ”„๋ฆฌ์…‹ ์ฒจ๋ถ€ํ•œ ๋ชจ๋ธ ์–ผ๊ตด ์ด๋ฏธ์ง€๋Š” ์•„๋ž˜ ๊ฒฝ๋กœ์— ์ €์žฅํ•ด์„œ ํ•จ๊ป˜ ์—…๋กœ๋“œํ•˜๋ฉด ๊ธฐ๋ณธ ํ”„๋ฆฌ์…‹์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ```text assets/model_face_preset.png ``` ์•ฑ์—์„œ๋Š” `๋ชจ๋ธ ์–ผ๊ตด ์†Œ์Šค` ๊ธฐ๋ณธ๊ฐ’์ด `์ฒจ๋ถ€ ์–ผ๊ตด ํ”„๋ฆฌ์…‹`์œผ๋กœ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ„๋„ ์–ผ๊ตด ์ด๋ฏธ์ง€๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋งŒ `์—…๋กœ๋“œ ์–ผ๊ตด`์„ ์„ ํƒํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํ™”๋ฉด์˜ `ํŽ˜๋ฅด์†Œ๋‚˜ ์–ผ๊ตด ์—…๋กœ๋“œ`์— ์–ผ๊ตด ์ด๋ฏธ์ง€๋ฅผ ์˜ฌ๋ฆฌ๋ฉด ํ•ด๋‹น ํŒŒ์ผ์ด `/api/generate`์˜ `model_face`๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ API ์ƒ์„ฑ์—์„œ๋Š” ์ด ์–ผ๊ตด ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ฒซ ๋ฒˆ์งธ ์ฐธ์กฐ ์ด๋ฏธ์ง€๋กœ ๋„ฃ๊ณ , ํ›„๋ณด 3์žฅ๊ณผ ํ›„์† ์ƒท ๋ชจ๋‘ ๋™์ผ ์ธ๋ฌผ๋กœ ์œ ์ง€ํ•˜๋„๋ก ํ”„๋กฌํ”„ํŠธ์— identity lock ์ง€์‹œ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ## ํ™”๋ฉด ๊ตฌ์„ฑ - ๋กœ๊ทธ์ธ / ํ”„๋กœ์ ํŠธ ์ €์žฅ - QR ๋˜๋Š” ๋กœ์ปฌ ์ œํ’ˆ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ: ์ œํ’ˆ 1~4 ๊ฐ๊ฐ ์•ž๋ฉด, ๋’ท๋ฉด ์˜ต์…˜ - ์นดํ…Œ๊ณ ๋ฆฌ, ํ•, ์ œํ’ˆ ๊ธฐ์žฅ, ์Šคํƒ€์ผ ์„ ํƒ - ํ”„๋กฌํ”„ํŠธ ์ž…๋ ฅ - ์นดํ…Œ๊ณ ๋ฆฌ(์ƒ์˜/ํ•˜์˜ ๋“ฑ)์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ์ƒท ๋ฒ„ํŠผ ์„ ํƒ - ์ „์‹ (์•ž๋ฉด) ํ›„๋ณด 3์žฅ ์šฐ์„  ์ƒ์„ฑ - ์„ ํƒํ•œ ํ›„๋ณด ์ปท ๊ธฐ์ค€ ์ƒท ๊ตฌ๋„ ๋ณ€๊ฒฝ ์ƒ์„ฑ (๊ฐ ์ƒท์€ assets/poses์˜ ๋ช…๋ช… ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋”ฐ๋ผ๊ฐ) - 1K / 2K ํ•ด์ƒ๋„ ์„ ํƒ - ์„ ํƒ ์ปท ์žฌ์ƒ์„ฑ - AI ํ‘œ๊ธฐ ์‚ฝ์ž… - ์ผ๊ด„ ๋‹ค์šด๋กœ๋“œ - ์ƒ์„ฑ ์‹œ๊ฐ„ ์•ˆ๋‚ด ## ๊ถŒ์žฅ ์ƒ์„ฑ ํŒŒ์ดํ”„๋ผ์ธ 1. ์ž…๋ ฅ ๊ฒ€์ฆ - ์ œํ’ˆ ์›๋ณธ ํ•ด์ƒ๋„, ๋ฐฐ๊ฒฝ ํˆฌ๋ช…๋„, ๋ธ”๋Ÿฌ, ๋กœ๊ณ  ์˜์—ญ, ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ™•์ธ - ๊ธด ๋ณ€ ๊ธฐ์ค€ ์ตœ์†Œ 1500px ์ด์ƒ ๊ถŒ์žฅ 2. ์ œํ’ˆ ์ „์ฒ˜๋ฆฌ - ์ œํ’ˆ 1~4์˜ ์•ž๋ฉด/๋’ท๋ฉด ๋ ˆํผ๋Ÿฐ์Šค ์ œํ’ˆ ์˜์—ญ ์„ธ๊ทธ๋ฉ˜ํ…Œ์ด์…˜ - ์‹ค๋ฃจ์—ฃ, ๋กœ๊ณ , ํŒจํ„ด, ๋ฒ„ํŠผ, ์†Œ์žฌ ํ…์Šค์ฒ˜ ๋ณด์กด์šฉ ๋งˆ์Šคํฌ ์ƒ์„ฑ - ์นดํ…Œ๊ณ ๋ฆฌ์™€ ๊ธฐ์žฅ ๊ฐ’์„ ํ”„๋กฌํ”„ํŠธ ์กฐ๊ฑด์œผ๋กœ ๋ณ€ํ™˜ 3. ๋ชจ๋ธ ์กฐ๊ฑด ์ƒ์„ฑ - ์„ ํƒํ•œ AI ๋ชจ๋ธ ์–ผ๊ตด ์ž„๋ฒ ๋”ฉ ๋˜๋Š” ๋ ˆํผ๋Ÿฐ์Šค ์ด๋ฏธ์ง€ ์—ฐ๊ฒฐ - ํฌ์ฆˆ ๋ ˆํผ๋Ÿฐ์Šค์—์„œ OpenPose / DensePose / depth ์กฐ๊ฑด ์ถ”์ถœ - ์ „์‹  3์ปท์„ ๋จผ์ € ์ƒ์„ฑํ•˜๊ณ  ์ดํ›„ ์Šคํƒ€์ผ ๋ณ€ํ˜• ์ปท ์ƒ์„ฑ 4. 1์ฐจ ์ด๋ฏธ์ง€ ์ƒ์„ฑ - ์ „์‹ (์ •๋ฉด) ํ›„๋ณด 3์žฅ์„ ๋จผ์ € ์ƒ์„ฑ - ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ•œ ๊ธฐ์ค€ ์ปท์˜ ์–ผ๊ตด/์˜์ƒ ์ •๋ณด๋ฅผ ํ›„์† ์ƒท ์ƒ์„ฑ์˜ ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์šฉ - ์ œํ’ˆ ๋งˆ์Šคํฌ๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ๊ณ ์ • - ์–ผ๊ตด, ์†, ๋‹ค๋ฆฌ, ์˜ท ๊ฒฝ๊ณ„๋ถ€๋ฅผ ๋ณ„๋„ ๊ฒ€์ˆ˜ ๋Œ€์ƒ์œผ๋กœ ์ €์žฅ - ์ปท๋ณ„ seed, prompt, negative prompt, model version ๊ธฐ๋ก 5. ์ƒท ๊ตฌ๋„ ํ™•์žฅ - ์„ ํƒ ๊ธฐ์ค€ ์ปท์—์„œ ์–ผ๊ตด, ์˜์ƒ, ์ƒ‰์ƒ, ์†Œ์žฌ, ๋กœ๊ณ ๋ฅผ ์œ ์ง€ - ๊ฐ ์ƒท์€ `assets/poses/`์˜ ๋™์ผ ์ด๋ฆ„ ๋ ˆํผ๋Ÿฐ์Šค(์˜ˆ: `์ „์‹ _์•ž๋ฉด_.*`)์—์„œ ํฌ์ฆˆยท๊ฐ๋„ยทํฌ๋กญ๋งŒ ๊ฐ€์ ธ์˜ด - ์นดํ…Œ๊ณ ๋ฆฌ์— ๋”ฐ๋ผ ๋…ธ์ถœ ์ƒท์ด ๋‹ฌ๋ผ์ง - ์ƒ์˜(์›ํ”ผ์Šคยท์•„์šฐํ„ฐ ํฌํ•จ): ์ „์‹ (์•ž๋ฉด), ์ „์‹ (์ธก๋ฉด), ์ „์‹ (ํ›„๋ฉด), ์ƒ๋ฐ˜์‹ (์•ž๋ฉด), ์ƒ๋ฐ˜์‹ (์ธก๋ฉด), ์ƒ๋ฐ˜์‹ (ํ›„๋ฉด), ์ƒ๋ฐ˜์‹ (ํด๋กœ์ฆˆ์—…), ๋””ํ…Œ์ผ(ํ›„๋ฉด) - ํ•˜์˜(์Šค์ปคํŠธ ํฌํ•จ): ์ „์‹ (์•ž๋ฉด), ์ „์‹ (์ธก๋ฉด), ์ „์‹ (ํ›„๋ฉด), ์ƒ๋ฐ˜์‹ (์•ž๋ฉด), ์ƒ๋ฐ˜์‹ (์ธก๋ฉด), ํ•˜๋ฐ˜์‹ , ํ•˜๋ฐ˜์‹ (ํด๋กœ์ฆˆ์—…) - ์ „์‹ ยท์ƒ๋ฐ˜์‹ (์•ž/์ธก/ํ›„)ยทํ•˜๋ฐ˜์‹ ์€ ๋ ˆํผ๋Ÿฐ์Šค ํ”„๋ ˆ์ด๋ฐ์— ๋งž์ถฐ ์ž๋™ ํฌ๋กญ, ํด๋กœ์ฆˆ์—…ยท๋””ํ…Œ์ผ์€ ํฌ๋กญ ์ƒ๋žต 6. ํ’ˆ์งˆ ๊ฒ€์ˆ˜ - ์ œํ’ˆ ํ˜•ํƒœ ๋ณ€ํ˜•๋ฅ  - ๋กœ๊ณ  ์™œ๊ณก - ์†๊ฐ€๋ฝ, ์–ผ๊ตด, ๋‹ค๋ฆฌ ๋น„์œจ - ๋ฐฐ๊ฒฝ ๋ˆ„๋ผ ํ’ˆ์งˆ - AI ํ‘œ๊ธฐ ๋ˆ„๋ฝ ์—ฌ๋ถ€ 7. ๊ณ ํ•ด์ƒ๋„ ํ›„์ฒ˜๋ฆฌ - 1K ์ƒ์„ฑ ํ›„ 2K ์—…์Šค์ผ€์ผ - ์–ผ๊ตด/์ œํ’ˆ ๋””ํ…Œ์ผ ์˜์—ญ ์„ ํƒ ์ƒคํ”ˆ - ์ƒ‰์ƒ ํŽธ์ฐจ ๋ณด์ • - JPG/PNG/WebP ๋ฐ ZIP ์ผ๊ด„ ๋‹ค์šด๋กœ๋“œ ## ์ถ”์ฒœ ๋ฐฑ์—”๋“œ ๊ตฌ์กฐ ```text client upload panel option builder result gallery api POST /projects POST /assets/product POST /assets/model-face POST /jobs/generate POST /jobs/:id/regenerate GET /jobs/:id GET /projects/:id/results.zip worker preprocess product extract pose generate first-pass images run quality checks upscale and sharpen export final assets storage original assets masks intermediate renders final images job metadata ``` ## ๋กœ์ปฌ ์‹คํ–‰ Docker ์•ฑ: ```bash docker build -t modelcut-studio . docker run --rm -p 7860:7860 -e OPENAI_API_KEY=... -e GEMINI_API_KEY=... modelcut-studio ``` Python ์ง์ ‘ ์‹คํ–‰: ```bash pip install -r requirements.txt python app.py ``` ์ •์  UI ์‹œ์•ˆ: `index.html`์„ ๋ธŒ๋ผ์šฐ์ €๋กœ ์—ด๋ฉด ๋ฐ”๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.