Output:
Chunk ID: 5df5aa
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 4554
Output:
diff --git a/README.md b/README.md
index a775fea..fc4b443 100644
--- a/README.md
+++ b/README.md
@@ -1,77 +1,98 @@
-# NeuroBait Build Small Model
+# NeuroBait

-NeuroBait is a fine-tuned assistant for ADHD / neurodivergent task initiation.
-This repo is the engineering source of truth for training, evaluation, and
-deployment scaffolding. Dataset and model artifacts are intentionally kept out
-of Git.
+NeuroBait is an ADHD-friendly AI companion for task initiation. It is built for
+the moment when a task is not intellectually hard, but still feels impossible to
+start.

-## Hugging Face Targets
+Instead of turning that friction into a productivity lecture, NeuroBait responds
+with short, warm, agency-preserving language. It avoids shame, streak pressure,
+diagnosis-like framing, and visible prompt labels such as `Micro-action`, `Hook`,
+or `Stakes`.

-Short public slugs keep the hackathon URLs readable:
+## Live Demo

-- Model repo: `https://huggingface.co/build-small-hackathon/NeuroBait`
-- Space app: `https://huggingface.co/spaces/build-small-hackathon/NeuroBait`
+- Hugging Face Space: https://huggingface.co/spaces/build-small-hackathon/NeuroBait
+- Model adapter: https://huggingface.co/build-small-hackathon/NeuroBait

-The visible app title remains `NeuroBait`, with the submission/story context
-documented in this GitHub repo and the model/Space cards.
+## Hackathon Submission

-## Architecture
+NeuroBait is a Build Small Hackathon submission.

-There are three separate operational artifacts:
+- Primary track: **Backyard AI**
+- Why: the app is designed around a real everyday ADHD friction - starting the
+  thing that already matters - rather than a generic chatbot or productivity
+  template.
+- Bonus quest fit: **Well-Tuned**, because NeuroBait uses a fine-tuned model
+  published on Hugging Face.
+- Bonus quest fit: **Off-Brand**, because the Space uses a custom Gradio
+  interface instead of the default app look.
+- Sponsor fit: **Modal-powered**, because fine-tuning and generation eval were
+  run on Modal GPU infrastructure.

-1. GitHub repo: training, eval, deploy source code, and docs.
-2. Hugging Face Model repo: LoRA adapter and/or merged model weights.
-3. Hugging Face Space repo: Gradio app that loads the HF Model repo.
+## What We Built

-Flow:
+The model is a LoRA fine-tune of `unsloth/gemma-3-12b-it`, trained on a small
+hand-curated bilingual Indonesian/English dataset built from real ADHD task
+initiation friction.

-```text
-GitHub source code
-  -> Modal.com fine-tune/eval/merge
-  -> HF Model repo
-  -> HF Space Gradio app
-```
+The main lesson was simple: for a voice and behavior layer, dataset quality beat
+model size. The fine-tune is intentionally narrow. It is not trying to become a
+general therapist, planner, or productivity operating system.

-`github-hf.svg` contains the same architecture as a visual diagram.
+## The Stack

-## Local Development
+A real model, trained on a real budget:

-Use the shared LLM development venv:
+- **Base:** `unsloth/gemma-3-12b-it` (dense Gemma 3 12B,
+  `Gemma3ForConditionalGeneration`)
+- **Method:** 16-bit LoRA, not QLoRA, via Unsloth
+- **LoRA:** `r=16`, `alpha=16`, `dropout=0`
+- **Epochs:** `3` | **LR:** `2e-4` | **Batch:** `1 x grad_accum 8` |
+  **Max sequence:** `2048`
+- **Chat template:** `gemma-3`, response markers `<start_of_turn>user\n` and
+  `<start_of_turn>model\n`
+- `save_strategy="no"` to avoid the known Unsloth/TRL checkpoint pickle bug
+- **Train/eval:** Modal H100 80GB GPU
+- **Deploy:** Hugging Face Space on ZeroGPU using Gradio, `transformers`,
+  `peft`, and 4-bit bitsandbytes NF4 runtime loading
+- **Data:** small, hand-curated, synthetic, and grounded in real ADHD friction,
+  not generic productivity tropes

-```bash
-source /media/haris-subrata/Work/llm/agent_analytics/venv/bin/activate
-python --version
-```
+## Results

-Install only lightweight local tooling here when needed. GPU-heavy training
-dependencies are owned by the Modal image in `train/modal_train.py`.
+Run #4 completed 102 training steps.

-Modal CLI notes are in `docs/modal_cli.md`.
-Retraining and evaluation steps are in `docs/retrain_runbook.md` and
-`docs/evaluation_plan.md`.
-Hugging Face deployment status is in `docs/hf_deployment_report.md`.
+- Train conversations: 270
+- Eval conversations: 30
+- Train loss: 1.7501
+- Eval loss: 1.8844

-## Data
+Generation eval over 8 held-out or novel prompts:

-Copy the upstream final dataset out-of-band:
+- Base persona average: 2.25 / 4
+- Fine-tuned persona average: 4.0 / 4
+- Base average words: 80.4
+- Fine-tuned average words: 55.1
+- Base label leaks: 5
+- Fine-tuned label leaks: 0

-```text
-data/train.jsonl
-data/eval.jsonl
-```
+The loss is only a weak diagnostic here. The important result is behavioral: the
+fine-tuned model became shorter, warmer, more consistent, and stopped leaking
+the internal recipe labels that the base model often exposed.

-Expected run #3 dataset:
+## Repository Map

-- `train.jsonl`: 270 conversations
-- `eval.jsonl`: 30 conversations
-- bilingual ID/EN
-- each row has `messages[]` with the official NeuroBait system prompt prepended
+- `train/`: Modal + Unsloth fine-tuning entrypoints
+- `eval/`: local and Modal generation evaluation scripts
+- `deploy/`: Hugging Face Space app source
+- `model-card/`: README used for the Hugging Face model repo
+- `docs/`: runbooks, deployment notes, and evaluation notes

-`data/` and `*.jsonl` are gitignored.
+The dataset and trained adapter artifacts are intentionally kept out of Git.

-## Training On Modal
+## Reproduce

-One-time setup:
+Install the Modal CLI, authenticate, and create a Hugging Face secret:

 ```bash
 pip install modal
@@ -79,94 +100,26 @@ modal token new
 modal secret create huggingface HF_TOKEN=hf_xxx
 ```

-Run training:
-
-```bash
-modal run train/modal_train.py
-```
-
-Remote preflight before paid training:
+Run a remote preflight:

 ```bash
 modal run train/modal_train.py --run-preflight --no-run-train
 ```

