Instructions to use kesha-humonen/runic-reader-2 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use kesha-humonen/runic-reader-2 with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
Download code/score_ocr.py from kesha-humonen/runic-reader-2: direct link, hf CLI and curl.
- Browser
- Download file 2.72 kB
-
https://huggingface.co/kesha-humonen/runic-reader-2/resolve/main/code/score_ocr.py
- Command line
-
hf download hf://kesha-humonen/runic-reader-2/code/score_ocr.py
-
curl -L -o score_ocr.py https://huggingface.co/kesha-humonen/runic-reader-2/resolve/main/code/score_ocr.py
2.72 kB
| """Reference-free confidence of recognizer outputs: mean negative log-likelihood of the (loop-cut) predicted | |
| transliteration under the recognizer that produced it, given the image and the recognition prompt. | |
| Input: a prediction file with {"id", "image", "pred", ...}. Output: one line per row, | |
| {"id", "nll", "n_tokens"}; nll is null for empty predictions. Reuses the training example builder | |
| (train_lora.Examples) with the prediction as the target and without the end-of-turn token. Resumable. | |
| """ | |
| import argparse | |
| import json | |
| import math | |
| import os | |
| import sys | |
| import torch | |
| sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) | |
| from qwen_common import load_model # noqa: E402 | |
| from train_lora import Examples # noqa: E402 | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--model", required=True) | |
| ap.add_argument("--adapter", required=True) | |
| ap.add_argument("--input", required=True) | |
| ap.add_argument("--image_root", required=True) | |
| ap.add_argument("--out", required=True) | |
| ap.add_argument("--device", default="cuda") | |
| ap.add_argument("--limit", type=int, default=0) # smoke tests | |
| args = ap.parse_args() | |
| rows = [json.loads(l) for l in open(args.input) if l.strip()] | |
| done = set() | |
| if os.path.exists(args.out): | |
| done = {json.loads(l)["id"] for l in open(args.out) if l.strip()} | |
| todo = [dict(r, target=r["pred"] or "") for r in rows if r["id"] not in done] | |
| if args.limit: | |
| todo = todo[:args.limit] | |
| print(f"rows {len(rows)} done {len(done)} todo {len(todo)}", flush=True) | |
| if not todo: | |
| return | |
| processor, model = load_model(args.model, adapter=args.adapter) | |
| model.to(args.device).eval() | |
| ds = Examples(todo, processor, "ocr", args.image_root) | |
| ds.end = "" # score the transliteration only, not the end-of-turn token | |
| fout = open(args.out, "a") | |
| for i, r in enumerate(todo): | |
| rec = {"id": r["id"], "nll": None, "n_tokens": 0} | |
| if r["target"].strip(): | |
| try: | |
| item = ds[i] | |
| n = int((item["labels"] != -100).sum()) | |
| batch = {k: v.to(args.device) for k, v in item.items()} | |
| with torch.no_grad(), torch.autocast("cuda", dtype=torch.bfloat16): | |
| loss = model(**batch).loss.item() | |
| rec.update(nll=loss if math.isfinite(loss) else None, n_tokens=n) | |
| except Exception as e: # keep going; the row is reported as unscored | |
| rec["error"] = repr(e)[:200] | |
| fout.write(json.dumps(rec) + "\n") | |
| fout.flush() | |
| if (i + 1) % 50 == 0: | |
| print(f"{i + 1}/{len(todo)}", flush=True) | |
| print("DONE", flush=True) | |
| if __name__ == "__main__": | |
| main() | |