firgiawann commited on
Commit
ce12294
·
verified ·
1 Parent(s): f91352b

Update 38 prevent runtime self-rebuild commits

Browse files
Files changed (3) hide show
  1. CHANGELOG.md +5 -0
  2. README.md +2 -0
  3. app.py +28 -15
CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
  # Changelog
2
 
 
 
 
 
 
3
  ## Update ke-37 - 2026-05-01
4
  - Perbaiki training yang berhenti pada tahap `preparing_dataset`.
5
  - Persiapan dataset, pseudo-label, training YOLO, penyimpanan `best.pt`, grafik PNG, confusion matrix, log, dan sync artefak kini berjalan dalam background worker sejak awal.
 
1
  # Changelog
2
 
3
+ ## Update ke-38 - 2026-05-02
4
+ - Cegah Space melakukan commit runtime ke repo Space yang sama secara default.
5
+ - Tambah guard `HF_ALLOW_SPACE_RUNTIME_COMMITS` untuk menghindari rebuild otomatis yang menyebabkan HTTP 503 setelah training.
6
+ - Minor update dinaikkan ke-38.
7
+
8
  ## Update ke-37 - 2026-05-01
9
  - Perbaiki training yang berhenti pada tahap `preparing_dataset`.
10
  - Persiapan dataset, pseudo-label, training YOLO, penyimpanan `best.pt`, grafik PNG, confusion matrix, log, dan sync artefak kini berjalan dalam background worker sejak awal.
README.md CHANGED
@@ -115,10 +115,12 @@ Opsional environment variable:
115
  - `HF_AUTOSYNC_INCLUDE_GLOBS` - pola file yang ingin disync (default `*.py,*.md,requirements.txt,.gitignore`)
116
  - `HF_AUTOSYNC_MAX_FILE_MB` - batas ukuran file yang di-sync (default `200` MB)
117
  - `HF_AUTOSYNC_IGNORE_GLOBS` - daftar pola file/folder yang diabaikan (dipisah koma)
 
118
 
119
  Catatan sync otomatis setelah training:
120
  - Jika `HF_MODEL_REPO` terisi, aplikasi akan upload `best.pt` ke `HF_MODEL_FILE`.
121
  - Jika tidak terisi, training tetap jalan normal dan hanya menyimpan `best.pt` lokal.
 
122
 
123
  Catatan auto-save hasil deteksi:
124
  - Setelah inferensi sukses, aplikasi menyimpan gambar anotasi ke `evaluation_outputs/` lokal.
 
115
  - `HF_AUTOSYNC_INCLUDE_GLOBS` - pola file yang ingin disync (default `*.py,*.md,requirements.txt,.gitignore`)
116
  - `HF_AUTOSYNC_MAX_FILE_MB` - batas ukuran file yang di-sync (default `200` MB)
117
  - `HF_AUTOSYNC_IGNORE_GLOBS` - daftar pola file/folder yang diabaikan (dipisah koma)
118
+ - `HF_ALLOW_SPACE_RUNTIME_COMMITS` - default `false`; aktifkan hanya jika benar-benar ingin app melakukan commit ke repo Space yang sedang berjalan
119
 
120
  Catatan sync otomatis setelah training:
121
  - Jika `HF_MODEL_REPO` terisi, aplikasi akan upload `best.pt` ke `HF_MODEL_FILE`.
122
  - Jika tidak terisi, training tetap jalan normal dan hanya menyimpan `best.pt` lokal.
123
+ - Jika `HF_MODEL_REPO` menunjuk ke Space yang sama, upload runtime dinonaktifkan secara default agar Space tidak rebuild sendiri dan memunculkan 503.
124
 
125
  Catatan auto-save hasil deteksi:
126
  - Setelah inferensi sukses, aplikasi menyimpan gambar anotasi ke `evaluation_outputs/` lokal.
app.py CHANGED
@@ -24,7 +24,7 @@ from ultralytics import YOLO
24
  CM_INIT = {"tp": 0, "fp": 0, "fn": 0, "tn": 0, "person": 0, "not_person": 0}
25
  EVAL_CLASSES = ["Person", "Not Person/Background"]
26
  APP_VERSION = os.getenv("APP_VERSION", "v0.9.0")
27
- APP_MINOR_UPDATE = os.getenv("APP_MINOR_UPDATE", "37")
28
 
29
 
30
  # Gradio/Spaces can trigger noisy asyncio cleanup traces ("Invalid file descriptor: -1")
