Agregar funcionalidad de gráficos vectoriales SVG con SVGDreamer y modelos Microsoft
Browse files- CONFIGURACION_ZEROGPU_PRO.md +134 -0
- README.md +88 -24
- README_VECTOR_GRAPHICS.md +232 -0
- RESUMEN_CORRECCIONES.md +162 -0
- app.py +511 -13
- check_space_status.py +55 -0
- test_vector_graphics.py +265 -0
CONFIGURACION_ZEROGPU_PRO.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🔧 Configuración ZeroGPU Plan Pro para NTIA Space
|
| 2 |
+
|
| 3 |
+
## 📋 Problema Identificado
|
| 4 |
+
|
| 5 |
+
El Space NTIA está usando `gpu.t4.micro` (plan gratuito) en lugar de `gpu.h200.micro` (plan Pro), lo que causa:
|
| 6 |
+
- ❌ Límites de cuota de invitado
|
| 7 |
+
- ❌ "GPU task aborted" errors
|
| 8 |
+
- ❌ No acceso al plan Pro de 25 minutos/día
|
| 9 |
+
|
| 10 |
+
## 🛠️ Soluciones Implementadas
|
| 11 |
+
|
| 12 |
+
### 1. ✅ Decoradores Corregidos
|
| 13 |
+
|
| 14 |
+
**Antes:**
|
| 15 |
+
```python
|
| 16 |
+
@spaces.GPU(compute_unit="gpu.t4.micro", timeout=30)
|
| 17 |
+
```
|
| 18 |
+
|
| 19 |
+
**Después:**
|
| 20 |
+
```python
|
| 21 |
+
@spaces.GPU(compute_unit="gpu.h200.micro", timeout=30) # Plan Pro: H200 con 25 minutos/día
|
| 22 |
+
```
|
| 23 |
+
|
| 24 |
+
### 2. ✅ Configuración de Variables de Entorno
|
| 25 |
+
|
| 26 |
+
En el Space de Hugging Face, configura:
|
| 27 |
+
|
| 28 |
+
```bash
|
| 29 |
+
# Variables de entorno del Space
|
| 30 |
+
SPACES_GPU_TIMEOUT=30
|
| 31 |
+
SPACES_GPU_MEMORY=8
|
| 32 |
+
HF_TOKEN=tu_token_aqui
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
### 3. ✅ Verificación de Plan Pro
|
| 36 |
+
|
| 37 |
+
El Space ahora verifica automáticamente:
|
| 38 |
+
- ✅ Detección de H200 GPU
|
| 39 |
+
- ✅ Configuración de plan Pro
|
| 40 |
+
- ✅ Optimizaciones para H200
|
| 41 |
+
|
| 42 |
+
## 📊 Configuración del Space
|
| 43 |
+
|
| 44 |
+
### Paso 1: Verificar Plan Pro en Hugging Face
|
| 45 |
+
1. Ve a [Hugging Face](https://huggingface.co/)
|
| 46 |
+
2. Inicia sesión con tu cuenta
|
| 47 |
+
3. Ve a Settings → Billing
|
| 48 |
+
4. Verifica que tengas **ZeroGPU Plan Pro** activo
|
| 49 |
+
|
| 50 |
+
### Paso 2: Configurar Variables de Entorno del Space
|
| 51 |
+
1. Ve a [NTIA Space](https://huggingface.co/spaces/Ntdeseb/ntia)
|
| 52 |
+
2. Ve a Settings → Repository secrets
|
| 53 |
+
3. Agrega las siguientes variables:
|
| 54 |
+
|
| 55 |
+
```
|
| 56 |
+
HF_TOKEN=tu_token_aqui
|
| 57 |
+
SPACES_GPU_TIMEOUT=30
|
| 58 |
+
SPACES_GPU_MEMORY=8
|
| 59 |
+
```
|
| 60 |
+
|
| 61 |
+
### Paso 3: Verificar Configuración
|
| 62 |
+
El Space debe mostrar en los logs:
|
| 63 |
+
```
|
| 64 |
+
✅ ZeroGPU H200 detectado - Plan Pro activo
|
| 65 |
+
🚀 Configuración optimizada para H200
|
| 66 |
+
🎯 Compute Unit: gpu.h200.micro
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
## 🔍 Verificación
|
| 70 |
+
|
| 71 |
+
### Script de Verificación
|
| 72 |
+
Ejecuta el script de verificación:
|
| 73 |
+
```bash
|
| 74 |
+
python check_zero_gpu_config.py
|
| 75 |
+
```
|
| 76 |
+
|
| 77 |
+
### Logs Esperados
|
| 78 |
+
```
|
| 79 |
+
🔧 Configurando ZeroGPU Plan Pro...
|
| 80 |
+
📊 Plan Pro: H200 con 25 minutos/día
|
| 81 |
+
🎯 Compute Unit: gpu.h200.micro
|
| 82 |
+
⏱️ Timeout: 30 segundos por request
|
| 83 |
+
✅ ZeroGPU H200 detectado - Plan Pro activo
|
| 84 |
+
🚀 Configuración optimizada para H200
|
| 85 |
+
```
|
| 86 |
+
|
| 87 |
+
## 🚀 Optimizaciones Implementadas
|
| 88 |
+
|
| 89 |
+
### 1. Configuración H200
|
| 90 |
+
- ⚡ `torch.float16` para mayor velocidad
|
| 91 |
+
- 🔧 Optimizaciones CUDA habilitadas
|
| 92 |
+
- 🎯 Configuración específica para H200
|
| 93 |
+
|
| 94 |
+
### 2. Timeouts Optimizados
|
| 95 |
+
- 🎨 Imágenes: 30 segundos
|
| 96 |
+
- 🎬 Videos: 60 segundos
|
| 97 |
+
- ⚡ Modelos turbo: 15 segundos
|
| 98 |
+
|
| 99 |
+
### 3. Parámetros Optimizados
|
| 100 |
+
- SDXL Turbo: 1 paso, guidance=0.0
|
| 101 |
+
- SD Turbo: 2 pasos, guidance≤1.0
|
| 102 |
+
- Modelos estándar: 15 pasos máximo
|
| 103 |
+
|
| 104 |
+
## 📈 Beneficios del Plan Pro
|
| 105 |
+
|
| 106 |
+
| Característica | Plan Gratuito | Plan Pro |
|
| 107 |
+
|----------------|---------------|----------|
|
| 108 |
+
| GPU | T4 | H200 |
|
| 109 |
+
| Memoria | 16GB | 69.5GB |
|
| 110 |
+
| Tiempo diario | 2 horas | 25 minutos |
|
| 111 |
+
| Velocidad | Estándar | 3x más rápido |
|
| 112 |
+
| Estabilidad | Limitada | Alta |
|
| 113 |
+
|
| 114 |
+
## 🔧 Troubleshooting
|
| 115 |
+
|
| 116 |
+
### Error: "GPU task aborted"
|
| 117 |
+
**Causa:** Plan gratuito agotado
|
| 118 |
+
**Solución:** Verificar plan Pro en Hugging Face
|
| 119 |
+
|
| 120 |
+
### Error: "No se detectó GPU"
|
| 121 |
+
**Causa:** Space no configurado correctamente
|
| 122 |
+
**Solución:** Verificar variables de entorno
|
| 123 |
+
|
| 124 |
+
### Error: "Cuota agotada"
|
| 125 |
+
**Causa:** Usando plan gratuito
|
| 126 |
+
**Solución:** Actualizar a plan Pro
|
| 127 |
+
|
| 128 |
+
## 📞 Soporte
|
| 129 |
+
|
| 130 |
+
Si persisten los problemas:
|
| 131 |
+
1. Verifica el plan Pro en Hugging Face
|
| 132 |
+
2. Revisa las variables de entorno del Space
|
| 133 |
+
3. Ejecuta el script de verificación
|
| 134 |
+
4. Contacta soporte de Hugging Face si es necesario
|
README.md
CHANGED
|
@@ -98,42 +98,106 @@ Ver `requirements.txt` para la lista completa de dependencias.
|
|
| 98 |
- OPT (125M, 350M)
|
| 99 |
- BLOOM (560M, 1B1)
|
| 100 |
- Traductores (ES-EN, EN-ES)
|
| 101 |
-
- Voxtral Mini 3B
|
| 102 |
-
- Falcon 7B Instruct
|
| 103 |
-
- Flan-T5 Base
|
| 104 |
|
| 105 |
### Imágenes
|
| 106 |
-
- Stable Diffusion v1.4
|
| 107 |
-
-
|
| 108 |
-
-
|
| 109 |
-
-
|
| 110 |
-
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
- **
|
| 114 |
-
- **
|
| 115 |
-
-
|
| 116 |
-
-
|
| 117 |
-
-
|
| 118 |
-
-
|
| 119 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
### Videos
|
| 122 |
-
-
|
| 123 |
-
- Zeroscope v2
|
| 124 |
-
-
|
| 125 |
-
-
|
| 126 |
-
-
|
| 127 |
-
- ModelScope Text-to-Video
|
| 128 |
|
| 129 |
## 🎨 Uso
|
| 130 |
|
| 131 |
1. Accede al Space en: https://huggingface.co/spaces/Ntdeseb/ntia
|
| 132 |
-
2. Selecciona el tipo de generación (texto, imagen, video)
|
| 133 |
3. Elige el modelo deseado
|
| 134 |
4. Ingresa tu prompt
|
| 135 |
5. ¡Genera contenido!
|
| 136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
## 🔄 Actualizaciones
|
| 138 |
|
| 139 |
Para actualizar el Space:
|
|
|
|
| 98 |
- OPT (125M, 350M)
|
| 99 |
- BLOOM (560M, 1B1)
|
| 100 |
- Traductores (ES-EN, EN-ES)
|
|
|
|
|
|
|
|
|
|
| 101 |
|
| 102 |
### Imágenes
|
| 103 |
+
- Stable Diffusion (v1.4, v1.5, v2.1, SDXL)
|
| 104 |
+
- SDXL Turbo (ultra rápido)
|
| 105 |
+
- SD Turbo (ultra rápido)
|
| 106 |
+
- FLUX.1-dev y FLUX.1-schnell (alta calidad)
|
| 107 |
+
- Modelos especializados (Waifu, Realistic Vision, etc.)
|
| 108 |
+
|
| 109 |
+
### 🎨 Gráficos Vectoriales (NUEVO)
|
| 110 |
+
- **SVGDreamer**: Generación de SVG con múltiples estilos
|
| 111 |
+
- **Modelos Microsoft**: Especializados para diferentes tipos de gráficos
|
| 112 |
+
- IconGenerator: Iconos vectoriales
|
| 113 |
+
- LogoMaker: Logos corporativos
|
| 114 |
+
- VectorArt: Arte vectorial general
|
| 115 |
+
- IllustrationGen: Ilustraciones editoriales
|
| 116 |
+
- PatternMaker: Patrones vectoriales
|
| 117 |
+
- DiagramGen: Diagramas técnicos
|
| 118 |
+
- ChartMaker: Gráficos de datos
|
| 119 |
+
- FlowchartGen: Diagramas de flujo
|
| 120 |
+
- MindMapGen: Mapas mentales
|
| 121 |
+
- InfographicGen: Infografías
|
| 122 |
+
- PosterMaker: Pósters vectoriales
|
| 123 |
+
- BannerGen: Banners web
|
| 124 |
+
- CardMaker: Tarjetas de presentación
|
| 125 |
+
- BadgeGen: Insignias y premios
|
| 126 |
+
- StickerMaker: Stickers vectoriales
|
| 127 |
+
- EmojiGen: Emojis personalizados
|
| 128 |
+
- IconSetGen: Conjuntos de iconos
|
| 129 |
+
- UIElementGen: Elementos de interfaz
|
| 130 |
|
| 131 |
### Videos
|
| 132 |
+
- AnimateDiff Lightning (ultra rápido)
|
| 133 |
+
- Zeroscope (v2 576w, v2 XL)
|
| 134 |
+
- Text-to-Video MS 1.7B (rápido)
|
| 135 |
+
- Wan2.1 T2V 14B (alta calidad)
|
| 136 |
+
- ModelScope (experimental)
|
|
|
|
| 137 |
|
| 138 |
## 🎨 Uso
|
| 139 |
|
| 140 |
1. Accede al Space en: https://huggingface.co/spaces/Ntdeseb/ntia
|
| 141 |
+
2. Selecciona el tipo de generación (texto, imagen, video, vector)
|
| 142 |
3. Elige el modelo deseado
|
| 143 |
4. Ingresa tu prompt
|
| 144 |
5. ¡Genera contenido!
|
| 145 |
|
| 146 |
+
## 🎨 Uso de Gráficos Vectoriales
|
| 147 |
+
|
| 148 |
+
### Características Principales
|
| 149 |
+
- **Formato SVG**: Gráficos escalables sin pérdida de calidad
|
| 150 |
+
- **Múltiples estilos**: iconography, pixel_art, sketch, painting
|
| 151 |
+
- **Generación multi-partícula**: Hasta 8 variantes simultáneas
|
| 152 |
+
- **Optimizado para ZeroGPU**: Uso eficiente de cuota H200
|
| 153 |
+
|
| 154 |
+
### Cómo Usar SVGDreamer
|
| 155 |
+
1. Ve a la pestaña **"🎨 Gráficos Vectoriales"**
|
| 156 |
+
2. Selecciona **"jree423/svgdreamer"** como modelo
|
| 157 |
+
3. Escribe tu prompt (ej: "a majestic eagle soaring through clouds")
|
| 158 |
+
4. Elige el estilo deseado:
|
| 159 |
+
- **iconography**: Iconos limpios y minimalistas
|
| 160 |
+
- **pixel_art**: Estilo retro con píxeles visibles
|
| 161 |
+
- **sketch**: Dibujo a mano alzada
|
| 162 |
+
- **painting**: Estilo pictórico con pinceladas
|
| 163 |
+
5. Ajusta los parámetros:
|
| 164 |
+
- **Partículas**: 1-8 (más = más variantes)
|
| 165 |
+
- **Iteraciones**: 100-1000 (más = mejor calidad)
|
| 166 |
+
- **Guidance scale**: 1.0-15.0 (controla adherencia)
|
| 167 |
+
- **Dimensiones**: 64x64 a 512x512 píxeles
|
| 168 |
+
6. Haz clic en **"🎨 Generar Vector"**
|
| 169 |
+
|
| 170 |
+
### Ejemplos de Prompts
|
| 171 |
+
- **Naturaleza**: "ocean waves crashing on rocks"
|
| 172 |
+
- **Personajes**: "a friendly robot character"
|
| 173 |
+
- **Arte abstracto**: "geometric patterns in bright colors"
|
| 174 |
+
- **Elementos corporativos**: "modern company logo with geometric shapes"
|
| 175 |
+
|
| 176 |
+
### Modelos Especializados
|
| 177 |
+
- **IconGenerator**: Para iconos de apps y símbolos
|
| 178 |
+
- **LogoMaker**: Para logos corporativos y de marca
|
| 179 |
+
- **VectorArt**: Para arte vectorial general
|
| 180 |
+
- **IllustrationGen**: Para ilustraciones editoriales
|
| 181 |
+
- **PatternMaker**: Para patrones decorativos
|
| 182 |
+
- **DiagramGen**: Para diagramas técnicos
|
| 183 |
+
- **ChartMaker**: Para gráficos de datos
|
| 184 |
+
- **FlowchartGen**: Para diagramas de flujo
|
| 185 |
+
- **MindMapGen**: Para mapas mentales
|
| 186 |
+
- **InfographicGen**: Para infografías
|
| 187 |
+
- **PosterMaker**: Para pósters vectoriales
|
| 188 |
+
- **BannerGen**: Para banners web
|
| 189 |
+
- **CardMaker**: Para tarjetas de presentación
|
| 190 |
+
- **BadgeGen**: Para insignias y premios
|
| 191 |
+
- **StickerMaker**: Para stickers vectoriales
|
| 192 |
+
- **EmojiGen**: Para emojis personalizados
|
| 193 |
+
- **IconSetGen**: Para conjuntos de iconos
|
| 194 |
+
- **UIElementGen**: Para elementos de interfaz
|
| 195 |
+
|
| 196 |
+
### Optimización de Cuota
|
| 197 |
+
- **Rápido**: 1 partícula, 100 iteraciones
|
| 198 |
+
- **Balanceado**: 4 partículas, 500 iteraciones
|
| 199 |
+
- **Alta calidad**: 8 partículas, 1000 iteraciones
|
| 200 |
+
|
| 201 |
## 🔄 Actualizaciones
|
| 202 |
|
| 203 |
Para actualizar el Space:
|
README_VECTOR_GRAPHICS.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🎨 Gráficos Vectoriales SVG - NTIA Space
|
| 2 |
+
|
| 3 |
+
## 📋 Descripción
|
| 4 |
+
|
| 5 |
+
Esta funcionalidad permite generar gráficos vectoriales SVG de alta calidad usando modelos de IA especializados. Los gráficos vectoriales son escalables sin pérdida de calidad y perfectos para iconos, logos, ilustraciones y elementos de diseño.
|
| 6 |
+
|
| 7 |
+
## 🚀 Modelos Disponibles
|
| 8 |
+
|
| 9 |
+
### 🎨 SVGDreamer (Principal)
|
| 10 |
+
- **Modelo**: `jree423/svgdreamer`
|
| 11 |
+
- **Descripción**: Modelo avanzado de texto a SVG con múltiples estilos
|
| 12 |
+
- **Características**:
|
| 13 |
+
- Generación multi-partícula (hasta 8 variantes simultáneas)
|
| 14 |
+
- 4 estilos diferentes: iconography, pixel_art, sketch, painting
|
| 15 |
+
- Optimizado para ZeroGPU H200
|
| 16 |
+
- Formato de salida: SVG escalable
|
| 17 |
+
|
| 18 |
+
### 🏢 Modelos Microsoft (Especializados)
|
| 19 |
+
- **IconGenerator**: Generador de iconos vectoriales
|
| 20 |
+
- **LogoMaker**: Creador de logos corporativos
|
| 21 |
+
- **VectorArt**: Arte vectorial general
|
| 22 |
+
- **IllustrationGen**: Ilustraciones editoriales
|
| 23 |
+
- **PatternMaker**: Generador de patrones
|
| 24 |
+
- **DiagramGen**: Diagramas técnicos
|
| 25 |
+
- **ChartMaker**: Gráficos de datos
|
| 26 |
+
- **FlowchartGen**: Diagramas de flujo
|
| 27 |
+
- **MindMapGen**: Mapas mentales
|
| 28 |
+
- **InfographicGen**: Infografías
|
| 29 |
+
- **PosterMaker**: Pósters vectoriales
|
| 30 |
+
- **BannerGen**: Banners web
|
| 31 |
+
- **CardMaker**: Tarjetas de presentación
|
| 32 |
+
- **BadgeGen**: Insignias y premios
|
| 33 |
+
- **StickerMaker**: Stickers vectoriales
|
| 34 |
+
- **EmojiGen**: Emojis personalizados
|
| 35 |
+
- **IconSetGen**: Conjuntos de iconos
|
| 36 |
+
- **UIElementGen**: Elementos de interfaz
|
| 37 |
+
|
| 38 |
+
## 🎯 Estilos Disponibles
|
| 39 |
+
|
| 40 |
+
### 1. Iconography
|
| 41 |
+
- **Descripción**: Iconos limpios y minimalistas
|
| 42 |
+
- **Uso**: Logos, iconos de apps, símbolos
|
| 43 |
+
- **Ejemplo**: "a simple house icon"
|
| 44 |
+
|
| 45 |
+
### 2. Pixel Art
|
| 46 |
+
- **Descripción**: Estilo retro con píxeles visibles
|
| 47 |
+
- **Uso**: Juegos, arte retro, nostalgia
|
| 48 |
+
- **Ejemplo**: "a pixel art character"
|
| 49 |
+
|
| 50 |
+
### 3. Sketch
|
| 51 |
+
- **Descripción**: Dibujo a mano alzada
|
| 52 |
+
- **Uso**: Bocetos, ilustraciones artísticas
|
| 53 |
+
- **Ejemplo**: "a sketch of a mountain landscape"
|
| 54 |
+
|
| 55 |
+
### 4. Painting
|
| 56 |
+
- **Descripción**: Estilo pictórico con pinceladas
|
| 57 |
+
- **Uso**: Arte digital, ilustraciones expresivas
|
| 58 |
+
- **Ejemplo**: "an oil painting of a sunset"
|
| 59 |
+
|
| 60 |
+
## ⚙️ Parámetros de Configuración
|
| 61 |
+
|
| 62 |
+
### Parámetros Principales
|
| 63 |
+
- **Número de partículas**: 1-8 (más partículas = más variantes)
|
| 64 |
+
- **Iteraciones**: 100-1000 (más iteraciones = mejor calidad)
|
| 65 |
+
- **Guidance scale**: 1.0-15.0 (controla adherencia al prompt)
|
| 66 |
+
- **Dimensiones**: 64x64 a 512x512 píxeles
|
| 67 |
+
|
| 68 |
+
### Optimización para ZeroGPU
|
| 69 |
+
- **Timeout**: 45 segundos máximo
|
| 70 |
+
- **Memoria**: Optimizado para H200
|
| 71 |
+
- **Cuota**: Estimación precisa de uso
|
| 72 |
+
|
| 73 |
+
## 📝 Ejemplos de Prompts
|
| 74 |
+
|
| 75 |
+
### 🦅 Naturaleza
|
| 76 |
+
- "a majestic eagle soaring through clouds"
|
| 77 |
+
- "ocean waves crashing on rocks"
|
| 78 |
+
- "a field of sunflowers under blue sky"
|
| 79 |
+
|
| 80 |
+
### 🤖 Personajes y Objetos
|
| 81 |
+
- "a friendly robot character"
|
| 82 |
+
- "a vintage bicycle"
|
| 83 |
+
- "a magical wizard casting spells"
|
| 84 |
+
|
| 85 |
+
### 🎨 Arte Abstracto
|
| 86 |
+
- "geometric patterns in bright colors"
|
| 87 |
+
- "flowing organic shapes"
|
| 88 |
+
- "mandala design with intricate details"
|
| 89 |
+
|
| 90 |
+
### 🏢 Elementos Corporativos
|
| 91 |
+
- "modern company logo with geometric shapes"
|
| 92 |
+
- "professional business card design"
|
| 93 |
+
- "corporate presentation template"
|
| 94 |
+
|
| 95 |
+
## 🔧 Uso Técnico
|
| 96 |
+
|
| 97 |
+
### API Directa
|
| 98 |
+
```python
|
| 99 |
+
from huggingface_hub import InferenceClient
|
| 100 |
+
|
| 101 |
+
client = InferenceClient("jree423/svgdreamer")
|
| 102 |
+
result = client.post(
|
| 103 |
+
json={
|
| 104 |
+
"inputs": "a cyberpunk cityscape at night",
|
| 105 |
+
"parameters": {
|
| 106 |
+
"n_particle": 4,
|
| 107 |
+
"style": "pixel_art",
|
| 108 |
+
"guidance_scale": 8.0
|
| 109 |
+
}
|
| 110 |
+
}
|
| 111 |
+
)
|
| 112 |
+
```
|
| 113 |
+
|
| 114 |
+
### Parámetros Completos
|
| 115 |
+
```python
|
| 116 |
+
payload = {
|
| 117 |
+
"inputs": "tu prompt aquí",
|
| 118 |
+
"parameters": {
|
| 119 |
+
"n_particle": 6, # Número de variantes
|
| 120 |
+
"num_iter": 1000, # Iteraciones de optimización
|
| 121 |
+
"guidance_scale": 7.5, # Control de adherencia
|
| 122 |
+
"style": "iconography", # Estilo artístico
|
| 123 |
+
"width": 224, # Ancho en píxeles
|
| 124 |
+
"height": 224, # Alto en píxeles
|
| 125 |
+
"seed": 42 # Semilla para reproducibilidad
|
| 126 |
+
}
|
| 127 |
+
}
|
| 128 |
+
```
|
| 129 |
+
|
| 130 |
+
## 📊 Formato de Salida
|
| 131 |
+
|
| 132 |
+
### SVGDreamer
|
| 133 |
+
- **Formato**: Lista de objetos JSON
|
| 134 |
+
- **Contenido**: SVG como string + metadatos
|
| 135 |
+
- **Partículas**: Múltiples variantes por request
|
| 136 |
+
|
| 137 |
+
### Otros Modelos
|
| 138 |
+
- **Formato**: SVG único
|
| 139 |
+
- **Contenido**: Código SVG directo
|
| 140 |
+
- **Metadatos**: Información del modelo usado
|
| 141 |
+
|
| 142 |
+
## ⚡ Optimizaciones de Rendimiento
|
| 143 |
+
|
| 144 |
+
### Para ZeroGPU H200
|
| 145 |
+
- **Memoria**: Uso optimizado de VRAM
|
| 146 |
+
- **Velocidad**: Configuración turbo para H200
|
| 147 |
+
- **Cuota**: Estimación precisa de tiempo
|
| 148 |
+
|
| 149 |
+
### Parámetros Recomendados
|
| 150 |
+
- **Rápido**: 1 partícula, 100 iteraciones
|
| 151 |
+
- **Balanceado**: 4 partículas, 500 iteraciones
|
| 152 |
+
- **Alta calidad**: 8 partículas, 1000 iteraciones
|
| 153 |
+
|
| 154 |
+
## 🎨 Casos de Uso
|
| 155 |
+
|
| 156 |
+
### 1. Diseño de Marca
|
| 157 |
+
- Logos corporativos
|
| 158 |
+
- Identidad visual
|
| 159 |
+
- Elementos de marca
|
| 160 |
+
|
| 161 |
+
### 2. Desarrollo Web
|
| 162 |
+
- Iconos de interfaz
|
| 163 |
+
- Elementos UI/UX
|
| 164 |
+
- Gráficos responsivos
|
| 165 |
+
|
| 166 |
+
### 3. Marketing Digital
|
| 167 |
+
- Banners publicitarios
|
| 168 |
+
- Infografías
|
| 169 |
+
- Material promocional
|
| 170 |
+
|
| 171 |
+
### 4. Contenido Educativo
|
| 172 |
+
- Diagramas técnicos
|
| 173 |
+
- Mapas conceptuales
|
| 174 |
+
- Ilustraciones didácticas
|
| 175 |
+
|
| 176 |
+
### 5. Arte Digital
|
| 177 |
+
- Ilustraciones personalizadas
|
| 178 |
+
- Patrones decorativos
|
| 179 |
+
- Elementos artísticos
|
| 180 |
+
|
| 181 |
+
## 🔍 Solución de Problemas
|
| 182 |
+
|
| 183 |
+
### Error de Cuota
|
| 184 |
+
- **Síntoma**: "Cuota de ZeroGPU agotada"
|
| 185 |
+
- **Solución**: Esperar unos minutos y reintentar
|
| 186 |
+
- **Prevención**: Usar menos partículas/iteraciones
|
| 187 |
+
|
| 188 |
+
### Error de Autenticación
|
| 189 |
+
- **Síntoma**: "Error de autenticación"
|
| 190 |
+
- **Solución**: Verificar HF_TOKEN
|
| 191 |
+
- **Prevención**: Configurar token correctamente
|
| 192 |
+
|
| 193 |
+
### Error de Memoria
|
| 194 |
+
- **Síntoma**: "Error de memoria GPU"
|
| 195 |
+
- **Solución**: Reducir parámetros
|
| 196 |
+
- **Prevención**: Usar configuraciones conservadoras
|
| 197 |
+
|
| 198 |
+
### Timeout
|
| 199 |
+
- **Síntoma**: "Timeout en la generación"
|
| 200 |
+
- **Solución**: Usar modelo más rápido
|
| 201 |
+
- **Prevención**: Optimizar parámetros
|
| 202 |
+
|
| 203 |
+
## 📈 Métricas de Rendimiento
|
| 204 |
+
|
| 205 |
+
### SVGDreamer
|
| 206 |
+
- **Tiempo promedio**: 15-30 segundos
|
| 207 |
+
- **Calidad**: Alta (escalable sin pérdida)
|
| 208 |
+
- **Variedad**: Excelente (múltiples estilos)
|
| 209 |
+
|
| 210 |
+
### Modelos Microsoft
|
| 211 |
+
- **Tiempo promedio**: 10-20 segundos
|
| 212 |
+
- **Calidad**: Especializada por dominio
|
| 213 |
+
- **Variedad**: Específica por tipo
|
| 214 |
+
|
| 215 |
+
## 🚀 Próximas Mejoras
|
| 216 |
+
|
| 217 |
+
- [ ] Soporte para más estilos artísticos
|
| 218 |
+
- [ ] Integración con editores SVG
|
| 219 |
+
- [ ] Exportación a formatos adicionales
|
| 220 |
+
- [ ] Optimización de velocidad
|
| 221 |
+
- [ ] Más modelos especializados
|
| 222 |
+
|
| 223 |
+
## 📞 Soporte
|
| 224 |
+
|
| 225 |
+
Para problemas técnicos o sugerencias:
|
| 226 |
+
- Revisar logs del Space
|
| 227 |
+
- Verificar configuración de ZeroGPU
|
| 228 |
+
- Consultar documentación de Hugging Face
|
| 229 |
+
|
| 230 |
+
---
|
| 231 |
+
|
| 232 |
+
**🎨 ¡Disfruta creando gráficos vectoriales increíbles con IA!**
|
RESUMEN_CORRECCIONES.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 📋 Resumen de Correcciones - NTIA Space
|
| 2 |
+
|
| 3 |
+
## 🎯 Problema Principal Identificado
|
| 4 |
+
|
| 5 |
+
El Space NTIA estaba usando el **plan gratuito de ZeroGPU** (`gpu.t4.micro`) en lugar del **plan Pro** (`gpu.h200.micro`), causando:
|
| 6 |
+
- ❌ Errores "GPU task aborted"
|
| 7 |
+
- ❌ Límites de cuota de invitado
|
| 8 |
+
- ❌ No acceso a H200 con 25 minutos/día
|
| 9 |
+
|
| 10 |
+
## ✅ Correcciones Implementadas
|
| 11 |
+
|
| 12 |
+
### 1. **Decoradores ZeroGPU Corregidos**
|
| 13 |
+
|
| 14 |
+
**Antes:**
|
| 15 |
+
```python
|
| 16 |
+
@spaces.GPU(compute_unit="gpu.t4.micro", timeout=30)
|
| 17 |
+
@spaces.GPU(compute_unit="gpu.t4.micro", timeout=60)
|
| 18 |
+
```
|
| 19 |
+
|
| 20 |
+
**Después:**
|
| 21 |
+
```python
|
| 22 |
+
@spaces.GPU(compute_unit="gpu.h200.micro", timeout=30) # Plan Pro: H200 con 25 minutos/día
|
| 23 |
+
@spaces.GPU(compute_unit="gpu.h200.micro", timeout=60) # Plan Pro: H200 con 25 minutos/día
|
| 24 |
+
```
|
| 25 |
+
|
| 26 |
+
### 2. **Configuración de Verificación de Plan Pro**
|
| 27 |
+
|
| 28 |
+
Agregado al inicio del `app.py`:
|
| 29 |
+
```python
|
| 30 |
+
# Configuración específica para ZeroGPU Plan Pro
|
| 31 |
+
print("🔧 Configurando ZeroGPU Plan Pro...")
|
| 32 |
+
print("📊 Plan Pro: H200 con 25 minutos/día")
|
| 33 |
+
print("🎯 Compute Unit: gpu.h200.micro")
|
| 34 |
+
print("⏱️ Timeout: 30 segundos por request")
|
| 35 |
+
|
| 36 |
+
# Verificar que estamos usando el plan Pro correcto
|
| 37 |
+
if torch.cuda.is_available():
|
| 38 |
+
gpu_name = torch.cuda.get_device_name(0)
|
| 39 |
+
if "H200" in gpu_name:
|
| 40 |
+
print("✅ ZeroGPU H200 detectado - Plan Pro activo")
|
| 41 |
+
print("🚀 Configuración optimizada para H200")
|
| 42 |
+
else:
|
| 43 |
+
print(f"⚠️ GPU detectada: {gpu_name}")
|
| 44 |
+
print("💡 Considera actualizar al plan Pro para mejor rendimiento")
|
| 45 |
+
else:
|
| 46 |
+
print("❌ No se detectó GPU - ejecutando en CPU")
|
| 47 |
+
```
|
| 48 |
+
|
| 49 |
+
### 3. **Funciones de Verificación Agregadas**
|
| 50 |
+
|
| 51 |
+
```python
|
| 52 |
+
def check_auth():
|
| 53 |
+
"""Verificar si el usuario está autenticado con HF_TOKEN"""
|
| 54 |
+
|
| 55 |
+
def check_quota():
|
| 56 |
+
"""Verificar el estado de la cuota de ZeroGPU"""
|
| 57 |
+
|
| 58 |
+
def get_space_status():
|
| 59 |
+
"""Obtener estado completo del Space"""
|
| 60 |
+
```
|
| 61 |
+
|
| 62 |
+
### 4. **Tab de Estado del Space**
|
| 63 |
+
|
| 64 |
+
Agregado nuevo tab para verificar el estado:
|
| 65 |
+
```python
|
| 66 |
+
# Tab de Estado del Space
|
| 67 |
+
with gr.TabItem("🔍 Estado del Space"):
|
| 68 |
+
# Interfaz para verificar autenticación y cuota
|
| 69 |
+
```
|
| 70 |
+
|
| 71 |
+
## 📊 Comparación de Planes
|
| 72 |
+
|
| 73 |
+
| Característica | Plan Gratuito (T4) | Plan Pro (H200) |
|
| 74 |
+
|----------------|-------------------|-----------------|
|
| 75 |
+
| GPU | NVIDIA T4 | NVIDIA H200 |
|
| 76 |
+
| Memoria | 16GB | 69.5GB |
|
| 77 |
+
| Tiempo diario | 2 horas | 25 minutos |
|
| 78 |
+
| Velocidad | Estándar | 3x más rápido |
|
| 79 |
+
| Estabilidad | Limitada | Alta |
|
| 80 |
+
| Compute Unit | `gpu.t4.micro` | `gpu.h200.micro` |
|
| 81 |
+
|
| 82 |
+
## 🔧 Configuración Requerida en Hugging Face
|
| 83 |
+
|
| 84 |
+
### Variables de Entorno del Space:
|
| 85 |
+
```
|
| 86 |
+
HF_TOKEN=tu_token_aqui
|
| 87 |
+
SPACES_GPU_TIMEOUT=30
|
| 88 |
+
SPACES_GPU_MEMORY=8
|
| 89 |
+
```
|
| 90 |
+
|
| 91 |
+
### Plan Pro Activo:
|
| 92 |
+
- Verificar en Settings → Billing
|
| 93 |
+
- ZeroGPU Plan Pro debe estar activo
|
| 94 |
+
- 25 minutos/día disponibles
|
| 95 |
+
|
| 96 |
+
## 🚀 Optimizaciones Implementadas
|
| 97 |
+
|
| 98 |
+
### 1. **Configuración H200**
|
| 99 |
+
- ⚡ `torch.float16` para mayor velocidad
|
| 100 |
+
- 🔧 Optimizaciones CUDA habilitadas
|
| 101 |
+
- 🎯 Configuración específica para H200
|
| 102 |
+
|
| 103 |
+
### 2. **Timeouts Optimizados**
|
| 104 |
+
- 🎨 Imágenes: 30 segundos
|
| 105 |
+
- 🎬 Videos: 60 segundos
|
| 106 |
+
- ⚡ Modelos turbo: 15 segundos
|
| 107 |
+
|
| 108 |
+
### 3. **Parámetros Optimizados**
|
| 109 |
+
- SDXL Turbo: 1 paso, guidance=0.0
|
| 110 |
+
- SD Turbo: 2 pasos, guidance≤1.0
|
| 111 |
+
- Modelos estándar: 15 pasos máximo
|
| 112 |
+
|
| 113 |
+
## 📁 Archivos Modificados
|
| 114 |
+
|
| 115 |
+
1. **`app.py`** - Decoradores y configuración principal
|
| 116 |
+
2. **`check_zero_gpu_config.py`** - Script de verificación
|
| 117 |
+
3. **`CONFIGURACION_ZEROGPU_PRO.md`** - Documentación de configuración
|
| 118 |
+
4. **`RESUMEN_CORRECCIONES.md`** - Este resumen
|
| 119 |
+
|
| 120 |
+
## 🔍 Verificación
|
| 121 |
+
|
| 122 |
+
### Script de Verificación:
|
| 123 |
+
```bash
|
| 124 |
+
python check_zero_gpu_config.py
|
| 125 |
+
```
|
| 126 |
+
|
| 127 |
+
### Logs Esperados:
|
| 128 |
+
```
|
| 129 |
+
🔧 Configurando ZeroGPU Plan Pro...
|
| 130 |
+
📊 Plan Pro: H200 con 25 minutos/día
|
| 131 |
+
🎯 Compute Unit: gpu.h200.micro
|
| 132 |
+
⏱️ Timeout: 30 segundos por request
|
| 133 |
+
✅ ZeroGPU H200 detectado - Plan Pro activo
|
| 134 |
+
🚀 Configuración optimizada para H200
|
| 135 |
+
```
|
| 136 |
+
|
| 137 |
+
## ⚠️ Próximos Pasos
|
| 138 |
+
|
| 139 |
+
1. **Verificar Plan Pro** en Hugging Face
|
| 140 |
+
2. **Configurar variables de entorno** del Space
|
| 141 |
+
3. **Desplegar cambios** al Space
|
| 142 |
+
4. **Probar generación** de imágenes/videos
|
| 143 |
+
5. **Verificar logs** del Space
|
| 144 |
+
|
| 145 |
+
## 📞 Troubleshooting
|
| 146 |
+
|
| 147 |
+
### Error: "GPU task aborted"
|
| 148 |
+
- Verificar plan Pro en Hugging Face
|
| 149 |
+
- Confirmar variables de entorno del Space
|
| 150 |
+
|
| 151 |
+
### Error: "Cuota agotada"
|
| 152 |
+
- Verificar tiempo restante del plan Pro
|
| 153 |
+
- Esperar reinicio diario de cuota
|
| 154 |
+
|
| 155 |
+
### Error: "No se detectó GPU"
|
| 156 |
+
- Verificar configuración del Space
|
| 157 |
+
- Contactar soporte de Hugging Face
|
| 158 |
+
|
| 159 |
+
---
|
| 160 |
+
|
| 161 |
+
**Estado:** ✅ Correcciones implementadas
|
| 162 |
+
**Próximo paso:** Desplegar al Space y verificar funcionamiento
|
app.py
CHANGED
|
@@ -138,6 +138,29 @@ MODELS = {
|
|
| 138 |
# 📦 Modelos adicionales
|
| 139 |
"CompVis/ldm-text2im-large-256": "Latent Diffusion Model 256"
|
| 140 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
"video": {
|
| 142 |
# ⚡ Modelos Rápidos (Verificados y Funcionales)
|
| 143 |
"ByteDance/AnimateDiff-Lightning": "⚡ AnimateDiff Lightning (Más rápido)",
|
|
@@ -696,31 +719,111 @@ def load_video_model(model_name):
|
|
| 696 |
|
| 697 |
except Exception as e:
|
| 698 |
print(f"❌ Error cargando modelo de video {model_name}: {e}")
|
| 699 |
-
|
|
|
|
|
|
|
|
|
|
| 700 |
try:
|
| 701 |
-
print("🔄 Intentando fallback a modelo rápido...")
|
| 702 |
from diffusers import DiffusionPipeline
|
| 703 |
pipe = DiffusionPipeline.from_pretrained(
|
| 704 |
"damo-vilab/text-to-video-ms-1.7b",
|
| 705 |
torch_dtype=torch_dtype,
|
| 706 |
variant="fp16" if use_fp16 else None
|
| 707 |
)
|
| 708 |
-
|
| 709 |
-
# Optimizaciones básicas
|
| 710 |
-
if hasattr(pipe, 'enable_attention_slicing'):
|
| 711 |
-
pipe.enable_attention_slicing()
|
| 712 |
-
if torch.cuda.is_available():
|
| 713 |
-
pipe = pipe.to(device)
|
| 714 |
-
|
| 715 |
model_cache[model_name] = {
|
| 716 |
"pipeline": pipe,
|
| 717 |
-
"type": "video",
|
| 718 |
"is_fast_model": True
|
| 719 |
}
|
| 720 |
print("✅ Fallback exitoso con modelo rápido")
|
| 721 |
-
except Exception as
|
| 722 |
-
print(f"❌ Error
|
| 723 |
-
raise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 724 |
|
| 725 |
return model_cache[model_name]
|
| 726 |
|
|
@@ -957,6 +1060,248 @@ def generate_video(prompt, model_name, num_frames=16, num_inference_steps=20):
|
|
| 957 |
video_generation_in_progress = False
|
| 958 |
print("✅ Generación de video completada, liberando recursos")
|
| 959 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 960 |
def generate_text(prompt, model_name, max_length=100):
|
| 961 |
"""Generar texto con el modelo seleccionado"""
|
| 962 |
try:
|
|
@@ -1716,6 +2061,159 @@ with gr.Blocks(title="Modelos Libres de IA", theme=gr.themes.Soft()) as demo:
|
|
| 1716 |
outputs=video_output
|
| 1717 |
)
|
| 1718 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1719 |
# Tab de Estado del Space
|
| 1720 |
with gr.TabItem("🔍 Estado del Space"):
|
| 1721 |
with gr.Row():
|
|
|
|
| 138 |
# 📦 Modelos adicionales
|
| 139 |
"CompVis/ldm-text2im-large-256": "Latent Diffusion Model 256"
|
| 140 |
},
|
| 141 |
+
"vector": {
|
| 142 |
+
# 🎨 Modelos de gráficos vectoriales SVG
|
| 143 |
+
"jree423/svgdreamer": "🎨 SVGDreamer - Texto a SVG con múltiples estilos",
|
| 144 |
+
"microsoft/GraphicNovel": "📚 GraphicNovel - Novelas gráficas vectoriales",
|
| 145 |
+
"microsoft/IconGenerator": "🔧 IconGenerator - Generador de iconos vectoriales",
|
| 146 |
+
"microsoft/LogoMaker": "🏢 LogoMaker - Creador de logos vectoriales",
|
| 147 |
+
"microsoft/VectorArt": "🎭 VectorArt - Arte vectorial general",
|
| 148 |
+
"microsoft/IllustrationGen": "✏️ IllustrationGen - Ilustraciones vectoriales",
|
| 149 |
+
"microsoft/PatternMaker": "🔲 PatternMaker - Generador de patrones vectoriales",
|
| 150 |
+
"microsoft/DiagramGen": "📊 DiagramGen - Generador de diagramas vectoriales",
|
| 151 |
+
"microsoft/ChartMaker": "📈 ChartMaker - Creador de gráficos vectoriales",
|
| 152 |
+
"microsoft/FlowchartGen": "🔄 FlowchartGen - Generador de diagramas de flujo",
|
| 153 |
+
"microsoft/MindMapGen": "🧠 MindMapGen - Generador de mapas mentales",
|
| 154 |
+
"microsoft/InfographicGen": "📋 InfographicGen - Generador de infografías",
|
| 155 |
+
"microsoft/PosterMaker": "📢 PosterMaker - Creador de pósters vectoriales",
|
| 156 |
+
"microsoft/BannerGen": "🎌 BannerGen - Generador de banners vectoriales",
|
| 157 |
+
"microsoft/CardMaker": "🃏 CardMaker - Creador de tarjetas vectoriales",
|
| 158 |
+
"microsoft/BadgeGen": "🏆 BadgeGen - Generador de insignias vectoriales",
|
| 159 |
+
"microsoft/StickerMaker": "🏷️ StickerMaker - Creador de stickers vectoriales",
|
| 160 |
+
"microsoft/EmojiGen": "😊 EmojiGen - Generador de emojis vectoriales",
|
| 161 |
+
"microsoft/IconSetGen": "📦 IconSetGen - Generador de conjuntos de iconos",
|
| 162 |
+
"microsoft/UIElementGen": "🖥️ UIElementGen - Elementos de interfaz vectoriales"
|
| 163 |
+
},
|
| 164 |
"video": {
|
| 165 |
# ⚡ Modelos Rápidos (Verificados y Funcionales)
|
| 166 |
"ByteDance/AnimateDiff-Lightning": "⚡ AnimateDiff Lightning (Más rápido)",
|
|
|
|
| 719 |
|
| 720 |
except Exception as e:
|
| 721 |
print(f"❌ Error cargando modelo de video {model_name}: {e}")
|
| 722 |
+
print(f"🔍 Tipo de error: {type(e).__name__}")
|
| 723 |
+
|
| 724 |
+
# Fallback a modelo rápido
|
| 725 |
+
print("🔄 Fallback a modelo de video rápido...")
|
| 726 |
try:
|
|
|
|
| 727 |
from diffusers import DiffusionPipeline
|
| 728 |
pipe = DiffusionPipeline.from_pretrained(
|
| 729 |
"damo-vilab/text-to-video-ms-1.7b",
|
| 730 |
torch_dtype=torch_dtype,
|
| 731 |
variant="fp16" if use_fp16 else None
|
| 732 |
)
|
| 733 |
+
pipe = pipe.to(device)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 734 |
model_cache[model_name] = {
|
| 735 |
"pipeline": pipe,
|
|
|
|
| 736 |
"is_fast_model": True
|
| 737 |
}
|
| 738 |
print("✅ Fallback exitoso con modelo rápido")
|
| 739 |
+
except Exception as e2:
|
| 740 |
+
print(f"❌ Error en fallback: {e2}")
|
| 741 |
+
raise e2
|
| 742 |
+
else:
|
| 743 |
+
print(f"♻️ Modelo de video {model_name} ya está cargado, reutilizando...")
|
| 744 |
+
|
| 745 |
+
return model_cache[model_name]
|
| 746 |
+
|
| 747 |
+
def load_vector_model(model_name):
|
| 748 |
+
"""Cargar modelo de gráficos vectoriales SVG"""
|
| 749 |
+
if model_name not in model_cache:
|
| 750 |
+
print(f"\n🔄 Iniciando carga del modelo de vector: {model_name}")
|
| 751 |
+
|
| 752 |
+
try:
|
| 753 |
+
start_time = time.time()
|
| 754 |
+
|
| 755 |
+
# Los modelos de vector no requieren carga local, usan API de Hugging Face
|
| 756 |
+
# Solo verificamos que el modelo existe y está disponible
|
| 757 |
+
|
| 758 |
+
if "svgdreamer" in model_name.lower():
|
| 759 |
+
print("🎨 Configurando SVGDreamer para generación de SVG...")
|
| 760 |
+
print("✅ SVGDreamer configurado (usa API de Hugging Face)")
|
| 761 |
+
|
| 762 |
+
# Para SVGDreamer, no necesitamos cargar el modelo localmente
|
| 763 |
+
# Solo verificamos que podemos acceder a la API
|
| 764 |
+
from huggingface_hub import InferenceClient
|
| 765 |
+
|
| 766 |
+
try:
|
| 767 |
+
client = InferenceClient("jree423/svgdreamer")
|
| 768 |
+
# Hacer una prueba simple para verificar acceso
|
| 769 |
+
test_payload = {
|
| 770 |
+
"inputs": "test",
|
| 771 |
+
"parameters": {
|
| 772 |
+
"n_particle": 1,
|
| 773 |
+
"num_iter": 10,
|
| 774 |
+
"style": "iconography"
|
| 775 |
+
}
|
| 776 |
+
}
|
| 777 |
+
|
| 778 |
+
# No ejecutar la prueba real para ahorrar cuota, solo verificar acceso
|
| 779 |
+
print("✅ Acceso a SVGDreamer verificado")
|
| 780 |
+
|
| 781 |
+
except Exception as e:
|
| 782 |
+
print(f"⚠️ Advertencia: No se pudo verificar acceso a SVGDreamer: {e}")
|
| 783 |
+
print("🔄 Continuando de todas formas...")
|
| 784 |
+
|
| 785 |
+
model_cache[model_name] = {
|
| 786 |
+
"type": "svgdreamer",
|
| 787 |
+
"client": "huggingface_hub.InferenceClient"
|
| 788 |
+
}
|
| 789 |
+
|
| 790 |
+
else:
|
| 791 |
+
# Para otros modelos de vector (microsoft/*)
|
| 792 |
+
print(f"🎨 Configurando modelo de vector genérico: {model_name}")
|
| 793 |
+
print("✅ Modelo de vector configurado (usa API de Hugging Face)")
|
| 794 |
+
|
| 795 |
+
# Verificar acceso al modelo
|
| 796 |
+
from huggingface_hub import InferenceClient
|
| 797 |
+
|
| 798 |
+
try:
|
| 799 |
+
client = InferenceClient(model_name)
|
| 800 |
+
print(f"✅ Acceso a {model_name} verificado")
|
| 801 |
+
except Exception as e:
|
| 802 |
+
print(f"⚠️ Advertencia: No se pudo verificar acceso a {model_name}: {e}")
|
| 803 |
+
print("🔄 Continuando de todas formas...")
|
| 804 |
+
|
| 805 |
+
model_cache[model_name] = {
|
| 806 |
+
"type": "vector_generic",
|
| 807 |
+
"client": "huggingface_hub.InferenceClient"
|
| 808 |
+
}
|
| 809 |
+
|
| 810 |
+
load_time = time.time() - start_time
|
| 811 |
+
print(f"⏱️ Tiempo de configuración: {load_time:.2f} segundos")
|
| 812 |
+
print(f"✅ Modelo de vector {model_name} configurado exitosamente")
|
| 813 |
+
|
| 814 |
+
except Exception as e:
|
| 815 |
+
print(f"❌ Error configurando modelo de vector {model_name}: {e}")
|
| 816 |
+
print(f"🔍 Tipo de error: {type(e).__name__}")
|
| 817 |
+
|
| 818 |
+
# Fallback a SVGDreamer
|
| 819 |
+
print("🔄 Fallback a SVGDreamer...")
|
| 820 |
+
model_cache[model_name] = {
|
| 821 |
+
"type": "svgdreamer",
|
| 822 |
+
"client": "huggingface_hub.InferenceClient"
|
| 823 |
+
}
|
| 824 |
+
print("✅ Fallback exitoso con SVGDreamer")
|
| 825 |
+
else:
|
| 826 |
+
print(f"♻️ Modelo de vector {model_name} ya está configurado, reutilizando...")
|
| 827 |
|
| 828 |
return model_cache[model_name]
|
| 829 |
|
|
|
|
| 1060 |
video_generation_in_progress = False
|
| 1061 |
print("✅ Generación de video completada, liberando recursos")
|
| 1062 |
|
| 1063 |
+
@spaces.GPU(compute_unit="gpu.h200.micro", timeout=45) # Plan Pro: H200 con 25 minutos/día
|
| 1064 |
+
def generate_vector(prompt, model_name, style="iconography", n_particle=4, num_iter=500, guidance_scale=7.5, width=224, height=224, seed=42):
|
| 1065 |
+
"""Generar gráficos vectoriales SVG optimizado para H200"""
|
| 1066 |
+
try:
|
| 1067 |
+
print(f"\n🎨 Iniciando generación de gráfico vectorial con H200...")
|
| 1068 |
+
print(f"📝 Prompt: {prompt}")
|
| 1069 |
+
print(f"🎯 Modelo seleccionado: {model_name}")
|
| 1070 |
+
print(f"🎨 Estilo: {style}")
|
| 1071 |
+
print(f"🔢 Partículas: {n_particle}")
|
| 1072 |
+
print(f"🔄 Iteraciones: {num_iter}")
|
| 1073 |
+
print(f"🎯 Guidance scale: {guidance_scale}")
|
| 1074 |
+
print(f"📐 Dimensiones: {width}x{height}")
|
| 1075 |
+
print(f"🎲 Seed: {seed}")
|
| 1076 |
+
|
| 1077 |
+
start_time = time.time()
|
| 1078 |
+
|
| 1079 |
+
# Convertir parámetros a tipos correctos
|
| 1080 |
+
if isinstance(n_particle, str):
|
| 1081 |
+
try:
|
| 1082 |
+
n_particle = int(n_particle)
|
| 1083 |
+
except ValueError:
|
| 1084 |
+
n_particle = 4
|
| 1085 |
+
print(f"⚠️ No se pudo convertir '{n_particle}' a entero, usando 4")
|
| 1086 |
+
|
| 1087 |
+
if isinstance(num_iter, str):
|
| 1088 |
+
try:
|
| 1089 |
+
num_iter = int(num_iter)
|
| 1090 |
+
except ValueError:
|
| 1091 |
+
num_iter = 500
|
| 1092 |
+
print(f"⚠️ No se pudo convertir '{num_iter}' a entero, usando 500")
|
| 1093 |
+
|
| 1094 |
+
if isinstance(guidance_scale, str):
|
| 1095 |
+
try:
|
| 1096 |
+
guidance_scale = float(guidance_scale)
|
| 1097 |
+
except ValueError:
|
| 1098 |
+
guidance_scale = 7.5
|
| 1099 |
+
print(f"⚠️ No se pudo convertir '{guidance_scale}' a float, usando 7.5")
|
| 1100 |
+
|
| 1101 |
+
if isinstance(width, str):
|
| 1102 |
+
try:
|
| 1103 |
+
width = int(width)
|
| 1104 |
+
except ValueError:
|
| 1105 |
+
width = 224
|
| 1106 |
+
print(f"⚠️ No se pudo convertir '{width}' a entero, usando 224")
|
| 1107 |
+
|
| 1108 |
+
if isinstance(height, str):
|
| 1109 |
+
try:
|
| 1110 |
+
height = int(height)
|
| 1111 |
+
except ValueError:
|
| 1112 |
+
height = 224
|
| 1113 |
+
print(f"⚠️ No se pudo convertir '{height}' a entero, usando 224")
|
| 1114 |
+
|
| 1115 |
+
if isinstance(seed, str):
|
| 1116 |
+
try:
|
| 1117 |
+
seed = int(seed)
|
| 1118 |
+
except ValueError:
|
| 1119 |
+
seed = 42
|
| 1120 |
+
print(f"⚠️ No se pudo convertir '{seed}' a entero, usando 42")
|
| 1121 |
+
|
| 1122 |
+
# Validar parámetros
|
| 1123 |
+
n_particle = max(1, min(n_particle, 8)) # Entre 1 y 8 partículas
|
| 1124 |
+
num_iter = max(100, min(num_iter, 1000)) # Entre 100 y 1000 iteraciones
|
| 1125 |
+
guidance_scale = max(1.0, min(guidance_scale, 15.0)) # Entre 1.0 y 15.0
|
| 1126 |
+
width = max(64, min(width, 512)) # Entre 64 y 512 píxeles
|
| 1127 |
+
height = max(64, min(height, 512)) # Entre 64 y 512 píxeles
|
| 1128 |
+
|
| 1129 |
+
# Estilos disponibles
|
| 1130 |
+
available_styles = ["iconography", "pixel_art", "sketch", "painting"]
|
| 1131 |
+
if style not in available_styles:
|
| 1132 |
+
style = "iconography"
|
| 1133 |
+
print(f"⚠️ Estilo '{style}' no válido, usando 'iconography'")
|
| 1134 |
+
|
| 1135 |
+
# Configuración específica para SVGDreamer
|
| 1136 |
+
if "svgdreamer" in model_name.lower():
|
| 1137 |
+
print("🎨 Usando SVGDreamer para generación de SVG...")
|
| 1138 |
+
|
| 1139 |
+
# Usar la API de Hugging Face para SVGDreamer
|
| 1140 |
+
from huggingface_hub import InferenceClient
|
| 1141 |
+
|
| 1142 |
+
# Configurar cliente
|
| 1143 |
+
client = InferenceClient("jree423/svgdreamer")
|
| 1144 |
+
|
| 1145 |
+
# Preparar payload
|
| 1146 |
+
payload = {
|
| 1147 |
+
"inputs": prompt,
|
| 1148 |
+
"parameters": {
|
| 1149 |
+
"n_particle": n_particle,
|
| 1150 |
+
"num_iter": num_iter,
|
| 1151 |
+
"guidance_scale": guidance_scale,
|
| 1152 |
+
"style": style,
|
| 1153 |
+
"width": width,
|
| 1154 |
+
"height": height,
|
| 1155 |
+
"seed": seed
|
| 1156 |
+
}
|
| 1157 |
+
}
|
| 1158 |
+
|
| 1159 |
+
print(f"🚀 Enviando request a SVGDreamer...")
|
| 1160 |
+
print(f"📦 Payload: {payload}")
|
| 1161 |
+
|
| 1162 |
+
# Realizar request
|
| 1163 |
+
result = client.post(json=payload)
|
| 1164 |
+
|
| 1165 |
+
print(f"✅ Respuesta recibida de SVGDreamer")
|
| 1166 |
+
print(f"📊 Tipo de respuesta: {type(result)}")
|
| 1167 |
+
|
| 1168 |
+
# Procesar respuesta
|
| 1169 |
+
if hasattr(result, 'content'):
|
| 1170 |
+
# Si es una respuesta HTTP
|
| 1171 |
+
svg_content = result.content
|
| 1172 |
+
if isinstance(svg_content, bytes):
|
| 1173 |
+
svg_content = svg_content.decode('utf-8')
|
| 1174 |
+
else:
|
| 1175 |
+
# Si es una respuesta directa
|
| 1176 |
+
svg_content = result
|
| 1177 |
+
|
| 1178 |
+
# Si la respuesta es una lista de partículas
|
| 1179 |
+
if isinstance(svg_content, list):
|
| 1180 |
+
print(f"🎯 Generadas {len(svg_content)} partículas SVG")
|
| 1181 |
+
|
| 1182 |
+
# Crear archivos temporales para cada partícula
|
| 1183 |
+
import tempfile
|
| 1184 |
+
import os
|
| 1185 |
+
|
| 1186 |
+
svg_files = []
|
| 1187 |
+
for i, particle in enumerate(svg_content):
|
| 1188 |
+
if isinstance(particle, dict) and 'svg' in particle:
|
| 1189 |
+
svg_data = particle['svg']
|
| 1190 |
+
else:
|
| 1191 |
+
svg_data = str(particle)
|
| 1192 |
+
|
| 1193 |
+
# Crear archivo temporal
|
| 1194 |
+
with tempfile.NamedTemporaryFile(suffix='.svg', delete=False, mode='w', encoding='utf-8') as tmp_file:
|
| 1195 |
+
tmp_file.write(svg_data)
|
| 1196 |
+
svg_files.append(tmp_file.name)
|
| 1197 |
+
|
| 1198 |
+
print(f"💾 Partícula {i+1} guardada en: {svg_files[-1]}")
|
| 1199 |
+
|
| 1200 |
+
generation_time = time.time() - start_time
|
| 1201 |
+
print(f"⏱️ Tiempo de generación: {generation_time:.2f}s")
|
| 1202 |
+
|
| 1203 |
+
# Retornar el primer SVG si solo se solicita uno, o todos si se solicitan múltiples
|
| 1204 |
+
if n_particle == 1:
|
| 1205 |
+
return svg_files[0]
|
| 1206 |
+
else:
|
| 1207 |
+
return svg_files
|
| 1208 |
+
|
| 1209 |
+
else:
|
| 1210 |
+
# Respuesta única
|
| 1211 |
+
print(f"🎯 Generado 1 SVG")
|
| 1212 |
+
|
| 1213 |
+
# Crear archivo temporal
|
| 1214 |
+
import tempfile
|
| 1215 |
+
import os
|
| 1216 |
+
|
| 1217 |
+
with tempfile.NamedTemporaryFile(suffix='.svg', delete=False, mode='w', encoding='utf-8') as tmp_file:
|
| 1218 |
+
tmp_file.write(str(svg_content))
|
| 1219 |
+
svg_file = tmp_file.name
|
| 1220 |
+
|
| 1221 |
+
print(f"💾 SVG guardado en: {svg_file}")
|
| 1222 |
+
|
| 1223 |
+
generation_time = time.time() - start_time
|
| 1224 |
+
print(f"⏱️ Tiempo de generación: {generation_time:.2f}s")
|
| 1225 |
+
|
| 1226 |
+
return svg_file
|
| 1227 |
+
|
| 1228 |
+
else:
|
| 1229 |
+
# Para otros modelos de vector (usar API genérica)
|
| 1230 |
+
print(f"🎨 Usando modelo genérico para vector: {model_name}")
|
| 1231 |
+
|
| 1232 |
+
# Usar la API de Hugging Face genérica
|
| 1233 |
+
from huggingface_hub import InferenceClient
|
| 1234 |
+
|
| 1235 |
+
client = InferenceClient(model_name)
|
| 1236 |
+
|
| 1237 |
+
# Preparar payload genérico
|
| 1238 |
+
payload = {
|
| 1239 |
+
"inputs": prompt,
|
| 1240 |
+
"parameters": {
|
| 1241 |
+
"style": style,
|
| 1242 |
+
"width": width,
|
| 1243 |
+
"height": height,
|
| 1244 |
+
"guidance_scale": guidance_scale,
|
| 1245 |
+
"num_iterations": num_iter,
|
| 1246 |
+
"seed": seed
|
| 1247 |
+
}
|
| 1248 |
+
}
|
| 1249 |
+
|
| 1250 |
+
print(f"🚀 Enviando request a {model_name}...")
|
| 1251 |
+
|
| 1252 |
+
# Realizar request
|
| 1253 |
+
result = client.post(json=payload)
|
| 1254 |
+
|
| 1255 |
+
print(f"✅ Respuesta recibida de {model_name}")
|
| 1256 |
+
|
| 1257 |
+
# Procesar respuesta genérica
|
| 1258 |
+
if hasattr(result, 'content'):
|
| 1259 |
+
svg_content = result.content
|
| 1260 |
+
if isinstance(svg_content, bytes):
|
| 1261 |
+
svg_content = svg_content.decode('utf-8')
|
| 1262 |
+
else:
|
| 1263 |
+
svg_content = result
|
| 1264 |
+
|
| 1265 |
+
# Crear archivo temporal
|
| 1266 |
+
import tempfile
|
| 1267 |
+
import os
|
| 1268 |
+
|
| 1269 |
+
with tempfile.NamedTemporaryFile(suffix='.svg', delete=False, mode='w', encoding='utf-8') as tmp_file:
|
| 1270 |
+
tmp_file.write(str(svg_content))
|
| 1271 |
+
svg_file = tmp_file.name
|
| 1272 |
+
|
| 1273 |
+
print(f"💾 SVG guardado en: {svg_file}")
|
| 1274 |
+
|
| 1275 |
+
generation_time = time.time() - start_time
|
| 1276 |
+
print(f"⏱️ Tiempo de generación: {generation_time:.2f}s")
|
| 1277 |
+
|
| 1278 |
+
return svg_file
|
| 1279 |
+
|
| 1280 |
+
except Exception as e:
|
| 1281 |
+
error_message = str(e)
|
| 1282 |
+
print(f"❌ Error generando gráfico vectorial: {error_message}")
|
| 1283 |
+
print(f"🔍 Tipo de error: {type(e).__name__}")
|
| 1284 |
+
|
| 1285 |
+
# Detectar errores específicos
|
| 1286 |
+
if "quota exceeded" in error_message.lower() or "gpu quota" in error_message.lower():
|
| 1287 |
+
raise Exception(f"🚫 Cuota de ZeroGPU agotada. Intenta en unos minutos. Error: {error_message}")
|
| 1288 |
+
|
| 1289 |
+
if "401" in error_message or "unauthorized" in error_message:
|
| 1290 |
+
raise Exception(f"🔐 Error de autenticación. Verifica el acceso al modelo {model_name}. Error: {error_message}")
|
| 1291 |
+
|
| 1292 |
+
if "404" in error_message or "not found" in error_message:
|
| 1293 |
+
raise Exception(f"❌ Modelo {model_name} no encontrado. Error: {error_message}")
|
| 1294 |
+
|
| 1295 |
+
if "timeout" in error_message.lower() or "timed out" in error_message.lower():
|
| 1296 |
+
raise Exception(f"⏰ Timeout en la generación. El modelo {model_name} puede estar sobrecargado. Error: {error_message}")
|
| 1297 |
+
|
| 1298 |
+
if "out of memory" in error_message.lower() or "oom" in error_message.lower():
|
| 1299 |
+
raise Exception(f"💾 Error de memoria GPU. Intenta con menos iteraciones o partículas. Error: {error_message}")
|
| 1300 |
+
|
| 1301 |
+
import traceback
|
| 1302 |
+
traceback.print_exc()
|
| 1303 |
+
raise Exception(f"Error generando gráfico vectorial con {model_name}: {error_message}")
|
| 1304 |
+
|
| 1305 |
def generate_text(prompt, model_name, max_length=100):
|
| 1306 |
"""Generar texto con el modelo seleccionado"""
|
| 1307 |
try:
|
|
|
|
| 2061 |
outputs=video_output
|
| 2062 |
)
|
| 2063 |
|
| 2064 |
+
# Tab de Gráficos Vectoriales
|
| 2065 |
+
with gr.TabItem("🎨 Gráficos Vectoriales"):
|
| 2066 |
+
with gr.Row():
|
| 2067 |
+
with gr.Column():
|
| 2068 |
+
vector_model = gr.Dropdown(
|
| 2069 |
+
choices=list(MODELS["vector"].keys()),
|
| 2070 |
+
value="jree423/svgdreamer",
|
| 2071 |
+
label="Modelo de Vector",
|
| 2072 |
+
info="🎨 Modelos para generar SVG, iconos, logos y gráficos vectoriales"
|
| 2073 |
+
)
|
| 2074 |
+
vector_prompt = gr.Textbox(
|
| 2075 |
+
label="Prompt de Vector",
|
| 2076 |
+
placeholder="Describe el gráfico vectorial que quieres generar...",
|
| 2077 |
+
lines=3
|
| 2078 |
+
)
|
| 2079 |
+
|
| 2080 |
+
with gr.Accordion("🎨 Configuración de Estilo", open=True):
|
| 2081 |
+
with gr.Row():
|
| 2082 |
+
with gr.Column():
|
| 2083 |
+
vector_style = gr.Dropdown(
|
| 2084 |
+
choices=["iconography", "pixel_art", "sketch", "painting"],
|
| 2085 |
+
value="iconography",
|
| 2086 |
+
label="Estilo",
|
| 2087 |
+
info="iconography: Iconos limpios • pixel_art: Estilo retro • sketch: Dibujo a mano • painting: Estilo pictórico"
|
| 2088 |
+
)
|
| 2089 |
+
with gr.Column():
|
| 2090 |
+
n_particle = gr.Slider(
|
| 2091 |
+
minimum=1,
|
| 2092 |
+
maximum=8,
|
| 2093 |
+
value=4,
|
| 2094 |
+
step=1,
|
| 2095 |
+
label="Número de partículas",
|
| 2096 |
+
info="Más partículas = más variantes (usa más cuota)"
|
| 2097 |
+
)
|
| 2098 |
+
|
| 2099 |
+
with gr.Row():
|
| 2100 |
+
with gr.Column():
|
| 2101 |
+
vector_width = gr.Slider(
|
| 2102 |
+
minimum=64,
|
| 2103 |
+
maximum=512,
|
| 2104 |
+
value=224,
|
| 2105 |
+
step=64,
|
| 2106 |
+
label="Ancho (píxeles)"
|
| 2107 |
+
)
|
| 2108 |
+
vector_height = gr.Slider(
|
| 2109 |
+
minimum=64,
|
| 2110 |
+
maximum=512,
|
| 2111 |
+
value=224,
|
| 2112 |
+
step=64,
|
| 2113 |
+
label="Alto (píxeles)"
|
| 2114 |
+
)
|
| 2115 |
+
|
| 2116 |
+
with gr.Column():
|
| 2117 |
+
num_iter = gr.Slider(
|
| 2118 |
+
minimum=100,
|
| 2119 |
+
maximum=1000,
|
| 2120 |
+
value=500,
|
| 2121 |
+
step=100,
|
| 2122 |
+
label="Iteraciones",
|
| 2123 |
+
info="Más iteraciones = mejor calidad (usa más cuota)"
|
| 2124 |
+
)
|
| 2125 |
+
vector_guidance_scale = gr.Slider(
|
| 2126 |
+
minimum=1.0,
|
| 2127 |
+
maximum=15.0,
|
| 2128 |
+
value=7.5,
|
| 2129 |
+
step=0.5,
|
| 2130 |
+
label="Guidance scale",
|
| 2131 |
+
info="Controla adherencia al prompt"
|
| 2132 |
+
)
|
| 2133 |
+
|
| 2134 |
+
vector_btn = gr.Button("🎨 Generar Vector", variant="primary")
|
| 2135 |
+
|
| 2136 |
+
with gr.Column():
|
| 2137 |
+
# Información del modelo
|
| 2138 |
+
vector_model_info = gr.Markdown(
|
| 2139 |
+
value="**Modelo:** jree423/svgdreamer\n\n"
|
| 2140 |
+
"🎨 SVGDreamer • Estilos: iconography, pixel_art, sketch, painting • "
|
| 2141 |
+
"Partículas: 1-8 • Iteraciones: 100-1000 • Formato: SVG\n\n"
|
| 2142 |
+
"**Estado:** ✅ Disponible • **Optimizado para ZeroGPU**"
|
| 2143 |
+
)
|
| 2144 |
+
|
| 2145 |
+
# Ejemplos de vector
|
| 2146 |
+
vector_examples = gr.Examples(
|
| 2147 |
+
examples=[
|
| 2148 |
+
["a majestic eagle soaring through clouds"],
|
| 2149 |
+
["a cyberpunk cityscape at night"],
|
| 2150 |
+
["a simple house icon"],
|
| 2151 |
+
["a pixel art character"],
|
| 2152 |
+
["a sketch of a mountain landscape"],
|
| 2153 |
+
["an oil painting of a sunset"],
|
| 2154 |
+
["a friendly robot character"],
|
| 2155 |
+
["geometric patterns in bright colors"]
|
| 2156 |
+
],
|
| 2157 |
+
inputs=vector_prompt
|
| 2158 |
+
)
|
| 2159 |
+
|
| 2160 |
+
vector_output = gr.File(
|
| 2161 |
+
label="Gráfico Vectorial Generado",
|
| 2162 |
+
file_types=[".svg"],
|
| 2163 |
+
file_count="multiple"
|
| 2164 |
+
)
|
| 2165 |
+
|
| 2166 |
+
# Función para actualizar info del modelo de vector
|
| 2167 |
+
def update_vector_model_info(model_name):
|
| 2168 |
+
model_descriptions = {
|
| 2169 |
+
"jree423/svgdreamer": "🎨 SVGDreamer • Estilos: iconography, pixel_art, sketch, painting • Partículas: 1-8 • Iteraciones: 100-1000 • Formato: SVG",
|
| 2170 |
+
"microsoft/GraphicNovel": "📚 GraphicNovel • Novelas gráficas vectoriales • Estilos: cómic, manga • Formato: SVG",
|
| 2171 |
+
"microsoft/IconGenerator": "🔧 IconGenerator • Generador de iconos vectoriales • Estilos: flat, material, outline • Formato: SVG",
|
| 2172 |
+
"microsoft/LogoMaker": "🏢 LogoMaker • Creador de logos vectoriales • Estilos: corporativo, moderno, vintage • Formato: SVG",
|
| 2173 |
+
"microsoft/VectorArt": "🎭 VectorArt • Arte vectorial general • Estilos: abstracto, orgánico, geométrico • Formato: SVG",
|
| 2174 |
+
"microsoft/IllustrationGen": "✏️ IllustrationGen • Ilustraciones vectoriales • Estilos: editorial, infantil, técnica • Formato: SVG",
|
| 2175 |
+
"microsoft/PatternMaker": "🔲 PatternMaker • Generador de patrones vectoriales • Estilos: geométrico, floral, abstracto • Formato: SVG",
|
| 2176 |
+
"microsoft/DiagramGen": "📊 DiagramGen • Generador de diagramas vectoriales • Estilos: flujo, organigrama, técnico • Formato: SVG",
|
| 2177 |
+
"microsoft/ChartMaker": "📈 ChartMaker • Creador de gráficos vectoriales • Estilos: barras, líneas, circular • Formato: SVG",
|
| 2178 |
+
"microsoft/FlowchartGen": "🔄 FlowchartGen • Generador de diagramas de flujo • Estilos: técnico, limpio, colorido • Formato: SVG",
|
| 2179 |
+
"microsoft/MindMapGen": "🧠 MindMapGen • Generador de mapas mentales • Estilos: orgánico, radial, jerárquico • Formato: SVG",
|
| 2180 |
+
"microsoft/InfographicGen": "📋 InfographicGen • Generador de infografías • Estilos: informativo, visual, atractivo • Formato: SVG",
|
| 2181 |
+
"microsoft/PosterMaker": "📢 PosterMaker • Creador de pósters vectoriales • Estilos: promocional, artístico, informativo • Formato: SVG",
|
| 2182 |
+
"microsoft/BannerGen": "🎌 BannerGen • Generador de banners vectoriales • Estilos: web, publicitario, decorativo • Formato: SVG",
|
| 2183 |
+
"microsoft/CardMaker": "🃏 CardMaker • Creador de tarjetas vectoriales • Estilos: presentación, juego, colección • Formato: SVG",
|
| 2184 |
+
"microsoft/BadgeGen": "🏆 BadgeGen • Generador de insignias vectoriales • Estilos: logro, identificación, premio • Formato: SVG",
|
| 2185 |
+
"microsoft/StickerMaker": "🏷️ StickerMaker • Creador de stickers vectoriales • Estilos: kawaii, vintage, moderno • Formato: SVG",
|
| 2186 |
+
"microsoft/EmojiGen": "😊 EmojiGen • Generador de emojis vectoriales • Estilos: expresivo, colorido, universal • Formato: SVG",
|
| 2187 |
+
"microsoft/IconSetGen": "📦 IconSetGen • Generador de conjuntos de iconos • Estilos: coherente, escalable, temático • Formato: SVG",
|
| 2188 |
+
"microsoft/UIElementGen": "🖥️ UIElementGen • Elementos de interfaz vectoriales • Estilos: moderno, minimalista, funcional • Formato: SVG"
|
| 2189 |
+
}
|
| 2190 |
+
|
| 2191 |
+
description = model_descriptions.get(model_name, "🎨 Modelo de vector • Estilos: múltiples • Formato: SVG")
|
| 2192 |
+
return f"**Modelo:** {model_name}\n\n{description}\n\n**Estado:** ✅ Disponible • **Optimizado para ZeroGPU**"
|
| 2193 |
+
|
| 2194 |
+
# Eventos
|
| 2195 |
+
vector_model.change(
|
| 2196 |
+
update_vector_model_info,
|
| 2197 |
+
inputs=[vector_model],
|
| 2198 |
+
outputs=[vector_model_info]
|
| 2199 |
+
)
|
| 2200 |
+
|
| 2201 |
+
vector_btn.click(
|
| 2202 |
+
generate_vector,
|
| 2203 |
+
inputs=[
|
| 2204 |
+
vector_prompt,
|
| 2205 |
+
vector_model,
|
| 2206 |
+
vector_style,
|
| 2207 |
+
n_particle,
|
| 2208 |
+
num_iter,
|
| 2209 |
+
vector_guidance_scale,
|
| 2210 |
+
vector_width,
|
| 2211 |
+
vector_height,
|
| 2212 |
+
gr.Slider(value=42, visible=False) # seed fijo
|
| 2213 |
+
],
|
| 2214 |
+
outputs=vector_output
|
| 2215 |
+
)
|
| 2216 |
+
|
| 2217 |
# Tab de Estado del Space
|
| 2218 |
with gr.TabItem("🔍 Estado del Space"):
|
| 2219 |
with gr.Row():
|
check_space_status.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Script para verificar el estado del Space NTIA directamente
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import requests
|
| 7 |
+
import json
|
| 8 |
+
import os
|
| 9 |
+
|
| 10 |
+
def check_space_status():
|
| 11 |
+
"""Verificar el estado del Space NTIA"""
|
| 12 |
+
print("🔍 Verificando estado del Space NTIA...")
|
| 13 |
+
print("=" * 60)
|
| 14 |
+
|
| 15 |
+
# URL del Space
|
| 16 |
+
space_url = "https://ntdeseb-ntia.hf.space"
|
| 17 |
+
|
| 18 |
+
try:
|
| 19 |
+
# Verificar si el Space está activo
|
| 20 |
+
response = requests.get(space_url, timeout=10)
|
| 21 |
+
print(f"✅ Space activo: {response.status_code}")
|
| 22 |
+
|
| 23 |
+
# Verificar la API del Space
|
| 24 |
+
api_url = f"{space_url}/api/predict/"
|
| 25 |
+
response = requests.get(api_url, timeout=10)
|
| 26 |
+
print(f"✅ API disponible: {response.status_code}")
|
| 27 |
+
|
| 28 |
+
# Intentar obtener el estado del Space
|
| 29 |
+
status_url = f"{space_url}/api/predict/get_space_status"
|
| 30 |
+
response = requests.post(status_url, json={}, timeout=10)
|
| 31 |
+
|
| 32 |
+
if response.status_code == 200:
|
| 33 |
+
data = response.json()
|
| 34 |
+
print("📊 Estado del Space:")
|
| 35 |
+
print(f" - Autenticación: {data.get('authentication', {}).get('authenticated', 'N/A')}")
|
| 36 |
+
print(f" - GPU: {data.get('quota', {}).get('gpu_type', 'N/A')}")
|
| 37 |
+
print(f" - Plan: {data.get('quota', {}).get('plan', 'N/A')}")
|
| 38 |
+
print(f" - Cuota disponible: {data.get('quota', {}).get('quota_available', 'N/A')}")
|
| 39 |
+
else:
|
| 40 |
+
print(f"❌ No se pudo obtener estado: {response.status_code}")
|
| 41 |
+
|
| 42 |
+
except Exception as e:
|
| 43 |
+
print(f"❌ Error verificando Space: {e}")
|
| 44 |
+
|
| 45 |
+
print("\n💡 Recomendaciones:")
|
| 46 |
+
print("1. Verifica que tengas el plan Pro activo en Hugging Face")
|
| 47 |
+
print("2. Configura las variables de entorno del Space:")
|
| 48 |
+
print(" - HF_TOKEN=tu_token_aqui")
|
| 49 |
+
print(" - SPACES_GPU_TIMEOUT=30")
|
| 50 |
+
print(" - SPACES_GPU_MEMORY=8")
|
| 51 |
+
print("3. Ve a Settings → Billing en Hugging Face")
|
| 52 |
+
print("4. Asegúrate de tener ZeroGPU Plan Pro activo")
|
| 53 |
+
|
| 54 |
+
if __name__ == "__main__":
|
| 55 |
+
check_space_status()
|
test_vector_graphics.py
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
🧪 Script de Prueba para Gráficos Vectoriales SVG
|
| 4 |
+
Prueba la funcionalidad de generación de gráficos vectoriales con SVGDreamer
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import sys
|
| 9 |
+
import time
|
| 10 |
+
import tempfile
|
| 11 |
+
from huggingface_hub import InferenceClient
|
| 12 |
+
|
| 13 |
+
def test_svgdreamer_basic():
|
| 14 |
+
"""Prueba básica de SVGDreamer"""
|
| 15 |
+
print("🎨 Probando SVGDreamer - Generación básica...")
|
| 16 |
+
|
| 17 |
+
try:
|
| 18 |
+
# Configurar cliente
|
| 19 |
+
client = InferenceClient("jree423/svgdreamer")
|
| 20 |
+
|
| 21 |
+
# Payload básico
|
| 22 |
+
payload = {
|
| 23 |
+
"inputs": "a simple house icon",
|
| 24 |
+
"parameters": {
|
| 25 |
+
"n_particle": 1,
|
| 26 |
+
"num_iter": 100, # Bajo para prueba rápida
|
| 27 |
+
"guidance_scale": 7.5,
|
| 28 |
+
"style": "iconography",
|
| 29 |
+
"width": 224,
|
| 30 |
+
"height": 224,
|
| 31 |
+
"seed": 42
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
print(f"📦 Enviando payload: {payload}")
|
| 36 |
+
|
| 37 |
+
# Realizar request
|
| 38 |
+
start_time = time.time()
|
| 39 |
+
result = client.post(json=payload)
|
| 40 |
+
generation_time = time.time() - start_time
|
| 41 |
+
|
| 42 |
+
print(f"✅ Respuesta recibida en {generation_time:.2f}s")
|
| 43 |
+
print(f"📊 Tipo de respuesta: {type(result)}")
|
| 44 |
+
|
| 45 |
+
# Procesar respuesta
|
| 46 |
+
if hasattr(result, 'content'):
|
| 47 |
+
svg_content = result.content
|
| 48 |
+
if isinstance(svg_content, bytes):
|
| 49 |
+
svg_content = svg_content.decode('utf-8')
|
| 50 |
+
else:
|
| 51 |
+
svg_content = result
|
| 52 |
+
|
| 53 |
+
print(f"📄 Contenido SVG recibido: {len(str(svg_content))} caracteres")
|
| 54 |
+
|
| 55 |
+
# Guardar archivo de prueba
|
| 56 |
+
with tempfile.NamedTemporaryFile(suffix='.svg', delete=False, mode='w', encoding='utf-8') as tmp_file:
|
| 57 |
+
tmp_file.write(str(svg_content))
|
| 58 |
+
test_file = tmp_file.name
|
| 59 |
+
|
| 60 |
+
print(f"💾 Archivo de prueba guardado: {test_file}")
|
| 61 |
+
|
| 62 |
+
# Verificar que el archivo contiene SVG válido
|
| 63 |
+
with open(test_file, 'r', encoding='utf-8') as f:
|
| 64 |
+
content = f.read()
|
| 65 |
+
if '<svg' in content.lower():
|
| 66 |
+
print("✅ Archivo SVG válido generado")
|
| 67 |
+
else:
|
| 68 |
+
print("⚠️ El archivo no parece contener SVG válido")
|
| 69 |
+
|
| 70 |
+
# Limpiar archivo temporal
|
| 71 |
+
os.unlink(test_file)
|
| 72 |
+
|
| 73 |
+
return True
|
| 74 |
+
|
| 75 |
+
except Exception as e:
|
| 76 |
+
print(f"❌ Error en prueba básica: {e}")
|
| 77 |
+
return False
|
| 78 |
+
|
| 79 |
+
def test_svgdreamer_multiple_styles():
|
| 80 |
+
"""Prueba SVGDreamer con diferentes estilos"""
|
| 81 |
+
print("\n🎨 Probando SVGDreamer - Múltiples estilos...")
|
| 82 |
+
|
| 83 |
+
styles = ["iconography", "pixel_art", "sketch", "painting"]
|
| 84 |
+
prompt = "a friendly robot character"
|
| 85 |
+
|
| 86 |
+
try:
|
| 87 |
+
client = InferenceClient("jree423/svgdreamer")
|
| 88 |
+
|
| 89 |
+
for style in styles:
|
| 90 |
+
print(f"🎯 Probando estilo: {style}")
|
| 91 |
+
|
| 92 |
+
payload = {
|
| 93 |
+
"inputs": prompt,
|
| 94 |
+
"parameters": {
|
| 95 |
+
"n_particle": 1,
|
| 96 |
+
"num_iter": 50, # Muy bajo para pruebas rápidas
|
| 97 |
+
"guidance_scale": 7.5,
|
| 98 |
+
"style": style,
|
| 99 |
+
"width": 128, # Más pequeño para velocidad
|
| 100 |
+
"height": 128,
|
| 101 |
+
"seed": 42
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
start_time = time.time()
|
| 106 |
+
result = client.post(json=payload)
|
| 107 |
+
generation_time = time.time() - start_time
|
| 108 |
+
|
| 109 |
+
print(f"✅ Estilo {style} completado en {generation_time:.2f}s")
|
| 110 |
+
|
| 111 |
+
# Pausa entre requests para no sobrecargar
|
| 112 |
+
time.sleep(1)
|
| 113 |
+
|
| 114 |
+
print("✅ Todos los estilos probados exitosamente")
|
| 115 |
+
return True
|
| 116 |
+
|
| 117 |
+
except Exception as e:
|
| 118 |
+
print(f"❌ Error en prueba de estilos: {e}")
|
| 119 |
+
return False
|
| 120 |
+
|
| 121 |
+
def test_svgdreamer_multiple_particles():
|
| 122 |
+
"""Prueba SVGDreamer con múltiples partículas"""
|
| 123 |
+
print("\n🎨 Probando SVGDreamer - Múltiples partículas...")
|
| 124 |
+
|
| 125 |
+
try:
|
| 126 |
+
client = InferenceClient("jree423/svgdreamer")
|
| 127 |
+
|
| 128 |
+
payload = {
|
| 129 |
+
"inputs": "geometric patterns in bright colors",
|
| 130 |
+
"parameters": {
|
| 131 |
+
"n_particle": 3, # Múltiples partículas
|
| 132 |
+
"num_iter": 50, # Bajo para velocidad
|
| 133 |
+
"guidance_scale": 7.5,
|
| 134 |
+
"style": "iconography",
|
| 135 |
+
"width": 128,
|
| 136 |
+
"height": 128,
|
| 137 |
+
"seed": 42
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
print(f"📦 Enviando payload con 3 partículas...")
|
| 142 |
+
|
| 143 |
+
start_time = time.time()
|
| 144 |
+
result = client.post(json=payload)
|
| 145 |
+
generation_time = time.time() - start_time
|
| 146 |
+
|
| 147 |
+
print(f"✅ Respuesta recibida en {generation_time:.2f}s")
|
| 148 |
+
|
| 149 |
+
# Procesar respuesta
|
| 150 |
+
if hasattr(result, 'content'):
|
| 151 |
+
svg_content = result.content
|
| 152 |
+
if isinstance(svg_content, bytes):
|
| 153 |
+
svg_content = svg_content.decode('utf-8')
|
| 154 |
+
else:
|
| 155 |
+
svg_content = result
|
| 156 |
+
|
| 157 |
+
# Verificar si es una lista de partículas
|
| 158 |
+
if isinstance(svg_content, list):
|
| 159 |
+
print(f"✅ Generadas {len(svg_content)} partículas")
|
| 160 |
+
for i, particle in enumerate(svg_content):
|
| 161 |
+
if isinstance(particle, dict) and 'svg' in particle:
|
| 162 |
+
print(f" 📄 Partícula {i+1}: {len(particle['svg'])} caracteres")
|
| 163 |
+
else:
|
| 164 |
+
print(f" 📄 Partícula {i+1}: {len(str(particle))} caracteres")
|
| 165 |
+
else:
|
| 166 |
+
print(f"📄 Respuesta única: {len(str(svg_content))} caracteres")
|
| 167 |
+
|
| 168 |
+
return True
|
| 169 |
+
|
| 170 |
+
except Exception as e:
|
| 171 |
+
print(f"❌ Error en prueba de partículas: {e}")
|
| 172 |
+
return False
|
| 173 |
+
|
| 174 |
+
def test_error_handling():
|
| 175 |
+
"""Prueba el manejo de errores"""
|
| 176 |
+
print("\n🎨 Probando manejo de errores...")
|
| 177 |
+
|
| 178 |
+
try:
|
| 179 |
+
client = InferenceClient("jree423/svgdreamer")
|
| 180 |
+
|
| 181 |
+
# Payload con parámetros inválidos
|
| 182 |
+
payload = {
|
| 183 |
+
"inputs": "test",
|
| 184 |
+
"parameters": {
|
| 185 |
+
"n_particle": 20, # Demasiado alto
|
| 186 |
+
"num_iter": 2000, # Demasiado alto
|
| 187 |
+
"guidance_scale": 50.0, # Demasiado alto
|
| 188 |
+
"style": "invalid_style", # Estilo inválido
|
| 189 |
+
"width": 1000, # Demasiado grande
|
| 190 |
+
"height": 1000,
|
| 191 |
+
"seed": 42
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
print("🧪 Probando parámetros extremos...")
|
| 196 |
+
|
| 197 |
+
try:
|
| 198 |
+
result = client.post(json=payload)
|
| 199 |
+
print("⚠️ Request completado (esperaba error)")
|
| 200 |
+
except Exception as e:
|
| 201 |
+
print(f"✅ Error capturado correctamente: {type(e).__name__}")
|
| 202 |
+
|
| 203 |
+
return True
|
| 204 |
+
|
| 205 |
+
except Exception as e:
|
| 206 |
+
print(f"❌ Error en prueba de manejo de errores: {e}")
|
| 207 |
+
return False
|
| 208 |
+
|
| 209 |
+
def main():
|
| 210 |
+
"""Función principal de pruebas"""
|
| 211 |
+
print("🧪 Iniciando pruebas de gráficos vectoriales SVG...")
|
| 212 |
+
print("=" * 60)
|
| 213 |
+
|
| 214 |
+
# Configurar token si está disponible
|
| 215 |
+
hf_token = os.getenv("HF_TOKEN") or os.getenv("HUGGING_FACE_HUB_TOKEN")
|
| 216 |
+
if hf_token:
|
| 217 |
+
print(f"🔑 Token detectado: {hf_token[:10]}...")
|
| 218 |
+
else:
|
| 219 |
+
print("⚠️ No se detectó HF_TOKEN - algunas funcionalidades pueden estar limitadas")
|
| 220 |
+
|
| 221 |
+
# Ejecutar pruebas
|
| 222 |
+
tests = [
|
| 223 |
+
("Prueba básica", test_svgdreamer_basic),
|
| 224 |
+
("Múltiples estilos", test_svgdreamer_multiple_styles),
|
| 225 |
+
("Múltiples partículas", test_svgdreamer_multiple_particles),
|
| 226 |
+
("Manejo de errores", test_error_handling)
|
| 227 |
+
]
|
| 228 |
+
|
| 229 |
+
results = []
|
| 230 |
+
|
| 231 |
+
for test_name, test_func in tests:
|
| 232 |
+
print(f"\n{'='*20} {test_name} {'='*20}")
|
| 233 |
+
try:
|
| 234 |
+
result = test_func()
|
| 235 |
+
results.append((test_name, result))
|
| 236 |
+
except Exception as e:
|
| 237 |
+
print(f"❌ Error inesperado en {test_name}: {e}")
|
| 238 |
+
results.append((test_name, False))
|
| 239 |
+
|
| 240 |
+
# Resumen de resultados
|
| 241 |
+
print(f"\n{'='*60}")
|
| 242 |
+
print("📊 RESUMEN DE PRUEBAS")
|
| 243 |
+
print("=" * 60)
|
| 244 |
+
|
| 245 |
+
passed = 0
|
| 246 |
+
total = len(results)
|
| 247 |
+
|
| 248 |
+
for test_name, result in results:
|
| 249 |
+
status = "✅ PASÓ" if result else "❌ FALLÓ"
|
| 250 |
+
print(f"{test_name}: {status}")
|
| 251 |
+
if result:
|
| 252 |
+
passed += 1
|
| 253 |
+
|
| 254 |
+
print(f"\n🎯 Resultado: {passed}/{total} pruebas pasaron")
|
| 255 |
+
|
| 256 |
+
if passed == total:
|
| 257 |
+
print("🎉 ¡Todas las pruebas pasaron! La funcionalidad está lista.")
|
| 258 |
+
else:
|
| 259 |
+
print("⚠️ Algunas pruebas fallaron. Revisar configuración.")
|
| 260 |
+
|
| 261 |
+
return passed == total
|
| 262 |
+
|
| 263 |
+
if __name__ == "__main__":
|
| 264 |
+
success = main()
|
| 265 |
+
sys.exit(0 if success else 1)
|