Download code/scripts/upload.py from nonsodev/essay-coach: direct link, hf CLI and curl.
- Browser
- Download file 2.95 kB
-
https://huggingface.co/nonsodev/essay-coach/resolve/main/code/scripts/upload.py
- Command line
-
hf download hf://nonsodev/essay-coach/code/scripts/upload.py
-
curl -L -o upload.py https://huggingface.co/nonsodev/essay-coach/resolve/main/code/scripts/upload.py
2.95 kB
| """Push finished runs from the Modal volume to Hugging Face (public, CC BY-NC-SA 4.0 like the data). | |
| MODAL_PROFILE=labs3 modal run scripts/upload.py # scores-v1 parts-v1 band-v1 | |
| MODAL_PROFILE=labs3 modal run scripts/upload.py --runs scores-v2 | |
| """ | |
| import modal | |
| app = modal.App("essay-coach-upload") | |
| vol = modal.Volume.from_name("essay-data") | |
| image = modal.Image.debian_slim(python_version="3.11").pip_install("huggingface_hub") | |
| HF_REPO = "nonsodev/essay-coach" | |
| README = """--- | |
| license: cc-by-nc-sa-4.0 | |
| language: en | |
| tags: [essay-scoring, argument-mining, deberta-v3, ielts] | |
| --- | |
| # Essay coach | |
| Three small models behind the Labs essay coach page: six analytic writing scores (ELLIPSE), argument parts with | |
| effectiveness (PERSUADE 2.0), and a ridge band estimate fitted on human-banded IELTS essays. | |
| - `runs/scores-v1`: deberta-v3-base regression head, MCRMSE 0.446 on the ELLIPSE test split (2,571 essays). | |
| - `runs/parts-v1`: deberta-v3-base token model, BIO over 7 part types plus effectiveness; span F1 0.656 and | |
| effectiveness log loss 0.478 on 2,000 held-out PERSUADE essays. | |
| - `runs/band-v1`: `band.json`, ridge on the six scores + part counts + length; 5-fold CV RMSE 0.79 bands, | |
| within half a band 67% of the time on 1,435 essays. An estimate, not a grade. | |
| - `code/`: the training, decoding and serving code as of upload. | |
| Trained on ELLIPSE and PERSUADE 2.0 (both CC BY-NC-SA 4.0), so these weights carry the same licence: share alike, | |
| non-commercial. Backbone: microsoft/deberta-v3-base. | |
| """ | |
| def upload(runs: list[str], code: dict[str, str]): | |
| import os | |
| import tempfile | |
| from huggingface_hub import HfApi | |
| api = HfApi() | |
| api.create_repo(HF_REPO, exist_ok=True) | |
| for tag in runs: | |
| run = f"/data/runs/{tag}" | |
| print(tag, sorted(os.listdir(run)), flush=True) | |
| api.upload_folder(folder_path=run, repo_id=HF_REPO, path_in_repo=f"runs/{tag}", commit_message=f"upload {tag}") | |
| with tempfile.TemporaryDirectory() as d: | |
| for rel, text in code.items(): | |
| p = os.path.join(d, rel) | |
| os.makedirs(os.path.dirname(p), exist_ok=True) | |
| open(p, "w").write(text) | |
| open(os.path.join(d, "README.md"), "w").write(README) | |
| api.upload_folder(folder_path=d, repo_id=HF_REPO, path_in_repo="", commit_message="code snapshot + README") | |
| print(f"done: https://huggingface.co/{HF_REPO}") | |
| def main(runs: str = "scores-v1,parts-v1,band-v1"): | |
| import glob | |
| import os | |
| root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| code = {} | |
| for pat in ("coach/*.py", "scripts/*.py", "web/*.html", "PLAN.md"): | |
| for p in glob.glob(os.path.join(root, pat)): | |
| code["code/" + os.path.relpath(p, root)] = open(p).read() | |
| upload.remote(runs.split(","), code) | |