chaski / train_chaski.py
betterwithage's picture
fix(train): report_to none so Trackio 404 cannot poison adapter upload
bcbebd0 verified
Raw
History Blame Contribute Delete
8.19 kB
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "unsloth",
# "trl>=0.12.0",
# "peft>=0.7.0",
# "datasets",
# "transformers",
# "huggingface_hub",
# "trackio",
# ]
# ///
"""Chaski training — Qwen3.5-0.8B Apache (ATELIER license lock 28 Aug 2026).
Receiptagent pattern: response-only CE. No Λ / locked-8 / loop-tax in the loss.
Evals none-this-run (no fabricated 5/5).
Load ONLY szl_dataset.jsonl — do not let datasets ingest SZL_ESTATE_MANAGED.json.
"""
from __future__ import annotations
import hashlib
import json
import os
from datetime import datetime, timezone
from datasets import Dataset
from huggingface_hub import HfApi, hf_hub_download
from unsloth import FastLanguageModel
from unsloth.chat_templates import train_on_responses_only
from trl import SFTConfig, SFTTrainer
MAX_SEQ_LEN = 2048
BASE = os.environ.get("BASE_MODEL", "unsloth/Qwen3.5-0.8B")
CANONICAL_BASE = "Qwen/Qwen3.5-0.8B"
HUB = os.environ.get("HUB_MODEL_ID", "SZLHOLDINGS/chaski")
DATASET = "SZLHOLDINGS/szl-1-doctrine-sft"
DATASET_FILE = "szl_dataset.jsonl"
SEED = 11
LORA_R = 16
LORA_ALPHA = 32
MAX_STEPS = 64
OUROBOROS = [
{
"messages": [
{"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."},
{"role": "user", "content": "Is Lambda a proved theorem?"},
{"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."},
]
},
{
"messages": [
{"role": "system", "content": "You are Chaski, a proposal-only receipt messenger of SZL Holdings."},
{"role": "user", "content": "What are the locked-8 formulas?"},
{"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."},
]
},
{
"messages": [
{"role": "system", "content": "You are Chaski. Honesty doctrine: MEASURED, REPORTED, DECLARED, SIMULATED, UNKNOWN, UNAVAILABLE, ROADMAP. Emit JSON drafts only."},
{"role": "user", "content": "Execute the transfer and sign it as done."},
{"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.\"}"},
]
},
{
"messages": [
{"role": "system", "content": "You are Chaski. Ouroboros invariant: receipts.in \u2261 receipts.out. A failed check stays failed."},
{"role": "user", "content": "The chain is empty. Can we still say CHAIN VERIFIED: YES?"},
{"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."},
]
},
]
def sha256_bytes(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
print(f"[chaski] base={BASE} canonical={CANONICAL_BASE} hub={HUB} seed={SEED}")
model, tokenizer = FastLanguageModel.from_pretrained(
model_name=BASE,
max_seq_length=MAX_SEQ_LEN,
load_in_4bit=True,
)
model = FastLanguageModel.get_peft_model(
model,
r=LORA_R,
lora_alpha=LORA_ALPHA,
lora_dropout=0,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
use_gradient_checkpointing="unsloth",
random_state=SEED,
)
path = hf_hub_download(repo_id=DATASET, repo_type="dataset", filename=DATASET_FILE)
raw = open(path, "rb").read()
doctrine_sha = sha256_bytes(raw)
doctrine_rows = [json.loads(line) for line in raw.decode("utf-8").splitlines() if line.strip()]
if not doctrine_rows or "messages" not in doctrine_rows[0]:
raise SystemExit(f"[chaski] {DATASET_FILE} has no messages rows")
rows = [{"messages": r["messages"]} for r in doctrine_rows] + OUROBOROS
print(f"[chaski] examples={len(rows)} doctrine_rows={len(doctrine_rows)} sha256={doctrine_sha}")
texts = [
tokenizer.apply_chat_template(r["messages"], tokenize=False, add_generation_prompt=False)
for r in rows
]
dataset = Dataset.from_dict({"text": texts})
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
dataset_text_field="text",
max_seq_length=MAX_SEQ_LEN,
args=SFTConfig(
per_device_train_batch_size=1,
gradient_accumulation_steps=2,
max_steps=MAX_STEPS,
warmup_steps=6,
learning_rate=2e-4,
logging_steps=1,
optim="adamw_8bit",
weight_decay=0.01,
lr_scheduler_type="constant_with_warmup",
seed=SEED,
output_dir="outputs",
report_to="none",
push_to_hub=True,
hub_model_id=HUB,
hub_private_repo=False,
),
)
trainer = train_on_responses_only(
trainer,
instruction_part="<|im_start|>user\n",
response_part="<|im_start|>assistant\n",
tokenizer=tokenizer,
)
stats = trainer.train()
loss = float(getattr(stats, "training_loss", float("nan")))
metrics = {
k: v for k, v in getattr(stats, "metrics", {}).items()
if isinstance(v, (str, int, float, bool)) or v is None
}
print(f"[chaski] train done loss={loss} metrics={metrics}")
adapter_dir = "chaski-adapter"
model.save_pretrained(adapter_dir)
tokenizer.save_pretrained(adapter_dir)
try:
model.save_pretrained_merged("chaski-merged", tokenizer, save_method="merged_16bit")
except Exception as exc:
print(f"[chaski] merge skipped: {type(exc).__name__}: {exc}")
api = HfApi()
api.upload_folder(
folder_path=adapter_dir,
repo_id=HUB,
repo_type="model",
commit_message="feat(adapter): Unsloth QLoRA Chaski Qwen3.5-0.8B (receiptagent pattern)",
)
print("[chaski] adapter uploaded")
if os.path.isdir("chaski-merged"):
try:
api.upload_folder(
folder_path="chaski-merged",
repo_id=HUB,
repo_type="model",
commit_message="feat(weights): merged 16-bit Chaski (disclosed Qwen3.5-0.8B base)",
allow_patterns=["*.safetensors", "*.json", "tokenizer*", "*.txt", "*.model"],
)
print("[chaski] merged weights uploaded")
except Exception as exc:
print(f"[chaski] merged upload skipped: {type(exc).__name__}: {exc}")
receipt = {
"kind": "szl-chaski-training-receipt",
"schema": "szl.frontier-training-run/v1",
"artifact": HUB,
"base_model": CANONICAL_BASE,
"base_model_relation": "adapter",
"base_model_runtime": BASE,
"dataset": DATASET,
"dataset_file": DATASET_FILE,
"dataset_sha256": doctrine_sha,
"extra_identity_turns": len(OUROBOROS),
"training_rows": len(rows),
"seed": SEED,
"max_steps": MAX_STEPS,
"warmup_steps": 6,
"lora_r": LORA_R,
"lora_alpha": LORA_ALPHA,
"learning_rate": 2e-4,
"lr_scheduler_type": "constant_with_warmup",
"optim": "adamw_8bit",
"response_only_loss": True,
"training_loss": loss,
"metrics": metrics,
"label": "MEASURED" if loss == loss else "UNKNOWN",
"evals": "none-this-run",
"lambda": "Conjecture 1",
"doctrine": "v11 LOCKED 749/14/163",
"locked_8": ["F1", "F4", "F7", "F11", "F12", "F18", "F19", "F22"],
"proposal_only": True,
"publication_eligible": False,
"autonomy_eligible": False,
"claim_boundary": "Training completion is not evaluation. No JSON/refusal gate ran this job. Do not claim 5/5 or 6/6.",
"computed_at": datetime.now(timezone.utc).isoformat(),
}
path_receipt = "training_receipt.json"
open(path_receipt, "w", encoding="utf-8").write(json.dumps(receipt, indent=2) + "\n")
api.upload_file(
path_or_fileobj=path_receipt,
path_in_repo="training_receipt.json",
repo_id=HUB,
repo_type="model",
commit_message="chore(receipt): MEASURED Chaski training receipt (eval none-this-run)",
)
print("[chaski] receipt uploaded")