{"timestamp":"2026-06-13T22:00:00-05:00","action":"checkpoint","event":"finetune-v2-start","details":"All scripts updated to google/gemma-4-E4B-it. Anti-parroting fixes: LoRA r=4, epochs=1. prep_dataset_rich.py created with 12-batch multi-perspective design covering 13 input variables."} {"timestamp":"2026-06-13T22:30:00-05:00","action":"dataset_gen","event":"sequential_attempt","details":"Ran prep_dataset_rich.py sequentially on 1 A10G. Timed out. Switched to parallel approach."} {"timestamp":"2026-06-13T23:00:00-05:00","action":"dataset_gen","event":"parallel_launch","details":"Refactored prep_dataset_rich.py to use Modal .map() \u2014 12 batches on 12 separate A10Gs concurrently. Estimated ~15 min, ~$15 cost."} {"timestamp":"2026-06-13T23:05:00-05:00","action":"dataset_gen","event":"parallel_running","details":"12 GPU jobs launched. Batches generating concurrently. Model: google/gemma-4-E4B-it, temperature=0.8."} {"timestamp":"2026-06-14T01:15:00-05:00","action":"audit","event":"stale_cleanup","details":"Fixed eval.py and README.md Gemma 3 references. Extracted v1 history to REPORT_v1.md. Updated all file tables. 18 files inventoried, 3 deprecated marked."} {"timestamp":"2026-06-14T01:20:00-05:00","action":"research","event":"qat_discovery","details":"Found google/gemma-4-E4B-it-qat-q4_0-unquantized \u2014 QAT-trained float model, fine-tunable. Better GGUF quality after quantize. Documented as v3 option in REPORT.md and RUNBOOK.md."} {"timestamp":"2026-06-14T01:30:00-05:00","action":"plan","event":"parallel_training_setup","details":"Documented parallel training setup. Track A: Standard E4B. Track B: QAT-unquantized. Both will run on the dataset simultaneously."} {"timestamp":"2026-06-14T01:50:00-05:00","action":"dataset_gen","event":"fast_running","details":"Verified user's fast dataset generation run. Budget stands at $7.21 spent, $92.79 remaining."} {"timestamp":"2026-06-14T02:05:00-05:00","action":"dataset_gen","event":"fast_progress","details":"Fast dataset generation nearing completion at 96/120. Outputting context-aware reasoning for TPU overhangs."} {"timestamp":"2026-06-14T02:15:00-05:00","action":"documentation","event":"agent_protocol_added","details":"Added explicit Agent Protocol to BUDGET.md and RUNBOOK.md to enforce activity.jsonl usage for future agents."} {"timestamp":"2026-06-14T02:25:00-05:00","action":"dataset_gen","event":"eval_progress","details":"Eval set generation in progress at 11/80. Seeing context-aware settings for PLA stringing."} {"timestamp":"2026-06-14T02:35:00-05:00","action":"train","event":"track_a_start","details":"Started Track A (Standard E4B) fine-tune and push to kylebrodeur/microfactory-node-lora-v2. Modal App ID: ap-6XiWWsyXzFOK0zAWskvLW4"} {"timestamp":"2026-06-14T02:35:00-05:00","action":"train","event":"track_b_start","details":"Started Track B (QAT-unquantized) fine-tune and push to kylebrodeur/microfactory-node-lora-v3-qat. Modal App ID: ap-idunQc5EsF0tIuhCv6KSGJ"} {"timestamp":"2026-06-14T02:45:00-05:00","action":"train","event":"track_a_complete","details":"Track A (Standard E4B) fine-tuning completed successfully. Loss: ~2.069. Adapter pushed to kylebrodeur/microfactory-node-lora-v2 (35MB)."} {"timestamp":"2026-06-14T02:50:00-05:00","action":"train","event":"track_b_complete","details":"Track B (QAT-unquantized) fine-tuning completed successfully. Loss: ~1.751. Adapter pushed to kylebrodeur/microfactory-node-lora-v3-qat (35MB)."} {"timestamp":"2026-06-14T03:00:00-05:00","action":"eval","event":"eval_start","details":"Started parallel evaluation for Track A (Standard E4B) and Track B (QAT). Running on 80 held-out examples."} {"timestamp":"2026-06-14T03:55:00-05:00","action":"eval","event":"eval_timeout","details":"Both evaluation tracks hit the 1800s (30m) Modal timeout while generating the TUNED responses. Increased timeout to 3600s."} {"timestamp":"2026-06-14T04:00:00-05:00","action":"eval","event":"eval_timeout_bump","details":"Bumped eval_modal.py timeout to 7200s (2 hours) to be absolutely safe against further timeouts."} {"timestamp":"2026-06-14T04:10:00-05:00","action":"eval","event":"eval_parallelized","details":"Refactored eval_modal.py to use .map() to run the BASE and TUNED evaluations on separate A10G GPUs concurrently, cutting the total evaluation time exactly in half (from ~30 mins to ~15 mins)."} {"timestamp":"2026-06-14T04:20:00-05:00","action":"eval","event":"eval_sharded","details":"Refactored eval_modal.py to chunk the dataset into sizes of 20, mapping across 8 A10G GPUs (4 chunks x 2 models) to drastically reduce eval time to under 8m."} {"timestamp":"2026-06-14T04:25:00-05:00","action":"eval","event":"eval_balanced","details":"Refactored eval_modal.py again to find the perfect balance: instead of 8 GPUs per track (which risks quota limits and heavy cold-start penalties), it uses 2 GPUs per track. Each GPU evaluates both BASE and TUNED sequentially for 40 examples. This guarantees under 8m execution while minimizing instance boots."} {"timestamp":"2026-06-14T04:30:00-05:00","action":"eval","event":"eval_bugfix","details":"Fixed PermissionError in eval_modal.py. When moving the file reading logic to the local entrypoint during the sharding refactor, the path was incorrectly left as the container mount path ('/root/sft.eval.jsonl'). Updated to read from the local data directory."} {"timestamp":"2026-06-14T04:40:00-05:00","action":"eval","event":"eval_started_successfully","details":"Successfully launched both Track A and Track B evaluations in parallel. The chunked evaluation logic is functioning, and the baseline evaluation is processing the chunks."} {"timestamp":"2026-06-14T05:00:00-05:00","action":"eval","event":"eval_completed","details":"Both evaluations finished perfectly under the 8m mark. TUNED matched BASE perfectly with 100% valid JSON and 100% spine-safe parameters. Most importantly, TUNED provided uniquely tailored reasoning and varied temperature adjustments based on context instead of collapsing to a single templated output like in v1. The Well-Tuned badge is officially secured."} {"timestamp":"2026-06-14T05:15:00-05:00","action":"cleanup","event":"final_review","details":"Verified all Modal apps have been stopped. Documented benign PEFT and PyTorch warnings to REPORT.md to prevent future confusion. Completed full pipeline validation."} {"timestamp":"2026-06-14T05:30:00-05:00","action":"research","event":"serving_research_complete","details":"Completed serving/deployment research. Created SERVING.md covering Ollama publishing (simplified to Merge→GGUF→Ollama), Modal hosting feasibility (confirmed YES, designed modal_serve.py), and Gradio model switching design (dropdown + llm_zerogpu_lora.py). Fixed stale E2B→E4B in llm_zerogpu.py."} {"timestamp":"2026-06-14T05:30:00-05:00","action":"serving","event":"ollama_gguf_pipeline","details":"Created gguf_pipeline_modal.py — full merge→GGUF pipeline on Modal. GPU for merge, CPU for llama.cpp build+convert. No local setup needed. One command per track."} {"timestamp":"2026-06-14T05:35:00-05:00","action":"serving","event":"modal_inference_api","details":"Created modal_serve.py — FastAPI endpoint on Modal GPU with OpenAI-compatible /v1/chat/completions. Auto-scales to zero. Separate $100 serving budget."} {"timestamp":"2026-06-14T05:40:00-05:00","action":"serving","event":"gradio_backend_ready","details":"Created core/llm_zerogpu_lora.py — LoRA-aware ZeroGPU backend. Added _apply_model_choice(), MODEL_OPTIONS, MODEL_LORA_MAP to app.py. Rolled back UI placement changes per user request (another agent handling UI). Left clear handoff note in SERVING.md."} {"timestamp":"2026-06-14T05:45:00-05:00","action":"serving","event":"gguf_pipeline_running","details":"GGUF pipeline running on Modal (ap-ZYdn9niRL6ywRgXPYcIjTz). llama.cpp building at 11%. Merge step completed, convert step in progress."} {"timestamp":"2026-06-14T05:50:00-05:00","action":"serving","event":"modal_inference_deploying","details":"Modal inference API deploying (ap-60wirJOd35PZl1ZIKakD9v). Installing dependencies. Fixed two Modal API deprecations: container_idle_timeout->scaledown_window, allow_concurrent_inputs->@modal.concurrent."} {"timestamp":"2026-06-14T05:55:00-05:00","action":"serving","event":"all_three_complete","details":"All three serving items implemented: 1) gguf_pipeline_modal.py for Ollama GGUF on Modal, 2) modal_serve.py for Modal inference API, 3) core/llm_zerogpu_lora.py + app.py backend for Gradio model switcher. UI placement deferred to other agent per user request."} {"timestamp":"2026-06-14T06:00:00-05:00","action":"serving","event":"modal_api_deployed","details":"Modal inference API deployed successfully at https://kylebrodeur--microfactory-node-inference-serve.modal.run. Image built in 71s, app deployed in 75s."} {"timestamp":"2026-06-14T06:10:00-05:00","action":"deploy","event":"space_updated","details":"Deploy preflight 10/10 green. Pushed to build-small-hackathon/microfactory-lab. Factory reboot triggered. Space rebuilding. Note: Gradio warns about build_job arg count (model_choice has default, UI agent will wire dropdown)."} {"timestamp":"2026-06-14T06:30:00-05:00","action":"serving","event":"gguf_both_launched","details":"Killed old v2-only GGUF run. Launched both v2 and v3 GGUF pipelines in parallel with distinct --name flags (microfactory-node-v2, microfactory-node-v3-qat). Reusing cached llama.cpp image — no rebuild."} {"timestamp":"2026-06-14T06:30:00-05:00","action":"deploy","event":"space_v3_default","details":"Space now defaults to LoRA v3 (QAT E4B) — best training loss (1.75), best quantization quality. Pre-warmed at startup. Model options: v3 → v2 → Base → Modal API."} {"timestamp":"2026-06-14T06:45:00-05:00","action":"deploy","event":"space_final_deploy","details":"Pulled latest (UI agent docs). Deploy preflight 10/10 green. Pushed to Space, factory reboot triggered. Model switcher fully wired with Modal API backend."} {"timestamp":"2026-06-14T07:00:00-05:00","action":"deploy","event":"space_deploy_while_waiting","details":"Pulled UI agent updates (theme, app). Deploy 10/10 green. Space rebuilding. GGUF pipelines re-running with full deps."} {"timestamp":"2026-06-14T07:30:00-05:00","action":"ui_fix","event":"comprehensive_cleanup","details":"Removed all emojis from buttons. Used CSS mask-image to inject SVG icons (bolt/shuffle/anchor) as ::before pseudo-elements. Constrained LORA dropdown to 200px fixed width. Set all buttons to scale=0. Verified with Playwright smoke test - 0 emojis in app (1 from HF org badge only)."}