Accéder au contenu principal

Tutoriel Qwen-Image-Edit-2509 : Générer des angles de produit prêts à l'emploi en studio

Transformez une photo en plusieurs clichés de produits à l'aide de Qwen-Image-Edit-2509 et LoRA. Générez des angles de studio cohérents pour Amazon, Etsy et les boutiques en ligne en quelques secondes.
Actualisé 12 nov. 2025  · 9 min de lecture

Les vendeurs individuels et les petites marques disposent rarement du budget nécessaire pour réaliser une séance photo complète de leurs produits. Dans ce guide, nous allons créer et exécuter une application Gradio qui transforme une seule image d'entrée en rendus de produits multi-angles prêts pour le commerce électronique (grand angle, macro, ±45°, vue de dessus) à l'aide de l' Qwen-Image-Edit-2509 avec des commandes de caméra virtuelle basées sur LoRA pour une photographie de produits IA reproductible.

En arrière-plan, nous utilisons :

  • Modèle de base : Qwen/Qwen-Image-Edit-2509 (Apache-2.0)
  • Contrôle de l'angle LoRA : dx8152/Qwen-Edit-2509-Multiple-angles
  • Vitesse optionnelle LoRA : lightx2v/Qwen-Image-Lightning

Dans ce tutoriel, vous apprendrez à :

  • Veuillez charger le pipeline d'édition Qwen et empiler plusieurs LoRA.
  • Déplacement de la caméra avec des macros d'angle robustes.
  • Développez une interface utilisateur Gradio épurée pour les créateurs et les équipes de commerce électronique.
  • Veuillez exporter tous les résultats au format ZIP pour faciliter le transfert.

Si vous souhaitez en savoir plus sur le traitement des données d'images dans le deep learning, veuillez consulter le cursus de compétences Traitement d'images en Python

Pourquoi utiliser Qwen Image Edit avec LoRA multi-angles ?

Qwen-Image-Edit-2509 est la dernière version du modèle d'édition d'images de Qwen, qui offre une cohérence améliorée et permet l'édition de plusieurs images. La fonctionnalité Multiple-Angles LoRA intègre des commandes fiables de « caméra virtuelle » qui vous permettent de dire :

  • Veuillez utiliser un objectif grand angle.
  • Veuillez passer en mode gros plan.
  • Veuillez tourner l'objectif de 45 degrés vers la gauche.
  • Veuillez orienter la caméra vers le haut (vue de dessus).

Ces commandes reformulent systématiquement le même produit sans le transformer en un nouveau produit.

Tutoriel étape par étape pour l'édition d'images Qwen : Création d'un booster de photos de produits 

Dans ce guide, nous allons créer une application qui transforme une image de produit unique en un ensemble d'angles prêts à l'emploi (y compris des angles tels que grand angle, gros plan, 45° gauche/droite et vue plongeante), avec des préréglages lifestyle optionnels et un mode de prévisualisation rapide. Il utilise le modèle Qwen/Qwen-Image-Edit-2509 et un Multiple-Angles LoRA intégré dans une interface utilisateur Gradio.

Nous passerons de la configuration de l'environnement au chargement du modèle, aux aides à la génération et à une interface utilisateur web.

Étape 1 : Conditions préalables

Veuillez d'abord installer toutes les dépendances d'exécution. Nous utilisons PyTorch avec les roues CUDA, les outils Hugging Face, la bibliothèque Diffusers, Gradio pour l'interface utilisateur et Pillow/OpenCV pour le traitement des images.

pip install -q torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
pip install -q transformers>=4.44.0 accelerate>=0.33.0 safetensors>=0.4.3
pip install -q pillow>=10.2.0 huggingface_hub>=0.24.0 opencv-python-headless>=4.9.0.80
pip install -q numpy>=1.26.0 gradio>=4.0.0
pip install -q git+https://github.com/huggingface/diffusers

