Carley1234 commited on
Commit
2fc30dd
·
verified ·
1 Parent(s): 03e7b1a

Upload 4 files

Browse files
Files changed (3) hide show
  1. README.md +7 -7
  2. app.py +34 -36
  3. requirements.txt +5 -2
README.md CHANGED
@@ -1,23 +1,23 @@
1
  ---
2
- title: VidSpri Animation Backend
3
  emoji: 🎬
4
- colorFrom: red
5
- colorTo: yellow
6
  sdk: docker
7
  sdk_version: 4.22.1
8
  app_port: 8000
9
- hardware: gpu-a10g-small
10
  python_version: 3.9
11
  ---
12
 
13
- # VidSpri - Servidor de Animación
14
 
15
- Este es el backend para la generación de animaciones de VidSpri. Utiliza el modelo **Stable Video Diffusion** para crear un video corto a partir de una imagen estática y una descripción de texto.
16
 
17
  ## Configuración del Space
18
 
19
  - **SDK:** Docker
20
- - **Hardware:** `gpu-a10g-small` (GPU A10G Small) - **Importante:** Se requiere una GPU para que el modelo funcione.
21
  - **Puerto de la App:** 8000
22
 
23
  ## Endpoint de la API
 
1
  ---
2
+ title: VidSpri Animation Backend (CPU)
3
  emoji: 🎬
4
+ colorFrom: blue
5
+ colorTo: green
6
  sdk: docker
7
  sdk_version: 4.22.1
8
  app_port: 8000
9
+ hardware: cpu-basic
10
  python_version: 3.9
11
  ---
12
 
13
+ # VidSpri - Servidor de Animación (CPU)
14
 
15
+ Este es el backend para la generación de animaciones de VidSpri. Utiliza el pipeline **TextToVideoZeroPipeline** con el modelo base **runwayml/stable-diffusion-v1-5** para crear un video corto a partir de una imagen estática y una descripción de texto, optimizado para ejecutarse en CPU.
16
 
17
  ## Configuración del Space
18
 
19
  - **SDK:** Docker
20
+ - **Hardware:** `cpu-basic` (CPU Básico) - Configurado para el plan gratuito de Hugging Face.
21
  - **Puerto de la App:** 8000
22
 
23
  ## Endpoint de la API
app.py CHANGED
@@ -3,7 +3,7 @@ import torch
3
  from fastapi import FastAPI, File, UploadFile, Form, HTTPException
4
  from fastapi.responses import StreamingResponse
5
  from fastapi.middleware.cors import CORSMiddleware
6
- from diffusers import StableVideoDiffusionPipeline
7
  from PIL import Image
8
  import io
9
  import os
@@ -13,7 +13,7 @@ import imageio
13
  # --- Configuración de la Aplicación FastAPI ---
14
  app = FastAPI()
15
 
