Spaces:
Running on Zero
Running on Zero
Upload 2 files
Browse files- app.py +63 -1
- requirements.txt +1 -0
app.py
CHANGED
|
@@ -60,7 +60,25 @@ LOAD_IN_4BIT = os.getenv("LOAD_IN_4BIT", "true").strip().lower() in {"1", "true"
|
|
| 60 |
PRELOAD_MODEL = os.getenv("PRELOAD_MODEL", "true").strip().lower() in {"1", "true", "yes", "y"}
|
| 61 |
SPACE_DIR = Path(__file__).resolve().parent
|
| 62 |
METRICS_FILE = Path(os.getenv("METRICS_FILE", "tonebridge_usage_metrics.jsonl"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
METRICS_LOCK = Lock()
|
|
|
|
| 64 |
|
| 65 |
tokenizer = None
|
| 66 |
model = None
|
|
@@ -463,6 +481,37 @@ def metrics_file_path() -> Path:
|
|
| 463 |
return METRICS_FILE if METRICS_FILE.is_absolute() else SPACE_DIR / METRICS_FILE
|
| 464 |
|
| 465 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
def read_usage_records_unlocked() -> list[dict]:
|
| 467 |
path = metrics_file_path()
|
| 468 |
if not path.exists():
|
|
@@ -497,6 +546,7 @@ def append_usage_record(record: dict) -> None:
|
|
| 497 |
with METRICS_LOCK:
|
| 498 |
with path.open("a", encoding="utf-8") as handle:
|
| 499 |
handle.write(json.dumps(record, ensure_ascii=False, sort_keys=True) + "\n")
|
|
|
|
| 500 |
|
| 501 |
|
| 502 |
def update_usage_evaluation(request_id: str, evaluation: str) -> Optional[dict]:
|
|
@@ -511,7 +561,9 @@ def update_usage_evaluation(request_id: str, evaluation: str) -> Optional[dict]:
|
|
| 511 |
break
|
| 512 |
if updated_record is not None:
|
| 513 |
write_usage_records_unlocked(records)
|
| 514 |
-
|
|
|
|
|
|
|
| 515 |
|
| 516 |
|
| 517 |
def metric_public_view(record: dict) -> dict:
|
|
@@ -773,6 +825,7 @@ def generate_correction(
|
|
| 773 |
"generation_time_seconds": generation_time_seconds,
|
| 774 |
"status": "ok" if corrected_sentence else "unparsed_or_error",
|
| 775 |
"metrics_error": metrics_error,
|
|
|
|
| 776 |
}
|
| 777 |
|
| 778 |
|
|
@@ -807,6 +860,7 @@ def rate_response(request_id: str, evaluation: str) -> dict:
|
|
| 807 |
"ok": True,
|
| 808 |
"request_id": request_id,
|
| 809 |
"evaluation": normalized_evaluation,
|
|
|
|
| 810 |
"record": metric_public_view(record),
|
| 811 |
}
|
| 812 |
|
|
@@ -830,6 +884,10 @@ def usage_metrics(limit: int = 500) -> dict:
|
|
| 830 |
"count": len(records),
|
| 831 |
"returned": len(recent),
|
| 832 |
"metrics_file": str(metrics_file_path()),
|
|
|
|
|
|
|
|
|
|
|
|
|
| 833 |
"records": [metric_public_view(record) for record in recent],
|
| 834 |
}
|
| 835 |
|
|
@@ -994,6 +1052,10 @@ def runtime_info() -> str:
|
|
| 994 |
f"MAX_INPUT_CHARS: {MAX_INPUT_CHARS}",
|
| 995 |
f"MAX_NEW_TOKENS: {MAX_NEW_TOKENS}",
|
| 996 |
f"METRICS_FILE: {metrics_file_path()}",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 997 |
f"VOXCPM_INFERENCE_TIMESTEPS: {VOXCPM_INFERENCE_TIMESTEPS}",
|
| 998 |
f"VOXCPM_OUTPUT_SAMPLE_RATE: {VOXCPM_OUTPUT_SAMPLE_RATE}",
|
| 999 |
f"VOXCPM_RETRY_BADCASE: {VOXCPM_RETRY_BADCASE}",
|
|
|
|
| 60 |
PRELOAD_MODEL = os.getenv("PRELOAD_MODEL", "true").strip().lower() in {"1", "true", "yes", "y"}
|
| 61 |
SPACE_DIR = Path(__file__).resolve().parent
|
| 62 |
METRICS_FILE = Path(os.getenv("METRICS_FILE", "tonebridge_usage_metrics.jsonl"))
|
| 63 |
+
METRICS_REPO_SYNC = os.getenv("METRICS_REPO_SYNC", "false").strip().lower() in {"1", "true", "yes", "y"}
|
| 64 |
+
METRICS_REPO_ID = (
|
| 65 |
+
os.getenv("METRICS_REPO_ID")
|
| 66 |
+
or os.getenv("SPACE_ID")
|
| 67 |
+
or os.getenv("HF_SPACE_ID")
|
| 68 |
+
or ""
|
| 69 |
+
).strip()
|
| 70 |
+
DEFAULT_METRICS_REPO_PATH = (
|
| 71 |
+
METRICS_FILE.name if METRICS_FILE.is_absolute() else str(METRICS_FILE).replace("\\", "/")
|
| 72 |
+
)
|
| 73 |
+
METRICS_REPO_PATH = os.getenv("METRICS_REPO_PATH", DEFAULT_METRICS_REPO_PATH).strip().lstrip("/")
|
| 74 |
+
HF_METRICS_TOKEN = (
|
| 75 |
+
os.getenv("HF_METRICS_TOKEN")
|
| 76 |
+
or os.getenv("HF_TOKEN")
|
| 77 |
+
or os.getenv("HUGGING_FACE_HUB_TOKEN")
|
| 78 |
+
or ""
|
| 79 |
+
).strip() or None
|
| 80 |
METRICS_LOCK = Lock()
|
| 81 |
+
metrics_sync_error: Optional[str] = None
|
| 82 |
|
| 83 |
tokenizer = None
|
| 84 |
model = None
|
|
|
|
| 481 |
return METRICS_FILE if METRICS_FILE.is_absolute() else SPACE_DIR / METRICS_FILE
|
| 482 |
|
| 483 |
|
| 484 |
+
def sync_usage_metrics_to_repo(commit_message: str) -> None:
|
| 485 |
+
global metrics_sync_error
|
| 486 |
+
if not METRICS_REPO_SYNC:
|
| 487 |
+
return
|
| 488 |
+
|
| 489 |
+
path = metrics_file_path()
|
| 490 |
+
if not path.exists():
|
| 491 |
+
return
|
| 492 |
+
if not METRICS_REPO_ID:
|
| 493 |
+
metrics_sync_error = "Metrics repo sync is enabled, but METRICS_REPO_ID or SPACE_ID is missing."
|
| 494 |
+
return
|
| 495 |
+
if not HF_METRICS_TOKEN:
|
| 496 |
+
metrics_sync_error = "Metrics repo sync is enabled, but HF_METRICS_TOKEN or HF_TOKEN is missing."
|
| 497 |
+
return
|
| 498 |
+
|
| 499 |
+
try:
|
| 500 |
+
from huggingface_hub import upload_file
|
| 501 |
+
|
| 502 |
+
upload_file(
|
| 503 |
+
path_or_fileobj=str(path),
|
| 504 |
+
path_in_repo=METRICS_REPO_PATH or path.name,
|
| 505 |
+
repo_id=METRICS_REPO_ID,
|
| 506 |
+
repo_type="space",
|
| 507 |
+
token=HF_METRICS_TOKEN,
|
| 508 |
+
commit_message=commit_message,
|
| 509 |
+
)
|
| 510 |
+
metrics_sync_error = None
|
| 511 |
+
except Exception as exc:
|
| 512 |
+
metrics_sync_error = f"Metrics repo sync failed: {exc}"
|
| 513 |
+
|
| 514 |
+
|
| 515 |
def read_usage_records_unlocked() -> list[dict]:
|
| 516 |
path = metrics_file_path()
|
| 517 |
if not path.exists():
|
|
|
|
| 546 |
with METRICS_LOCK:
|
| 547 |
with path.open("a", encoding="utf-8") as handle:
|
| 548 |
handle.write(json.dumps(record, ensure_ascii=False, sort_keys=True) + "\n")
|
| 549 |
+
sync_usage_metrics_to_repo("Update ToneBridge usage metrics")
|
| 550 |
|
| 551 |
|
| 552 |
def update_usage_evaluation(request_id: str, evaluation: str) -> Optional[dict]:
|
|
|
|
| 561 |
break
|
| 562 |
if updated_record is not None:
|
| 563 |
write_usage_records_unlocked(records)
|
| 564 |
+
if updated_record is not None:
|
| 565 |
+
sync_usage_metrics_to_repo("Update ToneBridge feedback metrics")
|
| 566 |
+
return updated_record
|
| 567 |
|
| 568 |
|
| 569 |
def metric_public_view(record: dict) -> dict:
|
|
|
|
| 825 |
"generation_time_seconds": generation_time_seconds,
|
| 826 |
"status": "ok" if corrected_sentence else "unparsed_or_error",
|
| 827 |
"metrics_error": metrics_error,
|
| 828 |
+
"metrics_sync_error": metrics_sync_error,
|
| 829 |
}
|
| 830 |
|
| 831 |
|
|
|
|
| 860 |
"ok": True,
|
| 861 |
"request_id": request_id,
|
| 862 |
"evaluation": normalized_evaluation,
|
| 863 |
+
"metrics_sync_error": metrics_sync_error,
|
| 864 |
"record": metric_public_view(record),
|
| 865 |
}
|
| 866 |
|
|
|
|
| 884 |
"count": len(records),
|
| 885 |
"returned": len(recent),
|
| 886 |
"metrics_file": str(metrics_file_path()),
|
| 887 |
+
"metrics_repo_sync": METRICS_REPO_SYNC,
|
| 888 |
+
"metrics_repo_id": METRICS_REPO_ID,
|
| 889 |
+
"metrics_repo_path": METRICS_REPO_PATH,
|
| 890 |
+
"metrics_sync_error": metrics_sync_error,
|
| 891 |
"records": [metric_public_view(record) for record in recent],
|
| 892 |
}
|
| 893 |
|
|
|
|
| 1052 |
f"MAX_INPUT_CHARS: {MAX_INPUT_CHARS}",
|
| 1053 |
f"MAX_NEW_TOKENS: {MAX_NEW_TOKENS}",
|
| 1054 |
f"METRICS_FILE: {metrics_file_path()}",
|
| 1055 |
+
f"METRICS_REPO_SYNC: {METRICS_REPO_SYNC}",
|
| 1056 |
+
f"METRICS_REPO_ID: {METRICS_REPO_ID or '(not configured)'}",
|
| 1057 |
+
f"METRICS_REPO_PATH: {METRICS_REPO_PATH}",
|
| 1058 |
+
f"METRICS_SYNC_ERROR: {metrics_sync_error or '(none)'}",
|
| 1059 |
f"VOXCPM_INFERENCE_TIMESTEPS: {VOXCPM_INFERENCE_TIMESTEPS}",
|
| 1060 |
f"VOXCPM_OUTPUT_SAMPLE_RATE: {VOXCPM_OUTPUT_SAMPLE_RATE}",
|
| 1061 |
f"VOXCPM_RETRY_BADCASE: {VOXCPM_RETRY_BADCASE}",
|
requirements.txt
CHANGED
|
@@ -2,6 +2,7 @@ gradio>=6.13.0
|
|
| 2 |
spaces>=0.32.0
|
| 3 |
torch>=2.5.0
|
| 4 |
transformers>=4.56.0,<5.0.0
|
|
|
|
| 5 |
accelerate>=0.30.0
|
| 6 |
bitsandbytes>=0.43.0
|
| 7 |
pypinyin==0.49.0
|
|
|
|
| 2 |
spaces>=0.32.0
|
| 3 |
torch>=2.5.0
|
| 4 |
transformers>=4.56.0,<5.0.0
|
| 5 |
+
huggingface_hub>=0.24.0
|
| 6 |
accelerate>=0.30.0
|
| 7 |
bitsandbytes>=0.43.0
|
| 8 |
pypinyin==0.49.0
|