Voici ce que fait chaque prérequis :

  • s sur les roues CUDA: La ligne PyTorch fait référence aux roues NVIDIA CUDA 12.1 pour l'accélération GPU.
  • s de transformateurs et de diffuseurs: Transformers gère les configurations et les tokeniseurs, tandis que Diffusers fournit l'QwenImageEditPlusPipeline.
  • Safetensors: Ils fournissent un format tensoriel sécurisé (plus rapide et plus sûr que Pickle).
  • s OpenCV-headless et Pillow: Il offre des fonctionnalités robustes d'E/S d'images et de redimensionnement pour le prétraitement et le post-traitement.
  • Gradio: Il s'agit d'une interface utilisateur web rapide qui fonctionne localement et dans Colab.

Une fois l'environnement prêt, nous pouvons procéder à l'authentification auprès de Hugging Face (facultatif) et charger les modèles.

Étape 2 : Authentification Hugging Face

Certains modèles ou adaptateurs peuvent nécessiter une authentification de la part de HuggingFace. Cette étape vous permet de vous connecter une seule fois pour la session.

from huggingface_hub import login
import os
HF_TOKEN = "Your_HF_Token"  # @param {type:"string"}
if HF_TOKEN:
    login(token=HF_TOKEN)
    print("Logged in to Hugging Face")
else:
    print("WARNING: No token provided. Continuing without authentication")

Veuillez commencer par vous connecter à votre compte HuggingFace et rechercher les jetons d'accès dans les paramètres de votre compte. Veuillez cliquer sur Créer un nouveau jeton et générer un nouveau jeton avec le type de jeton Lecture. Veuillez sélectionner les autorisations requises et générer un nouveau jeton.

Code d'accès HF

Dans la production/Colab, veuillez éviter de coder en dur les jetons. Utilisez plutôt des variables d'environnement ou les « secrets » Colab.

Étape 3 : Charger le modèle et configurer le pipeline

Dans cette section, nous configurons le pipeline Qwen-Image-Edit, chargeons les angles LoRA et ajoutons un commutateur rapide avec des paramètres adaptés au GPU. Veuillez noter que ce code fonctionne efficacement sur un GPU A100 à mémoire RAM élevée.

Étape 3.1 :  Importations et configuration du GPU

Nous allons maintenant importer les bibliothèques principales et détecter le GPU afin de définir automatiquement la précision, le découpage de l'attention et le découpage VAE pour assurer la stabilité.

import io
import zipfile
from typing import List, Tuple, Optional
import gc
import torch
from PIL import Image
from diffusers import QwenImageEditPlusPipeline
import gradio as gr
def get_gpu_config():
    if not torch.cuda.is_available():
        return {
            'device': 'cpu',
            'dtype': torch.float32,
            'gpu_name': 'CPU',
            'vram_gb': 0,
            'max_batch': 1,
            'enable_attention_slicing': True,
            'enable_vae_slicing': True,
        }
    gpu_name = torch.cuda.get_device_name(0)
    vram_gb = torch.cuda.get_device_properties(0).total_memory / 1e9 
    if 'T4' in gpu_name or vram_gb < 20:
        return {
            'device': 'cuda',
            'dtype': torch.bfloat16,
            'gpu_name': gpu_name,
            'vram_gb': vram_gb,
            'max_batch': 1,
            'enable_attention_slicing': True,
            'enable_vae_slicing': True,
        }
    else:
        return {
            'device': 'cuda',
            'dtype': torch.bfloat16,
            'gpu_name': gpu_name,
            'vram_gb': vram_gb,
            'max_batch': 2,
            'enable_attention_slicing': False,
            'enable_vae_slicing': False,
        }
