Update app.py
Browse files
app.py
CHANGED
|
@@ -109,6 +109,8 @@ warmup_state: Dict[str, Any] = {
|
|
| 109 |
# NOUVEAUX CHAMPS POUR RÉCAP
|
| 110 |
"asked": [], # liste demandée au lancement
|
| 111 |
"ok_repos": [], # liste des repos téléchargés OK
|
|
|
|
|
|
|
| 112 |
"failed_repos": [], # liste des repos en échec
|
| 113 |
"started_at": 0.0, # timestamp début
|
| 114 |
"finished_at": 0.0, # timestamp fin
|
|
@@ -174,26 +176,31 @@ def _dir_size_bytes(path: str) -> int:
|
|
| 174 |
except Exception:
|
| 175 |
return 0
|
| 176 |
|
| 177 |
-
def _download_one(repo_id: str, tries: int = 3) ->
|
| 178 |
"""
|
| 179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
"""
|
| 181 |
cache_home = os.path.expanduser(os.getenv("HF_HOME", "/home/user/.cache/huggingface"))
|
| 182 |
local_dir = os.path.join(cache_home, "models", repo_id.replace("/", "__"))
|
| 183 |
|
| 184 |
-
#
|
| 185 |
try:
|
| 186 |
if _is_repo_cached(repo_id):
|
| 187 |
sz = _dir_size_bytes(local_dir)
|
| 188 |
_log_warmup(f"[CACHE] {repo_id} • {local_dir} • {sz/1e6:.1f} MB (skip)")
|
| 189 |
-
return
|
| 190 |
except Exception:
|
| 191 |
pass
|
| 192 |
|
|
|
|
| 193 |
for attempt in range(1, tries + 1):
|
| 194 |
if warmup_stop.is_set():
|
| 195 |
_log_warmup(f"[STOP] Abandon demandé avant téléchargement de {repo_id}")
|
| 196 |
-
return
|
| 197 |
|
| 198 |
t0 = time.time()
|
| 199 |
_log_warmup(f"[START] {repo_id} • tentative {attempt}/{tries} • {local_dir}")
|
|
@@ -207,12 +214,13 @@ def _download_one(repo_id: str, tries: int = 3) -> bool:
|
|
| 207 |
dt = time.time() - t0
|
| 208 |
sz = _dir_size_bytes(local_dir)
|
| 209 |
_log_warmup(f"[DONE] {repo_id} • {dt:.1f}s • {sz/1e6:.1f} MB")
|
| 210 |
-
return
|
| 211 |
except Exception as e:
|
| 212 |
dt = time.time() - t0
|
| 213 |
_log_warmup(f"[FAIL] {repo_id} • {dt:.1f}s • {type(e).__name__}: {e}")
|
| 214 |
time.sleep(min(10, 2 * attempt))
|
| 215 |
-
return
|
|
|
|
| 216 |
|
| 217 |
def _warmup_thread(models: List[str]):
|
| 218 |
ok_count = 0
|
|
@@ -229,17 +237,23 @@ def _warmup_thread(models: List[str]):
|
|
| 229 |
warmup_state["current"] = repo
|
| 230 |
warmup_state["percent"] = int((i / max(1, len(models))) * 100)
|
| 231 |
|
| 232 |
-
|
| 233 |
with warmup_lock:
|
| 234 |
-
if ok:
|
| 235 |
ok_count += 1
|
| 236 |
warmup_state["ok_count"] = ok_count
|
| 237 |
-
warmup_state
|
| 238 |
-
|
|
|
|
|
|
|
| 239 |
warmup_state["failed_repos"].append(repo)
|
|
|
|
|
|
|
|
|
|
| 240 |
|
| 241 |
warmup_state["percent"] = int(((i + 1) / max(1, len(models))) * 100)
|
| 242 |
|
|
|
|
| 243 |
if warmup_stop.is_set():
|
| 244 |
_log_warmup("[STOP] Fin anticipée — demande reçue pendant le run")
|
| 245 |
break
|
|
@@ -568,6 +582,8 @@ async def warmup_start(payload: Optional[Dict[str, Any]] = Body(None)):
|
|
| 568 |
"job_id": job_id,
|
| 569 |
"asked": models[:],
|
| 570 |
"ok_repos": [],
|
|
|
|
|
|
|
| 571 |
"failed_repos": [],
|
| 572 |
"ok_count": 0,
|
| 573 |
"logs": [],
|
|
@@ -1041,55 +1057,31 @@ const warmupCloseBtn = document.getElementById('warmupCloseBtn');
|
|
| 1041 |
function buildFinalSummary(s){
|
| 1042 |
const asked = Array.isArray(s.asked) ? s.asked : [];
|
| 1043 |
const okL = Array.isArray(s.ok_repos) ? s.ok_repos : [];
|
| 1044 |
-
|
| 1045 |
-
const
|
| 1046 |
-
const
|
| 1047 |
-
|
| 1048 |
-
const ignored = asked.filter(m => cached.includes(m) && !okL.includes(m) && !failL.includes(m));
|
| 1049 |
-
const out = [];
|
| 1050 |
-
out.push("RÉCAP FINAL");
|
| 1051 |
-
out.push(`Demandés : ${asked.length}`);
|
| 1052 |
-
if (asked.length) out.push(asked.map(m => ' • ' + m).join('\n'));
|
| 1053 |
-
|
| 1054 |
-
out.push("");
|
| 1055 |
-
out.push(`⬛ Ignorés (déjà en cache) : ${ignored.length}`);
|
| 1056 |
-
if (ignored.length) out.push(ignored.map(m => ' • ' + m).join('\n'));
|
| 1057 |
-
|
| 1058 |
-
out.push("");
|
| 1059 |
-
out.push(`✅ Téléchargés : ${okL.length}`);
|
| 1060 |
-
if (okL.length) out.push(okL.map(m => ' • ' + m).join('\n'));
|
| 1061 |
-
|
| 1062 |
-
out.push("");
|
| 1063 |
-
out.push(`❌ ��checs : ${failL.length}`);
|
| 1064 |
-
if (failL.length) out.push(failL.map(m => ' • ' + m).join('\n'));
|
| 1065 |
-
|
| 1066 |
-
out.push("");
|
| 1067 |
-
out.push(`📦 En cache maintenant : ${cached.length}`);
|
| 1068 |
-
if (cached.length) out.push(cached.map(m => ' • ' + m).join('\n'));
|
| 1069 |
-
|
| 1070 |
-
return out.join('\n');
|
| 1071 |
-
// >>> FIN AJOUT <<<
|
| 1072 |
|
| 1073 |
const lines = [];
|
| 1074 |
-
lines.push(
|
| 1075 |
-
lines.push(
|
|
|
|
|
|
|
| 1076 |
if (asked.length) lines.push(asked.map(m=>' • '+m).join('\n'));
|
| 1077 |
|
| 1078 |
lines.push("");
|
| 1079 |
-
lines.push(
|
| 1080 |
-
if (
|
| 1081 |
|
| 1082 |
lines.push("");
|
| 1083 |
-
lines.push(
|
| 1084 |
-
if (
|
| 1085 |
|
| 1086 |
lines.push("");
|
| 1087 |
-
lines.push(
|
| 1088 |
-
if (
|
| 1089 |
|
| 1090 |
return lines.join('\n');
|
| 1091 |
-
}
|
| 1092 |
-
|
| 1093 |
|
| 1094 |
// >>> C2_BEGIN warmup_preface
|
| 1095 |
let warmupPreface = '';
|
|
@@ -1147,6 +1139,10 @@ async function refreshWarmupUI(){
|
|
| 1147 |
const ok = Number.isFinite(s.ok_count) ? s.ok_count : 0;
|
| 1148 |
const fail = Array.isArray(s.failed_repos) ? s.failed_repos.length : Math.max(0, tot - ok);
|
| 1149 |
warmupStatusEl.textContent = `✅ Terminé — ${ok}/${tot} téléchargés, ${fail} échec(s) [inst:${instanceId}]`;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1150 |
if (warmupPopupStatus) warmupPopupStatus.textContent = 'Terminé';
|
| 1151 |
if (warmupLogs) warmupLogs.textContent = buildFinalSummary(s);
|
| 1152 |
} else {
|
|
|
|
| 109 |
# NOUVEAUX CHAMPS POUR RÉCAP
|
| 110 |
"asked": [], # liste demandée au lancement
|
| 111 |
"ok_repos": [], # liste des repos téléchargés OK
|
| 112 |
+
"cache_repos": [], # liste des repos ignorés car déjà en cache
|
| 113 |
+
"downloaded_repos": [],# liste des repos réellement téléchargés pendant ce run
|
| 114 |
"failed_repos": [], # liste des repos en échec
|
| 115 |
"started_at": 0.0, # timestamp début
|
| 116 |
"finished_at": 0.0, # timestamp fin
|
|
|
|
| 176 |
except Exception:
|
| 177 |
return 0
|
| 178 |
|
| 179 |
+
def _download_one(repo_id: str, tries: int = 3) -> str:
|
| 180 |
"""
|
| 181 |
+
Renvoie un statut précis :
|
| 182 |
+
- "cache" : déjà présent localement, rien à faire
|
| 183 |
+
- "ok" : téléchargé avec succès
|
| 184 |
+
- "fail" : échec après toutes les tentatives
|
| 185 |
+
- "stopped" : arrêt demandé pendant le run
|
| 186 |
"""
|
| 187 |
cache_home = os.path.expanduser(os.getenv("HF_HOME", "/home/user/.cache/huggingface"))
|
| 188 |
local_dir = os.path.join(cache_home, "models", repo_id.replace("/", "__"))
|
| 189 |
|
| 190 |
+
# 1) Déjà en cache ?
|
| 191 |
try:
|
| 192 |
if _is_repo_cached(repo_id):
|
| 193 |
sz = _dir_size_bytes(local_dir)
|
| 194 |
_log_warmup(f"[CACHE] {repo_id} • {local_dir} • {sz/1e6:.1f} MB (skip)")
|
| 195 |
+
return "cache"
|
| 196 |
except Exception:
|
| 197 |
pass
|
| 198 |
|
| 199 |
+
# 2) Tentatives de téléchargement
|
| 200 |
for attempt in range(1, tries + 1):
|
| 201 |
if warmup_stop.is_set():
|
| 202 |
_log_warmup(f"[STOP] Abandon demandé avant téléchargement de {repo_id}")
|
| 203 |
+
return "stopped"
|
| 204 |
|
| 205 |
t0 = time.time()
|
| 206 |
_log_warmup(f"[START] {repo_id} • tentative {attempt}/{tries} • {local_dir}")
|
|
|
|
| 214 |
dt = time.time() - t0
|
| 215 |
sz = _dir_size_bytes(local_dir)
|
| 216 |
_log_warmup(f"[DONE] {repo_id} • {dt:.1f}s • {sz/1e6:.1f} MB")
|
| 217 |
+
return "ok"
|
| 218 |
except Exception as e:
|
| 219 |
dt = time.time() - t0
|
| 220 |
_log_warmup(f"[FAIL] {repo_id} • {dt:.1f}s • {type(e).__name__}: {e}")
|
| 221 |
time.sleep(min(10, 2 * attempt))
|
| 222 |
+
return "fail"
|
| 223 |
+
|
| 224 |
|
| 225 |
def _warmup_thread(models: List[str]):
|
| 226 |
ok_count = 0
|
|
|
|
| 237 |
warmup_state["current"] = repo
|
| 238 |
warmup_state["percent"] = int((i / max(1, len(models))) * 100)
|
| 239 |
|
| 240 |
+
res = _download_one(repo)
|
| 241 |
with warmup_lock:
|
| 242 |
+
if res == "ok":
|
| 243 |
ok_count += 1
|
| 244 |
warmup_state["ok_count"] = ok_count
|
| 245 |
+
warmup_state.setdefault("downloaded_repos", []).append(repo)
|
| 246 |
+
elif res == "cache":
|
| 247 |
+
warmup_state.setdefault("cache_repos", []).append(repo)
|
| 248 |
+
elif res == "fail":
|
| 249 |
warmup_state["failed_repos"].append(repo)
|
| 250 |
+
elif res == "stopped":
|
| 251 |
+
_log_warmup("[STOP] Fin anticipée — demande reçue pendant le run")
|
| 252 |
+
break
|
| 253 |
|
| 254 |
warmup_state["percent"] = int(((i + 1) / max(1, len(models))) * 100)
|
| 255 |
|
| 256 |
+
|
| 257 |
if warmup_stop.is_set():
|
| 258 |
_log_warmup("[STOP] Fin anticipée — demande reçue pendant le run")
|
| 259 |
break
|
|
|
|
| 582 |
"job_id": job_id,
|
| 583 |
"asked": models[:],
|
| 584 |
"ok_repos": [],
|
| 585 |
+
"cache_repos": [],
|
| 586 |
+
"downloaded_repos": [],
|
| 587 |
"failed_repos": [],
|
| 588 |
"ok_count": 0,
|
| 589 |
"logs": [],
|
|
|
|
| 1057 |
function buildFinalSummary(s){
|
| 1058 |
const asked = Array.isArray(s.asked) ? s.asked : [];
|
| 1059 |
const okL = Array.isArray(s.ok_repos) ? s.ok_repos : [];
|
| 1060 |
+
const failL = Array.isArray(s.failed_repos) ? s.failed_repos : [];
|
| 1061 |
+
const cacheL = Array.isArray(s.cache_repos) ? s.cache_repos : [];
|
| 1062 |
+
const dlL = Array.isArray(s.downloaded_repos) ? s.downloaded_repos : [];
|
| 1063 |
+
const tot = asked.length;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1064 |
|
| 1065 |
const lines = [];
|
| 1066 |
+
lines.push(`Terminé — demandés: ${tot} • ⬛ cache: ${cacheL.length} • ✅ téléchargés: ${dlL.length} • ❌ échecs: ${failL.length}`);
|
| 1067 |
+
lines.push("");
|
| 1068 |
+
|
| 1069 |
+
lines.push("Demandés : " + asked.length);
|
| 1070 |
if (asked.length) lines.push(asked.map(m=>' • '+m).join('\n'));
|
| 1071 |
|
| 1072 |
lines.push("");
|
| 1073 |
+
lines.push(`⬛ Ignorés (déjà en cache) : ${cacheL.length}`);
|
| 1074 |
+
if (cacheL.length) lines.push(cacheL.map(m=>' • '+m).join('\n'));
|
| 1075 |
|
| 1076 |
lines.push("");
|
| 1077 |
+
lines.push(`✅ Téléchargés : ${dlL.length}`);
|
| 1078 |
+
if (dlL.length) lines.push(dlL.map(m=>' • '+m).join('\n'));
|
| 1079 |
|
| 1080 |
lines.push("");
|
| 1081 |
+
lines.push(`❌ Échecs : ${failL.length}`);
|
| 1082 |
+
if (failL.length) lines.push(failL.map(m=>' • '+m).join('\n'));
|
| 1083 |
|
| 1084 |
return lines.join('\n');
|
|
|
|
|
|
|
| 1085 |
|
| 1086 |
// >>> C2_BEGIN warmup_preface
|
| 1087 |
let warmupPreface = '';
|
|
|
|
| 1139 |
const ok = Number.isFinite(s.ok_count) ? s.ok_count : 0;
|
| 1140 |
const fail = Array.isArray(s.failed_repos) ? s.failed_repos.length : Math.max(0, tot - ok);
|
| 1141 |
warmupStatusEl.textContent = `✅ Terminé — ${ok}/${tot} téléchargés, ${fail} échec(s) [inst:${instanceId}]`;
|
| 1142 |
+
const cacheN = Array.isArray(s.cache_repos) ? s.cache_repos.length : 0;
|
| 1143 |
+
const dlN = Array.isArray(s.downloaded_repos) ? s.downloaded_repos.length : 0;
|
| 1144 |
+
const failN = Array.isArray(s.failed_repos) ? s.failed_repos.length : 0;
|
| 1145 |
+
warmupStatusEl.textContent = `✅ Terminé — ⬛ ${cacheN} • ✅ ${dlN} • ❌ ${failN} / ${tot} [inst:${instanceId}]`;
|
| 1146 |
if (warmupPopupStatus) warmupPopupStatus.textContent = 'Terminé';
|
| 1147 |
if (warmupLogs) warmupLogs.textContent = buildFinalSummary(s);
|
| 1148 |
} else {
|