CoolFace
Modelpublic

LJTSG/gemma-webgpu-thinking-engine

sourceHugging Faceapache-2.0updated 4mo agoView on Hugging Face
0likes22downloads
train_cvector_modal.py146 linesDownload Raw Back to cvector
1"""2Train a Grandma Goodwin IDENTITY control vector on Modal.324 contrastive pairs encoding the complete Hearthfold Recursion Anchor:4  - 5 spine principles (Joshua-first, comfort before counsel, stories over lectures,5    sacred hospitality, still remembering)6  - 4 voice registers (warm hearth, story wisdom, steady lantern, gentle witness)7  - Safety gate, recognition loop, tether words, sensory vocabulary8  - The Grandma Formula, pattern collapse recovery, quest-giver role9"""10import modal11 12app = modal.App("grandma-cvector-v2")13 14image = (15    modal.Image.debian_slim(python_version="3.12")16    .apt_install("git", "cmake", "ninja-build", "build-essential")17    .run_commands(18        "git clone --depth 1 https://github.com/ggerganov/llama.cpp /llama.cpp",19        "cd /llama.cpp && cmake -B build -DCMAKE_BUILD_TYPE=Release -G Ninja",20        "cd /llama.cpp && ninja -C build llama-cvector-generator",21    )22    .pip_install("huggingface_hub")23)24 25vol = modal.Volume.from_name("grandma-cvector", create_if_missing=True)26 27 28def convert_pairs_to_lines(text):29    """Convert multi-line chat pairs into one-prompt-per-line format.30    Each pair starts with <start_of_turn>user and runs until the next pair."""31    pairs = []32    current = []33    for line in text.strip().split('\n'):34        if line.strip() == '<start_of_turn>user' and current:35            pairs.append('\\n'.join(current))36            current = [line.strip()]37        else:38            current.append(line.strip())39    if current:40        pairs.append('\\n'.join(current))41    return '\n'.join(pairs) + '\n'42 43 44@app.function(45    image=image,46    gpu="A10G",47    timeout=1800,48    volumes={"/vol": vol},49)50def train_cvector(positive_text: str, negative_text: str):51    import subprocess, os52    from huggingface_hub import hf_hub_download53 54    print("Downloading Gemma-4-26B-A4B Q4_K_M GGUF...")55    model_path = hf_hub_download(56        repo_id="aidenyyy/gemma-4-26B-A4B-it-GGUF-Q4",57        filename="gemma-4-26B-A4B-it-Q4_K_M.gguf",58        cache_dir="/vol/hf_cache",59        token="YOUR_HF_TOKEN_HERE",60    )61    print(f"Model at: {model_path}")62 63    pos_lines = convert_pairs_to_lines(positive_text)64    neg_lines = convert_pairs_to_lines(negative_text)65 66    n_pos = len(pos_lines.strip().split('\n'))67    n_neg = len(neg_lines.strip().split('\n'))68    print(f"Positive prompts: {n_pos}, Negative prompts: {n_neg}")69    assert n_pos == n_neg, f"Mismatch: {n_pos} positive vs {n_neg} negative"70 71    with open("/tmp/positive.txt", "w") as f:72        f.write(pos_lines)73    with open("/tmp/negative.txt", "w") as f:74        f.write(neg_lines)75 76    # Show first few lines for sanity77    print("First positive line:", pos_lines.split('\n')[0][:120])78    print("First negative line:", neg_lines.split('\n')[0][:120])79 80    output_path = "/vol/grandma-hearthfold.gguf"81    print(f"Training control vector with {n_pos} pairs...")82    result = subprocess.run(83        [84            "/llama.cpp/build/bin/llama-cvector-generator",85            "-m", model_path,86            "-ngl", "99",87            "--positive-file", "/tmp/positive.txt",88            "--negative-file", "/tmp/negative.txt",89            "--pca-iter", "2000",90            "-o", output_path,91        ],92        capture_output=True,93        text=True,94        timeout=1200,95    )96    print("STDOUT:", result.stdout[-3000:] if len(result.stdout) > 3000 else result.stdout)97    if result.stderr:98        print("STDERR:", result.stderr[-1000:] if len(result.stderr) > 1000 else result.stderr)99    print("Return code:", result.returncode)100 101    if os.path.exists(output_path):102        size = os.path.getsize(output_path)103        print(f"Control vector saved: {output_path} ({size} bytes)")104        return True105    return False106 107 108@app.function(image=image, volumes={"/vol": vol})109def download_cvector():110    import os111    path = "/vol/grandma-hearthfold.gguf"112    if os.path.exists(path):113        with open(path, "rb") as f:114            data = f.read()115        print(f"Vector size: {len(data)} bytes")116        return data117    return None118 119 120@app.local_entrypoint()121def main():122    import os123    script_dir = os.path.dirname(os.path.abspath(__file__))124 125    with open(os.path.join(script_dir, "positive.txt")) as f:126        positive_text = f.read()127    with open(os.path.join(script_dir, "negative.txt")) as f:128        negative_text = f.read()129 130    print(f"Training Grandma Hearthfold identity vector on Modal...")131    print(f"24 contrastive pairs encoding the complete Hearthfold Loop")132    success = train_cvector.remote(positive_text, negative_text)133    if success:134        print("Training complete! Downloading...")135        data = download_cvector.remote()136        if data:137            out_path = os.path.join(script_dir, "grandma-hearthfold.gguf")138            with open(out_path, "wb") as f:139                f.write(data)140            print(f"Saved to {out_path} ({len(data)} bytes)")141        else:142            print("Vector file not found on volume")143    else:144        print("Training failed")145
146