unstuck / README.md
art87able's picture
honest NVIDIA path (Nemotron-Mini-4B 5/5) + bake-off table + Modal runtime serving + 3-tier fallback + SFT dataset
9ff6699 verified
|
Raw
History Blame Contribute Delete
10.9 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade
metadata
title: Unstuck
emoji: 🧩
colorFrom: indigo
colorTo: purple
sdk: gradio
sdk_version: 6.17.3
python_version: 3.12.12
app_file: app.py
pinned: false
short_description: Tiny timed steps that learn your time-blindness
tags:
  - build-small-hackathon
  - backyard-ai
  - track:backyard
  - track:wood
  - achievement:offbrand
  - achievement:fieldnotes
  - achievement:sharing
  - achievement:offgrid
  - achievement:llama
  - achievement:welltuned
  - sponsor:openai
  - sponsor:openbmb
  - sponsor:nvidia
  - sponsor:modal
  - tiny-titan
  - tiny-model
  - llama-cpp
  - off-brand
  - field-notes
  - sharing-is-caring
  - codex
  - agent-trace
  - zerogpu
  - qwen
  - adhd
  - time-blindness
  - task-breakdown
  - calibration
  - privacy
  - small-models

Unstuck

Unstuck turns one overwhelming task into tiny timed steps, then learns your personal time-blindness and recalibrates the estimates to you. Built for the HF Build Small Hackathon (Backyard AI track). Runs a ≀4B model (Qwen/Qwen3-4B-Instruct-2507).

Your data stays yours. Plans and calibration history live in your browser (localStorage), not on the server β€” nothing is shared between users, and only the task text you submit ever reaches the model. Export/Import gives you the full round-trip.

What it does beyond a breakdown bot: a built-in step timer (Start β†’ Done measures for you), per-category calibration learned from your actual times with a visible "Your patterns" history, progressive reveal (only the next step is live β€” no wall of steps), recursive "Still stuck?" re-breakdown, skip-without-polluting-the-data, plan persistence across reloads, and a markdown checklist export. One generate() seam serves eight interchangeable backends: ZeroGPU, HF serverless inference, Nebius Token Factory, a fully-offline local GGUF (offgrid), OpenBMB MiniCPM (minicpm) and NVIDIA Nemotron (nemotron), a fine-tuned Qwen2.5-0.5B we trained on Modal and published to the Hub (finetuned), and that fine-tune served on a Modal web endpoint (modal) β€” each picked by one env var with no app changes. ZeroGPU also falls back ZeroGPU β†’ HF serverless β†’ local fine-tune, so a plan always returns even if GPU quota is exhausted.

Demo & submission

Model: Qwen/Qwen3-4B-Instruct-2507 (4B β€” within the Tiny Titan ≀4B bar). Built small, in the open with OpenAI Codex (Codex-attributed commits) and an honest deterministic calibration layer β€” no AI in the differentiator.

Badges & bonus quests β€” the evidence

Badge / track Claim Evidence
🏑 Backyard AI (track) A real anti-overwhelm tool for ADHD time-blindness the whole app: tiny timed steps + honest per-category calibration
πŸͺΆ Tiny Titan (≀4B) Runs on a genuinely tiny model default model Qwen/Qwen3-4B-Instruct-2507 (4 B)
πŸ”Œ Off the Grid (local-first) No cloud APIs β€” runs on the model in front of you UNSTUCK_BACKEND=offgrid β†’ local GGUF, zero network. Verified: docs/offgrid-proof.png is a plan generated fully offline by the local model. See Run fully offline below.
πŸ¦™ Llama Champion (llama.cpp) Model runs through the llama.cpp runtime the offgrid backend drives Qwen3-4B-…-Q4_K_M.gguf via llama-cpp-python (same proof screenshot)
🧾 Sharing is Caring (open trace) Agent trace shared on the Hub unstuck-agent-trace dataset
🎨 Off-Brand (custom UI) A frontend that pushes past the default Gradio look custom gr.themes theme + a Fraunces gradient wordmark, gradient buttons, layered/hover step cards, indigo focus rings, fully de-branded chrome (see THEME/CSS in app.py)
πŸ“ Field Notes A published write-up of what we built and learned HF blog: Building Unstuck small (also in docs/field-notes.md)
πŸ€– sponsor:openai (Codex) Codex-attributed commits in the repo built with the OpenAI Codex CLI β€” commit trail + the agent-trace dataset
🟒 sponsor:nvidia (Nemotron) The app runs on an NVIDIA Nemotron model nvidia/Nemotron-Mini-4B-Instruct (4B, under the 32B cap) through the app's exact prompt + validator β€” verified 5/5 schema-valid breakdowns (scripts/finetune/modal_nemotron_test.py). The larger reasoning Nemotron-3-Nano-30B is also callable via Nebius/NIM, but its think-tokens are less schema-reliable β€” see the bake-off below
πŸ”΅ sponsor:openbmb (MiniCPM) The app runs on an OpenBMB MiniCPM model UNSTUCK_BACKEND=minicpm serves openbmb/MiniCPM-V-4_5 over Nebius serverless via the same seam β€” live-verified valid breakdowns
⚑ sponsor:modal (Modal) Modal used to build and serve the app the fine-tune was LoRA-trained on a Modal A10G GPU (modal_finetune.py) and is served on a Modal web endpoint (modal_serve.py) reachable via UNSTUCK_BACKEND=modal β€” development and runtime
🎯 achievement:welltuned (fine-tuned) The app uses a fine-tuned model published on HF art87able/unstuck-qwen2.5-0.5b-steps β€” Qwen2.5-0.5B LoRA-tuned on 130 distilled Unstuck breakdowns (dataset); UNSTUCK_BACKEND=finetuned runs the app on it, and it's the always-on local fallback if ZeroGPU quota runs dry
πŸ… Bonus Quest Champion Most bonus criteria met the twelve rows above, each genuinely earned