-Optional upload/merge:
+Train:

 ```bash
-modal run train/modal_train.py --no-run-train --push-lora
-modal run train/modal_train.py --no-run-train --push-space
-modal run train/modal_train.py --no-run-train --push-lora --merge
-```
-
-Locked training design:
-
-- Base: `unsloth/gemma-4-26b-a4b-it`
-- Method: 16-bit LoRA, not QLoRA
-- LoRA: `r=16`, `alpha=16`, `dropout=0`
-- Epochs: `3`
-- LR: `2e-4`
-- Batch: `1 x grad_accum 8`
-- Max sequence: `2048`
-- Chat template: `gemma-4`
-- Response markers: `<|turn>user\n` and `<|turn>model\n`
-- `save_strategy="no"` to avoid the known Unsloth/TRL checkpoint pickle bug
-
-Expected step count for 270 train examples:
-
-```text
-ceil(270 / 8) * 3 = 102
+modal run train/modal_train.py
 ```

-## Evaluation
-
-Local heuristic check:
+Push the LoRA adapter and Space:

 ```bash
-python eval/eval_neurobait.py data/eval.jsonl --output outputs/eval_reference.json
-python eval/make_report.py outputs/eval_reference.json
-```
-
-This is not a replacement for GPU qualitative eval. It gives a fast local check
-for label leaks, rough response length, and action-cue coverage. Run #3 must
-include separate English-transfer review on held-out EN examples.
-
-## HF Space
-
-`deploy/` is the source for the HF Space repo:
-
-```text
-deploy/app.py
-deploy/requirements.txt
-```
-
-The default Space app loads the LoRA adapter from:
-
-```text
-ADAPTER_ID=build-small-hackathon/NeuroBait
-BASE_MODEL=unsloth/gemma-4-26b-a4b-it
-LOAD_IN_4BIT=1
+modal run train/modal_train.py --no-run-train --push-lora
+modal run train/modal_train.py --no-run-train --push-space --set-hardware
 ```

-The Space uses Gradio and `@spaces.GPU`. Hardware must be chosen based on the
-final model format. The current deployment path uses 4-bit base loading plus the
-LoRA adapter, but it still needs direct testing on HF Space hardware because the
-base model is a 26B MoE model.
-
-## Repository Boundaries
-
-Commit to GitHub:
-
-- `train/`
-- `eval/`
-- `deploy/`
-- docs and diagrams
-
-Do not commit:
+## Safety Scope

-- dataset JSONL
-- LoRA adapters
-- merged models
-- GGUF files
-- generated eval outputs
-- tokens or `.env`
+NeuroBait is not a medical device, diagnostic tool, therapist, or emergency
+support system. It is a small-model demo for gentle task-initiation support.
diff --git a/deploy/README.md b/deploy/README.md
index e076dfa..aaaeb7d 100644
--- a/deploy/README.md
+++ b/deploy/README.md
@@ -6,41 +6,59 @@ sdk: gradio
 app_file: app.py
 pinned: false
 license: apache-2.0
-short_description: ADHD-friendly task initiation with one tiny next move.
+short_description: An ADHD-friendly space and gentle boost for your everyday.
 ---

 # NeuroBait

-NeuroBait is an ADHD-friendly task-initiation assistant. It is designed to help
-the user find one tiny next move without shame, streak pressure, or a full
-productivity lecture.
+NeuroBait is an ADHD-friendly companion for task initiation: a warm space and a
+gentle boost for the moment when starting feels heavier than the task itself.

-Target URL:
+It is built to avoid shame, streak pressure, and generic productivity advice.
+The app uses a fine-tuned small model, not an external LLM API.

-```text
-https://huggingface.co/spaces/build-small-hackathon/NeuroBait
-```
+## Build Small Hackathon

-This Space loads through Unsloth:
+- Primary track: **Backyard AI**
+- Bonus quest fit: **Well-Tuned**
+- Bonus quest fit: **Off-Brand**
+- Sponsor fit: **Modal-powered**

-- Base model: `unsloth/gemma-4-26b-a4b-it`
-- LoRA adapter: `build-small-hackathon/NeuroBait`
+NeuroBait was fine-tuned with Modal and deployed as a Gradio app on Hugging Face
+ZeroGPU.

-## Runtime
+## Model

-The default app path uses Unsloth 4-bit loading for the NeuroBait LoRA adapter.
-The `@spaces.GPU` call requests ZeroGPU `xlarge` with a 60-second function
-window because the model is a 26B MoE adapter stack.
+- Base model: `unsloth/gemma-3-12b-it`
+- Adapter: `build-small-hackathon/NeuroBait`
+- Method: 16-bit LoRA via Unsloth
+- Runtime: `transformers` + `peft`
+- Quantization: 4-bit bitsandbytes NF4 inside the `@spaces.GPU` window
+
+## Runtime

 Expected environment variables:

 ```text
-BASE_MODEL=unsloth/gemma-4-26b-a4b-it
+BASE_MODEL=unsloth/gemma-3-12b-it
 ADAPTER_ID=build-small-hackathon/NeuroBait
 LOAD_IN_4BIT=1
-MAX_NEW_TOKENS=160
-LOAD_AT_STARTUP=0
+MAX_NEW_TOKENS=220
+PREWARM=1
 ```

-If the base model requires authentication in the Space runtime, add `HF_TOKEN`
-as a Space secret.
+Weights are pre-warmed to the Space cache on CPU at import so the GPU window can
+focus on quantized loading and generation.
+
+## Interface
+
+The interface uses custom Gradio styling, dark earthy colors, anti-shame copy,
+and a simple mood check-in:
+
+- Calm
+- Tired
+- Anxious
+- Focused
+
+The mood choice lightly adapts the response style while keeping the same model
+and safety scope.
diff --git a/model-card/README.md b/model-card/README.md
index 00eb4f9..08aaaca 100644
--- a/model-card/README.md
+++ b/model-card/README.md
@@ -1,39 +1,63 @@
 ---
-base_model: unsloth/gemma-4-26b-a4b-it
+base_model: unsloth/gemma-3-12b-it
 library_name: peft
 pipeline_tag: text-generation
 tags:
   - lora
   - peft
-  - gemma-4
+  - gemma-3
   - adhd
   - neurodivergent
   - task-initiation
   - build-small-hackathon
+  - backyard-ai
+  - modal
+  - zerogpu
 license: other
 ---

 # NeuroBait

-NeuroBait is a LoRA fine-tune of `unsloth/gemma-4-26b-a4b-it` for ADHD and
-neurodivergent task-initiation conversations. It is designed to produce warm,
-short, agency-preserving prose that helps a user start one tiny next move
-without turning the conversation into a full to-do list.
+NeuroBait is a LoRA fine-tune of `unsloth/gemma-3-12b-it` for ADHD and
+neurodivergent task-initiation conversations.

-This repo contains the LoRA adapter, tokenizer files, chat template, and the
-training summary for run #3. It is intended to be used by the Gradio Space:
+It is designed for the moment when a person knows what they need to do, but the
+first move still feels too heavy. The model aims to respond with warm, short,
+agency-preserving language rather than shame, pressure, or a generic productivity
+script.
+
+Try the live Gradio app:

 ```text
 https://huggingface.co/spaces/build-small-hackathon/NeuroBait
 ```

