recall / README.md
arturogp3's picture
Sync from GitHub via hub-sync
40c272a verified
|
Raw
History Blame Contribute Delete
5.75 kB
---
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](https://huggingface.co/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)
```bash
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:
```bash
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:
```bash
RECALL_STUB=0 RECALL_MODEL=1b RECALL_DTYPE=float32 RECALL_DEVICE=cpu python server.py
```
## The model
Recall runs on **[openbmb/MiniCPM4.1-8B](https://huggingface.co/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:
```bash
# 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.