video-generator / scripts /generate.py
Codex Local
Prepare Hugging Face Space deployment
cb2a484
"""
generate.py — Script principal de génération vidéo (Texte → Vidéo)
Modèle utilisé : Wan 2.1 T2V 1.3B (Hugging Face Diffusers)
Usage :
python generate.py --prompt "votre prompt" --output ../outputs/ma_video.mp4
"""
import argparse
import os
import sys
def _select_torch_dtype(torch_module):
if not torch_module.cuda.is_available():
return torch_module.float32
if torch_module.cuda.is_bf16_supported():
return torch_module.bfloat16
return torch_module.float16
def generate_video(
prompt: str,
output_path: str,
negative_prompt: str = "déformé, moche, flou, mauvaise qualité, artefacts, texte, filigrane",
num_frames: int = 24,
num_inference_steps: int = 25,
height: int = 480,
width: int = 832,
) -> str:
"""
Génère une vidéo à partir d'un prompt texte et la sauvegarde dans le chemin spécifié.
Args:
prompt (str) : Description textuelle de la vidéo à générer.
output_path (str) : Chemin de sauvegarde de la vidéo (ex: outputs/video.mp4).
negative_prompt (str) : Ce que l'on ne veut PAS voir dans la vidéo.
num_frames (int) : Nombre d'images à générer (24 ≈ 1 seconde à 24 fps).
num_inference_steps (int): Nombre d'étapes de diffusion (plus = meilleure qualité, plus lent).
height (int) : Hauteur de la vidéo en pixels.
width (int) : Largeur de la vidéo en pixels.
Returns:
str: Le chemin de la vidéo générée, ou une chaîne vide en cas d'erreur.
"""
try:
import torch
# Importation différée pour éviter les erreurs si les dépendances ne sont pas installées
from diffusers import AutoencoderKLWan, WanPipeline
from diffusers.utils import export_to_video
print(f"[INFO] Chargement du modèle Wan 2.1 T2V 1.3B...")
print(f"[INFO] (Le premier chargement peut prendre du temps — téléchargement des poids)")
model_id = "Wan-AI/Wan2.1-T2V-1.3B-Diffusers"
dtype = _select_torch_dtype(torch)
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"[INFO] Appareil détecté : {device} | dtype : {dtype}")
# Chargement du VAE (encodeur/décodeur vidéo)
vae = AutoencoderKLWan.from_pretrained(
model_id, subfolder="vae", torch_dtype=dtype
)
# Chargement du pipeline principal
pipe = WanPipeline.from_pretrained(
model_id, vae=vae, torch_dtype=dtype
)
if torch.cuda.is_available():
# Optimisation mémoire : décharge les parties inactives du modèle vers la RAM
pipe.enable_model_cpu_offload()
else:
pipe = pipe.to(device)
print(f"[INFO] Modèle chargé. Génération de la vidéo...")
print(f"[INFO] Prompt : {prompt}")
# Génération des frames vidéo
output = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
height=height,
width=width,
num_frames=num_frames,
num_inference_steps=num_inference_steps,
)
# Création du dossier de sortie si nécessaire
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
# Export en fichier vidéo MP4
video_path = export_to_video(output.frames[0], output_path, fps=16)
print(f"[SUCCESS] Vidéo sauvegardée : {video_path}")
return video_path
except ImportError as e:
print(f"[ERREUR] Dépendance manquante : {e}")
print("[AIDE] Installez les dépendances avec : pip install -r requirements.txt")
return ""
except OSError as e:
print(f"[ERREUR] Problème d'environnement Python ou de bibliothèque native : {e}")
print("[AIDE] Utilisez de préférence Python 3.10, 3.11 ou 3.12 avec une version compatible de PyTorch.")
return ""
except Exception as e:
print(f"[ERREUR] Erreur lors de la génération : {e}")
return ""
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Générateur de vidéo IA (Texte → Vidéo) avec Wan 2.1"
)
parser.add_argument(
"--prompt", type=str, required=True,
help="Description textuelle de la vidéo à générer"
)
parser.add_argument(
"--output", type=str, default="../outputs/generated_video.mp4",
help="Chemin de sortie pour la vidéo (défaut: ../outputs/generated_video.mp4)"
)
parser.add_argument(
"--negative_prompt", type=str,
default="déformé, moche, flou, mauvaise qualité, artefacts, texte, filigrane",
help="Ce que l'on ne veut PAS voir dans la vidéo"
)
parser.add_argument(
"--num_frames", type=int, default=24,
help="Nombre d'images à générer (défaut: 24 ≈ 1.5 secondes)"
)
parser.add_argument(
"--steps", type=int, default=25,
help="Nombre d'étapes de diffusion (défaut: 25)"
)
args = parser.parse_args()
result = generate_video(
prompt=args.prompt,
output_path=args.output,
negative_prompt=args.negative_prompt,
num_frames=args.num_frames,
num_inference_steps=args.steps,
)
if result:
print(f"\n✅ Génération réussie ! Vidéo disponible ici : {result}")
else:
print("\n❌ La génération a échoué. Consultez les messages d'erreur ci-dessus.")
sys.exit(1)