feat: push deploy pipeline - auth, sidebar layout, ML artifacts, LFS
Notable changes: - Add .gitattributes for LFS tracking on ML model artifacts - Add AuthGuard to all protected routes + login/register/logout flow - Add collapsible Sidebar replacing old Navbar - Redesign MainLayout with sidebar + mobile header - Add password show/hide toggle to AuthForm - Add Logout button to MobileNav - Update footer credit to ATLAS Project - Pijak x IBM SkillsBuild - Update deploy.yml: generate ONNX in CI (vs HuggingFace download) - Remove deprecated ML scripts (download/upload model .sh, .gitignore) - Remove stale MEMORY.md - Add ML model artifacts (TFLite, SavedModel, TFJS) - Update notebook.ipynb training pipeline Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
# Model artifacts — not stored in git. Uploaded to Hugging Face Hub after training.
|
||||
best_model/
|
||||
model/
|
||||
dataset/
|
||||
dataset.zip
|
||||
venv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Download best_model.keras from Hugging Face Hub.
|
||||
#
|
||||
# Usage:
|
||||
# bash download_model.sh # public repo — no auth needed
|
||||
# HF_TOKEN=hf_xxx bash download_model.sh # private repo
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
DEST="${SCRIPT_DIR}/best_model/best_model.keras"
|
||||
REPO_ID="MythEclipse2737/zeavis-edu-model"
|
||||
|
||||
: "${HF_TOKEN:=}"
|
||||
|
||||
FORCE="${1:-}"
|
||||
|
||||
if [ -f "$DEST" ] && [ "$FORCE" != "--force" ]; then
|
||||
echo "Model already exists at $DEST (use --force to overwrite)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$DEST")"
|
||||
|
||||
if command -v huggingface-cli &>/dev/null; then
|
||||
huggingface-cli download "$REPO_ID" "best_model/best_model.keras" --local-dir "$(dirname "$DEST")" $( [ -n "$HF_TOKEN" ] && echo "--token $HF_TOKEN" )
|
||||
elif command -v hf &>/dev/null; then
|
||||
hf download "$REPO_ID" "best_model/best_model.keras" --output "$DEST"
|
||||
elif command -v curl &>/dev/null; then
|
||||
URL="https://huggingface.co/${REPO_ID}/resolve/main/best_model/best_model.keras"
|
||||
curl -fL -o "$DEST" $( [ -n "$HF_TOKEN" ] && echo "-H Authorization: Bearer $HF_TOKEN" ) "$URL"
|
||||
else
|
||||
echo "ERROR: Need curl or huggingface-cli installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "$DEST" ]; then
|
||||
echo "Downloaded: $DEST"
|
||||
ls -lh "$DEST"
|
||||
else
|
||||
echo "ERROR: Download failed."
|
||||
exit 1
|
||||
fi
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
©©ءّ¸ث‡ق¬§¢¥ؤج™إأà’–سèز÷ئخ ’ڑھ¸¥ؤي—·(،وظ—ئƒ„÷ٌ2:10851638082828504866
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
+911
-959
File diff suppressed because one or more lines are too long
@@ -1,62 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Upload exported model artifacts (ONNX, TFLite) to Hugging Face Hub.
|
||||
#
|
||||
# Usage:
|
||||
# bash upload_model.sh
|
||||
# HF_TOKEN=hf_xxx bash upload_model.sh
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ID="MythEclipse2737/zeavis-edu-model"
|
||||
: "${HF_TOKEN:=}"
|
||||
: "${HF_USER:=MythEclipse2737}"
|
||||
|
||||
echo "Uploading model artifacts to Hugging Face Hub..."
|
||||
|
||||
if ! command -v huggingface-cli &>/dev/null && ! python3 -c "from huggingface_hub import HfApi" 2>/dev/null; then
|
||||
echo "ERROR: huggingface_hub not installed. pip install huggingface_hub"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python3 << PYEOF
|
||||
import os, sys
|
||||
sys.path.insert(0, "${SCRIPT_DIR}")
|
||||
|
||||
from huggingface_hub import HfApi
|
||||
|
||||
api = HfApi(token="${HF_TOKEN}" if "${HF_TOKEN}" else None)
|
||||
|
||||
model_dir = "${SCRIPT_DIR}/model"
|
||||
onnx = os.path.join(model_dir, "model.onnx")
|
||||
tflite = os.path.join(model_dir, "model.tflite")
|
||||
saved_model_pb = os.path.join(model_dir, "saved_model", "saved_model.pb")
|
||||
repo_id = "${REPO_ID}"
|
||||
|
||||
files_to_upload = []
|
||||
for local, remote in [
|
||||
(onnx, "model/model.onnx"),
|
||||
(tflite, "model/model.tflite"),
|
||||
(saved_model_pb, "model/saved_model/saved_model.pb"),
|
||||
]:
|
||||
if os.path.isfile(local):
|
||||
files_to_upload.append((local, remote))
|
||||
print(f" Queued: {local} -> {remote}")
|
||||
else:
|
||||
print(f" Skip (not found): {local}")
|
||||
|
||||
for local, remote in files_to_upload:
|
||||
print(f" Uploading {remote}...")
|
||||
api.upload_file(
|
||||
path_or_fileobj=local,
|
||||
path_in_repo=remote,
|
||||
repo_id=repo_id,
|
||||
repo_type="model",
|
||||
)
|
||||
print(f" ✅ {remote} uploaded")
|
||||
|
||||
if not files_to_upload:
|
||||
print(" Nothing to upload.")
|
||||
else:
|
||||
print(f"Upload complete: https://huggingface.co/{repo_id}")
|
||||
PYEOF
|
||||
Reference in New Issue
Block a user