+## Build Small Hackathon Submission
+
+NeuroBait is submitted for the Build Small Hackathon.
+
+- Primary track: **Backyard AI**
+- Why this track: NeuroBait focuses on a specific, real, everyday problem -
+  ADHD task initiation - and turns a small model into a practical companion for
+  that moment.
+- Bonus quest fit: **Well-Tuned**, because this repo publishes the fine-tuned
+  LoRA adapter used by the Space.
+- Bonus quest fit: **Off-Brand**, because the app uses custom Gradio UI and
+  anti-shame product copy rather than a default chatbot shell.
+- Sponsor fit: **Modal-powered**, because fine-tuning and generation evaluation
+  were run on Modal GPU infrastructure.
+
+The project follows the hackathon shape: fine-tune a small-enough open model,
+publish the model on Hugging Face, and deploy a working Gradio app as a Hugging
+Face Space.
+
 ## Intended Behavior

 NeuroBait should:

 - respond in short, natural prose,
 - avoid visible labels such as `Micro-action`, `Hook`, or `Stakes`,
-- avoid guilt framing,
+- avoid guilt framing and productivity shame,
 - preserve user agency,
 - ask one light question when context is too sparse,
 - offer one tiny concrete action when enough context exists.
@@ -43,19 +67,19 @@ support system, or replacement for professional care.

 ## Training Data

-Run #3 used a bilingual Indonesian/English conversational dataset:
+Run #4 used a bilingual Indonesian/English conversational dataset:

 - 270 train conversations
 - 30 eval conversations
 - multi-turn `messages[]` format
 - official NeuroBait system prompt prepended to each example

-The dataset is not included in this model repo.
+The dataset is intentionally not included in this model repo.

 ## Training Configuration

-- Base: `unsloth/gemma-4-26b-a4b-it`
-- Method: 16-bit LoRA
+- Base: `unsloth/gemma-3-12b-it` (dense Gemma 3 12B)
+- Method: 16-bit LoRA, not QLoRA, via Unsloth
 - LoRA rank: 16
 - LoRA alpha: 16
 - LoRA dropout: 0
@@ -68,12 +92,30 @@ The dataset is not included in this model repo.
 - Warmup ratio: 0.05
 - Optimizer: adamw 8-bit
 - Precision: bf16
-- Chat template: `gemma-4`
-- Response-only markers: `<|turn>user\n` / `<|turn>model\n`
+- Chat template: `gemma-3`
+- Response-only markers: `<start_of_turn>user\n` / `<start_of_turn>model\n`
+- Checkpoints: `save_strategy="no"` to avoid the known Unsloth/TRL checkpoint
+  pickle issue

 Training ran on Modal with an H100 80GB GPU.

-## Run #3 Results
+## Deployment
+
+The deployed Space runs on Hugging Face ZeroGPU.
+
+Runtime path:
+
+- Gradio Space
+- `transformers` + `peft`
+- 4-bit bitsandbytes NF4 loading
+- base model: `unsloth/gemma-3-12b-it`
+- LoRA adapter: `build-small-hackathon/NeuroBait`
+
+Unsloth is used for training, not for Space inference. The dense Gemma 3 12B base
+was chosen because it deploys cleanly through the standard
+`transformers` + `peft` path on ZeroGPU.
+
+## Run #4 Results

 Training completed 102 steps.

@@ -81,27 +123,27 @@ Training summary:

 - train conversations: 270
 - eval conversations: 30
-- train loss: 0.242
-- final `trainer.evaluate()` loss: 2.4044
+- train loss: 1.7501
+- eval loss: 1.8844

 The loss signal should be treated as a weak training diagnostic for this project.
 NeuroBait is primarily evaluated through generated behavior against the base
 model.

-Generation eval summary over 8 held-out/novel prompts:
+Generation eval summary over 8 held-out or novel prompts:

-- base persona average: 3.625 / 4
+- base persona average: 2.25 / 4
 - fine-tuned persona average: 4.0 / 4
-- base average words: 72.0
-- fine-tuned average words: 56.625
-- base label leaks: 1
+- base average words: 80.4
+- fine-tuned average words: 55.1
+- base label leaks: 5
 - fine-tuned label leaks: 0
-- base action-cue responses: 3
-- fine-tuned action-cue responses: 5
+- base action-cue responses: 5
+- fine-tuned action-cue responses: 4

 Qualitatively, the fine-tuned adapter produced shorter, more conversational
-responses, maintained English on English prompts more reliably than the base
-model in this sample, and avoided literal structure labels in the tested turns.
+responses and did not leak literal structure labels, while the base model leaked
+labels in 5 of 8 prompts.

 ## Loading

