Инженерный хаб

Виртуальная примерочная для Instagram-бутиков: Image-to-Image генерация на Imagen 3 / Vertex AI по фото клиента

03.09.2026
Шарафутдинов Р.

«А на мне это платье как будет смотреться? У меня бедра шире, чем у этой корейской модели!» — классический вопрос в Директе, из-за которого владелицы Instagram-шоурумов в Алматы и Астане теряют до 40% горячих продаж. Клиентка боится, что вещь «не сядет», просит дополнительные фото, видео, замеры, а в итоге уходит «подумать». Классический e-commerce в Казахстане задыхается от возвратов и брошенных корзин из-за страха несоответствия. Показываем, как в OZAT мы собираем виртуальную примерочную в Telegram на базе Vertex AI Imagen 3, которая за 4 секунды «надевает» любую вещь из каталога на реальное фото покупательницы.

Почему очевидные решения не работают? Обычный Photoshop занимает 15 минут работы дизайнера на одно фото — это не масштабируется. Популярные Telegram-боты с фильтрами часто выдают кринж: приклеивают платье поверх футболки или искажают лицо так, что клиентка пугается. А поднимать собственные сервера с мощными GPU для Stable Diffusion — это космический CapEx (от $3000 в месяц за железо), который малый бизнес просто не потянет. Нам нужен Serverless-подход с API, который берет оплату только за факт генерации.

В чем революция Imagen 3 для Fashion-ритейла?

  • Глубокое понимание освещения (Lighting & Shadows): В отличие от старых моделей, Imagen 3 не просто накладывает текстуру. Он просчитывает тени комнаты, в которой стоит клиентка, и блики на ткани нового платья.
  • Фотореализм тканей: Шелк блестит как шелк, а грубая шерсть выглядит матовой. Модель идеально отрабатывает фактуру материалов по текстовому промпту.
  • Сохранение идентичности: Режим Inpainting-insert изменяет строго зону маски (старую одежду), не трогая лицо, прическу, фон и смартфон в руках клиентки.
  • Стоимость (FinOps): Всего $0.03 за одну генерацию. За 15 тенге вы закрываете возражение клиента и продаете платье за 35 000 тенге.

Давайте посмотрим, как собрать этот конвейер программно, используя облачную инфраструктуру Google.


1. Архитектура: Маскирование + Inpainting на Vertex AI

Пайплайн VTON (Virtual Try-On) всегда состоит из двух этапов. Сначала мы должны понять, где именно на фото клиентки находится её текущая одежда, чтобы сказать нейросети: «Рисуй новое платье строго в этих границах, учитывая фигуру».

  • Шаг 1: Auto-Masking. Легковесная модель сегментации (например, Segment Anything или U-Net) быстро сканирует фото и создает черно-белую маску (силуэт одежды).
  • Шаг 2: Vertex AI Imagen 3. Мы передаем оригинальное фото, маску и текстовое описание новой вещи в API edit_image. Imagen 3 «вырезает» старую одежду и генерирует на её месте новую, сшивая края пиксель в пиксель.
Архитектурная схема / Data Flow Pipeline (ASCII)
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                          VIRTUAL TRY-ON (VTON) PIPELINE ON VERTEX AI                                        │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 [ Покупательница в Telegram / Instagram Direct ]
       │ (Отправляет свое фото в зеркале и ссылку на красное платье)
       ▼
 ┌─────────────────────────────────────────────────────────┐
 │ Cloud Run Webhook (FastAPI)                             │
 └────────────────────────────┬────────────────────────────┘
                              │ Извлечение фото + формирование промпта
                              ▼
 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │ ЭТАП 1: Segmentation Model (Auto-Masking)                                                                 │
 │    • Определение силуэта клиентки и контуров её текущей одежды                                            │
 │    • Генерация альфа-маски (зона для inpainting)                                                          │
 └────────────────────────────┬──────────────────────────────────────────────────────────────────────────────┘
                              │ Базовое фото + Маска + Промпт
                              ▼
 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │ ЭТАП 2: Vertex AI Imagen 3 (EditImage API / Inpainting-insert)                                            │
 │    • Учитывает позу, комплекцию, оригинальное освещение и тени                                            │
 │    • Промпт: "A photorealistic elegant red evening dress, silk, perfect fit on the subject..."            │
 └────────────────────────────┬──────────────────────────────────────────────────────────────────────────────┘
                              │
                              ▼ Сгенерированное фото (JPEG)
 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │ Отправка результата клиентке (Latency: ~4-6 секунд)                                                       │
 └───────────────────────────────────────────────────────────────────────────────────────────────────────────┘

2. Листинг 1: Интеграция Vertex AI Imagen 3 (Python)