gpu_config = get_gpu_config()
HF_BASE_MODEL = "Qwen/Qwen-Image-Edit-2509"
LORA_ANGLES = "dx8152/Qwen-Edit-2509-Multiple-angles"
LORA_LIGHTNING = "lightx2v/Qwen-Image-Lightning"
ANGLE_MACROS = {
    "Wide-angle": "将镜头转为广角镜头",
    "Close-up": "将镜头转为特写镜头",
    "Forward": "将镜头向前移动",
    "Left": "将镜头向左移动",
    "Right": "将镜头向右移动",
    "Down": "将镜头向下移动",
    "Rotate 45° Left": "将镜头向左旋转45度",
    "Rotate 45° Right": "将镜头向右旋转45度",
    "Top-down": "将镜头转为俯视",
}
BACKGROUND_PRESETS = {
    "(None)": None,
    "Pure Studio (white seamless)": "in a professional studio with seamless white background, soft shadows, product centered",
    "Soft Gray Studio": "in a professional studio with seamless soft gray background, gentle vignette, softbox lighting",
    "Lifestyle (cozy desk)": "on a cozy wooden desk near a window, soft natural light, minimal props",
    "Lifestyle (marble)": "on a clean white marble surface, bright daylight, subtle reflections",
    "Lifestyle (outdoor)": "outdoors on a neutral table, soft shade, bokeh background",
}
ASPECT_RATIOS = {
    "1:1 (Square)": (1024, 1024),
    "4:3 (Standard)": (1024, 768),
    "3:4 (Portrait)": (768, 1024),
    "16:9 (Widescreen)": (1024, 576),
    "9:16 (Mobile)": (576, 1024),
    "3:2 (Photo)": (1024, 683),
    "2:3 (Portrait Photo)": (683, 1024),
}

