TwilightTechie's picture
Publish experimental commitment-classifier pilot
f0e7192 verified
Raw History Blame Contribute Delete
2.69 kB
"""Initialize a fresh task adapter and trainable head from a fixed encoder base."""
# ruff: noqa: PLC0415
import argparse
import hashlib
import json
from pathlib import Path
from .model import save_adapter
from .optimization import load_trainable_model
def main():
import torch
from peft import LoraConfig, TaskType, get_peft_model
parser = argparse.ArgumentParser()
parser.add_argument("--base", required=True)
parser.add_argument("--base-id", required=True)
parser.add_argument("--base-revision", required=True)
parser.add_argument("--contract", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--seed", type=int, default=20260913)
parser.add_argument("--rank", type=int, default=32)
parser.add_argument("--alpha", type=int, default=64)
parser.add_argument("--dropout", type=float, default=0.05)
args = parser.parse_args()
if args.output.exists():
raise ValueError("Refusing to overwrite an initialized adapter")
if min(args.rank, args.alpha) <= 0 or not 0 <= args.dropout < 1:
raise ValueError("Invalid LoRA dimensions or dropout")
torch.set_num_threads(8)
torch.manual_seed(args.seed)
model, tokenizer, _labels, _ids = load_trainable_model(
args.base, args.contract, None, "full", fresh_head=True
)
model = get_peft_model(
model,
LoraConfig(
task_type=TaskType.SEQ_CLS,
r=args.rank,
lora_alpha=args.alpha,
lora_dropout=args.dropout,
target_modules=["attn.Wqkv", "attn.Wo", "mlp.Wi", "mlp.Wo"],
modules_to_save=["head", "classifier"],
bias="none",
revision=args.base_revision,
),
)
save_adapter(model, tokenizer, args.output, args.base_id, args.base_revision)
(args.output / "contract.json").write_bytes(args.contract.read_bytes())
receipt = {
"base_model": args.base_id,
"base_revision": args.base_revision,
"seed": args.seed,
"rank": args.rank,
"alpha": args.alpha,
"dropout": args.dropout,
"classifier_pooling": model.config.classifier_pooling,
"adapter_sha256": hashlib.sha256(
(args.output / "adapter_model.safetensors").read_bytes()
).hexdigest(),
"trainable_parameters": sum(
parameter.numel()
for parameter in model.parameters()
if parameter.requires_grad
),
}
(args.output / "initialization.json").write_text(
json.dumps(receipt, indent=2) + "\n"
)
print(json.dumps(receipt))
if __name__ == "__main__":
main()