Text Classification
Transformers
Safetensors
English
qwen3_5_text
text-generation
system-one
typed-decisions
decision-model
calibrated-probabilities
knowledge-distillation
jev
noul
choice
score
lora
qwen3_5
dual-head
vllm
Eval Results (legacy)
Instructions to use autotrust/JEV with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use autotrust/JEV with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="autotrust/JEV")# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("autotrust/JEV") model = AutoModelForCausalLM.from_pretrained("autotrust/JEV", device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 5,622 Bytes
b2f3bf4 448ef61 b2f3bf4 448ef61 b2f3bf4 448ef61 b2f3bf4 448ef61 b2f3bf4 448ef61 b2f3bf4 | 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 | #!/usr/bin/env python3
"""Export a serving bundle (DESIGN §9): merged text-only backbone (bf16 safetensors, HF layout of
Qwen3_5ForCausalLM without lm_head) + head.safetensors + judge_config.json + calibration.json + tokenizer.
python3 scripts/export.py --checkpoint checkpoints/s2_seed42/best --calibration checkpoints/s2_seed42/best/calibration.json \
--out exports/jev-judge-qwen35-9b --name jev-judge-qwen35-9b --version 0.7.0
"""
from __future__ import annotations
import argparse
import json
import os
import shutil
import sys
import torch
from safetensors.torch import save_file
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "src"))
from jev_judge import __version__ # noqa: E402
from jev_judge.calibration import load as load_calibration # noqa: E402
from jev_judge.checkpointing import load_checkpoint # noqa: E402
def save_sharded(state: dict[str, torch.Tensor], out_dir: str, max_shard_bytes: int = 4 * 1024**3) -> None:
shards: list[dict[str, torch.Tensor]] = [{}]
sizes = [0]
for k, v in state.items():
nbytes = v.numel() * v.element_size()
if sizes[-1] + nbytes > max_shard_bytes and shards[-1]:
shards.append({}); sizes.append(0)
shards[-1][k] = v
sizes[-1] += nbytes
n = len(shards)
weight_map = {}
for i, sh in enumerate(shards):
name = f"model-{i+1:05d}-of-{n:05d}.safetensors"
save_file({k: t.contiguous() for k, t in sh.items()}, os.path.join(out_dir, name), metadata={"format": "pt"})
weight_map.update({k: name for k in sh})
with open(os.path.join(out_dir, "model.safetensors.index.json"), "w") as f:
json.dump({"metadata": {"total_size": sum(sizes)}, "weight_map": weight_map}, f, indent=2)
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--checkpoint", required=True)
ap.add_argument("--calibration", required=True, help="calibration.json (fail-fast at serve time if missing)")
ap.add_argument("--out", required=True)
ap.add_argument("--name", default="jev-judge")
ap.add_argument("--version", default=__version__)
ap.add_argument("--include-lm-head", action="store_true",
help="also ship the base model's lm_head.weight so the bundle can do ordinary AR generation")
ap.add_argument("--mode", choices=["merged", "unmerged"], default="unmerged",
help="merged: LoRA folded into the shipped backbone (decision-only bundle); "
"unmerged: ship the *pristine* base backbone + adapter/ (dual-mode: AR generation is exactly the base model)")
args = ap.parse_args()
table = load_calibration(args.calibration) # validates schema
judge, cfg = load_checkpoint(args.checkpoint, device="cuda")
lm = judge.lm
os.makedirs(args.out, exist_ok=True)
if args.mode == "unmerged":
if not hasattr(lm, "peft_config"):
raise SystemExit("checkpoint has no LoRA adapter; use --mode merged")
lm.save_pretrained(os.path.join(args.out, "adapter")) # peft adapter (fp32 master weights)
lm = lm.unload() # drop adapter layers -> pristine base weights
args.include_lm_head = True # dual-mode bundles always ship the vocab head
elif hasattr(lm, "merge_and_unload"):
lm = lm.merge_and_unload()
lm.lm_head = None
state = {k: v.detach().cpu() for k, v in lm.state_dict().items() if not k.startswith("lm_head")} # dtypes as loaded (bf16 / fp32)
if args.include_lm_head:
# the judge dropped lm_head at load time; take the pristine rows from the base checkpoint
import glob
from safetensors import safe_open
found = False
for shard in sorted(glob.glob(os.path.join(cfg["base_model_path"], "*.safetensors"))):
with safe_open(shard, framework="pt", device="cpu") as f:
if "lm_head.weight" in f.keys():
state["lm_head.weight"] = f.get_tensor("lm_head.weight").to(torch.bfloat16)
found = True
break
if not found:
raise SystemExit("lm_head.weight not found in base checkpoint")
save_sharded(state, args.out)
# text-only config in Qwen3_5ForCausalLM layout
tcfg = lm.config.to_dict()
tcfg["architectures"] = ["Qwen3_5ForCausalLM"]
with open(os.path.join(args.out, "config.json"), "w") as f:
json.dump(tcfg, f, indent=2)
save_file({k: v.detach().to(torch.float32).cpu().contiguous() for k, v in judge.head.state_dict().items()},
os.path.join(args.out, "head.safetensors"))
jc = judge.judge_config({"model_name": args.name, "model_version": args.version, "lm_head_included": bool(args.include_lm_head),
"weights_mode": args.mode, "adapter_subfolder": "adapter" if args.mode == "unmerged" else None,
"lora": cfg.get("lora"), "trained_stage": cfg.get("stage"),
"source_checkpoint": os.path.abspath(args.checkpoint), "softcap": judge.head.softcap})
with open(os.path.join(args.out, "judge_config.json"), "w") as f:
json.dump(jc, f, indent=2)
shutil.copy(args.calibration, os.path.join(args.out, "calibration.json"))
judge.tokenizer.save_pretrained(args.out)
total = sum(v.numel() * v.element_size() for v in state.values())
print(f"exported [{args.mode}] {len(state)} tensors ({total/1e9:.1f} GB) + head + calibration + tokenizer"
f"{' + adapter/' if args.mode == 'unmerged' else ''} -> {args.out}")
if __name__ == "__main__":
main()
|