recall / README.md
arturogp3's picture
Sync from GitHub via hub-sync
40c272a verified
|
Raw
History Blame Contribute Delete
5.75 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade
metadata
title: Recall  AI Study Partner
emoji: 📚
colorFrom: indigo
colorTo: green
sdk: gradio
sdk_version: 6.17.3
app_file: server.py
pinned: false
license: mit

📚 Recall — an AI study partner that gets smarter about what you get wrong

Upload your study material → Recall generates a quiz deck → you answer → a small model grades and explains each answer → it generates new questions targeting exactly what you missed → end-of-session recap. Built for the Build Small Hackathon (Backyard AI track).

  • Model: openbmb/MiniCPM4.1-8B (fallback: MiniCPM5-1B)
  • Platform: Gradio app, hosted as a Hugging Face Space

Run it (stub mode — no GPU, no model download)

pip install -r requirements.txt
python server.py         # http://127.0.0.1:7860  ← polished custom frontend

Everything works end-to-end on canned data, so anyone can clone and click through the full loop in minute one.

server.py serves the Recall design (frontend/index.html) and a thin JSON API over the existing backend — the learning/content logic and the schema.py data contract are treated as an API and are never modified. The original Gradio form is still available as a fallback at /gradio (and standalone via python app.py).

Run with the real model

The heavy model deps (torch/transformers/…) are kept out of requirements.txt so the Space build stays fast in stub mode. Install them with the model requirements:

pip install -r requirements-model.txt
RECALL_STUB=0 python server.py

Dependency pins (why they're tight). MiniCPM4.1-8B's trust_remote_code imports symbols removed in transformers 5.x, so the real model needs transformers >=4.55,<5.0. That in turn requires huggingface-hub <1.0, which gradio 6.18 forbids (it needs hub >=1.2) — so requirements.txt and the Space sdk_version are pinned to gradio 6.17.3 (the newest gradio that still allows hub <1.0). Because a gradio-SDK Space force-installs one gradio for the whole Space, stub and real-model share it; 6.17.3 keeps both working without a Docker Space. The 1B fallback has no such constraint.

On Apple Silicon (M1/M2/…), the default bf16 + MPS combo produces garbage output (a known MPS bf16 instability — not present on the Space's CUDA GPU). For a clean local real-model smoke test, force CPU/float32:

RECALL_STUB=0 RECALL_MODEL=1b RECALL_DTYPE=float32 RECALL_DEVICE=cpu python server.py

The model

Recall runs on openbmb/MiniCPM4.1-8B, an 8B open model from OpenBMB chosen for the Backyard AI track: small enough to serve on a single Hugging Face ZeroGPU Space, capable enough to grade free-text answers and write grounded follow-up questions.

Where the model is load-bearing. Two user-visible features are pure model work, not templated strings:

  • Grading — it compares your free-text answer to the reference answer and returns a 0–5 score, a plain-language explanation, and the specific concept you missed.
  • Adaptive follow-ups — from that missed concept it writes brand-new questions that drill exactly what you got wrong.

How inference is served. Everything model-related goes through a single chat(messages, max_tokens) wrapper in llm.py; no other module imports transformers directly. The model is loaded once (lazily, via AutoModelForCausalLM in bf16 with device_map="auto") on the Space's ZeroGPU, with the GPU entrypoint wrapped in @spaces.GPU. max_tokens is kept tight (256–512) because latency is the demo-killer. Model output is never trusted: replies expected to be JSON are parsed defensively, with one repair retry and a safe fallback so a malformed generation can never crash the study loop.

Stub mode. With RECALL_STUB=1 (the default) chat() returns canned replies, so the whole app runs and demos end-to-end with no GPU and no model download. Flip RECALL_STUB=0 to use the real model.

Fallback (config flip, no code change). If the Space is too slow or runs out of memory, swap to a smaller model by setting RECALL_MODEL — the rest of the pipeline is unchanged:

# fast fallback
RECALL_MODEL=openbmb/MiniCPM5-1B RECALL_STUB=0 python app.py
# mid fallback (also earns the Tiny Titan badge)
RECALL_MODEL=openbmb/MiniCPM3-4B RECALL_STUB=0 python app.py

Project layout

File Owner What it is
schema.py shared The data contract (Card, CardState, GradeResult, Session). Don't change without a sync.
llm.py Nikolai Shared MiniCPM inference wrapper + defensive JSON parsing.
learning_engine.py Nikolai Scheduling (SM-2-lite), grading, adaptation, follow-ups, recap.
content_pipeline.py Frank PDF/text → chunks → question cards.
app.py Arturo Gradio UI (Upload / Study / Recap) over gr.State — fallback at /gradio.
server.py FastAPI server: serves the custom frontend + JSON API over the backend.
frontend/index.html The polished Recall design (Upload / Study / Recap), vanilla HTML/CSS/JS.

How to work in parallel

  1. At kickoff, lock schema.py together.
  2. Each module already ships working stubs — build your real logic behind the same function signatures, flip RECALL_STUB=0 to test for real.
  3. Don't change public function signatures without telling the team.

The judging hook

The small model is load-bearing in two visible places: grading free-text answers with explanations, and generating follow-up questions that drill the exact concept you missed. Make sure the demo shows both.