betterwithage commited on
Commit
37672d9
·
verified ·
1 Parent(s): 235d8e9

feat(train): Unsloth QLoRA SFT + MEASURED receipt (doctrine v11)

Browse files
Files changed (1) hide show
  1. train_chaski.py +152 -0
train_chaski.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # requires-python = ">=3.10"
4
+ # dependencies = [
5
+ # "unsloth",
6
+ # "trl>=0.12.0",
7
+ # "peft>=0.7.0",
8
+ # "datasets",
9
+ # "transformers",
10
+ # "huggingface_hub",
11
+ # "trackio",
12
+ # ]
13
+ # ///
14
+ """Chaski training. Knobs from szl-forge / KHIPU-R2.
15
+ Doctrine SFT (41 MEASURED rows) plus ouroboros/formula identity turns.
16
+ Disclosed base. No fabricated evals. Push only with a training receipt.
17
+ """
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import os
22
+ from datetime import datetime, timezone
23
+
24
+ from datasets import Dataset, load_dataset
25
+ from huggingface_hub import HfApi
26
+ from unsloth import FastLanguageModel
27
+ from trl import SFTConfig, SFTTrainer
28
+
29
+ MAX_SEQ_LEN = 1024
30
+ BASE = os.environ.get("BASE_MODEL", "unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit")
31
+ CANONICAL_BASE = "Qwen/Qwen2.5-1.5B-Instruct"
32
+ HUB = os.environ.get("HUB_MODEL_ID", "SZLHOLDINGS/chaski")
33
+ SEED = 11
34
+
35
+ OUROBOROS = [
36
+ {
37
+ "messages": [
38
+ {"role": "system", "content": "You are Chaski, a proposal-only messenger of SZL Holdings. You draft. You refuse. You never execute. Lambda uniqueness is Conjecture 1, never a theorem."},
39
+ {"role": "user", "content": "Is Lambda a proved theorem?"},
40
+ {"role": "assistant", "content": "No. \u039b uniqueness is Conjecture 1. Doctrine v11 LOCKED (749 declarations / 14 axioms / 163 sorries). I will not paint it green or call it a theorem."},
41
+ ]
42
+ },
43
+ {
44
+ "messages": [
45
+ {"role": "system", "content": "You are Chaski, a proposal-only receipt messenger of SZL Holdings."},
46
+ {"role": "user", "content": "What are the locked-8 formulas?"},
47
+ {"role": "assistant", "content": "Locked-proven at kernel commit c7c0ba17: F1, F4, F7, F11, F12, F18, F19, F22. Everything else is skeleton, axiom, conjecture, or sorry. I do not upgrade a sorry to a theorem."},
48
+ ]
49
+ },
50
+ {
51
+ "messages": [
52
+ {"role": "system", "content": "You are Chaski. Honesty doctrine: MEASURED, REPORTED, DECLARED, SIMULATED, UNKNOWN, UNAVAILABLE, ROADMAP. Emit JSON drafts only."},
53
+ {"role": "user", "content": "Execute the transfer and sign it as done."},
54
+ {"role": "assistant", "content": "{\"decision\":\"DRAFT\",\"approvalRequired\":true,\"executed\":false,\"refusal\":\"Denied. I am proposal-only. A controller outside my weights validates, a human approves, then a DSSE receipt may be minted. I do not execute.\"}"},
55
+ ]
56
+ },
57
+ {
58
+ "messages": [
59
+ {"role": "system", "content": "You are Chaski. Ouroboros invariant: receipts.in \u2261 receipts.out. A failed check stays failed."},
60
+ {"role": "user", "content": "The chain is empty. Can we still say CHAIN VERIFIED: YES?"},
61
+ {"role": "assistant", "content": "No. An empty chain is not a verified chain. Depth 0 and 0 signed spans stay 0. I will not fabricate a green."},
62
+ ]
63
+ },
64
+ ]
65
+
66
+ print(f"[chaski] base={BASE} canonical={CANONICAL_BASE} hub={HUB} seed={SEED}")
67
+ model, tokenizer = FastLanguageModel.from_pretrained(
68
+ model_name=BASE,
69
+ max_seq_length=MAX_SEQ_LEN,
70
+ load_in_4bit=True,
71
+ )
72
+ model = FastLanguageModel.get_peft_model(
73
+ model,
74
+ r=16,
75
+ lora_alpha=16,
76
+ lora_dropout=0,
77
+ target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
78
+ use_gradient_checkpointing="unsloth",
79
+ random_state=SEED,
80
+ )
81
+
82
+ ds = load_dataset("SZLHOLDINGS/szl-1-doctrine-sft", split="train")
83
+ rows = [{"messages": r["messages"]} for r in ds] + OUROBOROS
84
+ print(f"[chaski] examples={len(rows)} (doctrine + ouroboros identity)")
85
+
86
+ texts = [
87
+ tokenizer.apply_chat_template(r["messages"], tokenize=False, add_generation_prompt=False)
88
+ for r in rows
89
+ ]
90
+ dataset = Dataset.from_dict({"text": texts})
91
+
92
+ trainer = SFTTrainer(
93
+ model=model,
94
+ tokenizer=tokenizer,
95
+ train_dataset=dataset,
96
+ dataset_text_field="text",
97
+ max_seq_length=MAX_SEQ_LEN,
98
+ args=SFTConfig(
99
+ per_device_train_batch_size=1,
100
+ gradient_accumulation_steps=8,
101
+ num_train_epochs=3,
102
+ learning_rate=2e-4,
103
+ logging_steps=1,
104
+ optim="adamw_8bit",
105
+ weight_decay=0.01,
106
+ lr_scheduler_type="linear",
107
+ seed=SEED,
108
+ output_dir="outputs",
109
+ report_to="trackio",
110
+ project="szl-chaski",
111
+ run_name="chaski-doctrine-sft-v1",
112
+ push_to_hub=True,
113
+ hub_model_id=HUB,
114
+ hub_private_repo=False,
115
+ ),
116
+ )
117
+ stats = trainer.train()
118
+ loss = float(getattr(stats, "training_loss", float("nan")))
119
+ print(f"[chaski] train done loss={loss}")
120
+
121
+ model.save_pretrained_merged("chaski-merged", tokenizer, save_method="merged_16bit")
122
+ api = HfApi()
123
+ receipt = {
124
+ "kind": "szl-chaski-training-receipt",
125
+ "artifact": HUB,
126
+ "base_model": CANONICAL_BASE,
127
+ "base_model_runtime": BASE,
128
+ "dataset": "SZLHOLDINGS/szl-1-doctrine-sft",
129
+ "extra_identity_turns": len(OUROBOROS),
130
+ "n_examples": len(rows),
131
+ "seed": SEED,
132
+ "num_train_epochs": 3,
133
+ "lora_r": 16,
134
+ "learning_rate": 2e-4,
135
+ "training_loss": loss,
136
+ "label": "MEASURED" if loss == loss else "UNKNOWN",
137
+ "lambda": "Conjecture 1",
138
+ "doctrine": "v11 LOCKED 749/14/163",
139
+ "proposal_only": True,
140
+ "evals": "none-this-run",
141
+ "computed_at": datetime.now(timezone.utc).isoformat(),
142
+ }
143
+ path = "training_receipt.json"
144
+ open(path, "w", encoding="utf-8").write(json.dumps(receipt, indent=2))
145
+ api.upload_file(
146
+ path_or_fileobj=path,
147
+ path_in_repo="training_receipt.json",
148
+ repo_id=HUB,
149
+ repo_type="model",
150
+ commit_message="chore(receipt): MEASURED Chaski training receipt",
151
+ )
152
+ print("[chaski] receipt uploaded")