@@ -995,14 +995,16 @@ def _prepare_training_dataset(
995
  def sync_best_to_hf(best_model_path: Path) -> str:
996
  hf_repo = os.getenv("HF_MODEL_REPO", "").strip()
997
  hf_file = os.getenv("HF_MODEL_FILE", "best.pt").strip() or "best.pt"
998
- hf_repo_type = os.getenv("HF_MODEL_REPO_TYPE", "space").strip() or "space"
999
- hf_token = os.getenv("HF_TOKEN", "").strip() or None
1000
-
1001
- if not hf_repo:
1002
- return "HF sync dilewati: set HF_MODEL_REPO untuk upload otomatis."
1003
-
1004
- try:
1005
- api = HfApi(token=hf_token)
 
 
1006
  api.upload_file(
1007
  path_or_fileobj=str(best_model_path),
1008
  path_in_repo=hf_file,
@@ -1232,10 +1234,12 @@ def sync_training_artifacts_to_hf(
1232
  repo_dir = os.getenv("HF_TRAINING_DIR", "space_training_archive").strip().strip("/")
1233
  run_name = run_name or datetime.now().strftime("training_%Y%m%d_%H%M%S")
1234
 
1235
- if not hf_repo:
1236
- return "HF training artifact sync dilewati: set HF_MODEL_REPO."
1237
-
1238
- upload_items: list[tuple[Path | None, str]] = [
 
 
1239
  (results_csv, f"{repo_dir}/{run_name}/results.csv"),
1240
  (log_file, f"{repo_dir}/{run_name}/training.log"),
1241
  (chart_file, f"{repo_dir}/{run_name}/training_curve.png"),
@@ -1264,11 +1268,20 @@ def sync_training_artifacts_to_hf(
1264
  return f"HF training artifact sync gagal: {err}"
1265
 
1266
 
1267
- def _env_true(var_name: str, default: bool = False) -> bool:
1268
  val = os.getenv(var_name)
1269
  if val is None:
1270
  return default
1271
- return val.strip().lower() in {"1", "true", "yes", "on"}
 
 
 
 
 
 
 
 
 
1272
 
1273
 
1274
  def _parse_globs(raw_value: str) -> list[str]:
 
24
  CM_INIT = {"tp": 0, "fp": 0, "fn": 0, "tn": 0, "person": 0, "not_person": 0}
25
  EVAL_CLASSES = ["Person", "Not Person/Background"]
26
  APP_VERSION = os.getenv("APP_VERSION", "v0.9.0")
27
+ APP_MINOR_UPDATE = os.getenv("APP_MINOR_UPDATE", "38")
28
 
29
 
30
  # Gradio/Spaces can trigger noisy asyncio cleanup traces ("Invalid file descriptor: -1")
 
995
  def sync_best_to_hf(best_model_path: Path) -> str:
996
  hf_repo = os.getenv("HF_MODEL_REPO", "").strip()
997
  hf_file = os.getenv("HF_MODEL_FILE", "best.pt").strip() or "best.pt"
998
+ hf_repo_type = os.getenv("HF_MODEL_REPO_TYPE", "space").strip() or "space"
999
+ hf_token = os.getenv("HF_TOKEN", "").strip() or None
1000
+
1001
+ if not hf_repo:
1002
+ return "HF sync dilewati: set HF_MODEL_REPO untuk upload otomatis."
1003
+ if _skip_runtime_commit_to_current_space(hf_repo, hf_repo_type):
1004
+ return "HF sync dilewati: commit runtime ke Space yang sama dinonaktifkan agar Space tidak rebuild sendiri."
1005
+
1006
+ try:
1007
+ api = HfApi(token=hf_token)
1008
  api.upload_file(
1009
  path_or_fileobj=str(best_model_path),
1010
  path_in_repo=hf_file,
 
1234
  repo_dir = os.getenv("HF_TRAINING_DIR", "space_training_archive").strip().strip("/")
1235
  run_name = run_name or datetime.now().strftime("training_%Y%m%d_%H%M%S")
1236
 
1237
+ if not hf_repo:
1238
+ return "HF training artifact sync dilewati: set HF_MODEL_REPO."
1239
+ if _skip_runtime_commit_to_current_space(hf_repo, hf_repo_type):
1240
+ return "HF training artifact sync dilewati: commit runtime ke Space yang sama dinonaktifkan agar Space tidak rebuild sendiri."
1241
+
1242
+ upload_items: list[tuple[Path | None, str]] = [
1243
  (results_csv, f"{repo_dir}/{run_name}/results.csv"),
1244
  (log_file, f"{repo_dir}/{run_name}/training.log"),
1245
  (chart_file, f"{repo_dir}/{run_name}/training_curve.png"),
 
1268
  return f"HF training artifact sync gagal: {err}"
1269
 
1270
 
1271
+ def _env_true(var_name: str, default: bool = False) -> bool:
1272
  val = os.getenv(var_name)
1273
  if val is None:
1274
  return default
1275
+ return val.strip().lower() in {"1", "true", "yes", "on"}
1276
+
1277
+
1278
+ def _skip_runtime_commit_to_current_space(repo_id: str, repo_type: str) -> bool:
1279
+ if repo_type != "space":
1280
+ return False
1281
+ if _env_true("HF_ALLOW_SPACE_RUNTIME_COMMITS", default=False):
1282
+ return False
1283
+ current_space = os.getenv("SPACE_ID", "").strip() or os.getenv("HF_SPACE_ID", "").strip()
1284
+ return bool(current_space and repo_id.strip() == current_space)
1285
 
1286
 
1287
  def _parse_globs(raw_value: str) -> list[str]: