Spaces:
Runtime error
Runtime error
Enhance run_training function in app.py to include run_out_dir in yield outputs. This update improves the tracking of the output directory throughout the training process and ensures consistent error handling by including run_out_dir in all yield statements, enhancing user feedback and clarity.
Browse files
app.py
CHANGED
|
@@ -685,15 +685,16 @@ def run_training(
|
|
| 685 |
log_buf = "[QIE] Start Training invoked.\n"
|
| 686 |
ckpts: List[str] = []
|
| 687 |
artifacts: List[str] = []
|
|
|
|
| 688 |
# Emit an initial line so UI can confirm invocation
|
| 689 |
-
yield (log_buf, ckpts, artifacts)
|
| 690 |
if not output_name.strip():
|
| 691 |
log_buf += "[ERROR] OUTPUT NAME is required.\n"
|
| 692 |
-
yield (log_buf, ckpts, artifacts)
|
| 693 |
return
|
| 694 |
if not caption.strip():
|
| 695 |
log_buf += "[ERROR] CAPTION is required.\n"
|
| 696 |
-
yield (log_buf, ckpts, artifacts)
|
| 697 |
return
|
| 698 |
|
| 699 |
# Ensure /auto holds helper files expected by the script
|
|
@@ -705,6 +706,7 @@ def run_training(
|
|
| 705 |
import time
|
| 706 |
ds_name = f"dataset_{int(time.time())}"
|
| 707 |
ds_dir = os.path.join(DATA_ROOT_RUNTIME, ds_name)
|
|
|
|
| 708 |
img_folder_name = DEFAULT_IMAGE_FOLDER
|
| 709 |
img_dir = os.path.join(ds_dir, img_folder_name)
|
| 710 |
os.makedirs(img_dir, exist_ok=True)
|
|
@@ -713,11 +715,11 @@ def run_training(
|
|
| 713 |
base_files = _extract_paths(image_uploads)
|
| 714 |
if not base_files:
|
| 715 |
log_buf += "[ERROR] No images uploaded for IMAGE_FOLDER.\n"
|
| 716 |
-
yield (log_buf, ckpts, artifacts)
|
| 717 |
return
|
| 718 |
base_filenames = _copy_uploads(base_files, img_dir)
|
| 719 |
log_buf += f"[QIE] Copied {len(base_filenames)} base images to {img_dir}\n"
|
| 720 |
-
yield (log_buf, ckpts, artifacts)
|
| 721 |
|
| 722 |
# Prepare control sets
|
| 723 |
control_upload_sets = [
|
|
@@ -733,7 +735,7 @@ def run_training(
|
|
| 733 |
# Require control_0; others optional
|
| 734 |
if not control_upload_sets[0]:
|
| 735 |
log_buf += "[ERROR] control_0 images are required.\n"
|
| 736 |
-
yield (log_buf, ckpts, artifacts)
|
| 737 |
return
|
| 738 |
|
| 739 |
control_dirs: List[Optional[str]] = []
|
|
@@ -748,7 +750,7 @@ def run_training(
|
|
| 748 |
_copy_uploads(uploads, cdir)
|
| 749 |
control_dirs.append(folder_name)
|
| 750 |
log_buf += f"[QIE] Copied {len(uploads)} control_{i} images to {cdir}\n"
|
| 751 |
-
yield (log_buf, ckpts, artifacts)
|
| 752 |
|
| 753 |
# Metadata.jsonl will be generated by create_image_caption_json.py in train_QIE.sh
|
| 754 |
|
|
@@ -813,6 +815,7 @@ def run_training(
|
|
| 813 |
log_buf += f"[QIE] Using shell: {shell}\n"
|
| 814 |
log_buf += f"[QIE] Running script: {tmp_script}\n"
|
| 815 |
out_dir = os.path.join(out_base, output_name.strip())
|
|
|
|
| 816 |
ckpts = _list_checkpoints(out_dir)
|
| 817 |
# Copy the final script to dataset dir for download
|
| 818 |
used_script_path = os.path.join(out_base, "train_QIE_used.sh")
|
|
@@ -826,7 +829,7 @@ def run_training(
|
|
| 826 |
artifacts.append(used_script_path)
|
| 827 |
except Exception:
|
| 828 |
pass
|
| 829 |
-
yield (log_buf, ckpts, artifacts)
|
| 830 |
|
| 831 |
# Run and stream output
|
| 832 |
# Ensure child Python processes are unbuffered for real-time logs
|
|
@@ -863,7 +866,7 @@ def run_training(
|
|
| 863 |
metadata_json = os.path.join(out_base, "metadata.jsonl")
|
| 864 |
if os.path.isfile(metadata_json) and metadata_json not in artifacts:
|
| 865 |
artifacts.append(metadata_json)
|
| 866 |
-
yield (log_buf, ckpts, artifacts)
|
| 867 |
finally:
|
| 868 |
code = proc.wait()
|
| 869 |
# Clear active process registration if this proc
|
|
@@ -889,7 +892,7 @@ def run_training(
|
|
| 889 |
metadata_json = os.path.join(out_base, "metadata.jsonl")
|
| 890 |
if os.path.isfile(metadata_json) and metadata_json not in artifacts:
|
| 891 |
artifacts.append(metadata_json)
|
| 892 |
-
yield (log_buf, ckpts, artifacts)
|
| 893 |
|
| 894 |
|
| 895 |
def _stop_active_training() -> None:
|
|
@@ -1069,6 +1072,7 @@ def build_ui() -> gr.Blocks:
|
|
| 1069 |
# Models root / OUTPUT_DIR_BASE / DATASET_CONFIG are auto-resolved at runtime; no user input needed.
|
| 1070 |
|
| 1071 |
run_btn = gr.Button("Start Training", variant="primary")
|
|
|
|
| 1072 |
logs = gr.Textbox(label="Logs", lines=20)
|
| 1073 |
ckpt_files = gr.Files(label="Checkpoints (live)", interactive=False)
|
| 1074 |
scripts_files = gr.Files(label="Scripts & Config (live)", interactive=False)
|
|
@@ -1105,7 +1109,7 @@ def build_ui() -> gr.Blocks:
|
|
| 1105 |
tr_w, tr_h, train_bs, cr_w, cr_h, te_bs,
|
| 1106 |
seed_input, max_epochs, save_every,
|
| 1107 |
],
|
| 1108 |
-
outputs=[logs, ckpt_files, scripts_files],
|
| 1109 |
)
|
| 1110 |
|
| 1111 |
# 回収ボタン: 直近の dataset_ ディレクトリからチェックポイントとスクリプト/設定を再取得
|
|
|
|
| 685 |
log_buf = "[QIE] Start Training invoked.\n"
|
| 686 |
ckpts: List[str] = []
|
| 687 |
artifacts: List[str] = []
|
| 688 |
+
run_out_dir = ""
|
| 689 |
# Emit an initial line so UI can confirm invocation
|
| 690 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 691 |
if not output_name.strip():
|
| 692 |
log_buf += "[ERROR] OUTPUT NAME is required.\n"
|
| 693 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 694 |
return
|
| 695 |
if not caption.strip():
|
| 696 |
log_buf += "[ERROR] CAPTION is required.\n"
|
| 697 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 698 |
return
|
| 699 |
|
| 700 |
# Ensure /auto holds helper files expected by the script
|
|
|
|
| 706 |
import time
|
| 707 |
ds_name = f"dataset_{int(time.time())}"
|
| 708 |
ds_dir = os.path.join(DATA_ROOT_RUNTIME, ds_name)
|
| 709 |
+
run_out_dir = os.path.join(ds_dir, output_name.strip())
|
| 710 |
img_folder_name = DEFAULT_IMAGE_FOLDER
|
| 711 |
img_dir = os.path.join(ds_dir, img_folder_name)
|
| 712 |
os.makedirs(img_dir, exist_ok=True)
|
|
|
|
| 715 |
base_files = _extract_paths(image_uploads)
|
| 716 |
if not base_files:
|
| 717 |
log_buf += "[ERROR] No images uploaded for IMAGE_FOLDER.\n"
|
| 718 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 719 |
return
|
| 720 |
base_filenames = _copy_uploads(base_files, img_dir)
|
| 721 |
log_buf += f"[QIE] Copied {len(base_filenames)} base images to {img_dir}\n"
|
| 722 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 723 |
|
| 724 |
# Prepare control sets
|
| 725 |
control_upload_sets = [
|
|
|
|
| 735 |
# Require control_0; others optional
|
| 736 |
if not control_upload_sets[0]:
|
| 737 |
log_buf += "[ERROR] control_0 images are required.\n"
|
| 738 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 739 |
return
|
| 740 |
|
| 741 |
control_dirs: List[Optional[str]] = []
|
|
|
|
| 750 |
_copy_uploads(uploads, cdir)
|
| 751 |
control_dirs.append(folder_name)
|
| 752 |
log_buf += f"[QIE] Copied {len(uploads)} control_{i} images to {cdir}\n"
|
| 753 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 754 |
|
| 755 |
# Metadata.jsonl will be generated by create_image_caption_json.py in train_QIE.sh
|
| 756 |
|
|
|
|
| 815 |
log_buf += f"[QIE] Using shell: {shell}\n"
|
| 816 |
log_buf += f"[QIE] Running script: {tmp_script}\n"
|
| 817 |
out_dir = os.path.join(out_base, output_name.strip())
|
| 818 |
+
run_out_dir = out_dir
|
| 819 |
ckpts = _list_checkpoints(out_dir)
|
| 820 |
# Copy the final script to dataset dir for download
|
| 821 |
used_script_path = os.path.join(out_base, "train_QIE_used.sh")
|
|
|
|
| 829 |
artifacts.append(used_script_path)
|
| 830 |
except Exception:
|
| 831 |
pass
|
| 832 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 833 |
|
| 834 |
# Run and stream output
|
| 835 |
# Ensure child Python processes are unbuffered for real-time logs
|
|
|
|
| 866 |
metadata_json = os.path.join(out_base, "metadata.jsonl")
|
| 867 |
if os.path.isfile(metadata_json) and metadata_json not in artifacts:
|
| 868 |
artifacts.append(metadata_json)
|
| 869 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 870 |
finally:
|
| 871 |
code = proc.wait()
|
| 872 |
# Clear active process registration if this proc
|
|
|
|
| 892 |
metadata_json = os.path.join(out_base, "metadata.jsonl")
|
| 893 |
if os.path.isfile(metadata_json) and metadata_json not in artifacts:
|
| 894 |
artifacts.append(metadata_json)
|
| 895 |
+
yield (log_buf, ckpts, artifacts, run_out_dir)
|
| 896 |
|
| 897 |
|
| 898 |
def _stop_active_training() -> None:
|
|
|
|
| 1072 |
# Models root / OUTPUT_DIR_BASE / DATASET_CONFIG are auto-resolved at runtime; no user input needed.
|
| 1073 |
|
| 1074 |
run_btn = gr.Button("Start Training", variant="primary")
|
| 1075 |
+
run_out_dir_box = gr.Textbox(label="今回の出力フォルダ", lines=1, interactive=False)
|
| 1076 |
logs = gr.Textbox(label="Logs", lines=20)
|
| 1077 |
ckpt_files = gr.Files(label="Checkpoints (live)", interactive=False)
|
| 1078 |
scripts_files = gr.Files(label="Scripts & Config (live)", interactive=False)
|
|
|
|
| 1109 |
tr_w, tr_h, train_bs, cr_w, cr_h, te_bs,
|
| 1110 |
seed_input, max_epochs, save_every,
|
| 1111 |
],
|
| 1112 |
+
outputs=[logs, ckpt_files, scripts_files, run_out_dir_box],
|
| 1113 |
)
|
| 1114 |
|
| 1115 |
# 回収ボタン: 直近の dataset_ ディレクトリからチェックポイントとスクリプト/設定を再取得
|