daydream / README.md
kaiser-data's picture
README: storyline + speed + UX
f91a40d verified
|
Raw
History Blame Contribute Delete
10.6 kB
---
title: DAYDREAM
emoji: ๐ŸŒ™
colorFrom: indigo
colorTo: purple
sdk: gradio
sdk_version: 6.16.0
app_file: app/app.py
pinned: true
license: mit
short_description: "Small models, big dreams: a dream game with your tiger"
tags:
- track:thousand-token-wood
- sponsor:openbmb-minicpm
- sponsor:modal
- badge:best-agent
- badge:off-brand
- badge:best-demo
---
# ๐ŸŒ™ DAYDREAM โ€” *Press Your Luck, Keep Your Tiger*
A bedtime dream you **play** โ€” a real, goal-driven story, dreamed in real time by a
**fleet of small models**, none bigger than fits on one GPU. Each world gives you a
**quest**; you pursue it by taking **gambits** (safe / bold / reckless) through surreal
scenes with your stuffed tiger **Hobbes**, who grows brave because of the bets you take
*together*. Code rolls the dice; the little models supply the soul. Reach the goal to
wake with the prize โ€” or run out of lucidity and dissolve.
> **The thesis โ€” small models, big dreams.** You don't own one giant brain; you command
> a *fleet of scrappy small minds*. In a dream, a small model's fuzziness isn't a bug โ€”
> it's the aesthetic. **The constraint is the art.** Every model โ‰ค32B, by design.
---
## ๐Ÿ† Submission tags
- **Track:** *An Adventure in Thousand Token Wood* (whimsical) โ€” there's even a `Thousand Token Wood` world inside.
- **Sponsor prizes:** **OpenBMB / Best MiniCPM** (MiniCPM5-1B is our Keeper) ยท **Modal / Best Use** (4 services + a cost-guardian).
- **Bonus badges:** **Best Agent** (a coordinated multi-agent fleet) ยท **Off Brand** (custom dream-deck UI + live generated visuals) ยท **Best Demo**.
## โœจ What makes it different
1. **A real story, not a chat.** Every world is a quest with a visible goal; the Dreamweaver weaves *one coherent tale* that moves toward it each turn (forward on success, setback on failure) and resolves in a genuine climax โ€” reach the prize, or the dream collapses.
2. **A fleet, not a chatbot.** Five small models โ€” ๐ŸŒŒ Dreamweaver, ๐Ÿ‘ Nightmare, ๐Ÿฏ Hobbes, ๐Ÿ—บ Keeper, ๐ŸŽจ Painter โ€” each with one job, coordinated per turn. Every model โ‰ค32B.
3. **Code owns the dice, models own the words.** Pass/fail and every reward is computed by a seeded, model-free resolver. The models *never* decide outcomes โ€” so it's a **fair game**, not a story that flatters you. This is the heart of the design.
4. **Hobbes grows brave because of you.** A COURAGE meter rises when you survive bets made *with* him; his voice shifts cowering โ†’ steady โ†’ "I've got you." The "aww" is earned.
5. **The dream paints itself โ€” fast.** A FLUX image renders each beat on-GPU in **~0.5s**; a pre-generated hero greets you the instant you arrive, then live per-beat images shift the scene. Choices and state run async, so a warm turn is **~5s** with narration streaming in under a second.
6. **Engineered for real Modal deployment.** Multi-backend (vLLM MoE + llama.cpp + FLUX) plus a **cloud cost-guardian** we built after a runaway-GPU lesson โ€” scale-to-zero, hard container caps, a lease-based dead-man's-switch, and robustness so a cold/failed backend degrades gracefully instead of hanging a turn.
7. **Deterministic & shareable.** Same dream seed replays the same dice *and* the same images โ†’ *"beat my run, seed `abc123`."* Download your full run as a keepsake.
---
## ๐Ÿง  Architecture
DAYDREAM is a **fleet of small models refereed by code**: a deterministic Python core
owns the truth and the dice, while a handful of sub-32B models โ€” each on its own Modal
GPU โ€” supply only words and pixels. Three views:
### 1 ยท System โ€” three layers, one rule
> **The rule:** outcomes flow *down* from code; only language flows *up* from models.
```mermaid
flowchart TB
P([๐Ÿ‘ค Player])
subgraph CODE["โš™๏ธ Orchestration โ€” Python ยท owns the truth"]
direction LR
ENGINE["DreamEngine<br/><i>turn loop</i>"]
RESOLVER{{"๐ŸŽฒ Resolver<br/><i>seeded dice + rewards</i>"}}
STATE[("๐Ÿ—บ๏ธ WorldState<br/><i>externalized memory</i>")]
end
subgraph FLEET["๐Ÿค– The Fleet โ€” Modal serverless GPUs ยท every model โ‰ค 32B"]
direction LR
SPEC["๐ŸŒŒ Dreamweaver ยท ๐Ÿ‘ Nightmare ยท ๐Ÿฏ Hobbes<br/><b>Qwen3-30B-A3B</b> MoE on vLLM<br/><i>30B total ยท only 3B active/token</i>"]
ROUTER["๐Ÿ—บ Keeper<br/><b>MiniCPM-1B</b> ยท llama.cpp"]
VISION["๐ŸŽจ Painter<br/><b>FLUX.1-schnell</b>"]
end
P -- "gambit (safe/bold/reckless)" --> ENGINE
ENGINE --> RESOLVER -- "verdict" --> ENGINE
ENGINE <-. "context slice โ†” patch" .-> STATE
ENGINE == "narrate ยท react" ==> SPEC
ENGINE -. "async" .-> ROUTER
ENGINE -. "async" .-> VISION
SPEC == "prose + 3 choices" ==> P
VISION -. "image" .-> P
ROUTER -. "state patch" .-> STATE
classDef code fill:#1b1640,stroke:#7c5cff,color:#fff;
classDef fleet fill:#241a4d,stroke:#9d7bff,color:#fff;
classDef dice fill:#2a1022,stroke:#ff5c7c,color:#fff;
classDef player fill:#0b0a1c,stroke:#cdbcff,color:#fff;
class ENGINE,STATE code; class SPEC,ROUTER,VISION fleet; class RESOLVER dice; class P player;
```
### 2 ยท One turn โ€” critical path vs. async (why it feels instant)
```mermaid
sequenceDiagram
autonumber
actor P as ๐Ÿ‘ค Player
participant C as โš™๏ธ Resolver
participant D as ๐ŸŒŒ Dreamweaver
participant H as ๐Ÿฏ Hobbes
participant K as ๐Ÿ—บ Keeper
participant F as ๐ŸŽจ FLUX
P->>C: pick gambit
C->>C: roll seeded dice โ†’ verdict
Note over C: the outcome is FIXED before any model speaks โ€” the game is fair
C->>D: narrate this verdict
D-->>P: streams prose ยท first words in ~0.4s
par off the critical path (async)
C-)K: patch world-state (background)
C-)F: paint the beat (~0.5s on GPU)
end
D->>H: finished scene
H-->>P: reaction + 3 fresh gambits ยท ~5s
F--)P: dream image fades in
Note over P,F: you wait only for narration + choices (~5s) โ€”<br/>state and image never block the turn
```
### 3 ยท The fairness spine โ€” code owns the dice
```mermaid
flowchart LR
G["gambit + seed + turn"] --> R{{"๐ŸŽฒ resolve()<br/>pure ยท deterministic"}}
R --> V["verdict<br/>success / partial / fail<br/>+ reward magnitudes"]
V --> A["apply()<br/>move LUCIDITY ยท PROGRESS<br/>ยท COURAGE ยท MENACE"]
V --> N["๐ŸŒŒ model narrates<br/><i>the words, not the outcome</i>"]
A --> S[("WorldState")]
classDef c fill:#2a1022,stroke:#ff5c7c,color:#fff;
classDef m fill:#241a4d,stroke:#9d7bff,color:#fff;
class R,V,A c; class N m;
```
*Same `(seed, turn)` โ†’ same dice โ†’ **"beat my run, seed `abc123`"** is honest. A model can never decide whether you succeed.*
---
## ๐ŸŽฎ How it plays
1. Pick a world (Candy Desert, Sunken City, Rain Street, Red Planet, Thousand Token Wood) and a seed. A hero image and your **quest** greet you instantly.
2. Pursue the quest: take a **gambit** โ€” ๐ŸŸข safe / ๐ŸŸก bold / ๐Ÿ”ด reckless (each shows its odds + reward) โ€” or type your own action. Hobbes' three options are concrete, scene-specific steps toward the goal.
3. The **Dreamweaver** narrates the outcome the dice already decided, moving the story toward the goal; the **Nightmare** presses when menace climbs; **Hobbes** reacts in his current mood and offers the next steps; the **Keeper** updates world-state; the **Painter** repaints the scene.
4. Climb **PROGRESS** to 100 to wake with the prize, or run out of **LUCIDITY** and dissolve โ€” both end in a climactic beat. Watch **COURAGE** turn Hobbes brave along the way. Win or lose, the run freezes into a shareable Dream Journal you can download.
## ๐Ÿค– The fleet
*Full design + diagrams: **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)**.*
| Agent | Role | Backend (โ‰ค32B each) | Job |
|---|---|---|---|
| ๐ŸŒŒ Dreamweaver | specialist | Modal vLLM ยท Qwen3-30B-A3B (MoE, 3B active) | narrate the pre-decided outcome |
| ๐Ÿ‘ Nightmare | specialist | Modal vLLM ยท Qwen3-30B-A3B (MoE, 3B active) | press the dread when menace is high |
| ๐Ÿฏ Hobbes | specialist | Modal vLLM ยท Qwen3-30B-A3B (MoE, 3B active) | companion; voice keyed to COURAGE; offer gambits |
| ๐Ÿ—บ Keeper | router | Modal llama.cpp ยท **MiniCPM5-1B** | structured world-state (location, items, memory) |
| ๐ŸŽจ dream image | vision | Modal ยท FLUX.1-schnell | paint each beat, in parallel under the narration |
Backends are OpenAI-compatible โ†’ swap models or run "off the grid" via one env var, no code change.
## ๐Ÿง  Why it stays coherent on small models
The **world-state lives in code**, outside the models (`agents/world.py`). Each turn the engine
feeds each agent a compact slice of truth, so a 1B router can keep a consistent world that a
single small context never could. The **resolver** (`agents/resolver.py`) owns all game math,
seeded by `(seed, turn)` โ€” fair, replayable, and impossible for a model to fudge.
## โ˜๏ธ Best Use of Modal โ€” and a cost story
DAYDREAM runs **four Modal services** (vLLM, llama.cpp, FLUX, and a guardian). After a
keep-warm GPU once cold-looped and burned real money, we made cost control *structural*:
- **Scale-to-zero + `max_containers=1`** on every GPU app โ€” $0 idle, no fan-out.
- A **cloud guardian**: a cheap cron that warm-pings endpoints **only while a time-boxed lease is active** โ€” so warmth is a *pull*, not a pin. Forget to tear down? The lease expires and everything scales to zero on its own, independent of your laptop.
- A `make` control surface: `make status` (apps + lease + live spend tracker), `make stop` (panic), `make demo-up/down`.
All endpoint URLs derive from one `MODAL_WORKSPACE` slug, so moving workspaces is a one-line change.
## ๐Ÿš€ Run it
**Offline (no backend, fully playable):**
```bash
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
DAYDREAM_MOCK=1 python app/app.py
```
**Against Modal inference:** set `MODAL_WORKSPACE` + keys in `.env` (see `.env.example`), then `make deploy && python app/app.py`.
## ๐Ÿ—‚ Layout
| Path | What |
|---|---|
| `agents/dream.py` | the fleet engine (Dreamweaver ยท Nightmare ยท Hobbes ยท Keeper) |
| `agents/resolver.py` | seeded, model-free dice + reward math (code owns the game) |
| `agents/world.py` | environments + externalized `WorldState` |
| `agents/vision.py` | per-beat dream-image prompts + FLUX client |
| `agents/base.py` | tiny streaming/JSON Agent + `DAYDREAM_MOCK` offline mode |
| `app/app.py` | Gradio dream-deck UI |
| `modal_app/*.py` | Modal vLLM ยท llama.cpp ยท FLUX ยท guardian |
*Small models, big dreams.* ๐ŸŒ™