Voici les éléments clés des blocs de code ci-dessus :

  • Configuration automatique du GPU (fonctionget_gpu_config ) : Nous détectons l'accélérateur disponible et renvoyons un petit dictionnaire de configuration utilisé pour sélectionner le périphérique (CPU/CUDA), le type de données (tel que bfloat16 sur GPU) et les comportements de la mémoire :
    • Sur le processeur, nous utilisons par défaut float32 et activons le découpage attention/VAE pour des raisons de sécurité.
    • Sur T4 / <20 Go de VRAM, nous conservons bfloat16 mais activons le découpage pour éviter les OOM.
    • Sur les GPU de 20 Go ou plus (tels que l'A100), nous désactivons le découpage et autorisons des lots plus importants afin d'accélérer le processus.
  • Identifiants de modèle et adaptateurs : Nous chargeons Qwen-Image-Edit-2509 comme éditeur principal, ainsi que Multiple-angles LoRA pour le contrôle de la caméra, et nous pouvons éventuellement intégrer Lightning LoRA lorsque vous passez en mode rapide. mode rapide.  
    • HF_BASE_MODEL = "Qwen/Qwen-Image-Edit-2509" est le principal outil d'édition d'images.
    • LORA_ANGLES = "dx8152/Qwen-Edit-2509-Multiple-angles" ajoute des commandes de « caméra virtuelle ».
    • LORA_LIGHTNING = "lightx2v/Qwen-Image-Lightning" est un adaptateur de vitesse optionnel permettant d'accélérer les aperçus.

Remarque : pour le mode HQ, seul l'adaptateur d'angles reste actif.

  • Macros d'angle : ANGLE_MACROS associe des étiquettes telles que « Grand angle » ou « Vue plongeante » à des commandes chinoises équivalentes que les angles LoRA comprennent de manière fiable. Ces commandes permettent de déplacer la caméra virtuelle (déplacement/rotation/zoom) sans modifier son identité.
  • Préréglages d'arrière-plan : BACKGROUND_PRESETS sont de courts fragments en anglais tels que « surface en marbre », « studio gris clair », que nous intégrons dans l'invite finale. Elles sont orthogonales aux macros d'angle et sont chargées de contrôler la scène.
  • Formats d'image (ASPECT_RATIOS) : Ces fonctionnalités nous permettent de générer des toiles (1:1, 4:3, 16:9, etc.) et de redimensionner ou de recadrer au centre l'entrée avant l'inférence, de sorte que les sorties ne nécessitent pas de recadrage après la génération.

Nous avons désormais configuré le GPU et les adaptateurs. Veuillez instancier le pipeline Diffusers et connecter les LoRA.

Étape 3.2 : Conduite

Ensuite, nous chargeons le pipeline Qwen Edit de base, activons les optimisations de mémoire en fonction du GPU et empilons le Multiple-Angles LoRA. Nous avons également mis en place un commutateur de mode permettant d'ajouter en option le Lightning LoRA pour des aperçus rapides.

pipe = QwenImageEditPlusPipeline.from_pretrained(
    HF_BASE_MODEL,
    torch_dtype=gpu_config['dtype'],
)
pipe = pipe.to(gpu_config['device'])
if gpu_config['enable_attention_slicing']:
    pipe.enable_attention_slicing()
if gpu_config['enable_vae_slicing']:
    pipe.enable_vae_slicing()
pipe.load_lora_weights(LORA_ANGLES, adapter_name="angles")
current_mode = {"fast": False}
def set_pipeline_mode(use_lightning: bool):
    global current_mode  
    if use_lightning and not current_mode["fast"]:
        pipe.load_lora_weights(LORA_LIGHTNING, adapter_name="lightning")
        pipe.set_adapters(["angles", "lightning"], adapter_weights=[1.0, 1.0])
        current_mode["fast"] = True
    elif not use_lightning and current_mode["fast"]:
        pipe.set_adapters(["angles"], adapter_weights=[1.0])
        current_mode["fast"] = False
    elif not use_lightning and not current_mode["fast"]:
        pipe.set_adapters(["angles"], adapter_weights=[1.0])
set_pipeline_mode(False)

Le code ci-dessus correspond à la couche de configuration du pipeline pour l'application Product Shot Booster, qui exécute les fonctions suivantes :

  • Initialisation du pipeline : Il instancie l'QwenImageEditPlusPipeline à partir du modèle de base (Qwen/Qwen-Image-Edit-2509), le transfère vers le périphérique détecté (CPU/GPU) et définit la précision du tenseur (torch_dtype) en fonction de votre matériel.
  • Sécurité de la mémoire : Sur les GPU plus petits, cela permet à l'attention et au découpage VAE de réduire le pic de VRAM et d'éviter les erreurs de mémoire insuffisante, tout en sacrifiant un peu de vitesse au profit de la stabilité.
  • Composition LoRA : Il charge le LoRA multi-angles afin de fournir des commandes de « caméra virtuelle » reproductibles (déplacement/rotation/zoom) et, en option, intègre le LoRA Lightning pour des aperçus plus rapides.
  • Logique de commutation de mode : La fonction d'aide set_pipeline_mode() et l'indicateur current_mode gèrent les états HQ et Fast, empêchant ainsi les rechargements Lightning redondants et vous permettant de changer d'adaptateur.

Le pipeline est désormais prêt. Passons maintenant aux fonctions de génération de câblage et à l'interface utilisateur Gradio.

Étape 4 : Fonctions de génération

La génération de fonctions permet de générer de l'énergie en créant des invites, en redimensionnant selon le rapport d'aspect cible, en exécutant le pipeline selon les angles sélectionnés et en compressant les résultats dans un fichier zip pour le téléchargement.

Étape 4.1 : Compositeur de messages et outils d'aide au redimensionnement d'images

Avant d'invoquer le modèle, nous normalisons les entrées à l'aide de deux aides sans état :

  • compose_prompt() fonction : Cette fonction assemble une chaîne d'instructions unique à partir de l'angle de la caméra, du préréglage d'arrière-plan, de la scène personnalisée et des notes de style. Des clauses concises contribuent à maintenir la stabilité de l'analyse syntaxique des instructions de Qwen et évitent de surpondérer une partie quelconque.
  • resize_image() fonction : Il adapte l'image source au format cible à l'aide d'une stratégie de mise à l'échelle, le rééchantillonnage Lanczos permet un redimensionnement vers le bas/vers le haut de haute qualité, et un recadrage central afin que le sujet principal reste dans le cadre.
def compose_prompt(angle_phrase: str,
                   bg_preset_text: Optional[str],
                   custom_scene: str,
                   extra_style: str) -> str:
    parts = [angle_phrase]
    if bg_preset_text:
        parts.append(f"{bg_preset_text}")
    if custom_scene.strip():
        parts.append(custom_scene.strip())
    if extra_style.strip():
        parts.append(extra_style.strip())
    return " | ".join(parts)
def resize_image(img: Image.Image, target_size: Tuple[int, int]) -> Image.Image:
    target_w, target_h = target_size
    orig_w, orig_h = img.size
    scale = max(target_w / orig_w, target_h / orig_h)
    new_w = int(orig_w * scale)
    new_h = int(orig_h * scale)
    img = img.resize((new_w, new_h), Image.Resampling.LANCZOS) 
    left = (new_w - target_w) // 2
    top = (new_h - target_h) // 2
    img = img.crop((left, top, left + target_w, top + target_h))    
    return img

Les deux fonctions ci-dessus accomplissent les tâches suivantes :

  • Invite composable : Nous joignons les parties avec « | » afin de conserver une distinction visuelle entre les clauses, tandis que Qwen-Edit gère la ponctuation et produit une analyse cohérente sans privilégier la dernière clause. Nous utilisons également .strip() avec du texte utilisateur afin d'éviter les fragments vides.
  • Calcul de l'échelle de couverture : Cela garantit que l'image redimensionnée couvre entièrement la zone de travail cible dans les deux dimensions.
  • Rééchantillonnage de Lanczos : Il s'agit d'un filtre de haute qualité qui préserve les détails fins lors du sous-échantillonnage et réduit l'aliasing lors de la conversion ascendante.
  • Recadrage central : Après avoir redimensionné l'image, nous recadrons la zone cible exacte à partir du centre afin de conserver la composition originale et d'éviter tout recadrage décentré inattendu.

Avec l'aide de nos collaborateurs, nous sommes désormais en mesure d'exécuter une boucle de génération multi-angles et de regrouper les résultats.

Étape 4.2 : Générer des images 

Ensuite, nous validons les entrées, ajustons l'image à l'aspect choisi, parcourons les angles sélectionnés et exécutons le pipeline dans l'inference_mode. Enfin, nous fournissons un fichier zip contenant toutes les images générées.

def generate_images(
    source_img: Image.Image,
    angle_keys: List[str],
    bg_key: str,
    custom_scene: str,
    extra_style: str,
    aspect_ratio: str,
    use_lightning: bool,
    seed: int,
    steps: int,
    guidance_scale: float,
    true_cfg_scale: float,
    images_per_prompt: int,
    progress=gr.Progress()
) -> List[Image.Image]:   
    if source_img is None:
        return [], "WARNING: Please upload an image first!"    
    if not angle_keys:
        return [], "WARNING: Please select at least one angle!"  
    target_size = ASPECT_RATIOS[aspect_ratio]
    source_img = resize_image(source_img, target_size)  
    set_pipeline_mode(use_lightning)
    results = []
    generator = torch.manual_seed(seed)  
    bg_preset_text = BACKGROUND_PRESETS.get(bg_key)    
    total_angles = len(angle_keys)    
    for idx, angle_name in enumerate(angle_keys):
        progress((idx + 1) / total_angles, f"Generating {angle_name}...") 
        angle_phrase = ANGLE_MACROS[angle_name]
        full_prompt = compose_prompt(angle_phrase, bg_preset_text, custom_scene, extra_style)   
        inputs = {
            "image": [source_img],
            "prompt": full_prompt,
            "generator": generator,
            "true_cfg_scale": true_cfg_scale,
            "negative_prompt": " ",
            "num_inference_steps": steps,
            "guidance_scale": guidance_scale,
            "num_images_per_prompt": images_per_prompt,
            "height": target_size[1],
            "width": target_size[0],
        }     
        with torch.inference_mode():
            out = pipe(**inputs)   
        for img_idx, im in enumerate(out.images):
            results.append(im) 
        if 'T4' in gpu_config['gpu_name']:
            torch.cuda.empty_cache()
    return results
def create_zip(images: List[Image.Image]) -> Optional[str]:
    if not images:
        return None
    zip_path = "/content/product_shot_booster.zip"
    with zipfile.ZipFile(zip_path, mode="w", compression=zipfile.ZIP_DEFLATED) as zf:
        zf.writestr("manifest.txt", "Product Shot Booster Export\nGenerated angles exported as PNG files.\n")
        for idx, img in enumerate(images):
            buf = io.BytesIO()
            img.save(buf, format="PNG")
            zf.writestr(f"angle_{idx+1:03d}.png", buf.getvalue())
    return zip_path

La fonction generate_images() permet la génération et l'exportation multi-angles en :

  • Vérifier, normaliser et configurer : Il vérifie si une image a été téléchargée et si des angles ont été sélectionnés, puis ajuste l'image à l'aspect choisi (redimensionnement et recadrage centré) et bascule entre le mode HQ et le mode rapide via set_pipeline_mode(use_lightning)
  • Inférence efficace : Pour chaque angle, il crée une chaîne d'instructions unique comprenant une macro d'angle, un préréglage d'arrière-plan, une scène et un style. Il prépare ensuite les entrées Diffusers et s'exécute sous torch.inference_mode() afin d'économiser de la mémoire. Sur les GPU à faible VRAM (tels que le T4), les appels tels que torch.cuda.empty_cache() par angle contribuent à réduire la fragmentation.
  • Résultats agrégés avec commentaires de l'interface utilisateur : Il met à jour met à jour la progression de Gradio à mesure que chaque angle est terminé et rassemble toutes les sorties dans une seule liste pour la compression en aval.

La fonction create_zip(images) fournit une exportation portable qui écrit un fichier zip contenant une brève manifest.txtainsi que des images encodées via la mémoire (BytesIO) pour des fichiers sans perte et renvoie None si aucune image n'est présente.

Une fois la génération et le conditionnement finalisés, l'interface utilisateur peut déclencher un passage multi-angles et proposer le téléchargement en un clic de l'ensemble complet des angles.

Étape 5 : Interface utilisateur Gradio

Cette interface utilisateur permet aux utilisateurs de télécharger une image de produit, de sélectionner des angles et des formats d'image, de choisir un arrière-plan prédéfini, de définir des notes de style et de générer des images sous plusieurs angles à tout moment. 

with gr.Blocks(title="Product Shot Booster", theme=gr.themes.Soft()) as demo:
    gr.Markdown("<h1 style='text-align: center;font-weight: bold;'>Product Shot Booster</h1>")
    with gr.Row():
        with gr.Column(scale=1):
            input_image = gr.Image(
                label="Product Image",
                type="pil",
                height=300
            ) 
            angle_choices = gr.CheckboxGroup(
                choices=list(ANGLE_MACROS.keys()),
                value=["Wide-angle", "Close-up", "Rotate 45° Left", "Rotate 45° Right", "Top-down"],
                label="Camera Angles"
            ) 
            aspect_ratio = gr.Dropdown(
                choices=list(ASPECT_RATIOS.keys()),
                value="1:1 (Square)",
                label="Aspect Ratio"
            )
            bg_preset = gr.Dropdown(
                choices=list(BACKGROUND_PRESETS.keys()),
                value="(None)",
                label="Background"
            ) 
            custom_scene = gr.Textbox(
                label="Custom Scene",
                placeholder="e.g., 'on a matte black table with soft reflections'",
                lines=2
            )    
            extra_style = gr.Textbox(
                label="Style Notes",
                value="studio-grade lighting, high clarity, ecommerce-ready composition",
                lines=2
            )
        with gr.Column(scale=2):
            output_gallery = gr.Gallery(
                  label="Generated Images",
                  show_label=True,
                  columns=3,
                  height="auto",
                  object_fit="contain"
              )

            info_output = gr.Markdown("")
            zip_output = gr.File(label="Download ZIP")
    with gr.Accordion("Advanced Settings", open=False):
        with gr.Row():
            use_lightning = gr.Checkbox(
                label="Fast Mode (Lightning LoRA)",
                value=('T4' in gpu_config['gpu_name']),
                info="Enable for faster generation (recommended for T4)"
            )   
            seed = gr.Number(
                label="Seed",
                value=123,
                precision=0
            )  
            steps = gr.Slider(
                label="Inference Steps",
                minimum=10,
                maximum=60,
                value=28,
                step=1
            )
        with gr.Row():
            guidance_scale = gr.Slider(
                label="Guidance Scale",
                minimum=0.0,
                maximum=8.0,
                value=1.0,
                step=0.1
            )
            true_cfg_scale = gr.Slider(
                label="True CFG Scale",
                minimum=0.0,
                maximum=10.0,
                value=4.0,
                step=0.1
            ) 
            images_per_prompt = gr.Slider(
                label="Images per Angle",
                minimum=1,
                maximum=4,
                value=1,
                step=1
            )
    generate_btn = gr.Button("Generate", variant="primary", size="lg")
    def generate_and_zip(*args):
      images = generate_images(*args)
      zip_file = create_zip(images) if images else None
      return images, zip_file 
    generate_btn.click(
        fn=generate_and_zip,
        inputs=[
            input_image,
            angle_choices,
            bg_preset,
            custom_scene,
            extra_style,
            aspect_ratio,
            use_lightning,
            seed,
            steps,
            guidance_scale,
            true_cfg_scale,
            images_per_prompt
        ],
        outputs=[output_gallery, zip_output]
    )
demo.launch(share=True, debug=True, show_error=True)

Démonstration

Le code ci-dessus permet de créer une application Gradio interactive qui relie une seule action de génération à l'inférence et expose une interface utilisateur web partageable, en utilisant :

  • Entrées (colonne de gauche) : Le volet gauche rassemble tous les éléments nécessaires au modèle à l'aide d'un champ « gr.Image » (Télécharger une image de référence) pour télécharger une photo du produit, d'un champ « gr.CheckboxGroup » (Angles de caméra) pour les angles de caméra, de deux champs « gr.Dropdowns » (Paramètres d'image) pour le format d'image et les préréglages d'arrière-plan, et de deux champs « gr.Textbox » (Notes de scène et de style) pour les notes personnalisées sur la scène et le style afin d'affiner l'apparence.
  • Résultats (colonne de droite) : Une méthode d'gr.Gallery e affiche tous les angles générés dans une grille afin que vous puissiez comparer les compositions en un coup d'œil, et un composant d'gr.File e propose des fichiers ZIP au format PNG pour un téléchargement rapide.
  • Paramètres avancés : gr.Checkbox s active le mode rapide (Lightning LoRA) pour des aperçus rapides sur les GPU de classe T4, tandis que Seed et Steps ajustent la reproductibilité et le compromis entre qualité et temps. Guidance s et True-CFG s contrôlent la force d'édition par rapport à la stabilité de l'identité, et Images per Angle s vous permet de produire plusieurs variantes par macro de caméra en une seule fois.
  • Câblage de l'interface (action) : Un seul bouton« Générer » ( ) relie toutes les entrées à la fonction «Générer la galerie » ( generate_images() ) (qui exécute Qwen Edit avec les adaptateurs sélectionnés), puis à la fonction « Générer le ZIP » ( create_zip() ) (qui compresse les sorties), renvoyant à la fois la galerie et le fichier ZIP vers l'interface.
  • Lancement de l'application : Enfin, la méthode demo.launch() lance l'application web et fournit une URL publique à partager, idéale pour les sessions Colab, les démonstrations rapides ou l'envoi d'un lien aux parties prenantes afin qu'elles puissent essayer l'outil par elles-mêmes.

