Instructions to use vishwr/claim_drafter with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use vishwr/claim_drafter with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3.5-9B") model = PeftModel.from_pretrained(base_model, "vishwr/claim_drafter") - Notebooks
- Google Colab
- Kaggle
File size: 5,466 Bytes
164e036 | 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 141 142 143 144 145 146 147 148 149 | #!/usr/bin/env python3
"""Choose which patents to fetch claims for, before spending network calls.
Two modes.
Granted-claim targets (default) — walk a directory of HUPD application JSONs and
emit the patent numbers worth fetching: granted, in a target domain, and with
enough Background/Abstract text to survive the dataset filters. Pre-filtering
here avoids thousands of fetches for applications the builder would discard.
python3 scripts/select_targets.py --hupd hupd/sample/2016 \\
--output data/cache/targets_granted.txt
Publication targets (--publications) — emit "<application>\\t<publication>" pairs
for the SFT training split, so the as-filed (A1) claims can be fetched to build
DPO preference pairs. Restricted to the training split so the held-out evaluation
pool is never touched.
python3 scripts/select_targets.py --hupd hupd/sample/2016 --publications \\
--manifest data/sft/manifest.jsonl --output data/cache/targets_pubs.tsv
"""
import argparse
import glob
import json
import os
import random
import sys
from collections import Counter
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from claim_drafter.domains import classify
from claim_drafter.filters import clean_section
MIN_BACKGROUND_CHARS = 400
MIN_ABSTRACT_CHARS = 150
def iter_applications(hupd_dirs):
for d in hupd_dirs:
for path in sorted(glob.glob(os.path.join(d, "*.json"))):
try:
with open(path) as f:
yield json.load(f)
except ValueError:
continue
def already_fetched(path, key):
done = set()
if path and os.path.exists(path):
with open(path) as f:
for line in f:
try:
done.add(json.loads(line)[key])
except Exception:
pass
return done
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--hupd", nargs="+", required=True, help="directories of HUPD JSONs")
ap.add_argument("--output", required=True)
ap.add_argument("--publications", action="store_true",
help="emit application/publication pairs for as-filed claims")
ap.add_argument("--manifest", help="restrict to the train split of this manifest")
ap.add_argument("--domains", help="comma-separated domain allowlist")
ap.add_argument("--skip-cached", help="JSONL of already-fetched records")
ap.add_argument("--per-domain-cap", type=int, default=0,
help="cap per domain, for augmentation runs")
ap.add_argument("--seed", type=int, default=42)
args = ap.parse_args()
allow = set(args.domains.split(",")) if args.domains else None
restrict = None
if args.manifest:
restrict = set()
with open(args.manifest) as f:
for line in f:
r = json.loads(line)
if r.get("split") == "train":
restrict.add(r["application_number"])
stats = Counter()
by_domain = {}
rows = []
if args.publications:
done = already_fetched(args.skip_cached, "application_number")
for d in iter_applications(args.hupd):
app = d.get("application_number") or ""
if restrict is not None and app not in restrict:
continue
if app in done:
stats["already_cached"] += 1
continue
pub = (d.get("publication_number") or "").split("-")[0]
if not pub.startswith("US"):
stats["no_publication"] += 1
continue
rows.append("%s\t%s" % (app, pub))
else:
done = already_fetched(args.skip_cached, "patent_number")
for d in iter_applications(args.hupd):
if d.get("decision") != "ACCEPTED":
stats["not_granted"] += 1
continue
domain = classify(d.get("main_ipcr_label"))
if not domain or (allow and domain not in allow):
stats["off_domain"] += 1
continue
patent = d.get("patent_number") or ""
if not patent.isdigit():
stats["no_patent_number"] += 1
continue
if patent in done:
stats["already_cached"] += 1
continue
if len(clean_section(d.get("background"))) < MIN_BACKGROUND_CHARS:
stats["thin_background"] += 1
continue
if len(clean_section(d.get("abstract"))) < MIN_ABSTRACT_CHARS:
stats["thin_abstract"] += 1
continue
by_domain.setdefault(domain, []).append(patent)
rng = random.Random(args.seed)
for domain, patents in sorted(by_domain.items()):
patents = sorted(set(patents))
rng.shuffle(patents)
if args.per_domain_cap:
patents = patents[: args.per_domain_cap]
print(" %-26s %5d" % (domain, len(patents)))
rows.extend(patents)
rows = list(dict.fromkeys(rows))
os.makedirs(os.path.dirname(os.path.abspath(args.output)), exist_ok=True)
with open(args.output, "w") as f:
f.write("\n".join(rows) + ("\n" if rows else ""))
print("\nskipped: %s" % (" ".join("%s=%d" % kv for kv in sorted(stats.items())) or "none"))
print("wrote %d targets -> %s" % (len(rows), args.output))
if __name__ == "__main__":
main()
|