Backend bake-off β€” the seam, measured

Every small model is driven through Unstuck's exact breakdown contract (strict JSON schema + one repair retry) via the same ModelAdapter the app uses. Honest results (scripts/bakeoff.py):

Model (serverless on Nebius) Valid / 5 Avg steps Avg latency
Qwen3-30B-A3B (teacher) 5/5 5.0 2.9s
OpenBMB MiniCPM-V-4.5 5/5 4.2 0.8s
NVIDIA Nemotron-3-Nano-30B (reasoning) 0/5 β€” 41.8s
NVIDIA Nemotron-Mini-4B-Instruct (on Modal) 5/5 5.4 β€”
Unstuck fine-tune (Qwen2.5-0.5B) (on Modal) βœ“ valid β€” β€”

The reasoning 30B Nemotron is the outlier β€” its think-tokens overrun the token budget and break the schema, which is exactly why we use the 4B non-reasoning Nemotron-Mini for the NVIDIA path.

Run locally

pip install -r requirements.txt gradio
UNSTUCK_BACKEND=hf_inference HF_TOKEN=... python app.py

The default backend is zerogpu, which the Space uses. The hf_inference path is the lightweight local option.

Run fully offline (offgrid)

No network, no cloud β€” a local quantised GGUF drives the same generate() seam (the honest basis for the offgrid badge):

pip install -r requirements.txt gradio llama-cpp-python
# drop a Qwen3-4B GGUF (e.g. Qwen3-4B-Instruct-2507-Q4_K_M.gguf) into ./models/
UNSTUCK_BACKEND=offgrid OFFGRID_GGUF_PATH=models/Qwen3-4B-Instruct-2507-Q4_K_M.gguf python app.py

llama-cpp-python is deliberately left out of requirements.txt (it would bloat the Space build) β€” install it only for offline use.

Verified locally β€” here it is generating a plan with no network, entirely on Qwen3-4B-Instruct-2507-Q4_K_M.gguf through llama.cpp:

Unstuck running fully offline on a local GGUF via llama.cpp

Reproducible transcript (env β†’ local .gguf load β†’ model output, no network): docs/offgrid-proof.log.

Run on MiniCPM or Nemotron (Nebius serverless)

The same generate() seam runs the app on OpenBMB MiniCPM or NVIDIA Nemotron β€” both small (<32B) models served by Nebius Token Factory, selected by one env var:

# OpenBMB MiniCPM  (sponsor:openbmb)
UNSTUCK_BACKEND=minicpm  NEBIUS_API_KEY=... python app.py
# NVIDIA Nemotron  (sponsor:nvidia) β€” 30B-A3B reasoning model, callable but less schema-reliable
UNSTUCK_BACKEND=nemotron NEBIUS_API_KEY=... python app.py

MiniCPM-V is live-verified valid (5/5 in the bake-off). The Nebius Nemotron above is the 30B reasoning model β€” callable, but the verified-valid Nemotron is the 4B nvidia/Nemotron-Mini-4B-Instruct (run on Modal, 5/5). Override MINICPM_MODEL / NEMOTRON_MODEL (or *_BASE_URL + *_API_KEY) to point at any other host β€” e.g. NVIDIA's own NIM endpoint at build.nvidia.com:

# Nemotron on NVIDIA's own NIM (build.nvidia.com)
UNSTUCK_BACKEND=nemotron \
  NEMOTRON_BASE_URL=https://integrate.api.nvidia.com/v1 \
  NEMOTRON_API_KEY=nvapi-... \
  NEMOTRON_MODEL=nvidia/nemotron-3-nano-30b-a3b \
  python app.py

Run on our fine-tuned model (finetuned)

UNSTUCK_BACKEND=finetuned runs the app on art87able/unstuck-qwen2.5-0.5b-steps β€” a Qwen2.5-0.5B-Instruct LoRA we trained on a Modal A10G GPU by distilling 130 schema-valid breakdowns out of the strong serverless model, then merged and published to the Hub:

pip install -r requirements.txt gradio torch transformers
UNSTUCK_BACKEND=finetuned python app.py   # loads the published model, runs locally

The whole pipeline is in scripts/finetune/: gen_dataset.py (distillation) β†’ modal_finetune.py (LoRA on Modal) β†’ modal_verify.py (reloads the published model and asserts a schema-valid breakdown).

Your history lives in your browser. Use the in-app Export/Import buttons to move it between devices.

Source: https://github.com/art87able/unstuck (Codex Track)