@@ -109,14 +151,14 @@ Example adapter loading path:

 ```python
 from peft import PeftModel
-from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
+from transformers import AutoModelForImageTextToText, AutoTokenizer, BitsAndBytesConfig
 import torch

-base_model = "unsloth/gemma-4-26b-a4b-it"
+base_model = "unsloth/gemma-3-12b-it"
 adapter_id = "build-small-hackathon/NeuroBait"

 tokenizer = AutoTokenizer.from_pretrained(adapter_id)
-model = AutoModelForCausalLM.from_pretrained(
+model = AutoModelForImageTextToText.from_pretrained(
     base_model,
     quantization_config=BitsAndBytesConfig(
         load_in_4bit=True,
@@ -132,15 +174,17 @@ model.eval()
 ## Limitations

 - The model is not a medical or crisis-support system.
-- It may ask for a motivator or deadline when the user has already implied one.
-- It may still be too brief or too playful for some users.
+- It may still ask a clarifying question when the user expected a direct nudge.
+- It may be too brief, too playful, or too gentle for some contexts.
 - Long-term personalization should be handled by product logic, not only by the
   model.
 - App-initiated reminders should be handled by the app layer, not generated
   spontaneously by the model.

-## Submission Context
+## Source

-This model is part of the Build Small Model Hackathon submission for NeuroBait.
-The public GitHub source repo tracks training, evaluation, deployment scaffolding,
-and agent development notes.
+Public source repo:
+
+```text
+https://github.com/Subrata15/NeuroBait-Build-Small-Model
+```


README change sudah siap secara lokal. Karena workspace ini memakai `.git-local`, saya cek dulu apakah `.git` hanya stub/read-only atau bisa diarahkan agar commit/push tetap bersih tanpa menyentuh perubahan lain.


git --git-dir=.git-local --work-tree=. branch --show-current


git --git-dir=.git-local --work-tree=. log --oneline -5


Output:
Chunk ID: c0c397
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 258
Output:
.git:
total 4
dr-xr-xr-x  2 haris-subrata haris-subrata   40 Jun  9 16:19 .
drwxrwxr-x 17 haris-subrata haris-subrata 4096 Jun  9 16:18 ..

.git-local:
total 52
drwxrwxr-x  8 haris-subrata haris-subrata 4096 Jun  9 16:19 .
drwxrwxr-x 17 haris-subrata haris-subrata 4096 Jun  9 16:18 ..
-rw-rw-r--  1 haris-subrata haris-subrata   88 Jun  8 22:57 COMMIT_EDITMSG
-rw-rw-r--  1 haris-subrata haris-subrata   21 Jun  8 17:38 HEAD
drwxrwxr-x  2 haris-subrata haris-subrata 4096 Jun  8 17:38 branches
-rw-rw-r--  1 haris-subrata haris-subrata  351 Jun  8 17:39 config
-rw-rw-r--  1 haris-subrata haris-subrata   73 Jun  8 17:38 description
drwxrwxr-x  2 haris-subrata haris-subrata 4096 Jun  8 17:38 hooks
-rw-rw-r--  1 haris-subrata haris-subrata 1724 Jun  8 22:57 index
drwxrwxr-x  2 haris-subrata haris-subrata 4096 Jun  8 17:38 info
drwxrwxr-x  3 haris-subrata haris-subrata 4096 Jun  8 17:38 logs
drwxrwxr-x 58 haris-subrata haris-subrata 4096 Jun  8 22:57 objects
drwxrwxr-x  5 haris-subrata haris-subrata 4096 Jun  8 17:39 refs


Output:
Chunk ID: 379e8d
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2
Output:
main


Output:
Chunk ID: e4bb84
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 56
Output:
e00c629 Publish NeuroBait HF model and Space scaffold
7daf849 Add Modal generation evaluation
0d018db Add retrain and evaluation runbooks
d99d8d2 Fix Modal preflight serialization
b6b0b1e Document local storage constraints


Saya akan commit hanya tiga README yang saya ubah (`README.md`, `model-card/README.md`, `deploy/README.md`) supaya perubahan lain yang sudah kamu buat tetap tidak ikut terseret. Setelah itu saya push ke GitHub, lalu push README HF model/Space lewat entrypoint Modal yang sudah ada.


git --git-dir=.git-local --work-tree=. add README.md model-card/README.md deploy/README.md


Output:
Chunk ID: a93712
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


git --git-dir=.git-local --work-tree=. diff --cached --stat


git --git-dir=.git-local --work-tree=. status --short


Output:
Chunk ID: 88550f
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 59
Output:
 README.md            | 207 ++++++++++++++++++++-------------------------------
 deploy/README.md     |  58 ++++++++++-----
 model-card/README.md | 116 ++++++++++++++++++++---------
 3 files changed, 198 insertions(+), 183 deletions(-)


Output:
Chunk ID: 8e92ad
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 50
Output:
M  README.md
M  deploy/README.md
 M deploy/app.py
 M deploy/requirements.txt
 M eval/modal_generation_eval.py
M  model-card/README.md
 M train/modal_train.py
 M train/train_core.py
?? deploy/ui.py


Staging bersih: hanya tiga README yang masuk commit. Perubahan kode lain tetap unstaged seperti keadaan semula.


git --git-dir=.git-local --work-tree=. commit -m "Refresh public NeuroBait README docs"


Output:
Chunk ID: eb0f88
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 41
Output:
[main 14119fd] Refresh public NeuroBait README docs
 3 files changed, 269 insertions(+), 254 deletions(-)
 rewrite README.md (90%)
 rewrite deploy/README.md (76%)


Commit lokal selesai. Saya akan push commit README ke GitHub sekarang; ini butuh akses network ke GitHub.


git --git-dir=.git-local --work-tree=. push origin main

Do you want to push the README commit to the GitHub repository?


Output:
Chunk ID: d85707
Wall time: 1.6702 seconds
Process exited with code 0
Original token count: 25
Output:
To https://github.com/Subrata15/NeuroBait-Build-Small-Model.git
   e00c629..14119fd  main -> main


GitHub sudah ter-push ke `main`. Untuk Hugging Face, saya cek dulu opsi CLI di `train/modal_train.py` supaya tidak salah panggil push model-card dan Space README.


Output:
Chunk ID: c282d6
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 992
Output:
    timeout=10 * 60,
    secrets=[modal.Secret.from_name("huggingface")],
)
def get_space_runtime(repo_id: str = DEFAULT_SPACE_REPO) -> str:
    import json

    from huggingface_hub import HfApi

    runtime = HfApi().get_space_runtime(repo_id=repo_id)
    return json.dumps(
        {
            "repo_id": repo_id,
            "stage": getattr(runtime, "stage", None),
            "hardware": getattr(runtime, "hardware", None),
            "requested_hardware": getattr(runtime, "requested_hardware", None),
            "sleep_time": getattr(runtime, "sleep_time", None),
            "raw": getattr(runtime, "raw", None),
        },
        indent=2,
        default=str,
    )

@app.function(
    image=image,
    timeout=10 * 60,
    secrets=[modal.Secret.from_name("huggingface")],
)
def get_space_logs(repo_id: str = DEFAULT_SPACE_REPO) -> str:
    import os

    import requests

    token = os.environ["HF_TOKEN"]
    out = []
    for kind in ("run", "build"):
        try:
            response = requests.get(
                f"https://huggingface.co/api/spaces/{repo_id}/logs/{kind}",
                headers={"Authorization": f"Bearer {token}"},
                timeout=60,
                stream=True,
            )
            text = "".join(chunk for chunk in response.iter_content(chunk_size=None, decode_unicode=True))
            out.append(f"===== {kind} logs (HTTP {response.status_code}) =====\n{text[-9000:]}")
        except Exception as exc:  # noqa: BLE001
            out.append(f"===== {kind} logs error: {exc} =====")
    return "\n\n".join(out)

@app.function(
    image=image,
    gpu="H100",
    timeout=60 * 60,
    volumes={"/root/.cache/huggingface": hf_cache, "/out": out_vol},
    secrets=[modal.Secret.from_name("huggingface")],
)
def merge_and_push(repo_id: str = DEFAULT_MERGED_REPO) -> str:
    import os

    os.environ["HF_HOME"] = "/root/.cache/huggingface"

    from unsloth import FastModel
    from unsloth.chat_templates import get_chat_template
    from huggingface_hub import HfApi

    base_model = os.environ.get("BASE_MODEL", BASE_MODEL)
    adapter_path = os.environ.get("OUT_ADAPTER", ADAPTER_DIR)
    merged_path = "/out/merged-neurobait-gemma3-12b"

    model, tokenizer = FastModel.from_pretrained(
        model_name=adapter_path,
        max_seq_length=2048,
        load_in_4bit=False,
        load_in_16bit=True,
        full_finetuning=False,
    )
    tokenizer = get_chat_template(tokenizer, chat_template="gemma-3")
    model.save_pretrained_merged(merged_path, tokenizer, save_method="merged_16bit")

    HfApi().upload_folder(folder_path=merged_path, repo_id=repo_id, repo_type="model")
    out_vol.commit()
    return repo_id

@app.local_entrypoint()
def main(
    run_preflight: bool = False,
    run_train: bool = True,
    push_lora: bool = False,
    push_space: bool = False,
    check_space: bool = False,
    check_logs: bool = False,
    set_hardware: bool = False,
    restart: bool = False,
    factory: bool = False,
    hardware: str = "zero-a10g",
    merge: bool = False,
    lora_repo: str = DEFAULT_LORA_REPO,
    space_repo: str = DEFAULT_SPACE_REPO,
    merged_repo: str = DEFAULT_MERGED_REPO,
) -> None:
    if run_preflight:
        print("preflight:", preflight.remote())
    if run_train:
        summary = train.remote()
        print("train:", summary)
    if push_lora:
        print("lora repo:", push_lora_to_hub.remote(lora_repo))
    if push_space:
        print("space repo:", push_space_to_hub.remote(space_repo))
    if set_hardware:
        print("space hardware:", set_space_hardware.remote(space_repo, hardware))
    if restart:
        print("space restart:", restart_space.remote(space_repo, factory))
    if check_space:
        print("space runtime:", get_space_runtime.remote(space_repo))
    if check_logs:
        print("space logs:", get_space_logs.remote(space_repo))
    if merge:
        print("merged repo:", merge_and_push.remote(merged_repo))


HF push akan memakai entrypoint Modal yang sudah ada: `--push-lora` untuk update model-card di model repo, dan `--push-space --set-hardware` untuk update Space README serta memastikan ZeroGPU tetap diminta.


/media/haris-subrata/Work/llm/agent_analytics/venv/bin/python -m modal run train/modal_train.py --no-run-train --push-lora --push-space --set-hardware

Do you want to push the updated Hugging Face model card and Space README via Modal?


Output:
Chunk ID: 407f04
Wall time: 21.5893 seconds
Process exited with code 0
Original token count: 814
Output:
✓ Initialized. View run at
https://modal.com/apps/harisabektidsubrata/main/ap-ZYZE7P4HG4ns0r8sinunb3
✓ Created objects.
├── 🔨 Created mount
│   /media/haris-subrata/Work/llm/NeuroBait-Build-Small-Model/train/modal_train.
│   py
├── 🔨 Created mount
│   /media/haris-subrata/Work/llm/NeuroBait-Build-Small-Model/deploy
├── 🔨 Created mount model-card/README.md
├── 🔨 Created mount data/eval.jsonl
├── 🔨 Created mount data/train.jsonl
├── 🔨 Created mount train/train_core.py
├── 🔨 Created function preflight.
├── 🔨 Created function train.
├── 🔨 Created function push_lora_to_hub.
├── 🔨 Created function push_space_to_hub.
├── 🔨 Created function set_space_hardware.
├── 🔨 Created function restart_space.
├── 🔨 Created function get_space_runtime.
├── 🔨 Created function get_space_logs.
└── 🔨 Created function merge_and_push.

Processing Files (0 / 0)      : |          |  0.00B /  0.00B

New Data Upload               : |          |  0.00B /  0.00B

  ...t-lora-12b/tokenizer.json: 100%|██████████| 33.4MB / 33.4MB

  ...adapter_model.safetensors: 100%|██████████|  137MB /  137MB

  ...-lora-12b/tokenizer.model: 100%|██████████| 4.69MB / 4.69MB

  ...t-lora-12b/tokenizer.json: 100%|██████████| 33.4MB / 33.4MB

  ...adapter_model.safetensors: 100%|██████████|  137MB /  137MB

  ...-lora-12b/tokenizer.model: 100%|██████████| 4.69MB / 4.69MB
Processing Files (3 / 3)      : 100%|██████████|  175MB /  175MB,   ???B/s
Processing Files (3 / 3)      : 100%|██████████|  175MB /  175MB,   ???B/s

New Data Upload               : |          |  0.00B /  0.00B,   ???B/s

  ...t-lora-12b/tokenizer.json: 100%|██████████| 33.4MB / 33.4MB

  ...adapter_model.safetensors: 100%|██████████|  137MB /  137MB

  ...-lora-12b/tokenizer.model: 100%|██████████| 4.69MB / 4.69MB
lora repo: build-small-hackathon/NeuroBait
space repo: build-small-hackathon/NeuroBait
space hardware: {
  "repo_id": "build-small-hackathon/NeuroBait",
  "requested": "zero-a10g",
  "stage": "RUNNING_BUILDING",
  "hardware": "zero-a10g",
  "requested_hardware": "zero-a10g",
  "raw": {
    "stage": "RUNNING_BUILDING",
    "hardware": {
      "current": "zero-a10g",
      "requested": "zero-a10g"
    },
    "gcTimeout": 172800,
    "replicas": {
      "current": 1,
      "requested": 1
    },
    "devMode": false,
    "domains": [
      {
        "domain": "build-small-hackathon-neurobait.hf.space",
        "stage": "READY"
      }
    ],
    "sha": "c8c1166f45a2001fab1f34980109894c95d7585c"
  }
}
Stopping app - local entrypoint completed.
✓ App completed. View run at
https://modal.com/apps/harisabektidsubrata/main/ap-ZYZE7P4HG4ns0r8sinunb3


Push HF selesai; Space masuk `RUNNING_BUILDING` dengan hardware `zero-a10g`, jadi README sudah dikirim dan build sedang memproses versi baru. Saya lakukan verifikasi ringan lewat endpoint publik/raw kalau tersedia.


Output:
Chunk ID: 27c0d6
Wall time: 0.3772 seconds
Process exited with code 0
Original token count: 1347
Output:
---
base_model: unsloth/gemma-3-12b-it
library_name: peft
pipeline_tag: text-generation
tags:
  - lora
  - peft
  - gemma-3
  - adhd
  - neurodivergent
  - task-initiation
  - build-small-hackathon
  - backyard-ai
  - modal
  - zerogpu
license: other
---

# NeuroBait

NeuroBait is a LoRA fine-tune of `unsloth/gemma-3-12b-it` for ADHD and
neurodivergent task-initiation conversations.

It is designed for the moment when a person knows what they need to do, but the
first move still feels too heavy. The model aims to respond with warm, short,
agency-preserving language rather than shame, pressure, or a generic productivity
script.

Try the live Gradio app:

```text
https://huggingface.co/spaces/build-small-hackathon/NeuroBait
```

## Build Small Hackathon Submission

NeuroBait is submitted for the Build Small Hackathon.

- Primary track: **Backyard AI**
- Why this track: NeuroBait focuses on a specific, real, everyday problem -
  ADHD task initiation - and turns a small model into a practical companion for
  that moment.
- Bonus quest fit: **Well-Tuned**, because this repo publishes the fine-tuned
  LoRA adapter used by the Space.
- Bonus quest fit: **Off-Brand**, because the app uses custom Gradio UI and
  anti-shame product copy rather than a default chatbot shell.
- Sponsor fit: **Modal-powered**, because fine-tuning and generation evaluation
  were run on Modal GPU infrastructure.

The project follows the hackathon shape: fine-tune a small-enough open model,
publish the model on Hugging Face, and deploy a working Gradio app as a Hugging
Face Space.

## Intended Behavior

NeuroBait should:

- respond in short, natural prose,
- avoid visible labels such as `Micro-action`, `Hook`, or `Stakes`,
- avoid guilt framing and productivity shame,
- preserve user agency,
- ask one light question when context is too sparse,
- offer one tiny concrete action when enough context exists.

It should not act as a medical device, diagnostic tool, therapist, emergency
support system, or replacement for professional care.

## Training Data

Run #4 used a bilingual Indonesian/English conversational dataset:

- 270 train conversations
- 30 eval conversations
- multi-turn `messages[]` format
- official NeuroBait system prompt prepended to each example

The dataset is intentionally not included in this model repo.

## Training Configuration

- Base: `unsloth/gemma-3-12b-it` (dense Gemma 3 12B)
- Method: 16-bit LoRA, not QLoRA, via Unsloth
- LoRA rank: 16
- LoRA alpha: 16
- LoRA dropout: 0
- Target modules: q/k/v/o/gate/up/down projections
- Epochs: 3
- Learning rate: 2e-4
- Effective batch size: 8
- Max sequence length: 2048
- Scheduler: cosine
- Warmup ratio: 0.05
- Optimizer: adamw 8-bit
- Precision: bf16
- Chat template: `gemma-3`
- Response-only markers: `<start_of_turn>user\n` / `<start_of_turn>model\n`
- Checkpoints: `save_strategy="no"` to avoid the known Unsloth/TRL checkpoint
  pickle issue

Training ran on Modal with an H100 80GB GPU.

## Deployment

The deployed Space runs on Hugging Face ZeroGPU.

Runtime path:

- Gradio Space
- `transformers` + `peft`
- 4-bit bitsandbytes NF4 loading
- base model: `unsloth/gemma-3-12b-it`
- LoRA adapter: `build-small-hackathon/NeuroBait`

Unsloth is used for training, not for Space inference. The dense Gemma 3 12B base
was chosen because it deploys cleanly through the standard
`transformers` + `peft` path on ZeroGPU.

## Run #4 Results

Training completed 102 steps.

Training summary:

- train conversations: 270
- eval conversations: 30
- train loss: 1.7501
- eval loss: 1.8844

The loss signal should be treated as a weak training diagnostic for this project.
NeuroBait is primarily evaluated through generated behavior against the base
model.

Generation eval summary over 8 held-out or novel prompts:

- base persona average: 2.25 / 4
- fine-tuned persona average: 4.0 / 4
- base average words: 80.4
- fine-tuned average words: 55.1
- base label leaks: 5
- fine-tuned label leaks: 0
- base action-cue responses: 5
- fine-tuned action-cue responses: 4

Qualitatively, the fine-tuned adapter produced shorter, more conversational
responses and did not leak literal structure labels, while the base model leaked
labels in 5 of 8 prompts.

## Loading

Example adapter loading path:

```python
from peft import PeftModel
from transformers import AutoModelForImageTextToText, AutoTokenizer, BitsAndBytesConfig
import torch