16
- # Configura CORS para permitir peticiones desde cualquier origen (puedes restringirlo si es necesario)
17
  app.add_middleware(
18
  CORSMiddleware,
19
  allow_origins=["*"],
@@ -23,25 +23,27 @@ app.add_middleware(
23
  )
24
 
25
  # --- Carga del Modelo de IA ---
26
- # Esta sección carga el modelo de Stable Video Diffusion al iniciar el servidor.
27
- # Usamos un bloque try-except para manejar posibles errores si el modelo no se puede cargar.
28
  try:
29
- # Asegúrate de que el dispositivo sea 'cuda' para usar la GPU, que es esencial para este modelo.
30
- device = "cuda"
31
- # Carga el pipeline del modelo pre-entrenado desde Hugging Face.
32
- # El modelo se descargará automáticamente la primera vez que se ejecute.
33
- # torch.float16 es una optimización para usar menos memoria de la GPU.
34
- pipe = StableVideoDiffusionPipeline.from_pretrained(
35
- "stabilityai/stable-video-diffusion-img2vid-xt",
36
- torch_dtype=torch.float16,
37
- variant="fp16"
 
38
  )
 
 
39
  pipe.to(device)
40
- print("Modelo Stable Video Diffusion cargado exitosamente en la GPU.")
 
 
41
  except Exception as e:
42
  print(f"Error crítico al cargar el modelo: {e}")
43
- # Si el modelo no se carga, el servidor no podrá funcionar.
44
- # En un entorno de producción, podrías querer manejar esto de forma más robusta.
45
  pipe = None
46
 
47
  # --- Endpoints de la API ---
@@ -49,46 +51,42 @@ except Exception as e:
49
  @app.get("/")
50
  def read_root():
51
  """Endpoint raíz para verificar que el servidor está en funcionamiento."""
52
- return {"status": "Servidor de Animación de VidSpri está funcionando"}
53
 
54
  @app.post("/generate-video/")
55
  async def generate_video(
56
  image: UploadFile = File(...),
57
- prompt: str = Form("un personaje corriendo felizmente"), # Prompt por defecto
58
- frames: int = Form(25) # Número de fotogramas por defecto
59
  ):
60
  """
61
- Endpoint principal para generar un video a partir de una imagen y un prompt.
62
  """
63
  if pipe is None:
64
- raise HTTPException(status_code=503, detail="El modelo de IA no está disponible en este momento. Por favor, revisa los logs del servidor.")
65
 
66
  try:
67
- # 1. Cargar y preparar la imagen de entrada
68
  input_bytes = await image.read()
69
  image_pil = Image.open(io.BytesIO(input_bytes)).convert("RGB")
70
 
71
- # El modelo SVD requiere que las imágenes tengan un tamaño específico.
72
- # Redimensionamos la imagen si es necesario.
73
- image_pil = image_pil.resize((1024, 576))
 
74
 
75
- # 2. Generar el video usando el pipeline
76
- # `decode_chunk_size` es una optimización para modelos grandes.
77
- video_frames = pipe(image_pil, num_frames=frames, decode_chunk_size=8).frames[0]
78
-
79
- # 3. Convertir los fotogramas a un video MP4 en memoria
80
- # Convertimos las imágenes PIL a arrays de NumPy, que es el formato que necesita imageio.
81
  np_frames = [np.array(frame) for frame in video_frames]
82
-
83
  video_buffer = io.BytesIO()
84
 
85
- # Usamos imageio para escribir los fotogramas en el buffer como un video MP4.
86
- # El parámetro fps (fotogramas por segundo) controla la velocidad de la animación.
87
- imageio.mimwrite(video_buffer, np_frames, format="mp4", fps=10)
88
 
 
 
89
  video_buffer.seek(0)
90
 
91
- # 4. Devolver el video MP4 como una respuesta de streaming
92
  return StreamingResponse(video_buffer, media_type="video/mp4")
93
 
94
  except Exception as e:
 
3
  from fastapi import FastAPI, File, UploadFile, Form, HTTPException
4
  from fastapi.responses import StreamingResponse
5
  from fastapi.middleware.cors import CORSMiddleware
6
+ from diffusers import TextToVideoZeroPipeline
7
  from PIL import Image
8
  import io
9
  import os
 
13
  # --- Configuración de la Aplicación FastAPI ---
14
  app = FastAPI()
15
 
16
+ # Configura CORS para permitir peticiones desde cualquier origen
17
  app.add_middleware(
18
  CORSMiddleware,
19
  allow_origins=["*"],
 
23
  )
24
 
25
  # --- Carga del Modelo de IA ---
26
+ # Esta sección carga el modelo Zeroscope optimizado para CPU.
 
27
  try:
28
+ # IMPORTANTE: Especificamos "cpu" para asegurar que se ejecute en el hardware gratuito.
29
+ device = "cpu"
30
+ # El tipo de dato 'torch.float32' es el recomendado para CPU.
31
+ dtype = torch.float32
32
+
33
+ # Cargamos el pipeline del modelo Zeroscope v2 576w.
34
+ # El modelo se descargará automáticamente la primera vez.
35
+ pipe = TextToVideoZeroPipeline.from_pretrained(
36
+ "runwayml/stable-diffusion-v1-5",
37
+ torch_dtype=dtype
38
  )
39
+
40
+ # Movemos el pipeline al dispositivo CPU.
41
  pipe.to(device)
42
+
43
+ print("Modelo Zeroscope v2 cargado exitosamente en CPU.")
44
+
45
  except Exception as e:
46
  print(f"Error crítico al cargar el modelo: {e}")
 
 
47
  pipe = None
48
 
49
  # --- Endpoints de la API ---
 
51
  @app.get("/")
52
  def read_root():
53
  """Endpoint raíz para verificar que el servidor está en funcionamiento."""
54
+ return {"status": "Servidor de Animación (CPU) de VidSpri está funcionando"}
55
 
56
  @app.post("/generate-video/")
57
  async def generate_video(
58
  image: UploadFile = File(...),
59
+ prompt: str = Form("un personaje corriendo felizmente"),
60
+ frames: int = Form(25)
61
  ):
62
  """
63
+ Endpoint principal para generar un video a partir de una imagen y un prompt usando CPU.
64
  """
65
  if pipe is None:
66
+ raise HTTPException(status_code=503, detail="El modelo de IA no está disponible. Revisa los logs.")
67
 
68
  try:
69
+ # 1. Cargar la imagen de entrada. El prompt ya viene como texto.
70
  input_bytes = await image.read()
71
  image_pil = Image.open(io.BytesIO(input_bytes)).convert("RGB")
72
 
73
+ # 2. Generar el video usando el pipeline de Zeroscope.
74
+ # Este modelo usa el prompt para guiar la animación de la imagen.
75
+ result = pipe(prompt=prompt, image=image_pil, num_inference_steps=50, num_frames=frames)
76
+ video_frames = result.frames
77
 
78
+ # 3. Convertir los fotogramas (que están en formato PIL) a un video MP4 en memoria.
 
 
 
 
 
79
  np_frames = [np.array(frame) for frame in video_frames]
 
80
  video_buffer = io.BytesIO()
81
 
82
+ # Calculamos los FPS para que el video dure ~2 segundos.
83
+ fps = max(1, round(frames / 2))
 
84
 
85
+ # Usamos imageio para escribir los fotogramas en el buffer como MP4.
86
+ imageio.mimwrite(video_buffer, np_frames, format="mp4", fps=fps)
87
  video_buffer.seek(0)
88
 
89
+ # 4. Devolver el video MP4.
90
  return StreamingResponse(video_buffer, media_type="video/mp4")
91
 
92
  except Exception as e:
requirements.txt CHANGED
@@ -3,12 +3,15 @@ fastapi
3
  uvicorn
4
  python-multipart
5
 
6
- # Modelo de IA y procesamiento de imágenes
7
  torch
8
  diffusers
9
  transformers
10
- accelerate
11
  Pillow
12
  safetensors
13
  imageio
14
  imageio-ffmpeg
 
 
 
 
 
3
  uvicorn
4
  python-multipart
5
 
6
+ # Modelo de IA y procesamiento
7
  torch
8
  diffusers
9
  transformers
 
10
  Pillow
11
  safetensors
12
  imageio
13
  imageio-ffmpeg
14
+
15
+ # Dependencias adicionales para el modelo Zeroscope
16
+ einops
17
+ omegaconf