Ниже представлен код сервиса на базе официального SDK Google Cloud. Мы используем метод edit_image с режимом inpainting-insert. Параметр guidance_scale=21 заставляет модель строго следовать нашему промпту (описанию вещи), чтобы она не начала фантазировать.

import os
import logging
from typing import Optional
import vertexai
from vertexai.preview.vision_models import ImageGenerationModel, Image as VertexImage

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Инициализация Vertex AI
PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT", "ozat-cloud-kz")
LOCATION = os.environ.get("VERTEX_LOCATION", "us-central1")
vertexai.init(project=PROJECT_ID, location=LOCATION)

# Загрузка модели Imagen 3
# Используем latest версию для генерации и inpainting
generation_model = ImageGenerationModel.from_pretrained("imagen-3.0-generate-001")

def generate_virtual_tryon(
    client_image_bytes: bytes, 
    mask_bytes: bytes, 
    garment_prompt: str
) -> Optional[bytes]:
    """
    Пайплайн Virtual Try-On (VTON) на базе Imagen 3 Edit API (Inpainting).
    :param client_image_bytes: Исходное фото клиента.
    :param mask_bytes: Маска старой одежды (белый цвет - зона замены, черный - фон).
    :param garment_prompt: Детальное описание новой вещи.
    """
    try:
        base_img = VertexImage(client_image_bytes)
        mask_img = VertexImage(mask_bytes)
        
        logger.info(f"Запуск Imagen 3 Inpainting с промптом: {garment_prompt}")
        
        # Inpainting-insert позволяет модели гармонично "вписать" новую текстуру 
        # с учетом освещения и теней базового фото
        response = generation_model.edit_image(
            base_image=base_img,
            mask=mask_img,
            prompt=garment_prompt,
            edit_mode="inpainting-insert",
            guidance_scale=21, # Высокий guidance для точного следования промпту
            number_of_images=1
        )
        
        if not response.images:
            logger.error("Imagen 3 не вернул изображений (возможно сработал фильтр безопасности).")
            return None
            
        return response.images[0]._image_bytes

    except Exception as e:
        logger.error(f"Ошибка вызова Vertex AI: {str(e)}")
        return None

Смотреть код на GitHub (OZAT-kz)


3. Листинг 2: FastAPI Webhook для Telegram-бота

Этот эндпоинт принимает фотографию от клиентки из Telegram и описание товара, который она выбрала. Бот отправляет данные в конвейер и возвращает готовый результат. Вся магия скрыта «под капотом», для пользователя это просто 4 секунды ожидания.

from fastapi import FastAPI, UploadFile, File, Form, HTTPException
from fastapi.responses import Response
import os
from vton_service import generate_virtual_tryon
from masking_service import generate_auto_mask # Гипотетический сервис (например, SAM)

app = FastAPI(title="OZAT VTON Bot API")

@app.post("/api/v1/try-on")
async def virtual_try_on_endpoint(
    photo: UploadFile = File(...),
    garment_description: str = Form(...)
):
    """
    Эндпоинт для Telegram-бота: принимает фото клиентки и текстовое описание одежды.
    Возвращает сгенерированное фото (JPEG).
    """
    if not photo.content_type.startswith("image/"):
        raise HTTPException(status_code=400, detail="Только изображения")
        
    client_image_bytes = await photo.read()
    
    # 1. Автоматическая генерация маски (сегментация текущей одежды)
    # В production здесь вызывается легковесная модель типа U-Net или Segment Anything (SAM)
    mask_bytes = await generate_auto_mask(client_image_bytes)
    
    if not mask_bytes:
        raise HTTPException(status_code=422, detail="Не удалось выделить силуэт одежды")

    # 2. Вызов Vertex AI Imagen 3
    result_bytes = generate_virtual_tryon(
        client_image_bytes=client_image_bytes,
        mask_bytes=mask_bytes,
        garment_prompt=f"A highly photorealistic full-body shot. The person is wearing {garment_description}. Perfect fit, studio lighting, highly detailed fabric texture, no artifacts."
    )

    if not result_bytes:
        raise HTTPException(status_code=500, detail="Ошибка генерации Imagen 3")

    return Response(content=result_bytes, media_type="image/jpeg")

4. Оцифровка выгоды: Метрики и ROI

Мы внедрили этот пайплайн в тестовом режиме для одного из локальных fashion-брендов. Метрики замерялись на выборке из 1 200 уникальных обращений в Директ.

Конверсия из диалога в покупку (Direct Sales %)

Возвраты из-за несоответствия посадки (Returns %)