Enfin, cliquez sur Générer et observez le rendu complet du pack. 

Voici les résultats de mes expériences avec ce modèle. Tout d'abord, vous pouvez observer comment les produits sont présentés en fonction des différents paramètres définis.

Dans la vidéo suivante, vous pourrez observer comment j'interagis avec l'interface, les différents paramètres et les résultats générés à partir de notre image originale. 

Conclusions finales

Vous disposez désormais de l'application Product Shot Booster Gradio qui transforme une seule photo en rendus multi-angles à l'aide d'Qwen-Image-Edit-2509 s et des commandes de « caméra virtuelle » LoRA. Il est compatible avec les GPU (A100 optimal, mais les GPU plus petits utilisent le découpage), reproductible et prend en charge un aperçu rapide vers un flux de travail d'exportation HQ.

Voici ce que vous pouvez essayer ensuite :

  • Veuillez expédier : Ajoutez l'authentification et les quotas, et incluez des exportations prédéfinies en un clic pour les spécifications d'images Amazon/Etsy/PDP.
  • Mettre à l'échelle : Exposez une API d'/generate s et prenez en charge les tâches par lots (CSV/JSON des SKU) afin que les équipes puissent générer des packs d'angles à grande échelle.

Si vous souhaitez vous familiariser davantage avec la création d'applications basées sur l'IA, je vous recommande le cursus de compétences « Développer des applications d'IA »

=

Sujets