"""FATHOM Streamlit Demo โ€” DEM-03. 2-panel layout: Left: Recursion tree visualization (D3 or plotly sunburst) Right: W&B training curves embed (live iframe) Run: streamlit run space_demo/app.py """ from __future__ import annotations import json import os import streamlit as st st.set_page_config( page_title="FATHOM โ€” RL-Trained Recursive Language Model", page_icon="๐Ÿง ", layout="wide", ) st.markdown( f"**Live env:** [Pratham-math/fathom-env]({os.environ.get('FATHOM_SPACE_URL','https://Pratham-math-fathom-env.hf.space')}) " f"ยท **Trained model:** [Pratham-math/fathom-1.5b-grpo](https://huggingface.co/Pratham-math/fathom-1.5b-grpo) " f"ยท **W&B:** [run sy1tqun0](https://wandb.ai/pratham-alwar05-indian-institute-of-information-technolo/huggingface/runs/sy1tqun0)" ) # --------------------------------------------------------------------------- # Header # --------------------------------------------------------------------------- st.markdown("## ๐Ÿง  FATHOM Demo") st.markdown( "_First RL-Trained Recursive Language Model โ€” Meta ร— PyTorch ร— HF Hackathon_" ) st.divider() # --------------------------------------------------------------------------- # Reward composition badge (DEM-03 C.4: visible-to-judges reward overview) # --------------------------------------------------------------------------- with st.expander("Reward composition (4 components, deterministic verifier)", expanded=True): cb1, cb2 = st.columns([1, 2], gap="medium") with cb1: st.markdown("**Format gate** (multiplier)") st.success("`...` required \u2014 if missing, soft bonus + cap applies") st.caption("Source: `rewards/compose.py` \u2014 audited in REWARD_AUDIT.md") with cb2: try: import plotly.graph_objects as go # type: ignore labels = ["correctness", "token_budget", "recursion_efficiency"] weights = [0.70, 0.15, 0.15] colors = ["#2ca02c", "#1f77b4", "#ff7f0e"] fig0 = go.Figure(go.Pie( labels=labels, values=weights, marker=dict(colors=colors), hole=0.4, textinfo="label+percent", )) fig0.update_layout(margin=dict(l=10, r=10, t=10, b=10), height=200, showlegend=False) st.plotly_chart(fig0, use_container_width=True) except ImportError: st.metric("correctness", 0.70) st.metric("token_budget", 0.15) st.metric("recursion_efficiency", 0.15) st.divider() # --------------------------------------------------------------------------- # Sidebar: controls # --------------------------------------------------------------------------- with st.sidebar: st.header("Controls") env_url = st.text_input( "Env server URL", value=os.environ.get("FATHOM_SPACE_URL", "https://Pratham-math-fathom-env.hf.space"), key="env_url", ) st.divider() st.caption("Source: [github.com/Pratham-math/fathom](https://github.com/Pratham-math/fathom)") @st.cache_data(ttl=3600) def fetch_trace(url: str) -> dict: import httpx try: # Provide a quick dummy trace by interacting with the env. # Note: the real recursive model is not loaded in Streamlit, # so this just grabs the reset observation and submits a dummy answer. r = httpx.post(f"{url}/reset", json={"seed": 42}, timeout=10) r.raise_for_status() obs = r.json() q = obs.get("question", "Question") s = httpx.post(f"{url}/step", json={"action_type": "answer", "answer": "simulated"}, timeout=10) s.raise_for_status() return { "name": f"Live init: {q[:30]}...", "children": [ {"name": "REPL: simulated step"}, {"name": "โ†’ simulated"} ] } except Exception as e: return { "name": "[Example Trace] root: 200K doc", "children": [ { "name": "llm(chunk_0-50K)", "children": [{"name": "REPL: grep โ†’ 'azure'"}], }, {"name": "REPL: count_tokens โ†’ 200K"}, {"name": "โ†’ azure"}, ], } # --------------------------------------------------------------------------- # 2 columns # --------------------------------------------------------------------------- col_tree, col_wb = st.columns([1.5, 1.5], gap="medium") # โ”€โ”€ Column 1: Recursion tree โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ with col_tree: st.subheader("Recursion Tree") st.caption("Sample episode trace") sample_tree = fetch_trace(env_url) tree_json = json.dumps(sample_tree) d3_html = f"""
""" st.components.v1.html(d3_html, height=280) # โ”€โ”€ Column 3: W&B training curves โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ with col_wb: st.subheader("Training Curves") wb_url = os.environ.get("WANDB_RUN_URL", "https://wandb.ai/pratham-alwar05-indian-institute-of-information-technolo/huggingface/runs/sy1tqun0") if wb_url: st.components.v1.iframe(wb_url, height=260, scrolling=True) else: st.info("Set `WANDB_RUN_URL` env var to embed live training curves.") st.divider() st.caption("FATHOM Demo Space")