На входе — плоское RGB/RGBA-изображение I. На выходе — не просто набор
картинок, а редактируемый документ D, который можно снова отрендерить:
input.png
│
▼
analyzer / controller
│
├── text reconstruction
├── layer decomposition / matting
├── vector & primitive reconstruction
├── amodal completion / background recovery
└── hierarchy & z-order inference
│
▼
document.json + assets/*.png + preview.svg/psd
│
▼
renderer → reconstructed.png
│
▼
verifier → accept / refine / split / merge / retry
Ключевой инвариант: render(D) должен быть близок к I, но сам D должен
оставаться удобным для реальных операций: удалить объект, передвинуть его,
заменить текст, перекрасить или изменить размер.
Это inverse graphics / design reconstruction. Единственного «правильного» разложения нет: один и тот же растр можно объяснить разными наборами слоёв. Поэтому качество надо измерять не совпадением с историческим PSD, а внешним видом и успешностью последующих edit operations.
Синтетический генератор даёт почти бесплатные точные labels:
- исходные RGBA-слои;
- видимые и полные (amodal) маски;
- текст, шрифт и параметры оформления;
- bounding boxes и transforms;
- z-order, группы и связи перекрытия;
- эталон после контролируемого edit replay.
Главная опасность — domain gap. На синтетике слои обычно слишком «правильные»: ровная альфа, известный шрифт, идеальные края. В реальности встречаются JPEG ringing, ресайз, цветовые профили, glow, shadows, antialiasing, blur, текст как часть фотографии, несколько эффектов в одном пикселе и неизвестные шрифты.
Поэтому стратегия данных должна быть смешанной:
- процедурная синтетика с полным ground truth;
- реальные редактируемые макеты с разрешёнными лицензиями;
- flattened/degraded версии этих макетов;
- небольшой вручную проверенный real-world benchmark;
- hard-negative mining по ошибкам текущей системы.
Внутренний формат не должен быть PSD. PSD и SVG — экспортные форматы. Источник правды — versioned JSON scene graph и отдельные assets.
Минимальные типы узлов:
group— иерархия, clipping и общий transform;text— строка, font reference, size, weight, line height, alignment, fill, stroke, shadow, transform;raster— RGBA asset, crop, transform, opacity;vector— SVG path или primitive, fill/stroke;effect— на первом этапе только drop shadow и blur;background— solid/gradient/raster.
У каждого узла: id, type, bbox, affine transform, z_index, confidence,
provenance и ссылки на parent/children. Provenance нужен, чтобы verifier понимал,
каким инструментом узел получен и что можно безопасно повторить.
Controller получает thumbnail, OCR candidates и состояние scene graph. Он не рисует пиксели, а выбирает действие:
- выделить text region;
- извлечь foreground layer;
- разбить сложный layer рекурсивно;
- vectorize region;
- принять region как цельный raster;
- объединить дубли;
- остановить разложение.
Первая версия может использовать VLM API со structured JSON. Затем решения контроллера можно дистиллировать в маленькую локальную модель. Важнее состояния и верификация, чем конкретный VLM.
Практический ориентир — ReDesign (2026): иерархическое tree expansion с локальной проверкой каждого шага оказалось устойчивее фиксированного длинного конвейера. Независимые ветки дерева можно выполнять параллельно.
Текст нужно извлекать до генеративного разложения: диффузионная модель часто превращает буквы в растровый объект или немного меняет их.
Pipeline:
- text detection и recognition;
- оценка строки/абзаца, baseline, rotation и reading order;
- удаление исходного растра текста с восстановлением подложки;
- подбор ближайшего разрешённого шрифта;
- оптимизация font size, tracking, line height, color, stroke и shadow через differentiable или black-box rendering loss;
- создание настоящего
textnode.
Стартовая модель: PaddleOCR PP-OCRv6. Для шрифта — собственный retrieval index: рендерим распознанную строку всеми шрифтами из разрешённого каталога, извлекаем embeddings/геометрические признаки, затем дооптимизируем top-k кандидатов по pixel/edge/perceptual loss. FontCLIP можно проверить как feature encoder, но не считать его готовым font identifier.
Нужны два разных семейства proposals:
- design-aware decomposition: LayerD и Qwen-Image-Layered;
- open-vocabulary object proposals: SAM 3 либо Grounding DINO + SAM 2.
LayerD — быстрый и практически удобный baseline для graphic designs: умеет RGBA layers, SVG/PSD export и основан на BiRefNet. Qwen-Image-Layered полезен как generative proposal model, умеет variable layer count и рекурсивную декомпозицию, но рекомендуемое авторами разрешение — 640, доступны buckets 640 и 1024. Поэтому его результат нельзя просто upscale-нуть и назвать high-res.
SAM-подобная маска — только начальная геометрия. Для волос, полупрозрачности, теней и antialiasing нужен отдельный matting/refinement pass в исходном разрешении. Финальный alpha можно уточнять tile-wise, используя исходное изображение и coarse mask.
После удаления верхнего слоя появляются пиксели, которых не было во входе. Это принципиально неоднозначная генеративная часть.
Для каждого объекта храним отдельно:
visible_mask— что действительно видно;amodal_mask— предполагаемая полная форма;rgba_asset— восстановленная текстура объекта;- uncertainty map — где модель галлюцинировала скрытый контент.
Baseline:
- построить occlusion graph из overlaps и границ;
- расширить visible mask до plausible amodal mask;
- восстановить texture объекта и background раздельно;
- проверить, что recomposite восстанавливает исходные видимые пиксели;
- скрытые участки оценивать edit replay, а не reconstruction исходника.
Кандидаты для эксперимента: pix2gestalt как amodal baseline; Qwen-Image-Edit или другая controllable inpainting model для texture/background completion. Выбор production-модели делается только после проверки лицензии, стоимости и работы на собственном benchmark.
Не надо vectorize всё подряд. Сначала classifier выбирает представление:
- фотография/сложная текстура → raster;
- иконка, плоская иллюстрация, простая форма → vector;
- текст → text node;
- градиент/заливка → background/primitive.
Для простых форм сначала fitted primitives: rectangle, rounded rectangle, ellipse, line, polygon, linear/radial gradient. Для сложных плоских областей — VTracer/аналогичный vectorizer с последующей оптимизацией path parameters по rendering loss.
После каждого split/merge/extract система рендерит текущую ветку и проверяет:
- hallucination: появился ли контент, которого не было в parent;
- redundancy: перекрывают ли children один и тот же контент;
- coverage: покрывает ли union children parent;
- reconstruction loss;
- разумность слоя как объекта для редактирования.
Результат действия: accept, retry, refine, merge, prune или stop.
В конце полезен детерминированный optimization pass: при фиксированной структуре подстроить transforms, opacity, colors, gradient stops, alpha edges и typography, минимизируя multi-scale rendering loss. Это дешевле и надёжнее, чем повторно вызывать большую генеративную модель.
| Подзадача | Первый baseline | Роль | Обучать сразу? |
|---|---|---|---|
| Design decomposition | LayerD / BiRefNet | Быстрые RGBA proposals, SVG/PSD baseline | Только после benchmark |
| Generative decomposition | Qwen-Image-Layered | Coarse semantic RGBA layers, recursive split | Нет; сначала inference |
| Object discovery | SAM 3 | Open-vocabulary instances/masks | Нет |
| Fallback grounding | Grounding DINO + SAM 2 | Text-guided boxes + precise masks | Нет |
| OCR | PaddleOCR PP-OCRv6 | Detection/recognition | Fine-tune на synthetic typography при необходимости |
| Font matching | Собственный render-and-retrieve + FontCLIP experiment | Поиск ближайшего доступного шрифта | Да, маленькая domain model возможна |
| Amodal completion | pix2gestalt experiment | Full object proposal | Позже |
| Inpainting | Qwen-Image-Edit/другая licensed model | Background/texture recovery | LoRA только после baseline |
| Vectorization | primitive fitting + VTracer | Editable shapes | Нет |
| Controller/verifier | VLM + deterministic metrics | Tree actions и graceful verification | Сначала API, затем distillation |
| High-res refinement | Matting/refiner on tiles | Альфа и края в native resolution | Вероятный первый useful fine-tune |
Лицензии фиксируются на уровне каждой версии weights, code и dataset. Сейчас LayerD и Qwen-Image-Layered заявляют Apache-2.0; SAM 3 использует отдельную SAM License, поэтому её условия надо проверить до коммерческого решения.
Deliverables:
- JSON schema v0;
- renderer с round-trip test;
- 20 ручных acceptance examples;
- список поддерживаемых layer/effect types;
- определения coarse и fine decomposition;
- CLI-контракт:
decompose input.png --mode coarse|fine.
Критерий выхода: можно вручную собрать документ, экспортировать SVG и снова получить визуально тот же растр.
Запустить на одном benchmark:
- LayerD;
- Qwen-Image-Layered с 3/4/6/8 layers и recursive mode;
- OCR-first hybrid;
- SAM 3 proposals;
- простое background inpainting;
- export/re-render/verifier.
Сохранять все промежуточные artifacts, latency, peak VRAM и предполагаемую стоимость. Не выбирать победителя по красивым пяти картинкам.
Критерий выхода: таблица метрик и taxonomy ошибок минимум на 200 изображениях.
Сделать детерминированный генератор макетов с manifest и seed. Сначала 100k–1M композиций, но не генерировать весь объём до проверки первых 10k.
Обязательные variations:
- разные aspect ratios и 512/1024/2048 render targets;
- русский/английский текст, multiline, rotation, curved text позже;
- raster photos, cutouts, icons, shapes, gradients;
- partial occlusions;
- shadows, stroke, blur, transparency;
- realistic spacing/alignment и deliberately awkward layouts;
- JPEG/re-encode/downscale/upscale/noise/color perturbations;
- unknown-font split и unseen-template split.
Критерий выхода: генератор проходит property tests, а alpha-composite всех GT layers совпадает с clean target с машинной точностью до выбранного renderer.
Начать не с diffusion transformer, а с наиболее дешёвых измеримых компонентов:
- domain fine-tune LayerD/BiRefNet для следующего foreground layer;
- классификатор
text/vector/raster/effect/background; - high-resolution alpha refiner;
- hierarchy/z-order predictor;
- font retrieval model.
Curriculum для foreground extractor:
- 2–4 чистых плоских слоя;
- больше слоёв и полупрозрачность;
- тени/blur;
- degradations;
- реальные макеты и hard negatives.
Критерий выхода: statistically meaningful improvement не только на synthetic, но и на frozen real-world test set.
Собрать controller + verifier state machine:
- coarse analysis root;
- parallel expansion независимых nodes;
- локальные accept/retry/prune;
- budgets по числу model calls и GPU seconds;
- остановка по editability gain, а не только по pixel loss;
- кэширование результатов по image/node hash.
Критерий выхода: hybrid превосходит фиксированный serial pipeline по edit replay и не выходит за cost/latency budget.
Если pipeline упирается именно в несогласованность отдельных RGBA proposals, можно fine-tune end-to-end variable-layer model по архитектуре Qwen:
- RGBA-VAE;
- variable-layer diffusion/flow transformer;
- conditioning на input, layer-count/granularity и scene plan;
- permutation-aware matching predicted ↔ GT layers;
- reconstruction + alpha + perceptual + object identity losses;
- distillation в fewer steps.
Это дорогой этап. Он не заменяет OCR, scene graph, export и edit evaluation.
- dynamic routing: лёгкие designs не отправлять в тяжёлую модель;
- batching и parallel node expansion;
- quantization/compilation только после quality baseline;
- 1024 decomposition + native-resolution matting/refit вместо full diffusion 4K;
- confidence-driven retries;
- GPU worker API и job queue;
- privacy policy, retention и safe image handling;
- cost dashboard по каждому tool call.
Цель $0.30, потолок $0.50 проверяется end-to-end, включая OCR, VLM,
повторные попытки, storage и egress, а не только один diffusion call.
Нужна permutation-invariant привязка layers. Сначала Hungarian matching по комбинации mask IoU, appearance similarity, type и bbox. После matching:
L = λr * L_recompose
+ λa * L_alpha
+ λrgb * L_layer_rgb
+ λp * LPIPS(render(pred), target)
+ λe * L_edge
+ λm * L_mask
+ λz * L_z_order
+ λt * L_type
+ λc * L_coverage_redundancy
+ λedit * L_edit_replay
Важно: один L_recompose недостаточен. Модель может положить весь исходник в
один непрозрачный слой и получить идеальную реконструкцию с нулевой
редактируемостью. Нужны coverage/redundancy penalties, type-aware supervision,
layer sparsity/granularity policy и edit replay.
Подходит для:
- генератора и renderer;
- подготовки/валидации датасета;
- PaddleOCR и лёгких inference runs;
- LayerD на CPU/MPS, если зависимости совместимы;
- обучения небольших classifiers/refiners;
- API, UI и метрик.
Не стоит делать его основной training machine для Qwen-Image-Layered: пример авторов ориентирован на CUDA/bfloat16, а unified 32 GB ограничит размер модели, batch и скорость. Совместимость MPS надо проверять экспериментом, не считать гарантированной.
- baseline/fine-tune лёгких моделей: 1× NVIDIA 48 GB;
- Qwen inference/LoRA и high-res experiments: 1× 80 GB либо несколько GPU;
- full end-to-end fine-tuning: multi-GPU 80 GB class; точная конфигурация только после измерения model/optimizer/activation memory на выбранной архитектуре;
- dataset: сначала сотни GB, затем планировать TB-scale object storage.
Лучше арендовать GPU для коротких измеримых экспериментов, чем заранее строить дорогой training cluster.
- Неопределённый output. «Сделать как Canva» без scene schema и edit suite.
- Оптимизация только PSNR. Один слой-копия входа выигрывает пиксельно.
- Только чистая синтетика. Реальные эффекты ломают идеальные masks.
- Попытка сделать 4K внутри diffusion. Дорого и часто не нужно; лучше coarse semantics + native-res edge refinement.
- Текст после decomposition. Буквы теряются или галлюцинируются.
- Один фиксированный number of layers. Granularity зависит от edit intent.
- Слепой serial pipeline. Ошибка раннего шага распространяется дальше.
- Игнорирование лицензий assets/fonts/weights. Синтетика не означает автоматически безопасные права на исходные изображения и шрифты.
- Нет real-world holdout. Улучшения на synthetic benchmark могут быть фиктивными.
canva-like/
├── README.md
├── docs/
│ ├── PLAN.md
│ ├── DATA_AND_EVAL.md
│ └── adr/
├── schemas/
│ └── document.schema.json
├── src/canva_like/
│ ├── controller/
│ ├── decomposition/
│ ├── text/
│ ├── vector/
│ ├── completion/
│ ├── verifier/
│ ├── render/
│ └── export/
├── synthetic/
│ ├── renderer/
│ ├── templates/
│ └── degradations/
├── eval/
│ ├── metrics/
│ ├── edit_replay/
│ └── benchmark_manifest/
├── tests/
├── configs/
└── scripts/
Перед каждым дорогим этапом отвечаем числами:
- Baselines провалились на каком классе изображений?
- Ошибка вызвана маской, скрытым контентом, типографикой, hierarchy или export?
- Новый training улучшил frozen real set, а не только synthetic?
- Увеличение числа слоёв реально улучшает edit replay?
- Сколько процентов запросов требует тяжёлую generative branch?
- Вписывается ли p50/p95 стоимость в
$0.30/$0.50?
Если на эти вопросы нет ответа, учить следующую большую модель рано.
- Qwen-Image-Layered: https://github.com/QwenLM/Qwen-Image-Layered
- Qwen paper: https://arxiv.org/abs/2512.15603
- LayerD code: https://github.com/CyberAgentAILab/LayerD
- LayerD paper: https://openaccess.thecvf.com/content/ICCV2025/html/Suzuki_LayerD_Decomposing_Raster_Graphic_Designs_into_Layers_ICCV_2025_paper.html
- ReDesign: https://arxiv.org/abs/2607.25565
- SAM 3: https://github.com/facebookresearch/sam3
- SAM 2: https://github.com/facebookresearch/sam2
- Grounded SAM 2: https://github.com/IDEA-Research/Grounded-SAM-2
- PaddleOCR: https://github.com/PaddlePaddle/PaddleOCR
- FontCLIP: https://github.com/yukistavailable/FontCLIP
- pix2gestalt: https://gestalt.cs.columbia.edu/