Upload main.ipynb with huggingface_hub
Browse files- main.ipynb +199 -0
main.ipynb
CHANGED
|
@@ -1771,6 +1771,205 @@
|
|
| 1771 |
" imgsz=416\n",
|
| 1772 |
")"
|
| 1773 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1774 |
}
|
| 1775 |
],
|
| 1776 |
"metadata": {
|
|
|
|
| 1771 |
" imgsz=416\n",
|
| 1772 |
")"
|
| 1773 |
]
|
| 1774 |
+
},
|
| 1775 |
+
{
|
| 1776 |
+
"cell_type": "code",
|
| 1777 |
+
"execution_count": null,
|
| 1778 |
+
"id": "312e2447",
|
| 1779 |
+
"metadata": {},
|
| 1780 |
+
"outputs": [],
|
| 1781 |
+
"source": [
|
| 1782 |
+
"import time\n",
|
| 1783 |
+
"import os\n",
|
| 1784 |
+
"import subprocess\n",
|
| 1785 |
+
"from ultralytics.utils import callbacks\n",
|
| 1786 |
+
"\n",
|
| 1787 |
+
"README_FILE_PATH = \"README.md\"\n",
|
| 1788 |
+
"REPO_ID = \"Qbsoon/image-corner-rotation\"\n",
|
| 1789 |
+
"UPDATE_FREQUENCY = 'epoch'\n",
|
| 1790 |
+
"BATCH_UPDATE_INTERVAL = 50\n",
|
| 1791 |
+
"TIME_UPDATE_INTERVAL_SECONDS = 300\n",
|
| 1792 |
+
"LAST_UPDATE_TIME_FOR_README = time.time()\n",
|
| 1793 |
+
"\n",
|
| 1794 |
+
"status_data = {\n",
|
| 1795 |
+
" \"attempt\": 1,\n",
|
| 1796 |
+
" \"modelName\": \"YourModelName\",\n",
|
| 1797 |
+
" \"startDate\": \"N/A\",\n",
|
| 1798 |
+
" \"lastUpdate\": \"N/A\",\n",
|
| 1799 |
+
" \"datasetSize\": \"251440 Images\",\n",
|
| 1800 |
+
" \"equipment\": \"1x RTX 4070Ti Super (16GB VRAM)\",\n",
|
| 1801 |
+
" \"estimatedTotalTime\": \"~N/A\",\n",
|
| 1802 |
+
" \"currentEpoch\": 0,\n",
|
| 1803 |
+
" \"totalEpochs\": 0,\n",
|
| 1804 |
+
" \"overallProgress\": 0.0,\n",
|
| 1805 |
+
" \"statusText\": \"Initializing...\",\n",
|
| 1806 |
+
" \"training_active\": False\n",
|
| 1807 |
+
"}\n",
|
| 1808 |
+
"\n",
|
| 1809 |
+
"def generate_widget_html(current_status):\n",
|
| 1810 |
+
" spinner_animation_style = \"animation: spin 1s linear infinite;\" if current_status[\"training_active\"] else \"display: none;\"\n",
|
| 1811 |
+
" display_progress = min(current_status[\"overallProgress\"], 100.0)\n",
|
| 1812 |
+
"\n",
|
| 1813 |
+
" start_date_str = current_status[\"startDate\"]\n",
|
| 1814 |
+
" last_update_str = current_status[\"lastUpdate\"]\n",
|
| 1815 |
+
" if isinstance(start_date_str, float): start_date_str = time.strftime(\"%b %d, %Y\", time.localtime(start_date_str))\n",
|
| 1816 |
+
" if isinstance(last_update_str, float): last_update_str = time.strftime(\"%b %d, %Y %H:%M:%S\", time.localtime(last_update_str))\n",
|
| 1817 |
+
"\n",
|
| 1818 |
+
"\n",
|
| 1819 |
+
" html = f\"\"\"\n",
|
| 1820 |
+
"<div class=\"card\">\n",
|
| 1821 |
+
" <div class=\"header\">\n",
|
| 1822 |
+
" <div class=\"spinner\" style=\"{spinner_animation_style}\"></div>\n",
|
| 1823 |
+
" <h2>{current_status[\"modelName\"]} training</h2>\n",
|
| 1824 |
+
" </div>\n",
|
| 1825 |
+
" <div class=\"info-blocks\">\n",
|
| 1826 |
+
" <div class=\"info-block\"><strong>START DATE:</strong> {start_date_str}</div>\n",
|
| 1827 |
+
" <div class=\"info-block\"><strong>LAST UPDATE:</strong> {last_update_str}</div>\n",
|
| 1828 |
+
" <div class=\"info-block\"><strong>DATASET SIZE:</strong> {current_status[\"datasetSize\"]}</div>\n",
|
| 1829 |
+
" <div class=\"info-block\"><strong>EQUIPMENT:</strong> {current_status[\"equipment\"]}</div>\n",
|
| 1830 |
+
" <div class=\"info-block\"><strong>TRAINING TIME:</strong> {current_status[\"estimatedTotalTime\"]}</div>\n",
|
| 1831 |
+
" </div>\n",
|
| 1832 |
+
" <div class=\"progress-container\">\n",
|
| 1833 |
+
" <div class=\"progress-bar\" style=\"width: {display_progress}%;\"></div>\n",
|
| 1834 |
+
" </div>\n",
|
| 1835 |
+
" <div class=\"status-text\">{current_status[\"statusText\"]}</div>\n",
|
| 1836 |
+
"</div>\n",
|
| 1837 |
+
"\"\"\"\n",
|
| 1838 |
+
" return html\n",
|
| 1839 |
+
"\n",
|
| 1840 |
+
"def update_readme_and_upload_with_hf_cli(widget_html_content):\n",
|
| 1841 |
+
" global REPO_ID\n",
|
| 1842 |
+
" if REPO_ID == \"YOUR_USERNAME/YOUR_MODEL_NAME\":\n",
|
| 1843 |
+
" print(\"ERROR: Please update REPO_ID in the script with your Hugging Face repository ID.\")\n",
|
| 1844 |
+
" return\n",
|
| 1845 |
+
"\n",
|
| 1846 |
+
" try:\n",
|
| 1847 |
+
" with open(README_FILE_PATH, \"r\", encoding=\"utf-8\") as f:\n",
|
| 1848 |
+
" readme_content = f.read()\n",
|
| 1849 |
+
"\n",
|
| 1850 |
+
" start_placeholder = \"<!-- WIDGET_START -->\"\n",
|
| 1851 |
+
" end_placeholder = \"<!-- WIDGET_END -->\"\n",
|
| 1852 |
+
" \n",
|
| 1853 |
+
" start_index = readme_content.find(start_placeholder)\n",
|
| 1854 |
+
" end_index = readme_content.find(end_placeholder)\n",
|
| 1855 |
+
"\n",
|
| 1856 |
+
" if start_index != -1 and end_index != -1:\n",
|
| 1857 |
+
" pre_widget = readme_content[:start_index + len(start_placeholder)]\n",
|
| 1858 |
+
" post_widget = readme_content[end_index:]\n",
|
| 1859 |
+
" new_readme_content = pre_widget + \"\\n\" + widget_html_content + \"\\n\" + post_widget\n",
|
| 1860 |
+
" else:\n",
|
| 1861 |
+
" print(f\"Warning: Widget placeholders not found in {README_FILE_PATH}. Creating new content with widget.\")\n",
|
| 1862 |
+
" # Updated CSS here\n",
|
| 1863 |
+
" html_template_start = \"\"\"\n",
|
| 1864 |
+
"<html>\n",
|
| 1865 |
+
"<head>\n",
|
| 1866 |
+
" <style>\n",
|
| 1867 |
+
" /* Paste your full CSS styles here */\n",
|
| 1868 |
+
" body {{ font-family: Arial, sans-serif; }} /* Note: Double curly braces for f-string like formatting if this were an f-string, but it's a direct string here so single is fine. Keeping double for safety if it's ever converted. */\n",
|
| 1869 |
+
" .card {{ background: #FF8C00; border-radius: 16px; padding: 24px; width: 100%; max-width: 700px; box-shadow: 0 6px 12px rgba(0,0,0,0.2); color: #fff; box-sizing: border-box; margin: 20px auto; }}\n",
|
| 1870 |
+
" .card .header {{ display: flex; align-items: center; margin-bottom: 16px; }}\n",
|
| 1871 |
+
" .card .spinner {{ width: 24px; height: 24px; margin-right: 12px; border: 4px solid rgba(255,255,255,0.5); border-top-color: #fff; border-radius: 50%; animation: spin 1s linear infinite; }}\n",
|
| 1872 |
+
" .card .header h2 {{ font-size: 1.2rem; margin: 0; }}\n",
|
| 1873 |
+
" .card .info-blocks {{ display: flex; flex-wrap: nowrap; border: 1px solid rgba(255,255,255,0.5); border-radius: 12px; overflow: hidden; margin-bottom: 16px; }}\n",
|
| 1874 |
+
" .card .info-block {{ flex-grow: 1; flex-shrink: 1; flex-basis: 0; min-width: 0; padding: 8px 12px; font-size: 0.85rem; text-align: center; box-sizing: border-box; }}\n",
|
| 1875 |
+
" .card .info-block + .info-block {{ border-left: 1px solid rgba(255,255,255,0.5); }}\n",
|
| 1876 |
+
" .card .info-block strong {{ display: block; margin-bottom: 4px; font-weight: 600; text-transform: uppercase; }}\n",
|
| 1877 |
+
" .card .progress-container {{ background: rgba(255,255,255,0.3); border-radius: 12px; overflow: hidden; height: 14px; margin-bottom: 8px; }}\n",
|
| 1878 |
+
" .card .progress-bar {{ width: 0%; height: 100%; background: #fff; transition: width 0.5s ease-out; }}\n",
|
| 1879 |
+
" .card .status-text {{ font-size: 0.9rem; text-align: center; }}\n",
|
| 1880 |
+
" @keyframes spin {{ to {{ transform: rotate(360deg); }} }}\n",
|
| 1881 |
+
" </style>\n",
|
| 1882 |
+
"</head>\n",
|
| 1883 |
+
"<body>\n",
|
| 1884 |
+
"{widget_content}\n",
|
| 1885 |
+
"</body>\n",
|
| 1886 |
+
"</html>\n",
|
| 1887 |
+
"\"\"\"\n",
|
| 1888 |
+
" new_readme_content = html_template_start.format(widget_content=start_placeholder + \"\\n\" + widget_html_content + \"\\n\" + end_placeholder)\n",
|
| 1889 |
+
"\n",
|
| 1890 |
+
"\n",
|
| 1891 |
+
" with open(README_FILE_PATH, \"w\", encoding=\"utf-8\") as f:\n",
|
| 1892 |
+
" f.write(new_readme_content)\n",
|
| 1893 |
+
"\n",
|
| 1894 |
+
" commit_message = f\"Update training progress: {status_data.get('statusText', 'Progress update')}\"\n",
|
| 1895 |
+
" subprocess.run([\n",
|
| 1896 |
+
" \"huggingface-cli\", \"upload\",\n",
|
| 1897 |
+
" REPO_ID,\n",
|
| 1898 |
+
" README_FILE_PATH,\n",
|
| 1899 |
+
" \"README.md\",\n",
|
| 1900 |
+
" \"--commit-message\", commit_message\n",
|
| 1901 |
+
" ], check=True, capture_output=True, text=True)\n",
|
| 1902 |
+
" print(f\"README.md uploaded to {REPO_ID} at {time.strftime('%Y-%m-%d %H:%M:%S')}\")\n",
|
| 1903 |
+
"\n",
|
| 1904 |
+
" except FileNotFoundError:\n",
|
| 1905 |
+
" print(f\"Error: {README_FILE_PATH} not found. Ensure it exists in the current directory: {os.getcwd()}\")\n",
|
| 1906 |
+
" except subprocess.CalledProcessError as e:\n",
|
| 1907 |
+
" print(f\"Error during huggingface-cli upload: {e}\")\n",
|
| 1908 |
+
" print(f\"stdout: {e.stdout}\")\n",
|
| 1909 |
+
" print(f\"stderr: {e.stderr}\")\n",
|
| 1910 |
+
" except Exception as e:\n",
|
| 1911 |
+
" print(f\"An unexpected error occurred: {e}\")\n",
|
| 1912 |
+
"\n",
|
| 1913 |
+
"def on_train_start_callback(trainer):\n",
|
| 1914 |
+
" global LAST_UPDATE_TIME_FOR_README, status_data\n",
|
| 1915 |
+
" status_data[\"training_active\"] = True\n",
|
| 1916 |
+
" status_data[\"totalEpochs\"] = trainer.epochs\n",
|
| 1917 |
+
" status_data[\"startDate\"] = time.time()\n",
|
| 1918 |
+
" status_data[\"lastUpdate\"] = time.time()\n",
|
| 1919 |
+
" status_data[\"statusText\"] = \"Training started...\"\n",
|
| 1920 |
+
" status_data[\"overallProgress\"] = 0.0\n",
|
| 1921 |
+
" status_data[\"currentEpoch\"] = 0\n",
|
| 1922 |
+
" widget_html = generate_widget_html(status_data)\n",
|
| 1923 |
+
" update_readme_and_upload_with_hf_cli(widget_html)\n",
|
| 1924 |
+
" LAST_UPDATE_TIME_FOR_README = time.time()\n",
|
| 1925 |
+
"\n",
|
| 1926 |
+
"def on_epoch_end_callback(trainer):\n",
|
| 1927 |
+
" global LAST_UPDATE_TIME_FOR_README, status_data\n",
|
| 1928 |
+
" status_data[\"currentEpoch\"] = trainer.epoch + 1\n",
|
| 1929 |
+
" current_epoch_progress = 1.0\n",
|
| 1930 |
+
" overall_progress_val = ((trainer.epoch + current_epoch_progress) / trainer.epochs) * 100\n",
|
| 1931 |
+
" status_data[\"overallProgress\"] = round(overall_progress_val, 2)\n",
|
| 1932 |
+
" status_data[\"statusText\"] = f\"Fine-Tuning... {status_data['overallProgress']}% (Epoch {status_data['currentEpoch']}/{status_data['totalEpochs']})\"\n",
|
| 1933 |
+
" status_data[\"lastUpdate\"] = time.time()\n",
|
| 1934 |
+
" \n",
|
| 1935 |
+
" if UPDATE_FREQUENCY == 'epoch':\n",
|
| 1936 |
+
" widget_html = generate_widget_html(status_data)\n",
|
| 1937 |
+
" update_readme_and_upload_with_hf_cli(widget_html)\n",
|
| 1938 |
+
" LAST_UPDATE_TIME_FOR_README = time.time()\n",
|
| 1939 |
+
"\n",
|
| 1940 |
+
"def on_batch_end_callback(trainer):\n",
|
| 1941 |
+
" global LAST_UPDATE_TIME_FOR_README, status_data\n",
|
| 1942 |
+
"\n",
|
| 1943 |
+
" if UPDATE_FREQUENCY == 'batch' and (trainer.batch_idx + 1) % BATCH_UPDATE_INTERVAL == 0:\n",
|
| 1944 |
+
" current_epoch_progress = (trainer.batch_idx + 1) / len(trainer.train_loader)\n",
|
| 1945 |
+
" overall_progress_val = ((trainer.epoch + current_epoch_progress) / trainer.epochs) * 100\n",
|
| 1946 |
+
" status_data[\"overallProgress\"] = round(overall_progress_val, 2)\n",
|
| 1947 |
+
" status_data[\"statusText\"] = f\"Fine-Tuning... {status_data['overallProgress']}% (Epoch {trainer.epoch + 1}/{trainer.epochs})\"\n",
|
| 1948 |
+
" status_data[\"lastUpdate\"] = time.time()\n",
|
| 1949 |
+
" widget_html = generate_widget_html(status_data)\n",
|
| 1950 |
+
" update_readme_and_upload_with_hf_cli(widget_html)\n",
|
| 1951 |
+
" LAST_UPDATE_TIME_FOR_README = time.time()\n",
|
| 1952 |
+
"\n",
|
| 1953 |
+
"def on_train_end_callback(trainer):\n",
|
| 1954 |
+
" global status_data\n",
|
| 1955 |
+
" status_data[\"training_active\"] = False\n",
|
| 1956 |
+
" status_data[\"overallProgress\"] = 100.0\n",
|
| 1957 |
+
" status_data[\"statusText\"] = \"Training completed!\"\n",
|
| 1958 |
+
" status_data[\"lastUpdate\"] = time.time()\n",
|
| 1959 |
+
" widget_html = generate_widget_html(status_data)\n",
|
| 1960 |
+
" update_readme_and_upload_with_hf_cli(widget_html)\n",
|
| 1961 |
+
" print(\"Final README.md update uploaded.\")\n",
|
| 1962 |
+
"\n",
|
| 1963 |
+
"\n",
|
| 1964 |
+
"if hasattr(model, 'callbacks'):\n",
|
| 1965 |
+
" model.callbacks = {}\n",
|
| 1966 |
+
" \n",
|
| 1967 |
+
"model.add_callback(\"on_train_start\", on_train_start_callback)\n",
|
| 1968 |
+
"model.add_callback(\"on_epoch_end\", on_epoch_end_callback)\n",
|
| 1969 |
+
"if UPDATE_FREQUENCY == 'batch':\n",
|
| 1970 |
+
" model.add_callback(\"on_batch_end\", on_batch_end_callback)\n",
|
| 1971 |
+
"model.add_callback(\"on_train_end\", on_train_end_callback)"
|
| 1972 |
+
]
|
| 1973 |
}
|
| 1974 |
],
|
| 1975 |
"metadata": {
|