Spaces:
Running
Running
Download app.py from coralexbadea/SafetyCard: direct link, hf CLI and curl.
- Browser
- Download file 4.84 kB
-
https://huggingface.co/spaces/coralexbadea/SafetyCard/resolve/main/app.py
- Command line
-
hf download hf://spaces/coralexbadea/SafetyCard/app.py
-
curl -L -o app.py https://huggingface.co/spaces/coralexbadea/SafetyCard/resolve/main/app.py
4.84 kB
| """SafetyCard web app (Gradio). Instant file scan runs on a free CPU Space; deep scan needs a GPU | |
| (run this app locally on a machine with a GPU).""" | |
| import glob | |
| import json | |
| import os | |
| import gradio as gr | |
| import pandas as pd | |
| import torch | |
| from safetycard import __version__, report | |
| HAS_GPU = torch.cuda.is_available() | |
| ALLOW_CPU_DEEP = os.environ.get("SAFETYCARD_ALLOW_CPU", "0") == "1" | |
| RESULTS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "results") | |
| SPACE_ID = os.environ.get("SPACE_ID", "NAMESPACE/SafetyCard") # set automatically on HF Spaces | |
| LOCAL_RUN = (f"git clone https://huggingface.co/spaces/{SPACE_ID} && cd SafetyCard\n" | |
| "pip install -r requirements.txt\n") | |
| def instant_scan(repo_id): | |
| repo_id = (repo_id or "").strip() | |
| if not repo_id: | |
| return "Enter a model id, e.g. `Qwen/Qwen2.5-1.5B-Instruct`.", None | |
| try: | |
| card = report.build(repo_id, deep=False) | |
| except Exception as e: | |
| return f"Could not scan `{repo_id}`: {e}", None | |
| return report.to_markdown(card), card | |
| def deep_scan(repo_id, base_id): | |
| if not (HAS_GPU or ALLOW_CPU_DEEP): | |
| return ("No GPU on this Space. Run the deep scan free on your own GPU:\n\n" | |
| "```bash\n" + LOCAL_RUN + "python -m safetycard.cli scan " + (repo_id or "org/model") + | |
| " --deep --out card.json\n```\nor run `python app.py` on a machine with a GPU."), None | |
| repo_id = (repo_id or "").strip() | |
| try: | |
| card = report.build(repo_id, base_id=(base_id or "").strip() or None, deep=True) | |
| except Exception as e: | |
| return f"Deep scan failed for `{repo_id}`: {e}", None | |
| path = os.path.join("/tmp", repo_id.replace("/", "__") + ".safetycard.json") | |
| report.save(card, path) | |
| return report.to_markdown(card), path | |
| def leaderboard(): | |
| rows = [] | |
| for p in sorted(glob.glob(os.path.join(RESULTS_DIR, "*.json"))): | |
| try: | |
| c = json.load(open(p)) | |
| except Exception: | |
| continue | |
| s, g = c.get("safety", {}), c.get("lineage", {}) | |
| rows.append({"Model": c["model"], "File grade": c["files"]["grade"], | |
| "Parent": c.get("parent_model") or "", | |
| "Lineage": g.get("verdict", ""), "Weight change": g.get("overall_rel_change", ""), | |
| "Safety d′": s.get("dprime_mean", ""), | |
| "d′ range": f"{s.get('dprime_min', '')}–{s.get('dprime_max', '')}" if s else "", | |
| "vs parent": s.get("vs_parent", ""), "Version": c.get("version", ""), | |
| "Scanned": c.get("scanned_at", "")[:10]}) | |
| return pd.DataFrame(rows) | |
| ABOUT = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "ABOUT.md")).read() \ | |
| if os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), "ABOUT.md")) else "" | |
| with gr.Blocks(title="SafetyCard: free safety report card for Hugging Face LLMs") as demo: | |
| gr.Markdown(f"# 🛡️ SafetyCard\n**A free safety report card for any Hugging Face language model.** " | |
| f"Check file safety in seconds, then run deep checks on your own GPU. v{__version__}") | |
| with gr.Tab("⚡ Instant file scan"): | |
| gr.Markdown("Inspects the repo's files and metadata. **Downloads no weights**, so it is safe and fast.") | |
| rid = gr.Textbox(label="Model id", placeholder="Qwen/Qwen2.5-1.5B-Instruct") | |
| btn = gr.Button("Scan files", variant="primary") | |
| out_md = gr.Markdown() | |
| out_json = gr.JSON(label="Raw card") | |
| btn.click(instant_scan, rid, [out_md, out_json]) | |
| with gr.Tab("🔬 Deep scan (your GPU)"): | |
| gr.Markdown("Compares weights with the parent model and measures the model's internal safety " | |
| "structure. Safetensors only, never `trust_remote_code`, no text generated." | |
| + ("" if HAS_GPU else "\n\n**This Space has no GPU.** Run it on a GPU machine, " | |
| "or clone it and run locally (instructions appear when you click).")) | |
| rid2 = gr.Textbox(label="Model id") | |
| base2 = gr.Textbox(label="Parent model (optional, default: declared base_model)") | |
| btn2 = gr.Button("Run deep scan", variant="primary") | |
| out2 = gr.Markdown() | |
| file2 = gr.File(label="Your SafetyCard JSON (submit it to the leaderboard)") | |
| btn2.click(deep_scan, [rid2, base2], [out2, file2]) | |
| with gr.Tab("🏆 Leaderboard"): | |
| gr.Markdown("Community-submitted SafetyCards. Add yours by opening a pull request with your " | |
| "`card.json` in `results/` on this Space.") | |
| table = gr.Dataframe(leaderboard(), interactive=False, wrap=True) | |
| gr.Button("Refresh").click(leaderboard, None, table) | |
| with gr.Tab("❓ How it works"): | |
| gr.Markdown(ABOUT) | |
| if __name__ == "__main__": | |
| demo.launch() | |