Or4cl3-2 commited on
Commit
4e8be9d
Β·
verified Β·
1 Parent(s): de09b5f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +352 -1
app.py CHANGED
@@ -540,7 +540,264 @@ api.upload_folder(
540
  - Epochs: {num_epochs}
541
  - Model saved successfully!
542
 
543
- **You can still test it locally or manually upload!**"""# ==================== GRADIO INTERFACE ====================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
544
 
545
  def create_gradio_interface():
546
  agent = ArchitechAgent()
@@ -640,6 +897,100 @@ def create_gradio_interface():
640
  outputs=test_output
641
  )
642
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
643
  # About
644
  with gr.Tab("ℹ️ About"):
645
  gr.Markdown("""
 
540
  - Epochs: {num_epochs}
541
  - Model saved successfully!
542
 
543
+ **You can still test it locally or manually upload!**"""# ==================== MODEL MANAGEMENT ====================
544
+
545
+ import zipfile
546
+ import shutil
547
+ from pathlib import Path
548
+
549
+ class ModelManager:
550
+ def __init__(self):
551
+ self.models_dir = Path("./saved_models")
552
+ self.models_dir.mkdir(exist_ok=True)
553
+
554
+ @handle_errors("model_management")
555
+ def create_model_zip(self, model_path: str, model_name: str) -> Tuple[str, str]:
556
+ """Create a downloadable zip of a trained model"""
557
+ if not os.path.exists(model_path):
558
+ raise ArchitechError(f"Model path not found: {model_path}")
559
+
560
+ zip_filename = f"{model_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip"
561
+ zip_path = os.path.join(self.models_dir, zip_filename)
562
+
563
+ # Create zip file
564
+ with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
565
+ for root, dirs, files in os.walk(model_path):
566
+ for file in files:
567
+ file_path = os.path.join(root, file)
568
+ arcname = os.path.relpath(file_path, model_path)
569
+ zipf.write(file_path, arcname)
570
+
571
+ file_size = os.path.getsize(zip_path) / (1024 * 1024) # MB
572
+
573
+ return zip_path, f"βœ… Created {zip_filename} ({file_size:.2f} MB)"
574
+
575
+ @handle_errors("model_management")
576
+ def extract_model_zip(self, zip_file, progress=gr.Progress()) -> str:
577
+ """Extract uploaded model zip"""
578
+ if zip_file is None:
579
+ raise ArchitechError("No file uploaded!")
580
+
581
+ progress(0.1, "πŸ“¦ Extracting model archive...")
582
+
583
+ # Get filename
584
+ zip_filename = Path(zip_file.name).name
585
+ model_name = zip_filename.replace('.zip', '')
586
+ extract_path = os.path.join("./uploaded_models", model_name)
587
+
588
+ os.makedirs(extract_path, exist_ok=True)
589
+
590
+ progress(0.3, "πŸ“‚ Unpacking files...")
591
+
592
+ # Extract zip
593
+ with zipfile.ZipFile(zip_file.name, 'r') as zip_ref:
594
+ zip_ref.extractall(extract_path)
595
+
596
+ progress(0.7, "πŸ” Validating model files...")
597
+
598
+ # Check for required files
599
+ files = os.listdir(extract_path)
600
+ has_model = any('pytorch_model' in f or 'model.safetensors' in f for f in files)
601
+ has_config = 'config.json' in files
602
+ has_tokenizer = any('tokenizer' in f for f in files)
603
+
604
+ validation_status = []
605
+ if has_model:
606
+ validation_status.append("βœ… Model weights found")
607
+ else:
608
+ validation_status.append("⚠️ Model weights not found")
609
+
610
+ if has_config:
611
+ validation_status.append("βœ… Config file found")
612
+ else:
613
+ validation_status.append("⚠️ Config file not found")
614
+
615
+ if has_tokenizer:
616
+ validation_status.append("βœ… Tokenizer found")
617
+ else:
618
+ validation_status.append("⚠️ Tokenizer not found")
619
+
620
+ progress(1.0, "βœ… Extraction complete!")
621
+
622
+ return f"""πŸŽ‰ **Model Uploaded Successfully!**
623
+
624
+ **Extracted to:** `{extract_path}`
625
+
626
+ **Validation:**
627
+ {chr(10).join(validation_status)}
628
+
629
+ **Files found:** {len(files)} files
630
+
631
+ **You can now:**
632
+ 1. Use this model in the Test Model tab
633
+ 2. Continue training from this checkpoint
634
+ 3. Push to HuggingFace Hub
635
+
636
+ *Model path: `{extract_path}`*"""
637
+
638
+ def list_local_models(self) -> str:
639
+ """List all locally saved models"""
640
+ trained_models = []
641
+ uploaded_models = []
642
+
643
+ # Check trained models
644
+ if os.path.exists("./"):
645
+ for item in os.listdir("./"):
646
+ if item.startswith("trained_") and os.path.isdir(item):
647
+ size = sum(
648
+ os.path.getsize(os.path.join(dirpath, filename))
649
+ for dirpath, dirnames, filenames in os.walk(item)
650
+ for filename in filenames
651
+ ) / (1024 * 1024)
652
+ trained_models.append(f"- `{item}` ({size:.2f} MB)")
653
+
654
+ # Check uploaded models
655
+ if os.path.exists("./uploaded_models"):
656
+ for item in os.listdir("./uploaded_models"):
657
+ path = os.path.join("./uploaded_models", item)
658
+ if os.path.isdir(path):
659
+ size = sum(
660
+ os.path.getsize(os.path.join(dirpath, filename))
661
+ for dirpath, dirnames, filenames in os.walk(path)
662
+ for filename in filenames
663
+ ) / (1024 * 1024)
664
+ uploaded_models.append(f"- `{item}` ({size:.2f} MB)")
665
+
666
+ result = "## πŸ“¦ Local Models\n\n"
667
+
668
+ if trained_models:
669
+ result += "### Trained Models:\n" + "\n".join(trained_models) + "\n\n"
670
+ else:
671
+ result += "### Trained Models:\n*No trained models found*\n\n"
672
+
673
+ if uploaded_models:
674
+ result += "### Uploaded Models:\n" + "\n".join(uploaded_models) + "\n\n"
675
+ else:
676
+ result += "### Uploaded Models:\n*No uploaded models found*\n\n"
677
+
678
+ return result
679
+
680
+ @handle_errors("model_management")
681
+ def delete_model(self, model_path: str) -> str:
682
+ """Delete a local model"""
683
+ if not os.path.exists(model_path):
684
+ raise ArchitechError(f"Model not found: {model_path}")
685
+
686
+ shutil.rmtree(model_path)
687
+ return f"βœ… Deleted: {model_path}"
688
+
689
+ model_manager = ModelManager()
690
+
691
+ # Add this to the Gradio interface creation function
692
+ # Insert this tab after the "Test Model" tab and before "About"
693
+
694
+ def add_model_management_tab():
695
+ """Add Model Management tab to Gradio interface"""
696
+ with gr.Tab("πŸ’Ύ Model Management"):
697
+ gr.Markdown("""
698
+ ### Manage Your Models
699
+ Upload, download, and organize your trained models
700
+ """)
701
+
702
+ with gr.Row():
703
+ # Upload Section
704
+ with gr.Column():
705
+ gr.Markdown("### πŸ“€ Upload Model")
706
+
707
+ upload_file = gr.File(
708
+ label="Upload Model ZIP",
709
+ file_types=[".zip"],
710
+ type="filepath"
711
+ )
712
+
713
+ upload_btn = gr.Button("πŸ“¦ Extract and Save", variant="primary")
714
+ upload_output = gr.Markdown()
715
+
716
+ upload_btn.click(
717
+ fn=model_manager.extract_model_zip,
718
+ inputs=[upload_file],
719
+ outputs=upload_output
720
+ )
721
+
722
+ # Download Section
723
+ with gr.Column():
724
+ gr.Markdown("### πŸ“₯ Download Model")
725
+
726
+ model_path_input = gr.Textbox(
727
+ label="Model Path",
728
+ placeholder="e.g., ./trained_my-model or ./uploaded_models/my-model",
729
+ info="Path to the model directory you want to download"
730
+ )
731
+
732
+ model_name_input = gr.Textbox(
733
+ label="Archive Name",
734
+ placeholder="e.g., my-awesome-model",
735
+ info="Name for the downloaded zip file"
736
+ )
737
+
738
+ download_btn = gr.Button("πŸ“¦ Create ZIP", variant="primary")
739
+ download_file = gr.File(label="Download")
740
+ download_output = gr.Markdown()
741
+
742
+ def create_and_return_zip(model_path, model_name):
743
+ zip_path, message = model_manager.create_model_zip(model_path, model_name)
744
+ return zip_path, message
745
+
746
+ download_btn.click(
747
+ fn=create_and_return_zip,
748
+ inputs=[model_path_input, model_name_input],
749
+ outputs=[download_file, download_output]
750
+ )
751
+
752
+ gr.Markdown("---")
753
+
754
+ # List and Delete Section
755
+ with gr.Row():
756
+ with gr.Column():
757
+ gr.Markdown("### πŸ“‹ Your Models")
758
+
759
+ refresh_btn = gr.Button("πŸ”„ Refresh List", variant="secondary")
760
+ models_list = gr.Markdown()
761
+
762
+ refresh_btn.click(
763
+ fn=model_manager.list_local_models,
764
+ inputs=[],
765
+ outputs=models_list
766
+ )
767
+
768
+ # Auto-load on tab open
769
+ models_list.value = model_manager.list_local_models()
770
+
771
+ with gr.Column():
772
+ gr.Markdown("### πŸ—‘οΈ Delete Model")
773
+
774
+ delete_path = gr.Textbox(
775
+ label="Model Path to Delete",
776
+ placeholder="e.g., ./trained_my-model"
777
+ )
778
+
779
+ delete_btn = gr.Button("πŸ—‘οΈ Delete Model", variant="stop")
780
+ delete_output = gr.Markdown()
781
+
782
+ delete_btn.click(
783
+ fn=model_manager.delete_model,
784
+ inputs=[delete_path],
785
+ outputs=delete_output
786
+ )
787
+
788
+ gr.Markdown("""
789
+ ---
790
+ ### πŸ’‘ Tips:
791
+ - **Upload:** Upload model zips from other systems or backups
792
+ - **Download:** Create portable archives of your trained models
793
+ - **Organize:** Keep your workspace tidy by managing local models
794
+ - **Backup:** Download important models before deleting them
795
+
796
+ *Note: Uploaded/downloaded models persist only during your session unless you have persistent storage configured.*
797
+ """)
798
+
799
+ # This function should be called in create_gradio_interface()
800
+ # Add it right before the "About" tab# ==================== GRADIO INTERFACE ====================
801
 
802
  def create_gradio_interface():
803
  agent = ArchitechAgent()
 
897
  outputs=test_output
898
  )
899
 
900
+ # Model Management Tab
901
+ with gr.Tab("πŸ’Ύ Model Management"):
902
+ gr.Markdown("""
903
+ ### Manage Your Models
904
+ Upload, download, and organize your trained models
905
+ """)
906
+
907
+ with gr.Row():
908
+ # Upload Section
909
+ with gr.Column():
910
+ gr.Markdown("### πŸ“€ Upload Model")
911
+
912
+ upload_file = gr.File(
913
+ label="Upload Model ZIP",
914
+ file_types=[".zip"],
915
+ type="filepath"
916
+ )
917
+
918
+ upload_btn = gr.Button("πŸ“¦ Extract and Save", variant="primary")
919
+ upload_output = gr.Markdown()
920
+
921
+ upload_btn.click(
922
+ fn=model_manager.extract_model_zip,
923
+ inputs=[upload_file],
924
+ outputs=upload_output
925
+ )
926
+
927
+ # Download Section
928
+ with gr.Column():
929
+ gr.Markdown("### πŸ“₯ Download Model")
930
+
931
+ model_path_input = gr.Textbox(
932
+ label="Model Path",
933
+ placeholder="e.g., ./trained_my-model",
934
+ info="Path to the model directory"
935
+ )
936
+
937
+ model_name_input = gr.Textbox(
938
+ label="Archive Name",
939
+ placeholder="e.g., my-awesome-model",
940
+ info="Name for the zip file"
941
+ )
942
+
943
+ download_btn = gr.Button("πŸ“¦ Create ZIP", variant="primary")
944
+ download_file = gr.File(label="Download")
945
+ download_output = gr.Markdown()
946
+
947
+ def create_and_return_zip(model_path, model_name):
948
+ zip_path, message = model_manager.create_model_zip(model_path, model_name)
949
+ return zip_path, message
950
+
951
+ download_btn.click(
952
+ fn=create_and_return_zip,
953
+ inputs=[model_path_input, model_name_input],
954
+ outputs=[download_file, download_output]
955
+ )
956
+
957
+ gr.Markdown("---")
958
+
959
+ # List Models
960
+ with gr.Row():
961
+ with gr.Column():
962
+ gr.Markdown("### πŸ“‹ Your Models")
963
+ refresh_btn = gr.Button("πŸ”„ Refresh List", variant="secondary")
964
+ models_list = gr.Markdown()
965
+
966
+ refresh_btn.click(
967
+ fn=model_manager.list_local_models,
968
+ outputs=models_list
969
+ )
970
+
971
+ with gr.Column():
972
+ gr.Markdown("### πŸ—‘οΈ Delete Model")
973
+ delete_path = gr.Textbox(
974
+ label="Model Path to Delete",
975
+ placeholder="e.g., ./trained_my-model"
976
+ )
977
+ delete_btn = gr.Button("πŸ—‘οΈ Delete", variant="stop")
978
+ delete_output = gr.Markdown()
979
+
980
+ delete_btn.click(
981
+ fn=model_manager.delete_model,
982
+ inputs=[delete_path],
983
+ outputs=delete_output
984
+ )
985
+
986
+ gr.Markdown("""
987
+ ### πŸ’‘ Tips:
988
+ - Upload model zips from backups or other systems
989
+ - Download models as portable archives
990
+ - Keep your workspace organized
991
+ - Always backup before deleting!
992
+ """)
993
+
994
  # About
995
  with gr.Tab("ℹ️ About"):
996
  gr.Markdown("""