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 {
|