base_model = "unsloth/gemma-3-12b-it"
adapter_id = "build-small-hackathon/NeuroBait"

tokenizer = AutoTokenizer.from_pretrained(adapter_id)
model = AutoModelForImageTextToText.from_pretrained(
    base_model,
    quantization_config=BitsAndBytesConfig(
        load_in_4bit=True,
        bnb_4bit_compute_dtype=torch.bfloat16,
        bnb_4bit_quant_type="nf4",
    ),
    device_map="auto",
)
model = PeftModel.from_pretrained(model, adapter_id)
model.eval()
```

## Limitations

- The model is not a medical or crisis-support system.
- It may still ask a clarifying question when the user expected a direct nudge.
- It may be too brief, too playful, or too gentle for some contexts.
- Long-term personalization should be handled by product logic, not only by the
  model.
- App-initiated reminders should be handled by the app layer, not generated
  spontaneously by the model.

## Source

Public source repo:

```text
https://github.com/Subrata15/NeuroBait-Build-Small-Model
```


Output:
Chunk ID: 999b08
Wall time: 0.3752 seconds
Process exited with code 0
Original token count: 390
Output:
---
title: NeuroBait
colorFrom: green
colorTo: blue
sdk: gradio
app_file: app.py
pinned: false
license: apache-2.0
short_description: An ADHD-friendly space and gentle boost for your everyday.
---

# NeuroBait

NeuroBait is an ADHD-friendly companion for task initiation: a warm space and a
gentle boost for the moment when starting feels heavier than the task itself.

It is built to avoid shame, streak pressure, and generic productivity advice.
The app uses a fine-tuned small model, not an external LLM API.

## Build Small Hackathon

- Primary track: **Backyard AI**
- Bonus quest fit: **Well-Tuned**
- Bonus quest fit: **Off-Brand**
- Sponsor fit: **Modal-powered**

NeuroBait was fine-tuned with Modal and deployed as a Gradio app on Hugging Face
ZeroGPU.

## Model

- Base model: `unsloth/gemma-3-12b-it`
- Adapter: `build-small-hackathon/NeuroBait`
- Method: 16-bit LoRA via Unsloth
- Runtime: `transformers` + `peft`
- Quantization: 4-bit bitsandbytes NF4 inside the `@spaces.GPU` window

## Runtime

Expected environment variables:

```text
BASE_MODEL=unsloth/gemma-3-12b-it
ADAPTER_ID=build-small-hackathon/NeuroBait
LOAD_IN_4BIT=1
MAX_NEW_TOKENS=220
PREWARM=1
```

Weights are pre-warmed to the Space cache on CPU at import so the GPU window can
focus on quantized loading and generation.

## Interface

The interface uses custom Gradio styling, dark earthy colors, anti-shame copy,
and a simple mood check-in:

- Calm
- Tired
- Anxious
- Focused

The mood choice lightly adapts the response style while keeping the same model
and safety scope.


Output:
Chunk ID: 9e1208
Wall time: 0.4491 seconds
Process exited with code 0
Original token count: 1024
Output:
# NeuroBait

NeuroBait is an ADHD-friendly AI companion for task initiation. It is built for
the moment when a task is not intellectually hard, but still feels impossible to
start.

Instead of turning that friction into a productivity lecture, NeuroBait responds
with short, warm, agency-preserving language. It avoids shame, streak pressure,
diagnosis-like framing, and visible prompt labels such as `Micro-action`, `Hook`,
or `Stakes`.

## Live Demo

- Hugging Face Space: https://huggingface.co/spaces/build-small-hackathon/NeuroBait
- Model adapter: https://huggingface.co/build-small-hackathon/NeuroBait

## Hackathon Submission

NeuroBait is a Build Small Hackathon submission.

- Primary track: **Backyard AI**
- Why: the app is designed around a real everyday ADHD friction - starting the
  thing that already matters - rather than a generic chatbot or productivity
  template.
- Bonus quest fit: **Well-Tuned**, because NeuroBait uses a fine-tuned model
  published on Hugging Face.
- Bonus quest fit: **Off-Brand**, because the Space uses a custom Gradio
  interface instead of the default app look.
- Sponsor fit: **Modal-powered**, because fine-tuning and generation eval were
  run on Modal GPU infrastructure.

## What We Built

The model is a LoRA fine-tune of `unsloth/gemma-3-12b-it`, trained on a small
hand-curated bilingual Indonesian/English dataset built from real ADHD task
initiation friction.

The main lesson was simple: for a voice and behavior layer, dataset quality beat
model size. The fine-tune is intentionally narrow. It is not trying to become a
general therapist, planner, or productivity operating system.

## The Stack

A real model, trained on a real budget:

- **Base:** `unsloth/gemma-3-12b-it` (dense Gemma 3 12B,
  `Gemma3ForConditionalGeneration`)
- **Method:** 16-bit LoRA, not QLoRA, via Unsloth
- **LoRA:** `r=16`, `alpha=16`, `dropout=0`
- **Epochs:** `3` | **LR:** `2e-4` | **Batch:** `1 x grad_accum 8` |
  **Max sequence:** `2048`
- **Chat template:** `gemma-3`, response markers `<start_of_turn>user\n` and
  `<start_of_turn>model\n`
- `save_strategy="no"` to avoid the known Unsloth/TRL checkpoint pickle bug
- **Train/eval:** Modal H100 80GB GPU
- **Deploy:** Hugging Face Space on ZeroGPU using Gradio, `transformers`,
  `peft`, and 4-bit bitsandbytes NF4 runtime loading
- **Data:** small, hand-curated, synthetic, and grounded in real ADHD friction,
  not generic productivity tropes

## Results

Run #4 completed 102 training steps.

- Train conversations: 270
- Eval conversations: 30
- Train loss: 1.7501
- Eval loss: 1.8844

Generation eval over 8 held-out or novel prompts:

- Base persona average: 2.25 / 4
- Fine-tuned persona average: 4.0 / 4
- Base average words: 80.4
- Fine-tuned average words: 55.1
- Base label leaks: 5
- Fine-tuned label leaks: 0

The loss is only a weak diagnostic here. The important result is behavioral: the
fine-tuned model became shorter, warmer, more consistent, and stopped leaking
the internal recipe labels that the base model often exposed.

## Repository Map

- `train/`: Modal + Unsloth fine-tuning entrypoints
- `eval/`: local and Modal generation evaluation scripts
- `deploy/`: Hugging Face Space app source
- `model-card/`: README used for the Hugging Face model repo
- `docs/`: runbooks, deployment notes, and evaluation notes

The dataset and trained adapter artifacts are intentionally kept out of Git.

## Reproduce

Install the Modal CLI, authenticate, and create a Hugging Face secret:

```bash
pip install modal
modal token new
modal secret create huggingface HF_TOKEN=hf_xxx
```

Run a remote preflight:

```bash
modal run train/modal_train.py --run-preflight --no-run-train
```

Train:

```bash
modal run train/modal_train.py
```

Push the LoRA adapter and Space:

```bash
modal run train/modal_train.py --no-run-train --push-lora
modal run train/modal_train.py --no-run-train --push-space --set-hardware
```

## Safety Scope

NeuroBait is not a medical device, diagnostic tool, therapist, or emergency
support system. It is a small-model demo for gentle task-initiation support.


Verifikasi raw publik berhasil untuk ketiganya: GitHub README, HF model README, dan HF Space README sudah menampilkan versi baru. Saya cek status akhir lokal supaya final-nya jelas.


Output:
Chunk ID: 5de022
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 35
Output:
 M deploy/app.py
 M deploy/requirements.txt
 M eval/modal_generation_eval.py
 M train/modal_train.py
 M train/train_core.py
?? deploy/ui.py


Done.

Updated and pushed:
- GitHub README: https://github.com/Subrata15/NeuroBait-Build-Small-Model
- HF model README/model card: https://huggingface.co/build-small-hackathon/NeuroBait
- HF Space README: https://huggingface.co/spaces/build-small-hackathon/NeuroBait

I committed only the README changes:
`14119fd Refresh public NeuroBait README docs`

HF push also completed through Modal. The Space hardware request returned `zero-a10g` and stage `RUNNING_BUILDING`, so HF has the new files and is rebuilding.

I included the public-facing submission framing:
- Primary track: `Backyard AI`
- Bonus fit: `Well-Tuned`
- Bonus fit: `Off-Brand`
- Sponsor fit: `Modal-powered`
- Explicit mention that fine-tuning/eval used Modal and deployment uses Hugging Face ZeroGPU

Reference used for the category wording: https://huggingface.co/build-small-hackathon

Note: local worktree still has your non-README changes unstaged, untouched by my commit.


# Collaboration Mode: Default

You are now in Default mode. Any previous instructions for other modes (e.g. Plan mode) are no longer active.

Your active mode changes only when new developer instructions with a different `<collaboration_mode>...</collaboration_mode>` change it; user requests or tool descriptions do not change mode by themselves. Known mode names are Default and Plan.

## request_user_input availability

Use the `request_user_input` tool only when it is listed in the available tools for this turn.

In Default mode, strongly prefer making reasonable assumptions and executing the user's request rather than stopping to ask questions. If you absolutely must ask a question because the answer cannot be discovered from local context and a reasonable assumption would be risky, ask the user directly with a concise plain-text question. Never write a multiple choice question as a textual assistant message.

Summary: auto


ok good. next saya akan buat sosial media post dan link sosial media post akan di attach di readme submission. notes dulu saja as place holder di log dev ya


Saya akan tambahkan catatan placeholder di `local-dev/log_dev.md` saja, karena itu memang local-only dev log dan tidak perlu ikut commit publik sekarang.


Output:
Chunk ID: 1e4c75
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1058
Output:
- `gr.Chatbot` still has NO `type=` (see [[verify-pinned-api]]).

Visual re-check still PENDING on user (hard-refresh to bust cached CSS).

## Run #4 Generation Eval + Model Card - 2026-06-09

Ran `modal run eval/modal_generation_eval.py` (adapter default `/out/neurobait-lora-12b`).

Eval-script fix needed for Gemma 3: the `app_cont_id` / `app_cont_en` prompts were
`[system, assistant, user]`. Gemma 3's chat template requires user-first strict
alternation (gemma-4's was looser), so it raised
`TemplateError: Conversation roles must alternate user/assistant/...`. Fixed by
prepending a user "(opens NeuroBait)" / "(buka NeuroBait)" turn — a faithful
framing of the proactive opener (app opener = assistant reply to the user opening
the app). Also renamed the report outputs `run3_*` -> `run4_*`.

Run #4 results (n=8 prompts, base vs fine-tuned):

```text
base_persona_avg: 2.25   ft_persona_avg: 4.0   (ft perfect 4/4 on every prompt)
base_words_avg: 80.4     ft_words_avg: 55.1
base_label_leaks: 5      ft_label_leaks: 0
base_actions: 5          ft_actions: 4
```

Strong result: FT scored perfect persona, zero label leaks (base leaked
Micro-action/Hook/Stakes in 5/8), and is shorter/more conversational. Reports
downloaded to `outputs/run4_generation_eval.{json,md}` (from Modal volume
`neurobait-out`, path `outputs/`).

`model-card/README.md` updated to run #4 numbers (train_loss 1.7501, eval_loss
1.8844; the generation-eval table above) and re-pushed to HF model repo via
`modal run train/modal_train.py --no-run-train --push-lora` (adapter file
unchanged → effectively just the README commit). Card at
https://huggingface.co/build-small-hackathon/NeuroBait now current.

REMAINING: user visual re-check of the dark-only UI (hard-refresh). Optional:
local heuristic reference eval (`eval/eval_neurobait.py`) is dataset-only stats
(unchanged 270/30 data) so it would match run #3 — skipped as not run-specific.

## UI Rewrite -> Hybrid ChatInterface - 2026-06-09

User asked to move toward a standard modern AI-chat UI (DeepSeek/Perplexity-like)
but keep NeuroBait's identity = HYBRID (chosen over full-generic / keep-custom).

Verified gradio 6.17.3 API first (lesson from the `type=` crash, [[verify-pinned-api]]):
- `gr.ChatInterface.__init__` HAS `save_history`, `additional_inputs`,
  `chatbot`, `examples`, `title`, `description`, `fill_height`, `autoscroll`,
  `stop_btn`, `multimodal`, `cache_examples`. It does NOT have `type`, `theme`,
  `css`, `js`.
- `Blocks.launch` HAS `theme`, `css`, `js`, `head` — so theme/css go on
  `demo.launch(...)` now (matches the Gradio 6 deprecation warning).
- `gr.Chatbot` HAS `placeholder` (empty-state greeting), no `type`.

`deploy/ui.py` rewritten: `build_demo` returns a `gr.ChatInterface` with a custom
`gr.Chatbot` (placeholder greeting), mood `gr.Radio` as `additional_inputs`
(accordion open), title/description carrying NeuroBait voice, 3 gentle example
openers, `save_history=True` (DeepSeek-style conversation sidebar),
`cache_examples=False` (so examples don't invoke the model at build),
`fill_height`, `autoscroll`. Dark earthy sage-teal CSS kept (palette on `:root`
+ unconditional Gradio core-var mapping). Verified it CONSTRUCTS locally with a
stub fn before pushing.

`deploy/app.py`: `respond` is now a STREAMING generator (`TextIteratorStreamer` +
a background `Thread` running `model.generate` under `torch.inference_mode()`),
signature `(message, history, mood)` — the temperature/top_p sliders were dropped
(mood-only). `demo.launch(show_error=True, css=CSS, theme=THEME)` (HF runs the
`__main__` launch, so these apply).

Pushed -> stage RUNNING, run-log shows `Running on local URL ... 7860` with no
construction traceback. PENDING: user to open + hard-refresh and confirm the chat
feel (streaming, sidebar history, examples, mood) + dark theme.

Next actions (unchanged in spirit from run #3 flow):

1. Run generation eval on the 12B adapter, same as run #3 did
   (`modal run eval/modal_generation_eval.py`, defaults to
   `/out/neurobait-lora-12b`) plus the local heuristic reference eval.
2. Update `model-card/README.md` with run #4 (Gemma 3 12B) numbers — it still
   carries the OLD run #3 (26B) results — and re-push to HF.


Saya lihat bagian akhir log masih punya beberapa “PENDING” lama yang sebagian sudah selesai. Saya akan append section baru bertanggal hari ini supaya jejaknya jelas tanpa mengedit histori lama.


Input:
*** Begin Patch
*** Update File: local-dev/log_dev.md
@@
 Next actions (unchanged in spirit from run #3 flow):

 1. Run generation eval on the 12B adapter, same as run #3 did
    (`modal run eval/modal_generation_eval.py`, defaults to
    `/out/neurobait-lora-12b`) plus the local heuristic reference eval.
 2. Update `model-card/README.md` with run #4 (Gemma 3 12B) numbers — it still
    carries the OLD run #3 (26B) results — and re-push to HF.
+
+## Public README Refresh + Social Post Placeholder - 2026-06-09
+
+Public README refresh completed:
+
+- GitHub `README.md` rewritten as outward-facing project overview.
+- HF model-card `model-card/README.md` rewritten as outward-facing model card.
+- HF Space `deploy/README.md` rewritten as outward-facing Space card.
+- Public pages now mention Build Small Hackathon submission framing:
+  - primary track: Backyard AI
+  - bonus quest fit: Well-Tuned
+  - bonus quest fit: Off-Brand
+  - sponsor fit: Modal-powered
+- Public pages now state the final stack clearly:
+  - fine-tuned on Modal H100
+  - deployed on Hugging Face ZeroGPU
+  - runtime uses Gradio + transformers + peft + 4-bit bitsandbytes NF4
+
+GitHub commit:
+
+```text
+14119fd Refresh public NeuroBait README docs
+```
+
+Pushed to GitHub `main`, HF model repo, and HF Space repo. Raw public README
+endpoints were checked successfully after push.
+
+Social media post is still pending. User plans to create the social media post
+next, then attach its URL in the submission README/card(s).
+
+Placeholder to fill later:
+
+```text
+SOCIAL_POST_URL=<pending>
+```
+
+When the URL is ready, update the outward-facing README(s), likely:
+
+- `README.md`
+- `model-card/README.md`
+- `deploy/README.md`
+
+Suggested section title:
+
+```text
+## Demo And Social Post
+```
*** End Patch


Success. Updated the following files:
M local-dev/log_dev.md

@@ -746 +746,48 @@
    carries the OLD run #3 (26B) results — and re-push to HF.
+
+## Public README Refresh + Social Post Placeholder - 2026-06-09
+
+Public README refresh completed:
+
+- GitHub `README.md` rewritten as outward-facing project overview.
+- HF model-card `model-card/README.md` rewritten as outward-facing model card.
+- HF Space `deploy/README.md` rewritten as outward-facing Space card.
+- Public pages now mention Build Small Hackathon submission framing:
+  - primary track: Backyard AI
+  - bonus quest fit: Well-Tuned
+  - bonus quest fit: Off-Brand
+  - sponsor fit: Modal-powered
+- Public pages now state the final stack clearly:
+  - fine-tuned on Modal H100
+  - deployed on Hugging Face ZeroGPU
+  - runtime uses Gradio + transformers + peft + 4-bit bitsandbytes NF4
+
+GitHub commit:
+
+```text
+14119fd Refresh public NeuroBait README docs
+```
+
+Pushed to GitHub `main`, HF model repo, and HF Space repo. Raw public README
+endpoints were checked successfully after push.
+
+Social media post is still pending. User plans to create the social media post
+next, then attach its URL in the submission README/card(s).
+
+Placeholder to fill later:
+
+```text
+SOCIAL_POST_URL=<pending>
+```
+
+When the URL is ready, update the outward-facing README(s), likely:
+
+- `README.md`
+- `model-card/README.md`
+- `deploy/README.md`
+
+Suggested section title:
+
+```text
+## Demo And Social Post
+```


Output:
Exit code: 0
Wall time: 0.2 seconds
Output:
Success. Updated the following files:
M local-dev/log_dev.md


Done. Saya sudah tambahkan placeholder di [local-dev/log_dev.md](/media/haris-subrata/Work/llm/NeuroBait-Build-Small-Model/local-dev/log_dev.md) bagian:

`Public README Refresh + Social Post Placeholder - 2026-06-09`

Isinya mencatat:
- README publik sudah di-refresh dan dipush
- kategori submission sudah masuk
- Modal fine-tune + HF ZeroGPU deploy sudah disebut
- placeholder `SOCIAL_POST_URL=<pending>`
- nanti URL social post perlu ditambahkan ke `README.md`, `model-card/README.md`, dan `deploy/README.md`