Spaces:
Sleeping
Modele hybride : CNN sur ZeroGPU, reste du Space sur CPU
Browse filesMesures reelles sur CPU basic apres le dernier commit : MLP par defaut
252s (vs 66.6s GPU, x3.8, tolerable), extraction ResNet18 sur 352 images
<10s (inference pure, negligeable), mais CNN par defaut 601s / 10min
(vs 65.3s GPU, x9.2) -- une convolution entrainee sur plusieurs epoques
ne beneficie pas du meme overhead fixe qui masquait le cout GPU des
autres etapes, contrairement a l'hypothese du commit precedent.
Sur un Space materiel ZeroGPU, seules les fonctions decorees @spaces.GPU
empruntent un vrai GPU (et consomment le quota du visiteur) ; le reste
tourne sur le CPU du conteneur sans toucher au quota. Seul train_cnn_callback
reprend son decorateur et sa duree dynamique calibree ; MLP, extraction de
features, evaluation, prediction et test restent non decores (CPU, quota
zero). Le changement de materiel du Space (CPU basic -> ZeroGPU) se fait
cote Settings HF, pas dans ce commit.
- app.py +35 -1
- requirements.txt +1 -0
|
@@ -1,6 +1,7 @@
|
|
| 1 |
import json
|
| 2 |
|
| 3 |
import gradio as gr
|
|
|
|
| 4 |
|
| 5 |
from backbone_utils import extract_all_features, get_cached_features
|
| 6 |
from classical_ml_utils import train_classical_model
|
|
@@ -77,7 +78,40 @@ def train_mlp_callback(
|
|
| 77 |
# ---------------------------------------------------------------------------
|
| 78 |
# Tab 3 — SimpleCNN
|
| 79 |
# ---------------------------------------------------------------------------
|
| 80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
def train_cnn_callback(
|
| 82 |
num_conv_blocks, base_filters, kernel_size, use_batchnorm,
|
| 83 |
dropout, fc_dim,
|
|
|
|
| 1 |
import json
|
| 2 |
|
| 3 |
import gradio as gr
|
| 4 |
+
import spaces
|
| 5 |
|
| 6 |
from backbone_utils import extract_all_features, get_cached_features
|
| 7 |
from classical_ml_utils import train_classical_model
|
|
|
|
| 78 |
# ---------------------------------------------------------------------------
|
| 79 |
# Tab 3 — SimpleCNN
|
| 80 |
# ---------------------------------------------------------------------------
|
| 81 |
+
# Seul le CNN reste sur ZeroGPU : entraîner un vrai CNN (convolutions, plusieurs
|
| 82 |
+
# époques de backward) s'est révélé ~9x plus lent sur CPU basic (601s vs 65s
|
| 83 |
+
# mesurés) alors que le MLP (~3.8x, 252s vs 66.6s) et tout ce qui n'est que de
|
| 84 |
+
# l'inférence (extraction de features, évaluation, prédiction) restent
|
| 85 |
+
# raisonnables sur CPU. Sur un Space matériel ZeroGPU, seules les fonctions
|
| 86 |
+
# décorées @spaces.GPU empruntent un vrai GPU (et consomment le quota du
|
| 87 |
+
# visiteur) ; tout le reste de ce fichier tourne sur le CPU du conteneur
|
| 88 |
+
# sans jamais toucher au quota.
|
| 89 |
+
|
| 90 |
+
def cnn_gpu_duration(
|
| 91 |
+
num_conv_blocks, base_filters, kernel_size, use_batchnorm,
|
| 92 |
+
dropout, fc_dim,
|
| 93 |
+
learning_rate, weight_decay, batch_size, epochs,
|
| 94 |
+
model_tag,
|
| 95 |
+
request: gr.Request,
|
| 96 |
+
):
|
| 97 |
+
# Calibré sur deux exécutions réelles :
|
| 98 |
+
# 3 blocs, filtres=32, noyau=3, epochs=30 -> 65.3s (2.18 s/époque)
|
| 99 |
+
# 5 blocs, filtres=128, noyau=5, epochs=50 -> 153.9s (3.08 s/époque)
|
| 100 |
+
# Le nombre de paramètres varie de ~130x entre ces deux essais mais le temps
|
| 101 |
+
# par époque seulement de 40% : sur ce jeu de données minuscule, le coût est
|
| 102 |
+
# dominé par un overhead fixe (chargement/augmentation), pas par les FLOPs
|
| 103 |
+
# du réseau — le nombre de paramètres surestimerait donc très largement.
|
| 104 |
+
# On interpole plutôt sur un score d'architecture simple. Plafond 180s :
|
| 105 |
+
# nettement sous le quota journalier d'un compte gratuit (300s).
|
| 106 |
+
score = int(num_conv_blocks) * int(base_filters) * (int(kernel_size) / 3)
|
| 107 |
+
baseline_score, worst_score = 96.0, 1066.7
|
| 108 |
+
frac = max(0.0, min(1.0, (score - baseline_score) / (worst_score - baseline_score)))
|
| 109 |
+
per_epoch = 2.18 + 0.9 * frac
|
| 110 |
+
estimated = 15 + per_epoch * int(epochs)
|
| 111 |
+
return min(180, max(45, int(estimated * 1.4)))
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
@spaces.GPU(duration=cnn_gpu_duration)
|
| 115 |
def train_cnn_callback(
|
| 116 |
num_conv_blocks, base_filters, kernel_size, use_batchnorm,
|
| 117 |
dropout, fc_dim,
|
|
@@ -2,6 +2,7 @@ torchvision
|
|
| 2 |
datasets
|
| 3 |
huggingface_hub
|
| 4 |
pillow
|
|
|
|
| 5 |
scikit-learn
|
| 6 |
pandas
|
| 7 |
matplotlib
|
|
|
|
| 2 |
datasets
|
| 3 |
huggingface_hub
|
| 4 |
pillow
|
| 5 |
+
spaces
|
| 6 |
scikit-learn
|
| 7 |
pandas
|
| 8 |
matplotlib
|