File size: 5,020 Bytes
5264032 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | #!/usr/bin/env python3
"""
Assemble the Hugging Face bucket and publish it.
python code/upload_bucket.py --repo adeerkhan/msq-plurality-gap [--dry-run]
Stages, in order:
1. dataset/ the 42 items (jsonl + csv + card)
2. code/ the full harness
3. results/ every generation and every metric
4. figures/ the figures used in the README
5. model/ the evaluated model's weights (openbmb/MiniCPM5-2B, Apache-2.0)
6. README.md / FINDINGS.md / LICENSE / requirements.txt
"""
from __future__ import annotations
import argparse
import os
import pathlib
import shutil
import sys
ROOT = pathlib.Path(__file__).resolve().parent.parent
STAGE = ROOT / ".bucket"
MODEL_REPO = "openbmb/MiniCPM5-2B"
MODEL_FILES = ["config.json", "generation_config.json", "model.safetensors",
"model.safetensors.index.json", "tokenizer.json",
"tokenizer_config.json", "special_tokens_map.json",
"chat_template.jinja"]
README_TEXT = """# MiniCPM5-2B (evaluated checkpoint)
Unmodified weights of [`openbmb/MiniCPM5-2B`](https://huggingface.co/openbmb/MiniCPM5-2B),
mirrored here so the bucket is self-contained for re-running the evaluation.
* Architecture: `LlamaForCausalLM`, 42 layers, GQA 16 Q / 2 KV heads
* Parameters: 2,516,756,480 (1,981,982,720 non-embedding)
* Context length: 131,072
* Licence: Apache-2.0
* SHA of the upstream revision this was taken from: see `UPSTREAM_REVISION.txt`
The evaluation in this bucket was run against these weights in bfloat16 (and,
for the cross-model comparison, in NF4 4-bit for every model so that the
protocol is identical across models). The weights here are the unmodified
upstream bf16 checkpoint.
"""
def stage_model() -> None:
from huggingface_hub import snapshot_download
print("resolving model snapshot ...")
snap = pathlib.Path(snapshot_download(MODEL_REPO,
allow_patterns=MODEL_FILES + ["*.md"]))
dst = STAGE / "model"
dst.mkdir(parents=True, exist_ok=True)
for f in sorted(snap.iterdir()):
if f.name.endswith(".md"):
continue
target = dst / f.name
if target.exists():
continue
shutil.copyfile(f.resolve(), target)
print(f" + model/{f.name} ({target.stat().st_size/1e6:.0f} MB)")
# revision provenance
from huggingface_hub import HfApi
info = HfApi().model_info(MODEL_REPO)
(dst / "UPSTREAM_REVISION.txt").write_text(
f"upstream repo : https://huggingface.co/{MODEL_REPO}\n"
f"revision sha : {info.sha}\n"
f"last modified : {info.last_modified}\n"
f"licence : {info.card_data.get('license') if info.card_data else 'apache-2.0'}\n")
(dst / "README.md").write_text(README_TEXT)
EXCLUDE_CODE = {"stop_all.sh", "stop_fetches.sh", "stop_runs.sh", "fetch_one.sh",
"__pycache__"}
def stage_tree() -> None:
STAGE.mkdir(parents=True, exist_ok=True)
for name in ("dataset", "code", "results", "figures"):
src = ROOT / name
if not src.exists():
continue
dst = STAGE / name
if dst.exists():
shutil.rmtree(dst)
shutil.copytree(src, dst, ignore=shutil.ignore_patterns("__pycache__", "*.pyc"))
if name == "code":
for f in EXCLUDE_CODE:
(dst / f).unlink(missing_ok=True)
print(f" + {name}/")
for f in ("README.md", "FINDINGS.md", "LICENSE", "requirements.txt"):
if (ROOT / f).exists():
shutil.copyfile(ROOT / f, STAGE / f)
print(f" + {f}")
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--repo", default="adeerkhan/msq-plurality-gap")
ap.add_argument("--dry-run", action="store_true")
ap.add_argument("--skip-model", action="store_true")
ap.add_argument("--no-stage", action="store_true",
help="reuse the already-staged tree (for retries)")
args = ap.parse_args()
if STAGE.exists() and args.no_stage:
print(f"reusing staged tree at {STAGE}")
else:
if STAGE.exists():
shutil.rmtree(STAGE)
print("staging tree ...")
stage_tree()
if not args.skip_model:
stage_model()
total = sum(p.stat().st_size for p in STAGE.rglob("*") if p.is_file())
print(f"staged {total/1e9:.2f} GB at {STAGE}")
if args.dry_run:
for p in sorted(STAGE.rglob("*")):
if p.is_file():
print(f" {p.relative_to(STAGE)} {p.stat().st_size/1e6:.1f} MB")
return
from huggingface_hub import HfApi, upload_folder
api = HfApi()
api.create_repo(repo_id=args.repo, repo_type="model", exist_ok=True,
private=False)
print(f"uploading to https://huggingface.co/{args.repo}")
upload_folder(repo_id=args.repo, repo_type="model",
folder_path=str(STAGE), commit_message="MSQ: the unstated premise")
print("done")
if __name__ == "__main__":
main()
|