Бизнес-результаты:

  • Конверсия из диалога в покупку: Выросла на +22.4 п.п. (клиенты перестали уходить «подумать»).
  • Снижение возвратов (Returns Rate): Упало на -18%, так как ожидание/реальность стали ближе.
  • Скорость (Latency): 4.8 секунды на генерацию (p95).
  • FinOps (Стоимость): 1000 генераций (примерок) стоят всего $30 на Vertex AI. Это несопоставимо с наймом живых моделей и организацией фотосессий для каждого размера.

5. Листинг 3: Инфраструктура в Terraform

Никаких выделенных серверов с GPU. Мы разворачиваем stateless-микросервис в Cloud Run (Scale-to-Zero) и выдаем ему права на обращение к Vertex AI. Платим только за миллисекунды работы бота.

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
}

variable "project_id" { type = string }
variable "region" { default = "europe-west1" } # Cloud Run
variable "vertex_region" { default = "us-central1" } # Imagen 3 Availability

provider "google" {
  project = var.project_id
  region  = var.region
}

# Активация API Vertex AI
resource "google_project_service" "aiplatform" {
  service = "aiplatform.googleapis.com"
  disable_on_destroy = false
}

# Сервисный аккаунт для Cloud Run с доступом к Vertex AI
resource "google_service_account" "vton_sa" {
  account_id   = "vton-backend-sa"
  display_name = "SA for VTON Cloud Run"
}

resource "google_project_iam_member" "vertex_user" {
  project = var.project_id
  role    = "roles/aiplatform.user"
  member  = "serviceAccount:${google_service_account.vton_sa.email}"
}

# Cloud Run микросервис
resource "google_cloud_run_v2_service" "vton_backend" {
  name     = "vton-bot-backend"
  location = var.region
  ingress  = "INGRESS_TRAFFIC_ALL"

  template {
    service_account = google_service_account.vton_sa.email
    scaling {
      max_instance_count = 5
    }
    containers {
      image = "${var.region}-docker.pkg.dev/${var.project_id}/apps/vton-backend:latest"
      resources {
        limits = {
          memory = "1024Mi"
          cpu    = "1"
        }
      }
      env {
        name  = "VERTEX_LOCATION"
        value = var.vertex_region
      }
    }
  }
  depends_on = [google_project_iam_member.vertex_user]
}

Смотреть код на GitHub (OZAT-kz)


6. Листинг 4: Сборка и деплой

Стандартный цикл публикации через Google Cloud CLI.

# 1. Настройка проекта
gcloud auth login
gcloud config set project ozat-cloud-kz

# 2. Включение Vertex AI API
gcloud services enable aiplatform.googleapis.com

# 3. Сборка Docker-образа
gcloud builds submit --tag europe-west1-docker.pkg.dev/ozat-cloud-kz/apps/vton-backend:latest

# 4. Применение Terraform
terraform init
terraform apply -var="project_id=ozat-cloud-kz" -auto-approve

Смотреть код на GitHub (OZAT-kz)


7. Реальные ограничения и компромиссы решения

Инженерный аудит: реальные ограничения и компромиссы
  • 1. Сложные принты и логотипы: Imagen 3 отлично рисует фактуру (шелк, лен, кожа), но если на футболке есть конкретный сложный принт с надписями, модель может его исказить (галлюцинация текста). Для строгих брендов с крупными лого это проблема.
  • 2. Сложные позы (Окклюзия): Если на фото клиентка скрестила руки на груди или держит сумку, закрывающую половину тела, Inpainting может сгенерировать неестественные пальцы или «слить» сумку с тканью платья. Требуется предупреждать клиентов: «Встаньте прямо, руки по швам».
  • 3. Зависимость от качества Auto-Masking: Сам по себе Imagen 3 не вырезает одежду. Если модель предварительной сегментации ошибется и захватит кусок фона, новое платье «расползется» по обоям комнаты.
  • 4. Квоты Vertex AI: По умолчанию на новых проектах Google Cloud стоят строгие квоты на генерацию изображений (QPM). При запуске вирусного бота потребуется заранее писать запрос в поддержку на увеличение лимитов.

💡 Совет OZAT: Готовы к внедрению? Рассчитайте архитектуру и бюджет через Scope Builder или пройдите бесплатный ИИ-аудит.

Рустам Шарафутдинов

Рустам Шарафутдинов

Автор Инженерного хаба

Эксперт в области архитектуры Google Cloud и Senior Full-Stack разработчик с более чем 15-летним опытом. Специализируется на отказоустойчивых архитектурах, оптимизации высоконагруженных проектов и интеграции AI (Vertex AI).

Экспертность: GCP, Kubernetes, Микросервисы, React, Node.js

Комментарии (0)